1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) 2 // (C) Copyright 2003-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 #ifndef BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED 9 #define BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED 10 11 #include <boost/iostreams/detail/broken_overload_resolution/forward.hpp> 12 #include <boost/throw_exception.hpp> 13 14 namespace boost { namespace iostreams { 15 16 template< typename T, 17 typename Tr = 18 BOOST_IOSTREAMS_CHAR_TRAITS( 19 BOOST_DEDUCED_TYPENAME char_type_of<T>::type 20 ), 21 typename Alloc = 22 std::allocator< 23 BOOST_DEDUCED_TYPENAME char_type_of<T>::type 24 >, 25 typename Mode = BOOST_DEDUCED_TYPENAME mode_of<T>::type > 26 class stream_buffer 27 : public detail::stream_buffer_traits<T, Tr, Alloc, Mode>::type 28 { 29 private: 30 BOOST_STATIC_ASSERT(( 31 is_convertible< 32 BOOST_DEDUCED_TYPENAME iostreams::category_of<T>::type, Mode 33 >::value 34 )); 35 typedef typename 36 detail::stream_buffer_traits< 37 T, Tr, Alloc, Mode 38 >::type base_type; 39 public: 40 typedef typename char_type_of<T>::type char_type; 41 struct category 42 : Mode, 43 closable_tag, 44 streambuf_tag 45 { }; 46 BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) stream_buffer()47 stream_buffer() { } ~stream_buffer()48 ~stream_buffer() 49 { 50 try { 51 if (this->is_open() && this->auto_close()) 52 this->close(); 53 } catch (...) { } 54 } 55 template<typename U0> stream_buffer(const U0 & u0)56 stream_buffer(const U0& u0) 57 { 58 open_impl(detail::forward<T, U0>(), u0); 59 } 60 template<typename U0, typename U1> stream_buffer(const U0 & u0,const U1 & u1)61 stream_buffer(const U0& u0, const U1& u1) 62 { 63 open_impl(detail::forward<T, U0>(), u0, u1); 64 } 65 template<typename U0, typename U1, typename U2> stream_buffer(const U0 & u0,const U1 & u1,const U2 & u2)66 stream_buffer(const U0& u0, const U1& u1, const U2& u2) 67 { 68 open_impl(detail::forward<T, U0>(), u0, u1, u2); 69 } 70 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// 71 template<typename U0> stream_buffer(U0 & u0)72 stream_buffer(U0& u0) 73 { 74 open_impl(detail::forward<T, U0>(), u0); 75 } 76 template<typename U0, typename U1> stream_buffer(U0 & u0,const U1 & u1)77 stream_buffer(U0& u0, const U1& u1) 78 { 79 open_impl(detail::forward<T, U0>(), u0, u1); 80 } 81 template<typename U0, typename U1, typename U2> stream_buffer(U0 & u0,const U1 & u1,const U2 & u2)82 stream_buffer(U0& u0, const U1& u1, const U2& u2) 83 { 84 open_impl(detail::forward<T, U0>(), u0, u1, u2); 85 } 86 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// 87 template<typename U0> open(const U0 & u0)88 void open(const U0& u0) 89 { 90 open_impl(detail::forward<T, U0>(), u0); 91 } 92 template<typename U0, typename U1> open(const U0 & u0,const U1 & u1)93 void open(const U0& u0, const U1& u1) 94 { 95 open_impl(detail::forward<T, U0>(), u0, u1); 96 } 97 template<typename U0, typename U1, typename U2> open(const U0 & u0,const U1 & u1,const U2 & u2)98 void open(const U0& u0, const U1& u1, const U2& u2) 99 { 100 open_impl(detail::forward<T, U0>(), u0, u1, u2); 101 } 102 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// 103 template<typename U0> open(U0 & u0)104 void open(U0& u0) 105 { 106 open_impl(detail::forward<T, U0>(), u0); 107 } 108 template<typename U0, typename U1> open(U0 & u0,const U1 & u1)109 void open(U0& u0, const U1& u1) 110 { 111 open_impl(detail::forward<T, U0>(), u0, u1); 112 } 113 template<typename U0, typename U1, typename U2> open(U0 & u0,const U1 & u1,const U2 & u2)114 void open(U0& u0, const U1& u1, const U2& u2) 115 { 116 open_impl(detail::forward<T, U0>(), u0, u1, u2); 117 } 118 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// operator *()119 T& operator*() { return *this->component(); } operator ->()120 T* operator->() { return this->component(); } 121 private: 122 template<typename U0> open_impl(mpl::false_,const U0 & u0)123 void open_impl(mpl::false_, const U0& u0) 124 { 125 base_type::open(const_cast<U0&>(u0), -1, -1); 126 } 127 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// 128 template<typename U0> open_impl(mpl::false_,U0 & u0)129 void open_impl(mpl::false_, U0& u0) 130 { 131 base_type::open(detail::wrap(u0), -1, -1); 132 } 133 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// 134 template<typename U0> open_impl(mpl::true_,const U0 & u0)135 void open_impl(mpl::true_, const U0& u0) 136 { 137 base_type::open(T(const_cast<U0&>(u0)), -1, -1); 138 } 139 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// 140 template<typename U0> open_impl(mpl::true_,U0 & u0)141 void open_impl(mpl::true_, U0& u0) 142 { 143 base_type::open(T(u0), -1, -1); 144 } 145 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// 146 template<typename U0, typename U1> open_impl(mpl::false_,const U0 & u0,const U1 & u1)147 void open_impl(mpl::false_, const U0& u0, const U1& u1) 148 { 149 base_type::open(u0, u1, -1); 150 } 151 template<typename U0, typename U1> open_impl(mpl::true_,const U0 & u0,const U1 & u1)152 void open_impl(mpl::true_, const U0& u0, const U1& u1) 153 { 154 base_type::open(T(const_cast<U0&>(u0), u1), -1, -1); 155 } 156 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// 157 template<typename U0, typename U1> open_impl(mpl::true_,U0 & u0,const U1 & u1)158 void open_impl(mpl::true_, U0& u0, const U1& u1) 159 { 160 base_type::open(T(u0, u1), -1, -1); 161 } 162 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// 163 template<typename U0, typename U1, typename U2> open_impl(mpl::false_,const U0 & u0,const U1 & u1,const U2 & u2)164 void open_impl(mpl::false_, const U0& u0, const U1& u1, const U2& u2) 165 { 166 base_type::open(u0, u1, u2); 167 } 168 template<typename U0, typename U1, typename U2> open_impl(mpl::true_,const U0 & u0,const U1 & u1,const U2 & u2)169 void open_impl(mpl::true_, const U0& u0, const U1& u1, const U2& u2) 170 { 171 base_type::open(T(const_cast<U0&>(u0), u1, u2), -1, -1); 172 } 173 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// 174 template<typename U0, typename U1, typename U2> open_impl(mpl::true_,U0 & u0,const U1 & u1,const U2 & u2)175 void open_impl(mpl::true_, U0& u0, const U1& u1, const U2& u2) 176 { 177 base_type::open(T(u0, u1, u2), -1, -1); 178 } 179 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// check_open()180 void check_open() 181 { 182 if (this->is_open()) 183 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("already open")); 184 } 185 }; 186 187 } } // End namespaces iostreams, boost. 188 189 #endif // BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED 190