Go to the documentation of this file.
30 #ifndef _GG_StrongTypedef_h_
31 #define _GG_StrongTypedef_h_
33 #include <boost/static_assert.hpp>
34 #include <boost/type_traits/is_integral.hpp>
50 inline std::size_t
Value(std::size_t s)
55 #define GG_MEMBER_BOOL_OP_SELF_TYPE(op, rhs_type) \
56 inline bool operator op (rhs_type rhs) const \
57 { return m_value op rhs.m_value; }
59 #define GG_MEMBER_BOOL_OP_OTHER_TYPE(op, rhs_type) \
60 inline bool operator op (rhs_type rhs) const \
61 { return m_value op Value(rhs); }
63 #define GG_MEMBER_NEG_INCR_DECR(this_type) \
64 inline this_type operator-() const \
65 { return this_type(-m_value); } \
66 inline this_type& operator++() \
71 inline this_type& operator--() \
76 inline this_type operator++(int) \
78 this_type retval(m_value); \
82 inline this_type operator--(int) \
84 this_type retval(m_value); \
89 #define GG_MEMBER_ASSIGN_OP_SELF_TYPE(op, rhs_type) \
90 inline rhs_type& operator op (rhs_type rhs) \
92 m_value op rhs.m_value; \
96 #define GG_MEMBER_ASSIGN_OP_OTHER_TYPE_DECL(op, self_type, rhs_type) \
97 inline self_type& operator op ## = (rhs_type rhs)
99 #define GG_MEMBER_ASSIGN_OP_OTHER_TYPE(op, self_type, rhs_type) \
100 GG_MEMBER_ASSIGN_OP_OTHER_TYPE_DECL(op, self_type, rhs_type) \
102 m_value = static_cast<self_type::value_type>( \
103 m_value op Value(rhs) \
108 #define GG_MEMBER_OP_OTHER_TYPE_DECL(op, self_type, rhs_type) \
109 inline self_type& operator op (rhs_type rhs) const
111 #define GG_MEMBER_OP_OTHER_TYPE(op, self_type, rhs_type) \
112 GG_MEMBER_OP_OTHER_TYPE_DECL(op, self_type, rhs_type) \
113 { return self_type(m_value op Value(rhs)); }
115 #define GG_NONMEMBER_OP_SELF_TYPE(op, self_type) \
116 inline self_type operator op (self_type lhs, self_type rhs) \
117 { return lhs op ## = rhs; }
119 #define GG_NONMEMBER_OP_OTHER_TYPE(op, self_type, rhs_type) \
120 inline self_type operator op (self_type lhs, rhs_type rhs) \
121 { return lhs op ## = Value(rhs); }
123 #define GG_MEMBER_SELF_COMPARATORS(self_type) \
124 GG_MEMBER_BOOL_OP_SELF_TYPE(==, self_type); \
125 GG_MEMBER_BOOL_OP_SELF_TYPE(!=, self_type); \
126 GG_MEMBER_BOOL_OP_SELF_TYPE(<, self_type); \
127 GG_MEMBER_BOOL_OP_SELF_TYPE(>, self_type); \
128 GG_MEMBER_BOOL_OP_SELF_TYPE(<=, self_type); \
129 GG_MEMBER_BOOL_OP_SELF_TYPE(>=, self_type);
131 #define GG_MEMBER_OTHER_COMPARATORS(rhs_type) \
132 GG_MEMBER_BOOL_OP_OTHER_TYPE(==, rhs_type); \
133 GG_MEMBER_BOOL_OP_OTHER_TYPE(!=, rhs_type); \
134 GG_MEMBER_BOOL_OP_OTHER_TYPE(<, rhs_type); \
135 GG_MEMBER_BOOL_OP_OTHER_TYPE(>, rhs_type); \
136 GG_MEMBER_BOOL_OP_OTHER_TYPE(<=, rhs_type); \
137 GG_MEMBER_BOOL_OP_OTHER_TYPE(>=, rhs_type);
139 #define GG_MEMBER_ARITH_ASSIGN_OPS_SELF_TYPE(rhs_type) \
140 GG_MEMBER_ASSIGN_OP_SELF_TYPE(+=, rhs_type); \
141 GG_MEMBER_ASSIGN_OP_SELF_TYPE(-=, rhs_type); \
142 GG_MEMBER_ASSIGN_OP_SELF_TYPE(*=, rhs_type); \
143 GG_MEMBER_ASSIGN_OP_SELF_TYPE(/=, rhs_type);
145 #define GG_MEMBER_ARITH_ASSIGN_OPS_OTHER_TYPE(self_type, rhs_type) \
146 GG_MEMBER_ASSIGN_OP_OTHER_TYPE(+, self_type, rhs_type); \
147 GG_MEMBER_ASSIGN_OP_OTHER_TYPE(-, self_type, rhs_type); \
148 GG_MEMBER_ASSIGN_OP_OTHER_TYPE(*, self_type, rhs_type); \
149 GG_MEMBER_ASSIGN_OP_OTHER_TYPE(/, self_type, rhs_type);
151 #define GG_NONMEMBER_ARITH_OPS_SELF_TYPE(self_type) \
152 GG_NONMEMBER_OP_SELF_TYPE(+, self_type); \
153 GG_NONMEMBER_OP_SELF_TYPE(-, self_type); \
154 GG_NONMEMBER_OP_SELF_TYPE(*, self_type); \
155 GG_NONMEMBER_OP_SELF_TYPE(/, self_type);
157 #define GG_NONMEMBER_ARITH_OPS_OTHER_TYPE(self_type, rhs_type) \
158 GG_NONMEMBER_OP_OTHER_TYPE(+, self_type, rhs_type); \
159 GG_NONMEMBER_OP_OTHER_TYPE(-, self_type, rhs_type); \
160 GG_NONMEMBER_OP_OTHER_TYPE(*, self_type, rhs_type); \
161 GG_NONMEMBER_OP_OTHER_TYPE(/, self_type, rhs_type);
163 #define GG_NONMEMBER_REVERSED_BOOL_OP_SET(lhs_type, self_type) \
164 inline bool operator==(lhs_type x, self_type y) \
166 inline bool operator!=(lhs_type x, self_type y) \
168 inline bool operator<(lhs_type x, self_type y) \
169 { return !(y < x || y == x); } \
170 inline bool operator>(lhs_type x, self_type y) \
171 { return !(y > x || y == x); } \
172 inline bool operator<=(lhs_type x, self_type y) \
173 { return !(y < x); } \
174 inline bool operator>=(lhs_type x, self_type y) \
177 #define GG_NONMEMBER_REVERSED_ARITH_OP_SET(lhs_type, self_type) \
178 inline self_type operator+(lhs_type x, self_type y) \
180 inline self_type operator-(lhs_type x, self_type y) \
181 { return -(y -= x); } \
182 inline self_type operator*(lhs_type x, self_type y) \
186 #define GG_STRONG_DOUBLE_TYPEDEF(name, type) \
189 type Value(name x); \
190 double Value(name ## _d x); \
195 struct ConvertibleToBoolDummy {int _;}; \
198 typedef double value_type; \
200 name ## _d() : m_value(0.0) {} \
201 explicit name ## _d(double t) : m_value(t) {} \
203 GG_MEMBER_SELF_COMPARATORS(name ## _d); \
205 GG_MEMBER_OTHER_COMPARATORS(double); \
207 operator int ConvertibleToBoolDummy::* () const \
208 { return m_value ? &ConvertibleToBoolDummy::_ : 0; } \
210 GG_MEMBER_NEG_INCR_DECR(name ## _d); \
212 GG_MEMBER_ARITH_ASSIGN_OPS_SELF_TYPE(name ## _d); \
214 GG_MEMBER_ARITH_ASSIGN_OPS_OTHER_TYPE(name ## _d, double); \
216 GG_MEMBER_ASSIGN_OP_OTHER_TYPE_DECL(+, name ## _d, name); \
217 GG_MEMBER_ASSIGN_OP_OTHER_TYPE_DECL(-, name ## _d, name); \
218 GG_MEMBER_ASSIGN_OP_OTHER_TYPE_DECL(*, name ## _d, name); \
219 GG_MEMBER_ASSIGN_OP_OTHER_TYPE_DECL(/, name ## _d, name); \
224 friend double Value(name ## _d x); \
227 GG_NONMEMBER_ARITH_OPS_SELF_TYPE(name ## _d); \
229 GG_NONMEMBER_ARITH_OPS_OTHER_TYPE(name ## _d, double); \
231 GG_NONMEMBER_REVERSED_BOOL_OP_SET(double, name ## _d); \
233 GG_NONMEMBER_REVERSED_ARITH_OP_SET(double, name ## _d); \
235 inline double Value(name ## _d x) \
236 { return x.m_value; } \
238 inline std::ostream& operator<<(std::ostream& os, name ## _d x) \
239 { os << Value(x); return os; } \
241 inline std::istream& operator>>(std::istream& os, name ## _d& x) \
249 void dummy_function_to_force_semicolon()
259 #define GG_STRONG_INTEGRAL_TYPEDEF(name, type) \
260 GG_STRONG_DOUBLE_TYPEDEF(name, type); \
262 type Value(name x); \
267 struct ConvertibleToBoolDummy {int _;}; \
270 BOOST_STATIC_ASSERT((boost::is_integral<type>::value)); \
272 typedef type value_type; \
274 name() : m_value(0) {} \
275 explicit name(type t) : m_value(t) {} \
276 explicit name(name ## _d t) : \
277 m_value(static_cast<type>(Value(t))) \
280 name& operator=(name ## _d t) \
281 { m_value = static_cast<type>(Value(t)); return *this; } \
283 GG_MEMBER_SELF_COMPARATORS(name); \
285 GG_MEMBER_OTHER_COMPARATORS(type); \
286 GG_MEMBER_OTHER_COMPARATORS(name ## _d); \
287 GG_MEMBER_OTHER_COMPARATORS(double); \
289 operator int ConvertibleToBoolDummy::* () const \
290 { return m_value ? &ConvertibleToBoolDummy::_ : 0; } \
292 GG_MEMBER_NEG_INCR_DECR(name); \
294 GG_MEMBER_ARITH_ASSIGN_OPS_SELF_TYPE(name); \
295 GG_MEMBER_ASSIGN_OP_SELF_TYPE(%=, name); \
297 GG_MEMBER_ARITH_ASSIGN_OPS_OTHER_TYPE(name, type); \
298 GG_MEMBER_ASSIGN_OP_OTHER_TYPE(%, name, type); \
300 GG_MEMBER_ARITH_ASSIGN_OPS_OTHER_TYPE(name, name ## _d); \
301 GG_MEMBER_ARITH_ASSIGN_OPS_OTHER_TYPE(name, double); \
306 friend class name ## _d; \
307 friend type Value(name x); \
310 GG_NONMEMBER_ARITH_OPS_SELF_TYPE(name); \
311 GG_NONMEMBER_OP_SELF_TYPE(%, name); \
313 GG_NONMEMBER_ARITH_OPS_OTHER_TYPE(name, type); \
314 GG_NONMEMBER_OP_OTHER_TYPE(%, name, type); \
316 GG_NONMEMBER_REVERSED_BOOL_OP_SET(type, name); \
317 GG_NONMEMBER_REVERSED_BOOL_OP_SET(name ## _d, name); \
318 GG_NONMEMBER_REVERSED_BOOL_OP_SET(double, name); \
320 GG_NONMEMBER_REVERSED_ARITH_OP_SET(type, name); \
322 inline name ## _d operator+(name x, double y) \
323 { return name ## _d(Value(x)) + y; } \
324 inline name ## _d operator-(name x, double y) \
325 { return name ## _d(Value(x)) - y; } \
326 inline name ## _d operator*(name x, double y) \
327 { return name ## _d(Value(x)) * y; } \
328 inline name ## _d operator/(name x, double y) \
329 { return name ## _d(Value(x)) / y; } \
331 inline name ## _d operator+(double x, name y) \
332 { return x + name ## _d(Value(y)); } \
333 inline name ## _d operator-(double x, name y) \
334 { return x - name ## _d(Value(y)); } \
335 inline name ## _d operator*(double x, name y) \
336 { return x * name ## _d(Value(y)); } \
338 inline type Value(name x) \
339 { return x.m_value; } \
341 inline std::ostream& operator<<(std::ostream& os, name x) \
342 { os << Value(x); return os; } \
344 inline std::istream& operator>>(std::istream& os, name& x) \
352 inline name ## _d& name ## _d::operator+=(name rhs) \
353 { m_value += Value(rhs); return *this; } \
354 inline name ## _d& name ## _d::operator-=(name rhs) \
355 { m_value -= Value(rhs); return *this; } \
356 inline name ## _d& name ## _d::operator*=(name rhs) \
357 { m_value *= Value(rhs); return *this; } \
358 inline name ## _d& name ## _d::operator/=(name rhs) \
359 { m_value /= Value(rhs); return *this; } \
361 GG_NONMEMBER_ARITH_OPS_OTHER_TYPE(name ## _d, name); \
363 GG_NONMEMBER_REVERSED_ARITH_OP_SET(name, name ## _d); \
364 inline name ## _d operator/(name x, name ## _d y) \
365 { return name ## _d(Value(x) / Value(y)); } \
367 void dummy_function_to_force_semicolon()
374 #define GG_STRONG_SIZE_TYPEDEF(name) \
376 std::size_t Value(name x); \
381 struct ConvertibleToBoolDummy {int _;}; \
384 typedef std::size_t value_type; \
386 name() : m_value(0) {} \
387 explicit name(std::size_t t) : m_value(t) {} \
389 GG_MEMBER_SELF_COMPARATORS(name); \
391 GG_MEMBER_OTHER_COMPARATORS(std::size_t); \
393 operator int ConvertibleToBoolDummy::* () const \
394 { return m_value ? &ConvertibleToBoolDummy::_ : 0; } \
396 GG_MEMBER_NEG_INCR_DECR(name); \
398 GG_MEMBER_ARITH_ASSIGN_OPS_SELF_TYPE(name); \
399 GG_MEMBER_ASSIGN_OP_SELF_TYPE(%=, name); \
401 GG_MEMBER_ARITH_ASSIGN_OPS_OTHER_TYPE(name, std::size_t); \
402 GG_MEMBER_ASSIGN_OP_OTHER_TYPE(%, name, std::size_t); \
405 std::size_t m_value; \
407 friend class name ## _d; \
408 friend std::size_t Value(name x); \
411 GG_NONMEMBER_ARITH_OPS_SELF_TYPE(name); \
412 GG_NONMEMBER_OP_SELF_TYPE(%, name); \
414 GG_NONMEMBER_ARITH_OPS_OTHER_TYPE(name, std::size_t); \
415 GG_NONMEMBER_OP_OTHER_TYPE(%, name, std::size_t); \
417 GG_NONMEMBER_REVERSED_BOOL_OP_SET(std::size_t, name); \
419 GG_NONMEMBER_REVERSED_ARITH_OP_SET(std::size_t, name); \
421 inline std::size_t Value(name x) \
422 { return x.m_value; } \
424 inline std::ostream& operator<<(std::ostream& os, name x) \
425 { os << Value(x); return os; } \
427 inline std::istream& operator>>(std::istream& os, name& x) \
435 void dummy_function_to_force_semicolon()