1 /*******************************************************************************
2 * tlx/logger/wrap_unprintable.hpp
3 *
4 * Part of tlx - http://panthema.net/tlx
5 *
6 * Copyright (C) 2019 Timo Bingmann <tb@panthema.net>
7 *
8 * All rights reserved. Published under the Boost Software License, Version 1.0
9 ******************************************************************************/
10
11 #ifndef TLX_LOGGER_WRAP_UNPRINTABLE_HEADER
12 #define TLX_LOGGER_WRAP_UNPRINTABLE_HEADER
13
14 #include <tlx/meta/enable_if.hpp>
15
16 #include <ostream>
17 #include <utility>
18
19 namespace tlx {
20
21 //! SFINAE magic helper for wrap_unprintable()
22 template <typename, typename = void>
23 struct has_ostream_operator
24 { static constexpr bool value = false; };
25
26 template <typename Type>
27 struct has_ostream_operator<
28 Type, decltype(
29 std::declval<std::ostream&>() << std::declval<Type const&>(), void())>
30 { static constexpr bool value = true; };
31
32 //! SFINAE magic to return "<unprintable>" instead if the value HAS NO ostream
33 //! operator << available. Identical to shorter wrap_unp().
34 template <typename Type>
35 typename enable_if<!has_ostream_operator<Type>::value, const char*>::type
wrap_unprintable(Type,const char * instead="<unprintable>")36 wrap_unprintable(Type, const char* instead = "<unprintable>") {
37 return instead;
38 }
39
40 //! SFINAE magic to return the value if the value HAS a ostream operator <<
41 //! available. Identical to shorter wrap_unp().
42 template <typename Type>
43 typename enable_if<has_ostream_operator<Type>::value, Type>::type
wrap_unprintable(Type value,const char * =nullptr)44 wrap_unprintable(Type value, const char* = nullptr) {
45 return value;
46 }
47
48 //! SFINAE magic to return "<unprintable>" instead if the value HAS NO ostream
49 //! operator << available. Shortened name of wrap_unprintable()
50 template <typename Type>
51 typename enable_if<!has_ostream_operator<Type>::value, const char*>::type
wrap_unp(Type,const char * instead="<unprintable>")52 wrap_unp(Type, const char* instead = "<unprintable>") {
53 return instead;
54 }
55
56 //! SFINAE magic to return the value if the value HAS a ostream operator <<
57 //! available. Shortened name of wrap_unprintable()
58 template <typename Type>
59 typename enable_if<has_ostream_operator<Type>::value, Type>::type
wrap_unp(Type value,const char * =nullptr)60 wrap_unp(Type value, const char* = nullptr) {
61 return value;
62 }
63
64 } // namespace tlx
65
66 #endif // !TLX_LOGGER_WRAP_UNPRINTABLE_HEADER
67
68 /******************************************************************************/
69