3#include <boost/program_options.hpp>
4#include <boost/program_options/options_description.hpp>
5#include <boost/program_options/positional_options.hpp>
6#include <boost/program_options/variables_map.hpp>
16#include <unordered_map>
21 namespace po = boost::program_options;
34 template <
typename T,
typename =
void>
40 struct IsString<T, std::void_t<decltype(std::string_view{ std::declval<T>() })>> : std::true_type
48 template <
typename Type>
51 template <
typename Type>
63 template <
typename OptionType>
65 const std::string& option_desc,
66 std::optional<OptionType> defaultValue = {}) ->
decltype(
auto)
70 std::cerr <<
"ERROR: option has been already defined!" << std::endl;
73 auto option = std::make_unique<Option<OptionType>>(optionName, defaultValue.value_or(OptionType{}),
this);
74 option->add(option_desc, not defaultValue.has_value());
76 return OptionHandle{ std::move(option) };
79 auto verify(
int argc,
char** argv) -> bool;
100 virtual void retrieve(
const po::variables_map& varMap) = 0;
103 template <
typename Type>
113 :
name_{ std::move(name) }
114 ,
value_{ std::move(defaultValue) }
117 if (
auto end =
name_.find(
','))
119 key_ = name_.substr(0, end);
128 void add(
const std::string& desc,
bool is_requried =
false)
130 auto& po_desc =
program_->get_desc_ref();
133 auto desc_full = fmt::format(
"{} [ required ]", desc);
136 desc_full = fmt::format(
"{} [ = {} ]", desc,
value_);
139 desc_full = fmt::format(
"{} [ = {:?} ]", desc,
value_);
145 po_desc.add_options()(
name_.c_str(), desc_full.c_str());
149 po_desc.add_options()(
name_.c_str(), po::value<Type>(), desc_full.c_str());
159 void retrieve(
const po::variables_map& varMap)
override
161 if (varMap.count(
key_) != 0U)
175 const auto error_msg = fmt::format(R
"(Program option "--{}" is required! )", name_);
176 throw std::runtime_error(error_msg);
196 template <
typename Type>
210 return std::move(*
this);
215 std::unique_ptr<Option<Type>>
option_ =
nullptr;
auto operator=(const OptionConcept &) -> OptionConcept &=delete
virtual ~OptionConcept()=default
OptionConcept(OptionConcept &&)=delete
OptionConcept(const OptionConcept &)=delete
virtual void retrieve(const po::variables_map &varMap)=0
auto operator=(OptionConcept &&) -> OptionConcept &=delete
auto operator->() -> Option< Type > *
std::unique_ptr< Option< Type > > option_
auto make_positional(int pos) -> OptionHandle< Type > &&
OptionHandle(std::unique_ptr< Option< Type > > option)
ProgramOptions * program_
void add(const std::string &desc, bool is_requried=false)
Option(const Option &)=delete
auto is_positional() const -> bool
auto operator=(Option &&) -> Option &=delete
void set_required(bool p_rq=true)
auto operator=(const Option &) -> Option &=delete
auto is_required() const -> bool
void retrieve(const po::variables_map &varMap) override
void as_positional(int option)
Option(std::string name, Type defaultValue, ProgramOptions *program)
auto get_desc_ref() -> auto &
po::options_description desc_
ProgramOptions(const std::string &desc)
auto get_posDescRef() -> auto &
auto verify(int argc, char **argv) -> bool
po::positional_options_description pos_desc_
void delete_option(const std::string &optionName)
std::unordered_map< std::string, OptionConcept * > registries_
po::variables_map varMap_
auto create_option(const std::string &optionName, const std::string &option_desc, std::optional< OptionType > defaultValue={}) -> decltype(auto)
constexpr bool IsString_v