00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00030 #ifndef _GG_StrongTypedef_h_
00031 #define _GG_StrongTypedef_h_
00032
00033 #include <boost/static_assert.hpp>
00034 #include <boost/operators.hpp>
00035 #include <boost/type_traits/is_integral.hpp>
00036 #include <boost/serialization/nvp.hpp>
00037
00038 #include <iostream>
00039
00040
00041 #define GG_STRONG_DOUBLE_TYPEDEF(name) \
00042 class name; \
00043 class name ## _d; \
00044 double Value(name ## _d x); \
00045 \
00046 class name ## _d : \
00047 boost::equality_comparable1<name ## _d \
00048 , boost::equality_comparable2<name ## _d, double \
00049 , boost::unit_steppable<name ## _d \
00050 , boost::integer_arithmetic1<name ## _d \
00051 , boost::integer_arithmetic2<name ## _d, double \
00052 , boost::subtractable2_left<name ## _d, double \
00053 > > > > > > \
00054 { \
00055 private: \
00056 struct ConvertibleToBoolDummy {int _;}; \
00057 \
00058 public: \
00059 name ## _d() {} \
00060 explicit name ## _d(double t) : m_value(t) {} \
00061 \
00062 bool operator<(name ## _d rhs) const \
00063 { return m_value < rhs.m_value; } \
00064 bool operator==(name ## _d rhs) const \
00065 { return m_value == rhs.m_value; } \
00066 \
00067 bool operator<(double rhs) const \
00068 { return m_value < rhs; } \
00069 bool operator==(double rhs) const \
00070 { return m_value == rhs; } \
00071 \
00072 operator int ConvertibleToBoolDummy::* () const \
00073 { return m_value ? &ConvertibleToBoolDummy::_ : 0; } \
00074 \
00075 name ## _d operator-() const \
00076 { return name ## _d(-m_value); } \
00077 \
00078 name ## _d& operator++() \
00079 { ++m_value; return *this; } \
00080 name ## _d& operator--() \
00081 { --m_value; return *this; } \
00082 \
00083 name ## _d& operator+=(name ## _d rhs) \
00084 { m_value += rhs.m_value; return *this; } \
00085 name ## _d& operator-=(name ## _d rhs) \
00086 { m_value -= rhs.m_value; return *this; } \
00087 name ## _d& operator*=(name ## _d rhs) \
00088 { m_value *= rhs.m_value; return *this; } \
00089 name ## _d& operator/=(name ## _d rhs) \
00090 { m_value /= rhs.m_value; return *this; } \
00091 \
00092 name ## _d& operator+=(double rhs) \
00093 { m_value += rhs; return *this; } \
00094 name ## _d& operator-=(double rhs) \
00095 { m_value -= rhs; return *this; } \
00096 name ## _d& operator*=(double rhs) \
00097 { m_value *= rhs; return *this; } \
00098 name ## _d& operator/=(double rhs) \
00099 { m_value /= rhs; return *this; } \
00100 \
00101 name ## _d& operator+=(name rhs); \
00102 name ## _d& operator-=(name rhs); \
00103 name ## _d& operator*=(name rhs); \
00104 name ## _d& operator/=(name rhs); \
00105 \
00106 name ## _d operator+(name rhs); \
00107 name ## _d operator-(name rhs); \
00108 name ## _d operator*(name rhs); \
00109 name ## _d operator/(name rhs); \
00110 \
00111 private: \
00112 double m_value; \
00113 \
00114 friend class boost::serialization::access; \
00115 template <class Archive> \
00116 void serialize(Archive& ar, const unsigned int version) \
00117 { ar & BOOST_SERIALIZATION_NVP(m_value); } \
00118 \
00119 friend double Value(name ## _d x); \
00120 }; \
00121 \
00122 inline bool operator>(name ## _d x, name ## _d y) \
00123 { return y < x; } \
00124 inline bool operator<=(name ## _d x, name ## _d y) \
00125 { return x < y || x == y; } \
00126 inline bool operator>=(name ## _d x, name ## _d y) \
00127 { return y < x || x == y; } \
00128 \
00129 inline bool operator>(name ## _d x, double y) \
00130 { return !(x < y || x == y); } \
00131 inline bool operator<=(name ## _d x, double y) \
00132 { return x < y || x == y; } \
00133 inline bool operator>=(name ## _d x, double y) \
00134 { return !(x < y); } \
00135 inline bool operator>(double x, name ## _d y) \
00136 { return y < x; } \
00137 inline bool operator<(double x, name ## _d y) \
00138 { return !(y < x || y == x); } \
00139 inline bool operator<=(double x, name ## _d y) \
00140 { return !(y < x); } \
00141 inline bool operator>=(double x, name ## _d y) \
00142 { return y < x || x == y; } \
00143 \
00144 inline double Value(name ## _d x) \
00145 { return x.m_value; } \
00146 \
00147 inline std::ostream& operator<<(std::ostream& os, name ## _d x) \
00148 { os << Value(x); return os; } \
00149 \
00150 inline std::istream& operator>>(std::istream& os, name ## _d& x) \
00151 { \
00152 double t; \
00153 os >> t; \
00154 x = name ## _d(t); \
00155 return os; \
00156 } \
00157 \
00158 void dummy_function_to_force_semicolon()
00159
00168 #define GG_STRONG_INTEGRAL_TYPEDEF(name, type) \
00169 GG_STRONG_DOUBLE_TYPEDEF(name); \
00170 \
00171 type Value(name x); \
00172 \
00173 class name : \
00174 boost::equality_comparable1<name \
00175 , boost::equality_comparable2<name, type \
00176 , boost::equality_comparable2<name, name ## _d \
00177 , boost::equality_comparable2<name, double \
00178 , boost::unit_steppable<name \
00179 , boost::integer_arithmetic1<name \
00180 , boost::integer_arithmetic2<name, type \
00181 , boost::subtractable2_left<name, type \
00182 > > > > > > > > \
00183 { \
00184 private: \
00185 struct ConvertibleToBoolDummy {int _;}; \
00186 \
00187 public: \
00188 BOOST_STATIC_ASSERT((boost::is_integral<type>::value)); \
00189 \
00190 name() {} \
00191 explicit name(type t) : m_value(t) {} \
00192 explicit name(name ## _d t) : \
00193 m_value(static_cast<type>(Value(t))) \
00194 {} \
00195 \
00196 name& operator=(name ## _d t) \
00197 { m_value = static_cast<type>(Value(t)); return *this; } \
00198 \
00199 bool operator<(name rhs) const \
00200 { return m_value < rhs.m_value; } \
00201 bool operator==(name rhs) const \
00202 { return m_value == rhs.m_value; } \
00203 \
00204 bool operator<(type rhs) const \
00205 { return m_value < rhs; } \
00206 bool operator==(type rhs) const \
00207 { return m_value == rhs; } \
00208 \
00209 bool operator<(name ## _d rhs) const \
00210 { return m_value < Value(rhs); } \
00211 bool operator==(name ## _d rhs) const \
00212 { return m_value == Value(rhs); } \
00213 \
00214 bool operator<(double rhs) const \
00215 { return m_value < rhs; } \
00216 bool operator==(double rhs) const \
00217 { return m_value == rhs; } \
00218 \
00219 operator int ConvertibleToBoolDummy::* () const \
00220 { return m_value ? &ConvertibleToBoolDummy::_ : 0; } \
00221 \
00222 name operator-() const \
00223 { return name(-m_value); } \
00224 \
00225 name& operator++() \
00226 { ++m_value; return *this; } \
00227 name& operator--() \
00228 { --m_value; return *this; } \
00229 \
00230 name& operator+=(name rhs) \
00231 { m_value += rhs.m_value; return *this; } \
00232 name& operator-=(name rhs) \
00233 { m_value -= rhs.m_value; return *this; } \
00234 name& operator*=(name rhs) \
00235 { m_value *= rhs.m_value; return *this; } \
00236 name& operator/=(name rhs) \
00237 { m_value /= rhs.m_value; return *this; } \
00238 name& operator%=(name rhs) \
00239 { m_value %= rhs.m_value; return *this; } \
00240 \
00241 name& operator+=(type rhs) \
00242 { m_value += rhs; return *this; } \
00243 name& operator-=(type rhs) \
00244 { m_value -= rhs; return *this; } \
00245 name& operator*=(type rhs) \
00246 { m_value *= rhs; return *this; } \
00247 name& operator/=(type rhs) \
00248 { m_value /= rhs; return *this; } \
00249 name& operator%=(type rhs) \
00250 { m_value %= rhs; return *this; } \
00251 \
00252 name& operator+=(name ## _d rhs) \
00253 { return operator+=(Value(rhs)); } \
00254 name& operator-=(name ## _d rhs) \
00255 { return operator-=(Value(rhs)); } \
00256 name& operator*=(name ## _d rhs) \
00257 { return operator*=(Value(rhs)); } \
00258 name& operator/=(name ## _d rhs) \
00259 { return operator/=(Value(rhs)); } \
00260 \
00261 name& operator+=(double rhs) \
00262 { m_value = static_cast<type>(m_value + rhs); return *this; } \
00263 name& operator-=(double rhs) \
00264 { m_value = static_cast<type>(m_value - rhs); return *this; } \
00265 name& operator*=(double rhs) \
00266 { m_value = static_cast<type>(m_value * rhs); return *this; } \
00267 name& operator/=(double rhs) \
00268 { m_value = static_cast<type>(m_value / rhs); return *this; } \
00269 \
00270 private: \
00271 type m_value; \
00272 \
00273 friend class boost::serialization::access; \
00274 template <class Archive> \
00275 void serialize(Archive& ar, const unsigned int version) \
00276 { ar & BOOST_SERIALIZATION_NVP(m_value); } \
00277 \
00278 friend class name ## _d; \
00279 friend type Value(name x); \
00280 }; \
00281 \
00282 inline name ## _d operator+(name x, double y) \
00283 { return name ## _d(Value(x)) + y; } \
00284 inline name ## _d operator+(double x, name y) \
00285 { return x + name ## _d(Value(y)); } \
00286 \
00287 inline name ## _d operator-(name x, double y) \
00288 { return name ## _d(Value(x)) - y; } \
00289 inline name ## _d operator-(double x, name y) \
00290 { return x - name ## _d(Value(y)); } \
00291 \
00292 inline name ## _d operator*(name x, double y) \
00293 { return name ## _d(Value(x)) * y; } \
00294 inline name ## _d operator*(double x, name y) \
00295 { return x * name ## _d(Value(y)); } \
00296 \
00297 inline name ## _d operator/(name x, double y) \
00298 { return name ## _d(Value(x)) / y; } \
00299 \
00300 inline bool operator>(name x, name y) \
00301 { return y < x; } \
00302 inline bool operator<=(name x, name y) \
00303 { return x < y || x == y; } \
00304 inline bool operator>=(name x, name y) \
00305 { return y < x || x == y; } \
00306 \
00307 inline bool operator>(name x, type y) \
00308 { return !(x < y || x == y); } \
00309 inline bool operator<=(name x, type y) \
00310 { return x < y || x == y; } \
00311 inline bool operator>=(name x, type y) \
00312 { return !(x < y); } \
00313 inline bool operator>(type x, name y) \
00314 { return y < x; } \
00315 inline bool operator<(type x, name y) \
00316 { return !(y < x || y == x); } \
00317 inline bool operator<=(type x, name y) \
00318 { return !(y < x); } \
00319 inline bool operator>=(type x, name y) \
00320 { return y < x || x == y; } \
00321 \
00322 inline bool operator>(name x, name ## _d y) \
00323 { return !(x < y || x == y); } \
00324 inline bool operator<=(name x, name ## _d y) \
00325 { return x < y || x == y; } \
00326 inline bool operator>=(name x, name ## _d y) \
00327 { return !(x < y); } \
00328 inline bool operator>(name ## _d x, name y) \
00329 { return y < x; } \
00330 inline bool operator<(name ## _d x, name y) \
00331 { return !(y < x || y == x); } \
00332 inline bool operator<=(name ## _d x, name y) \
00333 { return !(y < x); } \
00334 inline bool operator>=(name ## _d x, name y) \
00335 { return y < x || x == y; } \
00336 \
00337 inline bool operator>(name x, double y) \
00338 { return !(x < y || x == y); } \
00339 inline bool operator<=(name x, double y) \
00340 { return x < y || x == y; } \
00341 inline bool operator>=(name x, double y) \
00342 { return !(x < y); } \
00343 inline bool operator>(double x, name y) \
00344 { return y < x; } \
00345 inline bool operator<(double x, name y) \
00346 { return !(y < x || y == x); } \
00347 inline bool operator<=(double x, name y) \
00348 { return !(y < x); } \
00349 inline bool operator>=(double x, name y) \
00350 { return y < x || x == y; } \
00351 \
00352 inline type Value(name x) \
00353 { return x.m_value; } \
00354 \
00355 inline std::ostream& operator<<(std::ostream& os, name x) \
00356 { os << Value(x); return os; } \
00357 \
00358 inline std::istream& operator>>(std::istream& os, name& x) \
00359 { \
00360 type t; \
00361 os >> t; \
00362 x = name(t); \
00363 return os; \
00364 } \
00365 \
00366 inline name ## _d& name ## _d::operator+=(name rhs) \
00367 { m_value += rhs.m_value; return *this; } \
00368 inline name ## _d& name ## _d::operator-=(name rhs) \
00369 { m_value -= rhs.m_value; return *this; } \
00370 inline name ## _d& name ## _d::operator*=(name rhs) \
00371 { m_value *= rhs.m_value; return *this; } \
00372 inline name ## _d& name ## _d::operator/=(name rhs) \
00373 { m_value /= rhs.m_value; return *this; } \
00374 \
00375 inline name ## _d operator+(name lhs, name ## _d rhs) \
00376 { return rhs += lhs; } \
00377 inline name ## _d operator-(name lhs, name ## _d rhs) \
00378 { return lhs - Value(rhs); } \
00379 inline name ## _d operator*(name lhs, name ## _d rhs) \
00380 { return rhs *= lhs; } \
00381 inline name ## _d operator/(name lhs, name ## _d rhs) \
00382 { return lhs / Value(rhs); } \
00383 \
00384 inline name ## _d name ## _d::operator+(name rhs) \
00385 { return name ## _d(m_value + rhs.m_value); } \
00386 inline name ## _d name ## _d::operator-(name rhs) \
00387 { return name ## _d(m_value - rhs.m_value); } \
00388 inline name ## _d name ## _d::operator*(name rhs) \
00389 { return name ## _d(m_value * rhs.m_value); } \
00390 inline name ## _d name ## _d::operator/(name rhs) \
00391 { return name ## _d(m_value / rhs.m_value); } \
00392 \
00393 void dummy_function_to_force_semicolon()
00394
00400 #define GG_STRONG_SIZE_TYPEDEF(name) \
00401 class name; \
00402 std::size_t Value(name x); \
00403 \
00404 class name : \
00405 boost::equality_comparable1<name \
00406 , boost::equality_comparable2<name, std::size_t \
00407 , boost::unit_steppable<name \
00408 , boost::integer_arithmetic1<name \
00409 , boost::integer_arithmetic2<name, std::size_t \
00410 , boost::subtractable2_left<name, std::size_t \
00411 > > > > > > \
00412 { \
00413 private: \
00414 struct ConvertibleToBoolDummy {int _;}; \
00415 \
00416 public: \
00417 name() {} \
00418 explicit name(std::size_t t) : m_value(t) {} \
00419 \
00420 bool operator<(name rhs) const \
00421 { return m_value < rhs.m_value; } \
00422 bool operator==(name rhs) const \
00423 { return m_value == rhs.m_value; } \
00424 \
00425 bool operator<(std::size_t rhs) const \
00426 { return m_value < rhs; } \
00427 bool operator==(std::size_t rhs) const \
00428 { return m_value == rhs; } \
00429 \
00430 operator int ConvertibleToBoolDummy::* () const \
00431 { return m_value ? &ConvertibleToBoolDummy::_ : 0; } \
00432 \
00433 name operator-() const \
00434 { return name(-m_value); } \
00435 \
00436 name& operator++() \
00437 { ++m_value; return *this; } \
00438 name& operator--() \
00439 { --m_value; return *this; } \
00440 \
00441 name& operator+=(name rhs) \
00442 { m_value += rhs.m_value; return *this; } \
00443 name& operator-=(name rhs) \
00444 { m_value -= rhs.m_value; return *this; } \
00445 name& operator*=(name rhs) \
00446 { m_value *= rhs.m_value; return *this; } \
00447 name& operator/=(name rhs) \
00448 { m_value /= rhs.m_value; return *this; } \
00449 name& operator%=(name rhs) \
00450 { m_value %= rhs.m_value; return *this; } \
00451 \
00452 name& operator+=(std::size_t rhs) \
00453 { m_value += rhs; return *this; } \
00454 name& operator-=(std::size_t rhs) \
00455 { m_value -= rhs; return *this; } \
00456 name& operator*=(std::size_t rhs) \
00457 { m_value *= rhs; return *this; } \
00458 name& operator/=(std::size_t rhs) \
00459 { m_value /= rhs; return *this; } \
00460 name& operator%=(std::size_t rhs) \
00461 { m_value %= rhs; return *this; } \
00462 \
00463 private: \
00464 std::size_t m_value; \
00465 \
00466 friend class boost::serialization::access; \
00467 template <class Archive> \
00468 void serialize(Archive& ar, const unsigned int version) \
00469 { ar & BOOST_SERIALIZATION_NVP(m_value); } \
00470 \
00471 friend class name ## _d; \
00472 friend std::size_t Value(name x); \
00473 }; \
00474 \
00475 inline bool operator>(name x, name y) \
00476 { return y < x; } \
00477 inline bool operator<=(name x, name y) \
00478 { return x < y || x == y; } \
00479 inline bool operator>=(name x, name y) \
00480 { return y < x || x == y; } \
00481 \
00482 inline bool operator>(name x, std::size_t y) \
00483 { return !(x < y || x == y); } \
00484 inline bool operator<=(name x, std::size_t y) \
00485 { return x < y || x == y; } \
00486 inline bool operator>=(name x, std::size_t y) \
00487 { return !(x < y); } \
00488 inline bool operator>(std::size_t x, name y) \
00489 { return y < x; } \
00490 inline bool operator<(std::size_t x, name y) \
00491 { return !(y < x || y == x); } \
00492 inline bool operator<=(std::size_t x, name y) \
00493 { return !(y < x); } \
00494 inline bool operator>=(std::size_t x, name y) \
00495 { return y < x || x == y; } \
00496 \
00497 inline std::size_t Value(name x) \
00498 { return x.m_value; } \
00499 \
00500 inline std::ostream& operator<<(std::ostream& os, name x) \
00501 { os << Value(x); return os; } \
00502 \
00503 inline std::istream& operator>>(std::istream& os, name& x) \
00504 { \
00505 std::size_t t; \
00506 os >> t; \
00507 x = name(t); \
00508 return os; \
00509 } \
00510 \
00511 void dummy_function_to_force_semicolon()
00512
00513 #endif // _GG_StrongTypedef_h_