Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Debugging array implementation -*- C++ -*-
  2.  
  3. // Copyright (C) 2012-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/array
  26.  *  This is a Standard C++ Library header.
  27.  */
  28.  
  29. #ifndef _GLIBCXX_DEBUG_ARRAY
  30. #define _GLIBCXX_DEBUG_ARRAY 1
  31.  
  32. #pragma GCC system_header
  33.  
  34. #include <debug/safe_sequence.h>
  35.  
  36. namespace std _GLIBCXX_VISIBILITY(default)
  37. {
  38. namespace __debug
  39. {
  40.   template<typename _Tp, std::size_t _Nm>
  41.     struct array
  42.     {
  43.       typedef _Tp                                     value_type;
  44.       typedef value_type*                             pointer;
  45.       typedef const value_type*                       const_pointer;
  46.       typedef value_type&                             reference;
  47.       typedef const value_type&                       const_reference;
  48.       typedef value_type*                             iterator;
  49.       typedef const value_type*                       const_iterator;
  50.       typedef std::size_t                             size_type;
  51.       typedef std::ptrdiff_t                          difference_type;
  52.       typedef std::reverse_iterator<iterator>         reverse_iterator;
  53.       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
  54.  
  55.       // Support for zero-sized arrays mandatory.
  56.       typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
  57.       typename _AT_Type::_Type                         _M_elems;
  58.  
  59.       template<std::size_t _Size>
  60.         struct _Array_check_subscript
  61.         {
  62.           std::size_t size() { return _Size; }
  63.  
  64.           _Array_check_subscript(std::size_t __index)
  65.           { __glibcxx_check_subscript(__index); }
  66.         };
  67.  
  68.       template<std::size_t _Size>
  69.         struct _Array_check_nonempty
  70.         {
  71.           bool empty() { return _Size == 0; }
  72.  
  73.           _Array_check_nonempty()
  74.           { __glibcxx_check_nonempty(); }
  75.         };
  76.  
  77.       // No explicit construct/copy/destroy for aggregate type.
  78.  
  79.       // DR 776.
  80.       void
  81.       fill(const value_type& __u)
  82.       { std::fill_n(begin(), size(), __u); }
  83.  
  84.       void
  85.       swap(array& __other)
  86.       noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())))
  87.       { std::swap_ranges(begin(), end(), __other.begin()); }
  88.  
  89.       // Iterators.
  90.       iterator
  91.       begin() noexcept
  92.       { return iterator(data()); }
  93.  
  94.       const_iterator
  95.       begin() const noexcept
  96.       { return const_iterator(data()); }
  97.  
  98.       iterator
  99.       end() noexcept
  100.       { return iterator(data() + _Nm); }
  101.  
  102.       const_iterator
  103.       end() const noexcept
  104.       { return const_iterator(data() + _Nm); }
  105.  
  106.       reverse_iterator
  107.       rbegin() noexcept
  108.       { return reverse_iterator(end()); }
  109.  
  110.       const_reverse_iterator
  111.       rbegin() const noexcept
  112.       { return const_reverse_iterator(end()); }
  113.  
  114.       reverse_iterator
  115.       rend() noexcept
  116.       { return reverse_iterator(begin()); }
  117.  
  118.       const_reverse_iterator
  119.       rend() const noexcept
  120.       { return const_reverse_iterator(begin()); }
  121.  
  122.       const_iterator
  123.       cbegin() const noexcept
  124.       { return const_iterator(data()); }
  125.  
  126.       const_iterator
  127.       cend() const noexcept
  128.       { return const_iterator(data() + _Nm); }
  129.  
  130.       const_reverse_iterator
  131.       crbegin() const noexcept
  132.       { return const_reverse_iterator(end()); }
  133.  
  134.       const_reverse_iterator
  135.       crend() const noexcept
  136.       { return const_reverse_iterator(begin()); }
  137.  
  138.       // Capacity.
  139.       constexpr size_type
  140.       size() const noexcept { return _Nm; }
  141.  
  142.       constexpr size_type
  143.       max_size() const noexcept { return _Nm; }
  144.  
  145.       constexpr bool
  146.       empty() const noexcept { return size() == 0; }
  147.  
  148.       // Element access.
  149.       reference
  150.       operator[](size_type __n) noexcept
  151.       {
  152.         __glibcxx_check_subscript(__n);
  153.         return _AT_Type::_S_ref(_M_elems, __n);
  154.       }
  155.  
  156.       constexpr const_reference
  157.       operator[](size_type __n) const noexcept
  158.       {
  159.         return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
  160.          : (_GLIBCXX_THROW_OR_ABORT(_Array_check_subscript<_Nm>(__n)),
  161.             _AT_Type::_S_ref(_M_elems, 0));
  162.       }
  163.  
  164.       reference
  165.       at(size_type __n)
  166.       {
  167.         if (__n >= _Nm)
  168.           std::__throw_out_of_range_fmt(__N("array::at: __n "
  169.                                             "(which is %zu) >= _Nm "
  170.                                             "(which is %zu)"),
  171.                                         __n, _Nm);
  172.         return _AT_Type::_S_ref(_M_elems, __n);
  173.       }
  174.  
  175.       constexpr const_reference
  176.       at(size_type __n) const
  177.       {
  178.         // Result of conditional expression must be an lvalue so use
  179.         // boolean ? lvalue : (throw-expr, lvalue)
  180.         return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
  181.           : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
  182.                                                ">= _Nm (which is %zu)"),
  183.                                            __n, _Nm),
  184.              _AT_Type::_S_ref(_M_elems, 0));
  185.       }
  186.  
  187.       reference
  188.       front() noexcept
  189.       {
  190.         __glibcxx_check_nonempty();
  191.         return *begin();
  192.       }
  193.  
  194.       constexpr const_reference
  195.       front() const noexcept
  196.       {
  197.         return _Nm ? _AT_Type::_S_ref(_M_elems, 0)
  198.           : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
  199.              _AT_Type::_S_ref(_M_elems, 0));
  200.       }
  201.  
  202.       reference
  203.       back() noexcept
  204.       {
  205.         __glibcxx_check_nonempty();
  206.         return _Nm ? *(end() - 1) : *end();
  207.       }
  208.  
  209.       constexpr const_reference
  210.       back() const noexcept
  211.       {
  212.         return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
  213.           : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
  214.              _AT_Type::_S_ref(_M_elems, 0));
  215.       }
  216.  
  217.       pointer
  218.       data() noexcept
  219.       { return _AT_Type::_S_ptr(_M_elems); }
  220.  
  221.       const_pointer
  222.       data() const noexcept
  223.       { return _AT_Type::_S_ptr(_M_elems); }
  224.     };
  225.  
  226.   // Array comparisons.
  227.   template<typename _Tp, std::size_t _Nm>
  228.     inline bool
  229.     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  230.     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
  231.  
  232.   template<typename _Tp, std::size_t _Nm>
  233.     inline bool
  234.     operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  235.     { return !(__one == __two); }
  236.  
  237.   template<typename _Tp, std::size_t _Nm>
  238.     inline bool
  239.     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
  240.     {
  241.       return std::lexicographical_compare(__a.begin(), __a.end(),
  242.                                           __b.begin(), __b.end());
  243.     }
  244.  
  245.   template<typename _Tp, std::size_t _Nm>
  246.     inline bool
  247.     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  248.     { return __two < __one; }
  249.  
  250.   template<typename _Tp, std::size_t _Nm>
  251.     inline bool
  252.     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  253.     { return !(__one > __two); }
  254.  
  255.   template<typename _Tp, std::size_t _Nm>
  256.     inline bool
  257.     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  258.     { return !(__one < __two); }
  259.  
  260.   // Specialized algorithms.
  261.   template<typename _Tp, std::size_t _Nm>
  262.     inline void
  263.     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
  264.     noexcept(noexcept(__one.swap(__two)))
  265.     { __one.swap(__two); }
  266.  
  267.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  268.     constexpr _Tp&
  269.     get(array<_Tp, _Nm>& __arr) noexcept
  270.     {
  271.       static_assert(_Int < _Nm, "index is out of bounds");
  272.       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
  273.         _S_ref(__arr._M_elems, _Int);
  274.     }
  275.  
  276.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  277.     constexpr _Tp&&
  278.     get(array<_Tp, _Nm>&& __arr) noexcept
  279.     {
  280.       static_assert(_Int < _Nm, "index is out of bounds");
  281.       return std::move(__debug::get<_Int>(__arr));
  282.     }
  283.  
  284.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  285.     constexpr const _Tp&
  286.     get(const array<_Tp, _Nm>& __arr) noexcept
  287.     {
  288.       static_assert(_Int < _Nm, "index is out of bounds");
  289.       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
  290.         _S_ref(__arr._M_elems, _Int);
  291.     }
  292. } // namespace __debug
  293.  
  294.   // Tuple interface to class template array.
  295.  
  296.   /// tuple_size
  297.   template<typename _Tp, std::size_t _Nm>
  298.     struct tuple_size<__debug::array<_Tp, _Nm>>
  299.     : public integral_constant<std::size_t, _Nm> { };
  300.  
  301.   /// tuple_element
  302.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  303.     struct tuple_element<_Int, __debug::array<_Tp, _Nm>>
  304.     {
  305.       static_assert(_Int < _Nm, "index is out of bounds");
  306.       typedef _Tp type;
  307.     };
  308. } // namespace std
  309.  
  310. #endif // _GLIBCXX_DEBUG_ARRAY
  311.