print.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #ifndef BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED
  2. #define BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED
  3. /// Copyright (c) 2018-2021 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. #ifndef BOOST_LEAF_ENABLE_WARNINGS ///
  7. # if defined(_MSC_VER) ///
  8. # pragma warning(push,1) ///
  9. # elif defined(__clang__) ///
  10. # pragma clang system_header ///
  11. # elif (__GNUC__*100+__GNUC_MINOR__>301) ///
  12. # pragma GCC system_header ///
  13. # endif ///
  14. #endif ///
  15. #include <boost/leaf/detail/optional.hpp>
  16. #include <type_traits>
  17. #include <exception>
  18. #include <iosfwd>
  19. #include <cstring>
  20. namespace boost { namespace leaf {
  21. namespace leaf_detail
  22. {
  23. template <int N>
  24. BOOST_LEAF_CONSTEXPR inline char const * check_prefix( char const * t, char const (&prefix)[N] )
  25. {
  26. return std::strncmp(t,prefix,sizeof(prefix)-1)==0 ? t+sizeof(prefix)-1 : t;
  27. }
  28. }
  29. template <class Name>
  30. inline char const * type()
  31. {
  32. using leaf_detail::check_prefix;
  33. char const * t =
  34. #ifdef __FUNCSIG__
  35. __FUNCSIG__;
  36. #else
  37. __PRETTY_FUNCTION__;
  38. #endif
  39. #if defined(__clang__)
  40. BOOST_LEAF_ASSERT(check_prefix(t,"const char *boost::leaf::type() ")==t+32);
  41. return t+32;
  42. #elif defined(__GNUC__)
  43. BOOST_LEAF_ASSERT(check_prefix(t,"const char* boost::leaf::type() ")==t+32);
  44. return t+32;
  45. #else
  46. char const * clang_style = check_prefix(t,"const char *boost::leaf::type() ");
  47. if( clang_style!=t )
  48. return clang_style;
  49. char const * gcc_style = check_prefix(t,"const char* boost::leaf::type() ");
  50. if( gcc_style!=t )
  51. return gcc_style;
  52. #endif
  53. return t;
  54. }
  55. namespace leaf_detail
  56. {
  57. template <class T, class E = void>
  58. struct is_printable: std::false_type
  59. {
  60. };
  61. template <class T>
  62. struct is_printable<T, decltype(std::declval<std::ostream&>()<<std::declval<T const &>(), void())>: std::true_type
  63. {
  64. };
  65. ////////////////////////////////////////
  66. template <class T, class E = void>
  67. struct has_printable_member_value: std::false_type
  68. {
  69. };
  70. template <class T>
  71. struct has_printable_member_value<T, decltype(std::declval<std::ostream&>()<<std::declval<T const &>().value, void())>: std::true_type
  72. {
  73. };
  74. ////////////////////////////////////////
  75. template <class Wrapper, bool WrapperPrintable=is_printable<Wrapper>::value, bool ValuePrintable=has_printable_member_value<Wrapper>::value, bool IsException=std::is_base_of<std::exception,Wrapper>::value>
  76. struct diagnostic;
  77. template <class Wrapper, bool ValuePrintable, bool IsException>
  78. struct diagnostic<Wrapper, true, ValuePrintable, IsException>
  79. {
  80. static constexpr bool is_invisible = false;
  81. static void print( std::ostream & os, Wrapper const & x )
  82. {
  83. os << x;
  84. }
  85. };
  86. template <class Wrapper, bool IsException>
  87. struct diagnostic<Wrapper, false, true, IsException>
  88. {
  89. static constexpr bool is_invisible = false;
  90. static void print( std::ostream & os, Wrapper const & x )
  91. {
  92. os << type<Wrapper>() << ": " << x.value;
  93. }
  94. };
  95. template <class Wrapper>
  96. struct diagnostic<Wrapper, false, false, true>
  97. {
  98. static constexpr bool is_invisible = false;
  99. static void print( std::ostream & os, Wrapper const & ex )
  100. {
  101. os << type<Wrapper>() << ": std::exception::what(): " << ex.what();
  102. }
  103. };
  104. template <class Wrapper>
  105. struct diagnostic<Wrapper, false, false, false>
  106. {
  107. static constexpr bool is_invisible = false;
  108. static void print( std::ostream & os, Wrapper const & )
  109. {
  110. os << type<Wrapper>() << ": {Non-Printable}";
  111. }
  112. };
  113. #ifndef BOOST_LEAF_NO_EXCEPTIONS
  114. template <>
  115. struct diagnostic<std::exception_ptr, false, false, false>
  116. {
  117. static constexpr bool is_invisible = true;
  118. BOOST_LEAF_CONSTEXPR static void print( std::ostream &, std::exception_ptr const & )
  119. {
  120. }
  121. };
  122. #endif
  123. }
  124. } }
  125. #if defined(_MSC_VER) && !defined(BOOST_LEAF_ENABLE_WARNINGS) ///
  126. #pragma warning(pop) ///
  127. #endif ///
  128. #endif