Any.hpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /**
  2. * @file 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() { if (ptr_) delete ptr_; }
  57. void operator=(Any const& other) { Any(other).swap(*this); }
  58. void swap(Any& other) { std::swap(ptr_, other.ptr_); }
  59. template<typename T, typename V>
  60. V T::* get() const { return dynamic_cast < data<T, V>* >(ptr_)->value_; }
  61. bool is_null() const { return ptr_ == nullptr; }
  62. template<typename T, typename V>
  63. void put(T* o, const V& value)
  64. {
  65. V T::* p = dynamic_cast <data<T, V>* >(ptr_)->value_;
  66. o->*(p) = value;
  67. }
  68. template<typename T>
  69. void restore(T* o, const common::Value& value)
  70. {
  71. if (value.is_type<double>()) {
  72. double v;
  73. value(v);
  74. put(o, v);
  75. } else if (value.is_type<unsigned int>()) {
  76. unsigned int v;
  77. value(v);
  78. put(o, v);
  79. } else if (value.is_type<int>()) {
  80. int v;
  81. value(v);
  82. put(o, v);
  83. } else if (value.is_type<bool>()) {
  84. bool v;
  85. value(v);
  86. put(o, v);
  87. } else if (value.is_type<std::vector<double> >()) {
  88. std::vector<double> v;
  89. value(v);
  90. put(o, v);
  91. } else if (value.is_type<std::vector<unsigned int> >()) {
  92. std::vector<unsigned int> v;
  93. value(v);
  94. put(o, v);
  95. } else if (value.is_type<std::vector<int> >()) {
  96. std::vector<int> v;
  97. value(v);
  98. put(o, v);
  99. } else if (value.is_type<std::vector<bool> >()) {
  100. std::vector<bool> v;
  101. value(v);
  102. put(o, v);
  103. } else {
  104. assert(false);
  105. }
  106. }
  107. template<typename T>
  108. common::Value save(const T* o) const
  109. {
  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. {
  163. if (ptr_) {
  164. data<T, double>* q_double =
  165. dynamic_cast < data<T, double>* >(ptr_);
  166. if (q_double) {
  167. return std::to_string(o->*(q_double->value_));
  168. } else {
  169. data<T, unsigned int>* q_uint =
  170. dynamic_cast < data<T, unsigned int>* >(ptr_);
  171. if (q_uint) {
  172. return std::to_string(o->*(q_uint->value_));
  173. } else {
  174. data<T, int>* q_int =
  175. dynamic_cast < data<T, int>* >(ptr_);
  176. if (q_int) {
  177. return std::to_string(o->*(q_int->value_));
  178. } else {
  179. data<T, bool>* q_bool =
  180. dynamic_cast < data<T, bool>* >(ptr_);
  181. if (q_bool) {
  182. return o->*(q_bool->value_) ? "true" : "false";
  183. } else {
  184. data<T, std::vector<double> >* q_double_v =
  185. dynamic_cast < data<T, std::vector<
  186. double> >* >(ptr_);
  187. if (q_double_v) {
  188. return "";
  189. } else {
  190. data<T, std::vector<int> >* q_int_v =
  191. dynamic_cast < data<T, std::vector<
  192. int> >* >(ptr_);
  193. if (q_int_v) {
  194. return "";
  195. } else {
  196. data<T, std::vector<bool> >* q_bool_v =
  197. dynamic_cast < data<T, std::vector<
  198. bool> >* >(ptr_);
  199. if (q_bool_v) {
  200. return "";
  201. } else {
  202. return "NA";
  203. }
  204. }
  205. }
  206. }
  207. }
  208. }
  209. }
  210. } else {
  211. return "NA";
  212. }
  213. }
  214. };
  215. }
  216. }
  217. #endif