File indexing completed on 2025-09-17 08:34:55
0001 #ifndef BOOST_LEAF_DIAGNOSTICS_HPP_INCLUDED
0002 #define BOOST_LEAF_DIAGNOSTICS_HPP_INCLUDED
0003
0004
0005
0006
0007
0008 #include <boost/leaf/config.hpp>
0009 #include <boost/leaf/context.hpp>
0010 #include <boost/leaf/handle_errors.hpp>
0011
0012 namespace boost { namespace leaf {
0013
0014 #if BOOST_LEAF_CFG_DIAGNOSTICS
0015
0016 class diagnostic_info: public error_info
0017 {
0018 void const * tup_;
0019 void (*print_tuple_contents_)(std::ostream &, void const * tup, error_id to_print, char const * & prefix);
0020
0021 protected:
0022
0023 diagnostic_info( diagnostic_info const & ) noexcept = default;
0024
0025 template <class Tup>
0026 BOOST_LEAF_CONSTEXPR diagnostic_info( error_info const & ei, Tup const & tup ) noexcept:
0027 error_info(ei),
0028 tup_(&tup),
0029 print_tuple_contents_(&detail::print_tuple_contents<Tup>)
0030 {
0031 }
0032
0033 template <class CharT, class Traits>
0034 void print_diagnostic_info(std::basic_ostream<CharT, Traits> & os) const
0035 {
0036 print_error_info(os);
0037 char const * prefix = exception() ? nullptr : "\nCaught:" BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER;
0038 print_tuple_contents_(os, tup_, error(), prefix);
0039 }
0040
0041 template <class CharT, class Traits>
0042 friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> & os, diagnostic_info const & x )
0043 {
0044 x.print_diagnostic_info(os);
0045 return os << '\n';
0046 }
0047 };
0048
0049 namespace detail
0050 {
0051 struct diagnostic_info_: diagnostic_info
0052 {
0053 template <class Tup>
0054 BOOST_LEAF_CONSTEXPR diagnostic_info_( error_info const & ei, Tup const & tup ) noexcept:
0055 diagnostic_info(ei, tup)
0056 {
0057 }
0058 };
0059
0060 template <>
0061 struct handler_argument_traits<diagnostic_info const &>: handler_argument_always_available<e_source_location>
0062 {
0063 template <class Tup>
0064 BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept
0065 {
0066 return diagnostic_info_(ei, tup);
0067 }
0068 };
0069 }
0070
0071 #else
0072
0073 class diagnostic_info: public error_info
0074 {
0075 protected:
0076
0077 diagnostic_info( diagnostic_info const & ) noexcept = default;
0078
0079 BOOST_LEAF_CONSTEXPR diagnostic_info( error_info const & ei ) noexcept:
0080 error_info(ei)
0081 {
0082 }
0083
0084 template <class CharT, class Traits>
0085 void print_diagnostic_info( std::basic_ostream<CharT, Traits> & os ) const
0086 {
0087 print_error_info(os);
0088 os << "\nboost::leaf::diagnostic_info N/A due to BOOST_LEAF_CFG_DIAGNOSTICS=0";
0089 }
0090
0091 template <class CharT, class Traits>
0092 friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> & os, diagnostic_info const & x )
0093 {
0094 x.print_diagnostic_info(os);
0095 return os << "\n";
0096 }
0097 };
0098
0099 namespace detail
0100 {
0101 struct diagnostic_info_: diagnostic_info
0102 {
0103 BOOST_LEAF_CONSTEXPR diagnostic_info_( error_info const & ei ) noexcept:
0104 diagnostic_info(ei)
0105 {
0106 }
0107 };
0108
0109 template <>
0110 struct handler_argument_traits<diagnostic_info const &>: handler_argument_always_available<e_source_location>
0111 {
0112 template <class Tup>
0113 BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const &, error_info const & ei ) noexcept
0114 {
0115 return diagnostic_info_(ei);
0116 }
0117 };
0118 }
0119
0120 #endif
0121
0122
0123
0124 #if BOOST_LEAF_CFG_DIAGNOSTICS
0125
0126 #if BOOST_LEAF_CFG_CAPTURE
0127
0128 class diagnostic_details: public diagnostic_info
0129 {
0130 detail::dynamic_allocator const * const da_;
0131
0132 protected:
0133
0134 diagnostic_details( diagnostic_details const & ) noexcept = default;
0135
0136 template <class Tup>
0137 BOOST_LEAF_CONSTEXPR diagnostic_details( error_info const & ei, Tup const & tup, detail::dynamic_allocator const * da ) noexcept:
0138 diagnostic_info(ei, tup),
0139 da_(da)
0140 {
0141 }
0142
0143 template <class CharT, class Traits>
0144 void print_diagnostic_details( std::basic_ostream<CharT, Traits> & os) const
0145 {
0146 print_diagnostic_info(os);
0147 if( da_ )
0148 {
0149 char const * prefix = "\nDiagnostic details:" BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER;
0150 da_->print(os, error(), prefix);
0151 }
0152 }
0153
0154 template <class CharT, class Traits>
0155 friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> & os, diagnostic_details const & x )
0156 {
0157 x.print_diagnostic_details(os);
0158 return os << '\n';
0159 }
0160 };
0161
0162 namespace detail
0163 {
0164 struct diagnostic_details_: diagnostic_details
0165 {
0166 template <class Tup>
0167 BOOST_LEAF_CONSTEXPR diagnostic_details_( error_info const & ei, Tup const & tup, dynamic_allocator const * da ) noexcept:
0168 diagnostic_details(ei, tup, da)
0169 {
0170 }
0171 };
0172
0173 template <>
0174 struct handler_argument_traits<diagnostic_details const &>: handler_argument_always_available<e_source_location, dynamic_allocator>
0175 {
0176 template <class Tup>
0177 BOOST_LEAF_CONSTEXPR static diagnostic_details_ get( Tup const & tup, error_info const & ei ) noexcept
0178 {
0179 slot<dynamic_allocator> const * da = find_in_tuple<slot<dynamic_allocator>>(tup);
0180 return diagnostic_details_(ei, tup, da ? da->has_value_any_key() : nullptr );
0181 }
0182 };
0183 }
0184
0185 #else
0186
0187 class diagnostic_details: public diagnostic_info
0188 {
0189 protected:
0190
0191 diagnostic_details( diagnostic_details const & ) noexcept = default;
0192
0193 template <class Tup>
0194 BOOST_LEAF_CONSTEXPR diagnostic_details( error_info const & ei, Tup const & tup ) noexcept:
0195 diagnostic_info(ei, tup)
0196 {
0197 }
0198
0199 template <class CharT, class Traits>
0200 void print_diagnostic_details( std::basic_ostream<CharT, Traits> & os ) const
0201 {
0202 print_diagnostic_info(os);
0203 os << "\nboost::leaf::diagnostic_details N/A due to BOOST_LEAF_CFG_CAPTURE=0";
0204 }
0205
0206 template <class CharT, class Traits>
0207 friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> & os, diagnostic_details const & x )
0208 {
0209 x.print_diagnostic_details(os);
0210 return os << "\n";
0211 }
0212 };
0213
0214 namespace detail
0215 {
0216 struct diagnostic_details_: diagnostic_details
0217 {
0218 template <class Tup>
0219 BOOST_LEAF_CONSTEXPR diagnostic_details_( error_info const & ei, Tup const & tup ) noexcept:
0220 diagnostic_details(ei, tup)
0221 {
0222 }
0223 };
0224
0225 template <>
0226 struct handler_argument_traits<diagnostic_details const &>: handler_argument_always_available<e_source_location>
0227 {
0228 template <class Tup>
0229 BOOST_LEAF_CONSTEXPR static diagnostic_details_ get( Tup const & tup, error_info const & ei ) noexcept
0230 {
0231 return diagnostic_details_(ei, tup);
0232 }
0233 };
0234 }
0235
0236 #endif
0237
0238 #else
0239
0240 class diagnostic_details: public diagnostic_info
0241 {
0242 protected:
0243
0244 diagnostic_details( diagnostic_details const & ) noexcept = default;
0245
0246 BOOST_LEAF_CONSTEXPR diagnostic_details( error_info const & ei ) noexcept:
0247 diagnostic_info(ei)
0248 {
0249 }
0250
0251 template <class CharT, class Traits>
0252 void print_diagnostic_details( std::basic_ostream<CharT, Traits> & os ) const
0253 {
0254 print_error_info(os);
0255 os << "\nboost::leaf::diagnostic_details N/A due to BOOST_LEAF_CFG_DIAGNOSTICS=0";
0256 }
0257
0258 template <class CharT, class Traits>
0259 friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> & os, diagnostic_details const & x )
0260 {
0261 x.print_diagnostic_details(os);
0262 return os << "\n";
0263 }
0264 };
0265
0266 namespace detail
0267 {
0268 struct diagnostic_details_: diagnostic_details
0269 {
0270 BOOST_LEAF_CONSTEXPR diagnostic_details_( error_info const & ei ) noexcept:
0271 diagnostic_details(ei)
0272 {
0273 }
0274 };
0275
0276 template <>
0277 struct handler_argument_traits<diagnostic_details const &>: handler_argument_always_available<e_source_location>
0278 {
0279 template <class Tup>
0280 BOOST_LEAF_CONSTEXPR static diagnostic_details_ get( Tup const &, error_info const & ei ) noexcept
0281 {
0282 return diagnostic_details_(ei);
0283 }
0284 };
0285 }
0286
0287 #endif
0288
0289 using verbose_diagnostic_info = diagnostic_details;
0290
0291 } }
0292
0293 #endif