declare_ref_func.hpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*!
  2. \file declare_ref_func.hpp
  3. \author Ha NGUYEN
  4. \date 02 Dec 2014
  5. \since 02 Dec 2014
  6. \brief Macros to add functions used to solve references in class CDomain, CAxis and CField
  7. */
  8. #ifndef __XIOS_DECLARE_REF_FUNC_HPP__
  9. #define __XIOS_DECLARE_REF_FUNC_HPP__
  10. // Declarations
  11. #define DECLARE_REF_FUNC(type, name_) \
  12. public: \
  13. void solveRefInheritance(bool apply = true); \
  14. void removeRefInheritance(); \
  15. bool hasDirect##type##Reference(void) const; \
  16. C##type* getDirect##type##Reference(void) const; \
  17. const StdString get##type##OutputName(void) const; \
  18. void setAttributesReference(bool apply = true); \
  19. bool hasRefTo(C##type* ref) const; \
  20. \
  21. private: \
  22. std::vector<C##type*> refObjects;
  23. // Definitions
  24. #define DEFINE_REF_FUNC(type, name_) \
  25. void C##type::solveRefInheritance(bool apply) \
  26. { \
  27. std::set<C##type*> tmpRefObjects; \
  28. C##type* refer_ptr = this; \
  29. std::vector<C##type*>().swap(refObjects); \
  30. refObjects.push_back(this); \
  31. \
  32. while (refer_ptr->hasDirect##type##Reference()) \
  33. { \
  34. tmpRefObjects.insert(refer_ptr); \
  35. \
  36. refer_ptr = refer_ptr->getDirect##type##Reference(); \
  37. \
  38. if (tmpRefObjects.end() != tmpRefObjects.find(refer_ptr)) \
  39. { \
  40. ERROR("void C" #type "::solveRefInheritance(bool apply)", \
  41. << "Circular dependency stopped for " #name_ " object " \
  42. << "with id = \"" << refer_ptr->getId() << "\"."); \
  43. } \
  44. \
  45. refObjects.push_back(refer_ptr); \
  46. SuperClassAttribute::setAttributes(refer_ptr, apply); \
  47. } \
  48. if (this->hasAttribute("name") && this->name.isEmpty()) \
  49. this->name.setValue(this->get##type##OutputName()); \
  50. } \
  51. \
  52. void C##type::setAttributesReference(bool apply) \
  53. { \
  54. for (int i = 1; i < refObjects.size(); ++i) \
  55. refObjects[i]->setAttributes(refObjects[i-1], apply); \
  56. if (refObjects.size() > 1) \
  57. refObjects[refObjects.size()-1]->removeRefInheritance(); \
  58. } \
  59. \
  60. void C##type::removeRefInheritance() \
  61. { \
  62. if (!this->name_##_ref.isEmpty()) \
  63. this->name_##_ref.reset(); \
  64. } \
  65. \
  66. bool C##type::hasDirect##type##Reference(void) const \
  67. { \
  68. return (!this->name_##_ref.isEmpty() && \
  69. C##type::has(this->name_##_ref)); \
  70. } \
  71. \
  72. C##type* C##type::getDirect##type##Reference(void) const \
  73. { \
  74. if (this->name_##_ref.isEmpty()) \
  75. ERROR("C" #type "* C" #type "::getDirect" #type "Reference(void)", \
  76. << "The " #name_ " with id = '" << getId() << "'" \
  77. << " has no " #name_ "_ref."); \
  78. \
  79. if (!C##type::has(this->name_##_ref)) \
  80. ERROR("C" #type "* C" #type "::getDirect" #type "Reference(void)", \
  81. << this->name_##_ref \
  82. << " refers to an unknown " #name_ " id."); \
  83. \
  84. return C##type::get(this->name_##_ref); \
  85. } \
  86. \
  87. const StdString C##type::get##type##OutputName(void) const \
  88. { \
  89. if (!this->name.isEmpty()) return this->name; \
  90. else if (this->hasAutoGeneratedId() && hasDirect##type##Reference()) \
  91. { \
  92. const C##type* refer_ptr = this, *tmp_ptr; \
  93. StdString nameRef = this->name_##_ref; \
  94. std::set<const C##type*> tmpRefObjects; \
  95. while (refer_ptr->hasAutoGeneratedId() && \
  96. (C##type::has(nameRef))) \
  97. { \
  98. tmpRefObjects.insert(refer_ptr); \
  99. tmp_ptr = refer_ptr; \
  100. refer_ptr = tmp_ptr->getDirect##type##Reference(); \
  101. if (refer_ptr->hasAutoGeneratedId() && \
  102. refer_ptr->hasDirect##type##Reference()) \
  103. nameRef = refer_ptr->name_##_ref; \
  104. else { \
  105. nameRef = refer_ptr->getId(); break; \
  106. } \
  107. if (tmpRefObjects.end() != tmpRefObjects.find(refer_ptr)) \
  108. { \
  109. ERROR("const StdString& C" #type "::get" #type "OutputName(void) const ", \
  110. << "Circular dependency stopped for " #name_ " object " \
  111. << "with id = \"" << refer_ptr->getId() << "\"."); \
  112. } \
  113. } \
  114. return nameRef; \
  115. } \
  116. else \
  117. return getId(); \
  118. } \
  119. \
  120. bool C##type::hasRefTo(C##type* ref) const \
  121. { \
  122. bool found = false; \
  123. for (int idx = 0; idx < refObjects.size(); ++idx) \
  124. if (ref == refObjects[idx]) { found = true; break; } \
  125. return found; \
  126. }
  127. #endif // __XIOS_DECLARE_REF_FUNC_HPP__