/* -*- c++ -*- Simple C++ variable array of non-POD objects This file is part of the dpp library of C++ template classes doc: http://diaxen.ssji.net/dpp/index.html repo: https://www.ssji.net/svn/projets/trunk/libdpp This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . (c) 2011 Alexandre Becoulet */ #ifndef DPP_VLARRAY_HH_ #define DPP_VLARRAY_HH_ #include #include #include #include /** @file @module{Variable length array} */ namespace dpp { /** @short Variable length array iterator class @module {Variable length array} @header dpp/vlarray @internal */ template class vlarray_iterator { template friend class vlarray_iterator; template friend class vlarray; vlarray_iterator(X *vlarray, unsigned int i) : _array(vlarray), _i(i) { } public: typedef X value_type; typedef X & reference; typedef const X & const_reference; typedef X * pointer; typedef const X * const_pointer; typedef unsigned int size_type; typedef int difference_type; typedef std::bidirectional_iterator_tag iterator_category; vlarray_iterator() { } template vlarray_iterator(const vlarray_iterator &i) : _array(i._array), _i(i._i) { } X & operator*() { return _array[_i]; } X * operator->() { return &_array[_i]; } vlarray_iterator & operator++() { _i += direction; return *this; } vlarray_iterator operator++(int) { vlarray_iterator tmp(*this); _i += direction; return tmp; } vlarray_iterator & operator--() { _i -= direction; return *this; } vlarray_iterator operator--(int) { vlarray_iterator tmp(*this); _i -= direction; return tmp; } vlarray_iterator operator-(int x) const { return vlarray_iterator(_array, _i - x * direction); } vlarray_iterator operator+(int x) const { return vlarray_iterator(_array, _i + x * direction); } difference_type operator-(const vlarray_iterator & i) const { return (_i - i._i) * direction; } bool operator<(const vlarray_iterator & i) const { return _i < i._i; } bool operator==(const vlarray_iterator &i) const { return _i == i._i; } bool operator!=(const vlarray_iterator &i) const { return _i != i._i; } private: X *_array; unsigned int _i; }; /** @short Variable length array class @module {Variable length array} @header dpp/vlarray Variable lenght arrays of non POD types are not supported in C++. This class provides a container array which uses storage space passed to constructor. The @ref #DPP_VLARRAY macro can be used to declare storage space buffer along with array container, providing variable lenght array feature: @example test/test_vlarray.cc:example */ template class vlarray { public: /** Variable array declaration macro. @This macro declares a buffer array of integers along with a @ref vlarray object and pass the buffer array as storage space to the @ref vlarray constructor. @hidecontent */ #define DPP_VLARRAY(type, size, name) \ uint64_t _##name[sizeof(type) * size / 8 + 1]; \ ::dpp::vlarray name(_##name, size); /* FIXME size alignment */ typedef X value_type; typedef X & reference; typedef const X & const_reference; typedef X * pointer; typedef const X * const_pointer; typedef unsigned int size_type; typedef int difference_type; typedef vlarray_iterator iterator; typedef vlarray_iterator const_iterator; typedef vlarray_iterator reverse_iterator; typedef vlarray_iterator const_reverse_iterator; /* @This declare a variable lenght array with given storage space and elements count. The default constructor is invoked for all new array items. */ vlarray(void *array, size_t size) : _array((X*)array), _size(size) { for (size_t i = 0; i < _size; i++) new ((X*)(_array + i)) X(); } /* @This invokes destructor for all array items */ ~vlarray() { for (size_t i = 0; i < _size; i++) (_array + i)->~X(); } size_t size() const { return _size; } size_t capacity() const { return _size; } X & operator[](int i) { return _array[i]; } const X & operator[](int i) const { return _array[i]; } X & at(int i) { if (i >= _size) throw std::out_of_range(""); return _array[i]; } const X & at(int i) const { if (i >= _size) throw std::out_of_range(""); return _array[i]; } /** @This returns @ref iterator to first object in pool */ iterator begin() { return iterator(_array, 0); } /** @This returns end @ref iterator */ iterator end() { return iterator(_array, size()); } /** @This returns @ref const_iterator to first object in pool */ const_iterator begin() const { return const_iterator(_array, 0); } /** @This returns end @ref const_iterator */ const_iterator end() const { return const_iterator(_array, size()); } /** @This returns @ref reverse_iterator to last object in pool */ reverse_iterator rbegin() { return reverse_iterator(_array, size() - 1); } /** @This returns end @ref reverse_iterator */ reverse_iterator rend() { return reverse_iterator(_array, -1); } /** @This returns @ref const_reverse_iterator to first object in pool */ const_reverse_iterator rbegin() const { return const_reverse_iterator(_array, size() - 1); } /** @This returns end @ref const_reverse_iterator */ const_reverse_iterator rend() const { return const_reverse_iterator(_array, -1); } private: X *_array; size_t _size; }; } #endif