// 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 #include #if defined(BOOST_POSIX_API) #include #elif defined(BOOST_WINDOWS_API) #include #endif #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace process { class child; namespace detail { template struct has_wchar; template struct has_wchar { typedef has_wchar next; typedef typename std::remove_cv< typename std::remove_reference::type>::type res_type; constexpr static bool my_value = is_wchar_t::value; constexpr static bool value = my_value || next::value; typedef std::integral_constant type; }; template struct has_wchar { typedef typename std::remove_cv< typename std::remove_reference::type>::type res_type; constexpr static bool value = is_wchar_t::value; typedef std::integral_constant type; }; #if defined(BOOST_WINDOWS_API) //everything needs to be wchar_t #if defined(BOOST_NO_ANSI_APIS) template struct required_char_type { typedef wchar_t type; }; #else template struct required_char_type; template<> struct required_char_type { typedef wchar_t type; }; template<> struct required_char_type { typedef char type; }; #endif #elif defined(BOOST_POSIX_API) template struct required_char_type { typedef char type; }; #endif template using required_char_type_t = typename required_char_type< has_wchar::value>::type; template struct make_builders_from_view { typedef boost::fusion::set set; typedef typename boost::fusion::result_of::deref::type ref_type; typedef typename std::remove_reference::type res_type; typedef typename initializer_tag::type tag; typedef typename initializer_builder::type builder_type; typedef typename boost::fusion::result_of::has_key has_key; typedef typename boost::fusion::result_of::next::type next_itr; typedef typename make_builders_from_view::type next; typedef typename std::conditional::type, typename make_builders_from_view::type >::type type; }; template struct make_builders_from_view { typedef boost::fusion::set type; }; template struct builder_ref { Builders &builders; builder_ref(Builders & builders) : builders(builders) {}; template void operator()(T && value) const { typedef typename initializer_tag::type>::type tag; typedef typename initializer_builder::type builder_type; boost::fusion::at_key(builders)(std::forward(value)); } }; template struct get_initializers_result { typedef typename T::result_type type; }; template<> struct get_initializers_result { typedef boost::fusion::void_ type; }; template struct helper_vector { }; template struct invoke_get_initializer_collect_keys; template struct invoke_get_initializer_collect_keys, Stack...> { typedef helper_vector type; }; template struct invoke_get_initializer_collect_keys, Stack...> { typedef typename invoke_get_initializer_collect_keys, Stack..., First>::type next; typedef helper_vector stack_t; typedef typename std::conditional::value, stack_t, next>::type type; }; template struct invoke_get_initializer; template struct invoke_get_initializer> { typedef boost::fusion::tuple::type...> result_type; template static result_type call(Sequence & seq) { return result_type(boost::fusion::at_key(seq).get_initializer()...);; } }; template inline boost::fusion::tuple::type...> get_initializers(boost::fusion::set & builders) { //typedef boost::fusion::tuple::type...> return_type; typedef typename invoke_get_initializer_collect_keys>::type keys; return invoke_get_initializer::call(builders); } template inline child basic_execute_impl(Args && ... args) { //create a tuple from the argument list boost::fusion::tuple::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::type builders; //typedef typename boost::fusion::result_of::as_vector::type inits_t; typedef typename boost::fusion::result_of::as_vector::type others_t; // typedef decltype(others) others_t; typedef typename ::boost::process::detail::make_builders_from_view< typename boost::fusion::result_of::begin::type, typename boost::fusion::result_of::end ::type>::type builder_t; builder_t builders; ::boost::process::detail::builder_ref builder_ref(builders); boost::fusion::for_each(others, builder_ref); auto other_inits = ::boost::process::detail::get_initializers(builders); boost::fusion::joint_view complete_inits(other_inits, inits); auto exec = boost::process::detail::api::make_executor(complete_inits); return exec(); } template inline child execute_impl(Args&& ... args) { typedef required_char_type_t req_char_type; return basic_execute_impl( boost::process::detail::char_converter_t::conv( std::forward(args))... ); } }}} #endif