HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HOM_EnumValue.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * COMMENTS:
7  * An enum value object is an immutable object inside a module containing
8  * other enum values.
9  */
10 
11 #ifndef __HOM_EnumValue_h__
12 #define __HOM_EnumValue_h__
13 
14 #include "HOM_API.h"
15 #include "HOM_Defines.h"
16 #include "HOM_PtrOrNull.h"
17 #include <SYS/SYS_Math.h>
18 #include <string>
19 #include <typeinfo>
20 
21 SWIGOUT(%rename(EnumValue) HOM_EnumValue;)
22 
24 {
25 public:
26  SWIGOUT(%ignore HOM_EnumValue;)
27  SWIGOUT(%ignore ~HOM_EnumValue;)
28 
30  {
31  // This only exists to keep std::map<> happy.
32  myEnumClass = &typeid(void);
33  myRepr = "";
34  myName = "";
35  myId = 0;
36  }
37 
38  // The id is a unique id for this enumeration value with its set of values.
39  // We use the type info to quickly compare two enum values to make sure
40  // they're from the same set of values. We use repr for the __repr__
41  // method (unfortunately, type_info.name() varies between platforms,
42  // contains mangling information, and contains the "HOM_" prefix). We
43  // assume that repr is a string constant (we don't store a deep copy).
44  // We similarly use name to hold the name of this particular enum value.
45  HOM_EnumValue(const std::type_info& enum_class, const char *repr,
46  const char *name, int id)
47  : myEnumClass(&enum_class), myRepr(repr), myName(name), myId(id)
48  {}
49 
50  // Swig doesn't properly let you ignore only one overloaded operator==.
51  // So, the methods wrapped by swig for Python are named __eq__.
53  { return value.myPointer && *this == *value.myPointer; }
54 
56  { return !__eq__(value); }
57 
59  { return myRepr; }
60 
61  int __hash__()
62  { return (int)SYSmultiplicative_inthash(myId); }
63 
64  std::string name() const
65  { return myName; }
66 
67  // These methods are used by the implementation and are not wrapped by
68  // swig.
69  SWIGOUT(%ignore operator==;)
70  bool operator==(const HOM_EnumValue &value) const
71  { return *myEnumClass == *value.myEnumClass && myId == value.myId; }
72 
73  SWIGOUT(%ignore operator!=;)
74  bool operator!=(const HOM_EnumValue &value) const
75  { return *myEnumClass != *value.myEnumClass || myId != value.myId; }
76 
77  SWIGOUT(%ignore enumClass;)
78  const std::type_info &enumClass() const
79  { return *myEnumClass; }
80 
81  SWIGOUT(%ignore id;)
82  int id() const
83  { return myId; }
84 
85  bool operator<(const HOM_EnumValue &value) const
86  {
87  int v = strcmp(myName, value.myName);
88  return v < 0 || ( v == 0 && myId < value.myId );
89  }
90 
91  SWIGOUT(%ignore operator=;)
92  HOM_EnumValue &operator=(const HOM_EnumValue &that)
93  {
94  if (&that != this)
95  {
96  myEnumClass = that.myEnumClass;
97  myRepr = that.myRepr;
98  myName = that.myName;
99  myId = that.myId;
100  }
101  return *this;
102  }
103 
104 
105 private:
106  const std::type_info *myEnumClass;
107  const char *myRepr;
108  const char *myName;
109  int myId;
110 };
111 
112 
113 // Use the HOM_DECLARE_ENUM_MODULE macro to declare an enumeration module
114 // class in the header file.
115 // HOM_DEFINE_ENUM_MODULE(enum_module, num_values, values_list)
116 // - enum_module is the name of the module (without the HOM_) prefix.
117 // - values_list is a comma-separated list of the enumeration values
118 // (set this in a define)
119 // - num_values is the number of enumeration values
120 // Use HOM_DEFINE_ENUM_MODULE to define its contents in the .C file. It
121 // takes the same parameters.
122 
123 // This pair of macros is used to build the class definition for the
124 // enumeration module.
125 #define HOM_DECLARE_ENUM_MODULE_START(enum_module) \
126  SWIGOUT(%nodefaultctor HOM_ ## enum_module;) \
127  SWIGOUT(%rename(enum_module) HOM_ ## enum_module;) \
128  class HOM_API HOM_ ## enum_module \
129  { \
130  public:
131 #define HOM_DECLARE_ENUM_MODULE_END \
132  };
133 
134 #ifndef SWIG
135 #include <hboost/preprocessor/cat.hpp>
136 #include <hboost/preprocessor/arithmetic/dec.hpp>
137 #include <hboost/preprocessor/tuple/to_seq.hpp>
138 #include <hboost/preprocessor/tuple/rem.hpp>
139 #include <hboost/preprocessor/seq/transform.hpp>
140 #include <hboost/preprocessor/seq/for_each.hpp>
141 #include <hboost/preprocessor/stringize.hpp>
142 
143 // For an enum value, we declare a static const HOM_EnumValue member.
144 // (It will be initialized with the HOM_DEFINE_ENUM_* macros). For
145 // each "Foo" enum value we also declare a "Foo_Id" constant. This constant
146 // is used so we can use enum values in switch statements in C++. It doesn't
147 // need a definition because it's a static const int that's initialized
148 // inside the class declaration.
149 //
150 // r will be the iteration value (plus 1, for some reason). We use it
151 // to give each enumeration value a unique id number.
152 #define HOM_DECLARE_ENUM_VALUE(r, unused_data, elem) \
153  static HOM_EnumValue elem; \
154  static const int HBOOST_PP_CAT(elem, _Id) = HBOOST_PP_DEC(r);
155 
156 // Call HOM_DECLARE_ENUM_VALUE for each enumeration value in the sequence.
157 // The whole thing is wrapped in the class definition.
158 #define HOM_DECLARE_ENUM_MODULE_FROM_SEQ(enum_module, values_seq) \
159  HOM_DECLARE_ENUM_MODULE_START(enum_module) \
160  HBOOST_PP_SEQ_FOR_EACH(HOM_DECLARE_ENUM_VALUE, _, values_seq) \
161  HOM_DECLARE_ENUM_MODULE_END
162 
163 // We wrap the comma-separated tuples of values in () to build what the boost
164 // preprocessor calls a tuple. We then convert that to a boost sequence
165 // and call the above macro. This macro is more convenient to use than the
166 // one above, though you might need to use the one above if you hit boost's
167 // maximum tuple size.
168 #define HOM_DECLARE_ENUM_MODULE(enum_module, num_values, values_tuple) \
169  HOM_DECLARE_ENUM_MODULE_FROM_SEQ(enum_module, \
170  HBOOST_PP_TUPLE_TO_SEQ(num_values, (values_tuple)))
171 
172 
173 // For each enum value we provide the definition of the static member variable,
174 // passing the enum class's type_info, the enum value's repr string, and
175 // the enum value's id into the constructor.
176 #define HOM_DEFINE_ENUM_VALUE(r, enum_module, elem) \
177  HOM_EnumValue HBOOST_PP_CAT(HOM_, enum_module)::elem \
178  (typeid(HBOOST_PP_CAT(HOM_, enum_module)), \
179  HBOOST_PP_STRINGIZE(enum_module) "." HBOOST_PP_STRINGIZE(elem), \
180  HBOOST_PP_STRINGIZE(elem), \
181  HBOOST_PP_DEC(r));
182 
183 // The .C file contains all the definitions for the static member variables.
184 #define HOM_DEFINE_ENUM_MODULE_FROM_SEQ(enum_module, values_seq) \
185  HBOOST_PP_SEQ_FOR_EACH(HOM_DEFINE_ENUM_VALUE, enum_module, values_seq)
186 
187 #define HOM_DEFINE_ENUM_MODULE(enum_module, num_values, values_tuple) \
188  HOM_DEFINE_ENUM_MODULE_FROM_SEQ(enum_module, \
189  HBOOST_PP_TUPLE_TO_SEQ(num_values, (values_tuple)))
190 
191 // Use HOM_DECLARE_ENUM_VALUE2 to declare an enum with a specific value.
192 // enum_module: enum module name (ignored)
193 // enum_elem: enum element name
194 // ienum_elem: internal enum element (ignored)
195 // ienum_elem_name: internal enum element name (ignored)
196 // enum_value: enum value
197 // E.g. usage:
198 // HOM_DECLARE_ENUM_MODULE_START(myEnumModule)
199 // HOM_DECLARE_ENUM_VALUE2(myEnumModule,myValue,0)
200 // HOM_DECLARE_ENUM_MODULE_END
201 #define HOM_DECLARE_ENUM_VALUE2(enum_module, enum_elem, ienum_elem, ienum_elem_name, enum_value) \
202  static HOM_EnumValue enum_elem; \
203  static const int HBOOST_PP_CAT(enum_elem,_Id) = enum_value;
204 
205 // Use HOM_DEFINE_ENUM_VALUE2 to define an enum with a specific id number.
206 // enum_module: enum module name
207 // enum_elem: enum element
208 // ienum_elem: internal enum element name (ignored)
209 // ienum_elem_name: internal element name
210 // enum_value: enum value
211 #define HOM_DEFINE_ENUM_VALUE2(enum_module, enum_elem, ienum_elem, ienum_elem_name, enum_value) \
212  HOM_EnumValue HBOOST_PP_CAT(HOM_,enum_module)::enum_elem \
213  ((typeid(HBOOST_PP_CAT(HOM_,enum_module))), \
214  HBOOST_PP_STRINGIZE(enum_module) "." HBOOST_PP_STRINGIZE(enum_elem), \
215  HBOOST_PP_STRINGIZE(enum_elem), \
216  enum_value);
217 
218 #else // SWIG
219 
220 // Swig can't handle boost's proprocessor macros, so we create a simple
221 // class for swig to wrap that just contains static HOM_EnumValue members.
222 // Because values_tuple is a comma-separated list, we don't need any boost
223 // preprocessor stuff.
224 #define HOM_DECLARE_ENUM_MODULE(enum_module, num_values, values_tuple) \
225  HOM_DECLARE_ENUM_MODULE_START(enum_module) \
226  static const HOM_EnumValue values_tuple; \
227  HOM_DECLARE_ENUM_MODULE_END
228 
229 #define HOM_DECLARE_ENUM_VALUE2(enum_module, enum_elem, ienum_elem, ienum_elem_name, enum_value) \
230  static const HOM_EnumValue enum_elem;
231 
232 #endif // SWIG
233 
234 #endif
bool operator<(const HOM_EnumValue &value) const
Definition: HOM_EnumValue.h:85
const GLdouble * v
Definition: glcorearb.h:836
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
#define SWIGOUT(x)
Definition: HOM_Defines.h:24
bool __eq__(HOM_PtrOrNull< HOM_EnumValue > value)
Definition: HOM_EnumValue.h:52
#define HOM_API
Definition: HOM_API.h:13
HOM_EnumValue(const std::type_info &enum_class, const char *repr, const char *name, int id)
Definition: HOM_EnumValue.h:45
bool __ne__(HOM_PtrOrNull< HOM_EnumValue > value)
Definition: HOM_EnumValue.h:55
GLuint const GLchar * name
Definition: glcorearb.h:785
std::string name() const
Definition: HOM_EnumValue.h:64
GLsizei const GLfloat * value
Definition: glcorearb.h:823
const std::type_info & enumClass() const
Definition: HOM_EnumValue.h:78
std::string __repr__() const
Definition: HOM_EnumValue.h:58