mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 21:36:11 +01:00
Embed Clara v1.1.1
This commit is contained in:
parent
b0f4f16ee0
commit
31e6499e64
106
include/external/clara.hpp
vendored
106
include/external/clara.hpp
vendored
@ -1,5 +1,11 @@
|
|||||||
// v1.0-develop.2
|
// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||||
// See https://github.com/philsquared/Clara
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See https://github.com/philsquared/Clara for more details
|
||||||
|
|
||||||
|
// Clara v1.1.1
|
||||||
|
|
||||||
#ifndef CATCH_CLARA_HPP_INCLUDED
|
#ifndef CATCH_CLARA_HPP_INCLUDED
|
||||||
#define CATCH_CLARA_HPP_INCLUDED
|
#define CATCH_CLARA_HPP_INCLUDED
|
||||||
@ -370,7 +376,7 @@ namespace detail {
|
|||||||
template<typename ClassT, typename ReturnT, typename ArgT>
|
template<typename ClassT, typename ReturnT, typename ArgT>
|
||||||
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
||||||
static const bool isValid = true;
|
static const bool isValid = true;
|
||||||
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;;
|
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
|
||||||
using ReturnType = ReturnT;
|
using ReturnType = ReturnT;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -535,7 +541,7 @@ namespace detail {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ResultValueBase() {
|
~ResultValueBase() override {
|
||||||
if( m_type == Ok )
|
if( m_type == Ok )
|
||||||
m_value.~T();
|
m_value.~T();
|
||||||
}
|
}
|
||||||
@ -573,7 +579,7 @@ namespace detail {
|
|||||||
auto errorMessage() const -> std::string { return m_errorMessage; }
|
auto errorMessage() const -> std::string { return m_errorMessage; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void enforceOk() const {
|
void enforceOk() const override {
|
||||||
// !TBD: If no exceptions, std::terminate here or something
|
// !TBD: If no exceptions, std::terminate here or something
|
||||||
switch( m_type ) {
|
switch( m_type ) {
|
||||||
case ResultBase::LogicError:
|
case ResultBase::LogicError:
|
||||||
@ -653,46 +659,30 @@ namespace detail {
|
|||||||
return ParserResult::ok( ParseResultType::Matched );
|
return ParserResult::ok( ParseResultType::Matched );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BoundRefBase {
|
struct NonCopyable {
|
||||||
BoundRefBase() = default;
|
NonCopyable() = default;
|
||||||
BoundRefBase( BoundRefBase const & ) = delete;
|
NonCopyable( NonCopyable const & ) = delete;
|
||||||
BoundRefBase( BoundRefBase && ) = delete;
|
NonCopyable( NonCopyable && ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase const & ) = delete;
|
NonCopyable &operator=( NonCopyable const & ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase && ) = delete;
|
NonCopyable &operator=( NonCopyable && ) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~BoundRefBase() = default;
|
struct BoundRef : NonCopyable {
|
||||||
|
virtual ~BoundRef() = default;
|
||||||
virtual auto isFlag() const -> bool = 0;
|
|
||||||
virtual auto isContainer() const -> bool { return false; }
|
virtual auto isContainer() const -> bool { return false; }
|
||||||
|
};
|
||||||
|
struct BoundValueRefBase : BoundRef {
|
||||||
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
||||||
|
};
|
||||||
|
struct BoundFlagRefBase : BoundRef {
|
||||||
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BoundValueRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return false; }
|
|
||||||
|
|
||||||
auto setFlag( bool ) -> ParserResult override {
|
|
||||||
return ParserResult::logicError( "Flags can only be set on boolean fields" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BoundFlagRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return true; }
|
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
|
||||||
bool flag;
|
|
||||||
auto result = convertInto( arg, flag );
|
|
||||||
if( result )
|
|
||||||
setFlag( flag );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef : BoundValueRefBase {
|
struct BoundValueRef : BoundValueRefBase {
|
||||||
T &m_ref;
|
T &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( T &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
auto setValue( std::string const &arg ) -> ParserResult override {
|
||||||
return convertInto( arg, m_ref );
|
return convertInto( arg, m_ref );
|
||||||
@ -700,10 +690,10 @@ namespace detail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef<std::vector<T>> : BoundValueRefBase {
|
struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
|
||||||
std::vector<T> &m_ref;
|
std::vector<T> &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto isContainer() const -> bool override { return true; }
|
auto isContainer() const -> bool override { return true; }
|
||||||
|
|
||||||
@ -748,12 +738,12 @@ namespace detail {
|
|||||||
|
|
||||||
template<typename ArgType, typename L>
|
template<typename ArgType, typename L>
|
||||||
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
||||||
ArgType temp;
|
ArgType temp{};
|
||||||
auto result = convertInto( arg, temp );
|
auto result = convertInto( arg, temp );
|
||||||
return !result
|
return !result
|
||||||
? result
|
? result
|
||||||
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename L>
|
template<typename L>
|
||||||
@ -803,6 +793,9 @@ namespace detail {
|
|||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator|( T const &other ) const -> Parser;
|
auto operator|( T const &other ) const -> Parser;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Common code and state for Args and Opts
|
// Common code and state for Args and Opts
|
||||||
@ -810,16 +803,16 @@ namespace detail {
|
|||||||
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
||||||
protected:
|
protected:
|
||||||
Optionality m_optionality = Optionality::Optional;
|
Optionality m_optionality = Optionality::Optional;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundRef> m_ref;
|
||||||
std::string m_hint;
|
std::string m_hint;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
|
|
||||||
explicit ParserRefImpl( std::shared_ptr<BoundRefBase> const &ref ) : m_ref( ref ) {}
|
explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ParserRefImpl( T &ref, std::string const &hint )
|
ParserRefImpl( T &ref, std::string const &hint )
|
||||||
: m_ref( std::make_shared<BoundRef<T>>( ref ) ),
|
: m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
||||||
m_hint( hint )
|
m_hint( hint )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -860,10 +853,10 @@ namespace detail {
|
|||||||
|
|
||||||
class ExeName : public ComposableParserImpl<ExeName> {
|
class ExeName : public ComposableParserImpl<ExeName> {
|
||||||
std::shared_ptr<std::string> m_name;
|
std::shared_ptr<std::string> m_name;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundValueRefBase> m_ref;
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundRefBase> {
|
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
|
||||||
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,7 +864,7 @@ namespace detail {
|
|||||||
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
||||||
|
|
||||||
explicit ExeName( std::string &ref ) : ExeName() {
|
explicit ExeName( std::string &ref ) : ExeName() {
|
||||||
m_ref = std::make_shared<BoundRef<std::string>>( ref );
|
m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
@ -914,7 +907,10 @@ namespace detail {
|
|||||||
if( token.type != TokenType::Argument )
|
if( token.type != TokenType::Argument )
|
||||||
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
||||||
|
|
||||||
auto result = m_ref->setValue( remainingTokens->token );
|
assert( dynamic_cast<detail::BoundValueRefBase*>( m_ref.get() ) );
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
|
|
||||||
|
auto result = valueRef->setValue( remainingTokens->token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
else
|
else
|
||||||
@ -987,20 +983,22 @@ namespace detail {
|
|||||||
if( remainingTokens && remainingTokens->type == TokenType::Option ) {
|
if( remainingTokens && remainingTokens->type == TokenType::Option ) {
|
||||||
auto const &token = *remainingTokens;
|
auto const &token = *remainingTokens;
|
||||||
if( isMatch(token.token ) ) {
|
if( isMatch(token.token ) ) {
|
||||||
if( m_ref->isFlag() ) {
|
if( auto flagRef = dynamic_cast<detail::BoundFlagRefBase*>( m_ref.get() ) ) {
|
||||||
auto result = m_ref->setFlag( true );
|
auto result = flagRef->setFlag( true );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
||||||
} else {
|
} else {
|
||||||
|
assert( dynamic_cast<detail::BoundValueRefBase*>( m_ref.get() ) );
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
++remainingTokens;
|
++remainingTokens;
|
||||||
if( !remainingTokens )
|
if( !remainingTokens )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto const &argToken = *remainingTokens;
|
auto const &argToken = *remainingTokens;
|
||||||
if( argToken.type != TokenType::Argument )
|
if( argToken.type != TokenType::Argument )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto result = m_ref->setValue( argToken.token );
|
auto result = valueRef->setValue( argToken.token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
@ -1077,6 +1075,12 @@ namespace detail {
|
|||||||
return Parser( *this ) |= other;
|
return Parser( *this ) |= other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward deprecated interface with '+' instead of '|'
|
||||||
|
template<typename T>
|
||||||
|
auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser { return operator|( other ); }
|
||||||
|
|
||||||
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
||||||
std::vector<HelpColumns> cols;
|
std::vector<HelpColumns> cols;
|
||||||
for (auto const &o : m_options) {
|
for (auto const &o : m_options) {
|
||||||
@ -1116,6 +1120,8 @@ namespace detail {
|
|||||||
for( auto const &cols : rows )
|
for( auto const &cols : rows )
|
||||||
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
||||||
|
|
||||||
|
optWidth = (std::min)(optWidth, consoleWidth/2);
|
||||||
|
|
||||||
for( auto const &cols : rows ) {
|
for( auto const &cols : rows ) {
|
||||||
auto row =
|
auto row =
|
||||||
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
||||||
|
106
third_party/clara.hpp
vendored
106
third_party/clara.hpp
vendored
@ -1,5 +1,11 @@
|
|||||||
// v1.0-develop.2
|
// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||||
// See https://github.com/philsquared/Clara
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See https://github.com/philsquared/Clara for more details
|
||||||
|
|
||||||
|
// Clara v1.1.1
|
||||||
|
|
||||||
#ifndef CLARA_HPP_INCLUDED
|
#ifndef CLARA_HPP_INCLUDED
|
||||||
#define CLARA_HPP_INCLUDED
|
#define CLARA_HPP_INCLUDED
|
||||||
@ -370,7 +376,7 @@ namespace detail {
|
|||||||
template<typename ClassT, typename ReturnT, typename ArgT>
|
template<typename ClassT, typename ReturnT, typename ArgT>
|
||||||
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
||||||
static const bool isValid = true;
|
static const bool isValid = true;
|
||||||
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;;
|
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
|
||||||
using ReturnType = ReturnT;
|
using ReturnType = ReturnT;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -535,7 +541,7 @@ namespace detail {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ResultValueBase() {
|
~ResultValueBase() override {
|
||||||
if( m_type == Ok )
|
if( m_type == Ok )
|
||||||
m_value.~T();
|
m_value.~T();
|
||||||
}
|
}
|
||||||
@ -573,7 +579,7 @@ namespace detail {
|
|||||||
auto errorMessage() const -> std::string { return m_errorMessage; }
|
auto errorMessage() const -> std::string { return m_errorMessage; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void enforceOk() const {
|
void enforceOk() const override {
|
||||||
// !TBD: If no exceptions, std::terminate here or something
|
// !TBD: If no exceptions, std::terminate here or something
|
||||||
switch( m_type ) {
|
switch( m_type ) {
|
||||||
case ResultBase::LogicError:
|
case ResultBase::LogicError:
|
||||||
@ -653,46 +659,30 @@ namespace detail {
|
|||||||
return ParserResult::ok( ParseResultType::Matched );
|
return ParserResult::ok( ParseResultType::Matched );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BoundRefBase {
|
struct NonCopyable {
|
||||||
BoundRefBase() = default;
|
NonCopyable() = default;
|
||||||
BoundRefBase( BoundRefBase const & ) = delete;
|
NonCopyable( NonCopyable const & ) = delete;
|
||||||
BoundRefBase( BoundRefBase && ) = delete;
|
NonCopyable( NonCopyable && ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase const & ) = delete;
|
NonCopyable &operator=( NonCopyable const & ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase && ) = delete;
|
NonCopyable &operator=( NonCopyable && ) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~BoundRefBase() = default;
|
struct BoundRef : NonCopyable {
|
||||||
|
virtual ~BoundRef() = default;
|
||||||
virtual auto isFlag() const -> bool = 0;
|
|
||||||
virtual auto isContainer() const -> bool { return false; }
|
virtual auto isContainer() const -> bool { return false; }
|
||||||
|
};
|
||||||
|
struct BoundValueRefBase : BoundRef {
|
||||||
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
||||||
|
};
|
||||||
|
struct BoundFlagRefBase : BoundRef {
|
||||||
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BoundValueRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return false; }
|
|
||||||
|
|
||||||
auto setFlag( bool ) -> ParserResult override {
|
|
||||||
return ParserResult::logicError( "Flags can only be set on boolean fields" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BoundFlagRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return true; }
|
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
|
||||||
bool flag;
|
|
||||||
auto result = convertInto( arg, flag );
|
|
||||||
if( result )
|
|
||||||
setFlag( flag );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef : BoundValueRefBase {
|
struct BoundValueRef : BoundValueRefBase {
|
||||||
T &m_ref;
|
T &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( T &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
auto setValue( std::string const &arg ) -> ParserResult override {
|
||||||
return convertInto( arg, m_ref );
|
return convertInto( arg, m_ref );
|
||||||
@ -700,10 +690,10 @@ namespace detail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef<std::vector<T>> : BoundValueRefBase {
|
struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
|
||||||
std::vector<T> &m_ref;
|
std::vector<T> &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto isContainer() const -> bool override { return true; }
|
auto isContainer() const -> bool override { return true; }
|
||||||
|
|
||||||
@ -748,12 +738,12 @@ namespace detail {
|
|||||||
|
|
||||||
template<typename ArgType, typename L>
|
template<typename ArgType, typename L>
|
||||||
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
||||||
ArgType temp;
|
ArgType temp{};
|
||||||
auto result = convertInto( arg, temp );
|
auto result = convertInto( arg, temp );
|
||||||
return !result
|
return !result
|
||||||
? result
|
? result
|
||||||
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename L>
|
template<typename L>
|
||||||
@ -803,6 +793,9 @@ namespace detail {
|
|||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator|( T const &other ) const -> Parser;
|
auto operator|( T const &other ) const -> Parser;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Common code and state for Args and Opts
|
// Common code and state for Args and Opts
|
||||||
@ -810,16 +803,16 @@ namespace detail {
|
|||||||
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
||||||
protected:
|
protected:
|
||||||
Optionality m_optionality = Optionality::Optional;
|
Optionality m_optionality = Optionality::Optional;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundRef> m_ref;
|
||||||
std::string m_hint;
|
std::string m_hint;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
|
|
||||||
explicit ParserRefImpl( std::shared_ptr<BoundRefBase> const &ref ) : m_ref( ref ) {}
|
explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ParserRefImpl( T &ref, std::string const &hint )
|
ParserRefImpl( T &ref, std::string const &hint )
|
||||||
: m_ref( std::make_shared<BoundRef<T>>( ref ) ),
|
: m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
||||||
m_hint( hint )
|
m_hint( hint )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -860,10 +853,10 @@ namespace detail {
|
|||||||
|
|
||||||
class ExeName : public ComposableParserImpl<ExeName> {
|
class ExeName : public ComposableParserImpl<ExeName> {
|
||||||
std::shared_ptr<std::string> m_name;
|
std::shared_ptr<std::string> m_name;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundValueRefBase> m_ref;
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundRefBase> {
|
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
|
||||||
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,7 +864,7 @@ namespace detail {
|
|||||||
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
||||||
|
|
||||||
explicit ExeName( std::string &ref ) : ExeName() {
|
explicit ExeName( std::string &ref ) : ExeName() {
|
||||||
m_ref = std::make_shared<BoundRef<std::string>>( ref );
|
m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
@ -914,7 +907,10 @@ namespace detail {
|
|||||||
if( token.type != TokenType::Argument )
|
if( token.type != TokenType::Argument )
|
||||||
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
||||||
|
|
||||||
auto result = m_ref->setValue( remainingTokens->token );
|
assert( dynamic_cast<detail::BoundValueRefBase*>( m_ref.get() ) );
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
|
|
||||||
|
auto result = valueRef->setValue( remainingTokens->token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
else
|
else
|
||||||
@ -987,20 +983,22 @@ namespace detail {
|
|||||||
if( remainingTokens && remainingTokens->type == TokenType::Option ) {
|
if( remainingTokens && remainingTokens->type == TokenType::Option ) {
|
||||||
auto const &token = *remainingTokens;
|
auto const &token = *remainingTokens;
|
||||||
if( isMatch(token.token ) ) {
|
if( isMatch(token.token ) ) {
|
||||||
if( m_ref->isFlag() ) {
|
if( auto flagRef = dynamic_cast<detail::BoundFlagRefBase*>( m_ref.get() ) ) {
|
||||||
auto result = m_ref->setFlag( true );
|
auto result = flagRef->setFlag( true );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
||||||
} else {
|
} else {
|
||||||
|
assert( dynamic_cast<detail::BoundValueRefBase*>( m_ref.get() ) );
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
++remainingTokens;
|
++remainingTokens;
|
||||||
if( !remainingTokens )
|
if( !remainingTokens )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto const &argToken = *remainingTokens;
|
auto const &argToken = *remainingTokens;
|
||||||
if( argToken.type != TokenType::Argument )
|
if( argToken.type != TokenType::Argument )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto result = m_ref->setValue( argToken.token );
|
auto result = valueRef->setValue( argToken.token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
@ -1077,6 +1075,12 @@ namespace detail {
|
|||||||
return Parser( *this ) |= other;
|
return Parser( *this ) |= other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward deprecated interface with '+' instead of '|'
|
||||||
|
template<typename T>
|
||||||
|
auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser { return operator|( other ); }
|
||||||
|
|
||||||
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
||||||
std::vector<HelpColumns> cols;
|
std::vector<HelpColumns> cols;
|
||||||
for (auto const &o : m_options) {
|
for (auto const &o : m_options) {
|
||||||
@ -1116,6 +1120,8 @@ namespace detail {
|
|||||||
for( auto const &cols : rows )
|
for( auto const &cols : rows )
|
||||||
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
||||||
|
|
||||||
|
optWidth = (std::min)(optWidth, consoleWidth/2);
|
||||||
|
|
||||||
for( auto const &cols : rows ) {
|
for( auto const &cols : rows ) {
|
||||||
auto row =
|
auto row =
|
||||||
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
||||||
|
Loading…
Reference in New Issue
Block a user