All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
type_Impl.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_IMPL_H
25 #define PXR_BASE_TF_TYPE_IMPL_H
26 
27 #include "pxr/base/tf/mallocTag.h"
28 
29 #include <initializer_list>
30 
31 PXR_NAMESPACE_OPEN_SCOPE
32 
33 template <class DERIVED, class BASE>
34 inline void*
35 Tf_CastToParent(void* addr, bool derivedToBase);
36 
37 // Declare and register casts for all the C++ bases in the given TypeVector.
38 template <typename TypeVector>
39 struct Tf_AddBases;
40 
41 template <typename... Bases>
42 struct Tf_AddBases<TfType::Bases<Bases...>>
43 {
44  // Declare types in Bases as TfTypes and accumulate them into a runtime
45  // vector.
46  static std::vector<TfType>
47  Declare()
48  {
49  return std::vector<TfType> {
51  TfType::GetCanonicalTypeName( typeid(Bases) ))...
52  };
53  }
54 
55  // Register casts to and from Derived and each base type in Bases.
56  template <typename Derived>
57  static void
58  RegisterCasts(TfType const* type)
59  {
60  struct Cast
61  {
62  const std::type_info *typeInfo;
63  TfType::_CastFunction func;
64  };
65 
66  const std::initializer_list<Cast> baseCasts = {
67  { &typeid(Bases), &Tf_CastToParent<Derived, Bases> }...
68  };
69 
70  for (const Cast &cast : baseCasts) {
71  type->_AddCppCastFunc(*cast.typeInfo, cast.func);
72  }
73  }
74 };
75 
76 template <class T, class BaseTypes>
77 TfType const &
79 {
80  // Declare each of the base types.
81  std::vector<TfType> baseTfTypes = Tf_AddBases<BaseTypes>::Declare();
82  // Declare our type T.
83  const std::type_info &typeInfo = typeid(T);
84  const std::string typeName = TfType::GetCanonicalTypeName(typeInfo);
85  return TfType::Declare(typeName, baseTfTypes);
86 }
87 
88 template <typename T, typename BaseTypes>
89 TfType const&
91 {
92  TfAutoMallocTag2 tag2("Tf", "TfType::Define");
93 
94  // Declare each of the base types.
95  std::vector<TfType> baseTfTypes = Tf_AddBases<BaseTypes>::Declare();
96 
97  // Declare our type T.
98  const std::type_info &typeInfo = typeid(T);
99  const std::string typeName = TfType::GetCanonicalTypeName(typeInfo);
100  TfType const& newType = TfType::Declare(typeName, baseTfTypes);
101 
102  // Record traits information about T.
103  const bool isPodType = std::is_pod<T>::value;
104  const bool isEnumType = std::is_enum<T>::value;
105  const size_t sizeofType = TfSizeofType<T>::value;
106 
107  newType._DefineCppType(typeInfo, sizeofType, isPodType, isEnumType);
108  Tf_AddBases<BaseTypes>::template RegisterCasts<T>(&newType);
109 
110  return newType;
111 }
112 
113 template <typename T>
114 TfType const&
116 {
117  return Define<T, Bases<> >();
118 }
119 
120 // Helper function to implement up/down casts between TfType types.
121 // This was taken from the previous TfType implementation.
122 template <class DERIVED, class BASE>
123 inline void*
124 Tf_CastToParent(void* addr, bool derivedToBase)
125 {
126  if (derivedToBase) {
127  // Upcast -- can be done implicitly.
128  DERIVED* derived = reinterpret_cast<DERIVED*>(addr);
129  BASE* base = derived;
130  return base;
131  } else {
132  // Downcast -- use static_cast.
133  BASE* base = reinterpret_cast<BASE*>(addr);
134  DERIVED* derived = static_cast<DERIVED*>(base);
135  return derived;
136  }
137 }
138 
139 PXR_NAMESPACE_CLOSE_SCOPE
140 
141 #endif // PXR_BASE_TF_TYPE_IMPL_H
static TfType const & Declare()
Declares a TfType with the given C++ type T and C++ base types Bases.
Definition: type_Impl.h:78
Scoped (i.e.
Definition: mallocTag.h:349
static TF_API std::string GetCanonicalTypeName(const std::type_info &)
Return the canonical typeName used for a given std::type_info.
Metafunction returning sizeof(T) for a type T (or 0 if T is a void type).
Definition: type.h:748
static TfType const & Define()
Define a TfType with the given C++ type T and C++ base types B.
Definition: type_Impl.h:90
TfType represents a dynamic runtime type.
Definition: type.h:64