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:
- 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:

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)
# 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")

View File

@ -38,6 +38,11 @@ THE SOFTWARE.
#include <unordered_set>
#include <vector>
#ifdef __cpp_lib_optional
#include <optional>
#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 <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>
struct type_is_container
{

View File

@ -454,3 +454,22 @@ TEST_CASE("Booleans", "[boolean]") {
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