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