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, 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 NStrStream = std::basic_stringstream<nasty_char, nasty_char_traits, AllocT>;
39
40 static_assert(std::constructible_from<NStrStream, nasty_char*, AllocT>);
41 static_assert(test_convertible<NStrStream, nasty_char*, const AllocT>());
42
43 // const nasty_char*
44 static_assert(std::constructible_from<NStrStream, const nasty_char*, AllocT>);
45 static_assert(test_convertible<NStrStream, const nasty_char*, const AllocT>());
46 }
47
48 template <typename CharT, typename TraitsT = std::char_traits<CharT>, typename AllocT = std::allocator<CharT>>
test_sfinae()49 void test_sfinae() {
50 using StrStream = std::basic_stringstream<CharT, TraitsT, AllocT>;
51
52 // `CharT*`
53 static_assert(std::constructible_from<StrStream, CharT*, const AllocT>);
54 static_assert(test_convertible<StrStream, CharT*, const AllocT>());
55
56 // `const CharT*`
57 static_assert(std::constructible_from<StrStream, const CharT*, const AllocT>);
58 static_assert(test_convertible<StrStream, const CharT*, const AllocT>());
59
60 // `std::basic_string_view<CharT>`
61 static_assert(std::constructible_from<StrStream, const std::basic_string_view<CharT, TraitsT>, const AllocT>);
62 static_assert(test_convertible<StrStream, std::basic_string_view<CharT, TraitsT>, const AllocT>());
63
64 // `std::basic_string<CharT>`
65 static_assert(std::constructible_from<StrStream, const std::basic_string<CharT, TraitsT>, const AllocT>);
66 static_assert(test_convertible<StrStream, const std::basic_string<CharT, TraitsT>, const AllocT>());
67
68 // ConstConvertibleStringView<CharT>
69 static_assert(std::constructible_from<StrStream, const ConstConvertibleStringView<CharT, TraitsT>, const AllocT>);
70 static_assert(test_convertible<StrStream, const ConstConvertibleStringView<CharT, TraitsT>, const AllocT>());
71
72 // NonConstConvertibleStringView<CharT>
73 static_assert(!std::constructible_from<StrStream, NonConstConvertibleStringView<CharT, TraitsT>, const AllocT>);
74 static_assert(!test_convertible<StrStream, NonConstConvertibleStringView<CharT, TraitsT>, const AllocT>());
75
76 static_assert(!std::constructible_from<StrStream, const NonConstConvertibleStringView<CharT, TraitsT>, const AllocT>);
77 static_assert(!test_convertible<StrStream, const NonConstConvertibleStringView<CharT, TraitsT>, const AllocT>());
78
79 // Non-`string-view-like`
80 static_assert(!std::constructible_from<StrStream, const SomeObject, const AllocT>);
81 static_assert(!test_convertible<StrStream, const SomeObject, const AllocT>());
82
83 // Non-allocator
84 static_assert(!std::constructible_from<StrStream, const std::basic_string_view<CharT, TraitsT>, const NonAllocator>);
85 static_assert(!test_convertible<StrStream, const std::basic_string_view<CharT, TraitsT>, const NonAllocator>());
86 }
87
88 template <typename CharT, typename TraitsT = std::char_traits<CharT>, typename AllocT = std::allocator<CharT>>
test()89 void test() {
90 using StrStream = std::basic_stringstream<CharT, TraitsT, AllocT>;
91
92 const AllocT allocator;
93
94 // const CharT*
95 {
96 StrStream ss(CS("zmt"), allocator);
97 assert(ss.str() == CS("zmt"));
98 assert(ss.rdbuf()->get_allocator() == allocator);
99 }
100 // std::basic_string_view<CharT>
101 {
102 const std::basic_string_view<CharT, TraitsT> csv = SV("zmt");
103 StrStream ss(csv, allocator);
104 assert(ss.str() == CS("zmt"));
105 assert(ss.rdbuf()->get_allocator() == allocator);
106 }
107 // std::basic_string<CharT>
108 {
109 const std::basic_string<CharT, TraitsT, AllocT> cs = ST("zmt", allocator);
110 StrStream ss(cs, allocator);
111 assert(ss.str() == CS("zmt"));
112 assert(ss.rdbuf()->get_allocator() == allocator);
113 }
114 // ConstConvertibleStringView<CharT>
115 {
116 const ConstConvertibleStringView<CharT, TraitsT> sv{CS("zmt")};
117 StrStream ss(sv, allocator);
118 assert(ss.str() == CS("zmt"));
119 assert(ss.rdbuf()->get_allocator() == allocator);
120 }
121 }
122
main(int,char **)123 int main(int, char**) {
124 test_sfinae_with_nasty_char();
125 test_sfinae_with_nasty_char<test_allocator<nasty_char>>();
126 test_sfinae<char>();
127 test_sfinae<char, constexpr_char_traits<char>, std::allocator<char>>();
128 test_sfinae<char, std::char_traits<char>, test_allocator<char>>();
129 test_sfinae<char, constexpr_char_traits<char>, test_allocator<char>>();
130 test<char>();
131 test<char, constexpr_char_traits<char>, std::allocator<char>>();
132 test<char, std::char_traits<char>, test_allocator<char>>();
133 test<char, constexpr_char_traits<char>, test_allocator<char>>();
134 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
135 test_sfinae<wchar_t>();
136 test_sfinae<wchar_t, constexpr_char_traits<wchar_t>, std::allocator<wchar_t>>();
137 test_sfinae<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>();
138 test_sfinae<wchar_t, constexpr_char_traits<wchar_t>, test_allocator<wchar_t>>();
139 test<wchar_t>();
140 test<wchar_t, constexpr_char_traits<wchar_t>, std::allocator<wchar_t>>();
141 test<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>();
142 test<wchar_t, constexpr_char_traits<wchar_t>, test_allocator<wchar_t>>();
143 #endif
144 return 0;
145 }
146