Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:58:04

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 #ifndef BOOST_PROCESS_DETAIL_ERROR_HPP
0012 #define BOOST_PROCESS_DETAIL_ERROR_HPP
0013 
0014 #include <boost/process/detail/config.hpp>
0015 #include <boost/process/detail/traits.hpp>
0016 
0017 
0018 #if defined(BOOST_POSIX_API)
0019 #include <boost/process/detail/posix/handler.hpp>
0020 #elif defined(BOOST_WINDOWS_API)
0021 #include <boost/process/detail/windows/handler.hpp>
0022 #endif
0023 
0024 #include <system_error>
0025 
0026 #include <type_traits>
0027 #include <boost/fusion/algorithm/query/find_if.hpp>
0028 #include <boost/fusion/sequence/intrinsic/begin.hpp>
0029 #include <boost/fusion/sequence/intrinsic/end.hpp>
0030 #include <boost/fusion/container/vector/convert.hpp>
0031 #include <boost/fusion/iterator/deref.hpp>
0032 #include <boost/fusion/sequence/comparison/equal_to.hpp>
0033 #include <boost/fusion/container/set/convert.hpp>
0034 #include <boost/type_index.hpp>
0035 
0036 /** \file boost/process/error.hpp
0037  *
0038  *    Header which provides the error properties. It allows to explicitly set the error handling, the properties are:
0039  *
0040 \xmlonly
0041 <programlisting>
0042 namespace boost {
0043   namespace process {
0044     <emphasis>unspecified</emphasis> <globalname alt="boost::process::ignore_error">ignore_error</globalname>;
0045     <emphasis>unspecified</emphasis> <globalname alt="boost::process::throw_on_error">throw_on_error</globalname>;
0046     <emphasis>unspecified</emphasis> <globalname alt="boost::process::error">error</globalname>;
0047     <emphasis>unspecified</emphasis> <globalname alt="boost::process::error_ref">error_ref</globalname>;
0048     <emphasis>unspecified</emphasis> <globalname alt="boost::process::error_code">error_code</globalname>;
0049   }
0050 }
0051 </programlisting>
0052 \endxmlonly
0053  *     For error there are two aliases: error_ref and error_code
0054  */
0055 
0056 namespace boost { namespace process {
0057 
0058 namespace detail {
0059 
0060 struct throw_on_error_ : ::boost::process::detail::api::handler_base_ext
0061 {
0062     constexpr throw_on_error_() = default;
0063 
0064     template <class Executor>
0065     void on_error(Executor&, const std::error_code & ec) const
0066     {
0067         throw process_error(ec, "process creation failed");
0068     }
0069 
0070     const throw_on_error_ &operator()() const {return *this;}
0071 };
0072 
0073 struct ignore_error_ : ::boost::process::detail::api::handler_base_ext
0074 {
0075     constexpr ignore_error_() = default;
0076 };
0077 
0078 struct set_on_error : ::boost::process::detail::api::handler_base_ext
0079 {
0080     set_on_error(const set_on_error&) = default;
0081     explicit set_on_error(std::error_code &ec) : ec_(ec) {}
0082 
0083     template <class Executor>
0084     void on_error(Executor&, const std::error_code & ec) const noexcept
0085     {
0086         ec_ = ec;
0087     }
0088 
0089 private:
0090     std::error_code &ec_;
0091 };
0092 
0093 struct error_
0094 {
0095     constexpr error_() = default;
0096     set_on_error operator()(std::error_code &ec) const {return set_on_error(ec);}
0097     set_on_error operator= (std::error_code &ec) const {return set_on_error(ec);}
0098 
0099 };
0100 
0101 
0102 template<typename T>
0103 struct is_error_handler : std::false_type {};
0104 
0105 template<> struct is_error_handler<set_on_error>    : std::true_type {};
0106 template<> struct is_error_handler<throw_on_error_> : std::true_type {};
0107 template<> struct is_error_handler<ignore_error_>   : std::true_type {};
0108 
0109 
0110 
0111 template<typename Iterator, typename End>
0112 struct has_error_handler_impl
0113 {
0114     typedef typename boost::fusion::result_of::deref<Iterator>::type ref_type;
0115     typedef typename std::remove_reference<ref_type>::type res_type_;
0116     typedef typename std::remove_cv<res_type_>::type res_type;
0117     typedef typename is_error_handler<res_type>::type cond;
0118 
0119     typedef typename boost::fusion::result_of::next<Iterator>::type next_itr;
0120     typedef typename has_error_handler_impl<next_itr, End>::type next;
0121 
0122     typedef typename boost::mpl::or_<cond, next>::type type;
0123 };
0124 
0125 template<typename Iterator>
0126 struct has_error_handler_impl<Iterator, Iterator>
0127 {
0128     typedef boost::mpl::false_ type;
0129 };
0130 
0131 
0132 template<typename Sequence>
0133 struct has_error_handler
0134 {
0135     typedef typename boost::fusion::result_of::as_vector<Sequence>::type vector_type;
0136 
0137     typedef typename has_error_handler_impl<
0138             typename boost::fusion::result_of::begin<vector_type>::type,
0139             typename boost::fusion::result_of::end<  vector_type>::type
0140             >::type type;
0141 };
0142 
0143 template<typename Sequence>
0144 struct has_ignore_error
0145 {
0146     typedef typename boost::fusion::result_of::as_set<Sequence>::type set_type;
0147     typedef typename boost::fusion::result_of::has_key<set_type, ignore_error_>::type  type1;
0148     typedef typename boost::fusion::result_of::has_key<set_type, ignore_error_&>::type type2;
0149     typedef typename boost::fusion::result_of::has_key<set_type, const ignore_error_&>::type type3;
0150     typedef typename boost::mpl::or_<type1,type2, type3>::type type;
0151 };
0152 
0153 struct error_builder
0154 {
0155     std::error_code *err;
0156     typedef set_on_error result_type;
0157     set_on_error get_initializer() {return set_on_error(*err);};
0158     void operator()(std::error_code & ec) {err = &ec;};
0159 };
0160 
0161 template<>
0162 struct initializer_tag<std::error_code>
0163 {
0164     typedef error_tag type;
0165 };
0166 
0167 
0168 template<>
0169 struct initializer_builder<error_tag>
0170 {
0171     typedef error_builder type;
0172 };
0173 
0174 }
0175 /**The ignore_error property will disable any error handling. This can be useful
0176 on linux, where error handling will require a pipe.*/
0177 constexpr boost::process::detail::ignore_error_ ignore_error;
0178 /**The throw_on_error property will enable the exception when launching a process.
0179 It is unnecessary by default, but may be used, when an additional error_code is provided.*/
0180 constexpr boost::process::detail::throw_on_error_ throw_on_error;
0181 /**
0182 The error property will set the executor to handle any errors by setting an
0183 [std::error_code](http://en.cppreference.com/w/cpp/error/error_code).
0184 
0185 \code{.cpp}
0186 std::error_code ec;
0187 system("gcc", error(ec));
0188 \endcode
0189 
0190 The following syntax is valid:
0191 
0192 \code{.cpp}
0193 error(ec);
0194 error=ec;
0195 \endcode
0196 
0197 The overload version is achieved by just passing an object of
0198  [std::error_code](http://en.cppreference.com/w/cpp/error/error_code) to the function.
0199 
0200 
0201  */
0202 constexpr boost::process::detail::error_ error;
0203 ///Alias for \xmlonly <globalname alt="boost::process::error">error</globalname> \endxmlonly .
0204 constexpr boost::process::detail::error_ error_ref;
0205 ///Alias for \xmlonly <globalname alt="boost::process::error">error</globalname> \endxmlonly .
0206 constexpr boost::process::detail::error_ error_code;
0207 
0208 
0209 }}
0210 
0211 #endif