diff --git a/README.md b/README.md index f7cf941..1e80e45 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Clara v1.1.2 +# Clara v1.1.3 [![Build Status](https://travis-ci.org/catchorg/Clara.svg?branch=master)](https://travis-ci.org/catchorg/Clara) [![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Clara?brach=master&svg=true)](https://ci.appveyor.com/project/catchorg/clara) [![codecov](https://codecov.io/gh/catchorg/Clara/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Clara) diff --git a/docs/release-notes.md b/docs/release-notes.md index dc07b20..67ac47d 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,5 +1,12 @@ +# 1.1.3 + +## Improvements +* `Args` now take arguments as `int argc, char const * const * argv`. + * This allows the use of string literals for arguments + + # 1.1.2 * Fix usage of `dynamic_cast` preventing Clara being used with `-fno-rtti` diff --git a/include/clara.hpp b/include/clara.hpp index 6a701a2..ca138dc 100644 --- a/include/clara.hpp +++ b/include/clara.hpp @@ -5,7 +5,7 @@ // // See https://github.com/philsquared/Clara for more details -// Clara v1.1.2 +// Clara v1.1.3 #ifndef CLARA_HPP_INCLUDED #define CLARA_HPP_INCLUDED diff --git a/single_include/clara.hpp b/single_include/clara.hpp index 9a60c17..257ba10 100644 --- a/single_include/clara.hpp +++ b/single_include/clara.hpp @@ -5,7 +5,7 @@ // // See https://github.com/philsquared/Clara for more details -// Clara v1.1.2 +// Clara v1.1.3 #ifndef CLARA_HPP_INCLUDED #define CLARA_HPP_INCLUDED @@ -18,6 +18,15 @@ #define CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH #endif +#ifndef CLARA_CONFIG_OPTIONAL_TYPE +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define CLARA_CONFIG_OPTIONAL_TYPE std::optional +#endif +#endif +#endif + + // ----------- #included from clara_textflow.hpp ----------- // TextFlowCpp @@ -389,11 +398,9 @@ namespace detail { std::vector m_args; public: - Args( int argc, char *argv[] ) { - m_exeName = argv[0]; - for( int i = 1; i < argc; ++i ) - m_args.push_back( argv[i] ); - } + Args( int argc, char const* const* argv ) + : m_exeName(argv[0]), + m_args(argv + 1, argv + argc) {} Args( std::initializer_list args ) : m_exeName( *args.begin() ), @@ -580,15 +587,13 @@ namespace detail { protected: void enforceOk() const override { - // !TBD: If no exceptions, std::terminate here or something - switch( m_type ) { - case ResultBase::LogicError: - throw std::logic_error( m_errorMessage ); - case ResultBase::RuntimeError: - throw std::runtime_error( m_errorMessage ); - case ResultBase::Ok: - break; - } + + // Errors shouldn't reach this point, but if they do + // the actual error message will be in m_errorMessage + assert( m_type != ResultBase::LogicError ); + assert( m_type != ResultBase::RuntimeError ); + if( m_type != ResultBase::Ok ) + std::abort(); } std::string m_errorMessage; // Only populated if resultType is an error @@ -658,6 +663,16 @@ namespace detail { return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" ); return ParserResult::ok( ParseResultType::Matched ); } +#ifdef CLARA_CONFIG_OPTIONAL_TYPE + template + inline auto convertInto( std::string const &source, std::optional& target ) -> ParserResult { + T temp; + auto result = convertInto( source, temp ); + if( result ) + target = temp; + return result; + } +#endif // CLARA_CONFIG_OPTIONAL_TYPE struct NonCopyable { NonCopyable() = default;