boost/iostreams/detail/closer.hpp
// (C) Copyright Jonathan Turkanis 2003. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) // See http://www.boost.org/libs/iostreams for documentation. #ifndef BOOST_IOSTREAMS_DETAIL_CLOSER_HPP_INCLUDED #define BOOST_IOSTREAMS_DETAIL_CLOSER_HPP_INCLUDED #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include <exception> // exception. #include <boost/iostreams/detail/ios.hpp> // openmode. #include <boost/iostreams/operations.hpp> // close #include <boost/iostreams/traits.hpp> // is_device. #include <boost/mpl/if.hpp> namespace boost { namespace iostreams { namespace detail { template<typename T> struct closer { closer(T& t) : t_(&t) { } ~closer() { try { t_->close(); } catch (std::exception&) { } } T* t_; }; template<typename Device> struct external_device_closer { external_device_closer(Device& dev, BOOST_IOS::openmode which) : device_(&dev), which_(which), dummy_(true), nothrow_(dummy_) { } external_device_closer(Device& dev, BOOST_IOS::openmode which, bool& nothrow) : device_(&dev), which_(which), dummy_(true), nothrow_(nothrow) { } ~external_device_closer() { try { boost::iostreams::close(*device_, which_); } catch (...) { if (!nothrow_) { nothrow_ = true; throw; } } } Device* device_; BOOST_IOS::openmode which_; bool dummy_; bool& nothrow_; }; template<typename Filter, typename Device> struct external_filter_closer { external_filter_closer(Filter& flt, Device& dev, BOOST_IOS::openmode which) : filter_(flt), device_(dev), which_(which), dummy_(true), nothrow_(dummy_) { } external_filter_closer( Filter& flt, Device& dev, BOOST_IOS::openmode which, bool& nothrow ) : filter_(flt), device_(dev), which_(which), dummy_(true), nothrow_(nothrow) { } ~external_filter_closer() { try { boost::iostreams::close(filter_, device_, which_); } catch (...) { if (!nothrow_) { nothrow_ = true; throw; } } } Filter& filter_; Device& device_; BOOST_IOS::openmode which_; bool dummy_; bool& nothrow_; }; template<typename FilterOrDevice, typename DeviceOrDummy = int> struct external_closer_traits { typedef typename mpl::if_< is_device<FilterOrDevice>, external_device_closer<FilterOrDevice>, external_filter_closer<FilterOrDevice, DeviceOrDummy> >::type type; }; template<typename FilterOrDevice, typename DeviceOrDummy = int> struct external_closer : external_closer_traits<FilterOrDevice, DeviceOrDummy>::type { typedef typename external_closer_traits< FilterOrDevice, DeviceOrDummy >::type base_type; external_closer(FilterOrDevice& dev, BOOST_IOS::openmode which) : base_type(dev, which) { BOOST_STATIC_ASSERT(is_device<FilterOrDevice>::value); }; external_closer( FilterOrDevice& dev, BOOST_IOS::openmode which, bool& nothrow ) : base_type(dev, which, nothrow) { BOOST_STATIC_ASSERT(is_device<FilterOrDevice>::value); }; external_closer( FilterOrDevice& flt, DeviceOrDummy& dev, BOOST_IOS::openmode which ) : base_type(flt, dev, which) { BOOST_STATIC_ASSERT(is_filter<FilterOrDevice>::value); }; external_closer( FilterOrDevice& flt, DeviceOrDummy& dev, BOOST_IOS::openmode which, bool& nothrow ) : base_type(flt, dev, which, nothrow) { BOOST_STATIC_ASSERT(is_filter<FilterOrDevice>::value); }; }; } } } // End namespaces detail, iostreams, boost. #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CLOSER_HPP_INCLUDED