1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2 // (C) Copyright 2004-2007 Jonathan Turkanis
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
5 
6 // See http://www.boost.org/libs/iostreams for documentation.
7 
8 // Contains the definition of the class template
9 // boost::iostreams::detail::double_object, which is similar to compressed pair
10 // except that both members of the pair have the same type, and
11 // compression occurs only if requested using a boolean template
12 // parameter.
13 
14 #ifndef BOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED
15 #define BOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED
16 
17 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
18 # pragma once
19 #endif
20 
21 #include <algorithm>              // swap.
22 #include <boost/detail/workaround.hpp>
23 #include <boost/mpl/if.hpp>
24 #if BOOST_WORKAROUND(__MWERKS__, > 0x3003)
25 # include <msl_utility>
26 #else
27 # include <boost/call_traits.hpp>
28 #endif
29 
30 namespace boost { namespace iostreams { namespace detail {
31 
32 template<typename T>
33 class single_object_holder {
34 public:
35 #if BOOST_WORKAROUND(__MWERKS__, > 0x3003)
36     typedef Metrowerks::call_traits<T>             traits_type;
37 #else
38     typedef boost::call_traits<T>                  traits_type;
39 #endif
40     typedef typename traits_type::param_type       param_type;
41     typedef typename traits_type::reference        reference;
42     typedef typename traits_type::const_reference  const_reference;
single_object_holder()43     single_object_holder() { }
single_object_holder(param_type t)44     single_object_holder(param_type t) : first_(t) { }
first()45     reference first() { return first_; }
first() const46     const_reference first() const { return first_; }
second()47     reference second() { return first_; }
second() const48     const_reference second() const { return first_; }
swap(single_object_holder & o)49     void swap(single_object_holder& o)
50     { std::swap(first_, o.first_); }
51 private:
52     T first_;
53 };
54 
55 template<typename T>
56 struct double_object_holder {
57 public:
58 #if BOOST_WORKAROUND(__MWERKS__, > 0x3003)
59     typedef Metrowerks::call_traits<T>             traits_type;
60 #else
61     typedef boost::call_traits<T>                  traits_type;
62 #endif
63     typedef typename traits_type::param_type       param_type;
64     typedef typename traits_type::reference        reference;
65     typedef typename traits_type::const_reference  const_reference;
double_object_holderboost::iostreams::detail::double_object_holder66     double_object_holder() { }
double_object_holderboost::iostreams::detail::double_object_holder67     double_object_holder(param_type t1, param_type t2)
68         : first_(t1), second_(t2) { }
firstboost::iostreams::detail::double_object_holder69     reference first() { return first_; }
firstboost::iostreams::detail::double_object_holder70     const_reference first() const { return first_; }
secondboost::iostreams::detail::double_object_holder71     reference second() { return second_; }
secondboost::iostreams::detail::double_object_holder72     const_reference second() const { return second_; }
swapboost::iostreams::detail::double_object_holder73     void swap(double_object_holder& d)
74     {
75         std::swap(first_, d.first_);
76         std::swap(second_, d.second_);
77     }
78 private:
79     T first_, second_;
80 };
81 
82 template<typename T, typename IsDouble>
83 class double_object
84     : public mpl::if_<
85                  IsDouble,
86                  double_object_holder<T>,
87                  single_object_holder<T>
88              >::type
89 {
90 private:
91     typedef typename
92             mpl::if_<
93                 IsDouble,
94                 double_object_holder<T>,
95                 single_object_holder<T>
96             >::type                                base_type;
97 public:
98 #if BOOST_WORKAROUND(__MWERKS__, > 0x3003)
99     typedef Metrowerks::call_traits<T>             traits_type;
100 #else
101     typedef boost::call_traits<T>                  traits_type;
102 #endif
103     typedef typename traits_type::param_type       param_type;
104     typedef typename traits_type::reference        reference;
105     typedef typename traits_type::const_reference  const_reference;
double_object()106     double_object() : base_type() {}
double_object(param_type t1,param_type t2)107     double_object(param_type t1, param_type t2)
108         : base_type(t1, t2) { }
is_double() const109     bool is_double() const { return IsDouble::value; }
110 };
111 
112 } } } // End namespaces detail, iostreams, boost.
113 
114 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED
115