| // Copyright (c) 2016 Klemens D. Morgenstern |
| // |
| // 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) |
| |
| #ifndef BOOST_PROCESS_DETAIL_USED_HANDLES_HPP_ |
| #define BOOST_PROCESS_DETAIL_USED_HANDLES_HPP_ |
| |
| #include <type_traits> |
| #include <boost/fusion/include/filter_if.hpp> |
| #include <boost/fusion/include/for_each.hpp> |
| |
| #if defined(BOOST_POSIX_API) |
| #include <boost/process/detail/posix/handles.hpp> |
| #include <boost/process/detail/posix/asio_fwd.hpp> |
| #else |
| #include <boost/process/detail/windows/handles.hpp> |
| #include <boost/process/detail/windows/asio_fwd.hpp> |
| #endif |
| |
| namespace boost { namespace process { namespace detail { |
| |
| struct uses_handles |
| { |
| //If you get an error here, you must add a `get_handles` function that returns a range or a single handle value |
| void get_used_handles() const; |
| }; |
| |
| template<typename T> |
| struct does_use_handle: std::is_base_of<uses_handles, T> {}; |
| |
| template<typename T> |
| struct does_use_handle<T&> : std::is_base_of<uses_handles, T> {}; |
| |
| template<typename T> |
| struct does_use_handle<const T&> : std::is_base_of<uses_handles, T> {}; |
| |
| template<typename Char, typename Sequence> |
| class executor; |
| |
| template<typename Func> |
| struct foreach_handle_invocator |
| { |
| Func & func; |
| foreach_handle_invocator(Func & func) : func(func) {} |
| |
| |
| template<typename Range> |
| void invoke(const Range & range) const |
| { |
| for (auto handle_ : range) |
| func(handle_); |
| |
| } |
| void invoke(::boost::process::detail::api::native_handle_type handle) const {func(handle);}; |
| |
| template<typename T> |
| void operator()(T & val) const {invoke(val.get_used_handles());} |
| }; |
| |
| template<typename Executor, typename Function> |
| void foreach_used_handle(Executor &exec, Function &&func) |
| { |
| boost::fusion::for_each(boost::fusion::filter_if<does_use_handle<boost::mpl::_>>(exec.seq), |
| foreach_handle_invocator<Function>(func)); |
| } |
| |
| template<typename Executor> |
| std::vector<::boost::process::detail::api::native_handle_type> |
| get_used_handles(Executor &exec) |
| { |
| std::vector<::boost::process::detail::api::native_handle_type> res; |
| foreach_used_handle(exec, [&](::boost::process::detail::api::native_handle_type handle){res.push_back(handle);}); |
| return res; |
| } |
| |
| |
| |
| }}} |
| |
| #endif /* BOOST_PROCESS_DETAIL_USED_HANDLES_HPP_ */ |