1*80f9458cSHristo Hristov //===----------------------------------------------------------------------===//
2*80f9458cSHristo Hristov //
3*80f9458cSHristo Hristov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*80f9458cSHristo Hristov // See https://llvm.org/LICENSE.txt for license information.
5*80f9458cSHristo Hristov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*80f9458cSHristo Hristov //
7*80f9458cSHristo Hristov //===----------------------------------------------------------------------===//
8*80f9458cSHristo Hristov 
9*80f9458cSHristo Hristov // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
10*80f9458cSHristo Hristov 
11*80f9458cSHristo Hristov // <sstream>
12*80f9458cSHristo Hristov 
13*80f9458cSHristo Hristov // template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
14*80f9458cSHristo Hristov // class basic_stringstream
15*80f9458cSHristo Hristov 
16*80f9458cSHristo Hristov // template<class T>
17*80f9458cSHristo Hristov //   basic_stringstream(const T& t, ios_base::openmode which, const Allocator& a);
18*80f9458cSHristo Hristov 
19*80f9458cSHristo Hristov #include <cassert>
20*80f9458cSHristo Hristov #include <concepts>
21*80f9458cSHristo Hristov #include <memory>
22*80f9458cSHristo Hristov #include <sstream>
23*80f9458cSHristo Hristov #include <string>
24*80f9458cSHristo Hristov #include <string_view>
25*80f9458cSHristo Hristov 
26*80f9458cSHristo Hristov #include "constexpr_char_traits.h"
27*80f9458cSHristo Hristov #include "nasty_string.h"
28*80f9458cSHristo Hristov #include "test_allocator.h"
29*80f9458cSHristo Hristov #include "test_convertible.h"
30*80f9458cSHristo Hristov #include "test_macros.h"
31*80f9458cSHristo Hristov 
32*80f9458cSHristo Hristov #include "../../helper_string_macros.h"
33*80f9458cSHristo Hristov #include "../../helper_types.h"
34*80f9458cSHristo Hristov 
35*80f9458cSHristo Hristov template <typename AllocT = std::allocator<nasty_char>>
test_sfinae_with_nasty_char()36*80f9458cSHristo Hristov void test_sfinae_with_nasty_char() {
37*80f9458cSHristo Hristov   // nasty_char*
38*80f9458cSHristo Hristov   using NStrStream = std::basic_stringstream<nasty_char, nasty_char_traits, test_allocator<nasty_char>>;
39*80f9458cSHristo Hristov 
40*80f9458cSHristo Hristov   static_assert(std::constructible_from<NStrStream, nasty_char*, test_allocator<nasty_char>>);
41*80f9458cSHristo Hristov   static_assert(test_convertible<NStrStream, nasty_char*, std::ios_base::openmode, const test_allocator<nasty_char>>());
42*80f9458cSHristo Hristov 
43*80f9458cSHristo Hristov   // const nasty_char*
44*80f9458cSHristo Hristov   static_assert(std::constructible_from<NStrStream, const nasty_char*, test_allocator<nasty_char>>);
45*80f9458cSHristo Hristov   static_assert(
46*80f9458cSHristo Hristov       test_convertible<NStrStream, const nasty_char*, std::ios_base::openmode, const test_allocator<nasty_char>>());
47*80f9458cSHristo Hristov }
48*80f9458cSHristo Hristov 
49*80f9458cSHristo Hristov template <typename CharT, typename TraitsT = std::char_traits<CharT>, typename AllocT = std::allocator<CharT>>
test_sfinae()50*80f9458cSHristo Hristov void test_sfinae() {
51*80f9458cSHristo Hristov   using StrStream = std::basic_stringstream<CharT, TraitsT, AllocT>;
52*80f9458cSHristo Hristov 
53*80f9458cSHristo Hristov   // `CharT*`
54*80f9458cSHristo Hristov   static_assert(std::constructible_from<StrStream, CharT*, AllocT>);
55*80f9458cSHristo Hristov   static_assert(test_convertible<StrStream, CharT*, std::ios_base::openmode, const AllocT>());
56*80f9458cSHristo Hristov 
57*80f9458cSHristo Hristov   // `const CharT*`
58*80f9458cSHristo Hristov   static_assert(std::constructible_from<StrStream, const CharT*, AllocT>);
59*80f9458cSHristo Hristov   static_assert(test_convertible<StrStream, const CharT*, std::ios_base::openmode, const AllocT>());
60*80f9458cSHristo Hristov 
61*80f9458cSHristo Hristov   // `std::basic_string_view<CharT>`
62*80f9458cSHristo Hristov   static_assert(std::constructible_from<StrStream,
63*80f9458cSHristo Hristov                                         const std::basic_string_view<CharT, TraitsT>,
64*80f9458cSHristo Hristov                                         std::ios_base::openmode,
65*80f9458cSHristo Hristov                                         const AllocT>);
66*80f9458cSHristo Hristov   static_assert(test_convertible<StrStream,
67*80f9458cSHristo Hristov                                  const std::basic_string_view<CharT, TraitsT>,
68*80f9458cSHristo Hristov                                  std::ios_base::openmode,
69*80f9458cSHristo Hristov                                  const AllocT>());
70*80f9458cSHristo Hristov 
71*80f9458cSHristo Hristov   // `std::basic_string<CharT>`
72*80f9458cSHristo Hristov   static_assert(std::constructible_from<StrStream,
73*80f9458cSHristo Hristov                                         const std::basic_string<CharT, TraitsT>,
74*80f9458cSHristo Hristov                                         std::ios_base::openmode,
75*80f9458cSHristo Hristov                                         const AllocT>);
76*80f9458cSHristo Hristov   static_assert(
77*80f9458cSHristo Hristov       test_convertible<StrStream, const std::basic_string<CharT, TraitsT>, std::ios_base::openmode, const AllocT>());
78*80f9458cSHristo Hristov 
79*80f9458cSHristo Hristov   // ConstConvertibleStringView<CharT>
80*80f9458cSHristo Hristov   static_assert(std::constructible_from<StrStream,
81*80f9458cSHristo Hristov                                         const ConstConvertibleStringView<CharT, TraitsT>,
82*80f9458cSHristo Hristov                                         std::ios_base::openmode,
83*80f9458cSHristo Hristov                                         const AllocT>);
84*80f9458cSHristo Hristov   static_assert(test_convertible<StrStream,
85*80f9458cSHristo Hristov                                  const ConstConvertibleStringView<CharT, TraitsT>,
86*80f9458cSHristo Hristov                                  std::ios_base::openmode,
87*80f9458cSHristo Hristov                                  const AllocT>());
88*80f9458cSHristo Hristov 
89*80f9458cSHristo Hristov   // NonConstConvertibleStringView<CharT>
90*80f9458cSHristo Hristov   static_assert(!std::constructible_from<StrStream,
91*80f9458cSHristo Hristov                                          NonConstConvertibleStringView<CharT, TraitsT>,
92*80f9458cSHristo Hristov                                          std::ios_base::openmode,
93*80f9458cSHristo Hristov                                          const AllocT>);
94*80f9458cSHristo Hristov   static_assert(!test_convertible<StrStream,
95*80f9458cSHristo Hristov                                   NonConstConvertibleStringView<CharT, TraitsT>,
96*80f9458cSHristo Hristov                                   std::ios_base::openmode,
97*80f9458cSHristo Hristov                                   const AllocT>());
98*80f9458cSHristo Hristov 
99*80f9458cSHristo Hristov   static_assert(!std::constructible_from<StrStream,
100*80f9458cSHristo Hristov                                          const NonConstConvertibleStringView<CharT, TraitsT>,
101*80f9458cSHristo Hristov                                          std::ios_base::openmode,
102*80f9458cSHristo Hristov                                          const AllocT>);
103*80f9458cSHristo Hristov   static_assert(!test_convertible<StrStream,
104*80f9458cSHristo Hristov                                   const NonConstConvertibleStringView<CharT, TraitsT>,
105*80f9458cSHristo Hristov                                   std::ios_base::openmode,
106*80f9458cSHristo Hristov                                   const AllocT>());
107*80f9458cSHristo Hristov 
108*80f9458cSHristo Hristov   // Non-`string-view-like`
109*80f9458cSHristo Hristov   static_assert(!std::constructible_from<StrStream, const SomeObject, std::ios_base::openmode, const AllocT>);
110*80f9458cSHristo Hristov   static_assert(!test_convertible<StrStream, const SomeObject, std::ios_base::openmode, const AllocT>());
111*80f9458cSHristo Hristov 
112*80f9458cSHristo Hristov   static_assert(!std::constructible_from<StrStream, const int, std::ios_base::openmode, const AllocT>);
113*80f9458cSHristo Hristov   static_assert(!test_convertible<StrStream, const int, std::ios_base::openmode, const AllocT>());
114*80f9458cSHristo Hristov 
115*80f9458cSHristo Hristov   // Non-mode
116*80f9458cSHristo Hristov   static_assert(
117*80f9458cSHristo Hristov       !std::constructible_from<StrStream, const std::basic_string_view<CharT, TraitsT>, NonMode, const NonAllocator>);
118*80f9458cSHristo Hristov   static_assert(
119*80f9458cSHristo Hristov       !test_convertible<StrStream, const std::basic_string_view<CharT, TraitsT>, NonMode, const NonAllocator>());
120*80f9458cSHristo Hristov 
121*80f9458cSHristo Hristov   // Non-allocator
122*80f9458cSHristo Hristov   static_assert(!std::constructible_from<StrStream,
123*80f9458cSHristo Hristov                                          const std::basic_string_view<CharT, TraitsT>,
124*80f9458cSHristo Hristov                                          std::ios_base::openmode,
125*80f9458cSHristo Hristov                                          const NonAllocator>);
126*80f9458cSHristo Hristov   static_assert(!test_convertible<StrStream,
127*80f9458cSHristo Hristov                                   const std::basic_string_view<CharT, TraitsT>,
128*80f9458cSHristo Hristov                                   std::ios_base::openmode,
129*80f9458cSHristo Hristov                                   const NonAllocator>());
130*80f9458cSHristo Hristov }
131*80f9458cSHristo Hristov 
132*80f9458cSHristo Hristov template <typename CharT, typename TraitsT = std::char_traits<CharT>, typename AllocT = std::allocator<CharT>>
test()133*80f9458cSHristo Hristov void test() {
134*80f9458cSHristo Hristov   using StrStream = std::basic_stringstream<CharT, TraitsT, AllocT>;
135*80f9458cSHristo Hristov 
136*80f9458cSHristo Hristov   const AllocT allocator;
137*80f9458cSHristo Hristov 
138*80f9458cSHristo Hristov   // const CharT*
139*80f9458cSHristo Hristov   {
140*80f9458cSHristo Hristov     StrStream ss(CS("zmt"), std::ios_base::out | std::ios_base::in, allocator);
141*80f9458cSHristo Hristov     assert(ss.str() == CS("zmt"));
142*80f9458cSHristo Hristov     assert(ss.rdbuf()->get_allocator() == allocator);
143*80f9458cSHristo Hristov   }
144*80f9458cSHristo Hristov   // std::basic_string_view<CharT>
145*80f9458cSHristo Hristov   {
146*80f9458cSHristo Hristov     const std::basic_string_view<CharT, TraitsT> csv = SV("zmt");
147*80f9458cSHristo Hristov     StrStream ss(csv, std::ios_base::out | std::ios_base::in, allocator);
148*80f9458cSHristo Hristov     assert(ss.str() == CS("zmt"));
149*80f9458cSHristo Hristov     assert(ss.rdbuf()->get_allocator() == allocator);
150*80f9458cSHristo Hristov   }
151*80f9458cSHristo Hristov   // std::basic_string<CharT>
152*80f9458cSHristo Hristov   {
153*80f9458cSHristo Hristov     const std::basic_string<CharT, TraitsT, AllocT> cs = ST("zmt", allocator);
154*80f9458cSHristo Hristov     StrStream ss(cs, std::ios_base::out | std::ios_base::in, allocator);
155*80f9458cSHristo Hristov     assert(ss.str() == CS("zmt"));
156*80f9458cSHristo Hristov     assert(ss.rdbuf()->get_allocator() == allocator);
157*80f9458cSHristo Hristov   }
158*80f9458cSHristo Hristov   // ConstConvertibleStringView<CharT>
159*80f9458cSHristo Hristov   {
160*80f9458cSHristo Hristov     const ConstConvertibleStringView<CharT, TraitsT> sv{CS("zmt")};
161*80f9458cSHristo Hristov     StrStream ss(sv, std::ios_base::out | std::ios_base::in, allocator);
162*80f9458cSHristo Hristov     assert(ss.str() == CS("zmt"));
163*80f9458cSHristo Hristov     assert(ss.rdbuf()->get_allocator() == allocator);
164*80f9458cSHristo Hristov   }
165*80f9458cSHristo Hristov }
166*80f9458cSHristo Hristov 
main(int,char **)167*80f9458cSHristo Hristov int main(int, char**) {
168*80f9458cSHristo Hristov   test_sfinae_with_nasty_char();
169*80f9458cSHristo Hristov   test_sfinae_with_nasty_char<test_allocator<nasty_char>>();
170*80f9458cSHristo Hristov   test_sfinae<char>();
171*80f9458cSHristo Hristov   test_sfinae<char, constexpr_char_traits<char>, std::allocator<char>>();
172*80f9458cSHristo Hristov   test_sfinae<char, std::char_traits<char>, test_allocator<char>>();
173*80f9458cSHristo Hristov   test_sfinae<char, constexpr_char_traits<char>, test_allocator<char>>();
174*80f9458cSHristo Hristov   test<char>();
175*80f9458cSHristo Hristov   test<char, constexpr_char_traits<char>, std::allocator<char>>();
176*80f9458cSHristo Hristov   test<char, std::char_traits<char>, test_allocator<char>>();
177*80f9458cSHristo Hristov   test<char, constexpr_char_traits<char>, test_allocator<char>>();
178*80f9458cSHristo Hristov #ifndef TEST_HAS_NO_WIDE_CHARACTERS
179*80f9458cSHristo Hristov   test_sfinae<wchar_t>();
180*80f9458cSHristo Hristov   test_sfinae<wchar_t, constexpr_char_traits<wchar_t>, std::allocator<wchar_t>>();
181*80f9458cSHristo Hristov   test_sfinae<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>();
182*80f9458cSHristo Hristov   test_sfinae<wchar_t, constexpr_char_traits<wchar_t>, test_allocator<wchar_t>>();
183*80f9458cSHristo Hristov   test<wchar_t>();
184*80f9458cSHristo Hristov   test<wchar_t, constexpr_char_traits<wchar_t>, std::allocator<wchar_t>>();
185*80f9458cSHristo Hristov   test<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>();
186*80f9458cSHristo Hristov   test<wchar_t, constexpr_char_traits<wchar_t>, test_allocator<wchar_t>>();
187*80f9458cSHristo Hristov #endif
188*80f9458cSHristo Hristov   return 0;
189*80f9458cSHristo Hristov }
190