A
Ares Lagae
Hello,
I am trying to create a container the stl way, and I have a couple of
questions. The code of the container in question can be found at
http://www.cs.kuleuven.ac.be/~ares/tmp/array_2_hpp.html
It is a 2d array that dynamically allocates its storage. It cannot be
resized. It offers element access methods for both sequential access and 2d
element access.
It allocates one big chunk of memory.
To avoid computing 1D indices from 2D indices like:
T* elements
elements = new T[rows * cols]
....
return elements[i + (j * cols)]
it then allocates an array of row pointers, that point in this big chunk of
memory:
T** elements
elements = new T*[...] // row pointers
elements[0] = new T[rows * cols] // actual storage
// set row pointers
....
return elements[j]
On the systems I tested, this made a lot of difference.
I have the following questions / thoughts on which I would appreciate
comments.
1) I need two kinds allocators (one for T's and one for T*'s). The exception
safe constructors seem overly complicated. For array_3 I would need an
additional allocator for T**'s, and almost 10 try/catch constructs.
2) Can allocator::deallocate() throw ? I had expected a no throw
declaration.
3) Whats the deal with the allocators ? Do they have instace variables or
not ? Do I need to store them or not ?
4) The std::uninitialized* functions seem to be unusable in this context ?
5) Have a look on how the begin() and end() are implemented. If the size of
the array is 0, then they both return the 0 pointer. Is this OK ?
6) In swap, do the allocators also need to be swapped?
7) std::swap is very important, but it cannot be partially specialized, and
you cannot define an overload in the std namespace ? How do I handle that ?
best regards,
Ares Lagae
I am trying to create a container the stl way, and I have a couple of
questions. The code of the container in question can be found at
http://www.cs.kuleuven.ac.be/~ares/tmp/array_2_hpp.html
It is a 2d array that dynamically allocates its storage. It cannot be
resized. It offers element access methods for both sequential access and 2d
element access.
It allocates one big chunk of memory.
To avoid computing 1D indices from 2D indices like:
T* elements
elements = new T[rows * cols]
....
return elements[i + (j * cols)]
it then allocates an array of row pointers, that point in this big chunk of
memory:
T** elements
elements = new T*[...] // row pointers
elements[0] = new T[rows * cols] // actual storage
// set row pointers
....
return elements[j]
On the systems I tested, this made a lot of difference.
I have the following questions / thoughts on which I would appreciate
comments.
1) I need two kinds allocators (one for T's and one for T*'s). The exception
safe constructors seem overly complicated. For array_3 I would need an
additional allocator for T**'s, and almost 10 try/catch constructs.
2) Can allocator::deallocate() throw ? I had expected a no throw
declaration.
3) Whats the deal with the allocators ? Do they have instace variables or
not ? Do I need to store them or not ?
4) The std::uninitialized* functions seem to be unusable in this context ?
5) Have a look on how the begin() and end() are implemented. If the size of
the array is 0, then they both return the 0 pointer. Is this OK ?
6) In swap, do the allocators also need to be swapped?
7) std::swap is very important, but it cannot be partially specialized, and
you cannot define an overload in the std namespace ? How do I handle that ?
best regards,
Ares Lagae