File indexing completed on 2025-01-18 09:50:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_PROCESS_V2_BIND_LAUNCHER_HPP
0012 #define BOOST_PROCESS_V2_BIND_LAUNCHER_HPP
0013
0014 #include <boost/process/v2/detail/config.hpp>
0015 #include <boost/process/v2/default_launcher.hpp>
0016
0017 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0018
0019 namespace detail
0020 {
0021
0022 template<std::size_t ... Idx>
0023 struct index_sequence { };
0024
0025 template<std::size_t Size, typename T>
0026 struct make_index_sequence_impl;
0027
0028 template<std::size_t Size, std::size_t ... Idx>
0029 struct make_index_sequence_impl<Size, index_sequence<Idx...>>
0030 {
0031 constexpr make_index_sequence_impl() {}
0032 using type = typename make_index_sequence_impl<Size - 1u, index_sequence<Size - 1u, Idx...>>::type;
0033 };
0034
0035 template<std::size_t ... Idx>
0036 struct make_index_sequence_impl<0u, index_sequence<Idx...>>
0037 {
0038 constexpr make_index_sequence_impl() {}
0039 using type = index_sequence<Idx...>;
0040 };
0041
0042
0043 template<std::size_t Cnt>
0044 struct make_index_sequence
0045 {
0046 using type = typename make_index_sequence_impl<Cnt, index_sequence<>>::type;
0047 };
0048
0049 template<std::size_t Cnt>
0050 using make_index_sequence_t = typename make_index_sequence<Cnt>::type;
0051
0052 }
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 template<typename Launcher, typename ... Init>
0063 struct bound_launcher
0064 {
0065 template<typename Launcher_, typename ... Init_>
0066 bound_launcher(Launcher_ && l, Init_ && ... init) :
0067 launcher_(std::forward<Launcher_>(l)), init_(std::forward<Init_>(init)...)
0068 {
0069 }
0070
0071 template<typename ExecutionContext, typename Args, typename ... Inits>
0072 auto operator()(ExecutionContext & context,
0073 const typename std::enable_if<std::is_convertible<
0074 ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
0075 filesystem::path >::type & executable,
0076 Args && args,
0077 Inits && ... inits) -> basic_process<typename ExecutionContext::executor_type>
0078 {
0079 return invoke(detail::make_index_sequence_t<sizeof...(Init)>{},
0080 context,
0081 executable,
0082 std::forward<Args>(args),
0083 std::forward<Inits>(inits)...);
0084 }
0085
0086
0087 template<typename ExecutionContext, typename Args, typename ... Inits>
0088 auto operator()(ExecutionContext & context,
0089 error_code & ec,
0090 const typename std::enable_if<std::is_convertible<
0091 ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
0092 filesystem::path >::type & executable,
0093 Args && args,
0094 Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
0095 {
0096 return invoke(detail::make_index_sequence_t<sizeof...(Init)>{},
0097 context, ec,
0098 executable,
0099 std::forward<Args>(args),
0100 std::forward<Inits>(inits)...);
0101 }
0102
0103 template<typename Executor, typename Args, typename ... Inits>
0104 auto operator()(Executor exec,
0105 const typename std::enable_if<
0106 BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
0107 BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
0108 filesystem::path >::type & executable,
0109 Args && args,
0110 Inits && ... inits ) -> basic_process<Executor>
0111 {
0112 return invoke(detail::make_index_sequence_t<sizeof...(Init)>{},
0113 std::move(exec),
0114 executable,
0115 std::forward<Args>(args),
0116 std::forward<Inits>(inits)...);
0117 }
0118
0119 template<typename Executor, typename Args, typename ... Inits>
0120 auto operator()(Executor exec,
0121 error_code & ec,
0122 const typename std::enable_if<
0123 BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
0124 BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
0125 filesystem::path >::type & executable,
0126 Args && args,
0127 Inits && ... inits ) -> basic_process<Executor>
0128 {
0129 return invoke(detail::make_index_sequence_t<sizeof...(Init)>{},
0130 std::move(exec), ec,
0131 executable,
0132 std::forward<Args>(args),
0133 std::forward<Inits>(inits)...);
0134 }
0135
0136 private:
0137 template<std::size_t ... Idx, typename ExecutionContext, typename Args, typename ... Inits>
0138 auto invoke(detail::index_sequence<Idx...>,
0139 ExecutionContext & context,
0140 const typename std::enable_if<std::is_convertible<
0141 ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
0142 filesystem::path >::type & executable,
0143 Args && args,
0144 Inits && ... inits) -> basic_process<typename ExecutionContext::executor_type>
0145 {
0146 return launcher_(context,
0147 executable,
0148 std::forward<Args>(args),
0149 std::get<Idx>(init_)...,
0150 std::forward<Inits>(inits)...);
0151 }
0152
0153
0154 template<std::size_t ... Idx, typename ExecutionContext, typename Args, typename ... Inits>
0155 auto invoke(detail::index_sequence<Idx...>,
0156 ExecutionContext & context,
0157 error_code & ec,
0158 const typename std::enable_if<std::is_convertible<
0159 ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
0160 filesystem::path >::type & executable,
0161 Args && args,
0162 Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
0163 {
0164 return launcher_(context, ec,
0165 executable,
0166 std::forward<Args>(args),
0167 std::get<Idx>(init_)...,
0168 std::forward<Inits>(inits)...);
0169 }
0170
0171 template<std::size_t ... Idx, typename Executor, typename Args, typename ... Inits>
0172 auto invoke(detail::index_sequence<Idx...>,
0173 Executor exec,
0174 const typename std::enable_if<
0175 BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
0176 BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
0177 filesystem::path >::type & executable,
0178 Args && args,
0179 Inits && ... inits ) -> basic_process<Executor>
0180 {
0181 return launcher_(std::move(exec),
0182 executable,
0183 std::forward<Args>(args),
0184 std::get<Idx>(init_)...,
0185 std::forward<Inits>(inits)...);
0186 }
0187
0188 template<std::size_t ... Idx, typename Executor, typename Args, typename ... Inits>
0189 auto invoke(detail::index_sequence<Idx...>,
0190 Executor exec,
0191 error_code & ec,
0192 const typename std::enable_if<
0193 BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
0194 BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
0195 filesystem::path >::type & executable,
0196 Args && args,
0197 Inits && ... inits ) -> basic_process<Executor>
0198 {
0199 return launcher_(std::move(exec), ec,
0200 executable,
0201 std::forward<Args>(args),
0202 std::get<Idx>(init_)...,
0203 std::forward<Inits>(inits)...);
0204 }
0205
0206 Launcher launcher_;
0207 std::tuple<Init...> init_;
0208 };
0209
0210
0211 template<typename Launcher, typename ... Init>
0212 auto bind_launcher(Launcher && launcher, Init && ... init)
0213 -> bound_launcher<typename std::decay<Launcher>::type,
0214 typename std::decay<Init>::type...>
0215 {
0216 return bound_launcher<typename std::decay<Launcher>::type,
0217 typename std::decay<Init>::type...>(
0218 std::forward<Launcher>(launcher),
0219 std::forward<Init>(init)...);
0220 }
0221
0222
0223
0224
0225
0226 template<typename ... Init>
0227 auto bind_default_launcher(Init && ... init)
0228 -> bound_launcher<default_process_launcher,
0229 typename std::decay<Init>::type...>
0230 {
0231 return bound_launcher<default_process_launcher,
0232 typename std::decay<Init>::type...>(
0233 default_process_launcher(),
0234 std::forward<Init>(init)...);
0235 }
0236
0237
0238 BOOST_PROCESS_V2_END_NAMESPACE
0239
0240 #endif