Commit 2c4ec6c7 authored by Kučera Petr RNDr. Ph.D.'s avatar Kučera Petr RNDr. Ph.D.
Browse files

EnumAnnotation split to EnumAnnotation and EnumOption

parent 12eb2e84
......@@ -25,11 +25,10 @@ enum class RELATION
Last = GEQ
};
SUBool::EnumAnnotation<RELATION> opt_relation("relation,r",
"Relation to check.",
{{RELATION::EQUAL, "eq", "equality"},
{RELATION::LEQ, "le", "less or equal"},
{RELATION::GEQ, "ge", "greater or equal"}});
const SUBool::EnumAnnotation<RELATION> kRelationAnnotation(
"RELATION", {{RELATION::EQUAL, "eq", "equality"},
{RELATION::LEQ, "le", "less or equal"},
{RELATION::GEQ, "ge", "greater or equal"}});
enum class COMPARE_KIND
{
......@@ -58,7 +57,7 @@ dump_config(const config_t &conf, unsigned level)
SUBool::logs.TLog(level) << "\tfile_left: " << conf.file_left << std::endl;
SUBool::logs.TLog(level) << "\tfile_right: " << conf.file_right << std::endl;
SUBool::logs.TLog(level) << "\tverbosity: " << conf.verbosity << std::endl;
opt_relation.DumpValue("\t", level, "relation", conf.relation);
kRelationAnnotation.DumpValue("\t", level, "relation", conf.relation);
SUBool::dump_enum_value(
"\t", level, "compare_kind", conf.compare_kind, compare_kind_names);
}
......@@ -69,14 +68,17 @@ parse_arguments(int argc, char *argv[])
config_t conf;
std::string relation;
std::string compare_kind;
auto opt_relation = SUBool::make_enum_option(
kRelationAnnotation, "relation,r", "Relation to check", conf.relation);
try
{
// options.positional_help("[input-left [input-right]]");
SUBool::PrgOptions opts;
opts.InputPair(
{&conf.file_left, "input-left"}, {&conf.file_right, "input-right"});
po::options_description desc("Configuration options");
desc.add(opt_relation.OptionDesc(&relation, conf.relation));
desc.add(opt_relation);
desc.add_options()("compare-kind,k",
po::value<std::string>(&compare_kind)
->default_value(compare_kind_names.at(
......@@ -101,7 +103,7 @@ parse_arguments(int argc, char *argv[])
}
try
{
conf.relation = opt_relation.Parse(relation);
conf.relation = opt_relation.Value();
conf.compare_kind =
SUBool::enum_of_name<COMPARE_KIND>(compare_kind, compare_kind_names);
}
......
......@@ -6,6 +6,9 @@
* Utility functions and structures used in programs.
*/
#ifndef __PRGUTIL_H
#define __PRGUTIL_H
#include <algorithm>
#include <array>
#include <fstream>
......@@ -270,34 +273,63 @@ namespace SUBool
std::string name;
std::string desc;
};
using ValueList = std::vector<Value>;
using iterator = typename ValueList::iterator;
using const_iterator = typename ValueList::const_iterator;
private:
std::vector<Value> mVA;
std::string mOptionName;
std::string mOptionHelp;
ValueList mValues;
std::string mName;
typename std::vector<Value>::const_iterator FindByName(
typename ValueList::const_iterator FindByName(
const std::string &name) const;
typename std::vector<Value>::const_iterator FindByEnumValue(
typename ValueList::const_iterator FindByEnumValue(
const T &enum_val) const;
public:
template <class InputIterator>
EnumAnnotation(std::string opt_name, std::string opt_desc,
InputIterator begin, InputIterator end);
EnumAnnotation(
std::string opt_name, std::string opt_desc, std::vector<Value> va);
EnumAnnotation(std::string opt_name, std::string opt_desc,
std::initializer_list<Value> va);
std::string enum_name, InputIterator begin, InputIterator end);
EnumAnnotation(std::string enum_name, ValueList va);
EnumAnnotation(std::string enum_name, std::initializer_list<Value> va);
boost::shared_ptr<po::option_description> OptionDesc(
std::string *value_bind, const T &default_value) const;
T Parse(const std::string &name) const;
const std::string &Name(const T &value) const;
void DumpValue(const std::string &line_prefix, unsigned level,
const std::string &label, const T &enum_value) const;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;
};
template <class T> class EnumOption
{
private:
const EnumAnnotation<T> &mEnumAnnotation;
std::string mOptionName;
std::string mOptionHelp;
T mDefaultValue;
std::string mOptionValue{};
boost::shared_ptr<po::option_description> mOptionDesc{};
public:
EnumOption(const EnumAnnotation<T> &enum_annotation, std::string opt_name,
std::string opt_help, const T &default_value);
boost::shared_ptr<po::option_description> Desc();
operator boost::shared_ptr<po::option_description>();
T Value() const;
};
template <class T, typename... Args>
EnumOption<T> make_enum_option(const EnumAnnotation<T> &ann, Args &&...arg);
} // namespace SUBool
inline unsigned
......@@ -350,43 +382,24 @@ SUBool::PrgOptions::Info() const
template <class T>
template <class InputIterator>
SUBool::EnumAnnotation<T>::EnumAnnotation(std::string opt_name,
std::string opt_desc, InputIterator begin, InputIterator end)
: mVA(begin, end), mOptionName(std::move(opt_name)),
mOptionHelp(std::move(opt_desc))
{
}
template <class T>
SUBool::EnumAnnotation<T>::EnumAnnotation(
std::string opt_name, std::string opt_desc, std::vector<Value> va)
: mVA(std::move(va)), mOptionName(std::move(opt_name)),
mOptionHelp(std::move(opt_desc))
std::string enum_name, InputIterator begin, InputIterator end)
: mValues(begin, end), mName(std::move(enum_name))
{
}
template <class T>
SUBool::EnumAnnotation<T>::EnumAnnotation(
std::string opt_name, std::string opt_desc, std::initializer_list<Value> va)
: mVA(std::move(va)), mOptionName(std::move(opt_name)),
mOptionHelp(std::move(opt_desc))
std::string enum_name, std::vector<Value> va)
: mValues(std::move(va)), mName(std::move(enum_name))
{
}
template <class T>
boost::shared_ptr<po::option_description>
SUBool::EnumAnnotation<T>::OptionDesc(
std::string *value_bind, const T &default_value) const
SUBool::EnumAnnotation<T>::EnumAnnotation(
std::string enum_name, std::initializer_list<Value> va)
: mValues(std::move(va)), mName(std::move(enum_name))
{
std::string help = mOptionHelp + " Possible values:";
for (const auto &val : mVA)
{
help += '\n';
help += val.name + " = " + val.desc;
}
return boost::make_shared<po::option_description>(mOptionName.c_str(),
po::value<std::string>(value_bind)->default_value(Name(default_value)),
help.c_str());
}
template <class T>
......@@ -394,10 +407,9 @@ T
SUBool::EnumAnnotation<T>::Parse(const std::string &name) const
{
auto i_val = FindByName(name);
if (i_val == mVA.end())
if (i_val == mValues.end())
{
std::string err =
"Failed to find value " + name + " for option " + mOptionName;
std::string err = "Failed to find value " + name + " in enum " + mName;
throw ParseException("EnumAnnotation::Parse", err);
}
return i_val->value;
......@@ -408,10 +420,9 @@ const std::string &
SUBool::EnumAnnotation<T>::Name(const T &value) const
{
auto i_name = FindByEnumValue(value);
if (i_name == mVA.end())
if (i_name == mValues.end())
{
std::string err =
"Failed to find name for a value of option " + mOptionName;
std::string err = "Failed to find name for a value in enum " + mName;
throw ParseException("EnumAnnotation::Parse", err);
}
return i_name->name;
......@@ -422,7 +433,7 @@ auto
SUBool::EnumAnnotation<T>::FindByName(const std::string &name) const ->
typename std::vector<Value>::const_iterator
{
return std::find_if(mVA.begin(), mVA.end(),
return std::find_if(mValues.begin(), mValues.end(),
[&name](const auto &val) { return name == val.name; });
}
......@@ -431,7 +442,7 @@ auto
SUBool::EnumAnnotation<T>::FindByEnumValue(const T &enum_val) const ->
typename std::vector<Value>::const_iterator
{
return std::find_if(mVA.begin(), mVA.end(),
return std::find_if(mValues.begin(), mValues.end(),
[&enum_val](const auto &val) { return enum_val == val.value; });
}
......@@ -442,3 +453,98 @@ SUBool::EnumAnnotation<T>::DumpValue(const std::string &line_prefix,
{
dump_value(line_prefix, level, label, Name(enum_value));
}
template <class T>
auto
SUBool::EnumAnnotation<T>::begin() -> iterator
{
return mValues.begin();
}
template <class T>
auto
SUBool::EnumAnnotation<T>::end() -> iterator
{
return mValues.end();
}
template <class T>
auto
SUBool::EnumAnnotation<T>::begin() const -> const_iterator
{
return mValues.begin();
}
template <class T>
auto
SUBool::EnumAnnotation<T>::end() const -> const_iterator
{
return mValues.end();
}
template <class T>
auto
SUBool::EnumAnnotation<T>::cbegin() const -> const_iterator
{
return mValues.begin();
}
template <class T>
auto
SUBool::EnumAnnotation<T>::cend() const -> const_iterator
{
return mValues.end();
}
template <class T>
SUBool::EnumOption<T>::EnumOption(const EnumAnnotation<T> &enum_annotation,
std::string opt_name, std::string opt_help, const T &default_value)
: mEnumAnnotation(enum_annotation), mOptionName(std::move(opt_name)),
mOptionHelp(std::move(opt_help)), mDefaultValue(default_value)
{
}
template <class T>
boost::shared_ptr<po::option_description>
SUBool::EnumOption<T>::Desc()
{
if (mOptionDesc)
{
return mOptionDesc;
}
std::string help = mOptionHelp + " Possible values:";
for (const auto &val : mEnumAnnotation)
{
help += '\n';
help += val.name + " = " + val.desc;
}
return mOptionDesc =
boost::make_shared<po::option_description>(mOptionName.c_str(),
po::value<std::string>(&mOptionValue)
->default_value(mEnumAnnotation.Name(mDefaultValue)),
help.c_str());
}
template <class T>
SUBool::EnumOption<T>::operator boost::shared_ptr<po::option_description>()
{
return Desc();
}
template <class T>
T
SUBool::EnumOption<T>::Value() const
{
return mEnumAnnotation.Parse(mOptionValue);
}
template <class T, typename... Args>
auto
SUBool::make_enum_option(const EnumAnnotation<T> &ann, Args &&...args)
-> EnumOption<T>
{
return EnumOption<T>(ann, std::forward<Args>(args)...);
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment