/* @file StructTdx.hpp */ #pragma once #include "reflect/TypeDescrExtra.hpp" #include "reflect/TaggedPtr.hpp" #include "reflect/struct/StructMember.hpp" #include #include #include namespace xo { namespace reflect { /* Extra type-associated information for a struct/class. * We use this to preserve information about memory layout * at runtime */ class StructTdx : public TypeDescrExtra { public: /* named ctor idiom. create new instance for struct with given member list * * to_self_tp. use this function to support .most_derived_self_tp() */ static std::unique_ptr make(std::vector member_v, bool have_to_self_tp, std::function to_self_tp); /* specialization for std::pair * coordinates with [reflect/Reflect.hpp] */ template static std::unique_ptr pair() { using struct_t = std::pair; std::vector mv; { auto lhs_access (GeneralStructMemberAccessor::make (&struct_t::first)); mv.push_back(StructMember("first", std::move(lhs_access))); } { auto rhs_access (GeneralStructMemberAccessor::make (&struct_t::second)); mv.push_back(StructMember("second", std::move(rhs_access))); } std::function null_to_self_tp; return make(std::move(mv), false /*!have_to_self_tp*/, null_to_self_tp); } /*pair*/ // ----- Inherited from TypeDescrExtra ----- virtual Metatype metatype() const override { return Metatype::mt_struct; } virtual TaggedPtr most_derived_self_tp(TypeDescrBase const * object_td, void * object) const override { if (this->have_to_self_tp_) { return this->to_self_tp_(object); } else { return TypeDescrExtra::most_derived_self_tp(object_td, object); } } virtual uint32_t n_child(void * /*object*/) const override { return this->member_v_.size(); } virtual TaggedPtr child_tp(uint32_t i, void * object) const override; virtual std::string const & struct_member_name(uint32_t i) const override; virtual StructMember const * struct_member(uint32_t i) const override; private: StructTdx(std::vector member_v, bool have_to_self_tp, std::function to_self_tp) : member_v_{std::move(member_v)}, have_to_self_tp_{have_to_self_tp}, to_self_tp_{std::move(to_self_tp)} {} private: /* per-instance-variable reflection details */ std::vector member_v_; /* true if .to_self_tp() is defined */ bool have_to_self_tp_ = false; /* get TaggedPtr for most-derived subtype of supplied T-instance */ std::function to_self_tp_; }; /*StructTdx*/ } /*namespace reflect*/ } /*namespace xo*/ /* end StructTdx.hpp */