cosmetic: indenting

This commit is contained in:
Roland Conybeare 2023-10-17 14:52:27 -04:00
commit 8231420c5e

View file

@ -98,204 +98,213 @@ namespace std {
} /*namespace std*/
namespace xo {
namespace reflect {
inline bool operator==(TypeInfoRef x, TypeInfoRef y) { return TypeInfoRef::is_equal(x, y); }
inline bool operator!=(TypeInfoRef x, TypeInfoRef y) { return !TypeInfoRef::is_equal(x, y); }
namespace reflect {
inline bool operator==(TypeInfoRef x, TypeInfoRef y) { return TypeInfoRef::is_equal(x, y); }
inline bool operator!=(TypeInfoRef x, TypeInfoRef y) { return !TypeInfoRef::is_equal(x, y); }
#ifdef NOT_IN_USE
namespace detail {
class HashTypeInfoRef {
public:
std::size_t operator()(TypeInfoRef x) const noexcept { return x.hash_code(); }
}; /*HashTypeInfoRef*/
namespace detail {
class HashTypeInfoRef {
public:
std::size_t operator()(TypeInfoRef x) const noexcept { return x.hash_code(); }
}; /*HashTypeInfoRef*/
class EqualTypeInfoRef {
public:
bool operator()(TypeInfoRef x, TypeInfoRef y) const noexcept { return TypeInfoRef::is_equal(x, y); }
}; /*EqualTypeInfoRef*/
} /*namespace detail*/
class EqualTypeInfoRef {
public:
bool operator()(TypeInfoRef x, TypeInfoRef y) const noexcept { return TypeInfoRef::is_equal(x, y); }
}; /*EqualTypeInfoRef*/
} /*namespace detail*/
#endif
class TypeDescrExtra;
class TypeDescrExtra;
/* run-time description for a native c++ type */
class TypeDescrBase {
public:
/* type-description objects for a type T is unique,
* --> can always use its address
*/
TypeDescrBase(TypeDescrBase const & x) = delete;
/* run-time description for a native c++ type */
class TypeDescrBase {
public:
/* type-description objects for a type T is unique,
* --> can always use its address
*/
TypeDescrBase(TypeDescrBase const & x) = delete;
/* test whether a type has been reflected.
* introducing this for unit testing
*/
static bool is_reflected(std::type_info const * tinfo) {
return (s_type_table_map.find(TypeInfoRef(tinfo))
!= s_type_table_map.end());
} /*is_reflected*/
/* test whether a type has been reflected.
* introducing this for unit testing
*/
static bool is_reflected(std::type_info const * tinfo) {
return (s_type_table_map.find(TypeInfoRef(tinfo))
!= s_type_table_map.end());
} /*is_reflected*/
/* NOTE:
* implementation here will be defeated if std::type_info
* objects violate ODR. This occurs with clang + 2-level namespaces,
* so important to linke with --flat_namespace defined.
* See FAQ
* [Build Issues|Q2 - dynamic_cast<Foo<*>> fails]
*/
static TypeDescrW require(std::type_info const * tinfo,
std::string_view canonical_name,
std::unique_ptr<TypeDescrExtra> tdextra);
/* NOTE:
* implementation here will be defeated if std::type_info
* objects violate ODR. This occurs with clang + 2-level namespaces,
* so important to linke with --flat_namespace defined.
* See FAQ
* [Build Issues|Q2 - dynamic_cast<Foo<*>> fails]
*/
static TypeDescrW require(std::type_info const * tinfo,
std::string_view canonical_name,
std::unique_ptr<TypeDescrExtra> tdextra);
/* print table of reflected types to os */
static void print_reflected_types(std::ostream & os);
/* print table of reflected types to os */
static void print_reflected_types(std::ostream & os);
TypeId id() const { return id_; }
std::type_info const * typeinfo() const { return typeinfo_; }
std::string_view const & canonical_name() const { return canonical_name_; }
std::string_view const & short_name() const { return short_name_; }
bool complete_flag() const { return complete_flag_; }
TypeDescrExtra * tdextra() const { return tdextra_.get(); }
Metatype metatype() const { return tdextra_->metatype(); }
TypeId id() const { return id_; }
std::type_info const * typeinfo() const { return typeinfo_; }
std::string_view const & canonical_name() const { return canonical_name_; }
std::string_view const & short_name() const { return short_name_; }
bool complete_flag() const { return complete_flag_; }
TypeDescrExtra * tdextra() const { return tdextra_.get(); }
Metatype metatype() const { return tdextra_->metatype(); }
/* true iff the type represented by *this is the same as the type T.
*
* Warning: comparing typeinfo address can give false negatives.
* suspect this is caused by problems coalescing linker symbols
* in the clang toolchain.
*/
template<typename T>
bool is_native() const {
return ((this->typeinfo() == &typeid(T))
|| (this->typeinfo()->hash_code() == typeid(T).hash_code())
|| (this->typeinfo()->name() == typeid(T).name()));
} /*is_native*/
/* true iff the type represented by *this is the same as the type T.
*
* Warning: comparing typeinfo address can give false negatives.
* suspect this is caused by problems coalescing linker symbols
* in the clang toolchain.
*/
template<typename T>
bool is_native() const {
return ((this->typeinfo() == &typeid(T))
|| (this->typeinfo()->hash_code() == typeid(T).hash_code())
|| (this->typeinfo()->name() == typeid(T).name()));
} /*is_native*/
/* safe downcast -- like dynamic_cast<>, but does not require a source type */
template<typename T>
T * recover_native(void * address) const {
if (this->is_native<T>()) {
return reinterpret_cast<T *>(address);
} else {
return nullptr;
}
} /*recover_native*/
/* safe downcast -- like dynamic_cast<>, but does not require a source type */
template<typename T>
T * recover_native(void * address) const {
if (this->is_native<T>()) {
return reinterpret_cast<T *>(address);
} else {
return nullptr;
}
} /*recover_native*/
bool is_vector() const { return this->tdextra_->is_vector(); }
bool is_struct() const { return this->tdextra_->is_struct(); }
bool is_vector() const { return this->tdextra_->is_vector(); }
bool is_struct() const { return this->tdextra_->is_struct(); }
/* given a T-instance object, return tagged pointer with T replaced
* by the most-derived-subtype of T to which *object belongs.
* This works only for descendants of reflect::SelfTagging
*/
TaggedPtr most_derived_self_tp(void * object) const;
/* given a T-instance object, return tagged pointer with T replaced
* by the most-derived-subtype of T to which *object belongs.
* This works only for descendants of reflect::SelfTagging
*/
TaggedPtr most_derived_self_tp(void * object) const;
/* if generalized vector (std::vector<T>, std::array<T,N>, ..):
* .n_child() reports #of elements
* if struct/class:
* .n_child() reports #of instance variables (that have been reflected)
*/
uint32_t n_child(void * object) const { return this->tdextra_->n_child(object); }
TaggedPtr child_tp(uint32_t i, void * object) const;
/* if generalized vector (std::vector<T>, std::array<T,N>, ..):
* .n_child() reports #of elements
* if struct/class:
* .n_child() reports #of instance variables (that have been reflected)
*/
uint32_t n_child(void * object) const { return this->tdextra_->n_child(object); }
TaggedPtr child_tp(uint32_t i, void * object) const;
/* require:
* - .is_struct() = true
* - i in [0 .. .n_child() - 1]
*/
std::string const & struct_member_name(uint32_t i) const {
return this->tdextra_->struct_member_name(i);
}
/* fetch runtime description for i'th reflected instance variable.
*
* require:
* - .is_struct() = true
* - i in [0 .. .n_child() - 1]
*/
StructMember const & struct_member(uint32_t i) const {
StructMember const * sm = this->tdextra_->struct_member(i);
/* require:
* - .is_struct() = true
* - i in [0 .. .n_child() - 1]
*/
std::string const & struct_member_name(uint32_t i) const {
return this->tdextra_->struct_member_name(i);
}
/* fetch runtime description for i'th reflected instance variable.
*
* require:
* - .is_struct() = true
* - i in [0 .. .n_child() - 1]
*/
StructMember const & struct_member(uint32_t i) const {
StructMember const * sm = this->tdextra_->struct_member(i);
assert(sm);
return *sm;
} /*struct_member*/
assert(sm);
return *sm;
} /*struct_member*/
void display(std::ostream & os) const;
std::string display_string() const;
void display(std::ostream & os) const;
std::string display_string() const;
/* mark this TypeDescr complete;
* returns the value of .complete_flag from _before_
* this call
*/
bool mark_complete();
/* mark this TypeDescr complete;
* returns the value of .complete_flag from _before_
* this call
*/
bool mark_complete();
/* call this once to attach extended type information to a type-description
* (e.g. description of struct members for a record type)
*/
void assign_tdextra(std::unique_ptr<TypeDescrExtra> tdx);
/* call this once to attach extended type information to a type-description
* (e.g. description of struct members for a record type)
*/
void assign_tdextra(std::unique_ptr<TypeDescrExtra> tdx);
private:
TypeDescrBase(TypeId id,
std::type_info const * tinfo,
std::string_view canonical_name,
std::unique_ptr<TypeDescrExtra> tdextra);
private:
TypeDescrBase(TypeId id,
std::type_info const * tinfo,
std::string_view canonical_name,
std::unique_ptr<TypeDescrExtra> tdextra);
private:
/* invariant:
* - for all TypeDescrImpl instances x:
* - s_type_table_v[x->id()] = x
* - s_type_table_map[TypeInfoRef(x->typeinfo())] = x
*/
private:
/* invariant:
* - for all TypeDescrImpl instances x:
* - s_type_table_v[x->id()] = x
* - s_type_table_map[TypeInfoRef(x->typeinfo())] = x
*/
/* hashmap of all TypeDescr instances, indexed by . singleton */
static std::unordered_map<TypeInfoRef, std::unique_ptr<TypeDescrBase>> s_type_table_map;
/* hashmap of (presumed) duplicate TypeInfoRef values.
* This happens with clang sometimes when the same type is referenced
* from multiple modules (i.e. shared libs).
*/
static std::unordered_map<TypeInfoRef, TypeDescrBase *> s_coalesced_type_table_map;
/* hashmap of all TypeDescr instances, indexed by . singleton */
static std::unordered_map<TypeInfoRef, std::unique_ptr<TypeDescrBase>> s_type_table_map;
/* hashmap of (presumed) duplicate TypeInfoRef values.
* This happens with clang sometimes when the same type is referenced
* from multiple modules (i.e. shared libs).
*/
static std::unordered_map<TypeInfoRef, TypeDescrBase *> s_coalesced_type_table_map;
/* vector of all TypeDescr instances. singleton. */
static std::vector<TypeDescrBase *> s_type_table_v;
/* vector of all TypeDescr instances. singleton. */
static std::vector<TypeDescrBase *> s_type_table_v;
private:
/* unique id# for this type */
TypeId id_;
/* typeinfo for type T */
std::type_info const * typeinfo_ = nullptr;
/* canonical name for this type (see demangle.hpp for type_name<T>())
* e.g.
* xo::option::Px2
*/
std::string_view canonical_name_;
/* suffix of .canonical_name, just after last ':'
* e.g.
* Px2
*/
std::string_view short_name_;
/* set to true once final value for .tdextra is established
* intially all TypeDescr objects will use AtomicTdx for .tdextra
* Reflect::require() upgrades .tdextra for particular types.
* When that procedure makes a decision for a type T,
* .complete_flag will be set to true for the corresponding TypeDescrBase instance
*/
bool complete_flag_ = false;
/* additional type information that either:
* (a) isn't universal across all types,
* e.g. dereferencing instance of a pointer type
* (b) can't be captured with template-fu,
* e.g. struct member names
*
* generally .tdextra will be populated some time after TypeDescrBase's ctor exits.
* This is necessary because of (b) above, also because of possibility of recursive
* types.
*/
std::unique_ptr<TypeDescrExtra> tdextra_;
}; /*TypeDescrBase*/
private:
/* unique id# for this type */
TypeId id_;
/* typeinfo for type T */
std::type_info const * typeinfo_ = nullptr;
/* canonical name for this type (see demangle.hpp for type_name<T>())
* e.g.
* xo::option::Px2
*/
std::string_view canonical_name_;
/* suffix of .canonical_name, just after last ':'
* e.g.
* Px2
*/
std::string_view short_name_;
/* set to true once final value for .tdextra is established
* intially all TypeDescr objects will use AtomicTdx for .tdextra
* Reflect::require() upgrades .tdextra for particular types.
* When that procedure makes a decision for a type T,
* .complete_flag will be set to true for the corresponding TypeDescrBase instance
*/
bool complete_flag_ = false;
/* additional type information that either:
* (a) isn't universal across all types,
* e.g. dereferencing instance of a pointer type
* (b) can't be captured with template-fu,
* e.g. struct member names
*
* generally .tdextra will be populated some time after TypeDescrBase's ctor exits.
* This is necessary because of (b) above, also because of possibility of recursive
* types.
*/
std::unique_ptr<TypeDescrExtra> tdextra_;
}; /*TypeDescrBase*/
inline std::ostream &
operator<<(std::ostream & os, TypeDescrBase const & x) {
x.display(os);
return os;
} /*operator<<*/
inline std::ostream &
operator<<(std::ostream & os, TypeDescrBase const & x) {
x.display(os);
return os;
} /*operator<<*/
} /*namespace reflect*/
/* tag to drive overload resolution */
struct reflected_types_printer {};
inline std::ostream &
operator<<(std::ostream & os, reflected_types_printer) {
TypeDescrBase::print_reflected_types(os);
return os;
}
} /*namespace reflect*/
} /*namespace xo*/
/* end TypeDescr.hpp */