| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- diff --git a/CMakeLists.txt b/CMakeLists.txt
- index 1e4e1b6..c919063 100644
- --- a/CMakeLists.txt
- +++ b/CMakeLists.txt
- @@ -1,4 +1,4 @@
- -cmake_minimum_required(VERSION 4.1.1)
- +cmake_minimum_required(VERSION 3.5)
-
- project(
- cppli
- @@ -7,7 +7,7 @@ project(
- LANGUAGES CXX
- )
-
- -set(CMAKE_CXX_STANDARD 23)
- +set(CMAKE_CXX_STANDARD 20)
- set(CMAKE_CXX_STANDARD_REQUIRED ON)
- set(CMAKE_CXX_EXTENSIONS OFF)
-
- @@ -31,7 +31,7 @@ target_include_directories(
- $<INSTALL_INTERFACE:include>
- )
-
- -target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
- +target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
-
- #if(MSVC)
- # target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX)
- @@ -78,7 +78,7 @@ if(CPPLI_BUILD_TESTS)
- PRIVATE ${PROJECT_NAME} Catch2::Catch2WithMain
- )
-
- - target_compile_features(cppli_tests PRIVATE cxx_std_23)
- + target_compile_features(cppli_tests PRIVATE cxx_std_20)
-
- include(CTest)
- include(Catch)
- diff --git a/src/cppli_types.cpp b/src/cppli_types.cpp
- index 91f17c3..d8f4ba0 100644
- --- a/src/cppli_types.cpp
- +++ b/src/cppli_types.cpp
- @@ -1,57 +1,102 @@
- -#include <charconv>
- #include <cppli_error.hpp>
- #include <cppli_types.hpp>
- #include <string>
- #include <system_error>
-
- +#if __cpp_lib_charconv >= 201606L && !defined(__GNUC__) || __GNUC__ >= 8
- + #define USE_FROM_CHARS
- +#endif
- +
- +#if defined(USE_FROM_CHARS)
- + #include <charconv>
- +#else
- + #include <sstream>
- +#endif
- +
- namespace cli {
- - Result<int> ValueConverter<int>::from_string(std::string_view str) {
- - int value{};
- - auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
- +#ifdef USE_FROM_CHARS
- + Result<int> ValueConverter<int>::from_string(std::string_view str) {
- + int value{};
- + auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
- +
- + if (ec == std::errc()) {
- + return Result<int>::ok(value);
- + }
-
- - if (ec == std::errc()) {
- - return Result<int>::ok(value);
- - }
- + if (ec == std::errc::invalid_argument) {
- + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
- + }
-
- - if (ec == std::errc::invalid_argument) {
- - return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
- - }
- + if (ec == std::errc::result_out_of_range) {
- + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Integer out of range"));
- + }
-
- - if (ec == std::errc::result_out_of_range) {
- - return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Integer out of range"));
- - }
- + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
- + }
-
- - return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
- - }
- + Result<double> ValueConverter<double>::from_string(std::string_view str) {
- + double value{};
- + auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
-
- - Result<double> ValueConverter<double>::from_string(std::string_view str) {
- - double value{};
- - auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
- + if (ec == std::errc()) {
- + return Result<double>::ok(value);
- + }
-
- - if (ec == std::errc()) {
- - return Result<double>::ok(value);
- - }
- + if (ec == std::errc::invalid_argument) {
- + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
- + }
-
- - if (ec == std::errc::invalid_argument) {
- - return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
- - }
- + if (ec == std::errc::result_out_of_range) {
- + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Floating-point out of range"));
- + }
-
- - if (ec == std::errc::result_out_of_range) {
- - return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Floating-point out of range"));
- - }
- + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
- + }
- +#else
- + Result<int> ValueConverter<int>::from_string(std::string_view str) {
- + try {
- + std::string str_copy(str);
- + std::istringstream iss(str_copy);
- + int value{};
- + iss >> value;
- +
- + if (iss.fail() || !iss.eof()) {
- + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
- + }
- +
- + return Result<int>::ok(value);
- + } catch (const std::exception&) {
- + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
- + }
- + }
-
- - return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
- - }
- + Result<double> ValueConverter<double>::from_string(std::string_view str) {
- + try {
- + std::string str_copy(str);
- + std::istringstream iss(str_copy);
- + double value{};
- + iss >> value;
- +
- + if (iss.fail() || !iss.eof()) {
- + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
- + }
- +
- + return Result<double>::ok(value);
- + } catch (const std::exception&) {
- + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
- + }
- + }
- +#endif
-
- - Result<bool> ValueConverter<bool>::from_string(std::string_view str) {
- - if (str == "true" || str == "1" || str == "yes" || str == "on") {
- - return Result<bool>::ok(true);
- - }
- + Result<bool> ValueConverter<bool>::from_string(std::string_view str) {
- + if (str == "true" || str == "1" || str == "yes" || str == "on") {
- + return Result<bool>::ok(true);
- + }
-
- - if (str == "false" || str == "0" || str == "no" || str == "off") {
- - return Result<bool>::ok(false);
- - }
- + if (str == "false" || str == "0" || str == "no" || str == "off") {
- + return Result<bool>::ok(false);
- + }
-
- - return Result<bool>::err(Error(ErrorCode::InvalidFlagValue, "Invalid boolean value (expected: true/false, 1/0, yes/no, on/off)"));
- - }
- -}// namespace cli
- + return Result<bool>::err(Error(ErrorCode::InvalidFlagValue, "Invalid boolean value (expected: true/false, 1/0, yes/no, on/off)"));
- + }
- +} // namespace cli
|