/* The following code declares class v_array, * an STL container (as wrapper) for variable-length array. * * (C) Copyright Nicolai M. Josuttis 2001. * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis) * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries. * 05 Aug 2001 - minor update (Nico Josuttis) * 20 Jan 2001 - STLport fix (Beman Dawes) * 29 Sep 2000 - Initial Revision (Nico Josuttis) * * Jan 29, 2004 */ #ifndef BOOST_V_ARRAY_HPP #define BOOST_V_ARRAY_HPP #include #include #include // Handles broken standard libraries better than #include #include // FIXES for broken compilers #include namespace boost { template class v_array { public: // type definitions typedef T value_type; typedef T* iterator; typedef const T* const_iterator; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; v_array (T *elems, size_type size) : m_elems (elems), m_size (size) { } T *m_elems; // pointer of dynamic size array of elements of type T size_type m_size; // array size // iterator support iterator begin() { return m_elems; } const_iterator begin() const { return m_elems; } iterator end() { return m_elems+m_size; } const_iterator end() const { return m_elems+m_size; } // reverse iterator support #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) // workaround for broken reverse_iterator in VC7 typedef std::reverse_iterator > reverse_iterator; typedef std::reverse_iterator > const_reverse_iterator; #else // workaround for broken reverse_iterator implementations typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #endif reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } // operator[] reference operator[](size_type i) { BOOST_ASSERT( i < m_size && "out of range" ); return m_elems[i]; } const_reference operator[](size_type i) const { BOOST_ASSERT( i < m_size && "out of range" ); return m_elems[i]; } // at() with range check reference at(size_type i) { rangecheck(i); return m_elems[i]; } const_reference at(size_type i) const { rangecheck(i); return m_elems[i]; } // front() and back() reference front() { return m_elems[0]; } const_reference front() const { return m_elems[0]; } reference back() { return m_elems[m_size-1]; } const_reference back() const { return m_elems[m_size-1]; } // size is constant size_type size() { return m_size; } const bool empty() { return m_size > 0 ? false : true; } const size_type max_size() { return m_size; } const // swap (note: linear complexity) void swap (v_array& y) { std::swap_ranges(begin(), begin () + std::min (size (), y.size ()), y.begin()); } // direct access to data (read-only) const T* data() const { return m_elems; } // use array as C array (direct read/write access to data) T* c_array() { return m_elems; } // assignment with type conversion template v_array& operator= (const v_array& rhs) { std::copy(rhs.begin(), rhs.begin() + std::min (size (), rhs.size ()), begin()); return *this; } // assign one value to all elements void assign (const T& value) { std::fill_n(begin(),size(),value); } private: static void rangecheck (size_type i) { if (i >= size()) { throw std::range_error("v_array<>: index out of range"); } } }; // comparisons template bool operator== (const v_array& x, const v_array& y) { return x.size() == y.size () && std::equal(x.begin(), x.end(), y.begin()); } template bool operator< (const v_array& x, const v_array& y) { return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); } template bool operator!= (const v_array& x, const v_array& y) { return !(x==y); } template bool operator> (const v_array& x, const v_array& y) { return y bool operator<= (const v_array& x, const v_array& y) { return !(y bool operator>= (const v_array& x, const v_array& y) { return !(x inline void swap (v_array& x, v_array& y) { x.swap(y); } } /* namespace boost */ #define BOOST_V_ARRAY(name,TYPE,size) \ size_t __boost_name##_size = (size); \ boost::v_array name((TYPE *) alloca (sizeof (TYPE) * (__boost_name##_size)), (__boost_name_size)) #endif /*BOOST_V_ARRAY_HPP*/