[Lemon-user] [Lemon-devel] Array class proposal

Alpár Jüttner alpar at cs.elte.hu
Thu Jul 26 16:06:39 CEST 2012


Two caveats concerning the array implementation of the previous mail:

      * The declarations 'T1 t1' in the constructor parameter lists
        should be changed to 'T1 &t1' or 'const T1 &t1'. In fact, both
        versions should be implemented. Even worse, all possible
        combinations of const/non-const parameters should be
        implemented. Any idea how to do it correctly? Maybe a pair of
        recursive call of the constructor having one less parameters?
      * The way how the memory block is allocated is wrong. Sometimes
        (not always it crashes at the call of delete []. Does anyone
        know how to correctly allocate a memory block which is to be
        deallocated by delete []?
        An alternative is the use std::allocator<>, but it seems to
        increase the memory footprint a bit.
        
Regards,
Alpar


On Thu, 2012-07-26 at 10:24 +0200, Alpár Jüttner wrote:
> 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; }
>   };
> }
> 
> 
> _______________________________________________
> Lemon-devel mailing list
> Lemon-devel at lemon.cs.elte.hu
> http://lemon.cs.elte.hu/mailman/listinfo/lemon-devel
> 
> 
> 
> _______________________________________________
> Lemon-user mailing list
> Lemon-user at lemon.cs.elte.hu
> http://lemon.cs.elte.hu/mailman/listinfo/lemon-user
> 





More information about the Lemon-user mailing list