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