PageRenderTime 29ms CodeModel.GetById 12ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/iostreams/close.hpp

http://hadesmem.googlecode.com/
C++ Header | 259 lines | 214 code | 38 blank | 7 comment | 27 complexity | 829df6d7246f1df7a07ffe9c1addc0c9 MD5 | raw file
  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_CLOSE_HPP_INCLUDED
  9#define BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
 10
 11#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 12# pragma once
 13#endif
 14
 15#include <boost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
 16#include <boost/detail/workaround.hpp>
 17#include <boost/iostreams/categories.hpp>
 18#include <boost/iostreams/flush.hpp>
 19#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
 20#include <boost/iostreams/detail/ios.hpp> // BOOST_IOS
 21#include <boost/iostreams/detail/select.hpp>
 22#include <boost/iostreams/detail/wrap_unwrap.hpp>
 23#include <boost/iostreams/operations_fwd.hpp>
 24#include <boost/iostreams/traits.hpp>
 25#include <boost/mpl/identity.hpp>
 26#include <boost/mpl/if.hpp>
 27#include <boost/type_traits/is_convertible.hpp>
 28#include <boost/type_traits/is_integral.hpp>
 29#include <boost/type_traits/remove_cv.hpp>
 30#include <boost/type_traits/remove_reference.hpp>
 31
 32// Must come last.
 33#include <boost/iostreams/detail/config/disable_warnings.hpp>
 34
 35namespace boost { namespace iostreams {
 36
 37template<typename T>
 38void close(T& t);
 39
 40template<typename T>
 41void close(T& t, BOOST_IOS::openmode which);
 42
 43template<typename T, typename Sink>
 44void close(T& t, Sink& snk, BOOST_IOS::openmode which);
 45    
 46namespace detail {
 47
 48template<typename T>
 49void close_all(T& t)
 50{ 
 51    try {
 52        boost::iostreams::close(t, BOOST_IOS::in);
 53    } catch (...) {
 54        try {
 55            boost::iostreams::close(t, BOOST_IOS::out);
 56        } catch (...) { }
 57        throw;
 58    }
 59    boost::iostreams::close(t, BOOST_IOS::out);
 60}
 61
 62template<typename T, typename Sink>
 63void close_all(T& t, Sink& snk)
 64{ 
 65    try {
 66        boost::iostreams::close(t, snk, BOOST_IOS::in);
 67    } catch (...) {
 68        try {
 69            boost::iostreams::close(t, snk, BOOST_IOS::out);
 70        } catch (...) { }
 71        throw;
 72    }
 73    boost::iostreams::close(t, snk, BOOST_IOS::out);
 74}
 75
 76} // End namespaces detail. 
 77
 78} } // End namespaces iostreams, boost.
 79
 80#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------//
 81# include <boost/iostreams/detail/vc6/close.hpp>
 82#else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------//
 83
 84namespace boost { namespace iostreams {
 85
 86namespace detail {
 87
 88template<typename T>
 89struct close_impl;
 90
 91} // End namespace detail.
 92
 93template<typename T>
 94void close(T& t) { detail::close_all(t); }
 95
 96template<typename T>
 97void close(T& t, BOOST_IOS::openmode which)
 98{ 
 99#ifdef BOOST_IOSTREAMS_STRICT
100    BOOST_ASSERT(which == BOOST_IOS::in || which == BOOST_IOS::out);
101#else
102    if (which == (BOOST_IOS::in | BOOST_IOS::out)) {
103        detail::close_all(t);
104        return;
105    }
106#endif
107    detail::close_impl<T>::close(detail::unwrap(t), which); 
108}
109
110template<typename T, typename Sink>
111void close(T& t, Sink& snk, BOOST_IOS::openmode which)
112{ 
113#ifdef BOOST_IOSTREAMS_STRICT
114    BOOST_ASSERT(which == BOOST_IOS::in || which == BOOST_IOS::out);
115#else
116    if (which == (BOOST_IOS::in | BOOST_IOS::out)) {
117        detail::close_all(t, snk);
118        return;
119    }
120#endif
121    detail::close_impl<T>::close(detail::unwrap(t), snk, which); 
122}
123
124namespace detail {
125
126//------------------Definition of close_impl----------------------------------//
127
128struct close_boost_stream { };
129struct close_filtering_stream { };
130
131template<typename T>
132struct close_tag {
133    typedef typename category_of<T>::type             category;
134    typedef typename detail::unwrapped_type<T>::type  unwrapped;
135    typedef typename
136            iostreams::select<
137                mpl::not_< is_convertible<category, closable_tag> >,
138                any_tag,
139                mpl::or_<
140                    is_boost_stream<unwrapped>,
141                    is_boost_stream_buffer<unwrapped>
142                >,
143                close_boost_stream,
144                mpl::or_<
145                    is_filtering_stream<unwrapped>,
146                    is_filtering_streambuf<unwrapped>
147                >,
148                close_filtering_stream,
149                mpl::or_<
150                    is_convertible<category, two_sequence>,
151                    is_convertible<category, dual_use>
152                >,
153                two_sequence,
154                else_,
155                closable_tag
156            >::type type;
157};
158
159template<typename T>
160struct close_impl
161    : mpl::if_<
162          is_custom<T>,
163          operations<T>,
164          close_impl<BOOST_DEDUCED_TYPENAME close_tag<T>::type>
165      >::type
166    { };
167
168template<>
169struct close_impl<any_tag> {
170    template<typename T>
171    static void close(T& t, BOOST_IOS::openmode which)
172    {
173        if (which == BOOST_IOS::out)
174            iostreams::flush(t);
175    }
176
177    template<typename T, typename Sink>
178    static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
179    {
180        if (which == BOOST_IOS::out) {
181            non_blocking_adapter<Sink> nb(snk);
182            iostreams::flush(t, nb);
183        }
184    }
185};
186
187template<>
188struct close_impl<close_boost_stream> {
189    template<typename T>
190    static void close(T& t)
191    {
192        t.close();
193    }
194    template<typename T>
195    static void close(T& t, BOOST_IOS::openmode which)
196    {
197        if (which == BOOST_IOS::out)
198            t.close();
199    }
200};
201
202template<>
203struct close_impl<close_filtering_stream> {
204    template<typename T>
205    static void close(T& t, BOOST_IOS::openmode which)
206    {
207        typedef typename category_of<T>::type category;
208        const bool in =  is_convertible<category, input>::value &&
209                        !is_convertible<category, output>::value;
210        if (in == (which == BOOST_IOS::in) && t.is_complete())
211            t.pop();
212    }
213};
214
215template<>
216struct close_impl<closable_tag> {
217    template<typename T>
218    static void close(T& t, BOOST_IOS::openmode which)
219    {
220        typedef typename category_of<T>::type category;
221        const bool in =  is_convertible<category, input>::value &&
222                        !is_convertible<category, output>::value;
223        if (in == (which == BOOST_IOS::in))
224            t.close();
225    }
226    template<typename T, typename Sink>
227    static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
228    {
229        typedef typename category_of<T>::type category;
230        const bool in =  is_convertible<category, input>::value &&
231                        !is_convertible<category, output>::value;
232        if (in == (which == BOOST_IOS::in)) {
233            non_blocking_adapter<Sink> nb(snk);
234            t.close(nb);
235        }
236    }
237};
238
239template<>
240struct close_impl<two_sequence> {
241    template<typename T>
242    static void close(T& t, BOOST_IOS::openmode which) { t.close(which); }
243    template<typename T, typename Sink>
244    static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
245    {
246        non_blocking_adapter<Sink> nb(snk);
247        t.close(nb, which);
248    }
249};
250
251} // End namespace detail.
252
253} } // End namespaces iostreams, boost.
254
255#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------//
256
257#include <boost/iostreams/detail/config/enable_warnings.hpp>
258
259#endif // #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED