diff --git a/src/lib/CodeGen.cpp b/src/lib/CodeGen.cpp index f2413ca..fb21de0 100644 --- a/src/lib/CodeGen.cpp +++ b/src/lib/CodeGen.cpp @@ -32,6 +32,7 @@ namespace tigl { } namespace { + auto customReplacedType(const std::string& type, const Tables& tables) -> const std::string& { const auto p = tables.m_customTypes.find(type); return p ? *p : type; @@ -200,7 +201,7 @@ namespace tigl { return typeName; case Cardinality::Vector: { - if (vectorInnerTypeIsUniquePtr(field)) + if (vectorInnerTypeIsCPACSClass(field)) return "std::vector>"; else return "std::vector<" + typeName + ">"; @@ -220,7 +221,20 @@ namespace tigl { return customReplacedType(field); } - auto vectorInnerTypeIsUniquePtr(const Field& field) const -> bool { + auto vectorInnerClass(const Field& field) const -> Class const& + { + if (field.cardinality() != Cardinality::Vector){ + throw std::logic_error("Requested vector inner type for non-vector type"); + } + auto const it = m_types.classes.find(field.typeName); + if(vectorInnerTypeIsCPACSClass(field) && it != std::end(m_types.classes)) { + return it->second; + } else { + throw std::logic_error("VectorInnerType is not a CPACS class"); + } + } + + auto vectorInnerTypeIsCPACSClass(const Field& field) const -> bool { if (field.cardinality() != Cardinality::Vector) throw std::logic_error("Requested vector inner type for non-vector type"); return m_types.classes.find(field.typeName) != std::end(m_types.classes); @@ -264,9 +278,18 @@ namespace tigl { hpp << "TIGL_EXPORT virtual " << getterSetterType(f) << "& Get" << capitalizeFirstLetter(f.name()) << "();"; hpp << EmptyLine; hpp << "TIGL_EXPORT virtual size_t Get" << capitalizeFirstLetter(f.cpacsName) << "Count() const;"; + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f))){ + hpp << "TIGL_EXPORT virtual size_t Get" << capitalizeFirstLetter(f.cpacsName) << "Index(const std::string& UID) const;"; + } + hpp << EmptyLine; hpp << "TIGL_EXPORT virtual const " << vectorInnerType(f) << "& Get" << capitalizeFirstLetter(f.cpacsName) << "(size_t index) const;"; hpp << "TIGL_EXPORT virtual " << vectorInnerType(f) << "& Get" << capitalizeFirstLetter(f.cpacsName) << "(size_t index);"; - } // generate special accessors for uid reference vectors + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f))){ + hpp << EmptyLine; + hpp << "TIGL_EXPORT virtual const " << vectorInnerType(f) << "& Get" << capitalizeFirstLetter(f.cpacsName) << "(const std::string& UID) const;"; + hpp << "TIGL_EXPORT virtual " << vectorInnerType(f) << "& Get" << capitalizeFirstLetter(f.cpacsName) << "(const std::string& UID);"; + } + } // generate special accessors for uid reference vectors else if (f.cardinality() == Cardinality::Vector && f.xmlTypeName == c_uidRefType) { hpp << "TIGL_EXPORT virtual void AddTo" << capitalizeFirstLetter(f.name()) << "(const " << vectorInnerType(f) << "& value);"; hpp << "TIGL_EXPORT virtual bool RemoveFrom" << capitalizeFirstLetter(f.name()) << "(const " << vectorInnerType(f) << "& value);"; @@ -386,6 +409,40 @@ namespace tigl { cpp << "}"; cpp << EmptyLine; + // Getter for index by UID + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f))){ + cpp << "size_t " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << "Index(const std::string& UID) const"; + cpp << "{"; + { + Scope s(cpp); + cpp << "for (size_t i=0; i < Get" << capitalizeFirstLetter(f.cpacsName) << "Count(); i++) {"; + { + Scope s(cpp); + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f)) && !hasMandatoryUidField(vectorInnerClass(f))) { + cpp << "const boost::optional tmpUID(*" << f.fieldName() << "[i]->GetUID());"; + cpp << "if (tmpUID == UID) {"; + { + Scope s(cpp); + cpp << "return i+1;"; + } + cpp << "}"; + } else { + cpp << "const std::string tmpUID(" << f.fieldName() << "[i]->GetUID());"; + cpp << "if (tmpUID == UID) {"; + { + Scope s(cpp); + cpp << "return i+1;"; + } + cpp << "}"; + } + } + cpp << "}"; + cpp << "throw CTiglError(\"Invalid UID in " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << "Index\", TIGL_UID_ERROR);"; + } + cpp << "}"; + cpp << EmptyLine; + } + //Getters for elements in vector type by index; for (auto isConst : { false, true }) { if(isConst){ @@ -396,14 +453,15 @@ namespace tigl { cpp << "{"; { Scope s(cpp); - cpp << "index--;"; - cpp << "if (index < 0 || index >= Get" << capitalizeFirstLetter(f.cpacsName) << "Count()) {"; + cpp << "if (index < 1 || index > Get" << capitalizeFirstLetter(f.cpacsName) << "Count()) {"; { Scope s(cpp); cpp << "throw CTiglError(\"Invalid index in " << getterSetterType(f) << "::Get" << capitalizeFirstLetter(f.cpacsName) << "\", TIGL_INDEX_ERROR);"; } cpp << "}"; - if (vectorInnerTypeIsUniquePtr(f)) { + cpp << "index--;"; + // CPACS classes are stored in smart pointers and we need to derefence + if (vectorInnerTypeIsCPACSClass(f)) { cpp << "return *" << f.fieldName() << "[index];"; } else { cpp << "return " << f.fieldName() << "[index];"; @@ -413,6 +471,38 @@ namespace tigl { cpp << EmptyLine; } + //Getters for elements in vector type by uid; + if(vectorInnerTypeIsCPACSClass(f) && hasUidField(vectorInnerClass(f))){ + for (auto isConst : { false, true }) { + if(isConst){ + cpp << "const " << vectorInnerType(f) << "& " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << "(const std::string& UID) const"; + } else { + cpp << vectorInnerType(f) << "& " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << "(const std::string& UID)"; + } + cpp << "{"; + { + Scope s(cpp); + cpp << "for (auto& elem : " << f.fieldName() <<" ) {"; + { + Scope s(cpp); + cpp << "if (elem->GetUID() == UID)"; + { + Scope s(cpp); + if (vectorInnerTypeIsCPACSClass(f)) { + cpp << "return *elem;"; + } else { + cpp << "return elem;"; + } + + } + cpp << "}"; + cpp << "throw CTiglError(\"Invalid UID in " << className << "::Get" << capitalizeFirstLetter(f.cpacsName) << ". \\\"\"+ UID + \"\\\" not found in CPACS file!\" , TIGL_UID_ERROR);"; + } + } + cpp << "}"; + cpp << EmptyLine; + } + } }// generate special accessors for uid reference vectors else if (f.cardinality() == Cardinality::Vector && f.xmlTypeName == c_uidRefType) { diff --git a/test/data/sequence/ref.cpp b/test/data/sequence/ref.cpp index 4efcaba..e5aeaa5 100644 --- a/test/data/sequence/ref.cpp +++ b/test/data/sequence/ref.cpp @@ -59,6 +59,7 @@ namespace generated TIGL_EXPORT virtual std::vector& GetEs(); TIGL_EXPORT virtual size_t GetECount() const; + TIGL_EXPORT virtual const int& GetE(size_t index) const; TIGL_EXPORT virtual int& GetE(size_t index); @@ -69,6 +70,7 @@ namespace generated TIGL_EXPORT virtual std::vector& GetGs(); TIGL_EXPORT virtual size_t GetGCount() const; + TIGL_EXPORT virtual const int& GetG(size_t index) const; TIGL_EXPORT virtual int& GetG(size_t index); @@ -79,6 +81,7 @@ namespace generated TIGL_EXPORT virtual std::vector& GetIs(); TIGL_EXPORT virtual size_t GetICount() const; + TIGL_EXPORT virtual const int& GetI(size_t index) const; TIGL_EXPORT virtual int& GetI(size_t index); @@ -325,19 +328,19 @@ namespace generated int& CPACSRoot::GetE(size_t index) { - index--; - if (index < 0 || index >= GetECount()) { + if (index < 1 || index > GetECount()) { throw CTiglError("Invalid index in std::vector::GetE", TIGL_INDEX_ERROR); } + index--; return m_es[index]; } const int& CPACSRoot::GetE(size_t index) const { - index--; - if (index < 0 || index >= GetECount()) { + if (index < 1 || index > GetECount()) { throw CTiglError("Invalid index in std::vector::GetE", TIGL_INDEX_ERROR); } + index--; return m_es[index]; } @@ -369,19 +372,19 @@ namespace generated int& CPACSRoot::GetG(size_t index) { - index--; - if (index < 0 || index >= GetGCount()) { + if (index < 1 || index > GetGCount()) { throw CTiglError("Invalid index in std::vector::GetG", TIGL_INDEX_ERROR); } + index--; return m_gs[index]; } const int& CPACSRoot::GetG(size_t index) const { - index--; - if (index < 0 || index >= GetGCount()) { + if (index < 1 || index > GetGCount()) { throw CTiglError("Invalid index in std::vector::GetG", TIGL_INDEX_ERROR); } + index--; return m_gs[index]; } @@ -413,19 +416,19 @@ namespace generated int& CPACSRoot::GetI(size_t index) { - index--; - if (index < 0 || index >= GetICount()) { + if (index < 1 || index > GetICount()) { throw CTiglError("Invalid index in std::vector::GetI", TIGL_INDEX_ERROR); } + index--; return m_is[index]; } const int& CPACSRoot::GetI(size_t index) const { - index--; - if (index < 0 || index >= GetICount()) { + if (index < 1 || index > GetICount()) { throw CTiglError("Invalid index in std::vector::GetI", TIGL_INDEX_ERROR); } + index--; return m_is[index]; }