fix-clang.patch 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. diff --git a/CMakeLists.txt b/CMakeLists.txt
  2. index 1e4e1b6..c919063 100644
  3. --- a/CMakeLists.txt
  4. +++ b/CMakeLists.txt
  5. @@ -1,4 +1,4 @@
  6. -cmake_minimum_required(VERSION 4.1.1)
  7. +cmake_minimum_required(VERSION 3.5)
  8. project(
  9. cppli
  10. @@ -7,7 +7,7 @@ project(
  11. LANGUAGES CXX
  12. )
  13. -set(CMAKE_CXX_STANDARD 23)
  14. +set(CMAKE_CXX_STANDARD 20)
  15. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  16. set(CMAKE_CXX_EXTENSIONS OFF)
  17. @@ -31,7 +31,7 @@ target_include_directories(
  18. $<INSTALL_INTERFACE:include>
  19. )
  20. -target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
  21. +target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
  22. #if(MSVC)
  23. # target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX)
  24. @@ -78,7 +78,7 @@ if(CPPLI_BUILD_TESTS)
  25. PRIVATE ${PROJECT_NAME} Catch2::Catch2WithMain
  26. )
  27. - target_compile_features(cppli_tests PRIVATE cxx_std_23)
  28. + target_compile_features(cppli_tests PRIVATE cxx_std_20)
  29. include(CTest)
  30. include(Catch)
  31. diff --git a/src/cppli_types.cpp b/src/cppli_types.cpp
  32. index 91f17c3..d8f4ba0 100644
  33. --- a/src/cppli_types.cpp
  34. +++ b/src/cppli_types.cpp
  35. @@ -1,57 +1,102 @@
  36. -#include <charconv>
  37. #include <cppli_error.hpp>
  38. #include <cppli_types.hpp>
  39. #include <string>
  40. #include <system_error>
  41. +#if __cpp_lib_charconv >= 201606L && !defined(__GNUC__) || __GNUC__ >= 8
  42. + #define USE_FROM_CHARS
  43. +#endif
  44. +
  45. +#if defined(USE_FROM_CHARS)
  46. + #include <charconv>
  47. +#else
  48. + #include <sstream>
  49. +#endif
  50. +
  51. namespace cli {
  52. - Result<int> ValueConverter<int>::from_string(std::string_view str) {
  53. - int value{};
  54. - auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
  55. +#ifdef USE_FROM_CHARS
  56. + Result<int> ValueConverter<int>::from_string(std::string_view str) {
  57. + int value{};
  58. + auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
  59. +
  60. + if (ec == std::errc()) {
  61. + return Result<int>::ok(value);
  62. + }
  63. - if (ec == std::errc()) {
  64. - return Result<int>::ok(value);
  65. - }
  66. + if (ec == std::errc::invalid_argument) {
  67. + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
  68. + }
  69. - if (ec == std::errc::invalid_argument) {
  70. - return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
  71. - }
  72. + if (ec == std::errc::result_out_of_range) {
  73. + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Integer out of range"));
  74. + }
  75. - if (ec == std::errc::result_out_of_range) {
  76. - return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Integer out of range"));
  77. - }
  78. + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
  79. + }
  80. - return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
  81. - }
  82. + Result<double> ValueConverter<double>::from_string(std::string_view str) {
  83. + double value{};
  84. + auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
  85. - Result<double> ValueConverter<double>::from_string(std::string_view str) {
  86. - double value{};
  87. - auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
  88. + if (ec == std::errc()) {
  89. + return Result<double>::ok(value);
  90. + }
  91. - if (ec == std::errc()) {
  92. - return Result<double>::ok(value);
  93. - }
  94. + if (ec == std::errc::invalid_argument) {
  95. + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
  96. + }
  97. - if (ec == std::errc::invalid_argument) {
  98. - return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
  99. - }
  100. + if (ec == std::errc::result_out_of_range) {
  101. + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Floating-point out of range"));
  102. + }
  103. - if (ec == std::errc::result_out_of_range) {
  104. - return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Floating-point out of range"));
  105. - }
  106. + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
  107. + }
  108. +#else
  109. + Result<int> ValueConverter<int>::from_string(std::string_view str) {
  110. + try {
  111. + std::string str_copy(str);
  112. + std::istringstream iss(str_copy);
  113. + int value{};
  114. + iss >> value;
  115. +
  116. + if (iss.fail() || !iss.eof()) {
  117. + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
  118. + }
  119. +
  120. + return Result<int>::ok(value);
  121. + } catch (const std::exception&) {
  122. + return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
  123. + }
  124. + }
  125. - return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
  126. - }
  127. + Result<double> ValueConverter<double>::from_string(std::string_view str) {
  128. + try {
  129. + std::string str_copy(str);
  130. + std::istringstream iss(str_copy);
  131. + double value{};
  132. + iss >> value;
  133. +
  134. + if (iss.fail() || !iss.eof()) {
  135. + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
  136. + }
  137. +
  138. + return Result<double>::ok(value);
  139. + } catch (const std::exception&) {
  140. + return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
  141. + }
  142. + }
  143. +#endif
  144. - Result<bool> ValueConverter<bool>::from_string(std::string_view str) {
  145. - if (str == "true" || str == "1" || str == "yes" || str == "on") {
  146. - return Result<bool>::ok(true);
  147. - }
  148. + Result<bool> ValueConverter<bool>::from_string(std::string_view str) {
  149. + if (str == "true" || str == "1" || str == "yes" || str == "on") {
  150. + return Result<bool>::ok(true);
  151. + }
  152. - if (str == "false" || str == "0" || str == "no" || str == "off") {
  153. - return Result<bool>::ok(false);
  154. - }
  155. + if (str == "false" || str == "0" || str == "no" || str == "off") {
  156. + return Result<bool>::ok(false);
  157. + }
  158. - return Result<bool>::err(Error(ErrorCode::InvalidFlagValue, "Invalid boolean value (expected: true/false, 1/0, yes/no, on/off)"));
  159. - }
  160. -}// namespace cli
  161. + return Result<bool>::err(Error(ErrorCode::InvalidFlagValue, "Invalid boolean value (expected: true/false, 1/0, yes/no, on/off)"));
  162. + }
  163. +} // namespace cli