enum.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_ENUM_H
25 #define PXR_BASE_TF_ENUM_H
26 
29 
30 #include "pxr/pxr.h"
31 #include "pxr/base/arch/defines.h"
32 #include "pxr/base/arch/demangle.h"
33 #include "pxr/base/tf/hash.h"
35 #include "pxr/base/tf/preprocessorUtilsLite.h"
37 #include "pxr/base/tf/api.h"
38 
39 #include <boost/operators.hpp>
40 #include <boost/preprocessor/punctuation/comma_if.hpp>
41 
42 #include <iosfwd>
43 #include <string>
44 #include <typeinfo>
45 #include <type_traits>
46 #include <vector>
47 
48 PXR_NAMESPACE_OPEN_SCOPE
49 
139 class TfEnum : boost::totally_ordered<TfEnum>
140 {
141 public:
144  : _typeInfo(&typeid(int)), _value(0)
145  {
146  }
147 
149  template <class T>
150  TfEnum(T value,
151  std::enable_if_t<std::is_enum<T>::value> * = 0)
152  : _typeInfo(&typeid(T)), _value(int(value))
153  {
154  }
155 
161  TfEnum(const std::type_info& ti, int value)
162  : _typeInfo(&ti), _value(value)
163  {
164  }
165 
167  bool operator==(const TfEnum& t) const {
168  return t._value == _value &&
169  TfSafeTypeCompare(*t._typeInfo, *_typeInfo);
170  }
171 
176  bool operator<(const TfEnum& t) const {
177  return _typeInfo->before(*t._typeInfo) ||
178  (!t._typeInfo->before(*_typeInfo) && _value < t._value);
179  }
180 
182  template <class T>
183  std::enable_if_t<std::is_enum<T>::value, bool>
184  operator==(T value) const {
185  return int(value) == _value && IsA<T>();
186  }
187 
189  template <class T>
190  std::enable_if_t<std::is_enum<T>::value, bool>
191  operator!=(T value) const {
192  return int(value) != _value || !IsA<T>();
193  }
194 
196  template <class T>
197  friend std::enable_if_t<std::is_enum<T>::value, bool>
198  operator==(T val, TfEnum const &e) {
199  return e == val;
200  }
201 
203  template <class T>
204  friend std::enable_if_t<std::is_enum<T>::value, bool>
205  operator!=(T val, TfEnum const &e) {
206  return e != val;
207  }
208 
210  template <class T>
211  bool IsA() const {
212  return TfSafeTypeCompare(*_typeInfo, typeid(T));
213  }
214 
217  bool IsA(const std::type_info& t) const {
218  return TfSafeTypeCompare(*_typeInfo, t);
219  }
220 
222  const std::type_info& GetType() const {
223  return *_typeInfo;
224  }
225 
227  const int& GetValueAsInt() const {
228  return _value;
229  }
230 
242  template <typename T>
243  T GetValue() const {
244  if (!IsA<T>())
245  _FatalGetValueError(typeid(T));
246 
247  return T(_value);
248  }
249 
251  template <typename T,
252  typename = typename std::enable_if<
253  std::is_integral<T>::value ||
254  std::is_enum<T>::value>::type
255  >
256  operator T() const
257  {
258  return T(_value);
259  }
260 
268 
272  TF_API static std::string GetName(TfEnum val);
273 
279  TF_API static std::string GetFullName(TfEnum val);
280 
285  TF_API static std::string GetDisplayName(TfEnum val);
286 
295  static std::vector<std::string> GetAllNames(TfEnum val) {
296  return GetAllNames(val.GetType());
297  }
298 
300  TF_API static std::vector<std::string> GetAllNames(const std::type_info &ti);
301 
310  template <class T>
311  static std::vector<std::string> GetAllNames() {
312  return GetAllNames(typeid(T));
313  }
314 
320  TF_API
321  static const std::type_info *GetTypeFromName(const std::string& typeName);
322 
328  template <class T>
329  static T GetValueFromName(const std::string &name, bool *foundIt = NULL) {
330  TfEnum e = GetValueFromName(typeid(T), name, foundIt);
331  return T(e.GetValueAsInt());
332  }
333 
337  TF_API
338  static TfEnum GetValueFromName(const std::type_info& ti,
339  const std::string &name,
340  bool *foundIt = NULL);
341 
351  TF_API
352  static TfEnum GetValueFromFullName(const std::string &fullname,
353  bool *foundIt = NULL);
354 
359  TF_API
360  static bool IsKnownEnumType(const std::string& typeName);
361 
363 
369  TF_API
370  static void _AddName(TfEnum val, const std::string &valName,
371  const std::string &displayName="");
372 
375  static void AddName(TfEnum val, const std::string &valName,
376  const std::string &displayName="")
377  {
378  _AddName(val, valName, displayName);
379  }
380 
381  template <typename T>
382  static TfEnum IntegralEnum(T value) {
383  TfEnum e;
384  e._typeInfo = &typeid(T);
385  e._value = int(value);
386  return e;
387  }
388 
389 private:
390  // Internal constructor for int values.
391  explicit TfEnum(int value)
392  : _typeInfo(&typeid(int)), _value(value)
393  {
394  }
395 
396  // Internal constructor for size_t values.
397  explicit TfEnum(size_t value)
398  : _typeInfo(&typeid(size_t)), _value(static_cast<int>(value))
399  {
400  }
401 
402  TF_API
403  void _FatalGetValueError(std::type_info const& typeInfo) const;
404 
405  const std::type_info* _typeInfo;
406  int _value;
407 };
408 
409 // TfHash support. Make the enum parameter be a deduced template type but
410 // enable the overload only for TfEnum. This disables implicit conversion from
411 // ordinary enum types to TfEnum.
412 template <class HashState, class Enum>
413 std::enable_if_t<std::is_same<Enum, TfEnum>::value>
414 TfHashAppend(HashState &h, Enum const &e)
415 {
416  h.Append(TfHashAsCStr(e.GetType().name()));
417  h.Append(e.GetValueAsInt());
418 }
419 
422 TF_API std::ostream& operator<<(std::ostream& out, const TfEnum & e);
423 
449 #define TF_ADD_ENUM_NAME(VAL, ...) \
450  TfEnum::_AddName(VAL, \
451  TF_PP_STRINGIZE(VAL) \
452  BOOST_PP_COMMA_IF(TF_NUM_ARGS(__VA_ARGS__)) \
453  __VA_ARGS__)
454 
455 PXR_NAMESPACE_CLOSE_SCOPE
456 
457 #endif // PXR_BASE_TF_ENUM_H
static std::vector< std::string > GetAllNames(TfEnum val)
Returns a vector of all the names associated with an enum type.
Definition: enum.h:295
Safely compare C++ RTTI type structures.
friend std::enable_if_t< std::is_enum< T >::value, bool > operator!=(T val, TfEnum const &e)
Compare a literal enum value val of enum type T with TfEnum e.
Definition: enum.h:205
static TF_API bool IsKnownEnumType(const std::string &typeName)
Returns true if typeName is a known enum type.
static std::vector< std::string > GetAllNames()
Returns a vector of all the names associated with an enum type.
Definition: enum.h:311
bool IsA(const std::type_info &t) const
True if *this has been assigned any enumerated value of type T with typeid(T)==t.
Definition: enum.h:217
static TF_API const std::type_info * GetTypeFromName(const std::string &typeName)
Returns the typeid for a given enum type name.
An enum class that records both enum type and enum value.
Definition: enum.h:139
static void AddName(TfEnum val, const std::string &valName, const std::string &displayName="")
Associates a name with an enumerated value.
Definition: enum.h:375
Demangle C++ typenames generated by the typeid() facility.
static TF_API std::string GetDisplayName(TfEnum val)
Returns the display name for an enumerated value.
TfEnum(const std::type_info &ti, int value)
Initializes value to integral value value with enum type ti.
Definition: enum.h:161
static TF_API std::string GetName(TfEnum val)
Returns the name associated with an enumerated value.
static TF_API TfEnum GetValueFromFullName(const std::string &fullname, bool *foundIt=NULL)
Returns the enumerated value for a fully-qualified name.
bool IsA() const
True if *this has been assigned any enumerated value of type T.
Definition: enum.h:211
const std::type_info & GetType() const
Returns the type of the enum value, as an std::type_info.
Definition: enum.h:222
TfEnum(T value, std::enable_if_t< std::is_enum< T >::value > *=0)
Initializes value to enum variable value of enum type T.
Definition: enum.h:150
static TF_API std::string GetFullName(TfEnum val)
Returns the fully-qualified name for an enumerated value.
static T GetValueFromName(const std::string &name, bool *foundIt=NULL)
Returns the enumerated value for a name.
Definition: enum.h:329
friend std::enable_if_t< std::is_enum< T >::value, bool > operator==(T val, TfEnum const &e)
Compare a literal enum value val of enum type T with TfEnum e.
Definition: enum.h:198
TfEnum()
Default constructor assigns integer value zero.
Definition: enum.h:143
std::enable_if_t< std::is_enum< T >::value, bool > operator!=(T value) const
False if *this has been assigned with value.
Definition: enum.h:191
TF_API std::ostream & operator<<(std::ostream &out, const TfEnum &e)
Output a TfEnum value.
static TF_API void _AddName(TfEnum val, const std::string &valName, const std::string &displayName="")
Associates a name with an enumerated value.
const int & GetValueAsInt() const
Returns the integral value of the enum value.
Definition: enum.h:227
bool operator==(const TfEnum &t) const
True if *this and t have both the same type and value.
Definition: enum.h:167
bool operator<(const TfEnum &t) const
Less than comparison.
Definition: enum.h:176
TfCStrHashWrapper TfHashAsCStr(char const *cstr)
Indicate that a char pointer is intended to be hashed as a C-style null terminated string.
Definition: hash.h:140
T GetValue() const
Returns the enum value for the enum type T.
Definition: enum.h:243
std::enable_if_t< std::is_enum< T >::value, bool > operator==(T value) const
True if *this has been assigned with value.
Definition: enum.h:184
bool TfSafeTypeCompare(const std::type_info &t1, const std::type_info &t2)
Safely compare std::type_info structures.