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

Last change on this file since 2230 was 2203, checked in by ymipsl, 3 years ago

New functionnality : domain, axis and scalar can now be retrieve with new syntax id :
ex. for domain :

id="domainId" : old syntax, working as before
id="fieldId::domainId" : get the domain related to "domainId" associated to the field "fieldId", work if only 1 domain related to domainId is associated to the field.
id="fieldId::domainId[n]" : get the nth domain related to "domainId" associated to the field "fieldId"
id="fieldId::" : get the domain associated the the field "fieldId, work if grid associated to th field is composed with exactly 1 domain (and possibly other components axis or scalars)
id="fieldId::[n] : get the nth domain composing the grid associated to the field

YM

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