array 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // Profile array implementation -*- C++ -*-
  2. // Copyright (C) 2012-2015 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file profile/array
  21. * This is a Standard C++ Library header.
  22. */
  23. #ifndef _GLIBCXX_PROFILE_ARRAY
  24. #define _GLIBCXX_PROFILE_ARRAY 1
  25. #pragma GCC system_header
  26. namespace std _GLIBCXX_VISIBILITY(default)
  27. {
  28. namespace __profile
  29. {
  30. template<typename _Tp, std::size_t _Nm>
  31. struct array
  32. {
  33. typedef _Tp value_type;
  34. typedef value_type* pointer;
  35. typedef const value_type* const_pointer;
  36. typedef value_type& reference;
  37. typedef const value_type& const_reference;
  38. typedef value_type* iterator;
  39. typedef const value_type* const_iterator;
  40. typedef std::size_t size_type;
  41. typedef std::ptrdiff_t difference_type;
  42. typedef std::reverse_iterator<iterator> reverse_iterator;
  43. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  44. // Support for zero-sized arrays mandatory.
  45. typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
  46. typename _AT_Type::_Type _M_elems;
  47. // No explicit construct/copy/destroy for aggregate type.
  48. // DR 776.
  49. void
  50. fill(const value_type& __u)
  51. { std::fill_n(begin(), size(), __u); }
  52. void
  53. swap(array& __other)
  54. noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())))
  55. { std::swap_ranges(begin(), end(), __other.begin()); }
  56. // Iterators.
  57. iterator
  58. begin() noexcept
  59. { return iterator(data()); }
  60. const_iterator
  61. begin() const noexcept
  62. { return const_iterator(data()); }
  63. iterator
  64. end() noexcept
  65. { return iterator(data() + _Nm); }
  66. const_iterator
  67. end() const noexcept
  68. { return const_iterator(data() + _Nm); }
  69. reverse_iterator
  70. rbegin() noexcept
  71. { return reverse_iterator(end()); }
  72. const_reverse_iterator
  73. rbegin() const noexcept
  74. { return const_reverse_iterator(end()); }
  75. reverse_iterator
  76. rend() noexcept
  77. { return reverse_iterator(begin()); }
  78. const_reverse_iterator
  79. rend() const noexcept
  80. { return const_reverse_iterator(begin()); }
  81. const_iterator
  82. cbegin() const noexcept
  83. { return const_iterator(data()); }
  84. const_iterator
  85. cend() const noexcept
  86. { return const_iterator(data() + _Nm); }
  87. const_reverse_iterator
  88. crbegin() const noexcept
  89. { return const_reverse_iterator(end()); }
  90. const_reverse_iterator
  91. crend() const noexcept
  92. { return const_reverse_iterator(begin()); }
  93. // Capacity.
  94. constexpr size_type
  95. size() const noexcept { return _Nm; }
  96. constexpr size_type
  97. max_size() const noexcept { return _Nm; }
  98. constexpr bool
  99. empty() const noexcept { return size() == 0; }
  100. // Element access.
  101. reference
  102. operator[](size_type __n) noexcept
  103. { return _AT_Type::_S_ref(_M_elems, __n); }
  104. constexpr const_reference
  105. operator[](size_type __n) const noexcept
  106. { return _AT_Type::_S_ref(_M_elems, __n); }
  107. reference
  108. at(size_type __n)
  109. {
  110. if (__n >= _Nm)
  111. std::__throw_out_of_range_fmt(__N("array::at: __n "
  112. "(which is %zu) >= _Nm "
  113. "(which is %zu)"),
  114. __n, _Nm);
  115. return _AT_Type::_S_ref(_M_elems, __n);
  116. }
  117. constexpr const_reference
  118. at(size_type __n) const
  119. {
  120. // Result of conditional expression must be an lvalue so use
  121. // boolean ? lvalue : (throw-expr, lvalue)
  122. return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
  123. : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
  124. ">= _Nm (which is %zu)"),
  125. __n, _Nm),
  126. _AT_Type::_S_ref(_M_elems, 0));
  127. }
  128. reference
  129. front() noexcept
  130. { return *begin(); }
  131. constexpr const_reference
  132. front() const noexcept
  133. { return _AT_Type::_S_ref(_M_elems, 0); }
  134. reference
  135. back() noexcept
  136. { return _Nm ? *(end() - 1) : *end(); }
  137. constexpr const_reference
  138. back() const noexcept
  139. {
  140. return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
  141. : _AT_Type::_S_ref(_M_elems, 0);
  142. }
  143. pointer
  144. data() noexcept
  145. { return _AT_Type::_S_ptr(_M_elems); }
  146. const_pointer
  147. data() const noexcept
  148. { return _AT_Type::_S_ptr(_M_elems); }
  149. };
  150. // Array comparisons.
  151. template<typename _Tp, std::size_t _Nm>
  152. inline bool
  153. operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  154. { return std::equal(__one.begin(), __one.end(), __two.begin()); }
  155. template<typename _Tp, std::size_t _Nm>
  156. inline bool
  157. operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  158. { return !(__one == __two); }
  159. template<typename _Tp, std::size_t _Nm>
  160. inline bool
  161. operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
  162. {
  163. return std::lexicographical_compare(__a.begin(), __a.end(),
  164. __b.begin(), __b.end());
  165. }
  166. template<typename _Tp, std::size_t _Nm>
  167. inline bool
  168. operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  169. { return __two < __one; }
  170. template<typename _Tp, std::size_t _Nm>
  171. inline bool
  172. operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  173. { return !(__one > __two); }
  174. template<typename _Tp, std::size_t _Nm>
  175. inline bool
  176. operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
  177. { return !(__one < __two); }
  178. // Specialized algorithms.
  179. template<typename _Tp, std::size_t _Nm>
  180. inline void
  181. swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
  182. noexcept(noexcept(__one.swap(__two)))
  183. { __one.swap(__two); }
  184. template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  185. constexpr _Tp&
  186. get(array<_Tp, _Nm>& __arr) noexcept
  187. {
  188. static_assert(_Int < _Nm, "index is out of bounds");
  189. return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
  190. _S_ref(__arr._M_elems, _Int);
  191. }
  192. template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  193. constexpr _Tp&&
  194. get(array<_Tp, _Nm>&& __arr) noexcept
  195. {
  196. static_assert(_Int < _Nm, "index is out of bounds");
  197. return std::move(__profile::get<_Int>(__arr));
  198. }
  199. template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  200. constexpr const _Tp&
  201. get(const array<_Tp, _Nm>& __arr) noexcept
  202. {
  203. static_assert(_Int < _Nm, "index is out of bounds");
  204. return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
  205. _S_ref(__arr._M_elems, _Int);
  206. }
  207. } // namespace __profile
  208. // Tuple interface to class template array.
  209. /// tuple_size
  210. template<typename _Tp, std::size_t _Nm>
  211. struct tuple_size<__profile::array<_Tp, _Nm>>
  212. : public integral_constant<std::size_t, _Nm> { };
  213. /// tuple_element
  214. template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  215. struct tuple_element<_Int, __profile::array<_Tp, _Nm>>
  216. {
  217. static_assert(_Int < _Nm, "index is out of bounds");
  218. typedef _Tp type;
  219. };
  220. } // namespace std
  221. #endif // _GLIBCXX_PROFILE_ARRAY