Skip to content

Commit

Permalink
diagnostic_info and diagnostic_details storing e_source_location in c…
Browse files Browse the repository at this point in the history
…ontext, avoids dynamic allocations
  • Loading branch information
zajo committed Sep 6, 2024
1 parent 16f1341 commit 62ea113
Show file tree
Hide file tree
Showing 10 changed files with 385 additions and 273 deletions.
8 changes: 8 additions & 0 deletions include/boost/leaf/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@
# endif
#endif

#ifndef BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER
# define BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER "\n "
#endif

#ifndef BOOST_LEAF_CFG_DIAGNOSTICS_DELIMITER
# define BOOST_LEAF_CFG_DIAGNOSTICS_DELIMITER "\n "
#endif

#if BOOST_LEAF_CFG_DIAGNOSTICS!=0 && BOOST_LEAF_CFG_DIAGNOSTICS!=1
# error BOOST_LEAF_CFG_DIAGNOSTICS must be 0 or 1.
#endif
Expand Down
58 changes: 53 additions & 5 deletions include/boost/leaf/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ namespace leaf_detail
struct handler_argument_traits_defaults<E, false>
{
using error_type = typename std::decay<E>::type;
using context_types = leaf_detail_mp11::mp_list<error_type>;
constexpr static bool always_available = false;

template <class Tup>
Expand Down Expand Up @@ -81,10 +82,10 @@ namespace leaf_detail
}
};

template <class E>
template <class... E>
struct handler_argument_always_available
{
using error_type = E;
using context_types = leaf_detail_mp11::mp_list<E...>;
constexpr static bool always_available = true;

template <class Tup>
Expand All @@ -102,7 +103,7 @@ namespace leaf_detail
template <>
struct handler_argument_traits<void>
{
using error_type = void;
using context_types = leaf_detail_mp11::mp_list<>;
constexpr static bool always_available = false;

template <class Tup>
Expand Down Expand Up @@ -134,6 +135,47 @@ namespace leaf_detail

////////////////////////////////////////

namespace leaf_detail
{
template <class T>
struct get_dispatch
{
static BOOST_LEAF_CONSTEXPR T const * get(T const * x) noexcept
{
return x;
}
static BOOST_LEAF_CONSTEXPR T const * get(void const *) noexcept
{
return nullptr;
}
};

template <class T>
BOOST_LEAF_CONSTEXPR inline T * find_in_tuple(std::tuple<> const &)
{
return nullptr;
}

template <class T, int I = 0, class... Tp>
BOOST_LEAF_CONSTEXPR inline typename std::enable_if<I == sizeof...(Tp) - 1, T>::type const *
find_in_tuple(std::tuple<Tp...> const & t) noexcept
{
return get_dispatch<T>::get(&std::get<I>(t));
}

template<class T, int I = 0, class... Tp>
BOOST_LEAF_CONSTEXPR inline typename std::enable_if<I < sizeof...(Tp) - 1, T>::type const *
find_in_tuple(std::tuple<Tp...> const & t) noexcept
{
if( T const * x = get_dispatch<T>::get(&std::get<I>(t)) )
return x;
else
return find_in_tuple<T, I+1, Tp...>(t);
}
}

////////////////////////////////////////

namespace leaf_detail
{
template <int I, class Tup>
Expand Down Expand Up @@ -193,7 +235,6 @@ namespace leaf_detail
namespace leaf_detail
{
template <class T> struct does_not_participate_in_context_deduction: std::is_abstract<T> { };
template <> struct does_not_participate_in_context_deduction<void>: std::true_type { };
template <> struct does_not_participate_in_context_deduction<error_id>: std::true_type { };

template <class L>
Expand All @@ -205,7 +246,7 @@ namespace leaf_detail
using type =
leaf_detail_mp11::mp_remove_if<
leaf_detail_mp11::mp_unique<
leaf_detail_mp11::mp_list<typename handler_argument_traits<T>::error_type...>
leaf_detail_mp11::mp_append<typename handler_argument_traits<T>::context_types...>
>,
does_not_participate_in_context_deduction
>;
Expand Down Expand Up @@ -317,6 +358,13 @@ class context
return os << '\n';
}

template <class T>
BOOST_LEAF_CONSTEXPR T const * get() const noexcept
{
leaf_detail::slot<T> const * e = leaf_detail::find_in_tuple<leaf_detail::slot<T>>(tup_);
return e ? e->has_value() : nullptr;
}

template <class R, class... H>
BOOST_LEAF_CONSTEXPR R handle_error( error_id, H && ... ) const;

Expand Down
16 changes: 9 additions & 7 deletions include/boost/leaf/detail/print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,9 @@ namespace leaf_detail
{
static_assert(show_in_diagnostics<T>::value, "show_in_diagnostics violation");
BOOST_LEAF_ASSERT(delimiter);
if( prefix )
{
os << prefix;
prefix = nullptr;
}
os << delimiter << parse_name<T>();
char const * p = prefix;
prefix = nullptr;
os << (p ? p : delimiter) << parse_name<T>();
if( mid )
os << mid << x;
return true;
Expand Down Expand Up @@ -110,7 +107,12 @@ namespace leaf_detail
template <class CharT, class Traits>
static bool print(std::basic_ostream<CharT, Traits> & os, char const * & prefix, char const * delimiter, Exception const & ex)
{
return print_impl<Exception>(os, prefix, delimiter, ", std::exception::what(): ", static_cast<std::exception const &>(ex).what());
if( print_impl<Exception>(os, prefix, delimiter, ", \"", static_cast<std::exception const &>(ex).what()) )
{
os << '"';
return true;
}
return false;
}
};

Expand Down
44 changes: 7 additions & 37 deletions include/boost/leaf/diagnostics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class diagnostic_info: public error_info
void print_diagnostic_info(std::basic_ostream<CharT, Traits> & os) const
{
print_error_info(os);
char const * prefix = exception() ? nullptr : "\nCaught:";
char const * prefix = exception() ? nullptr : "\nCaught:" BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER;
print_tuple_contents_(os, tup_, error(), prefix);
}

Expand All @@ -59,7 +59,7 @@ namespace leaf_detail
};

template <>
struct handler_argument_traits<diagnostic_info const &>: handler_argument_always_available<void>
struct handler_argument_traits<diagnostic_info const &>: handler_argument_always_available<e_source_location>
{
template <class Tup>
BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept
Expand Down Expand Up @@ -108,7 +108,7 @@ namespace leaf_detail
};

template <>
struct handler_argument_traits<diagnostic_info const &>: handler_argument_always_available<void>
struct handler_argument_traits<diagnostic_info const &>: handler_argument_always_available<e_source_location>
{
template <class Tup>
BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const &, error_info const & ei ) noexcept
Expand Down Expand Up @@ -147,7 +147,7 @@ class diagnostic_details: public diagnostic_info
print_diagnostic_info(os);
if( da_ )
{
char const * prefix = "\nDiagnostic details:";
char const * prefix = "\nDiagnostic details:" BOOST_LEAF_CFG_DIAGNOSTICS_FIRST_DELIMITER;
da_->print(os, error(), prefix);
}
}
Expand All @@ -162,36 +162,6 @@ class diagnostic_details: public diagnostic_info

namespace leaf_detail
{
template <class T>
struct get_dispatch
{
static BOOST_LEAF_CONSTEXPR T const * get(T const * x) noexcept
{
return x;
}
static BOOST_LEAF_CONSTEXPR T const * get(void const *) noexcept
{
return nullptr;
}
};

template <class T, int I = 0, class... Tp>
BOOST_LEAF_CONSTEXPR inline typename std::enable_if<I == sizeof...(Tp) - 1, T>::type const *
find_in_tuple(std::tuple<Tp...> const & t) noexcept
{
return get_dispatch<T>::get(&std::get<I>(t));
}

template<class T, int I = 0, class... Tp>
BOOST_LEAF_CONSTEXPR inline typename std::enable_if<I < sizeof...(Tp) - 1, T>::type const *
find_in_tuple(std::tuple<Tp...> const & t) noexcept
{
if( T const * x = get_dispatch<T>::get(&std::get<I>(t)) )
return x;
else
return find_in_tuple<T, I+1, Tp...>(t);
}

struct diagnostic_details_: diagnostic_details
{
template <class Tup>
Expand All @@ -202,7 +172,7 @@ namespace leaf_detail
};

template <>
struct handler_argument_traits<diagnostic_details const &>: handler_argument_always_available<dynamic_allocator>
struct handler_argument_traits<diagnostic_details const &>: handler_argument_always_available<e_source_location, dynamic_allocator>
{
template <class Tup>
BOOST_LEAF_CONSTEXPR static diagnostic_details_ get( Tup const & tup, error_info const & ei ) noexcept
Expand Down Expand Up @@ -254,7 +224,7 @@ namespace leaf_detail
};

template <>
struct handler_argument_traits<diagnostic_details const &>: handler_argument_always_available<void>
struct handler_argument_traits<diagnostic_details const &>: handler_argument_always_available<e_source_location>
{
template <class Tup>
BOOST_LEAF_CONSTEXPR static diagnostic_details_ get( Tup const & tup, error_info const & ei ) noexcept
Expand Down Expand Up @@ -305,7 +275,7 @@ namespace leaf_detail
};

template <>
struct handler_argument_traits<diagnostic_details const &>: handler_argument_always_available<void>
struct handler_argument_traits<diagnostic_details const &>: handler_argument_always_available<e_source_location>
{
template <class Tup>
BOOST_LEAF_CONSTEXPR static diagnostic_details_ get( Tup const &, error_info const & ei ) noexcept
Expand Down
9 changes: 7 additions & 2 deletions include/boost/leaf/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,17 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_source_location
char const * function;

template <class CharT, class Traits>
friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> & os, e_source_location const & x )
friend std::ostream & operator<<(std::basic_ostream<CharT, Traits> & os, e_source_location const & x)
{
return os << x.file << '(' << x.line << ") in function " << x.function;
}
};

template <>
struct show_in_diagnostics<e_source_location>: std::false_type
{
};

////////////////////////////////////////

namespace leaf_detail
Expand Down Expand Up @@ -148,7 +153,7 @@ namespace leaf_detail
{
if( to_print && to_print.value() != k )
return;
if( diagnostic<E>::print(os, prefix, "\n\t", value(k)) && !to_print )
if( diagnostic<E>::print(os, prefix, BOOST_LEAF_CFG_DIAGNOSTICS_DELIMITER, value(k)) && !to_print )
os << '(' << k/4 << ')';
}
}
Expand Down
Loading

0 comments on commit 62ea113

Please sign in to comment.