AmpGen 2.1
Loading...
Searching...
No Matches
Property.h
Go to the documentation of this file.
1#ifndef AMPGEN_PROPERTY_H
2#define AMPGEN_PROPERTY_H 1
3#include <stddef.h>
4#include <iostream>
5#include <sstream>
6#include <stdexcept>
7#include <string>
8#include <utility>
9#include <vector>
10#include <iomanip>
11#include <map>
12#include <cstring>
13#include <string_view>
14
15#include "AmpGen/MsgService.h"
17#include "AmpGen/Utilities.h"
18#include "AmpGen/MetaUtils.h"
20
21namespace AmpGen {
25 template <typename value_t> class Property {
26 protected:
27 std::string m_name;
28 std::string m_helpString;
29 value_t m_value;
30
31 public:
32 template <typename T>
33 Property(T *parent, const std::string &name, const value_t &def = value_t(), const std::string_view &helpString = "")
34 : m_name(name), m_helpString(helpString), m_value(def) {
35 setFromOptionsParser();
36 if constexpr(std::has_virtual_destructor<T>::value and not std::is_const_v<T>) {
37 if(parent != nullptr and dynamic_cast<ConfigurableBase *>(parent)) dynamic_cast<ConfigurableBase *>(parent)->registerParameter(name);
38 // std::cout << name << " " << def << " " << helpString << std::endl;
39 }
40 if(OptionsParser::printHelp()) help(def);
41 DEBUG(*this);
42 }
43 Property(const std::nullptr_t /*parent*/, const std::string &name, const value_t &def = value_t(), const std::string_view &helpString = "")
44 : m_name(name), m_helpString(helpString), m_value(def) {
45 setFromOptionsParser();
46 if(OptionsParser::printHelp()) help(def);
47 DEBUG(*this);
48 }
49 void set(const value_t &val) { m_value = val; }
50 template <typename T> bool operator==(const T &other) const { return m_value == other; }
51 template <typename T> bool operator!=(const T &other) const { return m_value != other; }
52 operator const value_t &() const { return m_value; }
53 operator value_t &() { return m_value; }
54 const value_t &value() const { return m_value; }
55 const std::string &name() const { return m_name; }
56 template <typename T> friend std::ostream &operator<<(std::ostream &os, const Property<T> &np);
57 bool setFromStrings(const std::vector<std::string> &vsl) {
58 bool status = true;
59 if constexpr(isVector<value_t>::value) {
60 m_value.resize(vsl.size());
61 for(unsigned int i = 0; i < vsl.size(); i++) {
63 if(status == false) {
64 ERROR("Failed to parse token: " << vsl[i] << " for parameter: " << m_name);
65 return false;
66 }
67 }
68 } else if constexpr(isTuple<value_t>::value) {
69 for_each_with_counter(m_value, [this, vsl](auto &f, unsigned i) {
70 bool status = true;
71 using basic_t = typename std::remove_const<typename std::remove_reference<decltype(f)>::type>::type;
72 *const_cast<basic_t *>(&f) = lexical_cast<basic_t>(vsl[i], status);
73 if(!status) { ERROR("Failed to parse token: " << vsl[i] << " for parameter: " << this->m_name); }
74 });
75 } else {
76 if(vsl.size() != 1) {
77 ERROR("Constructing parameter: " << m_name << " only one argument expected, but " << vsl.size() - 1 << " found");
78 for(auto const &v : vsl) ERROR(v);
79 return false;
80 }
81 m_value = lexical_cast<value_t>(vsl[0], status);
82 if(status == false) {
83 ERROR("Failed to parse token: " << vsl[0] << " for parameter: " << m_name);
84 return false;
85 }
86 }
87 return status;
88 }
89
90 private:
91 void help(const value_t &def) {
92 std::string type = type_string<value_t>();
93 type = replaceAll(type, "AmpGen::", "");
94 if(std::is_same_v<value_t, std::string>) type = "string";
95 if(std::is_same_v<value_t, std::vector<std::string>>) type = "strings";
96 std::cout << " " << bold_on << std::left << std::setw(27) << m_name << bold_off << std::setw(20) << "[" + type + "]";
97 auto tokens = split(m_helpString, '\n');
98 if(tokens.size() == 0) std::cout << std::endl;
99 for(size_t i = 0; i < tokens.size(); ++i) {
100 if(i == 0) {
101 std::cout << tokens[i];
102 if constexpr(isVector<value_t>::value) {
103 if(def != value_t()) std::cout << " (default = {" << vectorToString(def, ",") << "})";
104 } else if constexpr(isTuple<value_t>::value) {
105 if(def != value_t()) std::cout << " (default = [" << tupleToString(def, ",") << "])";
106 } else {
107 if(def != value_t()) std::cout << " (default = " << def << ")";
108 }
109 std::cout << std::endl;
110 } else
111 std::cout << std::string(48, ' ') << tokens[i] << std::endl;
112 }
113 }
114 bool setFromOptionsParser() {
115 auto parser = OptionsParser::getMe();
116 auto line = parser->find(m_name);
117 if(line == parser->end()) return false;
118 std::vector<std::string> vsl = line->second;
119 vsl.erase(vsl.begin());
120 return setFromStrings(vsl);
121 }
122 };
123 template <typename T> std::ostream &operator<<(std::ostream &os, const Property<T> &np);
124 template <typename... T> std::string helpStringOptions(const std::string &header, const T &...args);
125 template <typename T> bool operator==(const T &val, const Property<T> &prop) { return val == prop.value(); }
126};
127
128template <typename T> std::ostream &AmpGen::operator<<(std::ostream &os, const AmpGen::Property<T> &np) {
129 os << np.name() << " = ";
130 if constexpr(!isVector<T>::value)
131 os << np.m_value;
132 else {
133 for(unsigned i{0}; i != np.m_value.size(); ++i) os << np.m_value[i] << " ";
134 }
135 return os;
136}
137
138template <typename... T> std::string AmpGen::helpStringOptions(const std::string &header, const T &...args) {
139 std::stringstream rt;
140 rt << header;
141 for_each(std::make_tuple(args...), [&rt](const auto &f) mutable { rt << "\n\033[3m " << f.first << "\033[0m: " << f.second; });
142 return rt.str();
143}
144#endif
static OptionsParser * getMe()
static bool printHelp()
Properties are configurable characteristics of objects that will at some point inherit from a base cl...
Definition Property.h:25
Property(T *parent, const std::string &name, const value_t &def=value_t(), const std::string_view &helpString="")
Definition Property.h:33
const value_t & value() const
Definition Property.h:54
void set(const value_t &val)
Definition Property.h:49
bool operator!=(const T &other) const
Definition Property.h:51
bool operator==(const T &other) const
Definition Property.h:50
std::string m_helpString
Definition Property.h:28
const std::string & name() const
Definition Property.h:55
std::string m_name
Definition Property.h:27
value_t m_value
Definition Property.h:29
friend std::ostream & operator<<(std::ostream &os, const Property< T > &np)
bool setFromStrings(const std::vector< std::string > &vsl)
Definition Property.h:57
Property(const std::nullptr_t, const std::string &name, const value_t &def=value_t(), const std::string_view &helpString="")
Definition Property.h:43
#define ERROR(X)
Used for printing errors messages, and will always be printed.
Definition MsgService.h:85
#define DEBUG(X)
Used for printing verbose debugging messages, only if DEBUGLEVEL is defined.
Definition MsgService.h:69
std::string tupleToString(const tuple_t &tuple, const std::string &delim)
Definition Utilities.h:32
std::string vectorToString(iterator_type begin, iterator_type end, const std::string &delim, functor_type fcn)
Definition Utilities.h:24
std::vector< std::string > split(const std::string &, char, bool=true)
std::ostream & operator<<(std::ostream &os, const CompiledExpressionBase &expression)
std::string helpStringOptions(const std::string &header, const T &...args)
Definition Property.h:138
std::ostream & bold_on(std::ostream &)
std::ostream & bold_off(std::ostream &)
std::string replaceAll(const std::string &input, const std::string &toReplace, const std::string &replaceWith)
std::string type_string()
Utility classes for compile-time metaprogramming, such as identifying the types of arguments for gene...
Definition MetaUtils.h:17
Expression operator==(const Expression &A, const Expression &B)
return_type lexical_cast(const std::string &word, bool &status)
std::enable_if_t< I==sizeof...(Tp), void > for_each(std::tuple< Tp... > &, FuncT)
Definition MetaUtils.h:36