/* -*- 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