source: NonGTP/Boost/boost/iostreams/detail/closer.hpp @ 857

Revision 857, 4.2 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_DETAIL_CLOSER_HPP_INCLUDED
8#define BOOST_IOSTREAMS_DETAIL_CLOSER_HPP_INCLUDED
9
10#if defined(_MSC_VER) && (_MSC_VER >= 1020)
11# pragma once
12#endif
13
14#include <exception>                       // exception.
15#include <boost/iostreams/detail/ios.hpp>  // openmode.
16#include <boost/iostreams/operations.hpp>  // close
17#include <boost/iostreams/traits.hpp>      // is_device.
18#include <boost/mpl/if.hpp>
19
20namespace boost { namespace iostreams { namespace detail {
21
22template<typename T>
23struct closer {
24    closer(T& t) : t_(&t) { }
25    ~closer() { try { t_->close(); } catch (std::exception&) { } }
26    T* t_;
27};
28
29template<typename Device>
30struct external_device_closer {
31    external_device_closer(Device& dev, BOOST_IOS::openmode which)
32        : device_(&dev), which_(which),
33          dummy_(true), nothrow_(dummy_)
34        { }
35    external_device_closer(Device& dev, BOOST_IOS::openmode which, bool& nothrow)
36        : device_(&dev), which_(which),
37          dummy_(true), nothrow_(nothrow)
38        { }
39    ~external_device_closer()
40    {
41        try {
42            boost::iostreams::close(*device_, which_);
43        } catch (...) {
44            if (!nothrow_) {
45                nothrow_ = true;
46                throw;
47            }
48        }
49    }
50    Device*               device_;
51    BOOST_IOS::openmode   which_;
52    bool                  dummy_;
53    bool&                 nothrow_;
54};
55
56template<typename Filter, typename Device>
57struct external_filter_closer {
58    external_filter_closer(Filter& flt, Device& dev, BOOST_IOS::openmode which)
59        : filter_(flt), device_(dev), which_(which),
60          dummy_(true), nothrow_(dummy_)
61        { }
62    external_filter_closer( Filter& flt, Device& dev,
63                            BOOST_IOS::openmode which, bool& nothrow )
64        : filter_(flt), device_(dev), which_(which),
65          dummy_(true), nothrow_(nothrow)
66        { }
67    ~external_filter_closer()
68    {
69        try {
70            boost::iostreams::close(filter_, device_, which_);
71        } catch (...) {
72            if (!nothrow_) {
73                nothrow_ = true;
74                throw;
75            }
76        }
77    }
78    Filter&               filter_;
79    Device&               device_;
80    BOOST_IOS::openmode   which_;
81    bool                  dummy_;
82    bool&                 nothrow_;
83};
84
85template<typename FilterOrDevice, typename DeviceOrDummy = int>
86struct external_closer_traits {
87    typedef typename
88            mpl::if_<
89                is_device<FilterOrDevice>,
90                external_device_closer<FilterOrDevice>,
91                external_filter_closer<FilterOrDevice, DeviceOrDummy>
92            >::type type;
93};
94
95template<typename FilterOrDevice, typename DeviceOrDummy = int>
96struct external_closer
97    : external_closer_traits<FilterOrDevice, DeviceOrDummy>::type
98{
99    typedef typename
100            external_closer_traits<
101                FilterOrDevice, DeviceOrDummy
102            >::type base_type;
103    external_closer(FilterOrDevice& dev, BOOST_IOS::openmode which)
104        : base_type(dev, which)
105    { BOOST_STATIC_ASSERT(is_device<FilterOrDevice>::value); };
106    external_closer( FilterOrDevice& dev, BOOST_IOS::openmode which,
107                     bool& nothrow )
108        : base_type(dev, which, nothrow)
109    { BOOST_STATIC_ASSERT(is_device<FilterOrDevice>::value); };
110    external_closer( FilterOrDevice& flt, DeviceOrDummy& dev,
111                     BOOST_IOS::openmode which )
112        : base_type(flt, dev, which)
113    { BOOST_STATIC_ASSERT(is_filter<FilterOrDevice>::value); };
114    external_closer( FilterOrDevice& flt, DeviceOrDummy& dev,
115                     BOOST_IOS::openmode which, bool& nothrow )
116        : base_type(flt, dev, which, nothrow)
117    { BOOST_STATIC_ASSERT(is_filter<FilterOrDevice>::value); };
118};
119
120} } } // End namespaces detail, iostreams, boost.
121
122#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CLOSER_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.