OSDN Git Service

2011-11-19 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / debug / bitset
1 // Debugging bitset implementation -*- C++ -*-
2
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 // <http://www.gnu.org/licenses/>.
25
26 /** @file debug/bitset
27  *  This file is a GNU debug extension to the Standard C++ Library.
28  */
29
30 #ifndef _GLIBCXX_DEBUG_BITSET
31 #define _GLIBCXX_DEBUG_BITSET
32
33 #include <bitset>
34 #include <debug/safe_sequence.h>
35 #include <debug/safe_iterator.h>
36
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 namespace __debug
40 {
41   /// Class std::bitset with additional safety/checking/debug instrumentation.
42   template<size_t _Nb>
43     class bitset
44     : public _GLIBCXX_STD_C::bitset<_Nb>
45 #ifndef __GXX_EXPERIMENTAL_CXX0X__
46     , public __gnu_debug::_Safe_sequence_base
47 #endif
48     {
49       typedef _GLIBCXX_STD_C::bitset<_Nb> _Base;
50
51     public:
52       // In C++0x we rely on normal reference type to preserve the property
53       // of bitset to be use as a literal.
54       // TODO: Find another solution.
55 #ifdef __GXX_EXPERIMENTAL_CXX0X__
56       typedef typename _Base::reference reference;
57 #else
58       // bit reference:
59       class reference
60       : private _Base::reference
61         , public __gnu_debug::_Safe_iterator_base
62       {
63         typedef typename _Base::reference _Base_ref;
64
65         friend class bitset;
66         reference();
67
68         reference(const _Base_ref& __base,
69                   bitset* __seq __attribute__((__unused__))) _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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
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 #ifndef __GXX_EXPERIMENTAL_CXX0X__
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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
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