Add support for std::optional

Fixes #93. This adds C++17 only support for `std::optional` values for
command line parameters.
This commit is contained in:
Jarryd Beck 2018-01-31 18:25:52 +11:00
parent e792760ab9
commit 76bd60dc17
4 changed files with 54 additions and 6 deletions

View File

@ -12,7 +12,8 @@ matrix:
packages: packages:
- g++-4.9 - g++-4.9
sources: &sources sources: &sources
- llvm-toolchain-precise-3.8 - llvm-toolchain-trusty-3.8
- llvm-toolchain-trusty-5.0
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- os: linux - os: linux
env: COMPILER=g++-4.9 UNICODE_OPTIONS=-DCXXOPTS_USE_UNICODE_HELP=Yes env: COMPILER=g++-4.9 UNICODE_OPTIONS=-DCXXOPTS_USE_UNICODE_HELP=Yes
@ -27,9 +28,7 @@ matrix:
apt: apt:
packages: packages:
- g++-5 - g++-5
sources: &sources sources: *sources
- llvm-toolchain-precise-3.8
- ubuntu-toolchain-r-test
- os: linux - os: linux
env: COMPILER=g++-5 UNICODE_OPTIONS=-DCXXOPTS_USE_UNICODE_HELP=Yes env: COMPILER=g++-5 UNICODE_OPTIONS=-DCXXOPTS_USE_UNICODE_HELP=Yes
addons: addons:
@ -53,9 +52,17 @@ matrix:
- clang-3.8 - clang-3.8
- libc++-dev - libc++-dev
sources: *sources 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: > script: >
cmake -DCXXOPTS_BUILD_TESTS=ON -DCMAKE_CXX_COMPILER=$COMPILER 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 && make && make ARGS=--output-on-failure test
before_install: before_install:

View File

@ -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) 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 # request c++11 without gnu extension for the whole project and enable more warnings
if (CXXOPTS_CXX_STANDARD)
set(CMAKE_CXX_STANDARD ${CXXOPTS_CXX_STANDARD})
else()
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
endif()
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
if(MSVC) if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W2")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")

View File

@ -38,6 +38,11 @@ THE SOFTWARE.
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
#ifdef __cpp_lib_optional
#include <optional>
#define CXXOPTS_HAS_OPTIONAL
#endif
namespace cxxopts namespace cxxopts
{ {
static constexpr struct { static constexpr struct {
@ -697,6 +702,17 @@ namespace cxxopts
value.push_back(v); value.push_back(v);
} }
#ifdef CXXOPTS_HAS_OPTIONAL
template <typename T>
void
parse_value(const std::string& text, std::optional<T>& value)
{
T result;
parse_value(text, result);
value = std::move(result);
}
#endif
template <typename T> template <typename T>
struct type_is_container struct type_is_container
{ {

View File

@ -454,3 +454,22 @@ TEST_CASE("Booleans", "[boolean]") {
REQUIRE(result.count("others") == 1); REQUIRE(result.count("others") == 1);
} }
#ifdef CXXOPTS_HAS_OPTIONAL
TEST_CASE("std::optional", "[optional]") {
std::optional<std::string> optional;
cxxopts::Options options("optional", " - tests optional");
options.add_options()
("optional", "an optional option", cxxopts::value<std::optional<std::string>>(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