sl@0: /* The following code declares class array, sl@0: * an STL container (as wrapper) for arrays of constant size. sl@0: * sl@0: * See sl@0: * http://www.boost.org/libs/array/ sl@0: * for documentation. sl@0: * sl@0: * The original author site is at: http://www.josuttis.com/ sl@0: * sl@0: * (C) Copyright Nicolai M. Josuttis 2001. sl@0: * sl@0: * Distributed under the Boost Software License, Version 1.0. (See sl@0: * accompanying file LICENSE_1_0.txt or copy at sl@0: * http://www.boost.org/LICENSE_1_0.txt) sl@0: * sl@0: * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis) sl@0: * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries. sl@0: * 05 Aug 2001 - minor update (Nico Josuttis) sl@0: * 20 Jan 2001 - STLport fix (Beman Dawes) sl@0: * 29 Sep 2000 - Initial Revision (Nico Josuttis) sl@0: * sl@0: * Jan 29, 2004 sl@0: */ sl@0: #ifndef BOOST_ARRAY_HPP sl@0: #define BOOST_ARRAY_HPP sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: // Handles broken standard libraries better than sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: // FIXES for broken compilers sl@0: #include sl@0: sl@0: sl@0: namespace boost { sl@0: sl@0: template sl@0: class array { sl@0: public: sl@0: T elems[N]; // fixed-size array of elements of type T sl@0: sl@0: public: sl@0: // type definitions sl@0: typedef T value_type; sl@0: typedef T* iterator; sl@0: typedef const T* const_iterator; sl@0: typedef T& reference; sl@0: typedef const T& const_reference; sl@0: typedef std::size_t size_type; sl@0: typedef std::ptrdiff_t difference_type; sl@0: sl@0: // iterator support sl@0: iterator begin() { return elems; } sl@0: const_iterator begin() const { return elems; } sl@0: iterator end() { return elems+N; } sl@0: const_iterator end() const { return elems+N; } sl@0: sl@0: // reverse iterator support sl@0: #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) sl@0: typedef std::reverse_iterator reverse_iterator; sl@0: typedef std::reverse_iterator const_reverse_iterator; sl@0: #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) sl@0: // workaround for broken reverse_iterator in VC7 sl@0: typedef std::reverse_iterator > reverse_iterator; sl@0: typedef std::reverse_iterator > const_reverse_iterator; sl@0: #else sl@0: // workaround for broken reverse_iterator implementations sl@0: typedef std::reverse_iterator reverse_iterator; sl@0: typedef std::reverse_iterator const_reverse_iterator; sl@0: #endif sl@0: sl@0: reverse_iterator rbegin() { return reverse_iterator(end()); } sl@0: const_reverse_iterator rbegin() const { sl@0: return const_reverse_iterator(end()); sl@0: } sl@0: reverse_iterator rend() { return reverse_iterator(begin()); } sl@0: const_reverse_iterator rend() const { sl@0: return const_reverse_iterator(begin()); sl@0: } sl@0: sl@0: // operator[] sl@0: reference operator[](size_type i) sl@0: { sl@0: BOOST_ASSERT( i < N && "out of range" ); sl@0: return elems[i]; sl@0: } sl@0: sl@0: const_reference operator[](size_type i) const sl@0: { sl@0: BOOST_ASSERT( i < N && "out of range" ); sl@0: return elems[i]; sl@0: } sl@0: sl@0: // at() with range check sl@0: reference at(size_type i) { rangecheck(i); return elems[i]; } sl@0: const_reference at(size_type i) const { rangecheck(i); return elems[i]; } sl@0: sl@0: // front() and back() sl@0: reference front() sl@0: { sl@0: return elems[0]; sl@0: } sl@0: sl@0: const_reference front() const sl@0: { sl@0: return elems[0]; sl@0: } sl@0: sl@0: reference back() sl@0: { sl@0: return elems[N-1]; sl@0: } sl@0: sl@0: const_reference back() const sl@0: { sl@0: return elems[N-1]; sl@0: } sl@0: sl@0: // size is constant sl@0: static size_type size() { return N; } sl@0: static bool empty() { return false; } sl@0: static size_type max_size() { return N; } sl@0: enum { static_size = N }; sl@0: sl@0: // swap (note: linear complexity) sl@0: void swap (array& y) { sl@0: std::swap_ranges(begin(),end(),y.begin()); sl@0: } sl@0: sl@0: // direct access to data (read-only) sl@0: const T* data() const { return elems; } sl@0: T* data() { return elems; } sl@0: sl@0: // use array as C array (direct read/write access to data) sl@0: T* c_array() { return elems; } sl@0: sl@0: // assignment with type conversion sl@0: template sl@0: array& operator= (const array& rhs) { sl@0: std::copy(rhs.begin(),rhs.end(), begin()); sl@0: return *this; sl@0: } sl@0: sl@0: // assign one value to all elements sl@0: void assign (const T& value) sl@0: { sl@0: std::fill_n(begin(),size(),value); sl@0: } sl@0: sl@0: // check range (may be private because it is static) sl@0: static void rangecheck (size_type i) { sl@0: if (i >= size()) { sl@0: throw std::range_error("array<>: index out of range"); sl@0: } sl@0: } sl@0: sl@0: }; sl@0: sl@0: #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) sl@0: template< class T > sl@0: class array< T, 0 > { sl@0: sl@0: public: sl@0: // type definitions sl@0: typedef T value_type; sl@0: typedef T* iterator; sl@0: typedef const T* const_iterator; sl@0: typedef T& reference; sl@0: typedef const T& const_reference; sl@0: typedef std::size_t size_type; sl@0: typedef std::ptrdiff_t difference_type; sl@0: sl@0: // iterator support sl@0: iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); } sl@0: const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } sl@0: iterator end() { return begin(); } sl@0: const_iterator end() const { return begin(); } sl@0: sl@0: // reverse iterator support sl@0: #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) sl@0: typedef std::reverse_iterator reverse_iterator; sl@0: typedef std::reverse_iterator const_reverse_iterator; sl@0: #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) sl@0: // workaround for broken reverse_iterator in VC7 sl@0: typedef std::reverse_iterator > reverse_iterator; sl@0: typedef std::reverse_iterator > const_reverse_iterator; sl@0: #else sl@0: // workaround for broken reverse_iterator implementations sl@0: typedef std::reverse_iterator reverse_iterator; sl@0: typedef std::reverse_iterator const_reverse_iterator; sl@0: #endif sl@0: sl@0: reverse_iterator rbegin() { return reverse_iterator(end()); } sl@0: const_reverse_iterator rbegin() const { sl@0: return const_reverse_iterator(end()); sl@0: } sl@0: reverse_iterator rend() { return reverse_iterator(begin()); } sl@0: const_reverse_iterator rend() const { sl@0: return const_reverse_iterator(begin()); sl@0: } sl@0: sl@0: // operator[] sl@0: reference operator[](size_type i) sl@0: { sl@0: return failed_rangecheck(); sl@0: } sl@0: sl@0: const_reference operator[](size_type i) const sl@0: { sl@0: return failed_rangecheck(); sl@0: } sl@0: sl@0: // at() with range check sl@0: reference at(size_type i) { return failed_rangecheck(); } sl@0: const_reference at(size_type i) const { return failed_rangecheck(); } sl@0: sl@0: // front() and back() sl@0: reference front() sl@0: { sl@0: return failed_rangecheck(); sl@0: } sl@0: sl@0: const_reference front() const sl@0: { sl@0: return failed_rangecheck(); sl@0: } sl@0: sl@0: reference back() sl@0: { sl@0: return failed_rangecheck(); sl@0: } sl@0: sl@0: const_reference back() const sl@0: { sl@0: return failed_rangecheck(); sl@0: } sl@0: sl@0: // size is constant sl@0: static size_type size() { return 0; } sl@0: static bool empty() { return true; } sl@0: static size_type max_size() { return 0; } sl@0: enum { static_size = 0 }; sl@0: sl@0: void swap (array& y) { sl@0: } sl@0: sl@0: // direct access to data (read-only) sl@0: const T* data() const { return 0; } sl@0: T* data() { return 0; } sl@0: sl@0: // use array as C array (direct read/write access to data) sl@0: T* c_array() { return 0; } sl@0: sl@0: // assignment with type conversion sl@0: template sl@0: array& operator= (const array& ) { sl@0: return *this; sl@0: } sl@0: sl@0: // assign one value to all elements sl@0: void assign (const T& ) { } sl@0: sl@0: // check range (may be private because it is static) sl@0: static reference failed_rangecheck () { sl@0: std::range_error e("attempt to access element of an empty array"); sl@0: boost::throw_exception(e); sl@0: // sl@0: // We need to return something here to keep sl@0: // some compilers happy: however we will never sl@0: // actually get here.... sl@0: // sl@0: static T placeholder; sl@0: return placeholder; sl@0: } sl@0: }; sl@0: #endif sl@0: sl@0: // comparisons sl@0: template sl@0: bool operator== (const array& x, const array& y) { sl@0: return std::equal(x.begin(), x.end(), y.begin()); sl@0: } sl@0: template sl@0: bool operator< (const array& x, const array& y) { sl@0: return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); sl@0: } sl@0: template sl@0: bool operator!= (const array& x, const array& y) { sl@0: return !(x==y); sl@0: } sl@0: template sl@0: bool operator> (const array& x, const array& y) { sl@0: return y sl@0: bool operator<= (const array& x, const array& y) { sl@0: return !(y sl@0: bool operator>= (const array& x, const array& y) { sl@0: return !(x sl@0: inline void swap (array& x, array& y) { sl@0: x.swap(y); sl@0: } sl@0: sl@0: } /* namespace boost */ sl@0: sl@0: #endif /*BOOST_ARRAY_HPP*/