print.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #ifndef BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED
  2. #define BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED
  3. // Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc.
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/leaf/config.hpp>
  7. #include <boost/leaf/detail/demangle.hpp>
  8. #include <type_traits>
  9. #include <exception>
  10. #include <iosfwd>
  11. #include <cstring>
  12. namespace boost { namespace leaf {
  13. namespace leaf_detail
  14. {
  15. template <class T, class E = void>
  16. struct is_printable: std::false_type
  17. {
  18. };
  19. template <class T>
  20. struct is_printable<T, decltype(std::declval<std::ostream&>()<<std::declval<T const &>(), void())>: std::true_type
  21. {
  22. };
  23. ////////////////////////////////////////
  24. template <class T, class E = void>
  25. struct has_printable_member_value: std::false_type
  26. {
  27. };
  28. template <class T>
  29. struct has_printable_member_value<T, decltype(std::declval<std::ostream&>()<<std::declval<T const &>().value, void())>: std::true_type
  30. {
  31. };
  32. ////////////////////////////////////////
  33. template <
  34. class Wrapper,
  35. bool WrapperPrintable = is_printable<Wrapper>::value,
  36. bool ValuePrintable = has_printable_member_value<Wrapper>::value,
  37. bool IsException = std::is_base_of<std::exception,Wrapper>::value,
  38. bool IsEnum = std::is_enum<Wrapper>::value>
  39. struct diagnostic;
  40. template <class Wrapper, bool ValuePrintable, bool IsException, bool IsEnum>
  41. struct diagnostic<Wrapper, true, ValuePrintable, IsException, IsEnum>
  42. {
  43. static constexpr bool is_invisible = false;
  44. template <class CharT, class Traits>
  45. static void print( std::basic_ostream<CharT, Traits> & os, Wrapper const & x )
  46. {
  47. os << x;
  48. }
  49. };
  50. template <class Wrapper, bool IsException, bool IsEnum>
  51. struct diagnostic<Wrapper, false, true, IsException, IsEnum>
  52. {
  53. static constexpr bool is_invisible = false;
  54. template <class CharT, class Traits>
  55. static void print( std::basic_ostream<CharT, Traits> & os, Wrapper const & x )
  56. {
  57. os << type<Wrapper>() << ": " << x.value;
  58. }
  59. };
  60. template <class Wrapper, bool IsEnum>
  61. struct diagnostic<Wrapper, false, false, true, IsEnum>
  62. {
  63. static constexpr bool is_invisible = false;
  64. template <class CharT, class Traits>
  65. static void print( std::basic_ostream<CharT, Traits> & os, Wrapper const & ex )
  66. {
  67. os << type<Wrapper>() << ": std::exception::what(): " << ex.what();
  68. }
  69. };
  70. template <class Wrapper>
  71. struct diagnostic<Wrapper, false, false, false, false>
  72. {
  73. static constexpr bool is_invisible = false;
  74. template <class CharT, class Traits>
  75. static void print( std::basic_ostream<CharT, Traits> & os, Wrapper const & )
  76. {
  77. os << type<Wrapper>() << ": {not printable}";
  78. }
  79. };
  80. template <class Wrapper>
  81. struct diagnostic<Wrapper, false, false, false, true>
  82. {
  83. static constexpr bool is_invisible = false;
  84. template <class CharT, class Traits>
  85. static void print( std::basic_ostream<CharT, Traits> & os, Wrapper const & w )
  86. {
  87. os << type<Wrapper>() << ": " << static_cast<typename std::underlying_type<Wrapper>::type>(w);
  88. }
  89. };
  90. template <>
  91. struct diagnostic<std::exception_ptr, false, false, false>
  92. {
  93. static constexpr bool is_invisible = true;
  94. template <class CharT, class Traits>
  95. BOOST_LEAF_CONSTEXPR static void print( std::basic_ostream<CharT, Traits> &, std::exception_ptr const & )
  96. {
  97. }
  98. };
  99. }
  100. } }
  101. #endif