From 2b9aff3640c69d01f06d7b4f7447ba35a4b6dc9b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 25 Jun 2024 19:37:16 -0400 Subject: [PATCH] xo-reflect: + TypeDescr:: n_child_fixed(), fixed_child_td(i) --- include/xo/reflect/TypeDescr.hpp | 13 ++++++++++++- include/xo/reflect/TypeDescrExtra.hpp | 6 ++++++ include/xo/reflect/atomic/AtomicTdx.hpp | 1 + include/xo/reflect/function/FunctionTdx.hpp | 1 + include/xo/reflect/struct/StructTdx.hpp | 1 + include/xo/reflect/vector/VectorTdx.hpp | 10 ++++++++++ src/reflect/atomic/AtomicTdx.cpp | 6 ++++++ src/reflect/function/FunctionTdx.cpp | 6 ++++++ src/reflect/struct/StructTdx.cpp | 14 +++++++++++++- 9 files changed, 56 insertions(+), 2 deletions(-) diff --git a/include/xo/reflect/TypeDescr.hpp b/include/xo/reflect/TypeDescr.hpp index 870d356..a91befc 100644 --- a/include/xo/reflect/TypeDescr.hpp +++ b/include/xo/reflect/TypeDescr.hpp @@ -305,7 +305,18 @@ namespace xo { * .n_child() reports #of instance variables (that have been reflected) */ uint32_t n_child(void * object) const { return this->tdextra_->n_child(object); } - /** in some circumstances can use this with object=nullptr **/ + /** number of children, if that number is fixed at compile time. otherwise 0 + **/ + uint32_t n_child_fixed() const { return this->tdextra_->n_child_fixed(); } + /** TypeDescr for i'th child, using only information available at compile time. + * e.g. for vectors/pointers, always returns ElementType. + **/ + TypeDescr fixed_child_td(uint32_t i) const { return this->tdextra_->fixed_child_td(i); } + /** TaggedPtr to child @p i. + * Will report most-derived-type for type tag, + * so may refer to a proper subtype (e.g. derived class) of the type + * reported by @c fixed_child_td(i) + **/ TaggedPtr child_tp(uint32_t i, void * object) const; /* require: diff --git a/include/xo/reflect/TypeDescrExtra.hpp b/include/xo/reflect/TypeDescrExtra.hpp index 6829165..f53508a 100644 --- a/include/xo/reflect/TypeDescrExtra.hpp +++ b/include/xo/reflect/TypeDescrExtra.hpp @@ -59,6 +59,12 @@ namespace xo { * Will also return 0 for types like {bool, int, long} (because number is zero) **/ virtual uint32_t n_child_fixed() const = 0; + /** type description for i'th child, based on information available at compile time. + * For vectors/pointers, this always refers to element type. + * + * nullptr for atomics + **/ + virtual const TypeDescrBase * fixed_child_td(uint32_t i) const = 0; virtual TaggedPtr child_tp(uint32_t i, void * object) const = 0; /* require: * .is_struct() diff --git a/include/xo/reflect/atomic/AtomicTdx.hpp b/include/xo/reflect/atomic/AtomicTdx.hpp index 9bd5e56..d506819 100644 --- a/include/xo/reflect/atomic/AtomicTdx.hpp +++ b/include/xo/reflect/atomic/AtomicTdx.hpp @@ -26,6 +26,7 @@ namespace xo { virtual uint32_t n_child(void * /*object*/) const override { return 0; } virtual uint32_t n_child_fixed() const override { return 0; } virtual TaggedPtr child_tp(uint32_t /*i*/, void * /*object*/) const override; + virtual const TypeDescrBase * fixed_child_td(uint32_t /*i*/) const override; virtual std::string const & struct_member_name(uint32_t i) const override; //virtual StructMember const * struct_member(uint32_t /*i*/) const override { return nullptr; } diff --git a/include/xo/reflect/function/FunctionTdx.hpp b/include/xo/reflect/function/FunctionTdx.hpp index 64b02da..02f6055 100644 --- a/include/xo/reflect/function/FunctionTdx.hpp +++ b/include/xo/reflect/function/FunctionTdx.hpp @@ -35,6 +35,7 @@ namespace xo { virtual uint32_t n_child(void * /*object*/) const override { return 0; } virtual uint32_t n_child_fixed() const override { return 0; } virtual TaggedPtr child_tp(uint32_t i, void * object) const override; + virtual TypeDescr fixed_child_td(uint32_t i) const override; const std::string & struct_member_name(uint32_t i) const override; virtual const FunctionTdxInfo * fn_info() const override { return &info_; } diff --git a/include/xo/reflect/struct/StructTdx.hpp b/include/xo/reflect/struct/StructTdx.hpp index 0cd524d..57afe27 100644 --- a/include/xo/reflect/struct/StructTdx.hpp +++ b/include/xo/reflect/struct/StructTdx.hpp @@ -71,6 +71,7 @@ namespace xo { virtual uint32_t n_child(void * /*object*/) const override { return this->member_v_.size(); } virtual uint32_t n_child_fixed() const override { return this->member_v_.size(); } virtual TaggedPtr child_tp(uint32_t i, void * object) const override; + virtual TypeDescr fixed_child_td(uint32_t i) const override; virtual std::string const & struct_member_name(uint32_t i) const override; virtual StructMember const * struct_member(uint32_t i) const override; diff --git a/include/xo/reflect/vector/VectorTdx.hpp b/include/xo/reflect/vector/VectorTdx.hpp index dcdc20c..ebd318c 100644 --- a/include/xo/reflect/vector/VectorTdx.hpp +++ b/include/xo/reflect/vector/VectorTdx.hpp @@ -26,6 +26,7 @@ namespace xo { virtual uint32_t n_child(void * object) const override = 0; virtual uint32_t n_child_fixed() const override = 0; virtual TaggedPtr child_tp(uint32_t i, void * object) const override = 0; + virtual TypeDescr fixed_child_td(uint32_t i) const override = 0; /* (forbidden) */ virtual std::string const & struct_member_name(uint32_t i) const override; }; /*VectorTdx*/ @@ -33,6 +34,7 @@ namespace xo { // ----- StlVectorTdx ----- /* require: + * - VectorT::value_type * - VectorT.size() * - VectorT[int] :: lvalue */ @@ -60,6 +62,10 @@ namespace xo { return establish_most_derived_tp(&((*vec)[i])); } /*child_tp*/ + + virtual TypeDescr fixed_child_td(uint32_t /*i*/) const override { + return EstablishTypeDescr::establish(); + } }; /*StlVectorTdx*/ // ----- std::array ----- @@ -105,6 +111,10 @@ namespace xo { return establish_most_derived_tp(&((*vec)[i])); } + + virtual TypeDescr fixed_child_td(uint32_t /*i*/) const override { + return EstablishTypeDescr::establish(); + } }; /*StdVectorTdx*/ } /*namespace reflect*/ diff --git a/src/reflect/atomic/AtomicTdx.cpp b/src/reflect/atomic/AtomicTdx.cpp index 86e5d5b..bb7e1b8 100644 --- a/src/reflect/atomic/AtomicTdx.cpp +++ b/src/reflect/atomic/AtomicTdx.cpp @@ -2,6 +2,7 @@ #include "atomic/AtomicTdx.hpp" #include "TaggedPtr.hpp" +#include "TypeDescr.hpp" #include namespace xo { @@ -16,6 +17,11 @@ namespace xo { return TaggedPtr::universal_null(); } /*child_tp*/ + TypeDescr + AtomicTdx::fixed_child_td(uint32_t /*i*/) const { + return nullptr; + } + std::string const & AtomicTdx::struct_member_name(uint32_t i) const { return TypeDescrExtra::struct_member_name(i); diff --git a/src/reflect/function/FunctionTdx.cpp b/src/reflect/function/FunctionTdx.cpp index 27c0f8f..551cfef 100644 --- a/src/reflect/function/FunctionTdx.cpp +++ b/src/reflect/function/FunctionTdx.cpp @@ -2,6 +2,7 @@ #include "function/FunctionTdx.hpp" #include "TaggedPtr.hpp" +#include "TypeDescr.hpp" namespace xo { namespace reflect { @@ -36,6 +37,11 @@ namespace xo { return TaggedPtr::universal_null(); } + TypeDescr + FunctionTdx::fixed_child_td(uint32_t /*i*/) const { + return nullptr; + } + const std::string & FunctionTdx::struct_member_name(uint32_t i) const { diff --git a/src/reflect/struct/StructTdx.cpp b/src/reflect/struct/StructTdx.cpp index bf96972..c9edc11 100644 --- a/src/reflect/struct/StructTdx.cpp +++ b/src/reflect/struct/StructTdx.cpp @@ -1,6 +1,7 @@ /* @file StructTdx.cpp */ #include "struct/StructTdx.hpp" +#include "TypeDescr.hpp" namespace xo { using std::uint32_t; @@ -24,12 +25,23 @@ namespace xo { return TaggedPtr::universal_null(); } - StructMember const & member_info = this->member_v_[i]; + const StructMember & member_info = this->member_v_[i]; return member_info.get_member_tp(object); } /*get_child*/ + TypeDescr + StructTdx::fixed_child_td(uint32_t i ) const + { + if (i >= this->member_v_.size()) + return nullptr; + + const StructMember & member_info = this->member_v_[i]; + + return member_info.get_member_td(); + } /*fixed_child_td*/ + std::string const & StructTdx::struct_member_name(uint32_t i) const {