1169691Skan// class template array -*- C++ -*- 2169691Skan 3169691Skan// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. 4169691Skan// 5169691Skan// This file is part of the GNU ISO C++ Library. This library is free 6169691Skan// software; you can redistribute it and/or modify it under the 7169691Skan// terms of the GNU General Public License as published by the 8169691Skan// Free Software Foundation; either version 2, or (at your option) 9169691Skan// any later version. 10169691Skan 11169691Skan// This library is distributed in the hope that it will be useful, 12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14169691Skan// GNU General Public License for more details. 15169691Skan 16169691Skan// You should have received a copy of the GNU General Public License along 17169691Skan// with this library; see the file COPYING. If not, write to the Free 18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19169691Skan// USA. 20169691Skan 21169691Skan// As a special exception, you may use this file as part of a free software 22169691Skan// library without restriction. Specifically, if other files instantiate 23169691Skan// templates or use macros or inline functions from this file, or you compile 24169691Skan// this file and link it with other files to produce an executable, this 25169691Skan// file does not by itself cause the resulting executable to be covered by 26169691Skan// the GNU General Public License. This exception does not however 27169691Skan// invalidate any other reasons why the executable file might be covered by 28169691Skan// the GNU General Public License. 29169691Skan 30169691Skan/** @file tr1/array 31169691Skan * This is a TR1 C++ Library header. 32169691Skan */ 33169691Skan 34169691Skan#ifndef _TR1_ARRAY 35169691Skan#define _TR1_ARRAY 1 36169691Skan 37169691Skan#include <new> 38169691Skan#include <iterator> 39169691Skan#include <algorithm> 40169691Skan#include <cstddef> 41169691Skan#include <bits/functexcept.h> 42169691Skan#include <ext/type_traits.h> 43169691Skan 44169691Skan//namespace std::tr1 45169691Skannamespace std 46169691Skan{ 47169691Skan_GLIBCXX_BEGIN_NAMESPACE(tr1) 48169691Skan 49169691Skan /// @brief struct array [6.2.2]. 50169691Skan /// NB: Requires complete type _Tp. 51169691Skan template<typename _Tp, std::size_t _Nm> 52169691Skan struct array 53169691Skan { 54169691Skan typedef _Tp value_type; 55169691Skan typedef value_type& reference; 56169691Skan typedef const value_type& const_reference; 57169691Skan typedef value_type* iterator; 58169691Skan typedef const value_type* const_iterator; 59169691Skan typedef std::size_t size_type; 60169691Skan typedef std::ptrdiff_t difference_type; 61169691Skan typedef std::reverse_iterator<iterator> reverse_iterator; 62169691Skan typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 63169691Skan 64169691Skan // Support for zero-sized arrays mandatory. 65169691Skan value_type _M_instance[_Nm ? _Nm : 1] __attribute__((__aligned__)); 66169691Skan 67169691Skan // No explicit construct/copy/destroy for aggregate type. 68169691Skan 69169691Skan void 70169691Skan assign(const value_type& __u) 71169691Skan { std::fill_n(begin(), size(), __u); } 72169691Skan 73169691Skan void 74169691Skan swap(array& __other) 75169691Skan { std::swap_ranges(begin(), end(), __other.begin()); } 76169691Skan 77169691Skan // Iterators. 78169691Skan iterator 79169691Skan begin() 80169691Skan { return iterator(&_M_instance[0]); } 81169691Skan 82169691Skan const_iterator 83169691Skan begin() const 84169691Skan { return const_iterator(&_M_instance[0]); } 85169691Skan 86169691Skan iterator 87169691Skan end() 88169691Skan { return iterator(&_M_instance[_Nm]); } 89169691Skan 90169691Skan const_iterator 91169691Skan end() const 92169691Skan { return const_iterator(&_M_instance[_Nm]); } 93169691Skan 94169691Skan reverse_iterator 95169691Skan rbegin() 96169691Skan { return reverse_iterator(end()); } 97169691Skan 98169691Skan const_reverse_iterator 99169691Skan rbegin() const 100169691Skan { return const_reverse_iterator(end()); } 101169691Skan 102169691Skan reverse_iterator 103169691Skan rend() 104169691Skan { return reverse_iterator(begin()); } 105169691Skan 106169691Skan const_reverse_iterator 107169691Skan rend() const 108169691Skan { return const_reverse_iterator(begin()); } 109169691Skan 110169691Skan // Capacity. 111169691Skan size_type 112169691Skan size() const { return _Nm; } 113169691Skan 114169691Skan size_type 115169691Skan max_size() const { return _Nm; } 116169691Skan 117169691Skan bool 118169691Skan empty() const { return size() == 0; } 119169691Skan 120169691Skan // Element access. 121169691Skan reference 122169691Skan operator[](size_type __n) 123169691Skan { return _M_instance[__n]; } 124169691Skan 125169691Skan const_reference 126169691Skan operator[](size_type __n) const 127169691Skan { return _M_instance[__n]; } 128169691Skan 129169691Skan reference 130169691Skan at(size_type __n) 131169691Skan { 132169691Skan _M_check<_Nm>(__n); 133169691Skan return _M_instance[__n]; 134169691Skan } 135169691Skan 136169691Skan const_reference 137169691Skan at(size_type __n) const 138169691Skan { 139169691Skan _M_check<_Nm>(__n); 140169691Skan return _M_instance[__n]; 141169691Skan } 142169691Skan 143169691Skan reference 144169691Skan front() 145169691Skan { return *begin(); } 146169691Skan 147169691Skan const_reference 148169691Skan front() const 149169691Skan { return *begin(); } 150169691Skan 151169691Skan reference 152169691Skan back() 153169691Skan { return _Nm ? *(end() - 1) : *end(); } 154169691Skan 155169691Skan const_reference 156169691Skan back() const 157169691Skan { return _Nm ? *(end() - 1) : *end(); } 158169691Skan 159169691Skan _Tp* 160169691Skan data() 161169691Skan { return &_M_instance[0]; } 162169691Skan 163169691Skan const _Tp* 164169691Skan data() const 165169691Skan { return &_M_instance[0]; } 166169691Skan 167169691Skan private: 168169691Skan template<std::size_t _Mm> 169169691Skan typename __gnu_cxx::__enable_if<_Mm, void>::__type 170169691Skan _M_check(size_type __n) const 171169691Skan { 172169691Skan if (__builtin_expect(__n >= _Mm, false)) 173169691Skan std::__throw_out_of_range(__N("array::_M_check")); 174169691Skan } 175169691Skan 176169691Skan // Avoid "unsigned comparison with zero" warnings. 177169691Skan template<std::size_t _Mm> 178169691Skan typename __gnu_cxx::__enable_if<!_Mm, void>::__type 179169691Skan _M_check(size_type) const 180169691Skan { std::__throw_out_of_range(__N("array::_M_check")); } 181169691Skan }; 182169691Skan 183169691Skan // Array comparisons. 184169691Skan template<typename _Tp, std::size_t _Nm> 185169691Skan inline bool 186169691Skan operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 187169691Skan { return std::equal(__one.begin(), __one.end(), __two.begin()); } 188169691Skan 189169691Skan template<typename _Tp, std::size_t _Nm> 190169691Skan inline bool 191169691Skan operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 192169691Skan { return !(__one == __two); } 193169691Skan 194169691Skan template<typename _Tp, std::size_t _Nm> 195169691Skan inline bool 196169691Skan operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) 197169691Skan { 198169691Skan return std::lexicographical_compare(__a.begin(), __a.end(), 199169691Skan __b.begin(), __b.end()); 200169691Skan } 201169691Skan 202169691Skan template<typename _Tp, std::size_t _Nm> 203169691Skan inline bool 204169691Skan operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 205169691Skan { return __two < __one; } 206169691Skan 207169691Skan template<typename _Tp, std::size_t _Nm> 208169691Skan inline bool 209169691Skan operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 210169691Skan { return !(__one > __two); } 211169691Skan 212169691Skan template<typename _Tp, std::size_t _Nm> 213169691Skan inline bool 214169691Skan operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 215169691Skan { return !(__one < __two); } 216169691Skan 217169691Skan // Specialized algorithms [6.2.2.2]. 218169691Skan template<typename _Tp, std::size_t _Nm> 219169691Skan inline void 220169691Skan swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) 221169691Skan { std::swap_ranges(__one.begin(), __one.end(), __two.begin()); } 222169691Skan 223169691Skan // Tuple interface to class template array [6.2.2.5]. 224169691Skan template<typename _Tp> class tuple_size; 225169691Skan template<int _Int, typename _Tp> class tuple_element; 226169691Skan 227169691Skan template<typename _Tp, std::size_t _Nm> 228169691Skan struct tuple_size<array<_Tp, _Nm> > 229169691Skan { static const int value = _Nm; }; 230169691Skan 231169691Skan template<typename _Tp, std::size_t _Nm> 232169691Skan const int tuple_size<array<_Tp, _Nm> >::value; 233169691Skan 234169691Skan template<int _Int, typename _Tp, std::size_t _Nm> 235169691Skan struct tuple_element<_Int, array<_Tp, _Nm> > 236169691Skan { typedef _Tp type; }; 237169691Skan 238169691Skan template<int _Int, typename _Tp, std::size_t _Nm> 239169691Skan inline _Tp& 240169691Skan get(array<_Tp, _Nm>& __arr) 241169691Skan { return __arr[_Int]; } 242169691Skan 243169691Skan template<int _Int, typename _Tp, std::size_t _Nm> 244169691Skan inline const _Tp& 245169691Skan get(const array<_Tp, _Nm>& __arr) 246169691Skan { return __arr[_Int]; } 247169691Skan 248169691Skan_GLIBCXX_END_NAMESPACE 249169691Skan} 250169691Skan 251169691Skan#endif 252