src/sysc/packages/boost/detail/ob_compressed_pair.hpp

Go to the documentation of this file.
00001 //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
00002 //  Permission to copy, use, modify, sell and
00003 //  distribute this software is granted provided this copyright notice appears
00004 //  in all copies. This software is provided "as is" without express or implied
00005 //  warranty, and with no claim as to its suitability for any purpose.
00006 
00007 //  See http://www.boost.org for most recent version including documentation.
00008 //  see libs/utility/compressed_pair.hpp
00009 //
00010 /* Release notes:
00011    20 Jan 2001:
00012         Fixed obvious bugs (David Abrahams)
00013    07 Oct 2000:
00014       Added better single argument constructor support.
00015    03 Oct 2000:
00016       Added VC6 support (JM).
00017    23rd July 2000:
00018       Additional comments added. (JM)
00019    Jan 2000:
00020       Original version: this version crippled for use with crippled compilers
00021       - John Maddock Jan 2000.
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 // use member templates to emulate
00044 // partial specialisation.  Note that due to
00045 // problems with overload resolution with VC6
00046 // each of the compressed_pair versions that follow
00047 // have one template single-argument constructor
00048 // in place of two specific constructors:
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 // T1 != T2, both non-empty
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 // T1 != T2, T2 empty
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   // Total weirdness. If the assignment to _first is moved after
00173   // the call to the inherited operator=, then this breaks graph/test/graph.cpp
00174   // by way of iterator_adaptor.
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       // no need to swap empty base class:
00191       using std::swap;
00192       swap(_first, y._first);
00193    }
00194 };
00195 
00196 // T1 != T2, T1 empty
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       // no need to swap empty base class:
00240       using std::swap;
00241       swap(_second, y._second);
00242    }
00243 };
00244 
00245 // T1 != T2, both empty
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       // no need to swap empty base classes:
00278    }
00279 };
00280 
00281 // T1 == T2, and empty
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    // only one single argument constructor since T1 == T2
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       // no need to swap empty base classes:
00311    }
00312 };
00313 
00314 // T1 == T2, not empty
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    // only one single argument constructor since T1 == T2
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 } // namespace detail
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 // no partial specialisation, no member templates:
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    // can't define this in case T1 == T2:
00480    // explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
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 } // boost
00505 
00506 #endif // BOOST_OB_COMPRESSED_PAIR_HPP
00507 
00508 
00509 

Generated on Wed Apr 25 13:53:28 2007 for SystemC by  doxygen 1.5.1