// class template array -*- C++ -*-

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.

/** @file 
 *  This is a TR1 C++ Library header. 
 */

#ifndef _ARRAY
#define _ARRAY 1

#include <new>
#include <iterator>
#include <algorithm>
#include <bits/functexcept.h>

//namespace std::tr1
namespace std
{
namespace tr1
{
  /// @brief  struct array [6.2.2].
  /// NB: Requires complete type _Tp.
  template<typename _Tp, size_t _Nm = 1>
    struct array
    {
      typedef _Tp 	    			value_type;
      typedef value_type&                   	reference;
      typedef const value_type&             	const_reference;
      typedef value_type*          		iterator;
      typedef const value_type*			const_iterator;
      typedef size_t                    	size_type;
      typedef ptrdiff_t                     	difference_type;
      typedef std::reverse_iterator<iterator>	reverse_iterator;
      typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;

      // Compile time constant without other dependencies.
      enum { _S_index = _Nm };

      // Support for zero-sized arrays mandatory.
      value_type _M_instance[_Nm ? _Nm : 1];

      // No explicit construct/copy/destroy for aggregate type.

      void 
      assign(const value_type& u); 

      void 
      swap(array&);

      // Iterators.
      iterator 
      begin()
      { return reinterpret_cast<iterator>(&_M_instance[0]); }

      const_iterator 
      begin() const 
      { return reinterpret_cast<const_iterator>(&_M_instance[0]); }

      iterator 
      end() 
      { return reinterpret_cast<iterator>(&_M_instance[_Nm]); }

      const_iterator 
      end() const
      { return reinterpret_cast<const_iterator>(&_M_instance[_Nm]); }

      reverse_iterator 
      rbegin()
      { return reverse_iterator(this->end()); }

      const_reverse_iterator 
      rbegin() const
      { return const_reverse_iterator(this->end()); }

      reverse_iterator 
      rend()
      { return reverse_iterator(this->begin()); }

      const_reverse_iterator 
      rend() const
      { return const_reverse_iterator(this->begin()); }

      // Capacity.
      size_type 
      size() const { return _Nm; }

      size_type 
      max_size() const { return _Nm; }

      bool 
      empty() const { return size() == 0; }

      // Element access.
      reference 
      operator[](size_type __n)
      { return reinterpret_cast<reference>(_M_instance[__n]); }

      const_reference 
      operator[](size_type __n) const
      { return reinterpret_cast<const_reference>(_M_instance[__n]); }

      const_reference 
      at(size_type __n) const
      { 
	if (__builtin_expect(__n > _Nm, false))
	  std::__throw_out_of_range("array::at");
	return reinterpret_cast<const_reference>(_M_instance[__n]); 
      }

      reference 
      at(size_type __n)
      { 
	if (__builtin_expect(__n > _Nm, false))
	  std::__throw_out_of_range("array::at");
	return reinterpret_cast<reference>(_M_instance[__n]); 
      }

      reference 
      front(); 

      const_reference 
      front() const; 

      reference 
      back(); 

      const_reference 
      back() const; 

      _Tp* 
      data(); 

      const _Tp* 
      data() const;
    };

  // Array comparisons.
 template<typename _Tp, size_t _Nm>
   bool 
   operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
   { return std::equal(__one.begin(), __one.end(), __two.begin()); }

 template<typename _Tp, size_t _Nm>
   bool 
   operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
   { return !(__one == __two); }

 template<typename _Tp, size_t _Nm>
   bool 
   operator<(const array<_Tp, _Nm>& a, const array<_Tp, _Nm>& b)
   { 
     return std::lexicographical_compare(a.begin(), a.end(), 
					 b.begin(), b.end()); 
   }

 template<typename _Tp, size_t _Nm>
   bool 
   operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
   { return __two < __one; }

 template<typename _Tp, size_t _Nm>
   bool 
   operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
   { return !(__one > __two); }

 template<typename _Tp, size_t _Nm>
   bool 
   operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
   { return !(__one < __two); }

  // Specialized algorithms [6.2.2.2].
 template<typename _Tp, size_t _Nm>
   void
   swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
   { swap_ranges(__one.begin(), __one.end(), __two.begin()); }
} // namespace std::tr1
}

#endif
