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 
00008 // compressed_pair: pair that "compresses" empty members
00009 // (see libs/utility/compressed_pair.htm)
00010 //
00011 // JM changes 25 Jan 2004:
00012 // For the case where T1 == T2 and both are empty, then first() and second()
00013 // should return different objects.
00014 // JM changes 25 Jan 2000:
00015 // Removed default arguments from compressed_pair_switch to get
00016 // C++ Builder 4 to accept them
00017 // rewriten swap to get gcc and C++ builder to compile.
00018 // added partial specialisations for case T1 == T2 to avoid duplicate constructor defs.
00019 
00020 #ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP
00021 #define BOOST_DETAIL_COMPRESSED_PAIR_HPP
00022 
00023 #include <algorithm>
00024 
00025 #include <sysc/packages/boost/type_traits/remove_cv.hpp>
00026 #include <sysc/packages/boost/type_traits/is_empty.hpp>
00027 #include <sysc/packages/boost/type_traits/is_same.hpp>
00028 #include <sysc/packages/boost/call_traits.hpp>
00029 
00030 namespace boost
00031 {
00032 
00033 template <class T1, class T2>
00034 class compressed_pair;
00035 
00036 
00037 // compressed_pair
00038 
00039 namespace details
00040 {
00041    // JM altered 26 Jan 2000:
00042    template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
00043    struct compressed_pair_switch;
00044 
00045    template <class T1, class T2>
00046    struct compressed_pair_switch<T1, T2, false, false, false>
00047       {static const int value = 0;};
00048 
00049    template <class T1, class T2>
00050    struct compressed_pair_switch<T1, T2, false, true, true>
00051       {static const int value = 3;};
00052 
00053    template <class T1, class T2>
00054    struct compressed_pair_switch<T1, T2, false, true, false>
00055       {static const int value = 1;};
00056 
00057    template <class T1, class T2>
00058    struct compressed_pair_switch<T1, T2, false, false, true>
00059       {static const int value = 2;};
00060 
00061    template <class T1, class T2>
00062    struct compressed_pair_switch<T1, T2, true, true, true>
00063       {static const int value = 4;};
00064 
00065    template <class T1, class T2>
00066    struct compressed_pair_switch<T1, T2, true, false, false>
00067       {static const int value = 5;};
00068 
00069    template <class T1, class T2, int Version> class compressed_pair_imp;
00070 
00071 #ifdef __GNUC__
00072    // workaround for GCC (JM):
00073    using std::swap;
00074 #endif
00075    //
00076    // can't call unqualified swap from within classname::swap
00077    // as Koenig lookup rules will find only the classname::swap
00078    // member function not the global declaration, so use cp_swap
00079    // as a forwarding function (JM):
00080    template <typename T>
00081    inline void cp_swap(T& t1, T& t2)
00082    {
00083 #ifndef __GNUC__
00084       using std::swap;
00085 #endif
00086       swap(t1, t2);
00087    }
00088 
00089    // 0    derive from neither
00090 
00091    template <class T1, class T2>
00092    class compressed_pair_imp<T1, T2, 0>
00093    {
00094    public:
00095       typedef T1                                                 first_type;
00096       typedef T2                                                 second_type;
00097       typedef typename call_traits<first_type>::param_type       first_param_type;
00098       typedef typename call_traits<second_type>::param_type      second_param_type;
00099       typedef typename call_traits<first_type>::reference        first_reference;
00100       typedef typename call_traits<second_type>::reference       second_reference;
00101       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00102       typedef typename call_traits<second_type>::const_reference second_const_reference;
00103 
00104       compressed_pair_imp() {} 
00105 
00106       compressed_pair_imp(first_param_type x, second_param_type y)
00107          : first_(x), second_(y) {}
00108 
00109       compressed_pair_imp(first_param_type x)
00110          : first_(x) {}
00111 
00112       compressed_pair_imp(second_param_type y)
00113          : second_(y) {}
00114 
00115       first_reference       first()       {return first_;}
00116       first_const_reference first() const {return first_;}
00117 
00118       second_reference       second()       {return second_;}
00119       second_const_reference second() const {return second_;}
00120 
00121       void swap(::boost::compressed_pair<T1, T2>& y)
00122       {
00123          cp_swap(first_, y.first());
00124          cp_swap(second_, y.second());
00125       }
00126    private:
00127       first_type first_;
00128       second_type second_;
00129    };
00130 
00131    // 1    derive from T1
00132 
00133    template <class T1, class T2>
00134    class compressed_pair_imp<T1, T2, 1>
00135       : private ::boost::remove_cv<T1>::type
00136    {
00137    public:
00138       typedef T1                                                 first_type;
00139       typedef T2                                                 second_type;
00140       typedef typename call_traits<first_type>::param_type       first_param_type;
00141       typedef typename call_traits<second_type>::param_type      second_param_type;
00142       typedef typename call_traits<first_type>::reference        first_reference;
00143       typedef typename call_traits<second_type>::reference       second_reference;
00144       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00145       typedef typename call_traits<second_type>::const_reference second_const_reference;
00146 
00147       compressed_pair_imp() {}
00148 
00149       compressed_pair_imp(first_param_type x, second_param_type y)
00150          : first_type(x), second_(y) {}
00151 
00152       compressed_pair_imp(first_param_type x)
00153          : first_type(x) {}
00154 
00155       compressed_pair_imp(second_param_type y)
00156          : second_(y) {}
00157 
00158       first_reference       first()       {return *this;}
00159       first_const_reference first() const {return *this;}
00160 
00161       second_reference       second()       {return second_;}
00162       second_const_reference second() const {return second_;}
00163 
00164       void swap(::boost::compressed_pair<T1,T2>& y)
00165       {
00166          // no need to swap empty base class:
00167          cp_swap(second_, y.second());
00168       }
00169    private:
00170       second_type second_;
00171    };
00172 
00173    // 2    derive from T2
00174 
00175    template <class T1, class T2>
00176    class compressed_pair_imp<T1, T2, 2>
00177       : private ::boost::remove_cv<T2>::type
00178    {
00179    public:
00180       typedef T1                                                 first_type;
00181       typedef T2                                                 second_type;
00182       typedef typename call_traits<first_type>::param_type       first_param_type;
00183       typedef typename call_traits<second_type>::param_type      second_param_type;
00184       typedef typename call_traits<first_type>::reference        first_reference;
00185       typedef typename call_traits<second_type>::reference       second_reference;
00186       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00187       typedef typename call_traits<second_type>::const_reference second_const_reference;
00188 
00189       compressed_pair_imp() {}
00190 
00191       compressed_pair_imp(first_param_type x, second_param_type y)
00192          : second_type(y), first_(x) {}
00193 
00194       compressed_pair_imp(first_param_type x)
00195          : first_(x) {}
00196 
00197       compressed_pair_imp(second_param_type y)
00198          : second_type(y) {}
00199 
00200       first_reference       first()       {return first_;}
00201       first_const_reference first() const {return first_;}
00202 
00203       second_reference       second()       {return *this;}
00204       second_const_reference second() const {return *this;}
00205 
00206       void swap(::boost::compressed_pair<T1,T2>& y)
00207       {
00208          // no need to swap empty base class:
00209          cp_swap(first_, y.first());
00210       }
00211 
00212    private:
00213       first_type first_;
00214    };
00215 
00216    // 3    derive from T1 and T2
00217 
00218    template <class T1, class T2>
00219    class compressed_pair_imp<T1, T2, 3>
00220       : private ::boost::remove_cv<T1>::type,
00221         private ::boost::remove_cv<T2>::type
00222    {
00223    public:
00224       typedef T1                                                 first_type;
00225       typedef T2                                                 second_type;
00226       typedef typename call_traits<first_type>::param_type       first_param_type;
00227       typedef typename call_traits<second_type>::param_type      second_param_type;
00228       typedef typename call_traits<first_type>::reference        first_reference;
00229       typedef typename call_traits<second_type>::reference       second_reference;
00230       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00231       typedef typename call_traits<second_type>::const_reference second_const_reference;
00232 
00233       compressed_pair_imp() {}
00234 
00235       compressed_pair_imp(first_param_type x, second_param_type y)
00236          : first_type(x), second_type(y) {}
00237 
00238       compressed_pair_imp(first_param_type x)
00239          : first_type(x) {}
00240 
00241       compressed_pair_imp(second_param_type y)
00242          : second_type(y) {}
00243 
00244       first_reference       first()       {return *this;}
00245       first_const_reference first() const {return *this;}
00246 
00247       second_reference       second()       {return *this;}
00248       second_const_reference second() const {return *this;}
00249       //
00250       // no need to swap empty bases:
00251       void swap(::boost::compressed_pair<T1,T2>&) {}
00252    };
00253 
00254    // JM
00255    // 4    T1 == T2, T1 and T2 both empty
00256    //      Note does not actually store an instance of T2 at all -
00257    //      but reuses T1 base class for both first() and second().
00258    template <class T1, class T2>
00259    class compressed_pair_imp<T1, T2, 4>
00260       : private ::boost::remove_cv<T1>::type
00261    {
00262    public:
00263       typedef T1                                                 first_type;
00264       typedef T2                                                 second_type;
00265       typedef typename call_traits<first_type>::param_type       first_param_type;
00266       typedef typename call_traits<second_type>::param_type      second_param_type;
00267       typedef typename call_traits<first_type>::reference        first_reference;
00268       typedef typename call_traits<second_type>::reference       second_reference;
00269       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00270       typedef typename call_traits<second_type>::const_reference second_const_reference;
00271 
00272       compressed_pair_imp() {}
00273 
00274       compressed_pair_imp(first_param_type x, second_param_type y)
00275          : first_type(x), m_second(y) {}
00276 
00277       compressed_pair_imp(first_param_type x)
00278          : first_type(x), m_second(x) {}
00279 
00280       first_reference       first()       {return *this;}
00281       first_const_reference first() const {return *this;}
00282 
00283       second_reference       second()       {return m_second;}
00284       second_const_reference second() const {return m_second;}
00285 
00286       void swap(::boost::compressed_pair<T1,T2>&) {}
00287    private:
00288       T2 m_second;
00289    };
00290 
00291    // 5    T1 == T2 and are not empty:   //JM
00292 
00293    template <class T1, class T2>
00294    class compressed_pair_imp<T1, T2, 5>
00295    {
00296    public:
00297       typedef T1                                                 first_type;
00298       typedef T2                                                 second_type;
00299       typedef typename call_traits<first_type>::param_type       first_param_type;
00300       typedef typename call_traits<second_type>::param_type      second_param_type;
00301       typedef typename call_traits<first_type>::reference        first_reference;
00302       typedef typename call_traits<second_type>::reference       second_reference;
00303       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00304       typedef typename call_traits<second_type>::const_reference second_const_reference;
00305 
00306       compressed_pair_imp() {}
00307 
00308       compressed_pair_imp(first_param_type x, second_param_type y)
00309          : first_(x), second_(y) {}
00310 
00311       compressed_pair_imp(first_param_type x)
00312          : first_(x), second_(x) {}
00313 
00314       first_reference       first()       {return first_;}
00315       first_const_reference first() const {return first_;}
00316 
00317       second_reference       second()       {return second_;}
00318       second_const_reference second() const {return second_;}
00319 
00320       void swap(::boost::compressed_pair<T1, T2>& y)
00321       {
00322          cp_swap(first_, y.first());
00323          cp_swap(second_, y.second());
00324       }
00325    private:
00326       first_type first_;
00327       second_type second_;
00328    };
00329 
00330 }  // details
00331 
00332 template <class T1, class T2>
00333 class compressed_pair
00334    : private ::boost::details::compressed_pair_imp<T1, T2,
00335              ::boost::details::compressed_pair_switch<
00336                     T1,
00337                     T2,
00338                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
00339                     ::boost::is_empty<T1>::value,
00340                     ::boost::is_empty<T2>::value>::value>
00341 {
00342 private:
00343    typedef details::compressed_pair_imp<T1, T2,
00344              ::boost::details::compressed_pair_switch<
00345                     T1,
00346                     T2,
00347                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
00348                     ::boost::is_empty<T1>::value,
00349                     ::boost::is_empty<T2>::value>::value> base;
00350 public:
00351    typedef T1                                                 first_type;
00352    typedef T2                                                 second_type;
00353    typedef typename call_traits<first_type>::param_type       first_param_type;
00354    typedef typename call_traits<second_type>::param_type      second_param_type;
00355    typedef typename call_traits<first_type>::reference        first_reference;
00356    typedef typename call_traits<second_type>::reference       second_reference;
00357    typedef typename call_traits<first_type>::const_reference  first_const_reference;
00358    typedef typename call_traits<second_type>::const_reference second_const_reference;
00359 
00360             compressed_pair() : base() {}
00361             compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
00362    explicit compressed_pair(first_param_type x) : base(x) {}
00363    explicit compressed_pair(second_param_type y) : base(y) {}
00364 
00365    first_reference       first()       {return base::first();}
00366    first_const_reference first() const {return base::first();}
00367 
00368    second_reference       second()       {return base::second();}
00369    second_const_reference second() const {return base::second();}
00370 
00371    void swap(compressed_pair& y) { base::swap(y); }
00372 };
00373 
00374 // JM
00375 // Partial specialisation for case where T1 == T2:
00376 //
00377 template <class T>
00378 class compressed_pair<T, T>
00379    : private details::compressed_pair_imp<T, T,
00380              ::boost::details::compressed_pair_switch<
00381                     T,
00382                     T,
00383                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
00384                     ::boost::is_empty<T>::value,
00385                     ::boost::is_empty<T>::value>::value>
00386 {
00387 private:
00388    typedef details::compressed_pair_imp<T, T,
00389              ::boost::details::compressed_pair_switch<
00390                     T,
00391                     T,
00392                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
00393                     ::boost::is_empty<T>::value,
00394                     ::boost::is_empty<T>::value>::value> base;
00395 public:
00396    typedef T                                                  first_type;
00397    typedef T                                                  second_type;
00398    typedef typename call_traits<first_type>::param_type       first_param_type;
00399    typedef typename call_traits<second_type>::param_type      second_param_type;
00400    typedef typename call_traits<first_type>::reference        first_reference;
00401    typedef typename call_traits<second_type>::reference       second_reference;
00402    typedef typename call_traits<first_type>::const_reference  first_const_reference;
00403    typedef typename call_traits<second_type>::const_reference second_const_reference;
00404 
00405             compressed_pair() : base() {}
00406             compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
00407 #if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))
00408    explicit 
00409 #endif
00410       compressed_pair(first_param_type x) : base(x) {}
00411 
00412    first_reference       first()       {return base::first();}
00413    first_const_reference first() const {return base::first();}
00414 
00415    second_reference       second()       {return base::second();}
00416    second_const_reference second() const {return base::second();}
00417 
00418    void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }
00419 };
00420 
00421 template <class T1, class T2>
00422 inline
00423 void
00424 swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
00425 {
00426    x.swap(y);
00427 }
00428 
00429 } // boost
00430 
00431 #endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
00432 

Generated on Wed Jan 21 15:32:09 2009 for SystemC by  doxygen 1.5.5