1 // Copyright (c) 2016 Klemens D. Morgenstern
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef BOOST_PROCESS_DETAIL_USED_HANDLES_HPP_
7 #define BOOST_PROCESS_DETAIL_USED_HANDLES_HPP_
8
9 #include <type_traits>
10 #include <boost/fusion/include/filter_if.hpp>
11 #include <boost/fusion/include/for_each.hpp>
12
13 #if defined(BOOST_POSIX_API)
14 #include <boost/process/detail/posix/handles.hpp>
15 #include <boost/process/detail/posix/asio_fwd.hpp>
16 #else
17 #include <boost/process/detail/windows/handles.hpp>
18 #include <boost/process/detail/windows/asio_fwd.hpp>
19 #endif
20
21 namespace boost { namespace process { namespace detail {
22
23 struct uses_handles
24 {
25 //If you get an error here, you must add a `get_handles` function that returns a range or a single handle value
26 void get_used_handles() const;
27 };
28
29 template<typename T>
30 struct does_use_handle: std::is_base_of<uses_handles, T> {};
31
32 template<typename T>
33 struct does_use_handle<T&> : std::is_base_of<uses_handles, T> {};
34
35 template<typename T>
36 struct does_use_handle<const T&> : std::is_base_of<uses_handles, T> {};
37
38 template<typename Char, typename Sequence>
39 class executor;
40
41 template<typename Func>
42 struct foreach_handle_invocator
43 {
44 Func & func;
foreach_handle_invocatorboost::process::detail::foreach_handle_invocator45 foreach_handle_invocator(Func & func) : func(func) {}
46
47
48 template<typename Range>
invokeboost::process::detail::foreach_handle_invocator49 void invoke(const Range & range) const
50 {
51 for (auto handle_ : range)
52 func(handle_);
53
54 }
invokeboost::process::detail::foreach_handle_invocator55 void invoke(::boost::process::detail::api::native_handle_type handle) const {func(handle);};
56
57 template<typename T>
operator ()boost::process::detail::foreach_handle_invocator58 void operator()(T & val) const {invoke(val.get_used_handles());}
59 };
60
61 template<typename Executor, typename Function>
foreach_used_handle(Executor & exec,Function && func)62 void foreach_used_handle(Executor &exec, Function &&func)
63 {
64 boost::fusion::for_each(boost::fusion::filter_if<does_use_handle<boost::mpl::_>>(exec.seq),
65 foreach_handle_invocator<Function>(func));
66 }
67
68 template<typename Executor>
69 std::vector<::boost::process::detail::api::native_handle_type>
get_used_handles(Executor & exec)70 get_used_handles(Executor &exec)
71 {
72 std::vector<::boost::process::detail::api::native_handle_type> res;
73 foreach_used_handle(exec, [&](::boost::process::detail::api::native_handle_type handle){res.push_back(handle);});
74 return res;
75 }
76
77
78
79 }}}
80
81 #endif /* BOOST_PROCESS_DETAIL_USED_HANDLES_HPP_ */
82