Awali
Another Weighted Automata library
any.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 DYN_ANY_HH
18 #define DYN_ANY_HH
19 
24 
25 #include<string>
26 #include<iostream>
27 #include<sstream>
28 #include<list>
29 
30 namespace awali {
31  namespace dyn {
32 
33  namespace internal {
34  template<typename T>
35  bool any_typeof(const any_t& a);
36 
37  template<typename T>
38  T any_cast(const any_t& a);
39  }
40 
41  std::ostream& operator<<(std::ostream& o, const dyn::any_t& a);
42 
43 
52  struct any_t {
53  template<typename T>
54  friend T internal::any_cast(const any_t& a);
55 
56  template<typename T>
57  friend bool internal::any_typeof(const any_t& a);
58  friend std::ostream& operator<<(std::ostream& o, const dyn::any_t& a);
59 
60  private:
62 
63  bool is_tuple;
64 
65  std::ostream& output (std::ostream& o) const {
66  if (is_tuple) {
67  o << '[';
68  bool b = true;
70  = dynamic_cast<internal::Value<std::list<any_t>>&>
71  (*(this->val));
72  for (auto it =l.val.begin(); it != l.val.end(); it++) {
73  if (b)
74  b=false;
75  else
76  o << ',';
77  it->output(o);
78  }
79  o << ']';
80  return o;
81  }
82  else
83  return val->output(o);
84  }
85 
86 
87  template<typename H>
88  void static add_to_vect(std::list<any_t>&accu, const H& head) {
89  accu.emplace_back(head);
90  }
91 
92  template <typename H, typename...T>
93  void static add_to_vect
94  (std::list<any_t>& accu, const H& head, const T&... tail)
95  {
96  add_to_vect(accu,head);
97  add_to_vect(accu,tail...);
98  }
99 
100  public:
101  template<typename T>
102  any_t(const T& t) : val(new internal::Value<T>(t)), is_tuple(false) {}
103 
104  any_t() : val(nullptr), is_tuple(false) {}
105 
106  template<typename H, typename... T>
107  any_t(const H& head, const T&... tail)
108  : val(new internal::Value<std::list<any_t>>({})),
109  is_tuple(true)
110  {
112  = dynamic_cast<internal::Value<std::list<any_t>>&>
113  (*(this->val));
114  add_to_vect(test.val, head, tail...);
115  }
116 
117  any_t(const char *s) : val(new internal::Value<std::string>(s)), is_tuple(false) {}
118 
119  any_t(const any_t& a) : val(a.val->clone()), is_tuple(a.is_tuple) {}
120 
121  any_t& operator= (const any_t& t) {
122  if(&t==this) return *this;
123  delete val;
124  val=t.val->clone();
125  is_tuple=t.is_tuple;
126  return *this;
127  }
128 
129  bool operator< (const any_t& a) const {
130  return val->less(*(a.val));
131  }
132 
133 
134  bool operator==(const any_t& a) const {
135  return val->equal(*(a.val));
136  }
137 
138  bool operator!=(const any_t& a) const {
139  return !val->equal(*(a.val));
140  }
141 
142  bool operator>=(const any_t& a) const {
143  return !val->less(*(a.val));
144  }
145 
146  bool operator<=(const any_t& a) const {
147  return val->equal(*(a.val)) || val->less(*(a.val));
148  }
149 
150  bool operator>(const any_t& a) const {
151  return !val->equal(*(a.val)) && !val->less(*(a.val));
152  }
153 
154  template<typename T>
155  explicit
156  operator T() const {
157  return internal::any_cast<T>(*this);
158  }
159 
160  std::ostream& real_type_id(std::ostream &o) const {
161  return val->real_type_id(o);
162  }
163  std::ostream& real_type_name(std::ostream &o) const {
164  return val->real_type_name(o);
165  }
166 
167  ~any_t() {
168  delete val;
169  }
170  };
171 
172  std::ostream& operator<< (std::ostream& o, const any_t& a);
173 
174  struct any_cast_exception : public std::runtime_error {
175  any_cast_exception(const std::string& s) : std::runtime_error(s) {}
176  };
177 
178 
179  namespace internal {
180  template<typename T>
181  T any_cast(const any_t& a){
182  try {
183  const internal::Value<T>& test
184  = dynamic_cast<const internal::Value<T>&>(*(a.val));
185  return test.val;
186  }
187  catch (const std::bad_cast& e) {
188  std::stringstream ss;
189  ss << "Failed to extract content of "<< a << ". "
190  << "Tried to cast it as a "
191  << awali::internal::demangle(typeid(T).name())
192  << " but is actually of type ";
193  a.real_type_name(ss) << ".";
194  throw any_cast_exception(ss.str());
195  }
196  }
197  template<typename T>
198  bool any_typeof(const any_t& a){
199  try {
200  const internal::Value<T>& test
201  = dynamic_cast<const internal::Value<T>&>(*(a.val));
202  return true;
203  }
204  catch(std::bad_cast& e) {
205  return false;
206  }
207  }
208 
209  }
210 
211 
212 
213 
214 }}//end of namespaces awali::dyn, and awali
215 
216 #endif //DYN_ANY_HH
bool any_typeof(const any_t &a)
Definition: any.hh:198
T any_cast(const any_t &a)
Definition: any.hh:181
std::ostream & operator<<(std::ostream &o, automaton_t aut)
static std::string demangle(const char *name)
Definition: demangle.hxx:48
Main namespace of Awali.
Definition: ato.hh:22
Definition: any.hh:174
any_cast_exception(const std::string &s)
Definition: any.hh:175
Structure used to erase the type of labels/weights at the dyn layer.
Definition: any.hh:52
bool operator!=(const any_t &a) const
Definition: any.hh:138
bool operator<=(const any_t &a) const
Definition: any.hh:146
any_t()
Definition: any.hh:104
bool operator<(const any_t &a) const
Definition: any.hh:129
bool operator>(const any_t &a) const
Definition: any.hh:150
any_t & operator=(const any_t &t)
Definition: any.hh:121
std::ostream & real_type_id(std::ostream &o) const
Definition: any.hh:160
any_t(const H &head, const T &... tail)
Definition: any.hh:107
~any_t()
Definition: any.hh:167
bool operator>=(const any_t &a) const
Definition: any.hh:142
std::ostream & real_type_name(std::ostream &o) const
Definition: any.hh:163
any_t(const T &t)
Definition: any.hh:102
bool operator==(const any_t &a) const
Definition: any.hh:134
any_t(const char *s)
Definition: any.hh:117
friend std::ostream & operator<<(std::ostream &o, const dyn::any_t &a)
any_t(const any_t &a)
Definition: any.hh:119
Definition: value.hh:31
T val
Definition: value.hh:33
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