HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
type.h
Go to the documentation of this file.
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 
25 
26 #ifdef PXR_PYTHON_SUPPORT_ENABLED
27 class TfPyObjWrapper;
28 #endif // PXR_PYTHON_SUPPORT_ENABLED
29 
30 /// \class TfType
31 ///
32 /// TfType represents a dynamic runtime type.
33 ///
34 /// TfTypes are created and discovered at runtime, rather than compile
35 /// time.
36 ///
37 /// Features:
38 ///
39 /// - unique typename
40 /// - safe across DSO boundaries
41 /// - can represent C++ types, pure Python types, or Python subclasses of
42 /// wrapped C++ types
43 /// - lightweight value semantics -- you can copy and default construct
44 /// TfType, unlike \c std::type_info.
45 /// - totally ordered -- can use as a \c std::map key
46 ///
47 class TfType
48 {
49  struct _TypeInfo;
50 
51 public:
52  /// Callback invoked when a declared type needs to be defined.
54 
55  /// Base class of all factory types.
56  class FactoryBase {
57  public:
58  TF_API virtual ~FactoryBase();
59  };
60 
61 public:
62 
63  enum LegacyFlags {
64  ABSTRACT = 0x01, ///< Abstract (unmanufacturable and unclonable)
65  CONCRETE = 0x02, ///< Not abstract
66  MANUFACTURABLE = 0x08, ///< Manufacturable type (implies concrete)
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 
79 public:
80  /// A type-list of C++ base types.
81  /// \see TfType::Define()
82  template <class ... Args>
83  struct Bases {};
84 
85 public:
86  /// Construct an TfType representing an unknown type.
87  ///
88  /// To actually register a new type with the TfType system, see
89  /// TfType::Declare().
90  ///
91  /// Note that this always holds true:
92  /// \code
93  /// TfType().IsUnknown() == true
94  /// \endcode
95  ///
96  TF_API
97  TfType();
98 
99  /// Return an empty TfType, representing the unknown type.
100  ///
101  /// This is equivalento the default constructor, TfType(). This form exists
102  /// as a clearer way to express intent in code explicitly dealing with
103  /// unknown types.
104  ///
105  /// \see IsUnknown()
106  ///
107  TF_API
108  static TfType const& GetUnknownType();
109 
110  /// Equality operator.
111  ///
112  /// \note All unknown types (see IsUnknown()) are considered equal.
113  /// This is so all unknown types will only occupy one key when used in
114  /// an associative map.
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 
118  /// Comparison operator.
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 
125  /// \name Finding types
126  /// @{
127 
128  /// Retrieve the \c TfType corresponding to type \c T.
129  ///
130  /// The type \c T must have been declared or defined in the type system or
131  /// the \c TfType corresponding to an unknown type is returned.
132  ///
133  /// \see IsUnknown()
134  ///
135  template <typename T>
136  static TfType const& Find() {
137  return Find(typeid(T));
138  }
139 
140  /// Retrieve the \c TfType corresponding to \c obj.
141  ///
142  /// The \c TfType corresponding to the actual object represented
143  /// by \c obj is returned; this may not be the object returned by
144  /// \c TfType::Find<T>() if \c T is a polymorphic type.
145  ///
146  /// This works for Python subclasses of the C++ type \c T as well,
147  /// as long as \c T has been wrapped using TfPyPolymorphic.
148  ///
149  /// Of course, the object's type must have been declared or defined in the
150  /// type system or the \c TfType corresponding to an unknown type is
151  /// returned.
152  ///
153  /// \see IsUnknown()
154  ///
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 
166  /// Retrieve the \c TfType corresponding to an obj with the
167  /// given \c type_info.
168  ///
169  static TfType const& Find(const std::type_info &t) {
170  return _FindByTypeid(t);
171  }
172 
173  /// Retrieve the \c TfType corresponding to an obj with the
174  /// given \c type_info.
175  ///
176  static TfType const& FindByTypeid(const std::type_info &t) {
177  return _FindByTypeid(t);
178  }
179 
180  /// Retrieve the \c TfType corresponding to the given \c name.
181  ///
182  /// Every type defined in the TfType system has a unique, implementation
183  /// independent name. In addition, aliases can be added to identify
184  /// a type underneath a specific base type; see TfType::AddAlias().
185  /// The given name will first be tried as an alias under the root type,
186  /// and subsequently as a typename.
187  ///
188  /// This method is equivalent to:
189  /// \code
190  /// TfType::GetRoot().FindDerivedByName(name)
191  /// \endcode
192  ///
193  /// For any object \c obj,
194  /// \code
195  /// Find(obj) == FindByName( Find(obj).GetTypeName() )
196  /// \endcode
197  ///
198  TF_API
199  static TfType const& FindByName(const std::string &name);
200 
201  /// Retrieve the \c TfType that derives from this type and has the
202  /// given alias or typename.
203  ///
204  /// \see AddAlias
205  ///
206  TF_API
207  TfType const& FindDerivedByName(const std::string &name) const;
208 
209  /// Retrieve the \c TfType that derives from BASE and has the
210  /// given alias or typename.
211  ///
212  /// This is a convenience method, and is equivalent to:
213  /// \code
214  /// TfType::Find<BASE>().FindDerivedByName(name)
215  /// \endcode
216  ///
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
224  /// Retrieve the \c TfType corresponding to an obj with the
225  /// given Python class \c classObj.
226  ///
227  TF_API
228  static TfType const& FindByPythonClass(const TfPyObjWrapper & classObj);
229 #endif // PXR_PYTHON_SUPPORT_ENABLED
230 
231  /// @}
232 
233 
234  /// \name Type queries
235  /// @{
236 
237  /// Return the root type of the type hierarchy.
238  ///
239  /// All known types derive (directly or indirectly) from the root.
240  /// If a type is specified with no bases, it is implicitly
241  /// considered to derive from the root type.
242  ///
243  TF_API
244  static TfType const& GetRoot();
245 
246  /// Return the machine-independent name for this type.
247  /// This name is specified when the TfType is declared.
248  /// \see Declare()
249  ///
250  TF_API
251  const std::string &GetTypeName() const;
252 
253  /// Return a C++ RTTI type_info for this type.
254  ///
255  /// If this type is unknown, this will return a unique \c type_info
256  /// specifically for the unknown type.
257  ///
258  /// If this type has been declared, but not yet had a C++ type defined,
259  /// \c typeid(void) will be returned.
260  ///
261  /// \see Define()
262  ///
263  TF_API
264  const std::type_info &GetTypeid() const;
265 
266  /// Return the canonical typeName used for a given std::type_info.
267  ///
268  /// Exactly how the canonical name is generated is left undefined,
269  /// but in practice it is likely to be the demangled RTTI name
270  /// of the type_info, stripped of namespaces. The real answer
271  /// is implemented by this method.
272  ///
273  TF_API
274  static std::string GetCanonicalTypeName(const std::type_info &);
275 
276  /// Returns a vector of the aliases registered for the derivedType
277  /// under this, the base type.
278  /// \see AddAlias()
279  ///
280  TF_API
281  std::vector<std::string> GetAliases(TfType derivedType) const;
282 
283 #ifdef PXR_PYTHON_SUPPORT_ENABLED
284  /// Return the Python class object for this type.
285  ///
286  /// If this type is unknown or has not yet had a Python class
287  /// defined, this will return \c None, as an empty
288  /// \c TfPyObjWrapper
289  ///
290  /// \see DefinePythonClass()
291  ///
292  TF_API
293  TfPyObjWrapper GetPythonClass() const;
294 #endif // PXR_PYTHON_SUPPORT_ENABLED
295 
296  /// Return a vector of types from which this type was derived.
297  ///
298  TF_API
299  std::vector<TfType> GetBaseTypes() const;
300 
301  /// Copy the first \p maxBases base types of \p this type to \p out, or all
302  /// the base types if this type has \p maxBases or fewer base types. Return
303  /// \p this type's number of base types.
304  ///
305  /// Note that it is supported to change a TfType to its first base type by
306  /// calling this function. For example:
307  /// \code
308  /// TfType t = ...;
309  /// t.GetNBaseTypes(&t, 1);
310  /// \endcode
311  TF_API
312  size_t GetNBaseTypes(TfType *out, size_t maxBases) const;
313 
314  /// Return a vector of types derived directly from this type.
315  ///
316  TF_API
317  std::vector<TfType> GetDirectlyDerivedTypes() const;
318 
319  /// Return the canonical type for this type.
320  TF_API
321  TfType const& GetCanonicalType() const;
322 
323  /// Return the set of all types derived (directly or indirectly)
324  /// from this type.
325  ///
326  TF_API
327  void GetAllDerivedTypes( std::set<TfType> *result ) const;
328 
329  /// Build a vector of all ancestor types inherited by this type.
330  /// The starting type is itself included, as the first element of
331  /// the results vector.
332  ///
333  /// Types are given in "C3" resolution order, as used for new-style
334  /// classes starting in Python 2.3. This algorithm is more complicated
335  /// than a simple depth-first traversal of base classes, in order to
336  /// prevent some subtle errors with multiple-inheritance. See the
337  /// references below for more background.
338  ///
339  /// \note This can be expensive; consider caching the results. TfType
340  /// does not cache this itself since it is not needed internally.
341  ///
342  /// \see Guido van Rossum.
343  /// "Unifying types and classes in Python 2.2: Method resolution order."
344  /// http://www.python.org/download/releases/2.2.2/descrintro/#mro
345  ///
346  /// \see Barrett, Cassels, Haahr, Moon, Playford, Withington.
347  /// "A Monotonic Superclass Linearization for Dylan." OOPSLA 96.
348  /// https://opendylan.org/_static/c3-linearization.pdf
349  ///
350  TF_API
351  void GetAllAncestorTypes(std::vector<TfType> *result) const;
352 
353  /// Return true if this type is the same as or derived from \p queryType.
354  /// If \c queryType is unknown, this always returns \c false.
355  ///
356  TF_API
357  bool IsA(TfType queryType) const;
358 
359  /// Return true if this type is the same as or derived from T.
360  /// This is equivalent to:
361  /// \code
362  /// IsA(Find<T>())
363  /// \endcode
364  ///
365  template <typename T>
366  bool IsA() const { return IsA(Find<T>()); }
367 
368  /// Return true if this is the unknown type, representing a type
369  /// unknown to the TfType system.
370  ///
371  /// The unknown type does not derive from the root type, or any
372  /// other type.
373  ///
374  bool IsUnknown() const { return *this == TfType(); }
375 
377 
378  /// Convert to bool -- return true if this type is not unknown, false
379  /// otherwise.
380  operator UnspecifiedBoolType() const {
381  return IsUnknown() ? NULL : &TfType::_info;
382  }
383 
384  /// Boolean not operator -- return true if this type is unknown, false
385  /// otherwise.
386  bool operator !() const { return !bool(*this); }
387 
388  /// Return true if this is the root type.
389  ///
390  bool IsRoot() const { return *this == GetRoot(); }
391 
392  /// Return true if this is an enum type.
393  ///
394  TF_API
395  bool IsEnumType() const;
396 
397  /// Return true if this is a plain old data type, as defined by C++.
398  ///
399  TF_API
400  bool IsPlainOldDataType() const;
401 
402  /// Return the size required to hold an instance of this type on the stack
403  /// (does not include any heap allocated memory the instance uses).
404  ///
405  /// This is what the C++ sizeof operator returns for the type, so this
406  /// value is not very useful for Python types (it will always be
407  /// sizeof(pxr_boost::python::object)).
408  ///
409  TF_API
410  size_t GetSizeof() const;
411 
412  /// @}
413 
414 
415  /// \name Registering new types
416  /// @{
417 
418  /// Declare a TfType with the given \c typeName, but no base type
419  /// information. This just establishes the minimal stub for the
420  /// type to exist, prior to it being fleshed out with more
421  /// declarations (specifying base types) or a definition.
422  ///
423  TF_API
424  static TfType const&
425  Declare( const std::string & typeName );
426 
427  /// Declare a TfType with the given \c typeName and \c bases.
428  /// If the bases vector is empty, the type will be marked as
429  /// deriving from the root TfType (see TfType::GetRootType()).
430  /// The \c definitionCallback, if given, will be invoked later to
431  /// define the type when needed.
432  ///
433  /// It is ok to redeclare a type that has already been declared.
434  /// The given bases will supplement any existing bases. An
435  /// example use of this is the Plugin system, where only a single
436  /// base may be known in the plugin metadata, but when the code
437  /// is loaded later, a full set of bases is specified.
438  ///
439  /// It is an error to redeclare a type's definitionCallback.
440  ///
441  TF_API
442  static TfType const&
443  Declare( const std::string & typeName,
444  const std::vector<TfType> & bases,
445  DefinitionCallback definitionCallback=nullptr );
446 
447  /// Declares a TfType with the given C++ type T and C++ base types Bases.
448  /// Each of the base types will be declared (but not defined) as TfTypes if
449  /// they have not already been. See the other Declare() methods for more
450  /// details.
451  ///
452  template <typename T, typename BaseTypes = TfType::Bases<>>
453  static TfType const& Declare();
454 
455  /// Define a TfType with the given C++ type T and C++ base types
456  /// B. Each of the base types will be declared (but not defined)
457  /// as TfTypes if they have not already been.
458  ///
459  /// The typeName of the created TfType will be the canonical
460  /// demangled RTTI type name, as defined by GetCanonicalTypeName().
461  ///
462  /// It is an error to attempt to define a type that has already
463  /// been defined.
464  ///
465  template <typename T, typename B>
466  static TfType const& Define();
467 
468  /// Define a TfType with the given C++ type T and no bases.
469  /// See the other Define() template for more details.
470  ///
471  /// \note C++ does not allow default template arguments for function
472  /// templates, so we provide this separate definition for the case of
473  /// no bases.
474  ///
475  template <typename T>
476  static TfType const& Define();
477 
478 #ifdef PXR_PYTHON_SUPPORT_ENABLED
479  /// Define the Python class object corresponding to this TfType.
480  /// \see TfTypePythonClass
481  TF_API
482  void DefinePythonClass(const TfPyObjWrapper &classObj) const;
483 #endif // PXR_PYTHON_SUPPORT_ENABLED
484 
485  /// Add an alias for DERIVED beneath BASE.
486  ///
487  /// This is a convenience method, that declares both DERIVED and BASE
488  /// as TfTypes before adding the alias.
489  ///
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 
497  /// Add an alias name for this type under the given base type.
498  ///
499  /// Aliases are similar to typedefs in C++: they provide an
500  /// alternate name for a type. The alias is defined with respect
501  /// to the given \c base type. Aliases must be unique with respect to both
502  /// other aliases beneath that base type and names of derived types of that
503  /// base.
504  ///
505  TF_API
506  void AddAlias(TfType base, const std::string &name) const;
507 
508  /// Convenience method to add an alias and return *this.
509  /// \see AddAlias()
510  const TfType &Alias(TfType base, const std::string &name) const {
511  AddAlias(base, name);
512  return *this;
513  }
514 
515  /// @}
516 
517 
518  /// \name Pointer casts
519  /// @{
520 
521  /// Cast \c addr to the address corresponding to the type \c ancestor.
522  ///
523  /// (This is a dangerous function; there's probably a much better way to
524  /// do whatever it is you're trying to do.)
525  ///
526  /// With multiple inheritance, you can't do a reinterpret_cast back to an
527  /// ancestor type; this function figures out how to cast addr to the
528  /// address corresponding to the type ancestor if in fact ancestor is
529  /// really an ancestor of the type corresponding to \c *this.
530  ///
531  /// In order for this function to work correctly, \p addr must have been a
532  /// pointer of type corresponding to \c *this, which was cast to void; and
533  /// of course the type of \p ancestor must be an ancestor of the type of
534  /// \c *this.
535  ///
536  /// \warning You are warned: this is deadly dangerous stuff, and you
537  /// shouldn't be doing it!
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 
546  /// Cast \c addr, which pointed to the ancestor type \p ancestor, to the
547  /// type of \c *this.
548  ///
549  /// This function is the opposite of \c CastToAncestor(); the assumption
550  /// is that \c addr was a pointer to the type corresponding to \c
551  /// ancestor, and was then reinterpret-cast to \c void*, but now you wish
552  /// to turn cast the pointer to the type corresponding to \c *this. While
553  /// the fact that \p addr was a pointer of type \c ancestor is taken on
554  /// faith, a runtime check is performed to verify that the underlying
555  /// object pointed to by \p addr is of type \c *this (or derived from \c
556  /// *this).
557  ///
558  /// \warning Again, this is dangerous territory, and there's probably
559  /// something much better than using this function.
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 
568  /// @}
569 
570  /// \name Instantiation / Manufacturing
571  /// @{
572 
573  /// Sets the factory object for this type. A type's factory typically
574  /// has methods to instantiate the type given various arguments and must
575  /// inherit from \c FactoryBase. The factory cannot be changed once set.
576  TF_API
577  void SetFactory(std::unique_ptr<FactoryBase> &&factory) const;
578 
579  /// Sets the factory object for this type. A type's factory typically
580  /// has methods to instantiate the type given various arguments and must
581  /// inherit from \c FactoryBase. The factory cannot be changed once set.
582  template <class T>
583  void SetFactory(std::unique_ptr<T> &&factory) const {
584  SetFactory(std::unique_ptr<FactoryBase>(std::move(factory)));
585  }
586 
587  /// Sets the factory object for this type to be a \c T. The factory
588  /// cannot be changed once set.
589  template <class T>
590  void SetFactory() const { SetFactory(std::unique_ptr<FactoryBase>(new T)); }
591 
592  /// Sets the factory object for this type. A type's factory typically
593  /// has methods to instantiate the type given various arguments and must
594  /// inherit from \c FactoryBase. The factory cannot be changed once set.
595  const TfType& Factory(std::unique_ptr<FactoryBase> &&factory) const {
596  SetFactory(std::move(factory));
597  return *this;
598  }
599 
600  /// Sets the factory object for this type. A type's factory typically
601  /// has methods to instantiate the type given various arguments and must
602  /// inherit from \c FactoryBase. The factory cannot be changed once set.
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 
610  /// Sets the factory object for this type to be a \c T. The factory
611  /// cannot be changed once set.
612  template <class T>
613  const TfType& Factory() const {
614  SetFactory(std::unique_ptr<FactoryBase>(new T));
615  return *this;
616  }
617 
618  /// Returns the factory object for this type as a \c T*, or \c NULL if
619  /// there is no factory or the factory is not or is not derived from \c T.
620  /// Clients can check if a factory is set using
621  /// \c GetFactory<TfType::FactoryBase>().
622  template <class T>
623  T *GetFactory() const { return dynamic_cast<T*>(_GetFactory()); }
624 
625  /// @}
626 
627 private:
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 
731 /// Output a TfType, using the machine-independent type name.
732 /// \ingroup group_tf_DebuggingOutput
733 TF_API std::ostream& operator<<(std::ostream& out, const TfType &t);
734 
735 /// Metafunction returning sizeof(T) for a type T (or 0 if T is a void type).
736 template <typename T>
737 struct TfSizeofType {
738  static const size_t value = sizeof(T);
739 };
740 template <>
742  static const size_t value = 0;
743 };
744 template <>
745 struct TfSizeofType<const void> {
746  static const size_t value = 0;
747 };
748 template <>
749 struct TfSizeofType<volatile void> {
750  static const size_t value = 0;
751 };
752 template <>
753 struct TfSizeofType<const volatile void> {
754  static const size_t value = 0;
755 };
756 
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
bool operator<=(const TfType &t) const
Definition: type.h:121
bool IsUnknown() const
Definition: type.h:374
static TF_API TfType const & GetUnknownType()
#define TF_API
Definition: api.h:23
void
Definition: png.h:1083
bool IsA() const
Definition: type.h:366
static TfType const & FindDerivedByName(const std::string &name)
Definition: type.h:218
GLsizei const GLfloat * value
Definition: glcorearb.h:824
static TF_API std::string GetCanonicalTypeName(const std::type_info &)
Manufacturable type (implies concrete)
Definition: type.h:66
static TfType const & Find()
Definition: type.h:136
static TfType const & FindByTypeid(const std::type_info &t)
Definition: type.h:176
**But if you need a result
Definition: thread.h:622
TF_API std::vector< TfType > GetBaseTypes() const
TF_API void GetAllDerivedTypes(std::set< TfType > *result) const
TF_API TfType const & FindDerivedByName(const std::string &name) const
bool operator!() const
Definition: type.h:386
OutGridT const XformOp bool bool
friend struct Tf_AddBases
Definition: type.h:672
TF_API TfType()
static TfType const & Find(const std::type_info &t)
Definition: type.h:169
Base class of all factory types.
Definition: type.h:56
const void * CastToAncestor(TfType ancestor, const void *addr) const
Definition: type.h:541
friend void TfHashAppend(HashState &h, TfType const &type)
Definition: type.h:679
virtual TF_API ~FactoryBase()
static TfType const & Declare()
Definition: type_Impl.h:53
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
bool operator!=(const TfType &t) const
Definition: type.h:116
const TfType & Alias(TfType base, const std::string &name) const
Definition: type.h:510
const TfType & Factory() const
Definition: type.h:613
bool operator>(const TfType &t) const
Definition: type.h:120
static TfType const & Define()
Definition: type_Impl.h:61
bool IsRoot() const
Definition: type.h:390
static TF_API TfType const & FindByName(const std::string &name)
TF_API bool IsPlainOldDataType() const
TF_API void * CastToAncestor(TfType ancestor, void *addr) const
friend class Tf_TypeRegistry
Definition: type.h:674
TF_API std::vector< std::string > GetAliases(TfType derivedType) const
Metafunction returning sizeof(T) for a type T (or 0 if T is a void type).
Definition: type.h:737
LegacyFlags
Definition: type.h:63
GLuint const GLchar * name
Definition: glcorearb.h:786
TF_API size_t GetNBaseTypes(TfType *out, size_t maxBases) const
bool operator==(const TfType &t) const
Definition: type.h:115
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
friend struct _TypeInfo
Definition: type.h:673
Not abstract.
Definition: type.h:65
static TfType const & Find(const T &obj)
Definition: type.h:156
TF_API bool IsEnumType() const
GLdouble t
Definition: glad.h:2397
bool operator>=(const TfType &t) const
Definition: type.h:122
TF_API TfType const & GetCanonicalType() const
Return the canonical type for this type.
const TfType & Factory(std::unique_ptr< FactoryBase > &&factory) const
Definition: type.h:595
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
TF_API size_t GetSizeof() const
TF_API void GetAllAncestorTypes(std::vector< TfType > *result) const
const TfType & Factory(std::unique_ptr< T > &&factory) const
Definition: type.h:604
void(*)(TfType) DefinitionCallback
Callback invoked when a declared type needs to be defined.
Definition: type.h:53
TF_API const std::string & GetTypeName() const
TfType::_TypeInfo *TfType::* UnspecifiedBoolType
Definition: type.h:376
TF_API void * CastFromAncestor(TfType ancestor, void *addr) const
auto ptr(T p) -> const void *
Definition: format.h:4331
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
static void AddAlias(const std::string &name)
Definition: type.h:491
Definition: type.h:47
const void * CastFromAncestor(TfType ancestor, const void *addr) const
Definition: type.h:563
TF_API const std::type_info & GetTypeid() const
void SetFactory(std::unique_ptr< T > &&factory) const
Definition: type.h:583
T * GetFactory() const
Definition: type.h:623
TF_API std::ostream & operator<<(std::ostream &out, const TfType &t)
Abstract (unmanufacturable and unclonable)
Definition: type.h:64
TF_API std::vector< TfType > GetDirectlyDerivedTypes() const
static TF_API TfType const & GetRoot()
bool operator<(const TfType &t) const
Comparison operator.
Definition: type.h:119
void SetFactory() const
Definition: type.h:590