xref: /dragonfly/contrib/gcc-8.0/libstdc++-v3/include/debug/bitset (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1// Debugging bitset implementation -*- C++ -*-
2
3// Copyright (C) 2003-2018 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.
10
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.
15
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.
19
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/>.
24
25/** @file debug/bitset
26 *  This file is a GNU debug extension to the Standard C++ Library.
27 */
28
29#ifndef _GLIBCXX_DEBUG_BITSET
30#define _GLIBCXX_DEBUG_BITSET
31
32#pragma GCC system_header
33
34#include <bitset>
35#include <debug/safe_sequence.h>
36#include <debug/safe_iterator.h>
37
38namespace std _GLIBCXX_VISIBILITY(default)
39{
40namespace __debug
41{
42  /// Class std::bitset with additional safety/checking/debug instrumentation.
43  template<size_t _Nb>
44    class bitset
45    : public _GLIBCXX_STD_C::bitset<_Nb>
46#if __cplusplus < 201103L
47    , public __gnu_debug::_Safe_sequence_base
48#endif
49    {
50      typedef _GLIBCXX_STD_C::bitset<_Nb> _Base;
51
52    public:
53      // In C++11 we rely on normal reference type to preserve the property
54      // of bitset to be use as a literal.
55      // TODO: Find another solution.
56#if __cplusplus >= 201103L
57      typedef typename _Base::reference reference;
58#else
59      // bit reference:
60      class reference
61      : private _Base::reference
62        , public __gnu_debug::_Safe_iterator_base
63      {
64          typedef typename _Base::reference _Base_ref;
65
66          friend class bitset;
67          reference();
68
69          reference(const _Base_ref& __base, bitset* __seq) _GLIBCXX_NOEXCEPT
70          : _Base_ref(__base)
71          , _Safe_iterator_base(__seq, false)
72          { }
73
74      public:
75          reference(const reference& __x) _GLIBCXX_NOEXCEPT
76          : _Base_ref(__x)
77          , _Safe_iterator_base(__x, false)
78          { }
79
80          reference&
81          operator=(bool __x) _GLIBCXX_NOEXCEPT
82          {
83            _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
84                                    _M_message(__gnu_debug::__msg_bad_bitset_write)
85                                        ._M_iterator(*this));
86            *static_cast<_Base_ref*>(this) = __x;
87            return *this;
88          }
89
90          reference&
91          operator=(const reference& __x) _GLIBCXX_NOEXCEPT
92          {
93            _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
94                                     _M_message(__gnu_debug::__msg_bad_bitset_read)
95                                        ._M_iterator(__x));
96            _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
97                                    _M_message(__gnu_debug::__msg_bad_bitset_write)
98                                        ._M_iterator(*this));
99            *static_cast<_Base_ref*>(this) = __x;
100            return *this;
101          }
102
103          bool
104          operator~() const _GLIBCXX_NOEXCEPT
105          {
106            _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
107                                     _M_message(__gnu_debug::__msg_bad_bitset_read)
108                                        ._M_iterator(*this));
109            return ~(*static_cast<const _Base_ref*>(this));
110          }
111
112          operator bool() const _GLIBCXX_NOEXCEPT
113          {
114            _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
115                                    _M_message(__gnu_debug::__msg_bad_bitset_read)
116                                        ._M_iterator(*this));
117            return *static_cast<const _Base_ref*>(this);
118          }
119
120          reference&
121          flip() _GLIBCXX_NOEXCEPT
122          {
123            _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
124                                    _M_message(__gnu_debug::__msg_bad_bitset_flip)
125                                        ._M_iterator(*this));
126            _Base_ref::flip();
127            return *this;
128          }
129      };
130#endif
131
132      // 23.3.5.1 constructors:
133      _GLIBCXX_CONSTEXPR bitset() _GLIBCXX_NOEXCEPT
134      : _Base() { }
135
136#if __cplusplus >= 201103L
137      constexpr bitset(unsigned long long __val) noexcept
138#else
139      bitset(unsigned long __val)
140#endif
141      : _Base(__val) { }
142
143      template<typename _CharT, typename _Traits, typename _Alloc>
144        explicit
145        bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
146                 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
147                 __pos = 0,
148                 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
149                 __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
150          : _Base(__str, __pos, __n) { }
151
152      // _GLIBCXX_RESOLVE_LIB_DEFECTS
153      // 396. what are characters zero and one.
154      template<class _CharT, class _Traits, class _Alloc>
155          bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
156                 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
157                 __pos,
158                 typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
159                 __n,
160                 _CharT __zero, _CharT __one = _CharT('1'))
161          : _Base(__str, __pos, __n, __zero, __one) { }
162
163      bitset(const _Base& __x) : _Base(__x) { }
164
165#if __cplusplus >= 201103L
166      template<typename _CharT>
167        explicit
168        bitset(const _CharT* __str,
169                 typename std::basic_string<_CharT>::size_type __n
170                 = std::basic_string<_CharT>::npos,
171                 _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'))
172          : _Base(__str, __n, __zero, __one) { }
173#endif
174
175      // 23.3.5.2 bitset operations:
176      bitset<_Nb>&
177      operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
178      {
179          _M_base() &= __rhs;
180          return *this;
181      }
182
183      bitset<_Nb>&
184      operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
185      {
186          _M_base() |= __rhs;
187          return *this;
188      }
189
190      bitset<_Nb>&
191      operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
192      {
193          _M_base() ^= __rhs;
194          return *this;
195      }
196
197      bitset<_Nb>&
198      operator<<=(size_t __pos) _GLIBCXX_NOEXCEPT
199      {
200          _M_base() <<= __pos;
201          return *this;
202      }
203
204      bitset<_Nb>&
205      operator>>=(size_t __pos) _GLIBCXX_NOEXCEPT
206      {
207          _M_base() >>= __pos;
208          return *this;
209      }
210
211      bitset<_Nb>&
212      set() _GLIBCXX_NOEXCEPT
213      {
214          _Base::set();
215          return *this;
216      }
217
218      // _GLIBCXX_RESOLVE_LIB_DEFECTS
219      // 186. bitset::set() second parameter should be bool
220      bitset<_Nb>&
221      set(size_t __pos, bool __val = true)
222      {
223          _Base::set(__pos, __val);
224          return *this;
225      }
226
227      bitset<_Nb>&
228      reset() _GLIBCXX_NOEXCEPT
229      {
230          _Base::reset();
231          return *this;
232      }
233
234      bitset<_Nb>&
235      reset(size_t __pos)
236      {
237          _Base::reset(__pos);
238          return *this;
239      }
240
241      bitset<_Nb>
242      operator~() const _GLIBCXX_NOEXCEPT
243      { return bitset(~_M_base()); }
244
245      bitset<_Nb>&
246      flip() _GLIBCXX_NOEXCEPT
247      {
248          _Base::flip();
249          return *this;
250      }
251
252      bitset<_Nb>&
253      flip(size_t __pos)
254      {
255          _Base::flip(__pos);
256          return *this;
257      }
258
259      // element access:
260      // _GLIBCXX_RESOLVE_LIB_DEFECTS
261      // 11. Bitset minor problems
262      reference
263      operator[](size_t __pos)
264      {
265          __glibcxx_check_subscript(__pos);
266#if __cplusplus >= 201103L
267          return _M_base()[__pos];
268#else
269          return reference(_M_base()[__pos], this);
270#endif
271      }
272
273      // _GLIBCXX_RESOLVE_LIB_DEFECTS
274      // 11. Bitset minor problems
275      _GLIBCXX_CONSTEXPR bool
276      operator[](size_t __pos) const
277      {
278#if __cplusplus < 201103L
279          // TODO: Check in debug-mode too.
280          __glibcxx_check_subscript(__pos);
281#endif
282          return _Base::operator[](__pos);
283      }
284
285      using _Base::to_ulong;
286#if __cplusplus >= 201103L
287      using _Base::to_ullong;
288#endif
289
290      template <typename _CharT, typename _Traits, typename _Alloc>
291        std::basic_string<_CharT, _Traits, _Alloc>
292        to_string() const
293        { return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
294
295      // _GLIBCXX_RESOLVE_LIB_DEFECTS
296      // 396. what are characters zero and one.
297      template<class _CharT, class _Traits, class _Alloc>
298          std::basic_string<_CharT, _Traits, _Alloc>
299          to_string(_CharT __zero, _CharT __one = _CharT('1')) const
300          {
301            return _M_base().template
302              to_string<_CharT, _Traits, _Alloc>(__zero, __one);
303          }
304
305      // _GLIBCXX_RESOLVE_LIB_DEFECTS
306      // 434. bitset::to_string() hard to use.
307      template<typename _CharT, typename _Traits>
308        std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
309        to_string() const
310        { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
311
312      // _GLIBCXX_RESOLVE_LIB_DEFECTS
313      // 853. to_string needs updating with zero and one.
314      template<class _CharT, class _Traits>
315          std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
316          to_string(_CharT __zero, _CharT __one = _CharT('1')) const
317          { return to_string<_CharT, _Traits,
318                             std::allocator<_CharT> >(__zero, __one); }
319
320      template<typename _CharT>
321        std::basic_string<_CharT, std::char_traits<_CharT>,
322                          std::allocator<_CharT> >
323        to_string() const
324        {
325          return to_string<_CharT, std::char_traits<_CharT>,
326                           std::allocator<_CharT> >();
327        }
328
329      template<class _CharT>
330          std::basic_string<_CharT, std::char_traits<_CharT>,
331                            std::allocator<_CharT> >
332          to_string(_CharT __zero, _CharT __one = _CharT('1')) const
333          {
334            return to_string<_CharT, std::char_traits<_CharT>,
335                             std::allocator<_CharT> >(__zero, __one);
336          }
337
338      std::basic_string<char, std::char_traits<char>, std::allocator<char> >
339      to_string() const
340      {
341          return to_string<char,std::char_traits<char>,std::allocator<char> >();
342      }
343
344      std::basic_string<char, std::char_traits<char>, std::allocator<char> >
345      to_string(char __zero, char __one = '1') const
346      {
347          return to_string<char, std::char_traits<char>,
348                           std::allocator<char> >(__zero, __one);
349      }
350
351      using _Base::count;
352      using _Base::size;
353
354      bool
355      operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
356      { return _M_base() == __rhs; }
357
358      bool
359      operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
360      { return _M_base() != __rhs; }
361
362      using _Base::test;
363      using _Base::all;
364      using _Base::any;
365      using _Base::none;
366
367      bitset<_Nb>
368      operator<<(size_t __pos) const _GLIBCXX_NOEXCEPT
369      { return bitset<_Nb>(_M_base() << __pos); }
370
371      bitset<_Nb>
372      operator>>(size_t __pos) const _GLIBCXX_NOEXCEPT
373      { return bitset<_Nb>(_M_base() >> __pos); }
374
375      _Base&
376      _M_base() _GLIBCXX_NOEXCEPT
377      { return *this; }
378
379      const _Base&
380      _M_base() const _GLIBCXX_NOEXCEPT
381      { return *this; }
382    };
383
384  template<size_t _Nb>
385    bitset<_Nb>
386    operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
387    { return bitset<_Nb>(__x) &= __y; }
388
389  template<size_t _Nb>
390    bitset<_Nb>
391    operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
392    { return bitset<_Nb>(__x) |= __y; }
393
394  template<size_t _Nb>
395    bitset<_Nb>
396    operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
397    { return bitset<_Nb>(__x) ^= __y; }
398
399  template<typename _CharT, typename _Traits, size_t _Nb>
400    std::basic_istream<_CharT, _Traits>&
401    operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
402    { return __is >> __x._M_base(); }
403
404  template<typename _CharT, typename _Traits, size_t _Nb>
405    std::basic_ostream<_CharT, _Traits>&
406    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
407                 const bitset<_Nb>& __x)
408    { return __os << __x._M_base(); }
409
410} // namespace __debug
411
412#if __cplusplus >= 201103L
413  // DR 1182.
414  /// std::hash specialization for bitset.
415  template<size_t _Nb>
416    struct hash<__debug::bitset<_Nb>>
417    : public __hash_base<size_t, __debug::bitset<_Nb>>
418    {
419      size_t
420      operator()(const __debug::bitset<_Nb>& __b) const noexcept
421      { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); }
422    };
423#endif
424
425} // namespace std
426
427#endif
428