Subversion Repositories Kolibri OS

Rev

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

  1. // Profile 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 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)
  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(__N("array::at"));
  142.         return _AT_Type::_S_ref(_M_elems, __n);
  143.       }
  144.  
  145.       constexpr const_reference
  146.       at(size_type __n) const
  147.       {
  148.         // Result of conditional expression must be an lvalue so use
  149.         // boolean ? lvalue : (throw-expr, lvalue)
  150.         return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
  151.           : (std::__throw_out_of_range(__N("array::at")),
  152.              _AT_Type::_S_ref(_M_elems, 0));
  153.       }
  154.  
  155.       reference
  156.       front()
  157.       { return *begin(); }
  158.  
  159.       constexpr const_reference
  160.       front() const
  161.       { return _AT_Type::_S_ref(_M_elems, 0); }
  162.  
  163.       reference
  164.       back()
  165.       { return _Nm ? *(end() - 1) : *end(); }
  166.  
  167.       constexpr const_reference
  168.       back() const
  169.       {
  170.         return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
  171.                    : _AT_Type::_S_ref(_M_elems, 0);      
  172.       }
  173.  
  174.       pointer
  175.       data() noexcept
  176.       { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
  177.  
  178.       const_pointer
  179.       data() const noexcept
  180.       { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
  181.     };
  182.  
  183.   // Array comparisons.
  184.   template<typename _Tp, std::size_t _Nm>
  185.     inline bool
  186.     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  187.     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
  188.  
  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 !(__one == __two); }
  193.  
  194.   template<typename _Tp, std::size_t _Nm>
  195.     inline bool
  196.     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
  197.     {
  198.       return std::lexicographical_compare(__a.begin(), __a.end(),
  199.                                           __b.begin(), __b.end());
  200.     }
  201.  
  202.   template<typename _Tp, std::size_t _Nm>
  203.     inline bool
  204.     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  205.     { return __two < __one; }
  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 !(__one > __two); }
  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.   // Specialized algorithms.
  218.   template<typename _Tp, std::size_t _Nm>
  219.     inline void
  220.     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
  221.     noexcept(noexcept(__one.swap(__two)))
  222.     { __one.swap(__two); }
  223.  
  224.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  225.     constexpr _Tp&
  226.     get(array<_Tp, _Nm>& __arr) noexcept
  227.     {
  228.       static_assert(_Int < _Nm, "index is out of bounds");
  229.       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
  230.         _S_ref(__arr._M_elems, _Int);
  231.     }
  232.  
  233.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  234.     constexpr _Tp&&
  235.     get(array<_Tp, _Nm>&& __arr) noexcept
  236.     {
  237.       static_assert(_Int < _Nm, "index is out of bounds");
  238.       return std::move(get<_Int>(__arr));
  239.     }
  240.  
  241.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  242.     constexpr const _Tp&
  243.     get(const array<_Tp, _Nm>& __arr) noexcept
  244.     {
  245.       static_assert(_Int < _Nm, "index is out of bounds");
  246.       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
  247.         _S_ref(__arr._M_elems, _Int);
  248.     }
  249. } // namespace __profile
  250.  
  251.   // Tuple interface to class template array.
  252.  
  253.   /// tuple_size
  254.   template<typename _Tp, std::size_t _Nm>
  255.     struct tuple_size<__profile::array<_Tp, _Nm>>
  256.     : public integral_constant<std::size_t, _Nm> { };
  257.  
  258.   /// tuple_element
  259.   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  260.     struct tuple_element<_Int, __profile::array<_Tp, _Nm>>
  261.     {
  262.       static_assert(_Int < _Nm, "index is out of bounds");
  263.       typedef _Tp type;
  264.     };
  265. } // namespace std
  266.  
  267. #endif // _GLIBCXX_PROFILE_ARRAY
  268.