All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
type.h
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef TF_TYPE_H
25 #define TF_TYPE_H
26 
27 #include "pxr/pxr.h"
28 
29 #include "pxr/base/tf/api.h"
30 #include "pxr/base/tf/cxxCast.h"
31 #include "pxr/base/tf/refPtr.h"
32 #include "pxr/base/tf/registryManager.h"
33 #include "pxr/base/tf/traits.h"
34 #include "pxr/base/tf/typeFunctions.h"
35 
36 #include <boost/operators.hpp>
37 
38 #include <iosfwd>
39 #include <memory>
40 #include <set>
41 #include <type_traits>
42 #include <typeinfo>
43 #include <vector>
44 
45 PXR_NAMESPACE_OPEN_SCOPE
46 
47 #ifdef PXR_PYTHON_SUPPORT_ENABLED
48 class TfPyObjWrapper;
49 #endif // PXR_PYTHON_SUPPORT_ENABLED
50 
51 class TfType;
52 
70 class TfType : boost::totally_ordered<TfType>
71 {
72  struct _TypeInfo;
73 
74 public:
76  using DefinitionCallback = void (*)(TfType);
77 
79  class FactoryBase {
80  public:
81  TF_API virtual ~FactoryBase();
82  };
83 
84 public:
85 
86  enum LegacyFlags {
87  ABSTRACT = 0x01,
88  CONCRETE = 0x02,
89  MANUFACTURABLE = 0x08,
90  };
91 
92 #ifdef PXR_PYTHON_SUPPORT_ENABLED
93  // This is a non-templated base class for the templated
94  // polymorphic-to-Python infrastructure.
95  struct PyPolymorphicBase
96  {
97  protected:
98  TF_API virtual ~PyPolymorphicBase();
99  };
100 #endif // PXR_PYTHON_SUPPORT_ENABLED
101 
102 public:
105  template <class ... Args>
106  struct Bases {};
107 
108 public:
119  TF_API
120  TfType();
121 
130  TF_API
131  static TfType const& GetUnknownType();
132 
138  inline bool operator ==(const TfType& t) const { return _info == t._info; }
139 
141  inline bool operator <(const TfType& t) const { return _info < t._info; }
142 
143 
146 
154  template <typename T>
155  static TfType const& Find() {
156  return Find(typeid(T));
157  }
158 
173  template <typename T>
174  static TfType const& Find(const T &obj) {
175  typedef typename TfTraits::Type<T>::UnderlyingType Type;
176  // If T is polymorphic to python, we may have to bridge into python. We
177  // could also optimize for Ts that are not polymorphic at all and avoid
178  // doing rtti typeid lookups, but we trust the compiler to do this for
179  // us.
180  if (Type const *rawPtr = TfTypeFunctions<T>::GetRawPtr(obj))
181  return _FindImpl(rawPtr);
182  return GetUnknownType();
183  }
184 
188  static TfType const& Find(const std::type_info &t) {
189  return _FindByTypeid(t);
190  }
191 
195  static TfType const& FindByTypeid(const std::type_info &t) {
196  return _FindByTypeid(t);
197  }
198 
217  TF_API
218  static TfType const& FindByName(const std::string &name);
219 
225  TF_API
226  TfType const& FindDerivedByName(const std::string &name) const;
227 
236  template <typename BASE>
237  static TfType const& FindDerivedByName(const std::string &name)
238  {
239  return TfType::Find<BASE>().FindDerivedByName(name);
240  }
241 
242 #ifdef PXR_PYTHON_SUPPORT_ENABLED
243  TF_API
247  static TfType const& FindByPythonClass(const TfPyObjWrapper & classObj);
248 #endif // PXR_PYTHON_SUPPORT_ENABLED
249 
251 
252 
255 
262  TF_API
263  static TfType const& GetRoot();
264 
269  TF_API
270  const std::string &GetTypeName() const;
271 
279  TF_API
280  const std::type_info &GetTypeid() const;
281 
289  TF_API
290  static std::string GetCanonicalTypeName(const std::type_info &);
291 
296  TF_API
297  std::vector<std::string> GetAliases(TfType derivedType) const;
298 
299 #ifdef PXR_PYTHON_SUPPORT_ENABLED
300  TF_API
309  TfPyObjWrapper GetPythonClass() const;
310 #endif // PXR_PYTHON_SUPPORT_ENABLED
311 
314  TF_API
315  std::vector<TfType> GetBaseTypes() const;
316 
327  TF_API
328  size_t GetNBaseTypes(TfType *out, size_t maxBases) const;
329 
332  TF_API
333  std::vector<TfType> GetDirectlyDerivedTypes() const;
334 
336  TF_API
337  TfType const& GetCanonicalType() const;
338 
342  TF_API
343  void GetAllDerivedTypes( std::set<TfType> *result ) const;
344 
366  TF_API
367  void GetAllAncestorTypes(std::vector<TfType> *result) const;
368 
372  TF_API
373  bool IsA(TfType queryType) const;
374 
381  template <typename T>
382  bool IsA() const { return IsA(Find<T>()); }
383 
390  bool IsUnknown() const { return *this == TfType(); }
391 
392  typedef TfType::_TypeInfo * (TfType::*UnspecifiedBoolType);
393 
396  operator UnspecifiedBoolType() const {
397  return IsUnknown() ? NULL : &TfType::_info;
398  }
399 
402  bool operator !() const { return !bool(*this); }
403 
406  bool IsRoot() const { return *this == GetRoot(); }
407 
410  TF_API
411  bool IsEnumType() const;
412 
415  TF_API
416  bool IsPlainOldDataType() const;
417 
425  TF_API
426  size_t GetSizeof() const;
427 
429 
430 
433 
439  TF_API
440  static TfType const&
441  Declare( const std::string & typeName );
442 
457  TF_API
458  static TfType const&
459  Declare( const std::string & typeName,
460  const std::vector<TfType> & bases,
461  DefinitionCallback definitionCallback=nullptr );
462 
473  template <typename T, typename B>
474  static TfType const& Define();
475 
483  template <typename T>
484  static TfType const& Define();
485 
486 #ifdef PXR_PYTHON_SUPPORT_ENABLED
487  TF_API
490  void DefinePythonClass(const TfPyObjWrapper &classObj) const;
491 #endif // PXR_PYTHON_SUPPORT_ENABLED
492 
498  template <typename Base, typename Derived>
499  static void AddAlias(const std::string &name) {
500  TfType b = Declare(GetCanonicalTypeName(typeid(Base)));
501  TfType d = Declare(GetCanonicalTypeName(typeid(Derived)));
502  d.AddAlias(b, name);
503  }
504 
512  TF_API
513  void AddAlias(TfType base, const std::string &name) const;
514 
517  const TfType &Alias(TfType base, const std::string &name) const {
518  AddAlias(base, name);
519  return *this;
520  }
521 
523 
524 
527 
545  TF_API
546  void* CastToAncestor(TfType ancestor, void* addr) const;
547 
548  const void* CastToAncestor(TfType ancestor,
549  const void* addr) const {
550  return CastToAncestor(ancestor, const_cast<void*>(addr));
551  }
552 
567  TF_API
568  void* CastFromAncestor(TfType ancestor, void* addr) const;
569 
570  const void* CastFromAncestor(TfType ancestor,
571  const void* addr) const {
572  return CastFromAncestor(ancestor, const_cast<void*>(addr));
573  }
574 
576 
579 
583  TF_API
584  void SetFactory(std::unique_ptr<FactoryBase> factory) const;
585 
589  template <class T>
590  void SetFactory(std::unique_ptr<T>& factory) const {
591  SetFactory(std::unique_ptr<FactoryBase>(std::move(factory)));
592  }
593 
596  template <class T>
597  void SetFactory() const { SetFactory(std::unique_ptr<FactoryBase>(new T)); }
598 
602  const TfType& Factory(std::unique_ptr<FactoryBase> factory) const {
603  SetFactory(std::move(factory));
604  return *this;
605  }
606 
610  template <class T>
611  const TfType& Factory(std::unique_ptr<T>& factory) const
612  {
613  SetFactory(std::unique_ptr<FactoryBase>(std::move(factory)));
614  return *this;
615  }
616 
619  template <class T>
620  const TfType& Factory() const {
621  SetFactory(std::unique_ptr<FactoryBase>(new T));
622  return *this;
623  }
624 
629  template <class T>
630  T *GetFactory() const { return dynamic_cast<T*>(_GetFactory()); }
631 
633 
634 private:
635  TF_API
636  FactoryBase* _GetFactory() const;
637 
638 #ifdef PXR_PYTHON_SUPPORT_ENABLED
639  TF_API
640  static TfType const &_FindImplPyPolymorphic(PyPolymorphicBase const *ptr);
641 
642  // PyPolymorphic case.
643  template <class T>
644  static typename std::enable_if<
645  std::is_base_of<PyPolymorphicBase, T>::value, TfType const &>::type
646  _FindImpl(T const *rawPtr) {
647  return _FindImplPyPolymorphic(
648  static_cast<PyPolymorphicBase const *>(rawPtr));
649  }
650 
651  // Polymorphic.
652  template <class T>
653  static typename std::enable_if<
654  std::is_polymorphic<T>::value &&
655  !std::is_base_of<PyPolymorphicBase, T>::value, TfType const &>::type
656  _FindImpl(T const *rawPtr) {
657  if (auto ptr = dynamic_cast<PyPolymorphicBase const *>(rawPtr))
658  return _FindImplPyPolymorphic(ptr);
659  return Find(typeid(*rawPtr));
660  }
661 
662  template <class T>
663  static typename std::enable_if<
664  !std::is_polymorphic<T>::value, TfType const &>::type
665  _FindImpl(T const *rawPtr) {
666  return Find(typeid(T));
667  }
668 
669 #else
670  template <class T>
671  static typename std::enable_if<
672  std::is_polymorphic<T>::value, TfType const &>::type
673  _FindImpl(T const *rawPtr) {
674  return Find(typeid(*rawPtr));
675  }
676 
677  template <class T>
678  static typename std::enable_if<
679  !std::is_polymorphic<T>::value, TfType const &>::type
680  _FindImpl(T const *rawPtr) {
681  return Find(typeid(T));
682  }
683 
684 #endif // PXR_PYTHON_SUPPORT_ENABLED
685 
686  bool _IsAImpl(TfType queryType) const;
687 
688  typedef void *(*_CastFunction)(void *, bool derivedToBase);
689 
690  template <typename TypeVector>
691  friend struct Tf_AddBases;
692  friend struct _TypeInfo;
693  friend class Tf_TypeRegistry;
694  friend class TfHash;
695 
696  // Construct a TfType with the given _TypeInfo.
697  explicit TfType(_TypeInfo *info) : _info(info) {}
698 
699  // Adds base type(s), and link as a derived type of that bases.
700  void _AddBases(
701  const std::vector<TfType> &bases,
702  std::vector<std::string> *errorToEmit) const;
703 
704  // Add the given function for casting to/from the given baseType.
705  TF_API
706  void _AddCppCastFunc(
707  const std::type_info &baseTypeInfo, _CastFunction) const;
708 
709  // Define this TfType to have the given type_info.
710  TF_API
711  void _DefineCppType(const std::type_info &,
712  size_t sizeofType,
713  bool isPodType,
714  bool isEnumType) const;
715 
716  // Execute the definition callback if one exists.
717  void _ExecuteDefinitionCallback() const;
718 
719  // Retrieve the \c TfType corresponding to an obj with the
720  // given \c type_info.
721  TF_API
722  static TfType const& _FindByTypeid(const std::type_info &);
723 
724  // Pointer to internal type representation.
725  // Our only data member.
726  _TypeInfo *_info;
727 };
728 
731 TF_API std::ostream& operator<<(std::ostream& out, const TfType &t);
732 
734 template <typename T>
735 struct TfSizeofType {
736  static const size_t value = sizeof(T);
737 };
738 template <>
739 struct TfSizeofType<void> {
740  static const size_t value = 0;
741 };
742 template <>
743 struct TfSizeofType<const void> {
744  static const size_t value = 0;
745 };
746 template <>
747 struct TfSizeofType<volatile void> {
748  static const size_t value = 0;
749 };
750 template <>
751 struct TfSizeofType<const volatile void> {
752  static const size_t value = 0;
753 };
754 
755 PXR_NAMESPACE_CLOSE_SCOPE
756 
757 // Implementation details are put in this header.
758 #include "pxr/base/tf/type_Impl.h"
759 
760 #endif // TF_TYPE_H
TF_API const std::string & GetTypeName() const
Return the machine-independent name for this type.
const TfType & Factory() const
Sets the factory object for this type to be a T.
Definition: type.h:620
static TF_API TfType const & GetUnknownType()
Return an empty TfType, representing the unknown type.
const TfType & Alias(TfType base, const std::string &name) const
Convenience method to add an alias and return *this.
Definition: type.h:517
static TfType const & Find(const std::type_info &t)
Retrieve the TfType corresponding to an obj with the given type_info.
Definition: type.h:188
TF_API void GetAllAncestorTypes(std::vector< TfType > *result) const
Build a vector of all ancestor types inherited by this type.
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:499
static TfType const & Find()
Retrieve the TfType corresponding to type T.
Definition: type.h:155
TF_API bool IsEnumType() const
Return true if this is an enum type.
bool operator<(const TfType &t) const
Comparison operator.
Definition: type.h:141
Base class of all factory types.
Definition: type.h:79
TF_API void * CastFromAncestor(TfType ancestor, void *addr) const
Cast addr, which pointed to the ancestor type ancestor, to the type of *this.
Provides hash function on STL string types and other types.
Definition: hash.h:86
void SetFactory(std::unique_ptr< T > &factory) const
Sets the factory object for this type.
Definition: type.h:590
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...
static TfType const & Find(const T &obj)
Retrieve the TfType corresponding to obj.
Definition: type.h:174
Not abstract.
Definition: type.h:88
static TF_API TfType const & Declare(const std::string &typeName)
Declare a TfType with the given typeName, but no base type information.
void(*)(TfType) DefinitionCallback
Callback invoked when a declared type needs to be defined.
Definition: type.h:76
static TF_API std::string GetCanonicalTypeName(const std::type_info &)
Return the canonical typeName used for a given std::type_info.
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.
A type-list of C++ base types.
Definition: type.h:106
TF_API std::vector< TfType > GetDirectlyDerivedTypes() const
Return a vector of types derived directly from this type.
Metafunction returning sizeof(T) for a type T (or 0 if T is a void type).
Definition: type.h:735
static TfType const & FindByTypeid(const std::type_info &t)
Retrieve the TfType corresponding to an obj with the given type_info.
Definition: type.h:195
const TfType & Factory(std::unique_ptr< T > &factory) const
Sets the factory object for this type.
Definition: type.h:611
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:630
bool IsRoot() const
Return true if this is the root type.
Definition: type.h:406
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.
TF_API void * CastToAncestor(TfType ancestor, void *addr) const
Cast addr to the address corresponding to the type ancestor.
LegacyFlags
Definition: type.h:86
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
static TfType const & Define()
Define a TfType with the given C++ type T and C++ base types B.
Definition: type_Impl.h:78
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...
Boost Python object wrapper.
Definition: pyObjWrapper.h:66
bool IsUnknown() const
Return true if this is the unknown type, representing a type unknown to the TfType system...
Definition: type.h:390
bool operator==(const TfType &t) const
Equality operator.
Definition: type.h:138
TF_API bool IsPlainOldDataType() const
Return true if this is a plain old data type, as defined by C++.
static TF_API TfType const & GetRoot()
Return the root type of the type hierarchy.
TF_API const std::type_info & GetTypeid() const
Return a C++ RTTI type_info for this type.
const TfType & Factory(std::unique_ptr< FactoryBase > factory) const
Sets the factory object for this type.
Definition: type.h:602
TfType represents a dynamic runtime type.
Definition: type.h:70
Implements assorted functions based on compile-time type information.
Definition: typeFunctions.h:54
TF_API TfType const & GetCanonicalType() const
Return the canonical type for this type.
bool IsA() const
Return true if this type is the same as or derived from T.
Definition: type.h:382
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:597
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:237
bool operator!() const
Boolean not operator – return true if this type is unknown, false otherwise.
Definition: type.h:402
TF_API TfType()
Construct an TfType representing an unknown type.
Manufacturable type (implies concrete)
Definition: type.h:89
Abstract (unmanufacturable and unclonable)
Definition: type.h:87