Chris@16
|
1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
|
Chris@16
|
2 // (C) Copyright 2003-2007 Jonathan Turkanis
|
Chris@16
|
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
|
Chris@16
|
5
|
Chris@16
|
6 // See http://www.boost.org/libs/iostreams for documentation.
|
Chris@16
|
7
|
Chris@16
|
8 #ifndef BOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED
|
Chris@16
|
9 #define BOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED
|
Chris@16
|
10
|
Chris@16
|
11 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
Chris@16
|
12 # pragma once
|
Chris@16
|
13 #endif
|
Chris@16
|
14
|
Chris@16
|
15 #include <boost/config.hpp> // SFINAE, MSVC.
|
Chris@16
|
16 #include <boost/detail/workaround.hpp>
|
Chris@16
|
17 #include <boost/iostreams/detail/enable_if_stream.hpp>
|
Chris@16
|
18 #include <boost/iostreams/traits_fwd.hpp> // is_std_io.
|
Chris@16
|
19 #include <boost/mpl/bool.hpp>
|
Chris@16
|
20 #include <boost/mpl/identity.hpp>
|
Chris@16
|
21 #include <boost/mpl/eval_if.hpp>
|
Chris@16
|
22 #include <boost/mpl/if.hpp>
|
Chris@16
|
23 #include <boost/ref.hpp>
|
Chris@16
|
24
|
Chris@16
|
25 namespace boost { namespace iostreams { namespace detail {
|
Chris@16
|
26
|
Chris@16
|
27 //------------------Definition of wrap/unwrap traits--------------------------//
|
Chris@16
|
28
|
Chris@16
|
29 template<typename T>
|
Chris@16
|
30 struct wrapped_type
|
Chris@16
|
31 : mpl::if_<is_std_io<T>, reference_wrapper<T>, T>
|
Chris@16
|
32 { };
|
Chris@16
|
33
|
Chris@16
|
34 template<typename T>
|
Chris@16
|
35 struct unwrapped_type
|
Chris@16
|
36 : unwrap_reference<T>
|
Chris@16
|
37 { };
|
Chris@16
|
38
|
Chris@16
|
39 template<typename T>
|
Chris@16
|
40 struct unwrap_ios
|
Chris@16
|
41 : mpl::eval_if<
|
Chris@16
|
42 is_std_io<T>,
|
Chris@16
|
43 unwrap_reference<T>,
|
Chris@16
|
44 mpl::identity<T>
|
Chris@16
|
45 >
|
Chris@16
|
46 { };
|
Chris@16
|
47
|
Chris@16
|
48 //------------------Definition of wrap----------------------------------------//
|
Chris@16
|
49
|
Chris@16
|
50 #ifndef BOOST_NO_SFINAE //----------------------------------------------------//
|
Chris@16
|
51 template<typename T>
|
Chris@16
|
52 inline T wrap(const T& t BOOST_IOSTREAMS_DISABLE_IF_STREAM(T))
|
Chris@16
|
53 { return t; }
|
Chris@16
|
54
|
Chris@16
|
55 template<typename T>
|
Chris@16
|
56 inline typename wrapped_type<T>::type
|
Chris@16
|
57 wrap(T& t BOOST_IOSTREAMS_ENABLE_IF_STREAM(T)) { return boost::ref(t); }
|
Chris@16
|
58 #else // #ifndef BOOST_NO_SFINAE //-------------------------------------------//
|
Chris@16
|
59 template<typename T>
|
Chris@16
|
60 inline typename wrapped_type<T>::type // BCC 5.x needs namespace qualification.
|
Chris@16
|
61 wrap_impl(const T& t, mpl::true_) { return boost::ref(const_cast<T&>(t)); }
|
Chris@16
|
62
|
Chris@16
|
63 template<typename T>
|
Chris@16
|
64 inline typename wrapped_type<T>::type // BCC 5.x needs namespace qualification.
|
Chris@16
|
65 wrap_impl(T& t, mpl::true_) { return boost::ref(t); }
|
Chris@16
|
66
|
Chris@16
|
67 template<typename T>
|
Chris@16
|
68 inline typename wrapped_type<T>::type
|
Chris@16
|
69 wrap_impl(const T& t, mpl::false_) { return t; }
|
Chris@16
|
70
|
Chris@16
|
71 template<typename T>
|
Chris@16
|
72 inline typename wrapped_type<T>::type
|
Chris@16
|
73 wrap_impl(T& t, mpl::false_) { return t; }
|
Chris@16
|
74
|
Chris@16
|
75 template<typename T>
|
Chris@16
|
76 inline typename wrapped_type<T>::type
|
Chris@16
|
77 wrap(const T& t) { return wrap_impl(t, is_std_io<T>()); }
|
Chris@16
|
78
|
Chris@16
|
79 template<typename T>
|
Chris@16
|
80 inline typename wrapped_type<T>::type
|
Chris@16
|
81 wrap(T& t) { return wrap_impl(t, is_std_io<T>()); }
|
Chris@16
|
82 #endif // #ifndef BOOST_NO_SFINAE //------------------------------------------//
|
Chris@16
|
83
|
Chris@16
|
84 //------------------Definition of unwrap--------------------------------------//
|
Chris@16
|
85
|
Chris@16
|
86 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) //----------------------------------//
|
Chris@16
|
87
|
Chris@16
|
88 template<typename T>
|
Chris@16
|
89 typename unwrapped_type<T>::type&
|
Chris@16
|
90 unwrap(const reference_wrapper<T>& ref) { return ref.get(); }
|
Chris@16
|
91
|
Chris@16
|
92 template<typename T>
|
Chris@16
|
93 typename unwrapped_type<T>::type& unwrap(T& t) { return t; }
|
Chris@16
|
94
|
Chris@16
|
95 template<typename T>
|
Chris@16
|
96 const typename unwrapped_type<T>::type& unwrap(const T& t) { return t; }
|
Chris@16
|
97
|
Chris@16
|
98 #else // #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) //-------------------------//
|
Chris@16
|
99
|
Chris@16
|
100 // Since unwrap is a potential bottleneck, we avoid runtime tag dispatch.
|
Chris@16
|
101 template<bool IsRefWrap>
|
Chris@16
|
102 struct unwrap_impl;
|
Chris@16
|
103
|
Chris@16
|
104 template<>
|
Chris@16
|
105 struct unwrap_impl<true> {
|
Chris@16
|
106 template<typename T>
|
Chris@16
|
107 static typename unwrapped_type<T>::type& unwrap(const T& t)
|
Chris@16
|
108 { return t.get(); }
|
Chris@16
|
109 };
|
Chris@16
|
110
|
Chris@16
|
111 template<>
|
Chris@16
|
112 struct unwrap_impl<false> {
|
Chris@16
|
113 template<typename T>
|
Chris@16
|
114 static typename unwrapped_type<T>::type& unwrap(const T& t)
|
Chris@16
|
115 { return const_cast<T&>(t); }
|
Chris@16
|
116 };
|
Chris@16
|
117
|
Chris@16
|
118 template<typename T>
|
Chris@16
|
119 typename unwrapped_type<T>::type&
|
Chris@16
|
120 unwrap(const T& t)
|
Chris@16
|
121 { return unwrap_impl<is_reference_wrapper<T>::value>::unwrap(t); }
|
Chris@16
|
122
|
Chris@16
|
123 #endif // #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) //------------------------//
|
Chris@16
|
124
|
Chris@16
|
125 } } } // End namespaces detail, iostreams, boost.
|
Chris@16
|
126
|
Chris@16
|
127 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED
|