All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
type.h
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_TF_TYPE_H
8#define PXR_BASE_TF_TYPE_H
9
10#include "pxr/pxr.h"
11
12#include "pxr/base/tf/api.h"
15
16#include <iosfwd>
17#include <memory>
18#include <set>
19#include <string>
20#include <type_traits>
21#include <typeinfo>
22#include <vector>
23
24PXR_NAMESPACE_OPEN_SCOPE
25
26#ifdef PXR_PYTHON_SUPPORT_ENABLED
27class TfPyObjWrapper;
28#endif // PXR_PYTHON_SUPPORT_ENABLED
29
47class TfType
48{
49 struct _TypeInfo;
50
51public:
53 using DefinitionCallback = void (*)(TfType);
54
57 public:
58 TF_API virtual ~FactoryBase();
59 };
60
61public:
62
64 ABSTRACT = 0x01,
65 CONCRETE = 0x02,
67 };
68
69#ifdef PXR_PYTHON_SUPPORT_ENABLED
70 // This is a non-templated base class for the templated
71 // polymorphic-to-Python infrastructure.
72 struct PyPolymorphicBase
73 {
74 protected:
75 TF_API virtual ~PyPolymorphicBase();
76 };
77#endif // PXR_PYTHON_SUPPORT_ENABLED
78
79public:
82 template <class ... Args>
83 struct Bases {};
84
85public:
96 TF_API
98
107 TF_API
108 static TfType const& GetUnknownType();
109
115 inline bool operator ==(const TfType& t) const { return _info == t._info; }
116 inline bool operator !=(const TfType& t) const { return _info != t._info; }
117
119 inline bool operator <(const TfType& t) const { return _info < t._info; }
120 inline bool operator >(const TfType& t) const { return _info > t._info; }
121 inline bool operator <=(const TfType& t) const { return _info <= t._info; }
122 inline bool operator >=(const TfType& t) const { return _info >= t._info; }
123
124
127
135 template <typename T>
136 static TfType const& Find() {
137 return Find(typeid(T));
138 }
139
155 template <typename T>
156 static TfType const& Find(const T &obj) {
157 // If T is polymorphic to python, we may have to bridge into python. We
158 // could also optimize for Ts that are not polymorphic at all and avoid
159 // doing rtti typeid lookups, but we trust the compiler to do this for
160 // us.
161 if (auto const *rawPtr = TfTypeFunctions<T>::GetRawPtr(obj))
162 return _FindImpl(rawPtr);
163 return GetUnknownType();
164 }
165
169 static TfType const& Find(const std::type_info &t) {
170 return _FindByTypeid(t);
171 }
172
176 static TfType const& FindByTypeid(const std::type_info &t) {
177 return _FindByTypeid(t);
178 }
179
198 TF_API
199 static TfType const& FindByName(const std::string &name);
200
206 TF_API
207 TfType const& FindDerivedByName(const std::string &name) const;
208
217 template <typename BASE>
218 static TfType const& FindDerivedByName(const std::string &name)
219 {
220 return TfType::Find<BASE>().FindDerivedByName(name);
221 }
222
223#ifdef PXR_PYTHON_SUPPORT_ENABLED
227 TF_API
228 static TfType const& FindByPythonClass(const TfPyObjWrapper & classObj);
229#endif // PXR_PYTHON_SUPPORT_ENABLED
230
232
233
236
243 TF_API
244 static TfType const& GetRoot();
245
250 TF_API
251 const std::string &GetTypeName() const;
252
263 TF_API
264 const std::type_info &GetTypeid() const;
265
273 TF_API
274 static std::string GetCanonicalTypeName(const std::type_info &);
275
280 TF_API
281 std::vector<std::string> GetAliases(TfType derivedType) const;
282
283#ifdef PXR_PYTHON_SUPPORT_ENABLED
292 TF_API
294#endif // PXR_PYTHON_SUPPORT_ENABLED
295
298 TF_API
299 std::vector<TfType> GetBaseTypes() const;
300
311 TF_API
312 size_t GetNBaseTypes(TfType *out, size_t maxBases) const;
313
316 TF_API
317 std::vector<TfType> GetDirectlyDerivedTypes() const;
318
320 TF_API
321 TfType const& GetCanonicalType() const;
322
326 TF_API
327 void GetAllDerivedTypes( std::set<TfType> *result ) const;
328
350 TF_API
351 void GetAllAncestorTypes(std::vector<TfType> *result) const;
352
356 TF_API
357 bool IsA(TfType queryType) const;
358
365 template <typename T>
366 bool IsA() const { return IsA(Find<T>()); }
367
374 bool IsUnknown() const { return *this == TfType(); }
375
376 typedef TfType::_TypeInfo * (TfType::*UnspecifiedBoolType);
377
380 operator UnspecifiedBoolType() const {
381 return IsUnknown() ? NULL : &TfType::_info;
382 }
383
386 bool operator !() const { return !bool(*this); }
387
390 bool IsRoot() const { return *this == GetRoot(); }
391
394 TF_API
395 bool IsEnumType() const;
396
399 TF_API
400 bool IsPlainOldDataType() const;
401
409 TF_API
410 size_t GetSizeof() const;
411
413
414
417
423 TF_API
424 static TfType const&
425 Declare( const std::string & typeName );
426
441 TF_API
442 static TfType const&
443 Declare( const std::string & typeName,
444 const std::vector<TfType> & bases,
445 DefinitionCallback definitionCallback=nullptr );
446
452 template <typename T, typename BaseTypes = TfType::Bases<>>
453 static TfType const& Declare();
454
465 template <typename T, typename B>
466 static TfType const& Define();
467
475 template <typename T>
476 static TfType const& Define();
477
478#ifdef PXR_PYTHON_SUPPORT_ENABLED
481 TF_API
482 void DefinePythonClass(const TfPyObjWrapper &classObj) const;
483#endif // PXR_PYTHON_SUPPORT_ENABLED
484
490 template <typename Base, typename Derived>
491 static void AddAlias(const std::string &name) {
492 TfType b = Declare(GetCanonicalTypeName(typeid(Base)));
493 TfType d = Declare(GetCanonicalTypeName(typeid(Derived)));
494 d.AddAlias(b, name);
495 }
496
505 TF_API
506 void AddAlias(TfType base, const std::string &name) const;
507
510 const TfType &Alias(TfType base, const std::string &name) const {
511 AddAlias(base, name);
512 return *this;
513 }
514
516
517
520
538 TF_API
539 void* CastToAncestor(TfType ancestor, void* addr) const;
540
541 const void* CastToAncestor(TfType ancestor,
542 const void* addr) const {
543 return CastToAncestor(ancestor, const_cast<void*>(addr));
544 }
545
560 TF_API
561 void* CastFromAncestor(TfType ancestor, void* addr) const;
562
563 const void* CastFromAncestor(TfType ancestor,
564 const void* addr) const {
565 return CastFromAncestor(ancestor, const_cast<void*>(addr));
566 }
567
569
572
576 TF_API
577 void SetFactory(std::unique_ptr<FactoryBase> factory) const;
578
582 template <class T>
583 void SetFactory(std::unique_ptr<T>& factory) const {
584 SetFactory(std::unique_ptr<FactoryBase>(std::move(factory)));
585 }
586
589 template <class T>
590 void SetFactory() const { SetFactory(std::unique_ptr<FactoryBase>(new T)); }
591
595 const TfType& Factory(std::unique_ptr<FactoryBase> factory) const {
596 SetFactory(std::move(factory));
597 return *this;
598 }
599
603 template <class T>
604 const TfType& Factory(std::unique_ptr<T>& factory) const
605 {
606 SetFactory(std::unique_ptr<FactoryBase>(std::move(factory)));
607 return *this;
608 }
609
612 template <class T>
613 const TfType& Factory() const {
614 SetFactory(std::unique_ptr<FactoryBase>(new T));
615 return *this;
616 }
617
622 template <class T>
623 T *GetFactory() const { return dynamic_cast<T*>(_GetFactory()); }
624
626
627private:
628 TF_API
629 FactoryBase* _GetFactory() const;
630
631#ifdef PXR_PYTHON_SUPPORT_ENABLED
632 TF_API
633 static TfType const &_FindImplPyPolymorphic(PyPolymorphicBase const *ptr);
634
635 // PyPolymorphic case.
636 static TfType const &
637 _FindImpl(PyPolymorphicBase const *rawPtr) {
638 return _FindImplPyPolymorphic(rawPtr);
639 }
640
641 // Not PyPolymorphic.
642 template <class T>
643 static TfType const &
644 _FindImpl(T const *rawPtr) {
645 if constexpr (std::is_polymorphic<T>::value) {
646 if (auto ptr = dynamic_cast<PyPolymorphicBase const *>(rawPtr)) {
647 return _FindImplPyPolymorphic(ptr);
648 }
649 else {
650 return Find(typeid(*rawPtr));
651 }
652 }
653 else {
654 return Find(typeid(T));
655 }
656 }
657#else
658 template <class T>
659 static TfType const &
660 _FindImpl(T const *rawPtr) {
661 return Find(typeid(*rawPtr));
662 }
663
664#endif // PXR_PYTHON_SUPPORT_ENABLED
665
666 // Callers must hold at least a read lock on the type registry's mutex.
667 bool _IsAImplNoLock(TfType queryType) const;
668
669 typedef void *(*_CastFunction)(void *, bool derivedToBase);
670
671 template <typename TypeVector>
672 friend struct Tf_AddBases;
673 friend struct _TypeInfo;
674 friend class Tf_TypeRegistry;
675
676 // TfHash support.
677 template <class HashState>
678 friend void
679 TfHashAppend(HashState &h, TfType const &type) {
680 h.Append(type._info);
681 }
682
683 // Construct a TfType with the given _TypeInfo.
684 explicit TfType(_TypeInfo *info) : _info(info) {}
685
686 // Add base type(s), and link as a derived type of the bases. Callers
687 // must hold a registry write lock.
688 void _AddBasesNoLock(
689 const std::vector<TfType> &bases,
690 std::vector<std::string> *errorToEmit) const;
691
692 // Add the given function for casting to/from the given baseType.
693 TF_API
694 void _AddCppCastFunc(
695 const std::type_info &baseTypeInfo, _CastFunction) const;
696
697 // Define this TfType to have the given type_info.
698 TF_API
699 void _DefineCppType(const std::type_info &,
700 size_t sizeofType,
701 bool isPodType,
702 bool isEnumType) const;
703
704 TF_API
705 static TfType const &_DeclareImpl(
706 const std::type_info &thisTypeInfo,
707 const std::type_info **baseTypeInfos,
708 size_t numBaseTypes);
709
710 TF_API
711 static TfType const &_DefineImpl(
712 const std::type_info &thisTypeInfo,
713 const std::type_info **baseTypeInfos,
714 _CastFunction *castFunctions,
715 size_t numBaseTypes,
716 size_t sizeofThisType, bool isPod, bool isEnum);
717
718 // Execute the definition callback if one exists.
719 void _ExecuteDefinitionCallback() const;
720
721 // Retrieve the \c TfType corresponding to an obj with the
722 // given \c type_info.
723 TF_API
724 static TfType const& _FindByTypeid(const std::type_info &);
725
726 // Pointer to internal type representation.
727 // Our only data member.
728 _TypeInfo *_info;
729};
730
733TF_API std::ostream& operator<<(std::ostream& out, const TfType &t);
734
736template <typename T>
738 static const size_t value = sizeof(T);
739};
740template <>
741struct TfSizeofType<void> {
742 static const size_t value = 0;
743};
744template <>
745struct TfSizeofType<const void> {
746 static const size_t value = 0;
747};
748template <>
749struct TfSizeofType<volatile void> {
750 static const size_t value = 0;
751};
752template <>
753struct TfSizeofType<const volatile void> {
754 static const size_t value = 0;
755};
756
757PXR_NAMESPACE_CLOSE_SCOPE
758
759// Implementation details are put in this header.
760#include "pxr/base/tf/type_Impl.h"
761
762#endif // PXR_BASE_TF_TYPE_H
Boost Python object wrapper.
Definition: pyObjWrapper.h:79
Base class of all factory types.
Definition: type.h:56
TfType represents a dynamic runtime type.
Definition: type.h:48
const TfType & Alias(TfType base, const std::string &name) const
Convenience method to add an alias and return *this.
Definition: type.h:510
static TF_API TfType const & GetUnknownType()
Return an empty TfType, representing the unknown type.
TF_API std::vector< std::string > GetAliases(TfType derivedType) const
Returns a vector of the aliases registered for the derivedType under this, the base type.
TF_API std::vector< TfType > GetBaseTypes() const
Return a vector of types from which this type was derived.
TF_API void AddAlias(TfType base, const std::string &name) const
Add an alias name for this type under the given base type.
static TfType const & Define()
Define a TfType with the given C++ type T and no bases.
const TfType & Factory(std::unique_ptr< T > &factory) const
Sets the factory object for this type.
Definition: type.h:604
const TfType & Factory(std::unique_ptr< FactoryBase > factory) const
Sets the factory object for this type.
Definition: type.h:595
bool operator==(const TfType &t) const
Equality operator.
Definition: type.h:115
TF_API void DefinePythonClass(const TfPyObjWrapper &classObj) const
Define the Python class object corresponding to this TfType.
LegacyFlags
Definition: type.h:63
@ CONCRETE
Not abstract.
Definition: type.h:65
@ MANUFACTURABLE
Manufacturable type (implies concrete)
Definition: type.h:66
@ ABSTRACT
Abstract (unmanufacturable and unclonable)
Definition: type.h:64
static TF_API TfType const & FindByName(const std::string &name)
Retrieve the TfType corresponding to the given name.
static void AddAlias(const std::string &name)
Add an alias for DERIVED beneath BASE.
Definition: type.h:491
TF_API bool IsA(TfType queryType) const
Return true if this type is the same as or derived from queryType.
TF_API std::vector< TfType > GetDirectlyDerivedTypes() const
Return a vector of types derived directly from this type.
bool operator<(const TfType &t) const
Comparison operator.
Definition: type.h:119
TF_API bool IsEnumType() const
Return true if this is an enum type.
static TF_API TfType const & GetRoot()
Return the root type of the type hierarchy.
static TF_API TfType const & FindByPythonClass(const TfPyObjWrapper &classObj)
Retrieve the TfType corresponding to an obj with the given Python class classObj.
bool operator!() const
Boolean not operator – return true if this type is unknown, false otherwise.
Definition: type.h:386
bool IsA() const
Return true if this type is the same as or derived from T.
Definition: type.h:366
TF_API void SetFactory(std::unique_ptr< FactoryBase > factory) const
Sets the factory object for this type.
static TfType const & Find(const std::type_info &t)
Retrieve the TfType corresponding to an obj with the given type_info.
Definition: type.h:169
TF_API size_t GetSizeof() const
Return the size required to hold an instance of this type on the stack (does not include any heap all...
const TfType & Factory() const
Sets the factory object for this type to be a T.
Definition: type.h:613
TF_API void * CastToAncestor(TfType ancestor, void *addr) const
Cast addr to the address corresponding to the type ancestor.
static TF_API TfType const & Declare(const std::string &typeName)
Declare a TfType with the given typeName, but no base type information.
static TF_API TfType const & Declare(const std::string &typeName, const std::vector< TfType > &bases, DefinitionCallback definitionCallback=nullptr)
Declare a TfType with the given typeName and bases.
TF_API const std::string & GetTypeName() const
Return the machine-independent name for this type.
static TfType const & Define()
Define a TfType with the given C++ type T and C++ base types B.
static TfType const & Find()
Retrieve the TfType corresponding to type T.
Definition: type.h:136
TF_API void * CastFromAncestor(TfType ancestor, void *addr) const
Cast addr, which pointed to the ancestor type ancestor, to the type of *this.
TF_API void GetAllDerivedTypes(std::set< TfType > *result) const
Return the set of all types derived (directly or indirectly) from this type.
void SetFactory() const
Sets the factory object for this type to be a T.
Definition: type.h:590
static TfType const & Declare()
Declares a TfType with the given C++ type T and C++ base types Bases.
void(*)(TfType) DefinitionCallback
Callback invoked when a declared type needs to be defined.
Definition: type.h:53
TF_API void GetAllAncestorTypes(std::vector< TfType > *result) const
Build a vector of all ancestor types inherited by this type.
static TfType const & FindDerivedByName(const std::string &name)
Retrieve the TfType that derives from BASE and has the given alias or typename.
Definition: type.h:218
static TfType const & Find(const T &obj)
Retrieve the TfType corresponding to obj.
Definition: type.h:156
TF_API const std::type_info & GetTypeid() const
Return a C++ RTTI type_info for this type.
bool IsUnknown() const
Return true if this is the unknown type, representing a type unknown to the TfType system.
Definition: type.h:374
TF_API TfPyObjWrapper GetPythonClass() const
Return the Python class object for this type.
TF_API TfType const & FindDerivedByName(const std::string &name) const
Retrieve the TfType that derives from this type and has the given alias or typename.
T * GetFactory() const
Returns the factory object for this type as a T*, or NULL if there is no factory or the factory is no...
Definition: type.h:623
bool IsRoot() const
Return true if this is the root type.
Definition: type.h:390
TF_API size_t GetNBaseTypes(TfType *out, size_t maxBases) const
Copy the first maxBases base types of this type to out, or all the base types if this type has maxBas...
TF_API TfType const & GetCanonicalType() const
Return the canonical type for this type.
static TF_API std::string GetCanonicalTypeName(const std::type_info &)
Return the canonical typeName used for a given std::type_info.
void SetFactory(std::unique_ptr< T > &factory) const
Sets the factory object for this type.
Definition: type.h:583
TF_API TfType()
Construct an TfType representing an unknown type.
static TfType const & FindByTypeid(const std::type_info &t)
Retrieve the TfType corresponding to an obj with the given type_info.
Definition: type.h:176
TF_API bool IsPlainOldDataType() const
Return true if this is a plain old data type, as defined by C++.
A type-list of C++ base types.
Definition: type.h:83
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
Metafunction returning sizeof(T) for a type T (or 0 if T is a void type).
Definition: type.h:737
Implements assorted functions based on compile-time type information.
Definition: typeFunctions.h:37