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
10 // UNSUPPORTED: no-localization
11 // UNSUPPORTED: libcpp-has-no-experimental-syncstream
12 
13 // <syncstream>
14 
15 // template <class charT, class traits, class Allocator>
16 // class basic_syncbuf;
17 
18 // basic_syncbuf(streambuf_type* obuf, const Allocator&);
19 
20 #include <cassert>
21 #include <concepts>
22 #include <syncstream>
23 
24 #include "test_macros.h"
25 #include "constexpr_char_traits.h"
26 #include "test_allocator.h"
27 
28 template <class CharT>
test()29 void test() {
30   {
31     using Buf = std::basic_syncbuf<CharT>;
32     const std::allocator<CharT> alloc;
33     {
34       Buf buf = {nullptr, alloc};
35       assert(buf.get_wrapped() == nullptr);
36       assert(buf.get_allocator() == alloc);
37     }
38     {
39       Buf w;
40 #if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_THREADS)
41       assert(std::__wrapped_streambuf_mutex::__instance().__get_count(&w) == 0);
42 #endif
43       {
44         Buf buf = {&w, alloc};
45 #if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_THREADS)
46         assert(std::__wrapped_streambuf_mutex::__instance().__get_count(&w) == 1);
47 #endif
48         assert(buf.get_wrapped() == &w);
49         assert(buf.get_allocator() == alloc);
50       }
51 #if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_THREADS)
52       assert(std::__wrapped_streambuf_mutex::__instance().__get_count(&w) == 0);
53 #endif
54     }
55   }
56 
57   {
58     using Buf = std::basic_syncbuf<CharT, constexpr_char_traits<CharT>>;
59     const std::allocator<CharT> alloc;
60     {
61       Buf buf = {nullptr, alloc};
62       assert(buf.get_wrapped() == nullptr);
63       assert(buf.get_allocator() == alloc);
64     }
65     {
66       Buf w;
67 #if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_THREADS)
68       assert(std::__wrapped_streambuf_mutex::__instance().__get_count(&w) == 0);
69 #endif
70       {
71         Buf buf{&w, alloc};
72 #if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_THREADS)
73         assert(std::__wrapped_streambuf_mutex::__instance().__get_count(&w) == 1);
74 #endif
75         assert(buf.get_wrapped() == &w);
76         assert(buf.get_allocator() == alloc);
77       }
78 #if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_THREADS)
79       assert(std::__wrapped_streambuf_mutex::__instance().__get_count(&w) == 0);
80 #endif
81     }
82   }
83 
84   {
85     using Buf = std::basic_syncbuf<CharT, constexpr_char_traits<CharT>, test_allocator<CharT>>;
86     test_allocator<CharT> alloc{42};
87     {
88       Buf buf = {nullptr, alloc};
89       assert(buf.get_wrapped() == nullptr);
90       assert(buf.get_allocator() == alloc);
91     }
92     {
93       Buf w;
94 #if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_THREADS)
95       assert(std::__wrapped_streambuf_mutex::__instance().__get_count(&w) == 0);
96 #endif
97       {
98         Buf buf{&w, alloc};
99 #if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_THREADS)
100         assert(std::__wrapped_streambuf_mutex::__instance().__get_count(&w) == 1);
101 #endif
102         assert(buf.get_wrapped() == &w);
103         assert(buf.get_allocator() == alloc);
104       }
105 #if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_THREADS)
106       assert(std::__wrapped_streambuf_mutex::__instance().__get_count(&w) == 0);
107 #endif
108     }
109   }
110 }
111 
main(int,char **)112 int main(int, char**) {
113   test<char>();
114 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
115   test<wchar_t>();
116 #endif
117 
118   return 0;
119 }
120