diff --git a/.travis.yml b/.travis.yml index 6186ff6..87c78a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,8 @@ matrix: packages: - g++-4.9 sources: &sources - - llvm-toolchain-precise-3.8 + - llvm-toolchain-trusty-3.8 + - llvm-toolchain-trusty-5.0 - ubuntu-toolchain-r-test - os: linux env: COMPILER=g++-4.9 UNICODE_OPTIONS=-DCXXOPTS_USE_UNICODE_HELP=Yes @@ -27,9 +28,7 @@ matrix: apt: packages: - g++-5 - sources: &sources - - llvm-toolchain-precise-3.8 - - ubuntu-toolchain-r-test + sources: *sources - os: linux env: COMPILER=g++-5 UNICODE_OPTIONS=-DCXXOPTS_USE_UNICODE_HELP=Yes addons: @@ -53,9 +52,17 @@ matrix: - clang-3.8 - libc++-dev sources: *sources + - os: linux + env: COMPILER=clang++-5.0 CMAKE_OPTIONS=-DCXXOPTS_CXX_STANDARD=17 + addons: + apt: + packages: + - clang-5.0 + - g++-5 + sources: *sources script: > cmake -DCXXOPTS_BUILD_TESTS=ON -DCMAKE_CXX_COMPILER=$COMPILER - -DCMAKE_CXX_FLAGS=$CXXFLAGS $UNICODE_OPTIONS . + -DCMAKE_CXX_FLAGS=$CXXFLAGS $UNICODE_OPTIONS $CMAKE_OPTIONS . && make && make ARGS=--output-on-failure test before_install: diff --git a/CMakeLists.txt b/CMakeLists.txt index ae4dea2..2949e77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,14 @@ option(CXXOPTS_BUILD_EXAMPLES "Set to ON to build examples" ON) option(CXXOPTS_BUILD_TESTS "Set to ON to build tests" OFF) # request c++11 without gnu extension for the whole project and enable more warnings -set(CMAKE_CXX_STANDARD 11) +if (CXXOPTS_CXX_STANDARD) + set(CMAKE_CXX_STANDARD ${CXXOPTS_CXX_STANDARD}) +else() + set(CMAKE_CXX_STANDARD 11) +endif() + set(CMAKE_CXX_EXTENSIONS OFF) + if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W2") elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index 58f30aa..56b783f 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -38,6 +38,11 @@ THE SOFTWARE. #include #include +#ifdef __cpp_lib_optional +#include +#define CXXOPTS_HAS_OPTIONAL +#endif + namespace cxxopts { static constexpr struct { @@ -697,6 +702,17 @@ namespace cxxopts value.push_back(v); } +#ifdef CXXOPTS_HAS_OPTIONAL + template + void + parse_value(const std::string& text, std::optional& value) + { + T result; + parse_value(text, result); + value = std::move(result); + } +#endif + template struct type_is_container { diff --git a/test/options.cpp b/test/options.cpp index 14b55d6..aae6239 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -454,3 +454,22 @@ TEST_CASE("Booleans", "[boolean]") { REQUIRE(result.count("others") == 1); } + +#ifdef CXXOPTS_HAS_OPTIONAL +TEST_CASE("std::optional", "[optional]") { + std::optional optional; + cxxopts::Options options("optional", " - tests optional"); + options.add_options() + ("optional", "an optional option", cxxopts::value>(optional)); + + Argv av({"optional", "--optional", "foo"}); + + char** argv = av.argv(); + auto argc = av.argc(); + + options.parse(argc, argv); + + REQUIRE(optional.has_value()); + CHECK(*optional == "foo"); +} +#endif