Any.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /**
  2. * @file common/Any.hpp
  3. * @author The ARTIS Development Team
  4. * See the AUTHORS or Authors.txt file
  5. */
  6. /*
  7. * ARTIS - the multimodeling and simulation environment
  8. * This file is a part of the ARTIS environment
  9. *
  10. * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation, either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. */
  25. #ifndef COMMON_ANY_HPP
  26. #define COMMON_ANY_HPP
  27. #include <artis-star/common/Value.hpp>
  28. #include <string>
  29. #include <tuple>
  30. #include <utility>
  31. #include <vector>
  32. namespace artis {
  33. namespace common {
  34. class Any {
  35. private:
  36. struct base {
  37. virtual ~base() {}
  38. virtual base *clone() const = 0;
  39. };
  40. template<typename T, typename V>
  41. struct data : base {
  42. data(V T::* const &value)
  43. : value_(value) {}
  44. base *clone() const { return new data<T, V>(*this); }
  45. V T::* value_;
  46. };
  47. base *ptr_;
  48. public:
  49. Any()
  50. : ptr_(nullptr) {}
  51. template<typename T, typename V>
  52. Any(V T::* const &value)
  53. : ptr_(new data<T, V>(value)) {}
  54. Any(Any const &other)
  55. : ptr_(other.ptr_ ? other.ptr_->clone() : nullptr) {}
  56. virtual ~Any() {
  57. if (ptr_)
  58. delete ptr_;
  59. }
  60. void operator=(Any const &other) { Any(other).swap(*this); }
  61. void swap(Any &other) { std::swap(ptr_, other.ptr_); }
  62. template<typename T, typename V>
  63. V T::* get() const { return dynamic_cast < data<T, V> * >(ptr_)->value_; }
  64. bool is_null() const { return ptr_ == nullptr; }
  65. template<typename T, typename V>
  66. void put(T *o, const V &value) {
  67. V T::* p = dynamic_cast <data<T, V> * >(ptr_)->value_;
  68. o->*(p) = value;
  69. }
  70. template<typename T>
  71. void restore(T *o, const common::Value &value) {
  72. if (value.is_type<double>()) {
  73. double v;
  74. value(v);
  75. put(o, v);
  76. } else if (value.is_type<unsigned int>()) {
  77. unsigned int v;
  78. value(v);
  79. put(o, v);
  80. } else if (value.is_type<int>()) {
  81. int v;
  82. value(v);
  83. put(o, v);
  84. } else if (value.is_type<bool>()) {
  85. bool v;
  86. value(v);
  87. put(o, v);
  88. } else if (value.is_type<std::vector<double> >()) {
  89. std::vector<double> v;
  90. value(v);
  91. put(o, v);
  92. } else if (value.is_type<std::vector<unsigned int> >()) {
  93. std::vector<unsigned int> v;
  94. value(v);
  95. put(o, v);
  96. } else if (value.is_type<std::vector<int> >()) {
  97. std::vector<int> v;
  98. value(v);
  99. put(o, v);
  100. } else if (value.is_type<std::vector<bool> >()) {
  101. std::vector<bool> v;
  102. value(v);
  103. put(o, v);
  104. } else {
  105. assert(false);
  106. }
  107. }
  108. template<typename T>
  109. common::Value save(const T *o) const {
  110. if (ptr_) {
  111. data<T, double> *q_double =
  112. dynamic_cast < data<T, double> * >(ptr_);
  113. if (q_double) {
  114. return common::Value(o->*(q_double->value_));
  115. } else {
  116. data<T, unsigned int> *q_uint =
  117. dynamic_cast < data<T, unsigned int> * >(ptr_);
  118. if (q_uint) {
  119. return common::Value(o->*(q_uint->value_));
  120. } else {
  121. data<T, int> *q_int =
  122. dynamic_cast < data<T, int> * >(ptr_);
  123. if (q_int) {
  124. return common::Value(o->*(q_int->value_));
  125. } else {
  126. data<T, bool> *q_bool =
  127. dynamic_cast < data<T, bool> * >(ptr_);
  128. if (q_bool) {
  129. return common::Value(o->*(q_bool->value_));
  130. } else {
  131. data<T, std::vector<double> > *q_double_v =
  132. dynamic_cast < data<T, std::vector<
  133. double> > * >(ptr_);
  134. if (q_double_v) {
  135. return common::Value(o->*(q_double_v->value_));
  136. } else {
  137. data<T, std::vector<int> > *q_int_v =
  138. dynamic_cast < data<T, std::vector<
  139. int> > * >(ptr_);
  140. if (q_int_v) {
  141. return common::Value(o->*(q_int_v->value_));
  142. } else {
  143. data<T, std::vector<bool> > *q_bool_v =
  144. dynamic_cast < data<T, std::vector<
  145. bool> > * >(ptr_);
  146. if (q_bool_v) {
  147. return common::Value(
  148. o->*(q_bool_v->value_));
  149. }
  150. }
  151. }
  152. }
  153. }
  154. }
  155. }
  156. }
  157. assert(false);
  158. return common::Value();
  159. }
  160. template<typename T>
  161. std::string to_string(const T *o) const {
  162. if (ptr_) {
  163. data<T, double> *q_double =
  164. dynamic_cast < data<T, double> * >(ptr_);
  165. if (q_double) {
  166. return std::to_string(o->*(q_double->value_));
  167. } else {
  168. data<T, unsigned int> *q_uint =
  169. dynamic_cast < data<T, unsigned int> * >(ptr_);
  170. if (q_uint) {
  171. return std::to_string(o->*(q_uint->value_));
  172. } else {
  173. data<T, int> *q_int =
  174. dynamic_cast < data<T, int> * >(ptr_);
  175. if (q_int) {
  176. return std::to_string(o->*(q_int->value_));
  177. } else {
  178. data<T, bool> *q_bool =
  179. dynamic_cast < data<T, bool> * >(ptr_);
  180. if (q_bool) {
  181. return o->*(q_bool->value_) ? "true" : "false";
  182. } else {
  183. data<T, std::vector<double> > *q_double_v =
  184. dynamic_cast < data<T, std::vector<
  185. double> > * >(ptr_);
  186. if (q_double_v) {
  187. return "";
  188. } else {
  189. data<T, std::vector<int> > *q_int_v =
  190. dynamic_cast < data<T, std::vector<
  191. int> > * >(ptr_);
  192. if (q_int_v) {
  193. return "";
  194. } else {
  195. data<T, std::vector<bool> > *q_bool_v =
  196. dynamic_cast < data<T, std::vector<
  197. bool> > * >(ptr_);
  198. if (q_bool_v) {
  199. return "";
  200. } else {
  201. return "NA";
  202. }
  203. }
  204. }
  205. }
  206. }
  207. }
  208. }
  209. } else {
  210. return "NA";
  211. }
  212. }
  213. };
  214. }
  215. }
  216. #endif