| 9374 | } |
| 9375 | |
| 9376 | class Opt : public ParserRefImpl<Opt> { |
| 9377 | protected: |
| 9378 | std::vector<std::string> m_optNames; |
| 9379 | |
| 9380 | public: |
| 9381 | template<typename LambdaT> |
| 9382 | explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {} |
| 9383 | |
| 9384 | explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {} |
| 9385 | |
| 9386 | template<typename LambdaT> |
| 9387 | Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} |
| 9388 | |
| 9389 | template<typename T> |
| 9390 | Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} |
| 9391 | |
| 9392 | auto operator[]( std::string const &optName ) -> Opt & { |
| 9393 | m_optNames.push_back( optName ); |
| 9394 | return *this; |
| 9395 | } |
| 9396 | |
| 9397 | auto getHelpColumns() const -> std::vector<HelpColumns> { |
| 9398 | std::ostringstream oss; |
| 9399 | bool first = true; |
| 9400 | for( auto const &opt : m_optNames ) { |
| 9401 | if (first) |
| 9402 | first = false; |
| 9403 | else |
| 9404 | oss << ", "; |
| 9405 | oss << opt; |
| 9406 | } |
| 9407 | if( !m_hint.empty() ) |
| 9408 | oss << " <" << m_hint << ">"; |
| 9409 | return { { oss.str(), m_description } }; |
| 9410 | } |
| 9411 | |
| 9412 | auto isMatch( std::string const &optToken ) const -> bool { |
| 9413 | auto normalisedToken = normaliseOpt( optToken ); |
| 9414 | for( auto const &name : m_optNames ) { |
| 9415 | if( normaliseOpt( name ) == normalisedToken ) |
| 9416 | return true; |
| 9417 | } |
| 9418 | return false; |
| 9419 | } |
| 9420 | |
| 9421 | using ParserBase::parse; |
| 9422 | |
| 9423 | auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override { |
| 9424 | auto validationResult = validate(); |
| 9425 | if( !validationResult ) |
| 9426 | return InternalParseResult( validationResult ); |
| 9427 | |
| 9428 | auto remainingTokens = tokens; |
| 9429 | if( remainingTokens && remainingTokens->type == TokenType::Option ) { |
| 9430 | auto const &token = *remainingTokens; |
| 9431 | if( isMatch(token.token ) ) { |
| 9432 | if( m_ref->isFlag() ) { |
| 9433 | auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() ); |