Awali
Another Weighted Automata library
option.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2023 Sylvain Lombardy, Victor Marsault, Jacques Sakarovitch
3 //
4 // Awali is a free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef AWALI_DYN_OPTIONS_OPTION_HH
18 #define AWALI_DYN_OPTIONS_OPTION_HH
19 
20 #include <functional>
21 #include <typeinfo>
22 #include <unordered_map>
23 
26 #include <awali/common/enums.hh>
27 #include <awali/common/priority.hh>
28 #include <awali/dyn/core/any.hh>
30 
31 namespace awali { namespace dyn { namespace internal {
32 
33  template <typename T>
34  struct acceptor_t
35  {
36  virtual bool is_valid(T const&) { return true; }
37  virtual std::string acceptable_values()
38  {
39  return ("any value of type "
40  + awali::internal::demangle(typeid(T).name()));
41  }
42  virtual ~acceptor_t() = default;
43  };
44 
45  template <>
46  struct acceptor_t<bool>
47  {
48  virtual bool is_valid(bool const&) { return true; }
49  std::string acceptable_values() { return ("boolean"); }
50  virtual ~acceptor_t() = default;
51  };
52 
53  template <>
54  struct acceptor_t<std::string>
55  {
56  virtual bool is_valid(std::string const&) { return true; }
57  virtual std::string acceptable_values() { return ("any string"); }
58  virtual ~acceptor_t() = default;
59  };
60 
64  extern size_t next_id;
65 
66  using stov_t = std::function<option_value_pair_t(std::string const&)>;
67  /* stov= string to value*/
68 
69  stov_t get_stov(std::string const&);
70  void register_stov(std::string, stov_t);
71 
72  template <typename T>
73  class option_t
74  {
75  public:
76  using value_t = T;
77  const size_t id;
78 
79  private:
80  const std::string option_name;
81  acceptor_t<value_t> acceptor;
82  value_t default_value;
83  bool default_set_by_user = false;
84 
85  option_t(option_t<T> other, value_t def)
86  : id(other.id)
87  , option_name(other.option_name)
88  , acceptor(other.acceptor)
89  , default_value(other.default_set_by_user ? other.def : def)
90  , default_set_by_user(other.was_user_set)
91  {}
92 
93  template <typename X, typename P>
95  {
96  throw std::runtime_error("Wrong value type for option " + option_name
97  + ". Expected: " + acceptor.acceptable_values()
98  + ".");
99  }
100 
101  template <typename X = T, typename P>
103  {
104  return make(std::string(value), priority::value);
105  }
106 
107  template <typename X = T, typename P>
108  auto make(std::string const& value, priority::THREE<P>) ->
110  internal::option_value_pair_t>::type
111  {
112  if (value == "default")
113  return {id, default_value};
114  if (value == "true")
115  return {id, true};
116  if (value == "false")
117  return {id, false};
118  throw std::runtime_error("Wrong value for option " + option_name
119  + ". Expected a bool, got an std::string, thus expected one of the following values: \"default\", \"true\", \"false\".");
120  }
121 
122  template <typename X = T, typename P>
123  auto make(std::string const& value, priority::THREE<P>)
124  -> decltype(awali::internal::make_enum<X>(value),
125  internal::option_value_pair_t(id, default_value))
126  {
127  if (value == "default")
128  return {id, default_value};
129  return {id, awali::internal::make_enum<X>(value)};
130  }
131 
132 
133  template <typename P>
134  internal::option_value_pair_t make(const T& value, priority::FOUR<P>)
135  {
136  if (!acceptor.is_valid(value))
137  make(value, priority::one);
138  return {id, value};
139  }
140 
141 
142  public:
143  option_t(std::string name, T def, acceptor_t<T> acc = acceptor_t<T>())
144  : id(internal::next_id++)
145  , option_name(std::move(name))
146  , acceptor(acc)
147  , default_value(def)
148  {
149  register_stov(option_name,
150  [this](std::string const& val) { return (*this) = val; });
151  }
152 
153  bool acceptable(T value) { return acceptor(value); }
154 
156  {
158  return {id, true};
159  throw std::runtime_error(
160  "Using option without argument is only possible if they expect "
161  "boolean values.");
162  }
163 
164 
184  {
185  return option_t(*this, new_default_value);
186  }
187 
188 
189  /* Globally sets the default value of this option.
190  */
191  void set_default_value(value_t new_default_value)
192  {
193  default_value = new_default_value;
194  default_set_by_user = true;
195  }
196 
197  value_t get_default_value() { return default_value; }
198 
199  public:
200  template <typename X>
202  {
203  return make(value, priority::value);
204  }
205 
210  value_t of_string(std::string const& str)
211  {
213  return (value_t) pair.value;
214  }
215  };
216 
217 }}} // namespace awali::dyn::internal
218 
219 
221 
222 
223 #endif
Definition: option.hh:74
value_t of_string(std::string const &str)
Create of value of the type expected by this option_t, from string str.
Definition: option.hh:210
const size_t id
Definition: option.hh:77
option_t(std::string name, T def, acceptor_t< T > acc=acceptor_t< T >())
Definition: option.hh:143
value_t get_default_value()
Definition: option.hh:197
T value_t
Definition: option.hh:76
internal::option_value_pair_t operator=(const X &value)
Definition: option.hh:201
void set_default_value(value_t new_default_value)
Definition: option.hh:191
bool acceptable(T value)
Definition: option.hh:153
option_t< value_t > with_default_value(value_t new_default_value)
Creates a phony option_t that overrides system default value (but not user defined default,...
Definition: option.hh:183
stov_t get_stov(std::string const &)
void register_stov(std::string, stov_t)
size_t next_id
Global variable that assign a unique identifier to each instance of option<T> independentely of type ...
std::function< option_value_pair_t(std::string const &)> stov_t
Definition: option.hh:66
std::string demangle(const char *name)
Definition: demangle.hxx:46
static constexpr TOP< void > value
Definition: priority.hh:93
static constexpr ONE< void > one
Definition: priority.hh:76
Definition: priority.hh:52
pair_automaton< Aut > pair(const Aut &aut, bool keep_initials=false)
Definition: synchronizing_word.hh:266
Main namespace of Awali.
Definition: ato.hh:22
std::string acceptable_values()
Definition: option.hh:49
virtual bool is_valid(bool const &)
Definition: option.hh:48
virtual std::string acceptable_values()
Definition: option.hh:57
virtual bool is_valid(std::string const &)
Definition: option.hh:56
Definition: option.hh:35
virtual bool is_valid(T const &)
Definition: option.hh:36
virtual std::string acceptable_values()
Definition: option.hh:37