diff --git a/source/Hierarchy-Seek.inl b/source/Hierarchy-Seek.inl index dfc42f0..319685a 100644 --- a/source/Hierarchy-Seek.inl +++ b/source/Hierarchy-Seek.inl @@ -18,6 +18,29 @@ namespace Langulus::Entity { + /// Find a unit by type and optional offset + /// @tparam SEEK - the direction to seek in + /// @param type - the type of unit to search for + /// @param offset - the match to return + /// @return a pointer to the found unit, or nullptr if not found + TEMPLATE() template LANGULUS(INLINED) + const A::Unit* TME()::SeekUnit(DMeta type, Index offset) const { + return const_cast(static_cast(this)) + ->template SeekUnit(type, offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Decay* TME()::SeekUnit(Index offset) { + return dynamic_cast*>(static_cast(this) + ->template SeekUnit(MetaDataOf>(), offset)); + } + + TEMPLATE() template LANGULUS(INLINED) + const Decay* TME()::SeekUnit(Index offset) const { + return const_cast(this) + ->template SeekUnit(offset); + } + /// Find a unit by type and optional offset, but search first in an /// auxiliary descriptor /// @tparam SEEK - the direction to seek in @@ -26,19 +49,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, DMeta type, Index offset) const -> const A::Unit* { + const A::Unit* TME()::SeekUnitAux(const Neat& aux, DMeta type, Index offset) const { return const_cast(static_cast(this)) ->template SeekUnitAux(aux, type, offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, Index offset) -> Decay* { + Decay* TME()::SeekUnitAux(const Neat& aux, Index offset) { return dynamic_cast*>(static_cast(this) ->template SeekUnitAux(aux, MetaDataOf>(), offset)); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, Index offset) const -> const Decay* { + const Decay* TME()::SeekUnitAux(const Neat& aux, Index offset) const { return const_cast(this) ->template SeekUnitAux(aux, offset); } @@ -50,19 +73,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitExt(DMeta type, const Many& ext, Index offset) const -> const A::Unit* { + const A::Unit* TME()::SeekUnitExt(DMeta type, const Neat& ext, Index offset) const { return const_cast(static_cast(this)) ->template SeekUnitExt(type, ext, offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitExt(const Many& ext, Index offset) -> Decay* { + Decay* TME()::SeekUnitExt(const Neat& ext, Index offset) { return dynamic_cast*>(static_cast(this) ->template SeekUnitExt(MetaDataOf>(), ext, offset)); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitExt(const Many& ext, Index offset) const -> const Decay* { + const Decay* TME()::SeekUnitExt(const Neat& ext, Index offset) const { return const_cast(this) ->template SeekUnitExt(ext, offset); } @@ -76,22 +99,45 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) const -> const A::Unit* { + const A::Unit* TME()::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) const { return const_cast(static_cast(this)) ->template SeekUnitAuxExt(type, aux, ext, offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAuxExt(const Many& aux, const Many& ext, Index offset) -> Decay* { + Decay* TME()::SeekUnitAuxExt(const Neat& aux, const Neat& ext, Index offset) { return dynamic_cast*>(static_cast(this) ->template SeekUnitAuxExt(MetaDataOf>(), aux, ext, offset)); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAuxExt(const Many& aux, const Many& ext, Index offset) const -> const Decay* { + const Decay* TME()::SeekUnitAuxExt(const Neat& aux, const Neat& ext, Index offset) const { return const_cast(this) ->template SeekUnitAuxExt(aux, ext, offset); } + + /// Find a trait by type and optional offset + /// @tparam SEEK - the direction to seek in + /// @param type - the type of unit to search for + /// @param offset - the match to return + /// @return a pointer to the found unit, or nullptr if not found + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTrait(TMeta type, Index offset) const { + return const_cast(static_cast(this)) + ->template SeekTrait(type, offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTrait(Index offset) { + return static_cast(this) + ->template SeekTrait(MetaTraitOf(), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTrait(Index offset) const { + return const_cast(this) + ->template SeekTrait(offset); + } /// Find a trait by type and specific properties and optional offset /// @tparam SEEK - the direction to seek in @@ -100,19 +146,19 @@ namespace Langulus::Entity /// @param offset - the match to return /// @return a pointer to the found unit, or nullptr if not found TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekTraitAux(const Many& aux, TMeta type, Index offset) const -> Trait { + Trait TME()::SeekTraitAux(const Neat& aux, TMeta type, Index offset) const { return const_cast(static_cast(this)) ->template SeekTraitAux(aux, type, offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekTraitAux(const Many& aux, Index offset) -> Trait { + Trait TME()::SeekTraitAux(const Neat& aux, Index offset) { return static_cast(this) ->template SeekTraitAux(aux, MetaTraitOf(), offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekTraitAux(const Many& aux, Index offset) const -> Trait { + Trait TME()::SeekTraitAux(const Neat& aux, Index offset) const { return const_cast(this) ->template SeekTraitAux(aux, offset); } @@ -120,7 +166,13 @@ namespace Langulus::Entity TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Many& aux, CT::NotTagged auto& output, Index offset) const { + bool TME()::SeekValue(CT::NotTagged auto& output, Index offset) const { + return static_cast(this) + ->template SeekValue(MetaTraitOf(), output, offset); + } + + TEMPLATE() template LANGULUS(INLINED) + bool TME()::SeekValueAux(const Neat& aux, CT::NotTagged auto& output, Index offset) const { return static_cast(this) ->template SeekValueAux(MetaTraitOf(), aux, output, offset); } @@ -128,7 +180,17 @@ namespace Langulus::Entity TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Many& aux, CT::Tagged auto& output, Index offset) const { + bool TME()::SeekValue(CT::Tagged auto& output, Index offset) const { + using T = Deref; + auto lambda = [&]() { + return static_cast(this)->template + SeekValue(MetaTraitOf(), output.mData, offset); + }; + return T::Tags::ForEachOr(lambda); + } + + TEMPLATE() template LANGULUS(INLINED) + bool TME()::SeekValueAux(const Neat& aux, CT::Tagged auto& output, Index offset) const { using T = Deref; auto lambda = [&]() { return static_cast(this)->template @@ -145,25 +207,55 @@ namespace Langulus::Entity /// Available only when managed reflection is enabled /// TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, const Token& dataToken, Index offset) -> A::Unit* { + A::Unit* TME()::SeekUnit(const Token& dataToken, Index offset) { + return static_cast(this) + ->template SeekUnit(RTTI::GetMetaData(dataToken), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + const A::Unit* TME()::SeekUnit(const Token& dataToken, Index offset) const { + return static_cast(this) + ->template SeekUnit(RTTI::GetMetaData(dataToken), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + A::Unit* TME()::SeekUnitAux(const Neat& aux, const Token& dataToken, Index offset) { return static_cast(this) ->template SeekUnitAux(aux, RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekUnitAux(const Many& aux, const Token& dataToken, Index offset) const -> const A::Unit* { + const A::Unit* TME()::SeekUnitAux(const Neat& aux, const Token& dataToken, Index offset) const { return static_cast(this) ->template SeekUnitAux(aux, RTTI::GetMetaData(dataToken), offset); } TEMPLATE() template LANGULUS(INLINED) - auto TME()::SeekTraitAux(const Many& aux, const Token& traitToken, Index offset) const -> Trait { + Trait TME()::SeekTrait(const Token& traitToken, Index offset) { + return static_cast(this) + ->template SeekTrait(RTTI::GetMetaTrait(traitToken), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTrait(const Token& traitToken, Index offset) const { + return static_cast(this) + ->template SeekTrait(RTTI::GetMetaTrait(traitToken), offset); + } + + TEMPLATE() template LANGULUS(INLINED) + Trait TME()::SeekTraitAux(const Neat& aux, const Token& traitToken, Index offset) const { return static_cast(this) ->template SeekTraitAux(aux, RTTI::GetMetaTrait(traitToken), offset); } + + TEMPLATE() template LANGULUS(INLINED) + bool TME()::SeekValue(const Token& traitToken, CT::Data auto& output, Index offset) const { + return static_cast(this) + ->template SeekValue(RTTI::GetMetaTrait(traitToken), output, offset); + } TEMPLATE() template LANGULUS(INLINED) - bool TME()::SeekValueAux(const Token& traitToken, const Many& aux, CT::Data auto& output, Index offset) const { + bool TME()::SeekValueAux(const Token& traitToken, const Neat& aux, CT::Data auto& output, Index offset) const { return static_cast(this) ->template SeekValueAux(RTTI::GetMetaTrait(traitToken), aux, output, offset); } @@ -178,6 +270,22 @@ namespace Langulus::Entity namespace Langulus::Entity { + /// Find a specific unit, searching into the hierarchy + /// @tparam SEEK - where in the hierarchy are we seeking in? + /// @param meta - the unit to seek for + /// @param offset - which of the matches to return + /// @return the found unit, or nullptr if no such unit was found + template LANGULUS(INLINED) + A::Unit* Hierarchy::SeekUnit(DMeta meta, Index offset) { + for (auto owner : *this) { + A::Unit* result = owner->template SeekUnit(meta, offset); + if (result) + return result; + } + + return nullptr; + } + /// Find a unit by type and index from the hierarchy /// Scan a locally provided descriptor first /// @tparam SEEK - where to seek for the unit @@ -186,7 +294,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - auto Hierarchy::SeekUnitAux(const Many& aux, DMeta meta, Index offset) -> A::Unit* { + A::Unit* Hierarchy::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { const A::Unit* result {}; // Scan descriptor even if hierarchy is empty @@ -247,7 +355,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - auto Hierarchy::SeekUnitExt(DMeta type, const Many& ext, Index offset) -> A::Unit* { + A::Unit* Hierarchy::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { for (auto owner : *this) { A::Unit* result = owner->template SeekUnitExt(type, ext, offset); if (result) @@ -266,7 +374,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - auto Hierarchy::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) -> A::Unit* { + A::Unit* Hierarchy::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { // Scan descriptor even if hierarchy is empty A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* u) { @@ -292,6 +400,22 @@ namespace Langulus::Entity return SeekUnitExt(type, ext, offset); } + /// Find a trait by type (and index), searching into the hierarchy + /// @tparam SEEK - direction to search at + /// @param meta - the trait to search for + /// @param offset - the offset to apply + /// @return the trait, which is not empty, if trait was found + template LANGULUS(INLINED) + Trait Hierarchy::SeekTrait(TMeta meta, Index offset) { + for (auto owner : *this) { + auto result = owner->template SeekTrait(meta, offset); + if (result) + return result; + } + + return {}; + } + /// Find a trait, searching into the hierarchy (const) /// @tparam SEEK - direction to search at /// @param aux - descriptor to search through @@ -299,7 +423,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - auto Hierarchy::SeekTraitAux(const Many& aux, TMeta meta, Index offset) -> Trait { + Trait Hierarchy::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { // Scan descriptor Trait result; aux.ForEachDeep([&](const Trait& trait) { @@ -323,7 +447,37 @@ namespace Langulus::Entity // Let's delve into the hierarchy return SeekTrait(meta, offset); } - + + /// Find a trait by type (and index) from the hierarchy, and attempt + /// converting it to a desired output type + /// Supports pinnable outputs + /// @tparam SEEK - direction to search at + /// @param meta - the trait type to search for + /// @param output - [out] the output + /// @param offset - the number of the matching trait to use + /// @return true if output was rewritten + template LANGULUS(INLINED) + bool Hierarchy::SeekValue(TMeta meta, CT::Data auto& output, Index offset) const { + using D = Deref; + + if constexpr (CT::Pinnable) { + // Never touch pinned values + if (output.mLocked) + return false; + } + + // Let's delve into the hierarchy + for (auto owner : *this) { + if (owner->template SeekValue(meta, output, offset)) { + // Value was found + return true; + } + } + + // If reached, nothing was found + return false; + } + /// Find a trait by type (and index) from the hierarchy, and attempt /// converting it to a desired output type. Scan the aux container first /// Supports pinnable outputs, and pinnables will be pinned if trait was @@ -335,7 +489,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - bool Hierarchy::SeekValueAux(TMeta meta, const Many& aux, CT::Data auto& output, Index offset) const { + bool Hierarchy::SeekValueAux(TMeta meta, const Neat& aux, CT::Data auto& output, Index offset) const { using D = Deref; if constexpr (CT::Pinnable) { diff --git a/source/Hierarchy.hpp b/source/Hierarchy.hpp index 9895de8..00eae87 100644 --- a/source/Hierarchy.hpp +++ b/source/Hierarchy.hpp @@ -34,27 +34,31 @@ namespace Langulus::Entity /// /// Can't use virtuals, because we want these to be template functions, /// so that we retain the most of the static optimizations - /// TODO generalize these when deduce-this has been implemented well /// - /* + /*template + NOD() Unit* SeekUnit(DMeta, Index = IndexFirst) = delete; template - NOD() Unit* SeekUnitAux(const Many&, DMeta, Index = IndexFirst) = delete; + NOD() Unit* SeekUnitAux(const Neat&, DMeta, Index = IndexFirst) = delete; template - NOD() Unit* SeekUnitExt(DMeta, const Many&, Index = IndexFirst) = delete; + NOD() Unit* SeekUnitExt(DMeta, const Neat&, Index = IndexFirst) = delete; template - NOD() Unit* SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = IndexFirst) = delete; + NOD() Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = IndexFirst) = delete; template - NOD() Trait SeekTraitAux(const Many&, TMeta, Index = IndexFirst) = delete; + NOD() Trait SeekTrait(TMeta, Index = IndexFirst) = delete; + template + NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = IndexFirst) = delete; template - bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = IndexFirst) const = delete; + bool SeekValue(TMeta, CT::Data auto&, Index = IndexFirst) const = delete; + template + bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = IndexFirst) const = delete; template NOD() TMany GatherUnits(DMeta) = delete; template - NOD() TMany GatherUnitsExt(DMeta, const Many&) = delete; + NOD() TMany GatherUnitsExt(DMeta, const Neat&) = delete; template NOD() TraitList GatherTraits(TMeta) = delete; @@ -67,62 +71,82 @@ namespace Langulus::Entity /// The rest of these functions are defined for every SeekInterface /// They all use static_cast(this) as execution context for the /// above functions, which should be defined in THIS - /// TODO remove these when deduce-this has been implemented well /// template - NOD() auto SeekUnitAux(const Many&, DMeta, Index = 0) const -> const A::Unit*; + NOD() const A::Unit* SeekUnit(DMeta, Index = 0) const; template - NOD() auto SeekUnitAux(const Many&, Index = 0) -> Decay*; + NOD() Decay* SeekUnit(Index = 0); template - NOD() auto SeekUnitAux(const Many&, Index = 0) const -> const Decay*; + NOD() const Decay* SeekUnit(Index = 0) const; template - NOD() auto SeekUnitExt(DMeta, const Many&, Index = 0) const -> const A::Unit*; + NOD() const A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0) const; template - NOD() auto SeekUnitExt(const Many&, Index = 0) -> Decay*; + NOD() Decay* SeekUnitAux(const Neat&, Index = 0); template - NOD() auto SeekUnitExt(const Many&, Index = 0) const -> const Decay*; + NOD() const Decay* SeekUnitAux(const Neat&, Index = 0) const; template - NOD() auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) const -> const A::Unit*; + NOD() const A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0) const; template - NOD() auto SeekUnitAuxExt(const Many&, const Many&, Index = 0) -> Decay*; + NOD() Decay* SeekUnitExt(const Neat&, Index = 0); template - NOD() auto SeekUnitAuxExt(const Many&, const Many&, Index = 0) const -> const Decay*; + NOD() const Decay* SeekUnitExt(const Neat&, Index = 0) const; template - NOD() auto SeekTraitAux(const Many&, TMeta, Index = 0) const -> Trait; + NOD() const A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0) const; + template + NOD() Decay* SeekUnitAuxExt(const Neat&, const Neat&, Index = 0); + template + NOD() const Decay* SeekUnitAuxExt(const Neat&, const Neat&, Index = 0) const; + + template + NOD() Trait SeekTrait(TMeta, Index = 0) const; template - NOD() auto SeekTraitAux(const Many&, Index = 0) -> Trait; + NOD() Trait SeekTrait(Index = 0); template - NOD() auto SeekTraitAux(const Many&, Index = 0) const -> Trait; + NOD() Trait SeekTrait(Index = 0) const; + template + NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0) const; template - bool SeekValueAux(const Many&, CT::NotTagged auto&, Index = 0) const; + NOD() Trait SeekTraitAux(const Neat&, Index = 0); + template + NOD() Trait SeekTraitAux(const Neat&, Index = 0) const; + + + template + bool SeekValue(CT::NotTagged auto&, Index = IndexFirst) const; + template + bool SeekValueAux(const Neat&, CT::NotTagged auto&, Index = 0) const; + template - bool SeekValueAux(const Many&, CT::Tagged auto&, Index = 0) const; + bool SeekValue(CT::Tagged auto&, Index = IndexFirst) const; + template + bool SeekValueAux(const Neat&, CT::Tagged auto&, Index = 0) const; + template - NOD() auto GatherUnits(DMeta) const -> TMany; + NOD() TMany GatherUnits(DMeta) const; template - NOD() auto GatherUnits() -> TMany; + NOD() TMany GatherUnits(); template - NOD() auto GatherUnits() const -> TMany; + NOD() TMany GatherUnits() const; template - NOD() auto GatherUnitsExt(DMeta, const Many&) const -> TMany; + NOD() TMany GatherUnitsExt(DMeta, const Neat&) const; template - NOD() auto GatherUnitsExt(const Many&) -> TMany; + NOD() TMany GatherUnitsExt(const Neat&); template - NOD() auto GatherUnitsExt(const Many&) const -> TMany; + NOD() TMany GatherUnitsExt(const Neat&) const; template - NOD() auto GatherTraits(TMeta) const -> TraitList; + NOD() TraitList GatherTraits(TMeta) const; template - NOD() auto GatherTraits() -> TraitList; + NOD() TraitList GatherTraits(); template - NOD() auto GatherTraits() const -> TraitList; + NOD() TraitList GatherTraits() const; #if LANGULUS_FEATURE(MANAGED_REFLECTION) @@ -131,27 +155,40 @@ namespace Langulus::Entity /// Available only when managed reflection is enabled /// template - NOD() auto SeekUnitAux(const Many&, const Token&, Index = 0) -> A::Unit*; + NOD() A::Unit* SeekUnit(const Token&, Index = 0); template - NOD() auto SeekUnitAux(const Many&, const Token&, Index = 0) const -> const A::Unit*; + NOD() const A::Unit* SeekUnit(const Token&, Index = 0) const; template - NOD() auto SeekTraitAux(const Many&, const Token&, Index = 0) -> Trait; + NOD() A::Unit* SeekUnitAux(const Neat&, const Token&, Index = 0); + template + NOD() const A::Unit* SeekUnitAux(const Neat&, const Token&, Index = 0) const; + template - NOD() auto SeekTraitAux(const Many&, const Token&, Index = 0) const -> Trait; + NOD() Trait SeekTrait(const Token&, Index = 0); + template + NOD() Trait SeekTrait(const Token&, Index = 0) const; template - bool SeekValueAux(const Token&, const Many&, CT::Data auto&, Index = 0) const; + NOD() Trait SeekTraitAux(const Neat&, const Token&, Index = 0); + template + NOD() Trait SeekTraitAux(const Neat&, const Token&, Index = 0) const; template - NOD() auto GatherUnits(const Token&) -> TMany; + bool SeekValue(const Token&, CT::Data auto&, Index = 0) const; template - NOD() auto GatherUnits(const Token&) const -> TMany; + bool SeekValueAux(const Token&, const Neat&, CT::Data auto&, Index = 0) const; + + + template + NOD() TMany GatherUnits(const Token&); + template + NOD() TMany GatherUnits(const Token&) const; template - NOD() auto GatherTraits(const Token&) -> TraitList; + NOD() TraitList GatherTraits(const Token&); template - NOD() auto GatherTraits(const Token&) const -> TraitList; + NOD() TraitList GatherTraits(const Token&) const; #endif }; @@ -173,24 +210,33 @@ namespace Langulus::Entity /// /// Seek /// + using SeekInterface::SeekUnit; using SeekInterface::SeekUnitAux; using SeekInterface::SeekUnitExt; using SeekInterface::SeekUnitAuxExt; + using SeekInterface::SeekTrait; using SeekInterface::SeekTraitAux; + using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; template - NOD() auto SeekUnitAux(const Many&, DMeta, Index = 0) -> A::Unit*; + NOD() A::Unit* SeekUnit(DMeta, Index = 0); template - NOD() auto SeekUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; + NOD() A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); template - NOD() auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> A::Unit*; + NOD() A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); + template + NOD() A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); template - NOD() auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Trait; + NOD() Trait SeekTrait(TMeta, Index = 0); + template + NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0); template - bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; + bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; + template + bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -200,15 +246,15 @@ namespace Langulus::Entity using SeekInterface::GatherTraits; template - NOD() auto GatherUnitsExt(DMeta, const Many&) -> TMany; + NOD() TMany GatherUnitsExt(DMeta, const Neat&); template - NOD() auto GatherUnits(DMeta) -> TMany; + NOD() TMany GatherUnits(DMeta); template - NOD() auto GatherTraits(TMeta) -> TraitList; + NOD() TraitList GatherTraits(TMeta); template - NOD() auto GatherValues() const -> TMany; + NOD() TMany GatherValues() const; }; } // namespace Langulus::Entity diff --git a/source/Thing-Seek.inl b/source/Thing-Seek.inl index 1f464dd..b155c76 100644 --- a/source/Thing-Seek.inl +++ b/source/Thing-Seek.inl @@ -23,6 +23,44 @@ namespace Langulus::Entity { + /// Find a specific unit, searching into the hierarchy + /// @tparam SEEK - where in the hierarchy are we seeking in? + /// @param meta - the unit to seek for + /// @param offset - which of the matches to return + /// @return the found unit, or nullptr if no such unit was found + template + A::Unit* Thing::SeekUnit(DMeta meta, Index offset) { + A::Unit* result = nullptr; + if constexpr (SEEK & Seek::Here) { + // Seek here if requested + result = GetUnitMeta(meta, offset); + if (result) + return result; + } + + if constexpr (SEEK & Seek::Above) { + // Seek in parents up to root, if requested + if (mOwner) { + result = mOwner->template + SeekUnit(meta, offset); + if (result) + return result; + } + } + + if constexpr (SEEK & Seek::Below) { + // Seek children, if requested + for (auto child : mChildren) { + result = child->template + SeekUnit(meta, offset); + if (result) + return result; + } + } + + return nullptr; + } + /// Find a unit by type and index from the hierarchy /// Scan an auxiliary descriptor first /// @tparam SEEK - where to seek for the unit @@ -31,7 +69,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitAux(const Many& aux, DMeta meta, Index offset) { + A::Unit* Thing::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* unit) { if (unit->CastsTo(meta)) { @@ -52,34 +90,7 @@ namespace Langulus::Entity // If reached, then no unit was found in the descriptor // Let's delve into the hierarchy - if constexpr (SEEK & Seek::Here) { - // Seek here if requested - result = GetUnitMeta(meta, offset); - if (result) - return result; - } - - if constexpr (SEEK & Seek::Above) { - // Seek in parents up to root, if requested - if (mOwner) { - result = mOwner->template - SeekUnitAux({}, meta, offset); - if (result) - return result; - } - } - - if constexpr (SEEK & Seek::Below) { - // Seek children, if requested - for (auto child : mChildren) { - result = child->template - SeekUnitAux({}, meta, offset); - if (result) - return result; - } - } - - return nullptr; + return SeekUnit(meta, offset); } /// Find a unit by construct and index from the hierarchy @@ -88,7 +99,7 @@ namespace Langulus::Entity /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitExt(DMeta type, const Many& ext, Index offset) { + A::Unit* Thing::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { A::Unit* result = nullptr; if constexpr (SEEK & Seek::Here) { // Seek here if requested @@ -128,7 +139,7 @@ namespace Langulus::Entity /// @param offset - the Nth match to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - A::Unit* Thing::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) { + A::Unit* Thing::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { // Scan descriptor even if hierarchy is empty A::Unit* result {}; aux.ForEachDeep([&](const A::Unit* unit) { @@ -153,6 +164,43 @@ namespace Langulus::Entity return SeekUnitExt(type, ext, offset); } + /// Find a trait by type (and index), searching into the hierarchy + /// @tparam SEEK - direction to search at + /// @param meta - the trait to search for + /// @param offset - the offset to apply + /// @return the trait, which is not empty, if trait was found + template + Trait Thing::SeekTrait(TMeta meta, Index offset) { + if constexpr (SEEK & Seek::Here) { + // Seek here if requested + auto output = GetTrait(meta, offset); + if (output) + return Abandon(output); + } + + if constexpr (SEEK & Seek::Above) { + // Seek in parents up to root, if requested + if (mOwner) { + auto output = mOwner->template + SeekTrait(meta, offset); + if (output) + return Abandon(output); + } + } + + if constexpr (SEEK & Seek::Below) { + // Seek children, if requested + for (auto child : mChildren) { + auto output = child->template + SeekTrait(meta, offset); + if (output) + return Abandon(output); + } + } + + return {}; + } + /// Find a trait, searching into the hierarchy (const) /// Scan an auxiliary descriptor first /// @tparam SEEK - direction to search at @@ -161,7 +209,7 @@ namespace Langulus::Entity /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Trait Thing::SeekTraitAux(const Many& aux, TMeta meta, Index offset) { + Trait Thing::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { // Scan descriptor Trait result; aux.ForEachDeep([&](const Trait& trait) { @@ -180,36 +228,72 @@ namespace Langulus::Entity // If reached, then no trait was found in the descriptor // Let's delve into the hierarchy + return SeekTrait(meta, offset); + } + + /// Find a trait by type (and index) from the hierarchy, and attempt + /// converting it to a desired output type + /// Supports pinnable outputs + /// @tparam SEEK - direction to search at + /// @param meta - the trait type to search for + /// @param output - [out] the output + /// @param offset - the number of the matching trait to use + /// @return true if output was rewritten + template + bool Thing::SeekValue(TMeta meta, CT::Data auto& output, Index offset) const { + using D = Deref; + + if constexpr (CT::Pinnable) { + // Never touch pinned values + if (output.mLocked) + return false; + } + if constexpr (SEEK & Seek::Here) { // Seek here if requested - auto output = GetTrait(meta, offset); - if (output) - return Abandon(output); + auto temp = GetTrait(meta, offset); + try { + if (CT::Pinnable and temp.Is>()) + output = temp.As>(); + else if (not CT::Pinnable and temp.Is()) + output = temp.As(); + else if constexpr (CT::DescriptorMakable) + output = D {Describe(static_cast(temp))}; + else if constexpr (CT::Pinnable) + output = temp.template AsCast>(); + else + output = temp.template AsCast(); + + /*if constexpr (CT::Pinnable) + output = temp.template AsCast>(); + else + output = temp.template AsCast();*/ + return true; + } + catch (...) { } } if constexpr (SEEK & Seek::Above) { // Seek in parents up to root, if requested if (mOwner) { - auto output = mOwner->template - SeekTraitAux({}, meta, offset); - if (output) - return Abandon(output); + if (mOwner->template + SeekValue(meta, output, offset)) + return true; } } if constexpr (SEEK & Seek::Below) { // Seek children, if requested for (auto child : mChildren) { - auto output = child->template - SeekTraitAux({}, meta, offset); - if (output) - return Abandon(output); + if (child->template + SeekValue(meta, output, offset)) + return true; } } - return {}; + return false; } - + /// Find a value (regardless of trait) from the hierarchy, and attempt /// converting it to a desired output type. Scan the aux container first /// Supports pinnable outputs, and pinnables will be pinned if trait was @@ -221,7 +305,7 @@ namespace Langulus::Entity /// @return true if value has been found and rewritten template LANGULUS(INLINED) bool Thing::SeekValueAux( - TMeta meta, const Many& aux, CT::Data auto& output, Index offset + TMeta meta, const Neat& aux, CT::Data auto& output, Index offset ) const { using D = Deref; @@ -246,7 +330,7 @@ namespace Langulus::Entity // Didn't throw, but we're done only if offset matches done = offset == 0; --offset; - return done ? Loop::Break : Loop::Continue; + return not done; } catch (...) {} } @@ -266,7 +350,7 @@ namespace Langulus::Entity // Didn't throw, but we're done only if offset matches done = offset == 0; --offset; - return done ? Loop::Break : Loop::Continue; + return not done; } catch(...) { } @@ -286,50 +370,7 @@ namespace Langulus::Entity // If reached, then no data was found in the descriptor // Let's delve into the hierarchy - if constexpr (CT::Pinnable) { - // Never touch pinned values - if (output.mLocked) - return false; - } - - if constexpr (SEEK & Seek::Here) { - // Seek here if requested - auto temp = GetTrait(meta, offset); - try { - if (CT::Pinnable and temp.Is>()) - output = temp.As>(); - else if (not CT::Pinnable and temp.Is()) - output = temp.As(); - else if constexpr (CT::DescriptorMakable) - output = D {Describe(static_cast(temp))}; - else if constexpr (CT::Pinnable) - output = temp.template AsCast>(); - else - output = temp.template AsCast(); - return true; - } - catch (...) { } - } - - if constexpr (SEEK & Seek::Above) { - // Seek in parents up to root, if requested - if (mOwner) { - if (mOwner->template - SeekValueAux(meta, {}, output, offset)) - return true; - } - } - - if constexpr (SEEK & Seek::Below) { - // Seek children, if requested - for (auto child : mChildren) { - if (child->template - SeekValueAux(meta, {}, output, offset)) - return true; - } - } - - return false; + return SeekValue(meta, output, offset); } } // namespace Langulus::Entity diff --git a/source/Thing-Traits.cpp b/source/Thing-Traits.cpp index f8241ae..2b5db03 100644 --- a/source/Thing-Traits.cpp +++ b/source/Thing-Traits.cpp @@ -29,7 +29,7 @@ namespace Langulus::Entity /// @param trait - trait id /// @param offset - offset of result to use /// @return a filled trait if fount, empty if not - auto Thing::GetTrait(TMeta trait, Index offset) const -> Trait { + Trait Thing::GetTrait(TMeta trait, Index offset) const { return GetTrait(Trait::FromMeta(trait, nullptr), offset); } @@ -37,7 +37,7 @@ namespace Langulus::Entity /// @param trait - trait id /// @param offset - offset of result to use /// @return a filled trait if fount, empty if not - auto Thing::GetTrait(TMeta trait, Index offset) -> Trait { + Trait Thing::GetTrait(TMeta trait, Index offset) { return GetTrait(Trait::FromMeta(trait, nullptr), offset); } @@ -45,7 +45,7 @@ namespace Langulus::Entity /// @param id - the trait to search for /// @param index - the index of the trait we seek /// @return a pointer to the trait, or nullptr if not found - auto Thing::GetLocalTrait(TMeta id, Index index) -> Trait* { + Trait* Thing::GetLocalTrait(TMeta id, Index index) { if (id) { // Search a typed trait const auto found = mTraits.FindIt(id); @@ -76,7 +76,7 @@ namespace Langulus::Entity /// @param id - the trait to search for /// @param offset - the index of the trait we seek /// @return a pointer to the trait, or nullptr if not found - auto Thing::GetLocalTrait(TMeta id, Index offset) const -> const Trait* { + const Trait* Thing::GetLocalTrait(TMeta id, Index offset) const { return const_cast(*this).GetLocalTrait(id, offset); } @@ -84,7 +84,7 @@ namespace Langulus::Entity /// @param id - trait to match /// @param index - offset of result to use /// @return a non-empty trait, if found - auto Thing::GetTrait(const Trait& id, Index index) -> Trait { + Trait Thing::GetTrait(const Trait& id, Index index) { if (id.GetTrait()) { // Handle some predefined traits here if (id.template IsTrait()) { @@ -124,14 +124,14 @@ namespace Langulus::Entity /// @param id - trait to match /// @param index - offset of result to use /// @return a non-empty trait, if found - auto Thing::GetTrait(const Trait& id, Index index) const -> Trait { + Trait Thing::GetTrait(const Trait& id, Index index) const { return const_cast(this)->GetTrait(id, index); } /// Add a new trait to the thing /// @param trait - trait to shallow copy /// @return the new trait instance - auto Thing::AddTrait(Trait trait) -> Trait* { + Trait* Thing::AddTrait(Trait trait) { const auto tmeta = trait.GetTrait(); auto found = mTraits.FindIt(tmeta); if (found) { @@ -148,7 +148,7 @@ namespace Langulus::Entity /// Remove a trait from the universal entity /// @param trait - type of trait to remove /// @return the number of removed traits - auto Thing::RemoveTrait(TMeta trait) -> Count { + Count Thing::RemoveTrait(TMeta trait) { const auto found = mTraits.FindIt(trait); if (found) { const auto removed = found.GetValue().GetCount(); @@ -164,7 +164,7 @@ namespace Langulus::Entity /// Remove an exact-matching trait from this entity /// @param trait - type and value to remove /// @return the number of removed traits - auto Thing::RemoveTrait(Trait trait) -> Count { + Count Thing::RemoveTrait(Trait trait) { const auto found = mTraits.FindIt(trait.GetTrait()); if (found) { const auto removed = found.GetValue().Remove(trait); @@ -181,7 +181,7 @@ namespace Langulus::Entity /// A fast check whether traits of the given type are inside this entity /// @param trait - type of trait to check /// @return the number of matching traits - auto Thing::HasTraits(TMeta trait) const -> Count { + Count Thing::HasTraits(TMeta trait) const { const auto found = mTraits.FindIt(trait); return found ? found.GetValue().GetCount() : 0; } @@ -189,7 +189,7 @@ namespace Langulus::Entity /// A fast check whether traits of the given type and value are inside /// @param trait - trait to search for /// @return the number of matching traits - auto Thing::HasTraits(const Trait& trait) const -> Count { + Count Thing::HasTraits(const Trait& trait) const { const auto found = mTraits.FindIt(trait.GetTrait()); if (not found) return 0; @@ -205,7 +205,7 @@ namespace Langulus::Entity /// Get traits /// @return the map of traits LANGULUS_API(ENTITY) - auto Thing::GetTraits() const noexcept -> const TraitMap& { + const TraitMap& Thing::GetTraits() const noexcept { return mTraits; } @@ -223,9 +223,8 @@ namespace Langulus::Entity /// It can reside in one of the units /// @return the name, or empty string if no such trait was found here Text Thing::GetName() const { - Many unused; Text name; - SeekValueAux(name, unused); + SeekValue(name); return name; } diff --git a/source/Thing.cpp b/source/Thing.cpp index e0b133b..6cf98f8 100644 --- a/source/Thing.cpp +++ b/source/Thing.cpp @@ -54,10 +54,9 @@ namespace Langulus::Entity /// Construct as a child of another thing /// @param parent - the thing that owns this thing /// @param descriptor - instructions for creating the thing - Thing::Thing(Thing* parent, const Many& descriptor) + Thing::Thing(Thing* parent, const Neat& descriptor) : Resolvable {this} - , mOwner {parent} - { + , mOwner {parent} { if (parent) { parent->AddChild(this); mRuntime = parent->GetRuntime(); @@ -90,15 +89,14 @@ namespace Langulus::Entity /// because 'other' is removed from its children /// @param other - move that entity Thing::Thing(Thing&& other) noexcept - : Resolvable {this} - , mChildren {Move(other.mChildren)} - , mRuntime {Move(other.mRuntime)} - , mFlow {Move(other.mFlow)} + : Resolvable {this} + , mChildren {Move(other.mChildren)} + , mRuntime {Move(other.mRuntime)} + , mFlow {Move(other.mFlow)} , mUnitsAmbiguous {Move(other.mUnitsAmbiguous)} - , mUnitsList {Move(other.mUnitsList)} - , mTraits {Move(other.mTraits)} - , mRefreshRequired{true} - { + , mUnitsList {Move(other.mUnitsList)} + , mTraits {Move(other.mTraits)} + , mRefreshRequired {true} { // Remap children for (auto& child : mChildren) child->mOwner = this; @@ -120,15 +118,14 @@ namespace Langulus::Entity /// because 'other' is duplicated in its children /// @param other - clone that entity Thing::Thing(Abandoned&& other) - : Resolvable {this} - , mChildren {Abandon(other->mChildren)} - , mRuntime {Abandon(other->mRuntime)} - , mFlow {Abandon(other->mFlow)} + : Resolvable {this} + , mChildren {Abandon(other->mChildren)} + , mRuntime {Abandon(other->mRuntime)} + , mFlow {Abandon(other->mFlow)} , mUnitsAmbiguous {Abandon(other->mUnitsAmbiguous)} - , mUnitsList {Abandon(other->mUnitsList)} - , mTraits {Abandon(other->mTraits)} - , mRefreshRequired{true} - { + , mUnitsList {Abandon(other->mUnitsList)} + , mTraits {Abandon(other->mTraits)} + , mRefreshRequired {true} { // Remap children for (auto& child : mChildren) child->mOwner = this; @@ -150,10 +147,9 @@ namespace Langulus::Entity /// because 'other' is duplicated in its children /// @param other - clone that entity Thing::Thing(Cloned&& other) - : Resolvable {this} - , mChildren {Clone(other->mChildren)} - , mRefreshRequired{true} - { + : Resolvable {this} + , mChildren {Clone(other->mChildren)} + , mRefreshRequired {true} { TODO(); //TODO clone flow and runtime if pinned, recreate modules if new runtime, // recreate units and traits, then recreate children @@ -320,7 +316,7 @@ namespace Langulus::Entity /// @param id - the type of the unit /// @param index - the unit index to seek /// @return the unit if found, or nullptr if not - auto Thing::GetUnitMeta(DMeta id, Index index) -> A::Unit* { + A::Unit* Thing::GetUnitMeta(DMeta id, Index index) { if (id) { // Search a typed trait const auto found = mUnitsAmbiguous.FindIt(id); @@ -331,7 +327,7 @@ namespace Langulus::Entity return mUnitsList[index]; } - auto Thing::GetUnitMeta(DMeta type, Index offset) const -> const A::Unit* { + const A::Unit* Thing::GetUnitMeta(DMeta type, Index offset) const { return const_cast(this)->GetUnitMeta(type, offset); } @@ -342,7 +338,7 @@ namespace Langulus::Entity /// @param what - the desired properties of the unit /// @param index - the unit index to seek /// @return the unit if found, or nullptr if not - auto Thing::GetUnitExt(DMeta meta, const Many& what, Index index) -> A::Unit* { + A::Unit* Thing::GetUnitExt(DMeta meta, const Neat& what, Index index) { if (meta) { // Search a typed unit const auto found = mUnitsAmbiguous.FindIt(meta); @@ -375,7 +371,7 @@ namespace Langulus::Entity return nullptr; } - auto Thing::GetUnitExt(DMeta meta, const Many& what, Index index) const -> const A::Unit* { + const A::Unit* Thing::GetUnitExt(DMeta meta, const Neat& what, Index index) const { return const_cast(this)->GetUnitExt(meta, what, index); } @@ -384,31 +380,31 @@ namespace Langulus::Entity /// @param token - the type name of the unit /// @param offset - the unit index /// @return the unit if found, or nullptr if not - auto Thing::GetUnitMeta(const Token& token, Index offset) -> A::Unit* { + A::Unit* Thing::GetUnitMeta(const Token& token, Index offset) { return GetUnitMeta(RTTI::DisambiguateMeta(token), offset); } #endif /// Get the owner /// @return the owner - auto Thing::GetOwner() const noexcept -> const Ref& { + const Ref& Thing::GetOwner() const noexcept { return mOwner; } /// Get children hierarchy /// @return the hierarchy - auto Thing::GetChildren() const noexcept -> const Hierarchy& { + const Hierarchy& Thing::GetChildren() const noexcept { return mChildren; } /// Get a child by index /// @param id - the index to pick /// @return the child entity, or nullptr of none was found - auto Thing::GetChild(Index offset) -> Thing* { + Thing* Thing::GetChild(Index offset) { return mChildren[offset]; } - auto Thing::GetChild(Index offset) const -> const Thing* { + const Thing* Thing::GetChild(Index offset) const { return const_cast(this)->GetChild(offset); } @@ -416,7 +412,7 @@ namespace Langulus::Entity /// @param name - name to seek /// @param offset - offset to seek /// @return the child entity, or nullptr of none was found - auto Thing::GetNamedChild(const Token& name, Index offset) -> Thing* { + Thing* Thing::GetNamedChild(const Token& name, Index offset) { Index matches = 0; for (auto& child : mChildren) { if (child->GetName() == name) { @@ -429,7 +425,7 @@ namespace Langulus::Entity return nullptr; } - auto Thing::GetNamedChild(const Token& name, Index offset) const -> const Thing* { + const Thing* Thing::GetNamedChild(const Token& name, Index offset) const { return const_cast(this)->GetNamedChild(name, offset); } @@ -460,7 +456,7 @@ namespace Langulus::Entity /// Count the number of matching units in this entity /// @param type - the type of units to search for /// @return the number of matching units - auto Thing::HasUnits(DMeta type) const -> Count { + Count Thing::HasUnits(DMeta type) const { const auto found = mUnitsAmbiguous.FindIt(type); return found ? found.GetValue().GetCount() : 0; } @@ -473,19 +469,19 @@ namespace Langulus::Entity /// Get the current runtime /// @return the pointer to the runtime - auto Thing::GetRuntime() const noexcept -> const Pin>& { + const Pin>& Thing::GetRuntime() const noexcept { return mRuntime; } /// Get the current temporal flow /// @return the pointer to the flow - auto Thing::GetFlow() const noexcept -> const Pin>& { + const Pin>& Thing::GetFlow() const noexcept { return mFlow; } /// Create a local runtime for this thing /// @return the new runtime instance, or the old one if already created - auto Thing::CreateRuntime() -> Runtime* { + Runtime* Thing::CreateRuntime() { if (mRuntime.IsLocked()) return &*mRuntime; @@ -502,7 +498,7 @@ namespace Langulus::Entity /// Create a local flow for this thing /// @return the new flow instance, or the old one, if already created - auto Thing::CreateFlow() -> Temporal* { + Temporal* Thing::CreateFlow() { if (mFlow.IsLocked()) return &*mFlow; @@ -521,13 +517,13 @@ namespace Langulus::Entity /// instantiate it for use, if not yet instantiated /// @attention assumes a runtime is available in the hierarchy /// @param module - name of the module - /// @param desc - instructions for module setup + /// @param descriptor - instructions for module setup /// @return the instantiated module interface - auto Thing::LoadMod(const Token& module, const Many& desc) -> A::Module* { + A::Module* Thing::LoadMod(const Token& module, const Neat& descriptor) { const auto runtime = GetRuntime(); LANGULUS_ASSUME(UserAssumes, runtime, "No runtime available for loading a module"); - const auto instance = runtime->InstantiateModule(module, desc); + const auto instance = runtime->InstantiateModule(module, descriptor); LANGULUS_ASSERT(instance, Module, "Missing module"); return instance; } diff --git a/source/Thing.hpp b/source/Thing.hpp index d45cfe3..006c1ab 100644 --- a/source/Thing.hpp +++ b/source/Thing.hpp @@ -77,7 +77,7 @@ namespace Langulus::Entity public: LANGULUS_API(ENTITY) Thing(); LANGULUS_API(ENTITY) Thing(Describe&&); - LANGULUS_API(ENTITY) Thing(Thing*, const Many& = {}); + LANGULUS_API(ENTITY) Thing(Thing*, const Neat& = {}); LANGULUS_API(ENTITY) Thing(Thing&&) noexcept; LANGULUS_API(ENTITY) Thing(Cloned&&); LANGULUS_API(ENTITY) Thing(Abandoned&&); @@ -98,10 +98,10 @@ namespace Langulus::Entity bool RequiresRefresh() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetRuntime() const noexcept -> const Pin>&; + const Pin>& GetRuntime() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetFlow() const noexcept -> const Pin>&; + const Pin>& GetFlow() const noexcept; LANGULUS_API(ENTITY) void Do(Verb&); LANGULUS_API(ENTITY) void Select(Verb&); @@ -130,39 +130,39 @@ namespace Langulus::Entity /// Hierarchy management /// LANGULUS_API(ENTITY) - auto CreateRuntime() -> Runtime*; + Runtime* CreateRuntime(); LANGULUS_API(ENTITY) - auto CreateFlow() -> Temporal*; + Temporal* CreateFlow(); template - auto CreateChild(T&&...) -> Ref; + Ref CreateChild(T&&...); template - auto AddChild(Thing*) -> Count; + Count AddChild(Thing*); template - auto RemoveChild(Thing*) -> Count; + Count RemoveChild(Thing*); LANGULUS_API(ENTITY) - auto LoadMod(const Token&, const Many& = {}) -> A::Module*; + A::Module* LoadMod(const Token&, const Neat& = {}); NOD() LANGULUS_API(ENTITY) - auto GetOwner() const noexcept -> const Ref&; + const Ref& GetOwner() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetChildren() const noexcept -> const Hierarchy&; + const Hierarchy& GetChildren() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetChild(Index = 0) -> Thing*; + Thing* GetChild(Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetChild(Index = 0) const -> const Thing*; + const Thing* GetChild(Index = 0) const; NOD() LANGULUS_API(ENTITY) - auto GetNamedChild(const Token&, Index = 0) -> Thing*; + Thing* GetNamedChild(const Token&, Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetNamedChild(const Token&, Index = 0) const -> const Thing*; + const Thing* GetNamedChild(const Token&, Index = 0) const; LANGULUS_API(ENTITY) void DumpHierarchy() const; @@ -172,9 +172,9 @@ namespace Langulus::Entity /// Unit management /// template - auto AddUnit(A::Unit*) -> Count; + Count AddUnit(A::Unit*); template - auto RemoveUnit(A::Unit*) -> Count; + Count RemoveUnit(A::Unit*); template Many CreateUnit(A&&...); @@ -192,38 +192,38 @@ namespace Langulus::Entity NOD() LANGULUS_API(ENTITY) Count HasUnits(DMeta) const; - template NOD() - Count HasUnits() const; + template + NOD() Count HasUnits() const; NOD() LANGULUS_API(ENTITY) - auto GetUnits() const noexcept -> const UnitList&; + const UnitList& GetUnits() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetUnitsMap() const noexcept -> const UnitMap&; + const UnitMap& GetUnitsMap() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetUnitMeta(DMeta, Index = 0) -> A::Unit*; + A::Unit* GetUnitMeta(DMeta, Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetUnitMeta(DMeta, Index = 0) const -> const A::Unit*; + const A::Unit* GetUnitMeta(DMeta, Index = 0) const; NOD() LANGULUS_API(ENTITY) - auto GetUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; + A::Unit* GetUnitExt(DMeta, const Neat&, Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetUnitExt(DMeta, const Many&, Index = 0) const -> const A::Unit*; + const A::Unit* GetUnitExt(DMeta, const Neat&, Index = 0) const; - template NOD() - auto GetUnit(Index = 0) -> Decay*; - template NOD() - auto GetUnit(Index = 0) const -> const Decay*; + template + NOD() Decay* GetUnit(Index = 0); + template + NOD() const Decay* GetUnit(Index = 0) const; #if LANGULUS_FEATURE(MANAGED_REFLECTION) NOD() LANGULUS_API(ENTITY) - auto GetUnitMeta(const Token&, Index = 0) const -> A::Unit const*; + A::Unit const* GetUnitMeta(const Token&, Index = 0) const; NOD() LANGULUS_API(ENTITY) - auto GetUnitMeta(const Token&, Index = 0) -> A::Unit*; + A::Unit* GetUnitMeta(const Token&, Index = 0); - template NOD() - auto GetUnitAs(const Token&, Index = 0) -> Decay*; + template + NOD() Decay* GetUnitAs(const Token&, Index = 0); #endif private: @@ -234,38 +234,45 @@ namespace Langulus::Entity /// /// Trait management /// - LANGULUS_API(ENTITY) auto AddTrait(Trait) -> Trait*; + LANGULUS_API(ENTITY) Trait* AddTrait(Trait); - LANGULUS_API(ENTITY) auto RemoveTrait(TMeta) -> Count; - LANGULUS_API(ENTITY) auto RemoveTrait(Trait) -> Count; + LANGULUS_API(ENTITY) Count RemoveTrait(TMeta); + LANGULUS_API(ENTITY) Count RemoveTrait(Trait); NOD() LANGULUS_API(ENTITY) - auto HasTraits(TMeta) const -> Count; + Count HasTraits(TMeta) const; + NOD() LANGULUS_API(ENTITY) - auto HasTraits(const Trait&) const -> Count; + Count HasTraits(const Trait&) const; NOD() LANGULUS_API(ENTITY) - auto GetTraits() const noexcept -> const TraitMap&; + const TraitMap& GetTraits() const noexcept; NOD() LANGULUS_API(ENTITY) - auto GetTrait(TMeta, Index = 0) const -> Trait; + Trait GetTrait(TMeta, Index = 0) const; + NOD() LANGULUS_API(ENTITY) - auto GetTrait(TMeta, Index = 0) -> Trait; + Trait GetTrait(TMeta, Index = 0); + NOD() LANGULUS_API(ENTITY) - auto GetTrait(const Trait&, Index = 0) const -> Trait; + Trait GetTrait(const Trait&, Index = 0) const; + NOD() LANGULUS_API(ENTITY) - auto GetTrait(const Trait&, Index = 0) -> Trait; - template NOD() - auto GetTrait(Index = 0) -> Trait; + Trait GetTrait(const Trait&, Index = 0); + + template + NOD() Trait GetTrait(Index = 0); NOD() LANGULUS_API(ENTITY) - auto GetLocalTrait(TMeta, Index = 0) const -> const Trait*; + const Trait* GetLocalTrait(TMeta, Index = 0) const; + NOD() LANGULUS_API(ENTITY) - auto GetLocalTrait(TMeta, Index = 0) -> Trait*; - template NOD() - auto GetLocalTrait(Index = 0) -> Trait*; - template NOD() - auto GetLocalTrait(Index = 0) const -> Trait const*; + Trait* GetLocalTrait(TMeta, Index = 0); + + template + NOD() Trait* GetLocalTrait(Index = 0); + template + NOD() Trait const* GetLocalTrait(Index = 0) const; LANGULUS_API(ENTITY) void SetName(const Text&); @@ -276,24 +283,33 @@ namespace Langulus::Entity /// /// Seek /// + using SeekInterface::SeekUnit; using SeekInterface::SeekUnitAux; using SeekInterface::SeekUnitExt; using SeekInterface::SeekUnitAuxExt; + using SeekInterface::SeekTrait; using SeekInterface::SeekTraitAux; + using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; - template NOD() - auto SeekUnitAux(const Many&, DMeta, Index = 0) -> A::Unit*; - template NOD() - auto SeekUnitExt(DMeta, const Many&, Index = 0) -> A::Unit*; - template NOD() - auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> A::Unit*; + template + NOD() A::Unit* SeekUnit(DMeta, Index = 0); + template + NOD() A::Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); + template + NOD() A::Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); + template + NOD() A::Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); - template NOD() - auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Trait; + template + NOD() Trait SeekTrait(TMeta, Index = 0); + template + NOD() Trait SeekTraitAux(const Neat&, TMeta, Index = 0); template - bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; + bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; + template + bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -302,16 +318,16 @@ namespace Langulus::Entity using SeekInterface::GatherUnitsExt; using SeekInterface::GatherTraits; - template NOD() - auto GatherUnits(DMeta) -> TMany; - template NOD() - auto GatherUnitsExt(DMeta, const Many&) -> TMany; + template + NOD() TMany GatherUnits(DMeta); + template + NOD() TMany GatherUnitsExt(DMeta, const Neat&); - template NOD() - auto GatherTraits(TMeta) -> TraitList; + template + NOD() TraitList GatherTraits(TMeta); - template NOD() - auto GatherValues() const -> TMany; + template + NOD() TMany GatherValues() const; }; } // namespace Langulus::Entity \ No newline at end of file diff --git a/source/Thing.inl b/source/Thing.inl index e159916..f872bf1 100644 --- a/source/Thing.inl +++ b/source/Thing.inl @@ -581,8 +581,8 @@ namespace Langulus::Entity // Implicitly add a parent trait to descriptor, if one isn't // already added - it will be stripped later, when normalizing // the descriptor when producing the item from a factory - Construct descriptor = construct; - /*Traits::Parent parent; + Construct descriptor {construct}; + Traits::Parent parent; if (not descriptor->ExtractTrait(parent)) { parent = this; parent.MakeMissing(); @@ -592,7 +592,7 @@ namespace Langulus::Entity Reference(0), " references)" ); } - else parent << this;*/ + else parent << this; if (producer) { // Data has a specific producer, we can narrow the required diff --git a/source/Unit-Seek.inl b/source/Unit-Seek.inl index 022f701..8383394 100644 --- a/source/Unit-Seek.inl +++ b/source/Unit-Seek.inl @@ -13,6 +13,16 @@ namespace Langulus::A { + /// Find a specific unit, searching into the hierarchy + /// @tparam SEEK - where in the hierarchy are we seeking in? + /// @param meta - the unit to seek for + /// @param offset - which of the matches to return + /// @return the found unit, or nullptr if no such unit was found + template LANGULUS(INLINED) + Unit* Unit::SeekUnit(DMeta meta, Index offset) { + return mOwners.template SeekUnit(meta, offset); + } + /// Find a unit by type and index from the hierarchy /// @tparam SEEK - where to seek for the unit /// @param aux - descriptor to search through @@ -20,7 +30,7 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - Unit* Unit::SeekUnitAux(const Many& aux, DMeta meta, Index offset) { + Unit* Unit::SeekUnitAux(const Neat& aux, DMeta meta, Index offset) { return mOwners.template SeekUnitAux(aux, meta, offset); } @@ -31,7 +41,7 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return the unit if found, or nullptr otherwise template LANGULUS(INLINED) - Unit* Unit::SeekUnitExt(DMeta type, const Many& ext, Index offset) { + Unit* Unit::SeekUnitExt(DMeta type, const Neat& ext, Index offset) { return mOwners.template SeekUnitExt(type, ext, offset); } @@ -44,10 +54,20 @@ namespace Langulus::A /// @param offset - the index of the unit to return /// @return a pointer to the found unit, or nullptr if not found template LANGULUS(INLINED) - Unit* Unit::SeekUnitAuxExt(DMeta type, const Many& aux, const Many& ext, Index offset) { + Unit* Unit::SeekUnitAuxExt(DMeta type, const Neat& aux, const Neat& ext, Index offset) { return mOwners.template SeekUnitAuxExt(type, aux, ext, offset); } + /// Find a trait by type (and index), searching into the hierarchy + /// @tparam SEEK - direction to search at + /// @param meta - the trait to search for + /// @param offset - the offset to apply + /// @return the trait, which is not empty, if trait was found + template LANGULUS(INLINED) + Langulus::Trait Unit::SeekTrait(TMeta meta, Index offset) { + return mOwners.template SeekTrait(meta, offset); + } + /// Find a trait, searching into the hierarchy (const) /// @tparam SEEK - direction to search at /// @param aux - descriptor to search through @@ -55,10 +75,23 @@ namespace Langulus::A /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - Langulus::Trait Unit::SeekTraitAux(const Many& aux, TMeta meta, Index offset) { + Langulus::Trait Unit::SeekTraitAux(const Neat& aux, TMeta meta, Index offset) { return mOwners.template SeekTraitAux(aux, meta, offset); } + /// Find a trait by type (and index) from the hierarchy, and attempt + /// converting it to a desired output type + /// Supports pinnable outputs, and won't change anything if D is pinned + /// @tparam SEEK - direction to search at + /// @param meta - the trait type to search for + /// @param output - [out] the output + /// @param offset - the number of the matching trait to use + /// @return true if output was rewritten + template LANGULUS(INLINED) + bool Unit::SeekValue(TMeta meta, CT::Data auto& output, Index offset) const { + return mOwners.template SeekValue(meta, output, offset); + } + /// Find a trait by type (and index) from the hierarchy, and attempt /// converting it to a desired output type. Scan the aux container first /// Supports pinnable outputs, and pinnables will be pinned if trait was @@ -70,7 +103,7 @@ namespace Langulus::A /// @param offset - the number of the matching trait to use /// @return the trait, which is not empty, if trait was found template LANGULUS(INLINED) - bool Unit::SeekValueAux(TMeta meta, const Many& aux, CT::Data auto& output, Index offset) const { + bool Unit::SeekValueAux(TMeta meta, const Neat& aux, CT::Data auto& output, Index offset) const { return mOwners.template SeekValueAux(meta, aux, output, offset); } diff --git a/source/Unit.cpp b/source/Unit.cpp index 58694a6..6a7ab7c 100644 --- a/source/Unit.cpp +++ b/source/Unit.cpp @@ -12,8 +12,6 @@ using namespace Langulus::A; - -/// Unit destructor decouples from any owners Unit::~Unit() { for (auto entity : mOwners) Decouple(entity); @@ -29,11 +27,11 @@ void Unit::Select(Flow::Verb& verb) { /// Check if this unit has a given set of properties /// @param descriptor - descriptor with required properties /// @return true if the unit has the given properties -bool Unit::CompareDescriptor(const Many& descriptor) const { +bool Unit::CompareDescriptor(const Neat& descriptor) const { // First we compare traits only, all of them must be present bool mismatch = false; Offset memberOffset = 0; - descriptor.ForEachDeep([&](const Anyness::Trait& trait) { + descriptor.ForEach([&](const Anyness::Trait& trait) { if (not GetMember(trait.GetTrait(), memberOffset) .Compare(static_cast(trait))) { mismatch = true; @@ -45,9 +43,9 @@ bool Unit::CompareDescriptor(const Many& descriptor) const { }); // Then we run another check, based on data types, again, all - // of them must be present, either as trait, or in other form + // of them must be present, either in trait, or in other form memberOffset = 0; - descriptor.ForEachDeep([&](const Many& anythingElse) { + descriptor.ForEachTail([&](const Many& anythingElse) { if (not GetMember(TMeta {}, memberOffset).Compare(anythingElse)) { mismatch = true; return Loop::Break; @@ -62,7 +60,7 @@ bool Unit::CompareDescriptor(const Many& descriptor) const { /// Get the list of unit owners /// @return the owners -auto Unit::GetOwners() const noexcept -> const Hierarchy& { +const Hierarchy& Unit::GetOwners() const noexcept { return mOwners; } @@ -73,29 +71,24 @@ void Unit::Refresh() {} /// @attention assumes units are correctly coupled and coupling to /// different runtimes should be explicitly disallowed /// @return a pointer to the runtime, if available -auto Unit::GetRuntime() const noexcept -> Runtime* { +Runtime* Unit::GetRuntime() const noexcept { if (not mOwners) return nullptr; return &*mOwners[0]->GetRuntime(); } -/// Couple the component with an entity extracted from a descriptor's +/// Couple the component with an entity, extracted from a descriptor's /// Traits::Parent, if any was defined (always two-sided) /// This will call refresh to all units in that entity on next tick /// @param desc - the descriptor to scan for parents -/// @param fallback - a fallback Thing to couple to (optional) -/// This usually comes from the producer's context. For example, if you -/// don't provide a parent for the renderer, it will be instantiated as -/// a child to the graphics module owner (i.e. the runtime owner) -void Unit::Couple(const Many& desc, const Thing* fallback) { +void Unit::Couple(const Neat& desc) { + // Couple any Thing provided in the descriptor const Thing* owner = nullptr; if (not desc.ExtractTrait(owner)) desc.ExtractData(owner); if (owner and mOwners.Merge(IndexBack, const_cast(owner))) const_cast(owner)->AddUnit(this); - else if (fallback) - const_cast(fallback)->AddUnit(this); } /// Decouple the component from an entity (always two-sided) diff --git a/source/Unit.hpp b/source/Unit.hpp index edec2b8..f06f30b 100644 --- a/source/Unit.hpp +++ b/source/Unit.hpp @@ -63,9 +63,9 @@ namespace Langulus::A virtual void Refresh(); - auto GetRuntime() const noexcept -> Runtime*; - auto GetOwners() const noexcept -> const Hierarchy&; - bool CompareDescriptor(const Many&) const; + Runtime* GetRuntime() const noexcept; + const Hierarchy& GetOwners() const noexcept; + bool CompareDescriptor(const Neat&) const; /// /// Flow @@ -76,24 +76,33 @@ namespace Langulus::A /// /// Seek /// + using SeekInterface::SeekUnit; using SeekInterface::SeekUnitAux; using SeekInterface::SeekUnitExt; using SeekInterface::SeekUnitAuxExt; + using SeekInterface::SeekTrait; using SeekInterface::SeekTraitAux; + using SeekInterface::SeekValue; using SeekInterface::SeekValueAux; - template NOD() - auto SeekUnitAux(const Many&, DMeta, Index = 0) -> Unit*; - template NOD() - auto SeekUnitExt(DMeta, const Many&, Index = 0) -> Unit*; - template NOD() - auto SeekUnitAuxExt(DMeta, const Many&, const Many&, Index = 0) -> Unit*; + template + NOD() Unit* SeekUnit(DMeta, Index = 0); + template + NOD() Unit* SeekUnitAux(const Neat&, DMeta, Index = 0); + template + NOD() Unit* SeekUnitExt(DMeta, const Neat&, Index = 0); + template + NOD() Unit* SeekUnitAuxExt(DMeta, const Neat&, const Neat&, Index = 0); - template NOD() - auto SeekTraitAux(const Many&, TMeta, Index = 0) -> Langulus::Trait; + template + NOD() Langulus::Trait SeekTrait(TMeta, Index = 0); + template + NOD() Langulus::Trait SeekTraitAux(const Neat&, TMeta, Index = 0); template - bool SeekValueAux(TMeta, const Many&, CT::Data auto&, Index = 0) const; + bool SeekValue(TMeta, CT::Data auto&, Index = 0) const; + template + bool SeekValueAux(TMeta, const Neat&, CT::Data auto&, Index = 0) const; /// /// Gather @@ -102,19 +111,19 @@ namespace Langulus::A using SeekInterface::GatherUnitsExt; using SeekInterface::GatherTraits; - template NOD() - auto GatherUnits(DMeta) -> TMany; - template NOD() - auto GatherUnitsExt(DMeta, const Many&) -> TMany; + template + NOD() TMany GatherUnits(DMeta); + template + NOD() TMany GatherUnitsExt(DMeta, const Neat&); - template NOD() - auto GatherTraits(TMeta) -> TraitList; + template + NOD() TraitList GatherTraits(TMeta); - template NOD() - auto GatherValues() const -> TMany; + template + NOD() TMany GatherValues() const; protected: - void Couple(const Many&, const Thing* fallback = nullptr); + void Couple(const Neat&); void Decouple(const Thing*); void ReplaceOwner(const Thing*, const Thing*); };