source: NonGTP/Boost/boost/iostreams/close.hpp @ 857

Revision 857, 4.5 KB checked in by igarcia, 18 years ago (diff)
Line 
1// (C) Copyright Jonathan Turkanis 2003.
2// Distributed under the Boost Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
4
5// See http://www.boost.org/libs/iostreams for documentation.
6
7#ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
8#define BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
9
10#if defined(_MSC_VER) && (_MSC_VER >= 1020)
11# pragma once
12#endif
13
14#include <boost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
15#include <boost/detail/workaround.hpp>
16#include <boost/iostreams/categories.hpp>
17#include <boost/iostreams/flush.hpp>
18#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
19#include <boost/iostreams/detail/wrap_unwrap.hpp>
20#include <boost/iostreams/operations_fwd.hpp>
21#include <boost/iostreams/traits.hpp>
22#include <boost/mpl/identity.hpp>
23#include <boost/mpl/if.hpp>
24#include <boost/type_traits/is_convertible.hpp>
25
26// Must come last.
27#include <boost/iostreams/detail/config/disable_warnings.hpp>
28
29#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------//
30# include <boost/iostreams/detail/vc6/close.hpp>
31#else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------//
32
33namespace boost { namespace iostreams {
34
35namespace detail {
36
37template<typename T>
38struct close_impl;
39
40} // End namespace detail.
41
42template<typename T>
43void close(T& t, BOOST_IOS::openmode which)
44{ detail::close_impl<T>::close(detail::unwrap(t), which); }
45
46template<typename T, typename Sink>
47void close(T& t, Sink& snk, BOOST_IOS::openmode which)
48{ detail::close_impl<T>::close(detail::unwrap(t), snk, which); }
49
50namespace detail {
51
52//------------------Definition of close_impl----------------------------------//
53
54template<typename T>
55struct close_tag {
56    typedef typename category_of<T>::type category;
57    typedef typename
58            mpl::eval_if<
59                is_convertible<category, closable_tag>,
60                mpl::if_<
61                    mpl::or_<
62                        is_convertible<category, two_sequence>,
63                        is_convertible<category, dual_use>
64                    >,
65                    two_sequence,
66                    closable_tag
67                >,
68                mpl::identity<any_tag>
69            >::type type;
70};
71
72template<typename T>
73struct close_impl
74    : mpl::if_<
75          is_custom<T>,
76          operations<T>,
77          close_impl<BOOST_DEDUCED_TYPENAME close_tag<T>::type>
78      >::type
79    { };
80
81template<>
82struct close_impl<any_tag> {
83    template<typename T>
84    static void close(T& t, BOOST_IOS::openmode which)
85    {
86        if ((which & BOOST_IOS::out) != 0)
87            iostreams::flush(t);
88    }
89
90    template<typename T, typename Sink>
91    static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
92    {
93        if ((which & BOOST_IOS::out) != 0) {
94            non_blocking_adapter<Sink> nb(snk);
95            iostreams::flush(t, nb);
96        }
97    }
98};
99
100#include <boost/iostreams/detail/config/disable_warnings.hpp> // Borland.
101template<>
102struct close_impl<closable_tag> {
103    template<typename T>
104    static void close(T& t, BOOST_IOS::openmode which)
105    {
106        typedef typename category_of<T>::type category;
107        const bool in =  is_convertible<category, input>::value &&
108                        !is_convertible<category, output>::value;
109        if (in == ((which & BOOST_IOS::in) != 0))
110            t.close();
111    }
112    template<typename T, typename Sink>
113    static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
114    {
115        typedef typename category_of<T>::type category;
116        const bool in =  is_convertible<category, input>::value &&
117                        !is_convertible<category, output>::value;
118        if (in == ((which & BOOST_IOS::in) != 0)) {
119            non_blocking_adapter<Sink> nb(snk);
120            t.close(nb);
121        }
122    }
123};
124
125template<>
126struct close_impl<two_sequence> {
127    template<typename T>
128    static void close(T& t, BOOST_IOS::openmode which) { t.close(which); }
129    template<typename T, typename Sink>
130    static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
131    {
132        non_blocking_adapter<Sink> nb(snk);
133        t.close(nb, which);
134    }
135};
136
137} // End namespace detail.
138
139} } // End namespaces iostreams, boost.
140
141#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------//
142
143#include <boost/iostreams/detail/config/enable_warnings.hpp>
144
145#endif // #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.