Chris@16: /* Chris@16: * Distributed under the Boost Software License, Version 1.0.(See accompanying Chris@16: * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) Chris@16: * Chris@16: * See http://www.boost.org/libs/iostreams for documentation. Chris@16: Chris@16: * File: boost/iostreams/detail/execute.hpp Chris@16: * Date: Thu Dec 06 13:21:54 MST 2007 Chris@16: * Copyright: 2007-2008 CodeRage, LLC Chris@16: * Author: Jonathan Turkanis Chris@16: * Contact: turkanis at coderage dot com Chris@16: Chris@16: * Defines the overloaded function template Chris@16: * boost::iostreams::detail::execute_all() and the function template Chris@16: * boost::iostreams::detail::execute_foreach(). Chris@16: * Chris@16: * execute_all() invokes a primary operation and performs a sequence of cleanup Chris@16: * operations, returning the result of the primary operation if no exceptions Chris@16: * are thrown. If one of the operations throws an exception, performs the Chris@16: * remaining operations and rethrows the initial exception. Chris@16: * Chris@16: * execute_foreach() is a variant of std::foreach which invokes a function Chris@16: * object for each item in a sequence, catching all execptions and rethrowing Chris@16: * the first caught exception after the function object has been invoked on each Chris@16: * item. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED Chris@16: #define BOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1020) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include // MAX_EXECUTE_ARITY Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace iostreams { namespace detail { Chris@16: Chris@16: // Helper for class template execute_traits. Chris@16: template Chris@16: struct execute_traits_impl { Chris@16: typedef Result result_type; Chris@16: template Chris@16: static Result execute(Op op) { return op(); } Chris@16: }; Chris@16: Chris@16: // Specialization for void return. For simplicity, execute() returns int Chris@16: // for operations returning void. This could be avoided with additional work. Chris@16: template<> Chris@16: struct execute_traits_impl { Chris@16: typedef int result_type; Chris@16: template Chris@16: static int execute(Op op) { op(); return 0; } Chris@16: }; Chris@16: Chris@16: // Deduces the result type of Op and allows uniform treatment of operations Chris@16: // returning void and non-void. Chris@16: template< typename Op, Chris@16: typename Result = // VC6.5 workaround. Chris@16: #if !defined(BOOST_NO_RESULT_OF) && \ Chris@16: !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) Chris@16: typename boost::result_of::type Chris@16: #else Chris@16: BOOST_DEDUCED_TYPENAME Op::result_type Chris@16: #endif Chris@16: > Chris@16: struct execute_traits Chris@16: : execute_traits_impl Chris@16: { }; Chris@16: Chris@16: // Implementation with no cleanup operations. Chris@16: template Chris@16: typename execute_traits::result_type Chris@16: execute_all(Op op) Chris@16: { Chris@16: return execute_traits::execute(op); Chris@16: } Chris@16: Chris@16: // Implementation with one or more cleanup operations Chris@16: #define BOOST_PP_LOCAL_MACRO(n) \ Chris@16: template \ Chris@16: typename execute_traits::result_type \ Chris@16: execute_all(Op op, BOOST_PP_ENUM_BINARY_PARAMS(n, C, c)) \ Chris@16: { \ Chris@16: typename execute_traits::result_type r; \ Chris@16: try { \ Chris@16: r = boost::iostreams::detail::execute_all( \ Chris@16: op BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ Chris@16: BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(n), c) \ Chris@16: ); \ Chris@16: } catch (...) { \ Chris@16: try { \ Chris@16: BOOST_PP_CAT(c, BOOST_PP_DEC(n))(); \ Chris@16: } catch (...) { } \ Chris@16: throw; \ Chris@16: } \ Chris@16: BOOST_PP_CAT(c, BOOST_PP_DEC(n))(); \ Chris@16: return r; \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_PP_LOCAL_LIMITS (1, BOOST_IOSTREAMS_MAX_EXECUTE_ARITY) Chris@16: #include BOOST_PP_LOCAL_ITERATE() Chris@16: #undef BOOST_PP_LOCAL_MACRO Chris@16: Chris@16: template Chris@16: Op execute_foreach(InIt first, InIt last, Op op) Chris@16: { Chris@16: if (first == last) Chris@16: return op; Chris@16: try { Chris@16: op(*first); Chris@16: } catch (...) { Chris@16: try { Chris@16: ++first; Chris@16: boost::iostreams::detail::execute_foreach(first, last, op); Chris@16: } catch (...) { } Chris@16: throw; Chris@16: } Chris@16: ++first; Chris@16: return boost::iostreams::detail::execute_foreach(first, last, op); Chris@16: } Chris@16: Chris@16: } } } // End namespaces detail, iostreams, boost. Chris@16: Chris@16: #endif // #ifndef BOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED