Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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