SyDEVS  v0.6.6
Multiscale Simulation and Systems Modeling Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
qualified_type.h
Go to the documentation of this file.
1 #pragma once
2 #ifndef SYDEVS_QUALIFIED_TYPE_H_
3 #define SYDEVS_QUALIFIED_TYPE_H_
4 
5 #include <sydevs/core/pointer.h>
6 #include <sydevs/core/quantity.h>
7 #include <sydevs/core/identity.h>
8 #include <sydevs/core/arraynd.h>
10 #include <string>
11 #include <tuple>
12 #include <set>
13 #include <map>
14 #include <functional>
15 
16 namespace sydevs {
17 
18 
19 using tostring_function = std::function<std::string(const pointer&)>;
20 
21 // qualified type trait declaration
22 
23 template<typename T>
25  static constexpr bool valid = false;
26  static constexpr bool valid_and_sortable = false;
27  static std::string tostring(const T& X);
28  static pointer copy(const T& X);
29 };
30 
31 
32 // qualified type trait dependent function
33 
34 template<typename T>
35 std::string tostring(const T& val)
36 {
37  return qualified_type<T>::tostring(val);
38 }
39 
40 template<typename T>
42 {
43  return [](const pointer& val) -> std::string {
44  return qualified_type<T>::tostring(val.dereference<T>());
45  };
46 }
47 
48 
49 // qualified type trait specialization declarations
50 
51 template<>
53  static constexpr bool valid = true;
54  static constexpr bool valid_and_sortable = true;
55  static std::string tostring(const bool& X);
56  static pointer copy(const bool& X);
57 };
58 
59 template<>
61  static constexpr bool valid = true;
62  static constexpr bool valid_and_sortable = true;
63  static std::string tostring(const int64& X);
64  static pointer copy(const int64& X);
65 };
66 
67 template<>
69  static constexpr bool valid = true;
70  static constexpr bool valid_and_sortable = true;
71  static std::string tostring(const float64& X);
72  static pointer copy(const float64& X);
73 };
74 
75 template<>
76 struct qualified_type<std::string> {
77  static constexpr bool valid = true;
78  static constexpr bool valid_and_sortable = true;
79  static std::string tostring(const std::string& X);
80  static pointer copy(const std::string& X);
81 };
82 
83 template<typename U>
85  static constexpr bool valid = true;
86  static constexpr bool valid_and_sortable = true;
87  static std::string tostring(const quantity<U>& X);
88  static pointer copy(const quantity<U>& X);
89 };
90 
91 template<typename U>
93  static constexpr bool valid = true;
94  static constexpr bool valid_and_sortable = true;
95  static std::string tostring(const identity<U>& X);
96  static pointer copy(const identity<U>& X);
97 };
98 
99 template<typename T, int64 ndims>
100 struct qualified_type<arraynd<T, ndims>> {
101  static constexpr bool valid = qualified_type<T>::valid;
102  static constexpr bool valid_and_sortable = qualified_type<T>::valid_and_sortable && ndims == 1;
103  static std::string tostring(const arraynd<T, ndims>& X);
104  static pointer copy(const arraynd<T, ndims>& X);
105 };
106 
107 template<typename T1, typename T2>
108 struct qualified_type<std::pair<T1, T2>> {
111  static std::string tostring(const std::pair<T1, T2>& X);
112  static pointer copy(const std::pair<T1, T2>& X);
113 };
114 
115 template<typename T>
116 struct qualified_type<std::tuple<T>> {
117  static constexpr bool valid = qualified_type<T>::valid;
119  static std::string tostring(const std::tuple<T>& X);
120  static pointer copy(const std::tuple<T>& X);
121 };
122 
123 template<typename T, typename... Ts>
124 struct qualified_type<std::tuple<T, Ts...>> {
125  static constexpr bool valid = (qualified_type<T>::valid && qualified_type<std::tuple<Ts...>>::valid);
127  static std::string tostring(const std::tuple<T, Ts...>& X);
128  static pointer copy(const std::tuple<T, Ts...>& X);
129 };
130 
131 template<typename T>
132 struct qualified_type<std::vector<T>> {
133  static constexpr bool valid = qualified_type<T>::valid;
135  static std::string tostring(const std::vector<T>& X);
136  static pointer copy(const std::vector<T>& X);
137 };
138 
139 template<typename T>
140 struct qualified_type<std::set<T>> {
141  static constexpr bool valid = qualified_type<T>::valid;
143  static std::string tostring(const std::set<T>& X);
144  static pointer copy(const std::set<T>& X);
145 };
146 
147 template<typename Key, typename T>
148 struct qualified_type<std::map<Key, T>> {
151  static std::string tostring(const std::map<Key, T>& X);
152  static pointer copy(const std::map<Key, T>& X);
153 };
154 
155 template<typename T>
156 struct qualified_type<std::shared_ptr<T>> {
157  static constexpr bool valid = true;
158  static constexpr bool valid_and_sortable = false;
159  static std::string tostring(const std::shared_ptr<T>& X);
160  static pointer copy(const std::shared_ptr<T>& X);
161 };
162 
163 
164 // non qualified type trait definitions
165 
166 template<typename T>
167 inline std::string qualified_type<T>::tostring(const T& X)
168 {
169  throw std::logic_error("Conversion to string unavailable for a type that is not a qualified type");
170  return "";
171 }
172 
173 template<typename T>
175 {
176  throw std::logic_error("Copying unavailable for a type that is not a qualified type");
177  return pointer();
178 }
179 
180 
181 // boolean trait definitions
182 
183 inline std::string qualified_type<bool>::tostring(const bool& X)
184 {
185  return X ? std::string("true") : std::string("false");
186 }
187 
188 inline pointer qualified_type<bool>::copy(const bool& X)
189 {
190  return pointer(new bool(X));
191 }
192 
193 
194 // int64 trait definitions
195 
196 inline std::string qualified_type<int64>::tostring(const int64& X)
197 {
198  return (string_builder() << X).str();
199 }
200 
202 {
203  return pointer(new int64(X));
204 }
205 
206 
207 // float64 trait definitions
208 
209 inline std::string qualified_type<float64>::tostring(const float64& X)
210 {
211  return (string_builder() << X).str();
212 }
213 
215 {
216  return pointer(new float64(X));
217 }
218 
219 
220 // std::string trait definitions
221 
222 inline std::string qualified_type<std::string>::tostring(const std::string& X)
223 {
224  return "\"" + X + "\"";
225 }
226 
227 inline pointer qualified_type<std::string>::copy(const std::string& X)
228 {
229  return pointer(new std::string(X));
230 }
231 
232 
233 // quantity<U> trait definitions
234 
235 template<typename U>
237 {
238  return (string_builder() << X).str();
239 }
240 
241 template<typename U>
243 {
244  return pointer(new quantity<U>(X));
245 }
246 
247 
248 // identity<U> trait definitions
249 
250 template<typename U>
252 {
253  return (string_builder() << X).str();
254 }
255 
256 template<typename U>
258 {
259  return pointer(new identity<U>(X));
260 }
261 
262 
263 // arraynd<T, ndims> trait definitions
264 
265 template<typename T, int64 ndims>
267 {
268  auto indices = std::array<int64, ndims>();
269  for (int64 idim = 0; idim < ndims; ++idim) {
270  indices[idim] = 0;
271  }
272  int64 offset = X.offset();
273  int64 idim = 0;
274  auto s = std::string("{");
275  while (idim >= 0) {
276  if (indices[idim] < X.dims()[idim]) {
277  if (indices[idim] > 0) {
278  s += ", ";
279  }
280  if (idim == ndims - 1) {
281  s += qualified_type<T>::tostring(X.data()[offset]);
282  ++indices[idim];
283  offset += X.strides()[idim];
284  }
285  else {
286  ++idim;
287  s += "{";
288  }
289  }
290  else {
291  indices[idim] = 0;
292  offset -= X.dims()[idim]*X.strides()[idim];
293  --idim;
294  if (idim >= 0) {
295  ++indices[idim];
296  offset += X.strides()[idim];
297  s += "}";
298  }
299  }
300  }
301  s += "}";
302  return s;
303 }
304 
305 template<typename T, int64 ndims>
307 {
308  return pointer(new arraynd<T, ndims>(X.copy()));
309 }
310 
311 
312 // std::pair<T1, T2> trait definitions
313 
314 template<typename T1, typename T2>
315 inline std::string qualified_type<std::pair<T1, T2>>::tostring(const std::pair<T1, T2>& X)
316 {
317  return "{" + qualified_type<T1>::tostring(X.first) + ", " + qualified_type<T2>::tostring(X.second) + "}";
318 }
319 
320 template<typename T1, typename T2>
321 inline pointer qualified_type<std::pair<T1, T2>>::copy(const std::pair<T1, T2>& X)
322 {
323  return pointer(new std::pair<T1, T2>(X));
324 }
325 
326 
327 // std::tuple<T> trait definitions
328 
329 template<typename T>
330 inline std::string qualified_type<std::tuple<T>>::tostring(const std::tuple<T>& X)
331 {
332  return "{" + qualified_type<T>::tostring(std::get<0>(X)) + "}";
333 }
334 
335 template<typename T>
336 inline pointer qualified_type<std::tuple<T>>::copy(const std::tuple<T>& X)
337 {
338  return pointer(new std::tuple<T>(X));
339 }
340 
341 
342 // std::tuple<T, Ts...> trait definitions
343 
344 template<typename Tuple, std::size_t N>
346  static std::string tostring(const Tuple& X) {
347  return tuple_tostring_helper<Tuple, N - 1>::tostring(X) + ", " + qualified_type<typename std::tuple_element<N - 1, Tuple>::type>::tostring(std::get<N - 1>(X));
348  }
349 };
350 
351 template<typename Tuple>
352 struct tuple_tostring_helper<Tuple, 1> {
353  static std::string tostring(const Tuple& X) {
355  }
356 };
357 
358 template<typename T, typename... Ts>
359 inline std::string qualified_type<std::tuple<T, Ts...>>::tostring(const std::tuple<T, Ts...>& X)
360 {
361  return "{" + tuple_tostring_helper<std::tuple<T, Ts...>, std::tuple_size<std::tuple<T, Ts...>>::value>::tostring(X) + "}";
362 }
363 
364 template<typename T, typename... Ts>
365 inline pointer qualified_type<std::tuple<T, Ts...>>::copy(const std::tuple<T, Ts...>& X)
366 {
367  return pointer(new std::tuple<T, Ts...>(X));
368 }
369 
370 
371 // std::vector<T> trait definitions
372 
373 template<typename T>
374 inline std::string qualified_type<std::vector<T>>::tostring(const std::vector<T>& X)
375 {
376  auto s = std::string("{");
377  for (const auto& item : X) {
378  if (s.back() != '{') {
379  s += ", ";
380  }
381  s += qualified_type<T>::tostring(item);
382  }
383  s += "}";
384  return s;
385 }
386 
387 template<typename T>
388 inline pointer qualified_type<std::vector<T>>::copy(const std::vector<T>& X)
389 {
390  return pointer(new std::vector<T>(X));
391 }
392 
393 
394 // std::set<T> trait definitions
395 
396 template<typename T>
397 inline std::string qualified_type<std::set<T>>::tostring(const std::set<T>& X)
398 {
399  auto s = std::string("{");
400  for (const auto& item : X) {
401  if (s.back() != '{') {
402  s += ", ";
403  }
404  s += qualified_type<T>::tostring(item);
405  }
406  s += "}";
407  return s;
408 }
409 
410 template<typename T>
411 inline pointer qualified_type<std::set<T>>::copy(const std::set<T>& X)
412 {
413  return pointer(new std::set<T>(X));
414 }
415 
416 
417 // std::map<Key, T> trait definitions
418 
419 template<typename Key, typename T>
420 inline std::string qualified_type<std::map<Key, T>>::tostring(const std::map<Key, T>& X)
421 {
422  auto s = std::string("{");
423  for (const auto& entry : X) {
424  if (s.back() != '{') {
425  s += ", ";
426  }
427  s += ("{" + qualified_type<Key>::tostring(entry.first) + ", " + qualified_type<T>::tostring(entry.second) + "}");
428  }
429  s += "}";
430  return s;
431 }
432 
433 template<typename Key, typename T>
434 inline pointer qualified_type<std::map<Key, T>>::copy(const std::map<Key, T>& X)
435 {
436  return pointer(new std::map<Key, T>(X));
437 }
438 
439 
440 // shared pointer trait definitions
441 
442 template<typename T>
443 inline std::string qualified_type<std::shared_ptr<T>>::tostring(const std::shared_ptr<T>& X)
444 {
445  return "(shared_ptr:" +
446  (X ? (qualified_type<T>::valid ? qualified_type<T>::tostring(*X) : std::string("...")) :
447  std::string("nullptr"))
448  + ")";
449 }
450 
451 template<typename T>
452 inline pointer qualified_type<std::shared_ptr<T>>::copy(const std::shared_ptr<T>& X)
453 {
454  return pointer(new std::shared_ptr<T>(X));
455 }
456 
457 
458 } // namespace
459 
460 #endif
std::string tostring(const T &val)
Definition: qualified_type.h:35
std::function< std::string(const pointer &)> tostring_function
Definition: qualified_type.h:19
std::array< int64, ndims > dims() const
Returns the lengths of each dimension.
Definition: arraynd_base.h:197
std::array< int64, ndims > strides() const
Returns the number of element-size steps in memory between successive elements for each dimension...
Definition: arraynd_base.h:205
Definition: qualified_type.h:345
const T * data() const
Returns a pointer to the element data (const).
Definition: arraynd_base.h:237
Definition: qualified_type.h:24
A class for converting stream objects to string values.
Definition: string_builder.h:27
static constexpr bool valid_and_sortable
Indicates whether type T is both a qualified type and a sortable type.
Definition: qualified_type.h:26
A class template for a multidimensional array with elements of type T arranged in a lattice of ndims ...
Definition: arraynd.h:187
static pointer copy(const T &X)
If T is a qualified type, returns a deep copy of X.
Definition: qualified_type.h:174
static std::string tostring(const Tuple &X)
Definition: qualified_type.h:346
A data type which identifies an item by combining an encapsulated integer-valued index with a dimensi...
Definition: identity.h:41
int64 offset() const
Returns the number of element-size steps in memory before the first element.
Definition: arraynd_base.h:229
static std::string tostring(const Tuple &X)
Definition: qualified_type.h:353
arraynd< T, ndims > copy() const
Create a deep copy of the multidimensional array (data is copied).
Definition: arraynd.h:450
tostring_function tostring_converter()
Definition: qualified_type.h:41
int64_t int64
Definition: number_types.h:14
static std::string tostring(const T &X)
If T is a qualified type, converts X to a std::string.
Definition: qualified_type.h:167
double float64
Definition: number_types.h:22
static constexpr bool valid
Indicates whether type T is a qualified type.
Definition: qualified_type.h:25
A data type template which represents a dimensioned quantity as a multiple of a precision level...
Definition: quantity.h:234
A data type which represents a pointer to anything.
Definition: pointer.h:27