diff --git a/include/boost/iostreams/detail/closer.hpp b/include/boost/iostreams/detail/closer.hpp index 7fde2f8..1059d25 100755 --- a/include/boost/iostreams/detail/closer.hpp +++ b/include/boost/iostreams/detail/closer.hpp @@ -9,11 +9,13 @@ #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once -#endif +#endif #include // exception. #include // openmode. -#include // close. +#include // close +#include // is_device. +#include namespace boost { namespace iostreams { namespace detail { @@ -24,19 +26,62 @@ struct closer { T* t_; }; -template -struct external_closer { - external_closer(T& t, BOOST_IOS::openmode mode) - : t_(&t), mode_(mode) +template +struct external_device_closer { + external_device_closer(Device& dev, BOOST_IOS::openmode which) + : device_(&dev), which_(which) { } - ~external_closer() + ~external_device_closer() { try { - boost::iostreams::close(*t_, mode_); + boost::iostreams::close(*device_, which_); } catch (std::exception&) { } } - T* t_; - BOOST_IOS::openmode mode_; + Device* device_; + BOOST_IOS::openmode which_; +}; + +template +struct external_filter_closer { + external_filter_closer(Filter& flt, Device& dev, BOOST_IOS::openmode which) + : device_(&dev), which_(which) + { } + ~external_filter_closer() + { + try { + boost::iostreams::close(*filter_, *device_, which_); + } catch (std::exception&) { } + } + Filter* filter_; + Device* device_; + BOOST_IOS::openmode which_; +}; + +template +struct external_closer_traits { + typedef typename + mpl::if_< + is_device, + external_device_closer, + external_filter_closer + >::type type; +}; + +template +struct external_closer + : external_closer_traits::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::value); }; + external_closer( FilterOrDevice& flt, DeviceOrDummy& dev, + BOOST_IOS::openmode which ) + : base_type(flt, dev, which) + { BOOST_STATIC_ASSERT(is_filter::value); }; }; } } } // End namespaces detail, iostreams, boost.