cosmetic: indentation
This commit is contained in:
parent
c8280cb8c4
commit
9718be824b
2 changed files with 287 additions and 288 deletions
|
|
@ -17,219 +17,219 @@
|
|||
#include <utility> // for std::pair<>
|
||||
|
||||
namespace xo {
|
||||
namespace reflect {
|
||||
template<typename T>
|
||||
class EstablishTdx {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make() { return AtomicTdx::make(); }
|
||||
}; /*EstablishTdx*/
|
||||
namespace reflect {
|
||||
template<typename T>
|
||||
class EstablishTdx {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make() { return AtomicTdx::make(); }
|
||||
}; /*EstablishTdx*/
|
||||
|
||||
// ----- xo::ref::rp<Object> -----
|
||||
// ----- xo::ref::rp<Object> -----
|
||||
|
||||
/* definition provide after decl for Reflect {} below */
|
||||
template<typename Object>
|
||||
class EstablishTdx<xo::ref::rp<Object>> {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make();
|
||||
}; /*EstablishTdx*/
|
||||
/* definition provide after decl for Reflect {} below */
|
||||
template<typename Object>
|
||||
class EstablishTdx<xo::ref::rp<Object>> {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make();
|
||||
}; /*EstablishTdx*/
|
||||
|
||||
// ----- std::array<Element, N> -----
|
||||
// ----- std::array<Element, N> -----
|
||||
|
||||
/* definition provide after decl for Reflect {} below */
|
||||
template<typename Element, std::size_t N>
|
||||
class EstablishTdx<std::array<Element, N>> {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make();
|
||||
}; /*EstablishTdx*/
|
||||
/* definition provide after decl for Reflect {} below */
|
||||
template<typename Element, std::size_t N>
|
||||
class EstablishTdx<std::array<Element, N>> {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make();
|
||||
}; /*EstablishTdx*/
|
||||
|
||||
// ----- std::vector<Element> -----
|
||||
// ----- std::vector<Element> -----
|
||||
|
||||
/* definition provide after decl for Reflect {} below */
|
||||
template<typename Element>
|
||||
class EstablishTdx<std::vector<Element>> {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make();
|
||||
}; /*EstablishTdx*/
|
||||
/* definition provide after decl for Reflect {} below */
|
||||
template<typename Element>
|
||||
class EstablishTdx<std::vector<Element>> {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make();
|
||||
}; /*EstablishTdx*/
|
||||
|
||||
// ----- std::pair<Lhs, Rhs> -----
|
||||
// ----- std::pair<Lhs, Rhs> -----
|
||||
|
||||
/* definition provide after decl for Reflect {} below */
|
||||
template<typename Lhs, typename Rhs>
|
||||
class EstablishTdx<std::pair<Lhs, Rhs>> {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make();
|
||||
}; /*EstablishTdx*/
|
||||
/* definition provide after decl for Reflect {} below */
|
||||
template<typename Lhs, typename Rhs>
|
||||
class EstablishTdx<std::pair<Lhs, Rhs>> {
|
||||
public:
|
||||
static std::unique_ptr<TypeDescrExtra> make();
|
||||
}; /*EstablishTdx*/
|
||||
|
||||
// ----- MakeTagged -----
|
||||
// ----- MakeTagged -----
|
||||
|
||||
template<typename T>
|
||||
class TaggedPtrMaker {
|
||||
public:
|
||||
static TaggedPtr make_tp(T * x);
|
||||
static TaggedRcptr make_rctp(T * x);
|
||||
};
|
||||
template<typename T>
|
||||
class TaggedPtrMaker {
|
||||
public:
|
||||
static TaggedPtr make_tp(T * x);
|
||||
static TaggedRcptr make_rctp(T * x);
|
||||
};
|
||||
|
||||
template<>
|
||||
class TaggedPtrMaker<SelfTagging> {
|
||||
public:
|
||||
static TaggedPtr make_tp(SelfTagging * x) {
|
||||
return x->self_tp();
|
||||
} /*make_tp*/
|
||||
template<>
|
||||
class TaggedPtrMaker<SelfTagging> {
|
||||
public:
|
||||
static TaggedPtr make_tp(SelfTagging * x) {
|
||||
return x->self_tp();
|
||||
} /*make_tp*/
|
||||
|
||||
static TaggedRcptr make_rctp(SelfTagging * x) {
|
||||
return x->self_tp();
|
||||
} /*make_rctp*/
|
||||
}; /*TaggedPtrMaker*/
|
||||
static TaggedRcptr make_rctp(SelfTagging * x) {
|
||||
return x->self_tp();
|
||||
} /*make_rctp*/
|
||||
}; /*TaggedPtrMaker*/
|
||||
|
||||
// ----- Reflect -----
|
||||
// ----- Reflect -----
|
||||
|
||||
class Reflect {
|
||||
public:
|
||||
/* Use:
|
||||
* using mytype = ...;
|
||||
* if (Reflect::is_reflected<mytype>()) { ... }
|
||||
*/
|
||||
template<typename T>
|
||||
static bool is_reflected() { return TypeDescrBase::is_reflected(&typeid(T)); }
|
||||
class Reflect {
|
||||
public:
|
||||
/* Use:
|
||||
* using mytype = ...;
|
||||
* if (Reflect::is_reflected<mytype>()) { ... }
|
||||
*/
|
||||
template<typename T>
|
||||
static bool is_reflected() { return TypeDescrBase::is_reflected(&typeid(T)); }
|
||||
|
||||
/* Use:
|
||||
* using mytype = ...;
|
||||
* TypeDescrW td = Reflect::require<mytype>();
|
||||
*
|
||||
* Note:
|
||||
* To avoid cyclic header dependencies
|
||||
* (between EstablishTypeDescr.hpp <-> {vector/VectorTdx.hpp etc.},
|
||||
* we use a 2-stage setup process:
|
||||
*
|
||||
* 1. EstablishTypeDescr::establish<T>() creates a TypeDescr* object
|
||||
* with lowest-common-denominator .tdextra AtomicTdx.
|
||||
* (see [reflect/EstablishTypeDescr.hpp])
|
||||
*
|
||||
* 2. Reflect::require<T>() upgrades .tdextra to suitable implementation
|
||||
* depending on T; this means also need to visit reflection info
|
||||
* (TypeDescr objects) for nested types to upgrade them too.
|
||||
*
|
||||
* This allows template-fu for a compound type (like std::vector<T>),
|
||||
* implemented in specialized header (like [reflect/struct/VectorTdx.hpp]) to
|
||||
* refer to reflection info for T without having to pull in all the
|
||||
* headers needed to properly reflect T (like this [reflect/Reflect.hpp])
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
static TypeDescrW require() {
|
||||
TypeDescrW retval_td = EstablishTypeDescr::establish<T>();
|
||||
/* Use:
|
||||
* using mytype = ...;
|
||||
* TypeDescrW td = Reflect::require<mytype>();
|
||||
*
|
||||
* Note:
|
||||
* To avoid cyclic header dependencies
|
||||
* (between EstablishTypeDescr.hpp <-> {vector/VectorTdx.hpp etc.},
|
||||
* we use a 2-stage setup process:
|
||||
*
|
||||
* 1. EstablishTypeDescr::establish<T>() creates a TypeDescr* object
|
||||
* with lowest-common-denominator .tdextra AtomicTdx.
|
||||
* (see [reflect/EstablishTypeDescr.hpp])
|
||||
*
|
||||
* 2. Reflect::require<T>() upgrades .tdextra to suitable implementation
|
||||
* depending on T; this means also need to visit reflection info
|
||||
* (TypeDescr objects) for nested types to upgrade them too.
|
||||
*
|
||||
* This allows template-fu for a compound type (like std::vector<T>),
|
||||
* implemented in specialized header (like [reflect/struct/VectorTdx.hpp]) to
|
||||
* refer to reflection info for T without having to pull in all the
|
||||
* headers needed to properly reflect T (like this [reflect/Reflect.hpp])
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
static TypeDescrW require() {
|
||||
TypeDescrW retval_td = EstablishTypeDescr::establish<T>();
|
||||
|
||||
/* mark TypeDescr for T as complete (even though it isn't quite yet),
|
||||
* so that when we encounter recursive types, reflection terminates.
|
||||
* For example consider type resulting from code like
|
||||
*
|
||||
* typename T;
|
||||
* using T = std::vector<T *>;
|
||||
*
|
||||
*/
|
||||
if (retval_td->mark_complete()) {
|
||||
/* control here on 2nd+later calls to require<T>().
|
||||
* in principle can immediately short-circuit.
|
||||
*/
|
||||
} else {
|
||||
/* control comes here the first time require<T>() runs */
|
||||
/* mark TypeDescr for T as complete (even though it isn't quite yet),
|
||||
* so that when we encounter recursive types, reflection terminates.
|
||||
* For example consider type resulting from code like
|
||||
*
|
||||
* typename T;
|
||||
* using T = std::vector<T *>;
|
||||
*
|
||||
*/
|
||||
if (retval_td->mark_complete()) {
|
||||
/* control here on 2nd+later calls to require<T>().
|
||||
* in principle can immediately short-circuit.
|
||||
*/
|
||||
} else {
|
||||
/* control comes here the first time require<T>() runs */
|
||||
|
||||
auto final_tdx = EstablishTdx<T>::make();
|
||||
auto final_tdx = EstablishTdx<T>::make();
|
||||
|
||||
retval_td->assign_tdextra(std::move(final_tdx));
|
||||
retval_td->assign_tdextra(std::move(final_tdx));
|
||||
|
||||
/* also need to require for each child */
|
||||
}
|
||||
/* also need to require for each child */
|
||||
}
|
||||
|
||||
return retval_td;
|
||||
} /*require*/
|
||||
return retval_td;
|
||||
} /*require*/
|
||||
|
||||
/* Use:
|
||||
* T * xyz = ...;
|
||||
* TaggedPtr xyz_tp = Reflect::make_tp(xyz);
|
||||
*/
|
||||
template<typename T>
|
||||
static TaggedPtr make_tp(T * x) { return TaggedPtrMaker<T>::make_tp(x); }
|
||||
/* Use:
|
||||
* T * xyz = ...;
|
||||
* TaggedPtr xyz_tp = Reflect::make_tp(xyz);
|
||||
*/
|
||||
template<typename T>
|
||||
static TaggedPtr make_tp(T * x) { return TaggedPtrMaker<T>::make_tp(x); }
|
||||
|
||||
template<typename T>
|
||||
static TaggedRcptr make_rctp(T * x) { return TaggedPtrMaker<T>::make_rctp(x); }
|
||||
}; /*Reflect*/
|
||||
template<typename T>
|
||||
static TaggedRcptr make_rctp(T * x) { return TaggedPtrMaker<T>::make_rctp(x); }
|
||||
}; /*Reflect*/
|
||||
|
||||
// ----- MakeTagged -----
|
||||
// ----- MakeTagged -----
|
||||
|
||||
template<typename T>
|
||||
TaggedPtr
|
||||
TaggedPtrMaker<T>::make_tp(T * x) {
|
||||
return TaggedPtr(Reflect::require<T>(), x);
|
||||
} /*make_tp*/
|
||||
template<typename T>
|
||||
TaggedPtr
|
||||
TaggedPtrMaker<T>::make_tp(T * x) {
|
||||
return TaggedPtr(Reflect::require<T>(), x);
|
||||
} /*make_tp*/
|
||||
|
||||
template<typename T>
|
||||
TaggedRcptr
|
||||
TaggedPtrMaker<T>::make_rctp(T * x) {
|
||||
return TaggedRcptr(Reflect::require<T>(), x);
|
||||
} /*make_rctp*/
|
||||
template<typename T>
|
||||
TaggedRcptr
|
||||
TaggedPtrMaker<T>::make_rctp(T * x) {
|
||||
return TaggedRcptr(Reflect::require<T>(), x);
|
||||
} /*make_rctp*/
|
||||
|
||||
// ----- xo::ref::rp<Object> -----
|
||||
// ----- xo::ref::rp<Object> -----
|
||||
|
||||
/* declared above before
|
||||
* class Reflect { .. }
|
||||
*/
|
||||
template<typename Object>
|
||||
std::unique_ptr<TypeDescrExtra>
|
||||
EstablishTdx<xo::ref::rp<Object>>::make() {
|
||||
/* need to ensure Object is property reflected.
|
||||
*
|
||||
* In practice must be a class type, since has to store refcount
|
||||
* + supply assoc'd incr/decr methods
|
||||
*/
|
||||
Reflect::require<Object>();
|
||||
/* declared above before
|
||||
* class Reflect { .. }
|
||||
*/
|
||||
template<typename Object>
|
||||
std::unique_ptr<TypeDescrExtra>
|
||||
EstablishTdx<xo::ref::rp<Object>>::make() {
|
||||
/* need to ensure Object is property reflected.
|
||||
*
|
||||
* In practice must be a class type, since has to store refcount
|
||||
* + supply assoc'd incr/decr methods
|
||||
*/
|
||||
Reflect::require<Object>();
|
||||
|
||||
return RefPointerTdx<xo::ref::rp<Object>>::make();
|
||||
} /*make*/
|
||||
return RefPointerTdx<xo::ref::rp<Object>>::make();
|
||||
} /*make*/
|
||||
|
||||
// ----- std::array<Element, N> -----
|
||||
// ----- std::array<Element, N> -----
|
||||
|
||||
/* declared above before
|
||||
* class Reflect { .. }
|
||||
*/
|
||||
template<typename Element, std::size_t N>
|
||||
std::unique_ptr<TypeDescrExtra>
|
||||
EstablishTdx<std::array<Element, N>>::make() {
|
||||
/* need to ensure Element is properly reflected */
|
||||
Reflect::require<Element>();
|
||||
/* declared above before
|
||||
* class Reflect { .. }
|
||||
*/
|
||||
template<typename Element, std::size_t N>
|
||||
std::unique_ptr<TypeDescrExtra>
|
||||
EstablishTdx<std::array<Element, N>>::make() {
|
||||
/* need to ensure Element is properly reflected */
|
||||
Reflect::require<Element>();
|
||||
|
||||
return StdArrayTdx<Element, N>::make();
|
||||
} /*make*/
|
||||
return StdArrayTdx<Element, N>::make();
|
||||
} /*make*/
|
||||
|
||||
// ----- std::vector<Element> -----
|
||||
// ----- std::vector<Element> -----
|
||||
|
||||
/* declared above before
|
||||
* class Reflect { .. }
|
||||
*/
|
||||
template<typename Element>
|
||||
std::unique_ptr<TypeDescrExtra>
|
||||
EstablishTdx<std::vector<Element>>::make() {
|
||||
/* need to ensure Element is properly reflected */
|
||||
Reflect::require<Element>();
|
||||
/* declared above before
|
||||
* class Reflect { .. }
|
||||
*/
|
||||
template<typename Element>
|
||||
std::unique_ptr<TypeDescrExtra>
|
||||
EstablishTdx<std::vector<Element>>::make() {
|
||||
/* need to ensure Element is properly reflected */
|
||||
Reflect::require<Element>();
|
||||
|
||||
return StdVectorTdx<Element>::make();
|
||||
} /*make*/
|
||||
return StdVectorTdx<Element>::make();
|
||||
} /*make*/
|
||||
|
||||
// ----- std::pair<Lhs, Rhs> -----
|
||||
// ----- std::pair<Lhs, Rhs> -----
|
||||
|
||||
/* declared above before
|
||||
* class Reflect { .. }
|
||||
*/
|
||||
template<typename Lhs, typename Rhs>
|
||||
std::unique_ptr<TypeDescrExtra>
|
||||
EstablishTdx<std::pair<Lhs, Rhs>>::make() {
|
||||
/* need to ensure Lhs, Rhs are properly reflected */
|
||||
Reflect::require<Lhs>();
|
||||
Reflect::require<Rhs>();
|
||||
/* declared above before
|
||||
* class Reflect { .. }
|
||||
*/
|
||||
template<typename Lhs, typename Rhs>
|
||||
std::unique_ptr<TypeDescrExtra>
|
||||
EstablishTdx<std::pair<Lhs, Rhs>>::make() {
|
||||
/* need to ensure Lhs, Rhs are properly reflected */
|
||||
Reflect::require<Lhs>();
|
||||
Reflect::require<Rhs>();
|
||||
|
||||
return StructTdx::pair<Lhs, Rhs>();
|
||||
} /*make*/
|
||||
} /*namespace reflect*/
|
||||
return StructTdx::pair<Lhs, Rhs>();
|
||||
} /*make*/
|
||||
} /*namespace reflect*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end Reflect.hpp */
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
//#include "reflect/atomic/AtomicTdx.hpp"
|
||||
#include "TypeDescrExtra.hpp"
|
||||
#include "cxxutil/demangle.hpp"
|
||||
#include <iostream>
|
||||
|
|
@ -16,80 +15,80 @@
|
|||
#include <cassert>
|
||||
|
||||
namespace xo {
|
||||
namespace reflect {
|
||||
class TaggedPtr; /* see [reflect/TaggedPtr.hpp] */
|
||||
namespace reflect {
|
||||
class TaggedPtr; /* see [reflect/TaggedPtr.hpp] */
|
||||
|
||||
/* A reflected type is a type for which we keep information around at runtime
|
||||
* Assign reflected types unique (within an executable) ids,
|
||||
* allocating consecutively, starting from 1.
|
||||
* Reserve 0 as a sentinel
|
||||
*/
|
||||
class TypeId {
|
||||
public:
|
||||
/* allocate a new TypeId value.
|
||||
* promise:
|
||||
* - retval.id() > 0
|
||||
*/
|
||||
static TypeId allocate() { return TypeId(s_next_id++); }
|
||||
/* A reflected type is a type for which we keep information around at runtime
|
||||
* Assign reflected types unique (within an executable) ids,
|
||||
* allocating consecutively, starting from 1.
|
||||
* Reserve 0 as a sentinel
|
||||
*/
|
||||
class TypeId {
|
||||
public:
|
||||
/* allocate a new TypeId value.
|
||||
* promise:
|
||||
* - retval.id() > 0
|
||||
*/
|
||||
static TypeId allocate() { return TypeId(s_next_id++); }
|
||||
|
||||
std::uint32_t id() const { return id_; }
|
||||
std::uint32_t id() const { return id_; }
|
||||
|
||||
private:
|
||||
explicit TypeId(std::uint32_t id) : id_{id} {}
|
||||
private:
|
||||
explicit TypeId(std::uint32_t id) : id_{id} {}
|
||||
|
||||
private:
|
||||
static std::uint32_t s_next_id;
|
||||
private:
|
||||
static std::uint32_t s_next_id;
|
||||
|
||||
/* unique index# for this type.
|
||||
* 0 reserved for sentinel
|
||||
*/
|
||||
std::uint32_t id_ = 0;
|
||||
}; /*TypeId*/
|
||||
/* unique index# for this type.
|
||||
* 0 reserved for sentinel
|
||||
*/
|
||||
std::uint32_t id_ = 0;
|
||||
}; /*TypeId*/
|
||||
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream & os, TypeId x) {
|
||||
os << x.id();
|
||||
return os;
|
||||
} /*operator<<*/
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream & os, TypeId x) {
|
||||
os << x.id();
|
||||
return os;
|
||||
} /*operator<<*/
|
||||
|
||||
/* runtime description of a struct/class instance variable */
|
||||
class StructMember;
|
||||
/* runtime description of a struct/class instance variable */
|
||||
class StructMember;
|
||||
|
||||
class TypeDescrBase;
|
||||
class TypeDescrBase;
|
||||
|
||||
using TypeDescr = TypeDescrBase const *;
|
||||
using TypeDescrW = TypeDescrBase *;
|
||||
using TypeDescr = TypeDescrBase const *;
|
||||
using TypeDescrW = TypeDescrBase *;
|
||||
|
||||
/* convenience wrapper for a std::type_info pointer.
|
||||
* works properly with pybind11, since python doens't encounter
|
||||
* native type_info pointer, it won't try to delete it.
|
||||
*/
|
||||
class TypeInfoRef {
|
||||
public:
|
||||
explicit TypeInfoRef(std::type_info const * tinfo) : tinfo_{tinfo} {}
|
||||
TypeInfoRef(TypeInfoRef const & x) = default;
|
||||
/* convenience wrapper for a std::type_info pointer.
|
||||
* works properly with pybind11, since python doens't encounter
|
||||
* native type_info pointer, it won't try to delete it.
|
||||
*/
|
||||
class TypeInfoRef {
|
||||
public:
|
||||
explicit TypeInfoRef(std::type_info const * tinfo) : tinfo_{tinfo} {}
|
||||
TypeInfoRef(TypeInfoRef const & x) = default;
|
||||
|
||||
/* use:
|
||||
* TypeInfoRef tinfo = TypeInfoRef::make<T>();
|
||||
*/
|
||||
template<typename T>
|
||||
TypeInfoRef make() { return TypeInfoRef(&typeid(T)); }
|
||||
/* use:
|
||||
* TypeInfoRef tinfo = TypeInfoRef::make<T>();
|
||||
*/
|
||||
template<typename T>
|
||||
TypeInfoRef make() { return TypeInfoRef(&typeid(T)); }
|
||||
|
||||
std::size_t hash_code() const { return this->tinfo_->hash_code(); }
|
||||
char const * impl_name() const { return this->tinfo_->name(); }
|
||||
std::size_t hash_code() const { return this->tinfo_->hash_code(); }
|
||||
char const * impl_name() const { return this->tinfo_->name(); }
|
||||
|
||||
static bool is_equal(TypeInfoRef x, TypeInfoRef y) noexcept {
|
||||
if (x.hash_code() != y.hash_code())
|
||||
return false;
|
||||
static bool is_equal(TypeInfoRef x, TypeInfoRef y) noexcept {
|
||||
if (x.hash_code() != y.hash_code())
|
||||
return false;
|
||||
|
||||
return ::strcmp(x.impl_name(), y.impl_name()) == 0;
|
||||
} /*is_equal*/
|
||||
return ::strcmp(x.impl_name(), y.impl_name()) == 0;
|
||||
} /*is_equal*/
|
||||
|
||||
private:
|
||||
/* native type_info object for encapsulated type */
|
||||
std::type_info const * tinfo_ = nullptr;
|
||||
}; /*TypeInfoRef*/
|
||||
} /*namespace reflect*/
|
||||
private:
|
||||
/* native type_info object for encapsulated type */
|
||||
std::type_info const * tinfo_ = nullptr;
|
||||
}; /*TypeInfoRef*/
|
||||
} /*namespace reflect*/
|
||||
} /*namespace xo*/
|
||||
|
||||
namespace std {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue