Awali
Another Weighted Automata library
any.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2022 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 DYN_ANY_HH
18 #define DYN_ANY_HH
19 
24 
25 #include<string>
26 #include<iostream>
27 #include<sstream>
28 #include<list>
29 #include<type_traits>
30 
31 namespace awali {
32  namespace dyn {
33 
34  namespace internal {
35  template<typename T>
36  bool any_typeof(const any_t& a);
37 
38  template<typename T>
39  T any_cast(const any_t& a);
40 
41  template<typename T>
42  T any_move(any_t& a);
43 
44  template<typename T>
45  T const& any_cref(const any_t& a);
46  }
47 
48  std::ostream& operator<<(std::ostream& o, const dyn::any_t& a);
49 
50 
59  struct any_t {
60  template<typename T>
61  friend T internal::any_cast(const any_t& a);
62  template<typename T>
63  friend T internal::any_move(any_t& a);
64  template<typename T>
65  friend T const& internal::any_cref(const any_t& a);
66 
67  template<typename T>
68  friend bool internal::any_typeof(const any_t& a);
69  friend std::ostream& operator<<(std::ostream& o, const dyn::any_t& a);
70 
71  private:
73 
74  bool is_tuple;
75 
76  std::ostream& output (std::ostream& o) const {
77  if (is_tuple) {
78  o << '[';
79  bool b = true;
81  = dynamic_cast<internal::Value<std::list<any_t>>&>
82  (*(this->val));
83  for (auto it =l.val.begin(); it != l.val.end(); it++) {
84  if (b)
85  b=false;
86  else
87  o << ',';
88  it->output(o);
89  }
90  o << ']';
91  return o;
92  }
93  else
94  return val->output(o);
95  }
96 
97 
98  template<typename H>
99  void static add_to_vect(std::list<any_t>&accu, const H& head) {
100  accu.emplace_back(head);
101  }
102 
103  template <typename H, typename...T>
104  void static add_to_vect
105  (std::list<any_t>& accu, const H& head, const T&... tail)
106  {
107  add_to_vect(accu,head);
108  add_to_vect(accu,tail...);
109  }
110 
111  public:
112  template<typename T>
113  any_t(const T& t) : val(new internal::Value<T>(t)), is_tuple(false) {}
114 
115  any_t() : val(nullptr), is_tuple(false) {}
116 
117  template<typename H, typename... T>
118  any_t(const H& head, const T&... tail)
119  : val(new internal::Value<std::list<any_t>>({})),
120  is_tuple(true)
121  {
123  = dynamic_cast<internal::Value<std::list<any_t>>&>
124  (*(this->val));
125  add_to_vect(test.val, head, tail...);
126  }
127 
128  any_t(const char *s) : val(new internal::Value<std::string>(s)), is_tuple(false) {}
129 
130  any_t(const any_t& a) : val(a.val->clone()), is_tuple(a.is_tuple) {}
131 
132  any_t& operator= (const any_t& t) {
133  if(&t==this) return *this;
134  delete val;
135  val=t.val->clone();
136  is_tuple=t.is_tuple;
137  return *this;
138  }
139 
140  bool operator< (const any_t& a) const {
141  return val->less(*(a.val));
142  }
143 
144 
145  bool operator==(const any_t& a) const {
146  return val->equal(*(a.val));
147  }
148 
149  bool operator!=(const any_t& a) const {
150  return !val->equal(*(a.val));
151  }
152 
153  bool operator>=(const any_t& a) const {
154  return !val->less(*(a.val));
155  }
156 
157  bool operator<=(const any_t& a) const {
158  return val->equal(*(a.val)) || val->less(*(a.val));
159  }
160 
161  bool operator>(const any_t& a) const {
162  return !val->equal(*(a.val)) && !val->less(*(a.val));
163  }
164 
165  template<typename T>
166  explicit
167  operator T() const & {
168  return internal::any_cast<T>(*this);
169  }
170 
171  template<typename T>
172  explicit
173  operator T() && {
174  return internal::any_move<T>(*this);
175  }
176 
177  std::ostream& real_type_id(std::ostream &o) const {
178  return val->real_type_id(o);
179  }
180  std::ostream& real_type_name(std::ostream &o) const {
181  return val->real_type_name(o);
182  }
183 
184  ~any_t() {
185  delete val;
186  }
187  };
188 
189  std::ostream& operator<< (std::ostream& o, const any_t& a);
190 
191  struct any_cast_exception : public std::runtime_error {
192  any_cast_exception(const std::string& s) : std::runtime_error(s) {}
193  };
194 
195 
196  namespace internal {
197  template<typename T>
199  try {
200  internal::Value<T>& test
201  = dynamic_cast<internal::Value<T>&>(*(a.val));
202  return std::move(test.val);
203  }
204  catch (const std::bad_cast& e) {
205  std::stringstream ss;
206  ss << "Failed to extract content of "<< a << ". "
207  << "Tried to cast it as a "
208  << awali::internal::demangle(typeid(T).name())
209  << " but is actually of type ";
210  a.real_type_name(ss) << ".";
211  throw any_cast_exception(ss.str());
212  }
213  }
214  template<typename T>
215  T const& any_cref(const any_t& a){
216  try {
217  const internal::Value<T>& test
218  = dynamic_cast<const internal::Value<T>&>(*(a.val));
219  return test.val;
220  }
221  catch (const std::bad_cast& e) {
222  std::stringstream ss;
223  ss << "Failed to extract content of "<< a << ". "
224  << "Tried to cast it as a "
225  << awali::internal::demangle(typeid(T).name())
226  << " but is actually of type ";
227  a.real_type_name(ss) << ".";
228  throw any_cast_exception(ss.str());
229  }
230  }
231  template<typename T>
232  T any_cast(const any_t& a){
233  try {
234  const internal::Value<T>& test
235  = dynamic_cast<const internal::Value<T>&>(*(a.val));
236  return test.val;
237  }
238  catch (const std::bad_cast& e) {
239  std::stringstream ss;
240  ss << "Failed to extract content of "<< a << ". "
241  << "Tried to cast it as a "
242  << awali::internal::demangle(typeid(T).name())
243  << " but is actually of type ";
244  a.real_type_name(ss) << ".";
245  throw any_cast_exception(ss.str());
246  }
247  }
248  template<typename T>
249  bool any_typeof(const any_t& a){
250  try {
251  const internal::Value<T>& test
252  = dynamic_cast<const internal::Value<T>&>(*(a.val));
253  return true;
254  }
255  catch(std::bad_cast& e) {
256  return false;
257  }
258  }
259 
260  }
261 
262 
263 
264 
265 }}//end of namespaces awali::dyn, and awali
266 
267 #endif //DYN_ANY_HH
bool any_typeof(const any_t &a)
Definition: any.hh:249
T any_move(any_t &a)
Definition: any.hh:198
T const & any_cref(const any_t &a)
Definition: any.hh:215
T any_cast(const any_t &a)
Definition: any.hh:232
std::ostream & operator<<(std::ostream &o, automaton_t aut)
std::string demangle(const char *name)
Definition: demangle.hxx:48
Main namespace of Awali.
Definition: ato.hh:22
Definition: any.hh:191
any_cast_exception(const std::string &s)
Definition: any.hh:192
Structure used to erase the type of labels/weights at the dyn layer.
Definition: any.hh:59
bool operator!=(const any_t &a) const
Definition: any.hh:149
bool operator<=(const any_t &a) const
Definition: any.hh:157
any_t()
Definition: any.hh:115
bool operator<(const any_t &a) const
Definition: any.hh:140
bool operator>(const any_t &a) const
Definition: any.hh:161
any_t & operator=(const any_t &t)
Definition: any.hh:132
std::ostream & real_type_id(std::ostream &o) const
Definition: any.hh:177
any_t(const H &head, const T &... tail)
Definition: any.hh:118
~any_t()
Definition: any.hh:184
bool operator>=(const any_t &a) const
Definition: any.hh:153
std::ostream & real_type_name(std::ostream &o) const
Definition: any.hh:180
any_t(const T &t)
Definition: any.hh:113
bool operator==(const any_t &a) const
Definition: any.hh:145
any_t(const char *s)
Definition: any.hh:128
friend std::ostream & operator<<(std::ostream &o, const dyn::any_t &a)
any_t(const any_t &a)
Definition: any.hh:130
Definition: value.hh:32
T val
Definition: value.hh:34
Definition: untyped_value.hh:26
virtual bool equal(const untyped_value &uv) const =0
virtual bool less(const untyped_value &uv) const =0
virtual std::ostream & real_type_name(std::ostream &o) const =0
virtual std::ostream & real_type_id(std::ostream &o) const =0
virtual untyped_value * clone() const =0
virtual std::ostream & output(std::ostream &o) const =0