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 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 
42 
43 #ifdef PXR_PYTHON_SUPPORT_ENABLED
44 class TfPyObjWrapper;
45 #endif // PXR_PYTHON_SUPPORT_ENABLED
46 
47 /// \class TfType
48 ///
49 /// TfType represents a dynamic runtime type.
50 ///
51 /// TfTypes are created and discovered at runtime, rather than compile
52 /// time.
53 ///
54 /// Features:
55 ///
56 /// - unique typename
57 /// - safe across DSO boundaries
58 /// - can represent C++ types, pure Python types, or Python subclasses of
59 /// wrapped C++ types
60 /// - lightweight value semantics -- you can copy and default construct
61 /// TfType, unlike \c std::type_info.
62 /// - totally ordered -- can use as a \c std::map key
63 ///
64 class TfType
65 {
66  struct _TypeInfo;
67 
68 public:
69  /// Callback invoked when a declared type needs to be defined.
71 
72  /// Base class of all factory types.
73  class FactoryBase {
74  public:
75  TF_API virtual ~FactoryBase();
76  };
77 
78 public:
79 
80  enum LegacyFlags {
81  ABSTRACT = 0x01, ///< Abstract (unmanufacturable and unclonable)
82  CONCRETE = 0x02, ///< Not abstract
83  MANUFACTURABLE = 0x08, ///< Manufacturable type (implies concrete)
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:
97  /// A type-list of C++ base types.
98  /// \see TfType::Define()
99  template <class ... Args>
100  struct Bases {};
101 
102 public:
103  /// Construct an TfType representing an unknown type.
104  ///
105  /// To actually register a new type with the TfType system, see
106  /// TfType::Declare().
107  ///
108  /// Note that this always holds true:
109  /// \code
110  /// TfType().IsUnknown() == true
111  /// \endcode
112  ///
113  TF_API
114  TfType();
115 
116  /// Return an empty TfType, representing the unknown type.
117  ///
118  /// This is equivalento the default constructor, TfType(). This form exists
119  /// as a clearer way to express intent in code explicitly dealing with
120  /// unknown types.
121  ///
122  /// \see IsUnknown()
123  ///
124  TF_API
125  static TfType const& GetUnknownType();
126 
127  /// Equality operator.
128  ///
129  /// \note All unknown types (see IsUnknown()) are considered equal.
130  /// This is so all unknown types will only occupy one key when used in
131  /// an associative map.
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 
135  /// Comparison operator.
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 
142  /// \name Finding types
143  /// @{
144 
145  /// Retrieve the \c TfType corresponding to type \c T.
146  ///
147  /// The type \c T must have been declared or defined in the type system or
148  /// the \c TfType corresponding to an unknown type is returned.
149  ///
150  /// \see IsUnknown()
151  ///
152  template <typename T>
153  static TfType const& Find() {
154  return Find(typeid(T));
155  }
156 
157  /// Retrieve the \c TfType corresponding to \c obj.
158  ///
159  /// The \c TfType corresponding to the actual object represented
160  /// by \c obj is returned; this may not be the object returned by
161  /// \c TfType::Find<T>() if \c T is a polymorphic type.
162  ///
163  /// This works for Python subclasses of the C++ type \c T as well,
164  /// as long as \c T has been wrapped using TfPyPolymorphic.
165  ///
166  /// Of course, the object's type must have been declared or defined in the
167  /// type system or the \c TfType corresponding to an unknown type is
168  /// returned.
169  ///
170  /// \see IsUnknown()
171  ///
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 
183  /// Retrieve the \c TfType corresponding to an obj with the
184  /// given \c type_info.
185  ///
186  static TfType const& Find(const std::type_info &t) {
187  return _FindByTypeid(t);
188  }
189 
190  /// Retrieve the \c TfType corresponding to an obj with the
191  /// given \c type_info.
192  ///
193  static TfType const& FindByTypeid(const std::type_info &t) {
194  return _FindByTypeid(t);
195  }
196 
197  /// Retrieve the \c TfType corresponding to the given \c name.
198  ///
199  /// Every type defined in the TfType system has a unique, implementation
200  /// independent name. In addition, aliases can be added to identify
201  /// a type underneath a specific base type; see TfType::AddAlias().
202  /// The given name will first be tried as an alias under the root type,
203  /// and subsequently as a typename.
204  ///
205  /// This method is equivalent to:
206  /// \code
207  /// TfType::GetRoot().FindDerivedByName(name)
208  /// \endcode
209  ///
210  /// For any object \c obj,
211  /// \code
212  /// Find(obj) == FindByName( Find(obj).GetTypeName() )
213  /// \endcode
214  ///
215  TF_API
216  static TfType const& FindByName(const std::string &name);
217 
218  /// Retrieve the \c TfType that derives from this type and has the
219  /// given alias or typename.
220  ///
221  /// \see AddAlias
222  ///
223  TF_API
224  TfType const& FindDerivedByName(const std::string &name) const;
225 
226  /// Retrieve the \c TfType that derives from BASE and has the
227  /// given alias or typename.
228  ///
229  /// This is a convenience method, and is equivalent to:
230  /// \code
231  /// TfType::Find<BASE>().FindDerivedByName(name)
232  /// \endcode
233  ///
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  /// Retrieve the \c TfType corresponding to an obj with the
242  /// given Python class \c classObj.
243  ///
244  TF_API
245  static TfType const& FindByPythonClass(const TfPyObjWrapper & classObj);
246 #endif // PXR_PYTHON_SUPPORT_ENABLED
247 
248  /// @}
249 
250 
251  /// \name Type queries
252  /// @{
253 
254  /// Return the root type of the type hierarchy.
255  ///
256  /// All known types derive (directly or indirectly) from the root.
257  /// If a type is specified with no bases, it is implicitly
258  /// considered to derive from the root type.
259  ///
260  TF_API
261  static TfType const& GetRoot();
262 
263  /// Return the machine-independent name for this type.
264  /// This name is specified when the TfType is declared.
265  /// \see Declare()
266  ///
267  TF_API
268  const std::string &GetTypeName() const;
269 
270  /// Return a C++ RTTI type_info for this type.
271  ///
272  /// If this type is unknown or has not yet had a C++ type defined,
273  /// \c typeid(void) will be returned.
274  ///
275  /// \see Define()
276  ///
277  TF_API
278  const std::type_info &GetTypeid() const;
279 
280  /// Return the canonical typeName used for a given std::type_info.
281  ///
282  /// Exactly how the canonical name is generated is left undefined,
283  /// but in practice it is likely to be the demangled RTTI name
284  /// of the type_info, stripped of namespaces. The real answer
285  /// is implemented by this method.
286  ///
287  TF_API
288  static std::string GetCanonicalTypeName(const std::type_info &);
289 
290  /// Returns a vector of the aliases registered for the derivedType
291  /// under this, the base type.
292  /// \see AddAlias()
293  ///
294  TF_API
295  std::vector<std::string> GetAliases(TfType derivedType) const;
296 
297 #ifdef PXR_PYTHON_SUPPORT_ENABLED
298  /// Return the Python class object for this type.
299  ///
300  /// If this type is unknown or has not yet had a Python class
301  /// defined, this will return \c None, as an empty
302  /// \c TfPyObjWrapper
303  ///
304  /// \see DefinePythonClass()
305  ///
306  TF_API
307  TfPyObjWrapper GetPythonClass() const;
308 #endif // PXR_PYTHON_SUPPORT_ENABLED
309 
310  /// Return a vector of types from which this type was derived.
311  ///
312  TF_API
313  std::vector<TfType> GetBaseTypes() const;
314 
315  /// Copy the first \p maxBases base types of \p this type to \p out, or all
316  /// the base types if this type has \p maxBases or fewer base types. Return
317  /// \p this type's number of base types.
318  ///
319  /// Note that it is supported to change a TfType to its first base type by
320  /// calling this function. For example:
321  /// \code
322  /// TfType t = ...;
323  /// t.GetNBaseTypes(&t, 1);
324  /// \endcode
325  TF_API
326  size_t GetNBaseTypes(TfType *out, size_t maxBases) const;
327 
328  /// Return a vector of types derived directly from this type.
329  ///
330  TF_API
331  std::vector<TfType> GetDirectlyDerivedTypes() const;
332 
333  /// Return the canonical type for this type.
334  TF_API
335  TfType const& GetCanonicalType() const;
336 
337  /// Return the set of all types derived (directly or indirectly)
338  /// from this type.
339  ///
340  TF_API
341  void GetAllDerivedTypes( std::set<TfType> *result ) const;
342 
343  /// Build a vector of all ancestor types inherited by this type.
344  /// The starting type is itself included, as the first element of
345  /// the results vector.
346  ///
347  /// Types are given in "C3" resolution order, as used for new-style
348  /// classes starting in Python 2.3. This algorithm is more complicated
349  /// than a simple depth-first traversal of base classes, in order to
350  /// prevent some subtle errors with multiple-inheritance. See the
351  /// references below for more background.
352  ///
353  /// \note This can be expensive; consider caching the results. TfType
354  /// does not cache this itself since it is not needed internally.
355  ///
356  /// \see Guido van Rossum.
357  /// "Unifying types and classes in Python 2.2: Method resolution order."
358  /// http://www.python.org/download/releases/2.2.2/descrintro/#mro
359  ///
360  /// \see Barrett, Cassels, Haahr, Moon, Playford, Withington.
361  /// "A Monotonic Superclass Linearization for Dylan." OOPSLA 96.
362  /// http://www.webcom.com/haahr/dylan/linearization-oopsla96.html
363  ///
364  TF_API
365  void GetAllAncestorTypes(std::vector<TfType> *result) const;
366 
367  /// Return true if this type is the same as or derived from \p queryType.
368  /// If \c queryType is unknown, this always returns \c false.
369  ///
370  TF_API
371  bool IsA(TfType queryType) const;
372 
373  /// Return true if this type is the same as or derived from T.
374  /// This is equivalent to:
375  /// \code
376  /// IsA(Find<T>())
377  /// \endcode
378  ///
379  template <typename T>
380  bool IsA() const { return IsA(Find<T>()); }
381 
382  /// Return true if this is the unknown type, representing a type
383  /// unknown to the TfType system.
384  ///
385  /// The unknown type does not derive from the root type, or any
386  /// other type.
387  ///
388  bool IsUnknown() const { return *this == TfType(); }
389 
391 
392  /// Convert to bool -- return true if this type is not unknown, false
393  /// otherwise.
394  operator UnspecifiedBoolType() const {
395  return IsUnknown() ? NULL : &TfType::_info;
396  }
397 
398  /// Boolean not operator -- return true if this type is unknown, false
399  /// otherwise.
400  bool operator !() const { return !bool(*this); }
401 
402  /// Return true if this is the root type.
403  ///
404  bool IsRoot() const { return *this == GetRoot(); }
405 
406  /// Return true if this is an enum type.
407  ///
408  TF_API
409  bool IsEnumType() const;
410 
411  /// Return true if this is a plain old data type, as defined by C++.
412  ///
413  TF_API
414  bool IsPlainOldDataType() const;
415 
416  /// Return the size required to hold an instance of this type on the stack
417  /// (does not include any heap allocated memory the instance uses).
418  ///
419  /// This is what the C++ sizeof operator returns for the type, so this
420  /// value is not very useful for Python types (it will always be
421  /// sizeof(hboost::python::object)).
422  ///
423  TF_API
424  size_t GetSizeof() const;
425 
426  /// @}
427 
428 
429  /// \name Registering new types
430  /// @{
431 
432  /// Declare a TfType with the given \c typeName, but no base type
433  /// information. This just establishes the minimal stub for the
434  /// type to exist, prior to it being fleshed out with more
435  /// declarations (specifying base types) or a definition.
436  ///
437  TF_API
438  static TfType const&
439  Declare( const std::string & typeName );
440 
441  /// Declare a TfType with the given \c typeName and \c bases.
442  /// If the bases vector is empty, the type will be marked as
443  /// deriving from the root TfType (see TfType::GetRootType()).
444  /// The \c definitionCallback, if given, will be invoked later to
445  /// define the type when needed.
446  ///
447  /// It is ok to redeclare a type that has already been declared.
448  /// The given bases will supplement any existing bases. An
449  /// example use of this is the Plugin system, where only a single
450  /// base may be known in the plugin metadata, but when the code
451  /// is loaded later, a full set of bases is specified.
452  ///
453  /// It is an error to redeclare a type's definitionCallback.
454  ///
455  TF_API
456  static TfType const&
457  Declare( const std::string & typeName,
458  const std::vector<TfType> & bases,
459  DefinitionCallback definitionCallback=nullptr );
460 
461  /// Declares a TfType with the given C++ type T and C++ base types Bases.
462  /// Each of the base types will be declared (but not defined) as TfTypes if
463  /// they have not already been. See the other Declare() methods for more
464  /// details.
465  ///
466  template <typename T, typename BaseTypes = TfType::Bases<>>
467  static TfType const& Declare();
468 
469  /// Define a TfType with the given C++ type T and C++ base types
470  /// B. Each of the base types will be declared (but not defined)
471  /// as TfTypes if they have not already been.
472  ///
473  /// The typeName of the created TfType will be the canonical
474  /// demangled RTTI type name, as defined by GetCanonicalTypeName().
475  ///
476  /// It is an error to attempt to define a type that has already
477  /// been defined.
478  ///
479  template <typename T, typename B>
480  static TfType const& Define();
481 
482  /// Define a TfType with the given C++ type T and no bases.
483  /// See the other Define() template for more details.
484  ///
485  /// \note C++ does not allow default template arguments for function
486  /// templates, so we provide this separate definition for the case of
487  /// no bases.
488  ///
489  template <typename T>
490  static TfType const& Define();
491 
492 #ifdef PXR_PYTHON_SUPPORT_ENABLED
493  /// Define the Python class object corresponding to this TfType.
494  /// \see TfTypePythonClass
495  TF_API
496  void DefinePythonClass(const TfPyObjWrapper &classObj) const;
497 #endif // PXR_PYTHON_SUPPORT_ENABLED
498 
499  /// Add an alias for DERIVED beneath BASE.
500  ///
501  /// This is a convenience method, that declares both DERIVED and BASE
502  /// as TfTypes before adding the alias.
503  ///
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 
511  /// Add an alias name for this type under the given base type.
512  ///
513  /// Aliases are similar to typedefs in C++: they provide an
514  /// alternate name for a type. The alias is defined with respect
515  /// to the given \c base type. Aliases must be unique with respect to both
516  /// other aliases beneath that base type and names of derived types of that
517  /// base.
518  ///
519  TF_API
520  void AddAlias(TfType base, const std::string &name) const;
521 
522  /// Convenience method to add an alias and return *this.
523  /// \see AddAlias()
524  const TfType &Alias(TfType base, const std::string &name) const {
525  AddAlias(base, name);
526  return *this;
527  }
528 
529  /// @}
530 
531 
532  /// \name Pointer casts
533  /// @{
534 
535  /// Cast \c addr to the address corresponding to the type \c ancestor.
536  ///
537  /// (This is a dangerous function; there's probably a much better way to
538  /// do whatever it is you're trying to do.)
539  ///
540  /// With multiple inheritance, you can't do a reinterpret_cast back to an
541  /// ancestor type; this function figures out how to cast addr to the
542  /// address corresponding to the type ancestor if in fact ancestor is
543  /// really an ancestor of the type corresponding to \c *this.
544  ///
545  /// In order for this function to work correctly, \p addr must have been a
546  /// pointer of type corresponding to \c *this, which was cast to void; and
547  /// of course the type of \p ancestor must be an ancestor of the type of
548  /// \c *this.
549  ///
550  /// \warning You are warned: this is deadly dangerous stuff, and you
551  /// shouldn't be doing it!
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 
560  /// Cast \c addr, which pointed to the ancestor type \p ancestor, to the
561  /// type of \c *this.
562  ///
563  /// This function is the opposite of \c CastToAncestor(); the assumption
564  /// is that \c addr was a pointer to the type corresponding to \c
565  /// ancestor, and was then reinterpret-cast to \c void*, but now you wish
566  /// to turn cast the pointer to the type corresponding to \c *this. While
567  /// the fact that \p addr was a pointer of type \c ancestor is taken on
568  /// faith, a runtime check is performed to verify that the underlying
569  /// object pointed to by \p addr is of type \c *this (or derived from \c
570  /// *this).
571  ///
572  /// \warning Again, this is dangerous territory, and there's probably
573  /// something much better than using this function.
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 
582  /// @}
583 
584  /// \name Instantiation / Manufacturing
585  /// @{
586 
587  /// Sets the factory object for this type. A type's factory typically
588  /// has methods to instantiate the type given various arguments and must
589  /// inherit from \c FactoryBase. The factory cannot be changed once set.
590  TF_API
591  void SetFactory(std::unique_ptr<FactoryBase> factory) const;
592 
593  /// Sets the factory object for this type. A type's factory typically
594  /// has methods to instantiate the type given various arguments and must
595  /// inherit from \c FactoryBase. The factory cannot be changed once set.
596  template <class T>
597  void SetFactory(std::unique_ptr<T>& factory) const {
598  SetFactory(std::unique_ptr<FactoryBase>(std::move(factory)));
599  }
600 
601  /// Sets the factory object for this type to be a \c T. The factory
602  /// cannot be changed once set.
603  template <class T>
604  void SetFactory() const { SetFactory(std::unique_ptr<FactoryBase>(new T)); }
605 
606  /// Sets the factory object for this type. A type's factory typically
607  /// has methods to instantiate the type given various arguments and must
608  /// inherit from \c FactoryBase. The factory cannot be changed once set.
609  const TfType& Factory(std::unique_ptr<FactoryBase> factory) const {
610  SetFactory(std::move(factory));
611  return *this;
612  }
613 
614  /// Sets the factory object for this type. A type's factory typically
615  /// has methods to instantiate the type given various arguments and must
616  /// inherit from \c FactoryBase. The factory cannot be changed once set.
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 
624  /// Sets the factory object for this type to be a \c T. The factory
625  /// cannot be changed once set.
626  template <class T>
627  const TfType& Factory() const {
628  SetFactory(std::unique_ptr<FactoryBase>(new T));
629  return *this;
630  }
631 
632  /// Returns the factory object for this type as a \c T*, or \c NULL if
633  /// there is no factory or the factory is not or is not derived from \c T.
634  /// Clients can check if a factory is set using
635  /// \c GetFactory<TfType::FactoryBase>().
636  template <class T>
637  T *GetFactory() const { return dynamic_cast<T*>(_GetFactory()); }
638 
639  /// @}
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<
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<
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<
672  _FindImpl(T const *rawPtr) {
673  return Find(typeid(T));
674  }
675 
676 #else
677  template <class T>
678  static typename std::enable_if<
680  _FindImpl(T const *rawPtr) {
681  return Find(typeid(*rawPtr));
682  }
683 
684  template <class T>
685  static typename std::enable_if<
687  _FindImpl(T const *rawPtr) {
688  return Find(typeid(T));
689  }
690 
691 #endif // PXR_PYTHON_SUPPORT_ENABLED
692 
693  // Callers must hold at least a read lock on the type registry's mutex.
694  bool _IsAImplNoLock(TfType queryType) const;
695 
696  typedef void *(*_CastFunction)(void *, bool derivedToBase);
697 
698  template <typename TypeVector>
699  friend struct Tf_AddBases;
700  friend struct _TypeInfo;
701  friend class Tf_TypeRegistry;
702 
703  // TfHash support.
704  template <class HashState>
705  friend void
706  TfHashAppend(HashState &h, TfType const &type) {
707  h.Append(type._info);
708  }
709 
710  // Construct a TfType with the given _TypeInfo.
711  explicit TfType(_TypeInfo *info) : _info(info) {}
712 
713  // Add base type(s), and link as a derived type of the bases. Callers
714  // must hold a registry write lock.
715  void _AddBasesNoLock(
716  const std::vector<TfType> &bases,
717  std::vector<std::string> *errorToEmit) const;
718 
719  // Add the given function for casting to/from the given baseType.
720  TF_API
721  void _AddCppCastFunc(
722  const std::type_info &baseTypeInfo, _CastFunction) const;
723 
724  // Define this TfType to have the given type_info.
725  TF_API
726  void _DefineCppType(const std::type_info &,
727  size_t sizeofType,
728  bool isPodType,
729  bool isEnumType) const;
730 
731  // Execute the definition callback if one exists.
732  void _ExecuteDefinitionCallback() const;
733 
734  // Retrieve the \c TfType corresponding to an obj with the
735  // given \c type_info.
736  TF_API
737  static TfType const& _FindByTypeid(const std::type_info &);
738 
739  // Pointer to internal type representation.
740  // Our only data member.
741  _TypeInfo *_info;
742 };
743 
744 /// Output a TfType, using the machine-independent type name.
745 /// \ingroup group_tf_DebuggingOutput
746 TF_API std::ostream& operator<<(std::ostream& out, const TfType &t);
747 
748 /// Metafunction returning sizeof(T) for a type T (or 0 if T is a void type).
749 template <typename T>
750 struct TfSizeofType {
751  static const size_t value = sizeof(T);
752 };
753 template <>
755  static const size_t value = 0;
756 };
757 template <>
759  static const size_t value = 0;
760 };
761 template <>
762 struct TfSizeofType<volatile void> {
763  static const size_t value = 0;
764 };
765 template <>
766 struct TfSizeofType<const volatile void> {
767  static const size_t value = 0;
768 };
769 
771 
772 // Implementation details are put in this header.
773 #include "pxr/base/tf/type_Impl.h"
774 
775 #endif // PXR_BASE_TF_TYPE_H
bool operator<=(const TfType &t) const
Definition: type.h:138
bool IsUnknown() const
Definition: type.h:388
static TF_API TfType const & GetUnknownType()
#define TF_API
Definition: api.h:40
void
Definition: png.h:1083
bool IsA() const
Definition: type.h:380
static TfType const & FindDerivedByName(const std::string &name)
Definition: type.h:235
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
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:83
static TfType const & Find()
Definition: type.h:153
static TfType const & FindByTypeid(const std::type_info &t)
Definition: type.h:193
const TfType & Factory(std::unique_ptr< T > &factory) const
Definition: type.h:618
**But if you need a result
Definition: thread.h:613
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:400
TF_API TfType()
static TfType const & Find(const std::type_info &t)
Definition: type.h:186
Base class of all factory types.
Definition: type.h:73
const void * CastToAncestor(TfType ancestor, const void *addr) const
Definition: type.h:555
friend void TfHashAppend(HashState &h, TfType const &type)
Definition: type.h:706
virtual TF_API ~FactoryBase()
static TfType const & Declare()
Definition: type_Impl.h:78
bool operator!=(const TfType &t) const
Definition: type.h:133
const TfType & Alias(TfType base, const std::string &name) const
Definition: type.h:524
const TfType & Factory() const
Definition: type.h:627
bool operator>(const TfType &t) const
Definition: type.h:137
static TfType const & Define()
Definition: type_Impl.h:90
bool IsRoot() const
Definition: type.h:404
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:701
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:750
void SetFactory(std::unique_ptr< T > &factory) const
Definition: type.h:597
LegacyFlags
Definition: type.h:80
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:132
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
friend struct _TypeInfo
Definition: type.h:700
Not abstract.
Definition: type.h:82
static TfType const & Find(const T &obj)
Definition: type.h:173
TF_API bool IsEnumType() const
GLdouble t
Definition: glad.h:2397
bool operator>=(const TfType &t) const
Definition: type.h:139
TF_API TfType const & GetCanonicalType() const
Return the canonical type for this type.
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
TF_API size_t GetSizeof() const
TF_API void GetAllAncestorTypes(std::vector< TfType > *result) const
void(*)(TfType) DefinitionCallback
Callback invoked when a declared type needs to be defined.
Definition: type.h:70
TF_API const std::string & GetTypeName() const
TfType::_TypeInfo *TfType::* UnspecifiedBoolType
Definition: type.h:390
TF_API void * CastFromAncestor(TfType ancestor, void *addr) const
auto ptr(T p) -> const void *
Definition: format.h:2448
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
const TfType & Factory(std::unique_ptr< FactoryBase > factory) const
Definition: type.h:609
static void AddAlias(const std::string &name)
Definition: type.h:505
Definition: type.h:64
const void * CastFromAncestor(TfType ancestor, const void *addr) const
Definition: type.h:577
TF_API const std::type_info & GetTypeid() const
Definition: core.h:1131
T * GetFactory() const
Definition: type.h:637
TF_API std::ostream & operator<<(std::ostream &out, const TfType &t)
#define const
Definition: zconf.h:214
Abstract (unmanufacturable and unclonable)
Definition: type.h:81
TF_API std::vector< TfType > GetDirectlyDerivedTypes() const
type
Definition: core.h:1059
static TF_API TfType const & GetRoot()
bool operator<(const TfType &t) const
Comparison operator.
Definition: type.h:136
void SetFactory() const
Definition: type.h:604