• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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