source: XIOS/dev/dev_ym/XIOS_COUPLING/src/declare_ref_func.hpp @ 2121

Last change on this file since 2121 was 1984, checked in by ymipsl, 3 years ago

intermediate commit for new tranformation engine?
YM

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