00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP
00021 #define BOOST_DETAIL_COMPRESSED_PAIR_HPP
00022
00023 #include <algorithm>
00024
00025 #include <boost/type_traits/remove_cv.hpp>
00026 #include <boost/type_traits/is_empty.hpp>
00027 #include <boost/type_traits/is_same.hpp>
00028 #include <boost/call_traits.hpp>
00029
00030 #ifdef BOOST_MSVC
00031 # pragma warning(push)
00032 # pragma warning(disable:4512)
00033 #endif
00034 namespace boost
00035 {
00036
00037 template <class T1, class T2>
00038 class compressed_pair;
00039
00040
00041
00042
00043 namespace details
00044 {
00045
00046 template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
00047 struct compressed_pair_switch;
00048
00049 template <class T1, class T2>
00050 struct compressed_pair_switch<T1, T2, false, false, false>
00051 {static const int value = 0;};
00052
00053 template <class T1, class T2>
00054 struct compressed_pair_switch<T1, T2, false, true, true>
00055 {static const int value = 3;};
00056
00057 template <class T1, class T2>
00058 struct compressed_pair_switch<T1, T2, false, true, false>
00059 {static const int value = 1;};
00060
00061 template <class T1, class T2>
00062 struct compressed_pair_switch<T1, T2, false, false, true>
00063 {static const int value = 2;};
00064
00065 template <class T1, class T2>
00066 struct compressed_pair_switch<T1, T2, true, true, true>
00067 {static const int value = 4;};
00068
00069 template <class T1, class T2>
00070 struct compressed_pair_switch<T1, T2, true, false, false>
00071 {static const int value = 5;};
00072
00073 template <class T1, class T2, int Version> class compressed_pair_imp;
00074
00075 #ifdef __GNUC__
00076
00077 using std::swap;
00078 #endif
00079
00080
00081
00082
00083
00084 template <typename T>
00085 inline void cp_swap(T& t1, T& t2)
00086 {
00087 #ifndef __GNUC__
00088 using std::swap;
00089 #endif
00090 swap(t1, t2);
00091 }
00092
00093
00094
00095 template <class T1, class T2>
00096 class compressed_pair_imp<T1, T2, 0>
00097 {
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_imp() {}
00109
00110 compressed_pair_imp(first_param_type x, second_param_type y)
00111 : first_(x), second_(y) {}
00112
00113 compressed_pair_imp(first_param_type x)
00114 : first_(x) {}
00115
00116 compressed_pair_imp(second_param_type y)
00117 : second_(y) {}
00118
00119 first_reference first() {return first_;}
00120 first_const_reference first() const {return first_;}
00121
00122 second_reference second() {return second_;}
00123 second_const_reference second() const {return second_;}
00124
00125 void swap(::boost::compressed_pair<T1, T2>& y)
00126 {
00127 cp_swap(first_, y.first());
00128 cp_swap(second_, y.second());
00129 }
00130 private:
00131 first_type first_;
00132 second_type second_;
00133 };
00134
00135
00136
00137 template <class T1, class T2>
00138 class compressed_pair_imp<T1, T2, 1>
00139 : protected ::boost::remove_cv<T1>::type
00140 {
00141 public:
00142 typedef T1 first_type;
00143 typedef T2 second_type;
00144 typedef typename call_traits<first_type>::param_type first_param_type;
00145 typedef typename call_traits<second_type>::param_type second_param_type;
00146 typedef typename call_traits<first_type>::reference first_reference;
00147 typedef typename call_traits<second_type>::reference second_reference;
00148 typedef typename call_traits<first_type>::const_reference first_const_reference;
00149 typedef typename call_traits<second_type>::const_reference second_const_reference;
00150
00151 compressed_pair_imp() {}
00152
00153 compressed_pair_imp(first_param_type x, second_param_type y)
00154 : first_type(x), second_(y) {}
00155
00156 compressed_pair_imp(first_param_type x)
00157 : first_type(x) {}
00158
00159 compressed_pair_imp(second_param_type y)
00160 : second_(y) {}
00161
00162 first_reference first() {return *this;}
00163 first_const_reference first() const {return *this;}
00164
00165 second_reference second() {return second_;}
00166 second_const_reference second() const {return second_;}
00167
00168 void swap(::boost::compressed_pair<T1,T2>& y)
00169 {
00170
00171 cp_swap(second_, y.second());
00172 }
00173 private:
00174 second_type second_;
00175 };
00176
00177
00178
00179 template <class T1, class T2>
00180 class compressed_pair_imp<T1, T2, 2>
00181 : protected ::boost::remove_cv<T2>::type
00182 {
00183 public:
00184 typedef T1 first_type;
00185 typedef T2 second_type;
00186 typedef typename call_traits<first_type>::param_type first_param_type;
00187 typedef typename call_traits<second_type>::param_type second_param_type;
00188 typedef typename call_traits<first_type>::reference first_reference;
00189 typedef typename call_traits<second_type>::reference second_reference;
00190 typedef typename call_traits<first_type>::const_reference first_const_reference;
00191 typedef typename call_traits<second_type>::const_reference second_const_reference;
00192
00193 compressed_pair_imp() {}
00194
00195 compressed_pair_imp(first_param_type x, second_param_type y)
00196 : second_type(y), first_(x) {}
00197
00198 compressed_pair_imp(first_param_type x)
00199 : first_(x) {}
00200
00201 compressed_pair_imp(second_param_type y)
00202 : second_type(y) {}
00203
00204 first_reference first() {return first_;}
00205 first_const_reference first() const {return first_;}
00206
00207 second_reference second() {return *this;}
00208 second_const_reference second() const {return *this;}
00209
00210 void swap(::boost::compressed_pair<T1,T2>& y)
00211 {
00212
00213 cp_swap(first_, y.first());
00214 }
00215
00216 private:
00217 first_type first_;
00218 };
00219
00220
00221
00222 template <class T1, class T2>
00223 class compressed_pair_imp<T1, T2, 3>
00224 : protected ::boost::remove_cv<T1>::type,
00225 protected ::boost::remove_cv<T2>::type
00226 {
00227 public:
00228 typedef T1 first_type;
00229 typedef T2 second_type;
00230 typedef typename call_traits<first_type>::param_type first_param_type;
00231 typedef typename call_traits<second_type>::param_type second_param_type;
00232 typedef typename call_traits<first_type>::reference first_reference;
00233 typedef typename call_traits<second_type>::reference second_reference;
00234 typedef typename call_traits<first_type>::const_reference first_const_reference;
00235 typedef typename call_traits<second_type>::const_reference second_const_reference;
00236
00237 compressed_pair_imp() {}
00238
00239 compressed_pair_imp(first_param_type x, second_param_type y)
00240 : first_type(x), second_type(y) {}
00241
00242 compressed_pair_imp(first_param_type x)
00243 : first_type(x) {}
00244
00245 compressed_pair_imp(second_param_type y)
00246 : second_type(y) {}
00247
00248 first_reference first() {return *this;}
00249 first_const_reference first() const {return *this;}
00250
00251 second_reference second() {return *this;}
00252 second_const_reference second() const {return *this;}
00253
00254
00255 void swap(::boost::compressed_pair<T1,T2>&) {}
00256 };
00257
00258
00259
00260
00261
00262
00263
00264
00265 template <class T1, class T2>
00266 class compressed_pair_imp<T1, T2, 4>
00267 : protected ::boost::remove_cv<T1>::type
00268 {
00269 public:
00270 typedef T1 first_type;
00271 typedef T2 second_type;
00272 typedef typename call_traits<first_type>::param_type first_param_type;
00273 typedef typename call_traits<second_type>::param_type second_param_type;
00274 typedef typename call_traits<first_type>::reference first_reference;
00275 typedef typename call_traits<second_type>::reference second_reference;
00276 typedef typename call_traits<first_type>::const_reference first_const_reference;
00277 typedef typename call_traits<second_type>::const_reference second_const_reference;
00278
00279 compressed_pair_imp() {}
00280
00281 compressed_pair_imp(first_param_type x, second_param_type y)
00282 : first_type(x), m_second(y) {}
00283
00284 compressed_pair_imp(first_param_type x)
00285 : first_type(x), m_second(x) {}
00286
00287 first_reference first() {return *this;}
00288 first_const_reference first() const {return *this;}
00289
00290 second_reference second() {return m_second;}
00291 second_const_reference second() const {return m_second;}
00292
00293 void swap(::boost::compressed_pair<T1,T2>&) {}
00294 private:
00295 T2 m_second;
00296 };
00297
00298
00299
00300 template <class T1, class T2>
00301 class compressed_pair_imp<T1, T2, 5>
00302 {
00303 public:
00304 typedef T1 first_type;
00305 typedef T2 second_type;
00306 typedef typename call_traits<first_type>::param_type first_param_type;
00307 typedef typename call_traits<second_type>::param_type second_param_type;
00308 typedef typename call_traits<first_type>::reference first_reference;
00309 typedef typename call_traits<second_type>::reference second_reference;
00310 typedef typename call_traits<first_type>::const_reference first_const_reference;
00311 typedef typename call_traits<second_type>::const_reference second_const_reference;
00312
00313 compressed_pair_imp() {}
00314
00315 compressed_pair_imp(first_param_type x, second_param_type y)
00316 : first_(x), second_(y) {}
00317
00318 compressed_pair_imp(first_param_type x)
00319 : first_(x), second_(x) {}
00320
00321 first_reference first() {return first_;}
00322 first_const_reference first() const {return first_;}
00323
00324 second_reference second() {return second_;}
00325 second_const_reference second() const {return second_;}
00326
00327 void swap(::boost::compressed_pair<T1, T2>& y)
00328 {
00329 cp_swap(first_, y.first());
00330 cp_swap(second_, y.second());
00331 }
00332 private:
00333 first_type first_;
00334 second_type second_;
00335 };
00336
00337 }
00338
00339 template <class T1, class T2>
00340 class compressed_pair
00341 : private ::boost::details::compressed_pair_imp<T1, T2,
00342 ::boost::details::compressed_pair_switch<
00343 T1,
00344 T2,
00345 ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
00346 ::boost::is_empty<T1>::value,
00347 ::boost::is_empty<T2>::value>::value>
00348 {
00349 private:
00350 typedef details::compressed_pair_imp<T1, T2,
00351 ::boost::details::compressed_pair_switch<
00352 T1,
00353 T2,
00354 ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
00355 ::boost::is_empty<T1>::value,
00356 ::boost::is_empty<T2>::value>::value> base;
00357 public:
00358 typedef T1 first_type;
00359 typedef T2 second_type;
00360 typedef typename call_traits<first_type>::param_type first_param_type;
00361 typedef typename call_traits<second_type>::param_type second_param_type;
00362 typedef typename call_traits<first_type>::reference first_reference;
00363 typedef typename call_traits<second_type>::reference second_reference;
00364 typedef typename call_traits<first_type>::const_reference first_const_reference;
00365 typedef typename call_traits<second_type>::const_reference second_const_reference;
00366
00367 compressed_pair() : base() {}
00368 compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
00369 explicit compressed_pair(first_param_type x) : base(x) {}
00370 explicit compressed_pair(second_param_type y) : base(y) {}
00371
00372 first_reference first() {return base::first();}
00373 first_const_reference first() const {return base::first();}
00374
00375 second_reference second() {return base::second();}
00376 second_const_reference second() const {return base::second();}
00377
00378 void swap(compressed_pair& y) { base::swap(y); }
00379 };
00380
00381
00382
00383
00384 template <class T>
00385 class compressed_pair<T, T>
00386 : private details::compressed_pair_imp<T, T,
00387 ::boost::details::compressed_pair_switch<
00388 T,
00389 T,
00390 ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
00391 ::boost::is_empty<T>::value,
00392 ::boost::is_empty<T>::value>::value>
00393 {
00394 private:
00395 typedef details::compressed_pair_imp<T, T,
00396 ::boost::details::compressed_pair_switch<
00397 T,
00398 T,
00399 ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
00400 ::boost::is_empty<T>::value,
00401 ::boost::is_empty<T>::value>::value> base;
00402 public:
00403 typedef T first_type;
00404 typedef T second_type;
00405 typedef typename call_traits<first_type>::param_type first_param_type;
00406 typedef typename call_traits<second_type>::param_type second_param_type;
00407 typedef typename call_traits<first_type>::reference first_reference;
00408 typedef typename call_traits<second_type>::reference second_reference;
00409 typedef typename call_traits<first_type>::const_reference first_const_reference;
00410 typedef typename call_traits<second_type>::const_reference second_const_reference;
00411
00412 compressed_pair() : base() {}
00413 compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
00414 #if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))
00415 explicit
00416 #endif
00417 compressed_pair(first_param_type x) : base(x) {}
00418
00419 first_reference first() {return base::first();}
00420 first_const_reference first() const {return base::first();}
00421
00422 second_reference second() {return base::second();}
00423 second_const_reference second() const {return base::second();}
00424
00425 void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }
00426 };
00427
00428 template <class T1, class T2>
00429 inline
00430 void
00431 swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
00432 {
00433 x.swap(y);
00434 }
00435
00436 }
00437
00438 #ifdef BOOST_MSVC
00439 # pragma warning(pop)
00440 #endif
00441
00442 #endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
00443