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

EnumAnnotation

parent 06fb871a
......@@ -13,6 +13,10 @@
#include "normalform.h"
#include "prgutil.h"
const std::string SUBool::kPrgName = "cnfcomp";
const std::string SUBool::kPrgDesc =
"compare two functions represented by CNF formulas";
enum class RELATION
{
EQUAL,
......@@ -21,12 +25,11 @@ enum class RELATION
Last = GEQ
};
const std::array<std::string, static_cast<size_t>(RELATION::Last) + 1>
relation_names = {"eq", "le", "ge"};
const std::string SUBool::kPrgName = "cnfcomp";
const std::string SUBool::kPrgDesc =
"compare two functions represented by CNF formulas";
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"}});
enum class COMPARE_KIND
{
......@@ -55,8 +58,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;
SUBool::dump_enum_value(
"\t", level, "relation", conf.relation, relation_names);
opt_relation.DumpValue("\t", level, "relation", conf.relation);
SUBool::dump_enum_value(
"\t", level, "compare_kind", conf.compare_kind, compare_kind_names);
}
......@@ -74,11 +76,8 @@ parse_arguments(int argc, char *argv[])
opts.InputPair(
{&conf.file_left, "input-left"}, {&conf.file_right, "input-right"});
po::options_description desc("Configuration options");
desc.add_options()("relation,r",
po::value<std::string>(&relation)->default_value(
relation_names.at(static_cast<size_t>(conf.relation))),
"Relation to check. eq=equality, le=less than or equal, ge=greater "
"than or equal.")("compare-kind,k",
desc.add(opt_relation.OptionDesc(&relation, conf.relation));
desc.add_options()("compare-kind,k",
po::value<std::string>(&compare_kind)
->default_value(compare_kind_names.at(
static_cast<size_t>(conf.compare_kind))),
......@@ -102,7 +101,7 @@ parse_arguments(int argc, char *argv[])
}
try
{
conf.relation = SUBool::enum_of_name<RELATION>(relation, relation_names);
conf.relation = opt_relation.Parse(relation);
conf.compare_kind =
SUBool::enum_of_name<COMPARE_KIND>(compare_kind, compare_kind_names);
}
......
......@@ -6,8 +6,6 @@
* Utility functions and structures used in programs.
*/
#include <boost/smart_ptr/make_shared.hpp>
#include "prgutil.h"
#include "version.h"
......
......@@ -13,6 +13,7 @@
#include <sstream>
#include <boost/program_options.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include "logstream.h"
#include "sbexception.h"
......@@ -260,6 +261,43 @@ namespace SUBool
void Add(const po::options_description &desc);
};
template <class T> class EnumAnnotation
{
public:
struct Value
{
T value;
std::string name;
std::string desc;
};
private:
std::vector<Value> mVA;
std::string mOptionName;
std::string mOptionHelp;
typename std::vector<Value>::const_iterator FindByName(
const std::string &name) const;
typename std::vector<Value>::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);
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;
};
} // namespace SUBool
inline unsigned
......@@ -309,3 +347,98 @@ SUBool::PrgOptions::Info() const
{
std::cout << mPrgName << " - " << mPrgDesc << std::endl;
}
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))
{
}
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))
{
}
template <class T>
boost::shared_ptr<po::option_description>
SUBool::EnumAnnotation<T>::OptionDesc(
std::string *value_bind, const T &default_value) const
{
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>
T
SUBool::EnumAnnotation<T>::Parse(const std::string &name) const
{
auto i_val = FindByName(name);
if (i_val == mVA.end())
{
std::string err =
"Failed to find value " + name + " for option " + mOptionName;
throw ParseException("EnumAnnotation::Parse", err);
}
return i_val->value;
}
template <class T>
const std::string &
SUBool::EnumAnnotation<T>::Name(const T &value) const
{
auto i_name = FindByEnumValue(value);
if (i_name == mVA.end())
{
std::string err =
"Failed to find name for a value of option " + mOptionName;
throw ParseException("EnumAnnotation::Parse", err);
}
return i_name->name;
}
template <class T>
auto
SUBool::EnumAnnotation<T>::FindByName(const std::string &name) const ->
typename std::vector<Value>::const_iterator
{
return std::find_if(mVA.begin(), mVA.end(),
[&name](const auto &val) { return name == val.name; });
}
template <class T>
auto
SUBool::EnumAnnotation<T>::FindByEnumValue(const T &enum_val) const ->
typename std::vector<Value>::const_iterator
{
return std::find_if(mVA.begin(), mVA.end(),
[&enum_val](const auto &val) { return enum_val == val.value; });
}
template <class T>
void
SUBool::EnumAnnotation<T>::DumpValue(const std::string &line_prefix,
unsigned level, const std::string &label, const T &enum_value) const
{
dump_value(line_prefix, level, label, Name(enum_value));
}
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