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 PXR_BASE_TF_TYPE_H
25 #define PXR_BASE_TF_TYPE_H
26 
27 #include "pxr/pxr.h"
28 
29 #include "pxr/base/tf/api.h"
32 
33 #include <iosfwd>
34 #include <memory>
35 #include <set>
36 #include <string>
37 #include <type_traits>
38 #include <typeinfo>
39 #include <vector>
40 
41 PXR_NAMESPACE_OPEN_SCOPE
42 
43 #ifdef PXR_PYTHON_SUPPORT_ENABLED
44 class TfPyObjWrapper;
45 #endif // PXR_PYTHON_SUPPORT_ENABLED
46 
64 class TfType
65 {
66  struct _TypeInfo;
67 
68 public:
70  using DefinitionCallback = void (*)(TfType);
71 
73  class FactoryBase {
74  public:
75  TF_API virtual ~FactoryBase();
76  };
77 
78 public:
79 
80  enum LegacyFlags {
81  ABSTRACT = 0x01,
82  CONCRETE = 0x02,
83  MANUFACTURABLE = 0x08,
84  };
85 
86 #ifdef PXR_PYTHON_SUPPORT_ENABLED
87  // This is a non-templated base class for the templated
88  // polymorphic-to-Python infrastructure.
89  struct PyPolymorphicBase
90  {
91  protected:
92  TF_API virtual ~PyPolymorphicBase();
93  };
94 #endif // PXR_PYTHON_SUPPORT_ENABLED
95 
96 public:
99  template <class ... Args>
100  struct Bases {};
101 
102 public:
113  TF_API
114  TfType();
115 
124  TF_API
125  static TfType const& GetUnknownType();
126 
132  inline bool operator ==(const TfType& t) const { return _info == t._info; }
133  inline bool operator !=(const TfType& t) const { return _info != t._info; }
134 
136  inline bool operator <(const TfType& t) const { return _info < t._info; }
137  inline bool operator >(const TfType& t) const { return _info > t._info; }
138  inline bool operator <=(const TfType& t) const { return _info <= t._info; }
139  inline bool operator >=(const TfType& t) const { return _info >= t._info; }
140 
141 
144 
152  template <typename T>
153  static TfType const& Find() {
154  return Find(typeid(T));
155  }
156 
172  template <typename T>
173  static TfType const& Find(const T &obj) {
174  // If T is polymorphic to python, we may have to bridge into python. We
175  // could also optimize for Ts that are not polymorphic at all and avoid
176  // doing rtti typeid lookups, but we trust the compiler to do this for
177  // us.
178  if (auto const *rawPtr = TfTypeFunctions<T>::GetRawPtr(obj))
179  return _FindImpl(rawPtr);
180  return GetUnknownType();
181  }
182 
186  static TfType const& Find(const std::type_info &t) {
187  return _FindByTypeid(t);
188  }
189 
193  static TfType const& FindByTypeid(const std::type_info &t) {
194  return _FindByTypeid(t);
195  }
196 
215  TF_API
216  static TfType const& FindByName(const std::string &name);
217 
223  TF_API
224  TfType const& FindDerivedByName(const std::string &name) const;
225 
234  template <typename BASE>
235  static TfType const& FindDerivedByName(const std::string &name)
236  {
237  return TfType::Find<BASE>().FindDerivedByName(name);
238  }
239 
240 #ifdef PXR_PYTHON_SUPPORT_ENABLED
241  TF_API
245  static TfType const& FindByPythonClass(const TfPyObjWrapper & classObj);
246 #endif // PXR_PYTHON_SUPPORT_ENABLED
247 
249 
250 
253 
260  TF_API
261  static TfType const& GetRoot();
262 
267  TF_API
268  const std::string &GetTypeName() const;
269 
277  TF_API
278  const std::type_info &GetTypeid() const;
279 
287  TF_API
288  static std::string GetCanonicalTypeName(const std::type_info &);
289 
294  TF_API
295  std::vector<std::string> GetAliases(TfType derivedType) const;
296 
297 #ifdef PXR_PYTHON_SUPPORT_ENABLED
298  TF_API
307  TfPyObjWrapper GetPythonClass() const;
308 #endif // PXR_PYTHON_SUPPORT_ENABLED
309 
312  TF_API
313  std::vector<TfType> GetBaseTypes() const;
314 
325  TF_API
326  size_t GetNBaseTypes(TfType *out, size_t maxBases) const;
327 
330  TF_API
331  std::vector<TfType> GetDirectlyDerivedTypes() const;
332 
334  TF_API
335  TfType const& GetCanonicalType() const;
336 
340  TF_API
341  void GetAllDerivedTypes( std::set<TfType> *result ) const;
342 
364  TF_API
365  void GetAllAncestorTypes(std::vector<TfType> *result) const;
366 
370  TF_API
371  bool IsA(TfType queryType) const;
372 
379  template <typename T>
380  bool IsA() const { return IsA(Find<T>()); }
381 
388  bool IsUnknown() const { return *this == TfType(); }
389 
390  typedef TfType::_TypeInfo * (TfType::*UnspecifiedBoolType);
391 
394  operator UnspecifiedBoolType() const {
395  return IsUnknown() ? NULL : &TfType::_info;
396  }
397 
400  bool operator !() const { return !bool(*this); }
401 
404  bool IsRoot() const { return *this == GetRoot(); }
405 
408  TF_API
409  bool IsEnumType() const;
410 
413  TF_API
414  bool IsPlainOldDataType() const;
415 
423  TF_API
424  size_t GetSizeof() const;
425 
427 
428 
431 
437  TF_API
438  static TfType const&
439  Declare( const std::string & typeName );
440 
455  TF_API
456  static TfType const&
457  Declare( const std::string & typeName,
458  const std::vector<TfType> & bases,
459  DefinitionCallback definitionCallback=nullptr );
460 
466  template <typename T, typename BaseTypes = TfType::Bases<>>
467  static TfType const& Declare();
468 
479  template <typename T, typename B>
480  static TfType const& Define();
481 
489  template <typename T>
490  static TfType const& Define();
491 
492 #ifdef PXR_PYTHON_SUPPORT_ENABLED
493  TF_API
496  void DefinePythonClass(const TfPyObjWrapper &classObj) const;
497 #endif // PXR_PYTHON_SUPPORT_ENABLED
498 
504  template <typename Base, typename Derived>
505  static void AddAlias(const std::string &name) {
506  TfType b = Declare(GetCanonicalTypeName(typeid(Base)));
507  TfType d = Declare(GetCanonicalTypeName(typeid(Derived)));
508  d.AddAlias(b, name);
509  }
510 
519  TF_API
520  void AddAlias(TfType base, const std::string &name) const;
521 
524  const TfType &Alias(TfType base, const std::string &name) const {
525  AddAlias(base, name);
526  return *this;
527  }
528 
530 
531 
534 
552  TF_API
553  void* CastToAncestor(TfType ancestor, void* addr) const;
554 
555  const void* CastToAncestor(TfType ancestor,
556  const void* addr) const {
557  return CastToAncestor(ancestor, const_cast<void*>(addr));
558  }
559 
574  TF_API
575  void* CastFromAncestor(TfType ancestor, void* addr) const;
576 
577  const void* CastFromAncestor(TfType ancestor,
578  const void* addr) const {
579  return CastFromAncestor(ancestor, const_cast<void*>(addr));
580  }
581 
583 
586 
590  TF_API
591  void SetFactory(std::unique_ptr<FactoryBase> factory) const;
592 
596  template <class T>
597  void SetFactory(std::unique_ptr<T>& factory) const {
598  SetFactory(std::unique_ptr<FactoryBase>(std::move(factory)));
599  }
600 
603  template <class T>
604  void SetFactory() const { SetFactory(std::unique_ptr<FactoryBase>(new T)); }
605 
609  const TfType& Factory(std::unique_ptr<FactoryBase> factory) const {
610  SetFactory(std::move(factory));
611  return *this;
612  }
613 
617  template <class T>
618  const TfType& Factory(std::unique_ptr<T>& factory) const
619  {
620  SetFactory(std::unique_ptr<FactoryBase>(std::move(factory)));
621  return *this;
622  }
623 
626  template <class T>
627  const TfType& Factory() const {
628  SetFactory(std::unique_ptr<FactoryBase>(new T));
629  return *this;
630  }
631 
636  template <class T>
637  T *GetFactory() const { return dynamic_cast<T*>(_GetFactory()); }
638 
640 
641 private:
642  TF_API
643  FactoryBase* _GetFactory() const;
644 
645 #ifdef PXR_PYTHON_SUPPORT_ENABLED
646  TF_API
647  static TfType const &_FindImplPyPolymorphic(PyPolymorphicBase const *ptr);
648 
649  // PyPolymorphic case.
650  template <class T>
651  static typename std::enable_if<
652  std::is_base_of<PyPolymorphicBase, T>::value, TfType const &>::type
653  _FindImpl(T const *rawPtr) {
654  return _FindImplPyPolymorphic(
655  static_cast<PyPolymorphicBase const *>(rawPtr));
656  }
657 
658  // Polymorphic.
659  template <class T>
660  static typename std::enable_if<
661  std::is_polymorphic<T>::value &&
662  !std::is_base_of<PyPolymorphicBase, T>::value, TfType const &>::type
663  _FindImpl(T const *rawPtr) {
664  if (auto ptr = dynamic_cast<PyPolymorphicBase const *>(rawPtr))
665  return _FindImplPyPolymorphic(ptr);
666  return Find(typeid(*rawPtr));
667  }
668 
669  template <class T>
670  static typename std::enable_if<
671  !std::is_polymorphic<T>::value, TfType const &>::type
672  _FindImpl(T const *rawPtr) {
673  return Find(typeid(T));
674  }
675 
676 #else
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(*rawPtr));
682  }
683 
684  template <class T>
685  static typename std::enable_if<
686  !std::is_polymorphic<T>::value, TfType const &>::type
687  _FindImpl(T const *rawPtr) {
688  return Find(typeid(T));
689  }
690 
691 #endif // PXR_PYTHON_SUPPORT_ENABLED
692 
693  bool _IsAImpl(TfType queryType) const;
694 
695  typedef void *(*_CastFunction)(void *, bool derivedToBase);
696 
697  template <typename TypeVector>
698  friend struct Tf_AddBases;
699  friend struct _TypeInfo;
700  friend class Tf_TypeRegistry;
701 
702  // TfHash support.
703  template <class HashState>
704  friend void
705  TfHashAppend(HashState &h, TfType const &type) {
706  h.Append(type._info);
707  }
708 
709  // Construct a TfType with the given _TypeInfo.
710  explicit TfType(_TypeInfo *info) : _info(info) {}
711 
712  // Adds base type(s), and link as a derived type of that bases.
713  void _AddBases(
714  const std::vector<TfType> &bases,
715  std::vector<std::string> *errorToEmit) const;
716 
717  // Add the given function for casting to/from the given baseType.
718  TF_API
719  void _AddCppCastFunc(
720  const std::type_info &baseTypeInfo, _CastFunction) const;
721 
722  // Define this TfType to have the given type_info.
723  TF_API
724  void _DefineCppType(const std::type_info &,
725  size_t sizeofType,
726  bool isPodType,
727  bool isEnumType) const;
728 
729  // Execute the definition callback if one exists.
730  void _ExecuteDefinitionCallback() const;
731 
732  // Retrieve the \c TfType corresponding to an obj with the
733  // given \c type_info.
734  TF_API
735  static TfType const& _FindByTypeid(const std::type_info &);
736 
737  // Pointer to internal type representation.
738  // Our only data member.
739  _TypeInfo *_info;
740 };
741 
744 TF_API std::ostream& operator<<(std::ostream& out, const TfType &t);
745 
747 template <typename T>
748 struct TfSizeofType {
749  static const size_t value = sizeof(T);
750 };
751 template <>
752 struct TfSizeofType<void> {
753  static const size_t value = 0;
754 };
755 template <>
756 struct TfSizeofType<const void> {
757  static const size_t value = 0;
758 };
759 template <>
760 struct TfSizeofType<volatile void> {
761  static const size_t value = 0;
762 };
763 template <>
764 struct TfSizeofType<const volatile void> {
765  static const size_t value = 0;
766 };
767 
768 PXR_NAMESPACE_CLOSE_SCOPE
769 
770 // Implementation details are put in this header.
771 #include "pxr/base/tf/type_Impl.h"
772 
773 #endif // PXR_BASE_TF_TYPE_H
static TF_API TfType const & GetUnknownType()
Return an empty TfType, representing the unknown type.
TF_API void GetAllDerivedTypes(std::set< TfType > *result) const
Return the set of all types derived (directly or indirectly) from 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:186
bool IsA() const
Return true if this type is the same as or derived from T.
Definition: type.h:380
void SetFactory(std::unique_ptr< T > &factory) const
Sets the factory object for this type.
Definition: type.h:597
bool operator !() const
Boolean not operator – return true if this type is unknown, false otherwise.
Definition: type.h:400
static TF_API TfType const & FindByName(const std::string &name)
Retrieve the TfType corresponding to the given name.
bool operator==(const TfType &t) const
Equality operator.
Definition: type.h:132
static void AddAlias(const std::string &name)
Add an alias for DERIVED beneath BASE.
Definition: type.h:505
static TfType const & Find()
Retrieve the TfType corresponding to type T.
Definition: type.h:153
const TfType & Factory(std::unique_ptr< FactoryBase > factory) const
Sets the factory object for this type.
Definition: type.h:609
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 TfType const & GetCanonicalType() const
Return the canonical type for this type.
Base class of all factory types.
Definition: type.h:73
TF_API const std::string & GetTypeName() const
Return the machine-independent name for this type.
static TfType const & Find(const T &obj)
Retrieve the TfType corresponding to obj.
Definition: type.h:173
TF_API bool IsEnumType() const
Return true if this is an enum type.
Not abstract.
Definition: type.h:82
void(*)(TfType) DefinitionCallback
Callback invoked when a declared type needs to be defined.
Definition: type.h:70
static TF_API std::string GetCanonicalTypeName(const std::type_info &)
Return the canonical typeName used for a given std::type_info.
A type-list of C++ base types.
Definition: type.h:100
void SetFactory() const
Sets the factory object for this type to be a T.
Definition: type.h:604
TF_API void * CastFromAncestor(TfType ancestor, void *addr) const
Cast addr, which pointed to the ancestor type ancestor, to the type of *this.
Metafunction returning sizeof(T) for a type T (or 0 if T is a void type).
Definition: type.h:748
static TfType const & FindByTypeid(const std::type_info &t)
Retrieve the TfType corresponding to an obj with the given type_info.
Definition: type.h:193
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 & Alias(TfType base, const std::string &name) const
Convenience method to add an alias and return *this.
Definition: type.h:524
static TfType const & Define()
Define a TfType with the given C++ type T and C++ base types B.
Definition: type_Impl.h:90
TF_API const std::type_info & GetTypeid() const
Return a C++ RTTI type_info for this type.
TF_API std::vector< TfType > GetDirectlyDerivedTypes() const
Return a vector of types derived directly from this type.
TF_API void GetAllAncestorTypes(std::vector< TfType > *result) const
Build a vector of all ancestor types inherited by this type.
const TfType & Factory() const
Sets the factory object for this type to be a T.
Definition: type.h:627
LegacyFlags
Definition: type.h:80
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 & Declare()
Declares a TfType with the given C++ type T and C++ base types Bases.
Definition: type_Impl.h:78
bool IsRoot() const
Return true if this is the root type.
Definition: type.h:404
Boost Python object wrapper.
Definition: pyObjWrapper.h:66
TF_API void * CastToAncestor(TfType ancestor, void *addr) const
Cast addr to the address corresponding to the type ancestor.
TF_API std::vector< TfType > GetBaseTypes() const
Return a vector of types from which this type was derived.
static TF_API TfType const & GetRoot()
Return the root type of the type hierarchy.
TfType represents a dynamic runtime type.
Definition: type.h:64
Implements assorted functions based on compile-time type information.
Definition: typeFunctions.h:54
TF_API bool IsPlainOldDataType() const
Return true if this is a plain old data type, as defined by C++.
bool IsUnknown() const
Return true if this is the unknown type, representing a type unknown to the TfType system.
Definition: type.h:388
TF_API std::ostream & operator<<(std::ostream &out, const TfType &t)
Output a TfType, using the machine-independent type name.
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:235
bool operator<(const TfType &t) const
Comparison operator.
Definition: type.h:136
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:637
const TfType & Factory(std::unique_ptr< T > &factory) const
Sets the factory object for this type.
Definition: type.h:618
TF_API TfType()
Construct an TfType representing an unknown type.
Manufacturable type (implies concrete)
Definition: type.h:83
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.
Abstract (unmanufacturable and unclonable)
Definition: type.h:81