IsStreamable.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <type_traits>
7 
8 #include "Utilities/Requires.hpp"
10 
11 namespace tt {
12 // @{
13 /// \ingroup TypeTraitsGroup
14 /// \brief Check if type `T` has operator<<(`S`, `T`) defined.
15 ///
16 /// \details
17 /// Inherits from std::true_type if the type `T` has operator<<(`S`, `T`)
18 /// defined for a stream `S`, otherwise inherits from std::false_type
19 ///
20 /// \usage
21 /// For any type `T` and stream type `S`,
22 /// \code
23 /// using result = tt::is_streamable<S, T>;
24 /// \endcode
25 ///
26 /// \metareturns
27 /// std::bool_constant
28 ///
29 /// \semantics
30 /// If the type `T` has operator<<(`S`, `T`) defined for stream `S`, then
31 /// \code
32 /// typename result::type = std::true_type;
33 /// \endcode
34 /// otherwise
35 /// \code
36 /// typename result::type = std::false_type;
37 /// \endcode
38 ///
39 /// \example
40 /// \snippet Test_IsStreamable.cpp is_streamable_example
41 /// \see std::cout std::ifstream std::sstream std::ostream
42 /// \tparam S the stream type, e.g. std::stringstream or std::ostream
43 /// \tparam T the type we want to know if it has operator<<
44 template <typename S, typename T, typename = std::void_t<>>
45 struct is_streamable : std::false_type {};
46 
47 /// \cond
48 template <typename S, typename T>
49 struct is_streamable<
50  S, T,
51  std::void_t<decltype(std::declval<std::add_lvalue_reference_t<S>>()
52  << std::declval<T>()),
53  Requires<not std::is_same<S, T>::value>>> : std::true_type {};
54 /// \endcond
55 
56 /// \see is_streamable
57 template <typename S, typename T>
58 constexpr bool is_streamable_v = is_streamable<S, T>::value;
59 
60 /// \see is_streamable
61 template <typename S, typename T>
62 using is_streamable_t = typename is_streamable<S, T>::type;
63 // @}
64 } // namespace tt
std::false_type
StlStreamDeclarations.hpp
Requires.hpp
tt
Definition: TensorExpression.hpp:121
type_traits