1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11
10 
11 // <iomanip>
12 
13 // std::quoted
14 //   Verify that the result type of std::quoted can be streamed to
15 //   (and from) ostreams with the correct CharTraits, and not those
16 //   with the wrong CharTraits. To avoid our having to create working
17 //   ostreams with weird CharTraits, this is a compile-only test.
18 
19 #include <iomanip>
20 #include <istream>
21 #include <ostream>
22 #include <string>
23 #include <string_view>
24 #include <type_traits>
25 
26 #include "test_allocator.h"
27 #include "test_macros.h"
28 
29 template<class IS, class Q>
30 decltype(std::declval<IS>() >> std::declval<Q>(), std::true_type())
has_rightshift_impl(int)31 has_rightshift_impl(int) { return std::true_type(); }
32 
33 template<class IS, class Q>
34 std::false_type
has_rightshift_impl(long)35 has_rightshift_impl(long) { return std::false_type(); }
36 
37 template<class IS, class Q>
38 struct HasRightShift : decltype(has_rightshift_impl<IS, Q>(0)) {};
39 
40 template<class OS, class Q>
41 decltype(std::declval<OS>() << std::declval<Q>(), std::true_type())
has_leftshift_impl(int)42 has_leftshift_impl(int) { return std::true_type(); }
43 
44 template<class OS, class Q>
45 std::false_type
has_leftshift_impl(long)46 has_leftshift_impl(long) { return std::false_type(); }
47 
48 template<class OS, class Q>
49 struct HasLeftShift : decltype(has_leftshift_impl<OS, Q>(0)) {};
50 
51 template<class CharT>
52 struct FakeCharTraits : std::char_traits<CharT> {};
53 
test_string_literal()54 void test_string_literal()
55 {
56   using Q = decltype(std::quoted("hello"));
57   static_assert( HasLeftShift<std::ostream&, Q>::value, "");
58   static_assert(!HasRightShift<std::istream&, Q>::value, "");
59   static_assert( HasLeftShift<std::basic_ostream<char, FakeCharTraits<char>>&, Q>::value, "");
60   static_assert(!HasRightShift<std::basic_istream<char, FakeCharTraits<char>>&, Q>::value, "");
61 
62 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
63   using WQ = decltype(std::quoted(L"hello"));
64   static_assert( HasLeftShift<std::wostream&, WQ>::value, "");
65   static_assert(!HasRightShift<std::wistream&, WQ>::value, "");
66   static_assert( HasLeftShift<std::basic_ostream<wchar_t, FakeCharTraits<wchar_t>>&, WQ>::value, "");
67   static_assert(!HasRightShift<std::basic_istream<wchar_t, FakeCharTraits<wchar_t>>&, WQ>::value, "");
68 
69   static_assert(!HasLeftShift<std::ostream&, WQ>::value, "");
70   static_assert(!HasLeftShift<std::wostream&, Q>::value, "");
71 #endif // TEST_HAS_NO_WIDE_CHARACTERS
72 }
73 
test_std_string()74 void test_std_string()
75 {
76   std::string s = "hello";
77   const auto& cs = s;
78   using Q = decltype(std::quoted(s));
79   using CQ = decltype(std::quoted(cs));
80   static_assert( HasLeftShift<std::ostream&, Q>::value, "");
81   static_assert( HasRightShift<std::istream&, Q>::value, "");
82   static_assert( HasLeftShift<std::ostream&, CQ>::value, "");
83   static_assert(!HasRightShift<std::istream&, CQ>::value, "");
84   static_assert(!HasLeftShift<std::basic_ostream<char, FakeCharTraits<char>>&, Q>::value, "");
85   static_assert(!HasRightShift<std::basic_istream<char, FakeCharTraits<char>>&, Q>::value, "");
86   static_assert(!HasLeftShift<std::basic_ostream<char, FakeCharTraits<char>>&, CQ>::value, "");
87   static_assert(!HasRightShift<std::basic_istream<char, FakeCharTraits<char>>&, CQ>::value, "");
88 
89   std::basic_string<char, FakeCharTraits<char>, test_allocator<char>> st = "hello";
90   const auto& cst = st;
91   using QT = decltype(std::quoted(st));
92   using CQT = decltype(std::quoted(cst));
93   static_assert(!HasLeftShift<std::ostream&, QT>::value, "");
94   static_assert(!HasRightShift<std::istream&, QT>::value, "");
95   static_assert(!HasLeftShift<std::ostream&, CQT>::value, "");
96   static_assert(!HasRightShift<std::istream&, CQT>::value, "");
97   static_assert( HasLeftShift<std::basic_ostream<char, FakeCharTraits<char>>&, QT>::value, "");
98   static_assert( HasRightShift<std::basic_istream<char, FakeCharTraits<char>>&, QT>::value, "");
99   static_assert( HasLeftShift<std::basic_ostream<char, FakeCharTraits<char>>&, CQT>::value, "");
100   static_assert(!HasRightShift<std::basic_istream<char, FakeCharTraits<char>>&, CQT>::value, "");
101 
102 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
103   std::wstring ws = L"hello";
104   const auto& cws = ws;
105   using WQ = decltype(std::quoted(ws));
106   using CWQ = decltype(std::quoted(cws));
107   static_assert( HasLeftShift<std::wostream&, WQ>::value, "");
108   static_assert( HasRightShift<std::wistream&, WQ>::value, "");
109   static_assert( HasLeftShift<std::wostream&, CWQ>::value, "");
110   static_assert(!HasRightShift<std::wistream&, CWQ>::value, "");
111   static_assert(!HasLeftShift<std::basic_ostream<wchar_t, FakeCharTraits<wchar_t>>&, WQ>::value, "");
112   static_assert(!HasRightShift<std::basic_istream<wchar_t, FakeCharTraits<wchar_t>>&, WQ>::value, "");
113   static_assert(!HasLeftShift<std::basic_ostream<wchar_t, FakeCharTraits<wchar_t>>&, CWQ>::value, "");
114   static_assert(!HasRightShift<std::basic_istream<wchar_t, FakeCharTraits<wchar_t>>&, CWQ>::value, "");
115 
116   static_assert(!HasLeftShift<std::ostream&, WQ>::value, "");
117   static_assert(!HasLeftShift<std::wostream&, Q>::value, "");
118 #endif // TEST_HAS_NO_WIDE_CHARACTERS
119 }
120 
test_std_string_view()121 void test_std_string_view()
122 {
123   std::string_view s = "hello";
124   const auto& cs = s;
125   using Q = decltype(std::quoted(s));
126   using CQ = decltype(std::quoted(cs));
127   static_assert( HasLeftShift<std::ostream&, Q>::value, "");
128   static_assert(!HasRightShift<std::istream&, Q>::value, "");
129   static_assert( HasLeftShift<std::ostream&, CQ>::value, "");
130   static_assert(!HasRightShift<std::istream&, CQ>::value, "");
131   static_assert(!HasLeftShift<std::basic_ostream<char, FakeCharTraits<char>>&, Q>::value, "");
132   static_assert(!HasRightShift<std::basic_istream<char, FakeCharTraits<char>>&, Q>::value, "");
133   static_assert(!HasLeftShift<std::basic_ostream<char, FakeCharTraits<char>>&, CQ>::value, "");
134   static_assert(!HasRightShift<std::basic_istream<char, FakeCharTraits<char>>&, CQ>::value, "");
135 
136   std::basic_string_view<char, FakeCharTraits<char>> st = "hello";
137   const auto& cst = st;
138   using QT = decltype(std::quoted(st));
139   using CQT = decltype(std::quoted(cst));
140   static_assert(!HasLeftShift<std::ostream&, QT>::value, "");
141   static_assert(!HasRightShift<std::istream&, QT>::value, "");
142   static_assert(!HasLeftShift<std::ostream&, CQT>::value, "");
143   static_assert(!HasRightShift<std::istream&, CQT>::value, "");
144   static_assert( HasLeftShift<std::basic_ostream<char, FakeCharTraits<char>>&, QT>::value, "");
145   static_assert(!HasRightShift<std::basic_istream<char, FakeCharTraits<char>>&, QT>::value, "");
146   static_assert( HasLeftShift<std::basic_ostream<char, FakeCharTraits<char>>&, CQT>::value, "");
147   static_assert(!HasRightShift<std::basic_istream<char, FakeCharTraits<char>>&, CQT>::value, "");
148 
149 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
150   std::wstring_view ws = L"hello";
151   const auto& cws = ws;
152   using WQ = decltype(std::quoted(ws));
153   using CWQ = decltype(std::quoted(cws));
154   static_assert( HasLeftShift<std::wostream&, WQ>::value, "");
155   static_assert(!HasRightShift<std::wistream&, WQ>::value, "");
156   static_assert( HasLeftShift<std::wostream&, CWQ>::value, "");
157   static_assert(!HasRightShift<std::wistream&, CWQ>::value, "");
158   static_assert(!HasLeftShift<std::basic_ostream<wchar_t, FakeCharTraits<wchar_t>>&, WQ>::value, "");
159   static_assert(!HasRightShift<std::basic_istream<wchar_t, FakeCharTraits<wchar_t>>&, WQ>::value, "");
160   static_assert(!HasLeftShift<std::basic_ostream<wchar_t, FakeCharTraits<wchar_t>>&, CWQ>::value, "");
161   static_assert(!HasRightShift<std::basic_istream<wchar_t, FakeCharTraits<wchar_t>>&, CWQ>::value, "");
162 
163   static_assert(!HasLeftShift<std::ostream&, WQ>::value, "");
164   static_assert(!HasLeftShift<std::wostream&, Q>::value, "");
165 #endif // TEST_HAS_NO_WIDE_CHARACTERS
166 }
167