[Lemon-devel] Array class proposal
Alpár Jüttner
alpar at cs.elte.hu
Thu Jul 26 10:23:15 CEST 2012
Hi,
It is a common problem that one would like use an array of objects, but
(s)he can't because the object either (a) not default constructible or
(b) not copyable. Notably, it is a regular question from LEMON users how
to create an array of NodeMap<>.
If the object is at least default constructible, than you can use
new[]/delete[], otherwise (such as for NodeMap) the only reasonable
solution is using std::vector<Object *> and manually and individually
allocating/deleting the objects.
Note, that even std::array introduced by C++11 fails to solve this
problem, for (1) its size is determined compile-time, and (2) does not
resolve (a).
Instead, I propose another Array implementation, please find the
prototype at the end of this mail.
This is a fixed-size array, but the size is determined run time, i.e. at
construction. Moreover, the objects in the array are constructed using
the parameters passed to Array itself. Thus you can do this:
ListDigraph g;
ListDigraph::Node n;
...
int size = 12;
Array<ListDigraph::NodeMap<int> > map_array(size, g);
map_array[2][n]=5;
map_array[3][n]+=11;
or even:
Array<ListDigraph::NodeMap<bool> > map_array(size, g, true);
map_array[2][n]=false;
What do you think of this idea? Does it worth including into LEMON?
Plus a design question - do we need the _size member? Omitting it would
be result in a narrower layer above the simple pointer it actually
wraps. On the other, it allows a more stl-like interface with size(),
iterators, begin(), end() etc. But to be honest, I see very little use
of them here, except for size().
Regards,
Alpar
// *****************************************************
// * Array class *
// *****************************************************
template<class T >
class Array {
T * _array;
size_t _size;
///Copying is not allowed.
Array(const Array &);
///Copying is not allowed.
Array &operator=(const Array &);
public:
explicit Array(size_t size) : _array(new T[size]), _size(size) {}
template <class T1>
explicit Array(size_t size, T1 t1)
: _array( static_cast<T*>(operator new[] (size*sizeof(T)))),
_size(size)
{
for(size_t i=0;i<size;i++)
new (_array+i) T(t1);
}
template <class T1, class T2>
explicit Array(size_t size, T1 t1, T2 t2)
: _array( static_cast<T*>(operator new[] (size*sizeof(T)))),
_size(size)
{
for(size_t i=0;i<size;i++)
new (_array+i) T(t1,t2);
}
template <class T1, class T2, class T3>
explicit Array(size_t size, T1 t1, T2 t2, T3 t3)
: _array( static_cast<T*>(operator new[] (size*sizeof(T)))),
_size(size)
{
for(size_t i=0;i<size;i++)
new (_array+i) T(t1,t2,t3);
}
template <class T1, class T2, class T3, class T4>
explicit Array(size_t size, T1 t1, T2 t2, T3 t3, T4 t4)
: _array( static_cast<T*>(operator new[] (size*sizeof(T)))),
_size(size)
{
for(size_t i=0;i<size;i++)
new (_array+i) T(t1,t2,t3,t4);
}
template <class T1, class T2, class T3, class T4, class T5>
explicit Array(size_t size, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
: _array( static_cast<T*>(operator new[] (size*sizeof(T)))),
_size(size)
{
for(size_t i=0;i<size;i++)
new (_array+i) T(t1,t2,t3,t4,t5);
}
~Array() { delete [] _array; }
operator T* () { return _array; }
size_t size() { return _size; }
};
}
More information about the Lemon-devel
mailing list