Add prange entries in gimple-range-op.cc.
[official-gcc.git] / libstdc++-v3 / include / std / syncstream
blob08a901b62fd09ba431100577e288eb71292c0e06
1 // <syncstream> -*- C++ -*-
3 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file include/syncstream
26  *  This is a Standard C++ Library header.
27  */
29 #ifndef _GLIBCXX_SYNCSTREAM
30 #define _GLIBCXX_SYNCSTREAM 1
32 #pragma GCC system_header
34 #include <bits/requires_hosted.h> // iostreams
36 #include <bits/c++config.h>
38 #define __glibcxx_want_syncbuf
39 #include <bits/version.h>
41 #ifdef __cpp_lib_syncbuf // C++ >= 20 && HOSTED && CXX11ABI
42 #include <sstream>
44 #include <bits/alloc_traits.h>
45 #include <bits/allocator.h>
46 #include <bits/functexcept.h>
47 #include <bits/functional_hash.h>
48 #include <bits/std_mutex.h>
50 namespace std _GLIBCXX_VISIBILITY(default)
52 _GLIBCXX_BEGIN_NAMESPACE_VERSION
54   template<typename _CharT, typename _Traits, typename _Alloc>
55     class basic_syncbuf : public __syncbuf_base<_CharT, _Traits>
56     {
57     public:
58       using char_type = _CharT;
59       using int_type = typename _Traits::int_type;
60       using pos_type = typename _Traits::pos_type;
61       using off_type = typename _Traits::off_type;
62       using traits_type = _Traits;
63       using allocator_type = _Alloc;
64       using streambuf_type = basic_streambuf<_CharT, _Traits>;
66       basic_syncbuf()
67       : basic_syncbuf(nullptr, allocator_type{})
68       { }
70       explicit
71       basic_syncbuf(streambuf_type* __obuf)
72       : basic_syncbuf(__obuf, allocator_type{})
73       { }
75       basic_syncbuf(streambuf_type* __obuf, const allocator_type& __alloc)
76       : __syncbuf_base<_CharT, _Traits>(__obuf)
77       , _M_impl(__alloc)
78       , _M_mtx(__obuf)
79       { }
81       basic_syncbuf(basic_syncbuf&& __other)
82       : __syncbuf_base<_CharT, _Traits>(__other._M_wrapped)
83       , _M_impl(std::move(__other._M_impl))
84       , _M_mtx(std::move(__other._M_mtx))
85       {
86         this->_M_emit_on_sync = __other._M_emit_on_sync;
87         this->_M_needs_sync = __other._M_needs_sync;
88         __other._M_wrapped = nullptr;
89       }
91       ~basic_syncbuf()
92       {
93         __try
94           {
95             emit();
96           }
97         __catch (...)
98           { }
99       }
101       basic_syncbuf&
102       operator=(basic_syncbuf&& __other)
103       {
104         emit();
106         _M_impl = std::move(__other._M_impl);
107         this->_M_emit_on_sync = __other._M_emit_on_sync;
108         this->_M_needs_sync = __other._M_needs_sync;
109         this->_M_wrapped = __other._M_wrapped;
110         __other._M_wrapped = nullptr;
111         _M_mtx = std::move(__other._M_mtx);
113         return *this;
114       }
116       void
117       swap(basic_syncbuf& __other)
118       {
119         using _ATr = allocator_traits<_Alloc>;
120         if constexpr (!_ATr::propagate_on_container_swap::value)
121           __glibcxx_assert(get_allocator() == __other.get_allocator());
123         std::swap(_M_impl, __other._M_impl);
124         std::swap(this->_M_emit_on_sync, __other._M_emit_on_sync);
125         std::swap(this->_M_needs_sync, __other._M_needs_sync);
126         std::swap(this->_M_wrapped, __other._M_wrapped);
127         std::swap(_M_mtx, __other._M_mtx);
128       }
130       bool
131       emit()
132       {
133         if (!this->_M_wrapped)
134           return false;
136         auto __s = std::move(_M_impl).str();
138         const lock_guard<__mutex> __l(_M_mtx);
139         if (auto __size = __s.size())
140           {
141             auto __n = this->_M_wrapped->sputn(__s.data(), __size);
142             if (__n != __size)
143               {
144                 __s.erase(0, __n);
145                 _M_impl.str(std::move(__s));
146                 return false;
147               }
148           }
150         if (this->_M_needs_sync)
151           {
152             this->_M_needs_sync = false;
153             if (this->_M_wrapped->pubsync() != 0)
154               return false;
155           }
156         return true;
157       }
159       streambuf_type*
160       get_wrapped() const noexcept
161       { return this->_M_wrapped; }
163       allocator_type
164       get_allocator() const noexcept
165       { return _M_impl.get_allocator(); }
167       void
168       set_emit_on_sync(bool __b) noexcept
169       { this->_M_emit_on_sync = __b; }
171     protected:
172       int
173       sync() override
174       {
175         this->_M_needs_sync = true;
176         if (this->_M_emit_on_sync && !emit())
177           return -1;
178         return 0;
179       }
181       int_type
182       overflow(int_type __c) override
183       {
184         int_type __eof = traits_type::eof();
185         if (__builtin_expect(!traits_type::eq_int_type(__c, __eof), true))
186           return _M_impl.sputc(__c);
187         return __eof;
188       }
190       streamsize
191       xsputn(const char_type* __s, streamsize __n) override
192       { return _M_impl.sputn(__s, __n); }
194     private:
195       basic_stringbuf<char_type, traits_type, allocator_type> _M_impl;
197       struct __mutex
198       {
199 #if _GLIBCXX_HAS_GTHREADS
200         mutex* _M_mtx;
202         __mutex(void* __t)
203           : _M_mtx(__t ? &_S_get_mutex(__t) : nullptr)
204         { }
206         void
207         swap(__mutex& __other) noexcept
208         { std::swap(_M_mtx, __other._M_mtx); }
210         void
211         lock()
212         {
213           _M_mtx->lock();
214         }
216         void
217         unlock()
218         {
219           _M_mtx->unlock();
220         }
222         // FIXME: This should be put in the .so
223         static mutex&
224         _S_get_mutex(void* __t)
225         {
226           const unsigned char __mask = 0xf;
227           static mutex __m[__mask + 1];
229           auto __key = _Hash_impl::hash(__t) & __mask;
230           return __m[__key];
231         }
232 #else
233         __mutex(void*) { }
234         void swap(__mutex&&) noexcept { }
235         void lock() { }
236         void unlock() { }
237 #endif
238         __mutex(__mutex&&) = default;
239         __mutex& operator=(__mutex&&) = default;
240       };
241       __mutex _M_mtx;
242     };
244   template <typename _CharT, typename _Traits, typename _Alloc>
245     class basic_osyncstream : public basic_ostream<_CharT, _Traits>
246     {
247       using __ostream_type = basic_ostream<_CharT, _Traits>;
249     public:
250       // Types:
251       using char_type = _CharT;
252       using traits_type = _Traits;
253       using allocator_type = _Alloc;
254       using int_type = typename traits_type::int_type;
255       using pos_type = typename traits_type::pos_type;
256       using off_type = typename traits_type::off_type;
257       using syncbuf_type = basic_syncbuf<_CharT, _Traits, _Alloc>;
258       using streambuf_type = typename syncbuf_type::streambuf_type;
260     private:
261       syncbuf_type _M_syncbuf;
263     public:
264       basic_osyncstream(streambuf_type* __buf, const allocator_type& __a)
265         : _M_syncbuf(__buf, __a)
266       { this->init(std::__addressof(_M_syncbuf)); }
268       explicit basic_osyncstream(streambuf_type* __buf)
269         : _M_syncbuf(__buf)
270       { this->init(std::__addressof(_M_syncbuf)); }
272       basic_osyncstream(basic_ostream<char_type, traits_type>& __os,
273                         const allocator_type& __a)
274         : basic_osyncstream(__os.rdbuf(), __a)
275       { this->init(std::__addressof(_M_syncbuf)); }
277       explicit basic_osyncstream(basic_ostream<char_type, traits_type>& __os)
278         : basic_osyncstream(__os.rdbuf())
279       { this->init(std::__addressof(_M_syncbuf)); }
281       basic_osyncstream(basic_osyncstream&& __rhs) noexcept
282         : __ostream_type(std::move(__rhs)),
283         _M_syncbuf(std::move(__rhs._M_syncbuf))
284       { __ostream_type::set_rdbuf(std::__addressof(_M_syncbuf)); }
286       ~basic_osyncstream() = default;
288       basic_osyncstream& operator=(basic_osyncstream&&) = default;
290       syncbuf_type* rdbuf() const noexcept
291       { return const_cast<syncbuf_type*>(&_M_syncbuf); }
293       streambuf_type* get_wrapped() const noexcept
294       { return _M_syncbuf.get_wrapped(); }
296       void emit()
297       {
298         if (!_M_syncbuf.emit())
299           this->setstate(ios_base::failbit);
300       }
301     };
303   template <class _CharT, class _Traits, class _Allocator>
304     inline void
305     swap(basic_syncbuf<_CharT, _Traits, _Allocator>& __x,
306          basic_syncbuf<_CharT, _Traits, _Allocator>& __y) noexcept
307     { __x.swap(__y); }
309   using syncbuf = basic_syncbuf<char>;
310   using wsyncbuf = basic_syncbuf<wchar_t>;
312   using osyncstream = basic_osyncstream<char>;
313   using wosyncstream = basic_osyncstream<wchar_t>;
314 _GLIBCXX_END_NAMESPACE_VERSION
315 } // namespace std
316 #endif // __cpp_lib_syncbuf
318 #endif  /* _GLIBCXX_SYNCSTREAM */