ob_compressed_pair.hpp
Go to the documentation of this file.
00001 //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
00002 //  Use, modification and distribution are subject to the Boost Software License,
00003 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
00004 //  http://www.boost.org/LICENSE_1_0.txt).
00005 //
00006 //  See http://www.boost.org/libs/utility for most recent version including documentation.
00007 //  see libs/utility/compressed_pair.hpp
00008 //
00009 /* Release notes:
00010    20 Jan 2001:
00011         Fixed obvious bugs (David Abrahams)
00012    07 Oct 2000:
00013       Added better single argument constructor support.
00014    03 Oct 2000:
00015       Added VC6 support (JM).
00016    23rd July 2000:
00017       Additional comments added. (JM)
00018    Jan 2000:
00019       Original version: this version crippled for use with crippled compilers
00020       - John Maddock Jan 2000.
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 // use member templates to emulate
00043 // partial specialisation.  Note that due to
00044 // problems with overload resolution with VC6
00045 // each of the compressed_pair versions that follow
00046 // have one template single-argument constructor
00047 // in place of two specific constructors:
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 // T1 != T2, both non-empty
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 // T1 != T2, T2 empty
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   // Total weirdness. If the assignment to _first is moved after
00172   // the call to the inherited operator=, then this breaks graph/test/graph.cpp
00173   // by way of iterator_adaptor.
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       // no need to swap empty base class:
00190       using std::swap;
00191       swap(_first, y._first);
00192    }
00193 };
00194 
00195 // T1 != T2, T1 empty
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       // no need to swap empty base class:
00239       using std::swap;
00240       swap(_second, y._second);
00241    }
00242 };
00243 
00244 // T1 != T2, both empty
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       // no need to swap empty base classes:
00277    }
00278 };
00279 
00280 // T1 == T2, and empty
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    // only one single argument constructor since T1 == T2
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       // no need to swap empty base classes:
00310    }
00311 private:
00312    T2 m_second;
00313 };
00314 
00315 // T1 == T2, not empty
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    // only one single argument constructor since T1 == T2
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 } // namespace detail
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 // no partial specialisation, no member templates:
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    // can't define this in case T1 == T2:
00481    // explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
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 } // boost
00506 
00507 #endif // BOOST_OB_COMPRESSED_PAIR_HPP
00508 
00509 
00510 


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29