|
5 | 5 | //
|
6 | 6 | // See https://github.com/philsquared/Clara for more details
|
7 | 7 |
|
8 |
| -// Clara v1.1.0 |
| 8 | +// Clara v1.1.1 |
9 | 9 |
|
10 | 10 | #ifndef CLARA_HPP_INCLUDED
|
11 | 11 | #define CLARA_HPP_INCLUDED
|
@@ -659,57 +659,41 @@ namespace detail {
|
659 | 659 | return ParserResult::ok( ParseResultType::Matched );
|
660 | 660 | }
|
661 | 661 |
|
662 |
| - struct BoundRefBase { |
663 |
| - BoundRefBase() = default; |
664 |
| - BoundRefBase( BoundRefBase const & ) = delete; |
665 |
| - BoundRefBase( BoundRefBase && ) = delete; |
666 |
| - BoundRefBase &operator=( BoundRefBase const & ) = delete; |
667 |
| - BoundRefBase &operator=( BoundRefBase && ) = delete; |
668 |
| - |
669 |
| - virtual ~BoundRefBase() = default; |
| 662 | + struct NonCopyable { |
| 663 | + NonCopyable() = default; |
| 664 | + NonCopyable( NonCopyable const & ) = delete; |
| 665 | + NonCopyable( NonCopyable && ) = delete; |
| 666 | + NonCopyable &operator=( NonCopyable const & ) = delete; |
| 667 | + NonCopyable &operator=( NonCopyable && ) = delete; |
| 668 | + }; |
670 | 669 |
|
671 |
| - virtual auto isFlag() const -> bool = 0; |
| 670 | + struct BoundRef : NonCopyable { |
| 671 | + virtual ~BoundRef() = default; |
672 | 672 | virtual auto isContainer() const -> bool { return false; }
|
673 |
| - virtual auto setValue( std::string const &arg ) -> ParserResult = 0; |
674 |
| - virtual auto setFlag( bool flag ) -> ParserResult = 0; |
675 | 673 | };
|
676 |
| - |
677 |
| - struct BoundValueRefBase : BoundRefBase { |
678 |
| - auto isFlag() const -> bool override { return false; } |
679 |
| - |
680 |
| - auto setFlag( bool ) -> ParserResult override { |
681 |
| - return ParserResult::logicError( "Flags can only be set on boolean fields" ); |
682 |
| - } |
| 674 | + struct BoundValueRefBase : BoundRef { |
| 675 | + virtual auto setValue( std::string const &arg ) -> ParserResult = 0; |
683 | 676 | };
|
684 |
| - |
685 |
| - struct BoundFlagRefBase : BoundRefBase { |
686 |
| - auto isFlag() const -> bool override { return true; } |
687 |
| - |
688 |
| - auto setValue( std::string const &arg ) -> ParserResult override { |
689 |
| - bool flag = false; |
690 |
| - auto result = convertInto( arg, flag ); |
691 |
| - if( result ) |
692 |
| - setFlag( flag ); |
693 |
| - return result; |
694 |
| - } |
| 677 | + struct BoundFlagRefBase : BoundRef { |
| 678 | + virtual auto setFlag( bool flag ) -> ParserResult = 0; |
695 | 679 | };
|
696 | 680 |
|
697 | 681 | template<typename T>
|
698 |
| - struct BoundRef : BoundValueRefBase { |
| 682 | + struct BoundValueRef : BoundValueRefBase { |
699 | 683 | T &m_ref;
|
700 | 684 |
|
701 |
| - explicit BoundRef( T &ref ) : m_ref( ref ) {} |
| 685 | + explicit BoundValueRef( T &ref ) : m_ref( ref ) {} |
702 | 686 |
|
703 | 687 | auto setValue( std::string const &arg ) -> ParserResult override {
|
704 | 688 | return convertInto( arg, m_ref );
|
705 | 689 | }
|
706 | 690 | };
|
707 | 691 |
|
708 | 692 | template<typename T>
|
709 |
| - struct BoundRef<std::vector<T>> : BoundValueRefBase { |
| 693 | + struct BoundValueRef<std::vector<T>> : BoundValueRefBase { |
710 | 694 | std::vector<T> &m_ref;
|
711 | 695 |
|
712 |
| - explicit BoundRef( std::vector<T> &ref ) : m_ref( ref ) {} |
| 696 | + explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {} |
713 | 697 |
|
714 | 698 | auto isContainer() const -> bool override { return true; }
|
715 | 699 |
|
@@ -754,7 +738,7 @@ namespace detail {
|
754 | 738 |
|
755 | 739 | template<typename ArgType, typename L>
|
756 | 740 | inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
757 |
| - ArgType temp; |
| 741 | + ArgType temp{}; |
758 | 742 | auto result = convertInto( arg, temp );
|
759 | 743 | return !result
|
760 | 744 | ? result
|
@@ -819,16 +803,16 @@ namespace detail {
|
819 | 803 | class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
820 | 804 | protected:
|
821 | 805 | Optionality m_optionality = Optionality::Optional;
|
822 |
| - std::shared_ptr<BoundRefBase> m_ref; |
| 806 | + std::shared_ptr<BoundRef> m_ref; |
823 | 807 | std::string m_hint;
|
824 | 808 | std::string m_description;
|
825 | 809 |
|
826 |
| - explicit ParserRefImpl( std::shared_ptr<BoundRefBase> const &ref ) : m_ref( ref ) {} |
| 810 | + explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {} |
827 | 811 |
|
828 | 812 | public:
|
829 | 813 | template<typename T>
|
830 | 814 | ParserRefImpl( T &ref, std::string const &hint )
|
831 |
| - : m_ref( std::make_shared<BoundRef<T>>( ref ) ), |
| 815 | + : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ), |
832 | 816 | m_hint( hint )
|
833 | 817 | {}
|
834 | 818 |
|
@@ -869,18 +853,18 @@ namespace detail {
|
869 | 853 |
|
870 | 854 | class ExeName : public ComposableParserImpl<ExeName> {
|
871 | 855 | std::shared_ptr<std::string> m_name;
|
872 |
| - std::shared_ptr<BoundRefBase> m_ref; |
| 856 | + std::shared_ptr<BoundValueRefBase> m_ref; |
873 | 857 |
|
874 | 858 | template<typename LambdaT>
|
875 |
| - static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundRefBase> { |
| 859 | + static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> { |
876 | 860 | return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
877 | 861 | }
|
878 | 862 |
|
879 | 863 | public:
|
880 | 864 | ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
881 | 865 |
|
882 | 866 | explicit ExeName( std::string &ref ) : ExeName() {
|
883 |
| - m_ref = std::make_shared<BoundRef<std::string>>( ref ); |
| 867 | + m_ref = std::make_shared<BoundValueRef<std::string>>( ref ); |
884 | 868 | }
|
885 | 869 |
|
886 | 870 | template<typename LambdaT>
|
@@ -923,7 +907,10 @@ namespace detail {
|
923 | 907 | if( token.type != TokenType::Argument )
|
924 | 908 | return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
925 | 909 |
|
926 |
| - auto result = m_ref->setValue( remainingTokens->token ); |
| 910 | + assert( dynamic_cast<detail::BoundValueRefBase*>( m_ref.get() ) ); |
| 911 | + auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() ); |
| 912 | + |
| 913 | + auto result = valueRef->setValue( remainingTokens->token ); |
927 | 914 | if( !result )
|
928 | 915 | return InternalParseResult( result );
|
929 | 916 | else
|
@@ -996,20 +983,22 @@ namespace detail {
|
996 | 983 | if( remainingTokens && remainingTokens->type == TokenType::Option ) {
|
997 | 984 | auto const &token = *remainingTokens;
|
998 | 985 | if( isMatch(token.token ) ) {
|
999 |
| - if( m_ref->isFlag() ) { |
1000 |
| - auto result = m_ref->setFlag( true ); |
| 986 | + if( auto flagRef = dynamic_cast<detail::BoundFlagRefBase*>( m_ref.get() ) ) { |
| 987 | + auto result = flagRef->setFlag( true ); |
1001 | 988 | if( !result )
|
1002 | 989 | return InternalParseResult( result );
|
1003 | 990 | if( result.value() == ParseResultType::ShortCircuitAll )
|
1004 | 991 | return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
1005 | 992 | } else {
|
| 993 | + assert( dynamic_cast<detail::BoundValueRefBase*>( m_ref.get() ) ); |
| 994 | + auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() ); |
1006 | 995 | ++remainingTokens;
|
1007 | 996 | if( !remainingTokens )
|
1008 | 997 | return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
1009 | 998 | auto const &argToken = *remainingTokens;
|
1010 | 999 | if( argToken.type != TokenType::Argument )
|
1011 | 1000 | return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
1012 |
| - auto result = m_ref->setValue( argToken.token ); |
| 1001 | + auto result = valueRef->setValue( argToken.token ); |
1013 | 1002 | if( !result )
|
1014 | 1003 | return InternalParseResult( result );
|
1015 | 1004 | if( result.value() == ParseResultType::ShortCircuitAll )
|
|
0 commit comments