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

EnumOption in enum_opt.h, refactoring

parent d76640b1
......@@ -9,6 +9,7 @@
#include "cnfcompare.h"
#include "cnfutil.h"
#include "cpuutil.h"
#include "enum_opt.h"
#include "logstream.h"
#include "normalform.h"
#include "prgutil.h"
......
/*
* Project SUBool
* Petr Kucera, 2018
* Petr Kucera, 2021
*/
/**@file enum.h
* Utility functions and structures related to annotated enums.
......@@ -16,8 +16,9 @@
namespace SUBool
{
template <class T>
T
[[deprecated("Use EnumAnnotation")]] T
enum_of_int(unsigned val)
{
if (val > static_cast<unsigned>(T::Last))
......@@ -28,7 +29,7 @@ namespace SUBool
}
template <class E, size_t S>
E
[[deprecated("Use EnumAnnotation")]] E
enum_of_name(const std::string &val, const std::array<std::string, S> &names)
{
auto i = std::find(names.begin(), names.end(), val);
......@@ -50,7 +51,7 @@ namespace SUBool
};
template <class Enum, class Names>
void
[[deprecated("Use EnumAnnotation")]] void
dump_enum_value(const std::string &line_prefix, unsigned level,
const std::string &name, const Enum &enum_value, const Names &names)
{
......@@ -62,9 +63,10 @@ namespace SUBool
template <class T> class EnumAnnotation
{
public:
using enum_t = T;
struct Value
{
T value;
enum_t value;
std::string name;
std::string desc;
};
......@@ -88,10 +90,10 @@ namespace SUBool
EnumAnnotation(std::string enum_name, ValueList va);
EnumAnnotation(std::string enum_name, std::initializer_list<Value> va);
T Parse(const std::string &name) const;
const std::string &Name(const T &value) const;
enum_t Parse(const std::string &name) const;
const std::string &Name(const enum_t &value) const;
void DumpValue(const std::string &line_prefix, unsigned level,
const std::string &label, const T &enum_value) const;
const std::string &label, const enum_t &enum_value) const;
iterator begin();
iterator end();
......@@ -128,8 +130,8 @@ SUBool::EnumAnnotation<T>::EnumAnnotation(
}
template <class T>
T
SUBool::EnumAnnotation<T>::Parse(const std::string &name) const
auto
SUBool::EnumAnnotation<T>::Parse(const std::string &name) const -> enum_t
{
auto i_val = FindByName(name);
if (i_val == mValues.end())
......@@ -164,7 +166,7 @@ SUBool::EnumAnnotation<T>::FindByName(const std::string &name) const ->
template <class T>
auto
SUBool::EnumAnnotation<T>::FindByEnumValue(const T &enum_val) const ->
SUBool::EnumAnnotation<T>::FindByEnumValue(const enum_t &enum_val) const ->
typename std::vector<Value>::const_iterator
{
return std::find_if(mValues.begin(), mValues.end(),
......@@ -174,7 +176,7 @@ SUBool::EnumAnnotation<T>::FindByEnumValue(const T &enum_val) const ->
template <class T>
void
SUBool::EnumAnnotation<T>::DumpValue(const std::string &line_prefix,
unsigned level, const std::string &label, const T &enum_value) const
unsigned level, const std::string &label, const enum_t &enum_value) const
{
logs.DumpValue(line_prefix, level, label, Name(enum_value));
}
......
/*
* Project SUBool
* Petr Kucera, 2021
*/
/**@file enum_opt.h
* Program option for selecting an enum value.
*/
#ifndef __ENUM_OPT_H
#define __ENUM_OPT_H
#include <boost/program_options.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include "enum.h"
#include "sbexception.h"
namespace po = boost::program_options;
namespace SUBool
{
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
// Template and inline functions implementation
//
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
......@@ -186,30 +186,6 @@ namespace SUBool
void Add(const po::options_description &desc);
};
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
// Template and inline functions implementation
......@@ -262,55 +238,4 @@ SUBool::PrgOptions::Info() const
std::cout << mPrgName << " - " << mPrgDesc << std::endl;
}
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