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

source code of libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string_view.mode.alloc.pass.cpp