#pragma once #include #include #include #include #include namespace NLastGetopt { class TOpt; class TOpts; class TOptsParser; class TOptsParseResult; /// base of all getopt exceptions class TException: public yexception { }; /// TOpts configuration is incorrect class TConfException: public TException { }; /// User passed incorrect arguments, parsing failed /// Note: use `throw TUsageException()` instead of `ythrow TUsageException()` to prevent appearence of stacktrace /// and location of the `ythrow` statment in error messages. class TUsageException: public TException { }; struct IOptHandler { virtual void HandleOpt(const TOptsParser* parser) = 0; virtual ~IOptHandler() = default; }; namespace NPrivate { template class THandlerFunctor0 : public IOptHandler { TpFunc Func_; public: THandlerFunctor0(TpFunc func) : Func_(func) { } void HandleOpt(const TOptsParser*) override { Func_(); } }; template class THandlerFunctor1 : public IOptHandler { TpFunc Func_; const TpArg Def_; const bool HasDef_; public: THandlerFunctor1(TpFunc func) : Func_(func) , Def_() , HasDef_(false) { } template THandlerFunctor1(const TpFunc& func, const T& def) : Func_(func) , Def_(def) , HasDef_(true) { } void HandleOpt(const TOptsParser* parser) override; }; template class THandlerFunctor1 : public IOptHandler { TpFunc Func_; public: THandlerFunctor1(TpFunc func) : Func_(func) { } void HandleOpt(const TOptsParser* parser) override { Func_(parser); } }; template class TStoreResultFunctor { private: T* Target_; public: TStoreResultFunctor(T* target) : Target_(target) { } void operator()(const TpVal& val) { *Target_ = val; } }; template class TStoreMappedResultFunctor { private: TpTarget* Target_; const TpFunc Func_; public: TStoreMappedResultFunctor(TpTarget* target, const TpFunc& func) : Target_(target) , Func_(func) { } void operator()(const TpVal& val) { *Target_ = Func_(val); } }; template class TStoreValueFunctor { T* Target; const TpVal Value; public: template TStoreValueFunctor(T* target, const TpArg& value) : Target(target) , Value(value) { } void operator()(const TOptsParser*) { *Target = Value; } }; TString OptToString(char c); TString OptToString(const TString& longOption); TString OptToString(const TOpt* opt); template inline T OptFromStringImpl(const TStringBuf& value) { return FromString(value); } template <> inline TStringBuf OptFromStringImpl(const TStringBuf& value) { return value; } template <> inline const char* OptFromStringImpl(const TStringBuf& value) { return value.data(); } template T OptFromString(const TStringBuf& value, const TSomeOpt opt) { try { return OptFromStringImpl(value); } catch (...) { throw TUsageException() << "failed to parse opt " << OptToString(opt) << " value " << TString(value).Quote() << ": " << CurrentExceptionMessage(); } } // wrapper of FromString that prints nice message about option used template T OptFromString(const TStringBuf& value, const TSomeOpt opt); } }