Awali
Another Weighted Automata library
option.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2021 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 <unordered_map>
21 #include <typeinfo>
22 
23 #include <awali/dyn/core/any.hh>
24 #include <awali/common/priority.hh>
25 #include <awali/common/enums.hh>
29 
30 namespace awali {
31  namespace dyn {
32  namespace internal {
33 
34  template<typename T>
35  struct acceptor_t {
36  virtual bool is_valid(T const& value) {
37  return true;
38  }
39  virtual std::string acceptable_values() {
40  return ("any value of type "+awali::internal::demangle(typeid(T).name()));
41  }
42  };
43 
44  template<>
45  struct acceptor_t<bool> {
46  virtual bool is_valid(bool const& value) {
47  return true;
48  }
49  std::string acceptable_values() {
50  return ("boolean");
51  }
52  };
53 
54  template<>
55  struct acceptor_t<std::string> {
56  virtual bool is_valid(std::string const& value) {
57  return true;
58  }
59  virtual std::string acceptable_values() {
60  return ("any string");
61  }
62  };
63 
67  extern size_t next_id;
68 
69  template<typename T>
70  class option_t {
71  public:
72  using value_t = T;
73  const size_t id;
74 
75  private:
76  std::string option_name;
77  acceptor_t<value_t> acceptor;
78  value_t default_value;
79  bool default_set_by_user = false;
80 
81  option_t(option_t<T> other, value_t def) :
82  id(other.id),
83  option_name(other.option_name),
84  acceptor(other.acceptor),
85  default_value(other.default_set_by_user?other.def:def),
86  default_set_by_user(other.was_user_set)
87  {}
88 
89  template<typename X, typename P>
91  throw std::runtime_error("Wrong value type for option "+option_name
92  + ". Expecting: "
93  + acceptor.acceptable_values()
94  + "." );
95  }
96 
97  template<typename X=T, typename P>
99  make(const char* value, priority::TWO<P>)
100  { return make(std::string(value), priority::value); }
101 
102  template<typename X=T, typename P>
103  auto make(std::string const& value, priority::THREE<P>)
104  -> decltype(
105  awali::internal::make_enum<X>(value),
106  internal::option_value_pair_t(id, default_value)
107  ) {
108  if (value == "default")
109  return {id, default_value};
110  return {id, awali::internal::make_enum<X>(value)};
111  }
112 
113  template<typename P>
114  internal::option_value_pair_t make(const T& value, priority::FOUR<P>) {
115  if (!acceptor.is_valid(value))
116  make(value, priority::one);
117  return {id, value};
118  }
119 
120 
121 
122  public:
123  option_t(std::string name, T def, acceptor_t<T> acc = acceptor_t<T>())
124  : id(internal::next_id++), option_name(name), acceptor(acc),
125  default_value(def)
126  {}
127 
128  bool acceptable(T value) {
129  return acceptor(value);
130  }
131 
134  return {id, true};
135  throw std::runtime_error("Using option without argument is only possible if they expect boolean values.");
136  }
137 
138 
157  return option_t(*this, new_default_value);
158  }
159 
160 
161  /* Globally sets the default value of this option.
162  */
163  void set_default_value(value_t new_default_value) {
164  default_value = new_default_value;
165  default_set_by_user = true;
166  }
167 
169  return default_value;
170  }
171 
172  public:
173 
174  template<typename X>
176  return make(value, priority::value);
177  }
178 
183  value_t of_string(std::string str) {
185  return (value_t) pair.value;
186  }
187 
188  };
189 
190  } // end of namespace awali::dyn::internal
191  } // end of namespace awali::dyn
192 } //end of namespace awali
193 
194 
196 
197 
198 
199 
200 #endif
Definition: option.hh:70
const size_t id
Definition: option.hh:73
option_t(std::string name, T def, acceptor_t< T > acc=acceptor_t< T >())
Definition: option.hh:123
value_t get_default_value()
Definition: option.hh:168
T value_t
Definition: option.hh:72
internal::option_value_pair_t operator=(const X &value)
Definition: option.hh:175
value_t of_string(std::string str)
Create of value of the type expected by this option_t, from string str.
Definition: option.hh:183
void set_default_value(value_t new_default_value)
Definition: option.hh:163
bool acceptable(T value)
Definition: option.hh:128
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:156
size_t next_id
Global variable that assign a unique identifier to each instance of option<T> independentely of type ...
static std::string demangle(const char *name)
Definition: demangle.hxx:48
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 &value)
Definition: option.hh:46
virtual std::string acceptable_values()
Definition: option.hh:59
virtual bool is_valid(std::string const &value)
Definition: option.hh:56
Definition: option.hh:35
virtual std::string acceptable_values()
Definition: option.hh:39
virtual bool is_valid(T const &value)
Definition: option.hh:36