diff --git a/include/external/clara.hpp b/include/external/clara.hpp index 88a5e9fe..7dab7e2f 100644 --- a/include/external/clara.hpp +++ b/include/external/clara.hpp @@ -1,5 +1,11 @@ -// v1.0-develop.2 -// See https://github.com/philsquared/Clara +// Copyright 2017 Two Blue Cubes Ltd. All rights reserved. +// +// 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 #define CATCH_CLARA_HPP_INCLUDED @@ -370,7 +376,7 @@ namespace detail { template struct UnaryLambdaTraits { static const bool isValid = true; - using ArgType = typename std::remove_const::type>::type;; + using ArgType = typename std::remove_const::type>::type; using ReturnType = ReturnT; }; @@ -535,7 +541,7 @@ namespace detail { return *this; } - ~ResultValueBase() { + ~ResultValueBase() override { if( m_type == Ok ) m_value.~T(); } @@ -573,7 +579,7 @@ namespace detail { auto errorMessage() const -> std::string { return m_errorMessage; } protected: - virtual void enforceOk() const { + void enforceOk() const override { // !TBD: If no exceptions, std::terminate here or something switch( m_type ) { case ResultBase::LogicError: @@ -653,46 +659,30 @@ namespace detail { return ParserResult::ok( ParseResultType::Matched ); } - struct BoundRefBase { - BoundRefBase() = default; - BoundRefBase( BoundRefBase const & ) = delete; - BoundRefBase( BoundRefBase && ) = delete; - BoundRefBase &operator=( BoundRefBase const & ) = delete; - BoundRefBase &operator=( BoundRefBase && ) = delete; + struct NonCopyable { + NonCopyable() = default; + NonCopyable( NonCopyable const & ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable &operator=( NonCopyable const & ) = delete; + NonCopyable &operator=( NonCopyable && ) = delete; + }; - virtual ~BoundRefBase() = default; - - virtual auto isFlag() const -> bool = 0; + struct BoundRef : NonCopyable { + virtual ~BoundRef() = default; virtual auto isContainer() const -> bool { return false; } + }; + struct BoundValueRefBase : BoundRef { virtual auto setValue( std::string const &arg ) -> ParserResult = 0; + }; + struct BoundFlagRefBase : BoundRef { 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 - struct BoundRef : BoundValueRefBase { + struct BoundValueRef : BoundValueRefBase { 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 { return convertInto( arg, m_ref ); @@ -700,10 +690,10 @@ namespace detail { }; template - struct BoundRef> : BoundValueRefBase { + struct BoundValueRef> : BoundValueRefBase { std::vector &m_ref; - explicit BoundRef( std::vector &ref ) : m_ref( ref ) {} + explicit BoundValueRef( std::vector &ref ) : m_ref( ref ) {} auto isContainer() const -> bool override { return true; } @@ -748,12 +738,12 @@ namespace detail { template inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult { - ArgType temp; + ArgType temp{}; auto result = convertInto( arg, temp ); return !result ? result : LambdaInvoker::ReturnType>::invoke( lambda, temp ); - }; + } template @@ -803,6 +793,9 @@ namespace detail { public: template auto operator|( T const &other ) const -> Parser; + + template + auto operator+( T const &other ) const -> Parser; }; // Common code and state for Args and Opts @@ -810,16 +803,16 @@ namespace detail { class ParserRefImpl : public ComposableParserImpl { protected: Optionality m_optionality = Optionality::Optional; - std::shared_ptr m_ref; + std::shared_ptr m_ref; std::string m_hint; std::string m_description; - explicit ParserRefImpl( std::shared_ptr const &ref ) : m_ref( ref ) {} + explicit ParserRefImpl( std::shared_ptr const &ref ) : m_ref( ref ) {} public: template ParserRefImpl( T &ref, std::string const &hint ) - : m_ref( std::make_shared>( ref ) ), + : m_ref( std::make_shared>( ref ) ), m_hint( hint ) {} @@ -860,10 +853,10 @@ namespace detail { class ExeName : public ComposableParserImpl { std::shared_ptr m_name; - std::shared_ptr m_ref; + std::shared_ptr m_ref; template - static auto makeRef(LambdaT const &lambda) -> std::shared_ptr { + static auto makeRef(LambdaT const &lambda) -> std::shared_ptr { return std::make_shared>( lambda) ; } @@ -871,7 +864,7 @@ namespace detail { ExeName() : m_name( std::make_shared( "" ) ) {} explicit ExeName( std::string &ref ) : ExeName() { - m_ref = std::make_shared>( ref ); + m_ref = std::make_shared>( ref ); } template @@ -914,7 +907,10 @@ namespace detail { if( token.type != TokenType::Argument ) return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); - auto result = m_ref->setValue( remainingTokens->token ); + assert( dynamic_cast( m_ref.get() ) ); + auto valueRef = static_cast( m_ref.get() ); + + auto result = valueRef->setValue( remainingTokens->token ); if( !result ) return InternalParseResult( result ); else @@ -987,20 +983,22 @@ namespace detail { if( remainingTokens && remainingTokens->type == TokenType::Option ) { auto const &token = *remainingTokens; if( isMatch(token.token ) ) { - if( m_ref->isFlag() ) { - auto result = m_ref->setFlag( true ); + if( auto flagRef = dynamic_cast( m_ref.get() ) ) { + auto result = flagRef->setFlag( true ); if( !result ) return InternalParseResult( result ); if( result.value() == ParseResultType::ShortCircuitAll ) return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); } else { + assert( dynamic_cast( m_ref.get() ) ); + auto valueRef = static_cast( m_ref.get() ); ++remainingTokens; if( !remainingTokens ) return InternalParseResult::runtimeError( "Expected argument following " + token.token ); auto const &argToken = *remainingTokens; if( argToken.type != TokenType::Argument ) return InternalParseResult::runtimeError( "Expected argument following " + token.token ); - auto result = m_ref->setValue( argToken.token ); + auto result = valueRef->setValue( argToken.token ); if( !result ) return InternalParseResult( result ); if( result.value() == ParseResultType::ShortCircuitAll ) @@ -1077,6 +1075,12 @@ namespace detail { return Parser( *this ) |= other; } + // Forward deprecated interface with '+' instead of '|' + template + auto operator+=( T const &other ) -> Parser & { return operator|=( other ); } + template + auto operator+( T const &other ) const -> Parser { return operator|( other ); } + auto getHelpColumns() const -> std::vector { std::vector cols; for (auto const &o : m_options) { @@ -1116,6 +1120,8 @@ namespace detail { for( auto const &cols : rows ) optWidth = (std::max)(optWidth, cols.left.size() + 2); + optWidth = (std::min)(optWidth, consoleWidth/2); + for( auto const &cols : rows ) { auto row = TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) + diff --git a/third_party/clara.hpp b/third_party/clara.hpp index aa429e7a..2134a46a 100644 --- a/third_party/clara.hpp +++ b/third_party/clara.hpp @@ -1,5 +1,11 @@ -// v1.0-develop.2 -// See https://github.com/philsquared/Clara +// Copyright 2017 Two Blue Cubes Ltd. All rights reserved. +// +// 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 #define CLARA_HPP_INCLUDED @@ -370,7 +376,7 @@ namespace detail { template struct UnaryLambdaTraits { static const bool isValid = true; - using ArgType = typename std::remove_const::type>::type;; + using ArgType = typename std::remove_const::type>::type; using ReturnType = ReturnT; }; @@ -535,7 +541,7 @@ namespace detail { return *this; } - ~ResultValueBase() { + ~ResultValueBase() override { if( m_type == Ok ) m_value.~T(); } @@ -573,7 +579,7 @@ namespace detail { auto errorMessage() const -> std::string { return m_errorMessage; } protected: - virtual void enforceOk() const { + void enforceOk() const override { // !TBD: If no exceptions, std::terminate here or something switch( m_type ) { case ResultBase::LogicError: @@ -653,46 +659,30 @@ namespace detail { return ParserResult::ok( ParseResultType::Matched ); } - struct BoundRefBase { - BoundRefBase() = default; - BoundRefBase( BoundRefBase const & ) = delete; - BoundRefBase( BoundRefBase && ) = delete; - BoundRefBase &operator=( BoundRefBase const & ) = delete; - BoundRefBase &operator=( BoundRefBase && ) = delete; + struct NonCopyable { + NonCopyable() = default; + NonCopyable( NonCopyable const & ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable &operator=( NonCopyable const & ) = delete; + NonCopyable &operator=( NonCopyable && ) = delete; + }; - virtual ~BoundRefBase() = default; - - virtual auto isFlag() const -> bool = 0; + struct BoundRef : NonCopyable { + virtual ~BoundRef() = default; virtual auto isContainer() const -> bool { return false; } + }; + struct BoundValueRefBase : BoundRef { virtual auto setValue( std::string const &arg ) -> ParserResult = 0; + }; + struct BoundFlagRefBase : BoundRef { 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 - struct BoundRef : BoundValueRefBase { + struct BoundValueRef : BoundValueRefBase { 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 { return convertInto( arg, m_ref ); @@ -700,10 +690,10 @@ namespace detail { }; template - struct BoundRef> : BoundValueRefBase { + struct BoundValueRef> : BoundValueRefBase { std::vector &m_ref; - explicit BoundRef( std::vector &ref ) : m_ref( ref ) {} + explicit BoundValueRef( std::vector &ref ) : m_ref( ref ) {} auto isContainer() const -> bool override { return true; } @@ -748,12 +738,12 @@ namespace detail { template inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult { - ArgType temp; + ArgType temp{}; auto result = convertInto( arg, temp ); return !result ? result : LambdaInvoker::ReturnType>::invoke( lambda, temp ); - }; + } template @@ -803,6 +793,9 @@ namespace detail { public: template auto operator|( T const &other ) const -> Parser; + + template + auto operator+( T const &other ) const -> Parser; }; // Common code and state for Args and Opts @@ -810,16 +803,16 @@ namespace detail { class ParserRefImpl : public ComposableParserImpl { protected: Optionality m_optionality = Optionality::Optional; - std::shared_ptr m_ref; + std::shared_ptr m_ref; std::string m_hint; std::string m_description; - explicit ParserRefImpl( std::shared_ptr const &ref ) : m_ref( ref ) {} + explicit ParserRefImpl( std::shared_ptr const &ref ) : m_ref( ref ) {} public: template ParserRefImpl( T &ref, std::string const &hint ) - : m_ref( std::make_shared>( ref ) ), + : m_ref( std::make_shared>( ref ) ), m_hint( hint ) {} @@ -860,10 +853,10 @@ namespace detail { class ExeName : public ComposableParserImpl { std::shared_ptr m_name; - std::shared_ptr m_ref; + std::shared_ptr m_ref; template - static auto makeRef(LambdaT const &lambda) -> std::shared_ptr { + static auto makeRef(LambdaT const &lambda) -> std::shared_ptr { return std::make_shared>( lambda) ; } @@ -871,7 +864,7 @@ namespace detail { ExeName() : m_name( std::make_shared( "" ) ) {} explicit ExeName( std::string &ref ) : ExeName() { - m_ref = std::make_shared>( ref ); + m_ref = std::make_shared>( ref ); } template @@ -914,7 +907,10 @@ namespace detail { if( token.type != TokenType::Argument ) return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); - auto result = m_ref->setValue( remainingTokens->token ); + assert( dynamic_cast( m_ref.get() ) ); + auto valueRef = static_cast( m_ref.get() ); + + auto result = valueRef->setValue( remainingTokens->token ); if( !result ) return InternalParseResult( result ); else @@ -987,20 +983,22 @@ namespace detail { if( remainingTokens && remainingTokens->type == TokenType::Option ) { auto const &token = *remainingTokens; if( isMatch(token.token ) ) { - if( m_ref->isFlag() ) { - auto result = m_ref->setFlag( true ); + if( auto flagRef = dynamic_cast( m_ref.get() ) ) { + auto result = flagRef->setFlag( true ); if( !result ) return InternalParseResult( result ); if( result.value() == ParseResultType::ShortCircuitAll ) return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); } else { + assert( dynamic_cast( m_ref.get() ) ); + auto valueRef = static_cast( m_ref.get() ); ++remainingTokens; if( !remainingTokens ) return InternalParseResult::runtimeError( "Expected argument following " + token.token ); auto const &argToken = *remainingTokens; if( argToken.type != TokenType::Argument ) return InternalParseResult::runtimeError( "Expected argument following " + token.token ); - auto result = m_ref->setValue( argToken.token ); + auto result = valueRef->setValue( argToken.token ); if( !result ) return InternalParseResult( result ); if( result.value() == ParseResultType::ShortCircuitAll ) @@ -1077,6 +1075,12 @@ namespace detail { return Parser( *this ) |= other; } + // Forward deprecated interface with '+' instead of '|' + template + auto operator+=( T const &other ) -> Parser & { return operator|=( other ); } + template + auto operator+( T const &other ) const -> Parser { return operator|( other ); } + auto getHelpColumns() const -> std::vector { std::vector cols; for (auto const &o : m_options) { @@ -1116,6 +1120,8 @@ namespace detail { for( auto const &cols : rows ) optWidth = (std::max)(optWidth, cols.left.size() + 2); + optWidth = (std::min)(optWidth, consoleWidth/2); + for( auto const &cols : rows ) { auto row = TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +