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 //   void str(const T& t);
18 
19 #include <cassert>
20 #include <memory>
21 #include <sstream>
22 #include <string>
23 #include <string_view>
24 
25 #include "constexpr_char_traits.h"
26 #include "nasty_string.h"
27 #include "test_allocator.h"
28 #include "test_macros.h"
29 
30 #include "../../helper_concepts.h"
31 #include "../../helper_string_macros.h"
32 #include "../../helper_types.h"
33 
34 template <typename AllocT = std::allocator<nasty_char>>
test_sfinae_with_nasty_char()35 void test_sfinae_with_nasty_char() {
36   using NStrBuf = std::basic_stringbuf<nasty_char, nasty_char_traits, AllocT>;
37 
38   static_assert(is_valid_argument_for_str_member<NStrBuf, nasty_char*>);
39   static_assert(is_valid_argument_for_str_member<NStrBuf, const nasty_char*>);
40 }
41 
42 template <typename CharT, typename TraitsT = std::char_traits<CharT>, typename AllocT = std::allocator<CharT>>
test_sfinae()43 void test_sfinae() {
44   using StrBuff = std::basic_stringbuf<CharT, TraitsT, AllocT>;
45 
46   static_assert(is_valid_argument_for_str_member<StrBuff, CharT*>);
47   static_assert(is_valid_argument_for_str_member<StrBuff, const CharT*>);
48   static_assert(is_valid_argument_for_str_member<StrBuff, std::basic_string_view<CharT, TraitsT>>);
49   static_assert(is_valid_argument_for_str_member<StrBuff, std::basic_string<CharT, TraitsT, AllocT>>);
50   static_assert(is_valid_argument_for_str_member<StrBuff, ConstConvertibleStringView<CharT, TraitsT>>);
51 
52   static_assert(!is_valid_argument_for_str_member<StrBuff, CharT>);
53   static_assert(!is_valid_argument_for_str_member<StrBuff, int>);
54   static_assert(!is_valid_argument_for_str_member<StrBuff, SomeObject>);
55   static_assert(!is_valid_argument_for_str_member<StrBuff, std::nullptr_t>);
56   static_assert(!is_valid_argument_for_str_member<StrBuff, NonConstConvertibleStringView<CharT, TraitsT>>);
57 }
58 
59 template <typename CharT, typename TraitsT = std::char_traits<CharT>, typename AllocT = std::allocator<CharT>>
test()60 void test() {
61   AllocT allocator;
62 
63   std::basic_stringbuf<CharT, TraitsT, AllocT> ss(std::ios_base::in | std::ios_base::out, allocator);
64   assert(ss.str().empty());
65 
66   // const CharT*
67   ss.str(CS("ba"));
68   assert(ss.str() == CS("ba"));
69 
70   // std::basic_string_view<CharT>
71   ss.str(SV("ma"));
72   assert(ss.str() == CS("ma"));
73 
74   // std::basic_string<CharT>
75   ss.str(ST("zmt", allocator));
76   assert(ss.str() == CS("zmt"));
77 
78   // ConstConvertibleStringView<CharT>
79   ss.str(ConstConvertibleStringView<CharT, TraitsT>{CS("da")});
80   assert(ss.str() == CS("da"));
81 
82   const std::basic_string<CharT, TraitsT, AllocT> s(allocator);
83   ss.str(s);
84   assert(ss.str().empty());
85 }
86 
main(int,char **)87 int main(int, char**) {
88   test_sfinae_with_nasty_char();
89   test_sfinae_with_nasty_char<test_allocator<nasty_char>>();
90   test_sfinae<char>();
91   test_sfinae<char, constexpr_char_traits<char>, std::allocator<char>>();
92   test_sfinae<char, std::char_traits<char>, test_allocator<char>>();
93   test_sfinae<char, constexpr_char_traits<char>, test_allocator<char>>();
94   test<char>();
95   test<char, constexpr_char_traits<char>, std::allocator<char>>();
96   test<char, std::char_traits<char>, test_allocator<char>>();
97   test<char, constexpr_char_traits<char>, test_allocator<char>>();
98 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
99   test_sfinae<wchar_t>();
100   test_sfinae<wchar_t, constexpr_char_traits<wchar_t>, std::allocator<wchar_t>>();
101   test_sfinae<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>();
102   test_sfinae<wchar_t, constexpr_char_traits<wchar_t>, test_allocator<wchar_t>>();
103   test<wchar_t>();
104   test<wchar_t, constexpr_char_traits<wchar_t>, std::allocator<wchar_t>>();
105   test<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>();
106   test<wchar_t, constexpr_char_traits<wchar_t>, test_allocator<wchar_t>>();
107 #endif
108 
109   return 0;
110 }
111