Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:53

0001 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
0002 // (C) Copyright 2003-2007 Jonathan Turkanis
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
0005 
0006 // See http://www.boost.org/libs/iostreams for documentation.
0007 
0008 #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
0009 #define BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
0010 
0011 #if defined(_MSC_VER)
0012 # pragma once
0013 #endif
0014 
0015 #include <boost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
0016 #include <boost/detail/workaround.hpp>
0017 #include <boost/iostreams/categories.hpp>
0018 #include <boost/iostreams/flush.hpp>
0019 #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
0020 #include <boost/iostreams/detail/ios.hpp> // BOOST_IOS
0021 #include <boost/iostreams/detail/select.hpp>
0022 #include <boost/iostreams/detail/wrap_unwrap.hpp>
0023 #include <boost/iostreams/operations_fwd.hpp>
0024 #include <boost/iostreams/traits.hpp>
0025 #include <boost/mpl/identity.hpp>
0026 #include <boost/mpl/if.hpp>
0027 #include <boost/type_traits/is_convertible.hpp>
0028 #include <boost/type_traits/is_integral.hpp>
0029 #include <boost/type_traits/remove_cv.hpp>
0030 #include <boost/type_traits/remove_reference.hpp>
0031 
0032 // Must come last.
0033 #include <boost/iostreams/detail/config/disable_warnings.hpp>
0034 
0035 namespace boost { namespace iostreams {
0036 
0037 template<typename T>
0038 void close(T& t);
0039 
0040 template<typename T>
0041 void close(T& t, BOOST_IOS::openmode which);
0042 
0043 template<typename T, typename Sink>
0044 void close(T& t, Sink& snk, BOOST_IOS::openmode which);
0045     
0046 namespace detail {
0047 
0048 template<typename T>
0049 void close_all(T& t)
0050 { 
0051     try {
0052         boost::iostreams::close(t, BOOST_IOS::in);
0053     } catch (...) {
0054         try {
0055             boost::iostreams::close(t, BOOST_IOS::out);
0056         } catch (...) { }
0057         throw;
0058     }
0059     boost::iostreams::close(t, BOOST_IOS::out);
0060 }
0061 
0062 template<typename T, typename Sink>
0063 void close_all(T& t, Sink& snk)
0064 { 
0065     try {
0066         boost::iostreams::close(t, snk, BOOST_IOS::in);
0067     } catch (...) {
0068         try {
0069             boost::iostreams::close(t, snk, BOOST_IOS::out);
0070         } catch (...) { }
0071         throw;
0072     }
0073     boost::iostreams::close(t, snk, BOOST_IOS::out);
0074 }
0075 
0076 } // End namespace detail. 
0077 
0078 } } // End namespaces iostreams, boost.
0079 
0080 namespace boost { namespace iostreams {
0081 
0082 namespace detail {
0083 
0084 template<typename T>
0085 struct close_impl;
0086 
0087 } // End namespace detail.
0088 
0089 template<typename T>
0090 void close(T& t) { detail::close_all(t); }
0091 
0092 template<typename T>
0093 void close(T& t, BOOST_IOS::openmode which)
0094 { 
0095 #ifdef BOOST_IOSTREAMS_STRICT
0096     BOOST_ASSERT(which == BOOST_IOS::in || which == BOOST_IOS::out);
0097 #else
0098     if (which == (BOOST_IOS::in | BOOST_IOS::out)) {
0099         detail::close_all(t);
0100         return;
0101     }
0102 #endif
0103     detail::close_impl<T>::close(detail::unwrap(t), which); 
0104 }
0105 
0106 template<typename T, typename Sink>
0107 void close(T& t, Sink& snk, BOOST_IOS::openmode which)
0108 { 
0109 #ifdef BOOST_IOSTREAMS_STRICT
0110     BOOST_ASSERT(which == BOOST_IOS::in || which == BOOST_IOS::out);
0111 #else
0112     if (which == (BOOST_IOS::in | BOOST_IOS::out)) {
0113         detail::close_all(t, snk);
0114         return;
0115     }
0116 #endif
0117     detail::close_impl<T>::close(detail::unwrap(t), snk, which); 
0118 }
0119 
0120 namespace detail {
0121 
0122 //------------------Definition of close_impl----------------------------------//
0123 
0124 struct close_boost_stream { };
0125 struct close_filtering_stream { };
0126 
0127 template<typename T>
0128 struct close_tag {
0129     typedef typename category_of<T>::type             category;
0130     typedef typename detail::unwrapped_type<T>::type  unwrapped;
0131     typedef typename
0132             iostreams::select<
0133                 mpl::not_< is_convertible<category, closable_tag> >,
0134                 any_tag,
0135                 mpl::or_<
0136                     is_boost_stream<unwrapped>,
0137                     is_boost_stream_buffer<unwrapped>
0138                 >,
0139                 close_boost_stream,
0140                 mpl::or_<
0141                     is_filtering_stream<unwrapped>,
0142                     is_filtering_streambuf<unwrapped>
0143                 >,
0144                 close_filtering_stream,
0145                 mpl::or_<
0146                     is_convertible<category, two_sequence>,
0147                     is_convertible<category, dual_use>
0148                 >,
0149                 two_sequence,
0150                 else_,
0151                 closable_tag
0152             >::type type;
0153 };
0154 
0155 template<typename T>
0156 struct close_impl
0157     : mpl::if_<
0158           is_custom<T>,
0159           operations<T>,
0160           close_impl<BOOST_DEDUCED_TYPENAME close_tag<T>::type>
0161       >::type
0162     { };
0163 
0164 template<>
0165 struct close_impl<any_tag> {
0166     template<typename T>
0167     static void close(T& t, BOOST_IOS::openmode which)
0168     {
0169         if (which == BOOST_IOS::out)
0170             iostreams::flush(t);
0171     }
0172 
0173     template<typename T, typename Sink>
0174     static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
0175     {
0176         if (which == BOOST_IOS::out) {
0177             non_blocking_adapter<Sink> nb(snk);
0178             iostreams::flush(t, nb);
0179         }
0180     }
0181 };
0182 
0183 template<>
0184 struct close_impl<close_boost_stream> {
0185     template<typename T>
0186     static void close(T& t)
0187     {
0188         t.close();
0189     }
0190     template<typename T>
0191     static void close(T& t, BOOST_IOS::openmode which)
0192     {
0193         if (which == BOOST_IOS::out)
0194             t.close();
0195     }
0196 };
0197 
0198 template<>
0199 struct close_impl<close_filtering_stream> {
0200     template<typename T>
0201     static void close(T& t, BOOST_IOS::openmode which)
0202     {
0203         typedef typename category_of<T>::type category;
0204         const bool in =  is_convertible<category, input>::value &&
0205                         !is_convertible<category, output>::value;
0206         if (in == (which == BOOST_IOS::in) && t.is_complete())
0207             t.pop();
0208     }
0209 };
0210 
0211 template<>
0212 struct close_impl<closable_tag> {
0213     template<typename T>
0214     static void close(T& t, BOOST_IOS::openmode which)
0215     {
0216         typedef typename category_of<T>::type category;
0217         const bool in =  is_convertible<category, input>::value &&
0218                         !is_convertible<category, output>::value;
0219         if (in == (which == BOOST_IOS::in))
0220             t.close();
0221     }
0222     template<typename T, typename Sink>
0223     static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
0224     {
0225         typedef typename category_of<T>::type category;
0226         const bool in =  is_convertible<category, input>::value &&
0227                         !is_convertible<category, output>::value;
0228         if (in == (which == BOOST_IOS::in)) {
0229             non_blocking_adapter<Sink> nb(snk);
0230             t.close(nb);
0231         }
0232     }
0233 };
0234 
0235 template<>
0236 struct close_impl<two_sequence> {
0237     template<typename T>
0238     static void close(T& t, BOOST_IOS::openmode which) { t.close(which); }
0239     template<typename T, typename Sink>
0240     static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
0241     {
0242         non_blocking_adapter<Sink> nb(snk);
0243         t.close(nb, which);
0244     }
0245 };
0246 
0247 } // End namespace detail.
0248 
0249 } } // End namespaces iostreams, boost.
0250 
0251 #include <boost/iostreams/detail/config/enable_warnings.hpp>
0252 
0253 #endif // #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED