diff --git a/CMakeLists.txt b/CMakeLists.txt index 219a714..8a30e80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ RETURN() ENDIF() -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.1) project(cxxopts) set(VERSION "0.0.1") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 625abe9..d6f9b3d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,9 +18,34 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -add_executable(example example.cpp) +add_executable(example example.cpp cxxopts.hpp) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall") -target_link_libraries(example ${CXXOPTS_LINKER_LIBRARIES}) +# Visual Studio 12 2013 Update 5 or newer is required to fix in-class member +# initialization using std::make_shared. +# https://connect.microsoft.com/VisualStudio/feedbackdetail/view/818825 +if(MSVC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0.21005.1) + message(SEND_ERROR "Visual Studio 12 2013 Update 5 or newer is required.") +endif() -install(FILES cxxopts.hpp DESTINATION include) +target_link_libraries(example + ${CXXOPTS_LINKER_LIBRARIES} + ) +target_compile_features(example PUBLIC + cxx_auto_type + ) +target_include_directories(example PUBLIC + ${CMAKE_CURRENT_BINARY_DIR} + ) + +include(WriteCompilerDetectionHeader) +write_compiler_detection_header( + FILE cxxopts_compiler_detection.h + PREFIX cxxopts + COMPILERS GNU MSVC Clang + FEATURES + cxx_unicode_literals + cxx_constexpr + cxx_noexcept +) + +install(FILES cxxopts.hpp ${CMAKE_CURRENT_BINARY_DIR}/cxxopts_compiler_detection.h DESTINATION include) diff --git a/src/cxxopts.hpp b/src/cxxopts.hpp index 4d1913d..0bb76c6 100644 --- a/src/cxxopts.hpp +++ b/src/cxxopts.hpp @@ -38,6 +38,21 @@ THE SOFTWARE. #include #include #include +#include + +#include + +#if cxxopts_COMPILER_CXX_CONSTEXPR +#define cxxopts_CONSTEXPR_OR_CONST constexpr +#else +#define cxxopts_CONSTEXPR_OR_CONST const +#endif + +#if cxxopts_COMPILER_CXX_UNICODE_LITERALS +#define cxxopts_U8(x) u8 ## x +#else +#define cxxopts_U8(x) x +#endif //when we ask cxxopts to use Unicode, help strings are processed using ICU, //which results in the correct lengths being computed for strings when they @@ -271,7 +286,7 @@ namespace cxxopts } virtual const char* - what() const noexcept + what() const cxxopts_NOEXCEPT { return m_message.c_str(); } @@ -303,7 +318,7 @@ namespace cxxopts { public: option_exists_error(const std::string& option) - : OptionSpecException(u8"Option ‘" + option + u8"’ already exists") + : OptionSpecException(cxxopts_U8("Option `") + option + cxxopts_U8("` already exists")) { } }; @@ -312,7 +327,7 @@ namespace cxxopts { public: invalid_option_format_error(const std::string& format) - : OptionSpecException(u8"Invalid option format ‘" + format + u8"’") + : OptionSpecException(cxxopts_U8("Invalid option format `") + format + cxxopts_U8("`")) { } }; @@ -321,7 +336,7 @@ namespace cxxopts { public: option_not_exists_exception(const std::string& option) - : OptionParseException(u8"Option ‘" + option + u8"’ does not exist") + : OptionParseException(cxxopts_U8("Option `") + option + cxxopts_U8("` does not exist")) { } }; @@ -330,7 +345,7 @@ namespace cxxopts { public: missing_argument_exception(const std::string& option) - : OptionParseException(u8"Option ‘" + option + u8"’ is missing an argument") + : OptionParseException(cxxopts_U8("Option `") + option + cxxopts_U8("` is missing an argument")) { } }; @@ -339,7 +354,7 @@ namespace cxxopts { public: option_requires_argument_exception(const std::string& option) - : OptionParseException(u8"Option ‘" + option + u8"’ requires an argument") + : OptionParseException(cxxopts_U8("Option `") + option + cxxopts_U8("` requires an argument")) { } }; @@ -353,8 +368,8 @@ namespace cxxopts const std::string& arg ) : OptionParseException( - u8"Option ‘" + option + u8"’ does not take an argument, but argument‘" - + arg + "’ given") + cxxopts_U8("Option `") + option + cxxopts_U8("` does not take an argument, but argument`") + + arg + "` given") { } }; @@ -363,7 +378,7 @@ namespace cxxopts { public: option_not_present_exception(const std::string& option) - : OptionParseException(u8"Option ‘" + option + u8"’ not present") + : OptionParseException(cxxopts_U8("Option `") + option + cxxopts_U8("` not present")) { } }; @@ -376,7 +391,7 @@ namespace cxxopts const std::string& arg ) : OptionParseException( - u8"Argument ‘" + arg + u8"’ failed to parse" + cxxopts_U8("Argument `") + arg + cxxopts_U8("` failed to parse") ) { } @@ -428,25 +443,25 @@ namespace cxxopts template struct value_has_arg { - static constexpr bool value = true; + static cxxopts_CONSTEXPR_OR_CONST bool value = true; }; template <> struct value_has_arg { - static constexpr bool value = false; + static cxxopts_CONSTEXPR_OR_CONST bool value = false; }; template struct type_is_container { - static constexpr bool value = false; + static cxxopts_CONSTEXPR_OR_CONST bool value = false; }; template struct type_is_container> { - static constexpr bool value = true; + static cxxopts_CONSTEXPR_OR_CONST bool value = true; }; template @@ -820,8 +835,8 @@ namespace cxxopts namespace { - constexpr int OPTION_LONGEST = 30; - constexpr int OPTION_DESC_GAP = 2; + cxxopts_CONSTEXPR_OR_CONST int OPTION_LONGEST = 30; + cxxopts_CONSTEXPR_OR_CONST int OPTION_DESC_GAP = 2; std::basic_regex option_matcher ("--([[:alnum:]][-_[:alnum:]]+)(=(.*))?|-([a-zA-Z]+)");