All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 TF_ENUM_H
25 #define 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/preprocessorUtils.h"
34 #include "pxr/base/tf/safeTypeCompare.h"
35 #include "pxr/base/tf/api.h"
36 
37 #include <boost/operators.hpp>
38 #include <boost/preprocessor/punctuation/comma_if.hpp>
39 #include <boost/preprocessor/stringize.hpp>
40 #include <boost/type_traits/is_enum.hpp>
41 #include <boost/utility/enable_if.hpp>
42 
43 #include <iosfwd>
44 #include <string>
45 #include <typeinfo>
46 #include <type_traits>
47 #include <vector>
48 
49 PXR_NAMESPACE_OPEN_SCOPE
50 
140 class TfEnum : boost::totally_ordered<TfEnum>
141 {
142 public:
145  : _typeInfo(&typeid(int)), _value(0)
146  {
147  }
148 
150  template <class T>
151  TfEnum(T value,
152  typename boost::enable_if<boost::is_enum<T> >::type * = 0)
153  : _typeInfo(&typeid(T)), _value(int(value))
154  {
155  }
156 
162  TfEnum(const std::type_info& ti, int value)
163  : _typeInfo(&ti), _value(value)
164  {
165  }
166 
168  bool operator==(const TfEnum& t) const {
169  return t._value == _value &&
170  TfSafeTypeCompare(*t._typeInfo, *_typeInfo);
171  }
172 
177  bool operator<(const TfEnum& t) const {
178  return _typeInfo->before(*t._typeInfo) ||
179  (!t._typeInfo->before(*_typeInfo) && _value < t._value);
180  }
181 
183  template <class T>
184  typename boost::enable_if<boost::is_enum<T>, bool>::type
185  operator==(T value) const {
186  return int(value) == _value && IsA<T>();
187  }
188 
190  template <class T>
191  typename boost::enable_if<boost::is_enum<T>, bool>::type
192  operator!=(T value) const {
193  return int(value) != _value || !IsA<T>();
194  }
195 
197  template <class T>
198  friend typename boost::enable_if<boost::is_enum<T>, bool>::type
199  operator==(T val, TfEnum const &e) {
200  return e == val;
201  }
202 
204  template <class T>
205  friend typename boost::enable_if<boost::is_enum<T>, bool>::type
206  operator!=(T val, TfEnum const &e) {
207  return e != val;
208  }
209 
211  template <class T>
212  bool IsA() const {
213  return TfSafeTypeCompare(*_typeInfo, typeid(T));
214  }
215 
218  bool IsA(const std::type_info& t) const {
219  return TfSafeTypeCompare(*_typeInfo, t);
220  }
221 
223  const std::type_info& GetType() const {
224  return *_typeInfo;
225  }
226 
228  const int& GetValueAsInt() const {
229  return _value;
230  }
231 
243  template <typename T>
244  T GetValue() const {
245  if (!IsA<T>())
246  _FatalGetValueError(typeid(T));
247 
248  return T(_value);
249  }
250 
252  template <typename T,
253  typename = typename std::enable_if<
254  std::is_integral<T>::value ||
255  std::is_enum<T>::value>::type
256  >
257  operator T() const
258  {
259  return T(_value);
260  }
261 
269 
273  TF_API static std::string GetName(TfEnum val);
274 
280  TF_API static std::string GetFullName(TfEnum val);
281 
286  TF_API static std::string GetDisplayName(TfEnum val);
287 
296  static std::vector<std::string> GetAllNames(TfEnum val) {
297  return GetAllNames(val.GetType());
298  }
299 
301  TF_API static std::vector<std::string> GetAllNames(const std::type_info &ti);
302 
311  template <class T>
312  static std::vector<std::string> GetAllNames() {
313  return GetAllNames(typeid(T));
314  }
315 
321  TF_API
322  static const std::type_info *GetTypeFromName(const std::string& typeName);
323 
329  template <class T>
330  static T GetValueFromName(const std::string &name, bool *foundIt = NULL) {
331  TfEnum e = GetValueFromName(typeid(T), name, foundIt);
332  return T(e.GetValueAsInt());
333  }
334 
338  TF_API
339  static TfEnum GetValueFromName(const std::type_info& ti,
340  const std::string &name,
341  bool *foundIt = NULL);
342 
352  TF_API
353  static TfEnum GetValueFromFullName(const std::string &fullname,
354  bool *foundIt = NULL);
355 
360  TF_API
361  static bool IsKnownEnumType(const std::string& typeName);
362 
364 
370  TF_API
371  static void _AddName(TfEnum val, const std::string &valName,
372  const std::string &displayName="");
373 
376  static void AddName(TfEnum val, const std::string &valName,
377  const std::string &displayName="")
378  {
379  _AddName(val, valName, displayName);
380  }
381 
382  template <typename T>
383  static TfEnum IntegralEnum(T value) {
384  TfEnum e;
385  e._typeInfo = &typeid(T);
386  e._value = int(value);
387  return e;
388  }
389 
390 private:
391  // Internal constructor for int values.
392  explicit TfEnum(int value)
393  : _typeInfo(&typeid(int)), _value(value)
394  {
395  }
396 
397  // Internal constructor for size_t values.
398  explicit TfEnum(size_t value)
399  : _typeInfo(&typeid(size_t)), _value(static_cast<int>(value))
400  {
401  }
402 
403  TF_API
404  void _FatalGetValueError(std::type_info const& typeInfo) const;
405 
406  const std::type_info* _typeInfo;
407  int _value;
408 };
409 
412 TF_API std::ostream& operator<<(std::ostream& out, const TfEnum & e);
413 
439 #define TF_ADD_ENUM_NAME(VAL, ...) \
440  TfEnum::_AddName(VAL, \
441  BOOST_PP_STRINGIZE(VAL) \
442  BOOST_PP_COMMA_IF(TF_NUM_ARGS(__VA_ARGS__)) \
443  __VA_ARGS__)
444 
445 PXR_NAMESPACE_CLOSE_SCOPE
446 
447 #endif // TF_ENUM_H
friend boost::enable_if< boost::is_enum< T >, bool >::type operator!=(T val, TfEnum const &e)
Compare a literal enum value val of enum type T with TfEnum e.
Definition: enum.h:206
static std::vector< std::string > GetAllNames(TfEnum val)
Returns a vector of all the names associated with an enum type.
Definition: enum.h:296
T GetValue() const
Returns the enum value for the enum type T.
Definition: enum.h:244
const std::type_info & GetType() const
Returns the type of the enum value, as an std::type_info.
Definition: enum.h:223
static TF_API bool IsKnownEnumType(const std::string &typeName)
Returns true if typeName is a known enum type.
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:218
static std::vector< std::string > GetAllNames()
Returns a vector of all the names associated with an enum type.
Definition: enum.h:312
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:140
bool operator<(const TfEnum &t) const
Less than comparison.
Definition: enum.h:177
static void AddName(TfEnum val, const std::string &valName, const std::string &displayName="")
Associates a name with an enumerated value.
Definition: enum.h:376
static TF_API std::string GetDisplayName(TfEnum val)
Returns the display name for an enumerated value.
friend boost::enable_if< boost::is_enum< T >, bool >::type operator==(T val, TfEnum const &e)
Compare a literal enum value val of enum type T with TfEnum e.
Definition: enum.h:199
TfEnum(const std::type_info &ti, int value)
Initializes value to integral value value with enum type ti.
Definition: enum.h:162
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.
boost::enable_if< boost::is_enum< T >, bool >::type operator==(T value) const
True if *this has been assigned with value.
Definition: enum.h:185
static TF_API std::string GetFullName(TfEnum val)
Returns the fully-qualified name for an enumerated value.
boost::enable_if< boost::is_enum< T >, bool >::type operator!=(T value) const
False if *this has been assigned with value.
Definition: enum.h:192
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
static T GetValueFromName(const std::string &name, bool *foundIt=NULL)
Returns the enumerated value for a name.
Definition: enum.h:330
TfEnum()
Default constructor assigns integer value zero.
Definition: enum.h:144
static TF_API void _AddName(TfEnum val, const std::string &valName, const std::string &displayName="")
Associates a name with an enumerated value.
bool IsA() const
True if *this has been assigned any enumerated value of type T.
Definition: enum.h:212
TfEnum(T value, typename boost::enable_if< boost::is_enum< T > >::type *=0)
Initializes value to enum variable value of enum type T.
Definition: enum.h:151
bool operator==(const TfEnum &t) const
True if *this and t have both the same type and value.
Definition: enum.h:168
const int & GetValueAsInt() const
Returns the integral value of the enum value.
Definition: enum.h:228
bool TfSafeTypeCompare(const std::type_info &t1, const std::type_info &t2)
Safely compare std::type_info structures.