Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // Debugging array implementation -*- C++ -*-
  2.  
  3. // Copyright (C) 2012-2013 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)
  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(__N("array::at"));
  169.         return _AT_Type::_S_ref(_M_elems, __n);
  170.       }
  171.  
  172.       constexpr const_reference
  173.       at(size_type __n) const
  174.       {
  175.         // Result of conditional expression must be an lvalue so use
  176.         // boolean ? lvalue : (throw-expr, lvalue)
  177.         return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
  178.           : (std::__throw_out_of_range(__N("array::at")),
  179.              _AT_Type::_S_ref(_M_elems, 0));
  180.       }
  181.  
  182.       reference
  183.       front()
  184.       {
  185.         __glibcxx_check_nonempty();
  186.         return *begin();
  187.       }
  188.  
  189.       constexpr const_reference
  190.       front() const
  191.       {
  192.         return _Nm ? _AT_Type::_S_ref(_M_elems, 0)
  193.           : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
  194.              _AT_Type::_S_ref(_M_elems, 0));
  195.       }
  196.  
  197.       reference
  198.       back()
  199.       {
  200.         __glibcxx_check_nonempty();
  201.         return _Nm ? *(end() - 1) : *end();
  202.       }
  203.  
  204.       constexpr const_reference
  205.       back() const
  206.       {
  207.         return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
  208.           : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
  209.              _AT_Type::_S_ref(_M_elems, 0));
  210.       }
  211.  
  212.       pointer
  213.       data() noexcept
  214.       { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
  215.  
  216.       const_pointer
  217.       data() const noexcept
  218.       { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
  219.     };
  220.  
  221.   // Array comparisons.
  222.   template<typename _Tp, std::size_t _Nm>
  223.     inline bool
  224.     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  225.     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
  226.  
  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 !(__one == __two); }
  231.  
  232.   template<typename _Tp, std::size_t _Nm>
  233.     inline bool
  234.     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
  235.     {
  236.       return std::lexicographical_compare(__a.begin(), __a.end(),
  237.                                           __b.begin(), __b.end());
  238.     }
  239.  
  240.   template<typename _Tp, std::size_t _Nm>
  241.     inline bool
  242.     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  243.     { return __two < __one; }
  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 !(__one > __two); }
  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.   // Specialized algorithms.
  256.   template<typename _Tp, std::size_t _Nm>
  257.     inline void
  258.     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
  259.     noexcept(noexcept(__one.swap(__two)))
  260.     { __one.swap(__two); }
  261.  
  262.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  263.     constexpr _Tp&
  264.     get(array<_Tp, _Nm>& __arr) noexcept
  265.     {
  266.       static_assert(_Int < _Nm, "index is out of bounds");
  267.       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
  268.         _S_ref(__arr._M_elems, _Int);
  269.     }
  270.  
  271.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  272.     constexpr _Tp&&
  273.     get(array<_Tp, _Nm>&& __arr) noexcept
  274.     {
  275.       static_assert(_Int < _Nm, "index is out of bounds");
  276.       return std::move(get<_Int>(__arr));
  277.     }
  278.  
  279.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  280.     constexpr const _Tp&
  281.     get(const array<_Tp, _Nm>& __arr) noexcept
  282.     {
  283.       static_assert(_Int < _Nm, "index is out of bounds");
  284.       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
  285.         _S_ref(__arr._M_elems, _Int);
  286.     }
  287. } // namespace __debug
  288.  
  289.   // Tuple interface to class template array.
  290.  
  291.   /// tuple_size
  292.   template<typename _Tp, std::size_t _Nm>
  293.     struct tuple_size<__debug::array<_Tp, _Nm>>
  294.     : public integral_constant<std::size_t, _Nm> { };
  295.  
  296.   /// tuple_element
  297.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  298.     struct tuple_element<_Int, __debug::array<_Tp, _Nm>>
  299.     {
  300.       static_assert(_Int < _Nm, "index is out of bounds");
  301.       typedef _Tp type;
  302.     };
  303. } // namespace std
  304.  
  305. #endif // _GLIBCXX_DEBUG_ARRAY
  306.