Internals.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /**
  2. * @file artis/kernel/Internals.hpp
  3. * @author See the AUTHORS file
  4. */
  5. /*
  6. * Copyright (C) 2012-2019 ULCO http://www.univ-littoral.fr
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #ifndef __ARTIS_KERNEL_INTERNALS_HPP
  22. #define __ARTIS_KERNEL_INTERNALS_HPP
  23. #include <artis/context/State.hpp>
  24. #include <artis/kernel/Any.hpp>
  25. #include <artis/kernel/Macro.hpp>
  26. #include <vector>
  27. namespace artis {
  28. namespace kernel {
  29. template<typename T, typename U, typename V>
  30. class Internals {
  31. template<typename W>
  32. struct element {
  33. unsigned int index;
  34. const std::string name;
  35. W T::* var;
  36. element(unsigned int index, const std::string& name, W T::* var)
  37. :
  38. index(index), name(name), var(var) { }
  39. };
  40. public:
  41. Internals() { }
  42. virtual ~Internals() { }
  43. const Any& get(unsigned int index) const { return internals.at(index); }
  44. template<typename W>
  45. void I_(std::initializer_list<element<W> > list)
  46. {
  47. for (typename std::initializer_list<element<W> >::iterator it =
  48. list.begin(); it != list.end(); ++it) {
  49. if (internals.size() <= it->index) {
  50. internals.resize(it->index + 1);
  51. internal_names.resize(it->index + 1, std::string());
  52. }
  53. internals[it->index] = it->var;
  54. internal_names[it->index] = it->name;
  55. #ifdef WITH_TRACE
  56. utils::Trace<utils::DoubleTime>::trace()
  57. << utils::TraceElement<utils::DoubleTime>(
  58. true,
  59. dynamic_cast<T*>(this)->path(dynamic_cast<T*>(this)),
  60. utils::DoubleTime::null,
  61. utils::INTERNAL_DECL)
  62. << utils::KernelInfo(it->name, true);
  63. utils::Trace<utils::DoubleTime>::trace().flush();
  64. #endif
  65. }
  66. }
  67. template<typename W>
  68. void internal_(unsigned int index, const std::string& name, W T::* var)
  69. {
  70. if (internals.size() <= index) {
  71. internals.resize(index + 1, Any());
  72. internal_names.resize(index + 1, std::string());
  73. }
  74. internals[index] = Any(var);
  75. internal_names[index] = name;
  76. #ifdef WITH_TRACE
  77. utils::Trace<utils::DoubleTime>::trace()
  78. << utils::TraceElement<utils::DoubleTime>(
  79. true,
  80. dynamic_cast<T*>(this)->path(dynamic_cast<T*>(this)),
  81. utils::DoubleTime::null,
  82. utils::INTERNAL_DECL)
  83. << utils::KernelInfo(name, true);
  84. utils::Trace<utils::DoubleTime>::trace().flush();
  85. #endif
  86. }
  87. const std::string& name(unsigned int index) const { return internal_names.at(index); }
  88. virtual void restore(AbstractModel<U, V>* model,
  89. const context::State<U>& state)
  90. {
  91. unsigned int index = 0;
  92. for (typename std::vector<Any>::iterator it = internals.begin();
  93. it != internals.end(); ++it) {
  94. if (not it->is_null()) {
  95. it->restore<T>(static_cast < T* >(model),
  96. state.get_internal(index));
  97. }
  98. ++index;
  99. }
  100. }
  101. virtual void save(const AbstractModel<U, V>* model,
  102. context::State<U>& state) const
  103. {
  104. unsigned int index = 0;
  105. for (typename std::vector<Any>::const_iterator it =
  106. internals.begin(); it != internals.end(); ++it) {
  107. if (not it->is_null()) {
  108. state.add_internal(index,
  109. it->save<T>(
  110. static_cast < const T* >(model)));
  111. }
  112. ++index;
  113. }
  114. }
  115. unsigned int size() const { return internals.size(); }
  116. private:
  117. std::vector<std::string> internal_names;
  118. std::vector<Any> internals;
  119. };
  120. #define Internal(index, var) \
  121. internal_(index, std::string(ESCAPEQUOTE(index)), var)
  122. #define Internals(W, L) I_< W >(UNWRAP2 L)
  123. }
  124. } // namespace artis kernel
  125. #endif