| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 | // Copyright (c) 2006, 2007 Julio M. Merino Vidal// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling// Copyright (c) 2009 Boris Schaeling// Copyright (c) 2010 Felipe Tanus, Boris Schaeling// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling// Copyright (c) 2016 Klemens D. Morgenstern//// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)/** * \file boost/process/execute.hpp * * Defines a function to execute a program. */#ifndef BOOST_PROCESS_EXECUTE_HPP#define BOOST_PROCESS_EXECUTE_HPP#include <boost/process/detail/config.hpp>#include <boost/process/detail/traits.hpp>#if defined(BOOST_POSIX_API)#include <boost/process/detail/posix/executor.hpp>#elif defined(BOOST_WINDOWS_API)#include <boost/process/detail/windows/executor.hpp>#endif#include <boost/process/detail/basic_cmd.hpp>#include <boost/process/detail/handler.hpp>#include <boost/fusion/view.hpp>#include <boost/fusion/container.hpp>#include <boost/fusion/sequence.hpp>#include <boost/fusion/tuple.hpp>#include <boost/fusion/algorithm/transformation/filter_if.hpp>#include <boost/fusion/adapted/std_tuple.hpp>#include <boost/fusion/container/vector/convert.hpp>#include <type_traits>#include <utility>namespace boost { namespace process {class child;namespace detail {template<typename ...Args>struct has_wchar;template<typename First, typename ...Args>struct has_wchar<First, Args...>{    typedef has_wchar<Args...> next;    typedef typename std::remove_cv<                typename std::remove_reference<First>::type>::type res_type;    constexpr static bool my_value = is_wchar_t<res_type>::value;    constexpr static bool value = my_value || next::value;    typedef std::integral_constant<bool, value> type;};template<typename First>struct has_wchar<First>{    typedef typename std::remove_cv<                typename std::remove_reference<First>::type>::type res_type;    constexpr static bool value = is_wchar_t<res_type>::value;    typedef std::integral_constant<bool, value> type;};#if defined(BOOST_WINDOWS_API)//everything needs to be wchar_t#if defined(BOOST_NO_ANSI_APIS)template<bool has_wchar>struct required_char_type{    typedef wchar_t type;};#elsetemplate<bool has_wchar> struct required_char_type;template<> struct required_char_type<true>{    typedef wchar_t type;};template<> struct required_char_type<false>{    typedef char type;};#endif#elif defined(BOOST_POSIX_API)template<bool has_wchar>struct required_char_type{    typedef char type;};#endiftemplate<typename ... Args>using required_char_type_t = typename required_char_type<                    has_wchar<Args...>::value>::type;template<typename Iterator, typename End, typename ...Args>struct make_builders_from_view{    typedef boost::fusion::set<Args...> set;    typedef typename boost::fusion::result_of::deref<Iterator>::type ref_type;    typedef typename std::remove_reference<ref_type>::type res_type;    typedef typename initializer_tag<res_type>::type tag;    typedef typename initializer_builder<tag>::type builder_type;    typedef typename boost::fusion::result_of::has_key<set, builder_type> has_key;    typedef typename boost::fusion::result_of::next<Iterator>::type next_itr;    typedef typename make_builders_from_view<next_itr, End>::type next;    typedef typename            std::conditional<has_key::value,                typename make_builders_from_view<next_itr, End, Args...>::type,                typename make_builders_from_view<next_itr, End, Args..., builder_type>::type            >::type type;};template<typename Iterator, typename ...Args>struct make_builders_from_view<Iterator, Iterator, Args...>{    typedef boost::fusion::set<Args...> type;};template<typename Builders>struct builder_ref{    Builders &builders;    builder_ref(Builders & builders) : builders(builders) {};    template<typename T>    void operator()(T && value) const    {        typedef typename initializer_tag<typename std::remove_reference<T>::type>::type tag;        typedef typename initializer_builder<tag>::type builder_type;        boost::fusion::at_key<builder_type>(builders)(std::forward<T>(value));    }};template<typename T>struct get_initializers_result{    typedef typename T::result_type type;};template<>struct get_initializers_result<boost::fusion::void_>{    typedef boost::fusion::void_ type;};template<typename ...Args>struct helper_vector{};template<typename T, typename ...Stack>struct invoke_get_initializer_collect_keys;template<typename ...Stack>struct invoke_get_initializer_collect_keys<boost::fusion::vector<>, Stack...>{    typedef helper_vector<Stack...> type;};template<typename First, typename ...Args, typename ...Stack>struct invoke_get_initializer_collect_keys<boost::fusion::vector<First, Args...>, Stack...>{    typedef typename invoke_get_initializer_collect_keys<boost::fusion::vector<Args...>, Stack..., First>::type next;    typedef helper_vector<Stack...> stack_t;    typedef typename std::conditional<std::is_same<boost::fusion::void_, First>::value,            stack_t, next>::type type;};template<typename Keys>struct invoke_get_initializer;template<typename ...Args>struct invoke_get_initializer<helper_vector<Args...>>{    typedef boost::fusion::tuple<typename get_initializers_result<Args>::type...> result_type;    template<typename Sequence>    static result_type call(Sequence & seq)    {        return result_type(boost::fusion::at_key<Args>(seq).get_initializer()...);;    }};template<typename ...Args>inline boost::fusion::tuple<typename get_initializers_result<Args>::type...>        get_initializers(boost::fusion::set<Args...> & builders){    //typedef boost::fusion::tuple<typename get_initializers_result<Args>::type...> return_type;    typedef typename invoke_get_initializer_collect_keys<boost::fusion::vector<Args...>>::type keys;    return invoke_get_initializer<keys>::call(builders);}template<typename Char, typename ... Args>inline child basic_execute_impl(Args && ... args){    //create a tuple from the argument list    boost::fusion::tuple<typename std::remove_reference<Args>::type&...> tup(args...);    auto inits = boost::fusion::filter_if<                boost::process::detail::is_initializer<                    typename std::remove_reference<                        boost::mpl::_                        >::type                    >                >(tup);    auto others = boost::fusion::filter_if<                boost::mpl::not_<                    boost::process::detail::is_initializer<                     typename std::remove_reference<                            boost::mpl::_                            >::type                        >                    >                >(tup);   // typename detail::make_builders_from_view<decltype(others)>::type builders;    //typedef typename boost::fusion::result_of::as_vector<decltype(inits)>::type  inits_t;    typedef typename boost::fusion::result_of::as_vector<decltype(others)>::type others_t;    //  typedef decltype(others) others_t;    typedef typename ::boost::process::detail::make_builders_from_view<            typename boost::fusion::result_of::begin<others_t>::type,            typename boost::fusion::result_of::end  <others_t>::type>::type builder_t;    builder_t builders;    ::boost::process::detail::builder_ref<builder_t> builder_ref(builders);    boost::fusion::for_each(others, builder_ref);    auto other_inits = ::boost::process::detail::get_initializers(builders);    boost::fusion::joint_view<decltype(other_inits), decltype(inits)> complete_inits(other_inits, inits);    auto exec = boost::process::detail::api::make_executor<Char>(complete_inits);    return exec();}template<typename ...Args>inline child execute_impl(Args&& ... args){    typedef required_char_type_t<Args...> req_char_type;    return basic_execute_impl<req_char_type>(        boost::process::detail::char_converter_t<req_char_type, Args>::conv(                std::forward<Args>(args))...            );}}}}#endif
 |