00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef BOOST_OB_COMPRESSED_PAIR_HPP
00025 #define BOOST_OB_COMPRESSED_PAIR_HPP
00026
00027 #include <algorithm>
00028 #ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
00029 #include <boost/type_traits/object_traits.hpp>
00030 #endif
00031 #ifndef BOOST_SAME_TRAITS_HPP
00032 #include <boost/type_traits/same_traits.hpp>
00033 #endif
00034 #ifndef BOOST_CALL_TRAITS_HPP
00035 #include <boost/call_traits.hpp>
00036 #endif
00037
00038 namespace boost
00039 {
00040 #ifdef BOOST_MSVC6_MEMBER_TEMPLATES
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 template <class T1, class T2>
00051 class compressed_pair;
00052
00053 namespace detail{
00054
00055 template <class A, class T1, class T2>
00056 struct best_conversion_traits
00057 {
00058 typedef char one;
00059 typedef char (&two)[2];
00060 static A a;
00061 static one test(T1);
00062 static two test(T2);
00063
00064 enum { value = sizeof(test(a)) };
00065 };
00066
00067 template <int>
00068 struct init_one;
00069
00070 template <>
00071 struct init_one<1>
00072 {
00073 template <class A, class T1, class T2>
00074 static void init(const A& a, T1* p1, T2*)
00075 {
00076 *p1 = a;
00077 }
00078 };
00079
00080 template <>
00081 struct init_one<2>
00082 {
00083 template <class A, class T1, class T2>
00084 static void init(const A& a, T1*, T2* p2)
00085 {
00086 *p2 = a;
00087 }
00088 };
00089
00090
00091
00092 template <class T1, class T2>
00093 class compressed_pair_0
00094 {
00095 private:
00096 T1 _first;
00097 T2 _second;
00098 public:
00099 typedef T1 first_type;
00100 typedef T2 second_type;
00101 typedef typename call_traits<first_type>::param_type first_param_type;
00102 typedef typename call_traits<second_type>::param_type second_param_type;
00103 typedef typename call_traits<first_type>::reference first_reference;
00104 typedef typename call_traits<second_type>::reference second_reference;
00105 typedef typename call_traits<first_type>::const_reference first_const_reference;
00106 typedef typename call_traits<second_type>::const_reference second_const_reference;
00107
00108 compressed_pair_0() : _first(), _second() {}
00109 compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
00110 template <class A>
00111 explicit compressed_pair_0(const A& val)
00112 {
00113 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
00114 }
00115 compressed_pair_0(const ::boost::compressed_pair<T1,T2>& x)
00116 : _first(x.first()), _second(x.second()) {}
00117
00118 #if 0
00119 compressed_pair_0& operator=(const compressed_pair_0& x) {
00120 cout << "assigning compressed pair 0" << endl;
00121 _first = x._first;
00122 _second = x._second;
00123 cout << "finished assigning compressed pair 0" << endl;
00124 return *this;
00125 }
00126 #endif
00127
00128 first_reference first() { return _first; }
00129 first_const_reference first() const { return _first; }
00130
00131 second_reference second() { return _second; }
00132 second_const_reference second() const { return _second; }
00133
00134 void swap(compressed_pair_0& y)
00135 {
00136 using std::swap;
00137 swap(_first, y._first);
00138 swap(_second, y._second);
00139 }
00140 };
00141
00142
00143 template <class T1, class T2>
00144 class compressed_pair_1 : T2
00145 {
00146 private:
00147 T1 _first;
00148 public:
00149 typedef T1 first_type;
00150 typedef T2 second_type;
00151 typedef typename call_traits<first_type>::param_type first_param_type;
00152 typedef typename call_traits<second_type>::param_type second_param_type;
00153 typedef typename call_traits<first_type>::reference first_reference;
00154 typedef typename call_traits<second_type>::reference second_reference;
00155 typedef typename call_traits<first_type>::const_reference first_const_reference;
00156 typedef typename call_traits<second_type>::const_reference second_const_reference;
00157
00158 compressed_pair_1() : T2(), _first() {}
00159 compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}
00160
00161 template <class A>
00162 explicit compressed_pair_1(const A& val)
00163 {
00164 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
00165 }
00166
00167 compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
00168 : T2(x.second()), _first(x.first()) {}
00169
00170 #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
00171
00172
00173
00174 compressed_pair_1& operator=(const compressed_pair_1& x) {
00175 _first = x._first;
00176 T2::operator=(x);
00177 return *this;
00178 }
00179 #endif
00180
00181 first_reference first() { return _first; }
00182 first_const_reference first() const { return _first; }
00183
00184 second_reference second() { return *this; }
00185 second_const_reference second() const { return *this; }
00186
00187 void swap(compressed_pair_1& y)
00188 {
00189
00190 using std::swap;
00191 swap(_first, y._first);
00192 }
00193 };
00194
00195
00196 template <class T1, class T2>
00197 class compressed_pair_2 : T1
00198 {
00199 private:
00200 T2 _second;
00201 public:
00202 typedef T1 first_type;
00203 typedef T2 second_type;
00204 typedef typename call_traits<first_type>::param_type first_param_type;
00205 typedef typename call_traits<second_type>::param_type second_param_type;
00206 typedef typename call_traits<first_type>::reference first_reference;
00207 typedef typename call_traits<second_type>::reference second_reference;
00208 typedef typename call_traits<first_type>::const_reference first_const_reference;
00209 typedef typename call_traits<second_type>::const_reference second_const_reference;
00210
00211 compressed_pair_2() : T1(), _second() {}
00212 compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
00213 template <class A>
00214 explicit compressed_pair_2(const A& val)
00215 {
00216 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
00217 }
00218 compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
00219 : T1(x.first()), _second(x.second()) {}
00220
00221 #if 0
00222 compressed_pair_2& operator=(const compressed_pair_2& x) {
00223 cout << "assigning compressed pair 2" << endl;
00224 T1::operator=(x);
00225 _second = x._second;
00226 cout << "finished assigning compressed pair 2" << endl;
00227 return *this;
00228 }
00229 #endif
00230 first_reference first() { return *this; }
00231 first_const_reference first() const { return *this; }
00232
00233 second_reference second() { return _second; }
00234 second_const_reference second() const { return _second; }
00235
00236 void swap(compressed_pair_2& y)
00237 {
00238
00239 using std::swap;
00240 swap(_second, y._second);
00241 }
00242 };
00243
00244
00245 template <class T1, class T2>
00246 class compressed_pair_3 : T1, T2
00247 {
00248 public:
00249 typedef T1 first_type;
00250 typedef T2 second_type;
00251 typedef typename call_traits<first_type>::param_type first_param_type;
00252 typedef typename call_traits<second_type>::param_type second_param_type;
00253 typedef typename call_traits<first_type>::reference first_reference;
00254 typedef typename call_traits<second_type>::reference second_reference;
00255 typedef typename call_traits<first_type>::const_reference first_const_reference;
00256 typedef typename call_traits<second_type>::const_reference second_const_reference;
00257
00258 compressed_pair_3() : T1(), T2() {}
00259 compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
00260 template <class A>
00261 explicit compressed_pair_3(const A& val)
00262 {
00263 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
00264 }
00265 compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
00266 : T1(x.first()), T2(x.second()) {}
00267
00268 first_reference first() { return *this; }
00269 first_const_reference first() const { return *this; }
00270
00271 second_reference second() { return *this; }
00272 second_const_reference second() const { return *this; }
00273
00274 void swap(compressed_pair_3& y)
00275 {
00276
00277 }
00278 };
00279
00280
00281 template <class T1, class T2>
00282 class compressed_pair_4 : T1
00283 {
00284 public:
00285 typedef T1 first_type;
00286 typedef T2 second_type;
00287 typedef typename call_traits<first_type>::param_type first_param_type;
00288 typedef typename call_traits<second_type>::param_type second_param_type;
00289 typedef typename call_traits<first_type>::reference first_reference;
00290 typedef typename call_traits<second_type>::reference second_reference;
00291 typedef typename call_traits<first_type>::const_reference first_const_reference;
00292 typedef typename call_traits<second_type>::const_reference second_const_reference;
00293
00294 compressed_pair_4() : T1() {}
00295 compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
00296
00297 explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
00298 compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
00299 : T1(x.first()), m_second(x.second()) {}
00300
00301 first_reference first() { return *this; }
00302 first_const_reference first() const { return *this; }
00303
00304 second_reference second() { return m_second; }
00305 second_const_reference second() const { return m_second; }
00306
00307 void swap(compressed_pair_4& y)
00308 {
00309
00310 }
00311 private:
00312 T2 m_second;
00313 };
00314
00315
00316 template <class T1, class T2>
00317 class compressed_pair_5
00318 {
00319 private:
00320 T1 _first;
00321 T2 _second;
00322 public:
00323 typedef T1 first_type;
00324 typedef T2 second_type;
00325 typedef typename call_traits<first_type>::param_type first_param_type;
00326 typedef typename call_traits<second_type>::param_type second_param_type;
00327 typedef typename call_traits<first_type>::reference first_reference;
00328 typedef typename call_traits<second_type>::reference second_reference;
00329 typedef typename call_traits<first_type>::const_reference first_const_reference;
00330 typedef typename call_traits<second_type>::const_reference second_const_reference;
00331
00332 compressed_pair_5() : _first(), _second() {}
00333 compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
00334
00335 explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
00336 compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c)
00337 : _first(c.first()), _second(c.second()) {}
00338
00339 first_reference first() { return _first; }
00340 first_const_reference first() const { return _first; }
00341
00342 second_reference second() { return _second; }
00343 second_const_reference second() const { return _second; }
00344
00345 void swap(compressed_pair_5& y)
00346 {
00347 using std::swap;
00348 swap(_first, y._first);
00349 swap(_second, y._second);
00350 }
00351 };
00352
00353 template <bool e1, bool e2, bool same>
00354 struct compressed_pair_chooser
00355 {
00356 template <class T1, class T2>
00357 struct rebind
00358 {
00359 typedef compressed_pair_0<T1, T2> type;
00360 };
00361 };
00362
00363 template <>
00364 struct compressed_pair_chooser<false, true, false>
00365 {
00366 template <class T1, class T2>
00367 struct rebind
00368 {
00369 typedef compressed_pair_1<T1, T2> type;
00370 };
00371 };
00372
00373 template <>
00374 struct compressed_pair_chooser<true, false, false>
00375 {
00376 template <class T1, class T2>
00377 struct rebind
00378 {
00379 typedef compressed_pair_2<T1, T2> type;
00380 };
00381 };
00382
00383 template <>
00384 struct compressed_pair_chooser<true, true, false>
00385 {
00386 template <class T1, class T2>
00387 struct rebind
00388 {
00389 typedef compressed_pair_3<T1, T2> type;
00390 };
00391 };
00392
00393 template <>
00394 struct compressed_pair_chooser<true, true, true>
00395 {
00396 template <class T1, class T2>
00397 struct rebind
00398 {
00399 typedef compressed_pair_4<T1, T2> type;
00400 };
00401 };
00402
00403 template <>
00404 struct compressed_pair_chooser<false, false, true>
00405 {
00406 template <class T1, class T2>
00407 struct rebind
00408 {
00409 typedef compressed_pair_5<T1, T2> type;
00410 };
00411 };
00412
00413 template <class T1, class T2>
00414 struct compressed_pair_traits
00415 {
00416 private:
00417 typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
00418 typedef typename chooser::template rebind<T1, T2> bound_type;
00419 public:
00420 typedef typename bound_type::type type;
00421 };
00422
00423 }
00424
00425 template <class T1, class T2>
00426 class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
00427 {
00428 private:
00429 typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
00430 public:
00431 typedef T1 first_type;
00432 typedef T2 second_type;
00433 typedef typename call_traits<first_type>::param_type first_param_type;
00434 typedef typename call_traits<second_type>::param_type second_param_type;
00435 typedef typename call_traits<first_type>::reference first_reference;
00436 typedef typename call_traits<second_type>::reference second_reference;
00437 typedef typename call_traits<first_type>::const_reference first_const_reference;
00438 typedef typename call_traits<second_type>::const_reference second_const_reference;
00439
00440 compressed_pair() : base_type() {}
00441 compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
00442 template <class A>
00443 explicit compressed_pair(const A& x) : base_type(x){}
00444
00445 first_reference first() { return base_type::first(); }
00446 first_const_reference first() const { return base_type::first(); }
00447
00448 second_reference second() { return base_type::second(); }
00449 second_const_reference second() const { return base_type::second(); }
00450 };
00451
00452 template <class T1, class T2>
00453 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
00454 {
00455 x.swap(y);
00456 }
00457
00458 #else
00459
00460
00461 template <class T1, class T2>
00462 class compressed_pair
00463 {
00464 private:
00465 T1 _first;
00466 T2 _second;
00467 public:
00468 typedef T1 first_type;
00469 typedef T2 second_type;
00470 typedef typename call_traits<first_type>::param_type first_param_type;
00471 typedef typename call_traits<second_type>::param_type second_param_type;
00472 typedef typename call_traits<first_type>::reference first_reference;
00473 typedef typename call_traits<second_type>::reference second_reference;
00474 typedef typename call_traits<first_type>::const_reference first_const_reference;
00475 typedef typename call_traits<second_type>::const_reference second_const_reference;
00476
00477 compressed_pair() : _first(), _second() {}
00478 compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
00479 explicit compressed_pair(first_param_type x) : _first(x), _second() {}
00480
00481
00482
00483 first_reference first() { return _first; }
00484 first_const_reference first() const { return _first; }
00485
00486 second_reference second() { return _second; }
00487 second_const_reference second() const { return _second; }
00488
00489 void swap(compressed_pair& y)
00490 {
00491 using std::swap;
00492 swap(_first, y._first);
00493 swap(_second, y._second);
00494 }
00495 };
00496
00497 template <class T1, class T2>
00498 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
00499 {
00500 x.swap(y);
00501 }
00502
00503 #endif
00504
00505 }
00506
00507 #endif // BOOST_OB_COMPRESSED_PAIR_HPP
00508
00509
00510