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