Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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