Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
0002 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
0003 // Copyright (c) 2009 Boris Schaeling
0004 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
0005 // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
0006 // Copyright (c) 2016 Klemens D. Morgenstern
0007 //
0008 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0009 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 /**
0012  * \file boost/process/execute.hpp
0013  *
0014  * Defines a function to execute a program.
0015  */
0016 
0017 #ifndef BOOST_PROCESS_EXECUTE_HPP
0018 #define BOOST_PROCESS_EXECUTE_HPP
0019 
0020 #include <boost/process/detail/config.hpp>
0021 #include <boost/process/detail/traits.hpp>
0022 
0023 #if defined(BOOST_POSIX_API)
0024 #include <boost/process/detail/posix/executor.hpp>
0025 #elif defined(BOOST_WINDOWS_API)
0026 #include <boost/process/detail/windows/executor.hpp>
0027 #endif
0028 
0029 #include <boost/process/detail/basic_cmd.hpp>
0030 #include <boost/process/detail/handler.hpp>
0031 
0032 #include <boost/fusion/view.hpp>
0033 #include <boost/fusion/container.hpp>
0034 #include <boost/fusion/sequence.hpp>
0035 #include <boost/fusion/tuple.hpp>
0036 #include <boost/fusion/algorithm/transformation/filter_if.hpp>
0037 #include <boost/fusion/adapted/std_tuple.hpp>
0038 #include <boost/fusion/container/vector/convert.hpp>
0039 
0040 #include <type_traits>
0041 #include <utility>
0042 
0043 namespace boost { namespace process {
0044 
0045 class child;
0046 
0047 namespace detail {
0048 
0049 
0050 template<typename ...Args>
0051 struct has_wchar;
0052 
0053 template<typename First, typename ...Args>
0054 struct has_wchar<First, Args...>
0055 {
0056     typedef has_wchar<Args...> next;
0057     typedef typename std::remove_cv<
0058                 typename std::remove_reference<First>::type>::type res_type;
0059 
0060     constexpr static bool my_value = is_wchar_t<res_type>::value;
0061     constexpr static bool value = my_value || next::value;
0062 
0063     typedef std::integral_constant<bool, value> type;
0064 };
0065 
0066 template<typename First>
0067 struct has_wchar<First>
0068 {
0069     typedef typename std::remove_cv<
0070                 typename std::remove_reference<First>::type>::type res_type;
0071 
0072     constexpr static bool value = is_wchar_t<res_type>::value;
0073 
0074     typedef std::integral_constant<bool, value> type;
0075 };
0076 
0077 
0078 #if defined(BOOST_WINDOWS_API)
0079 //everything needs to be wchar_t
0080 #if defined(BOOST_NO_ANSI_APIS)
0081 template<bool has_wchar>
0082 struct required_char_type
0083 {
0084     typedef wchar_t type;
0085 };
0086 #else
0087 template<bool has_wchar> struct required_char_type;
0088 template<> struct required_char_type<true>
0089 {
0090     typedef wchar_t type;
0091 };
0092 template<> struct required_char_type<false>
0093 {
0094     typedef char type;
0095 };
0096 #endif
0097 
0098 #elif defined(BOOST_POSIX_API)
0099 template<bool has_wchar>
0100 struct required_char_type
0101 {
0102     typedef char type;
0103 };
0104 #endif
0105 
0106 template<typename ... Args>
0107 using required_char_type_t = typename required_char_type<
0108                     has_wchar<Args...>::value>::type;
0109 
0110 
0111 template<typename Iterator, typename End, typename ...Args>
0112 struct make_builders_from_view
0113 {
0114     typedef boost::fusion::set<Args...> set;
0115     typedef typename boost::fusion::result_of::deref<Iterator>::type ref_type;
0116     typedef typename std::remove_reference<ref_type>::type res_type;
0117     typedef typename initializer_tag<res_type>::type tag;
0118     typedef typename initializer_builder<tag>::type builder_type;
0119     typedef typename boost::fusion::result_of::has_key<set, builder_type> has_key;
0120 
0121     typedef typename boost::fusion::result_of::next<Iterator>::type next_itr;
0122     typedef typename make_builders_from_view<next_itr, End>::type next;
0123 
0124     typedef typename
0125             std::conditional<has_key::value,
0126                 typename make_builders_from_view<next_itr, End, Args...>::type,
0127                 typename make_builders_from_view<next_itr, End, Args..., builder_type>::type
0128             >::type type;
0129 
0130 };
0131 
0132 template<typename Iterator, typename ...Args>
0133 struct make_builders_from_view<Iterator, Iterator, Args...>
0134 {
0135     typedef boost::fusion::set<Args...> type;
0136 };
0137 
0138 template<typename Builders>
0139 struct builder_ref
0140 {
0141     Builders &builders;
0142     builder_ref(Builders & builders) : builders(builders) {};
0143 
0144     template<typename T>
0145     void operator()(T && value) const
0146     {
0147         typedef typename initializer_tag<typename std::remove_reference<T>::type>::type tag;
0148         typedef typename initializer_builder<tag>::type builder_type;
0149         boost::fusion::at_key<builder_type>(builders)(std::forward<T>(value));
0150     }
0151 };
0152 
0153 template<typename T>
0154 struct get_initializers_result
0155 {
0156     typedef typename T::result_type type;
0157 };
0158 
0159 template<>
0160 struct get_initializers_result<boost::fusion::void_>
0161 {
0162     typedef boost::fusion::void_ type;
0163 };
0164 
0165 template<typename ...Args>
0166 struct helper_vector
0167 {
0168 
0169 };
0170 
0171 template<typename T, typename ...Stack>
0172 struct invoke_get_initializer_collect_keys;
0173 
0174 template<typename ...Stack>
0175 struct invoke_get_initializer_collect_keys<boost::fusion::vector<>, Stack...>
0176 {
0177     typedef helper_vector<Stack...> type;
0178 };
0179 
0180 
0181 template<typename First, typename ...Args, typename ...Stack>
0182 struct invoke_get_initializer_collect_keys<boost::fusion::vector<First, Args...>, Stack...>
0183 {
0184     typedef typename invoke_get_initializer_collect_keys<boost::fusion::vector<Args...>, Stack..., First>::type next;
0185     typedef helper_vector<Stack...> stack_t;
0186 
0187     typedef typename std::conditional<std::is_same<boost::fusion::void_, First>::value,
0188             stack_t, next>::type type;
0189 
0190 
0191 };
0192 
0193 
0194 template<typename Keys>
0195 struct invoke_get_initializer;
0196 
0197 template<typename ...Args>
0198 struct invoke_get_initializer<helper_vector<Args...>>
0199 
0200 {
0201     typedef boost::fusion::tuple<typename get_initializers_result<Args>::type...> result_type;
0202 
0203     template<typename Sequence>
0204     static result_type call(Sequence & seq)
0205     {
0206         return result_type(boost::fusion::at_key<Args>(seq).get_initializer()...);;
0207     }
0208 };
0209 
0210 
0211 
0212 
0213 
0214 template<typename ...Args>
0215 inline boost::fusion::tuple<typename get_initializers_result<Args>::type...>
0216         get_initializers(boost::fusion::set<Args...> & builders)
0217 {
0218     //typedef boost::fusion::tuple<typename get_initializers_result<Args>::type...> return_type;
0219     typedef typename invoke_get_initializer_collect_keys<boost::fusion::vector<Args...>>::type keys;
0220     return invoke_get_initializer<keys>::call(builders);
0221 }
0222 
0223 
0224 template<typename Char, typename ... Args>
0225 inline child basic_execute_impl(Args && ... args)
0226 {
0227     //create a tuple from the argument list
0228     boost::fusion::tuple<typename std::remove_reference<Args>::type&...> tup(args...);
0229 
0230     auto inits = boost::fusion::filter_if<
0231                 boost::process::detail::is_initializer<
0232                     typename std::remove_reference<
0233                         boost::mpl::_
0234                         >::type
0235                     >
0236                 >(tup);
0237 
0238     auto others = boost::fusion::filter_if<
0239                 boost::mpl::not_<
0240                     boost::process::detail::is_initializer<
0241                      typename std::remove_reference<
0242                             boost::mpl::_
0243                             >::type
0244                         >
0245                     >
0246                 >(tup);
0247 
0248    // typename detail::make_builders_from_view<decltype(others)>::type builders;
0249 
0250     //typedef typename boost::fusion::result_of::as_vector<decltype(inits)>::type  inits_t;
0251     typedef typename boost::fusion::result_of::as_vector<decltype(others)>::type others_t;
0252     //  typedef decltype(others) others_t;
0253     typedef typename ::boost::process::detail::make_builders_from_view<
0254             typename boost::fusion::result_of::begin<others_t>::type,
0255             typename boost::fusion::result_of::end  <others_t>::type>::type builder_t;
0256 
0257     builder_t builders;
0258     ::boost::process::detail::builder_ref<builder_t> builder_ref(builders);
0259 
0260     boost::fusion::for_each(others, builder_ref);
0261     auto other_inits = ::boost::process::detail::get_initializers(builders);
0262 
0263 
0264     boost::fusion::joint_view<decltype(other_inits), decltype(inits)> complete_inits(other_inits, inits);
0265 
0266     auto exec = boost::process::detail::api::make_executor<Char>(complete_inits);
0267     return exec();
0268 }
0269 
0270 template<typename ...Args>
0271 inline child execute_impl(Args&& ... args)
0272 {
0273     typedef required_char_type_t<Args...> req_char_type;
0274 
0275     return basic_execute_impl<req_char_type>(
0276         boost::process::detail::char_converter_t<req_char_type, Args>::conv(
0277                 std::forward<Args>(args))...
0278             );
0279 }
0280 
0281 }}}
0282 
0283 
0284 #endif