Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:12

0001 //
0002 // boost/process/v2/bind_launcher.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2022 Klemens D. Morgenstern (klemens dot morgenstern at gmx dot net)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 /** @brief  Utility class to bind initializers to a launcher
0055  * @tparam Launcher The inner launcher to be used
0056  * @tparam ...Init The initializers to be prepended.
0057  * 
0058  * This can be used when multiple processes shared some settings, 
0059  * e.g. 
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 /// @brief  @overload bind_launcher(Launcher && launcher, Init && init)
0223 /// @tparam ...Init The initializer types to bind to the default_launcher.
0224 /// @param ...init The initializers types to bind to the default_launcher.
0225 /// @return The new default_launcher.
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 // BOOST_PROCESS_V2_BIND_LAUNCHER_HPP