File indexing completed on 2025-01-30 09:58:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
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
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
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
0176
0177 constexpr boost::process::detail::ignore_error_ ignore_error;
0178
0179
0180 constexpr boost::process::detail::throw_on_error_ throw_on_error;
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 constexpr boost::process::detail::error_ error;
0203
0204 constexpr boost::process::detail::error_ error_ref;
0205
0206 constexpr boost::process::detail::error_ error_code;
0207
0208
0209 }}
0210
0211 #endif