I need a container class with API as close as possible to std::vector (except no reallocation), but whose elements' storage (and not its member variables such as size) can be specified to be allocated from an existing buffer, so that I can have all vectors' held elements in a contiguous buffer. That is, .end() of one vector points to the same element in the buffer as .front() of the next.
I don't know whether I can simply use a custom allocator with std::vector, because I can't find information on whether that allocates storage for the whole class including the size and pointer data members (in which case I can't use this approach), or just the data elements it holds (in which case I can use it).
I only need an instance's storage to be allocated once, so there's no issue with reallocation. I'm posting here to see if there's already such a container published, rather than reimplementing most of the std vector interface with iterators etc. from scratch.
Update: I unchecked the answer that was posted because it doesn't work in debug mode in Visual C++ 2012. Example with T
= float
:
template<class T>
inline typename ContigAlloc<T>::pointer ContigAlloc<T>::allocate(std::size_t n)
{
std::cout << "Alloc " << n << "; type match: " << std::boolalpha << std::is_same<T, float>::value << std::endl;
return reinterpret_cast<T *>(_buff.alloc(T * sizeof(n)));
}
template<class T>
inline void ContigAlloc<T>::deallocate(T *p, std::size_t n) // TODO: noexcept when VC++2013
{
std::cout << "Deall " << n << "; type match: " << std::boolalpha << std::is_same<T, float>::value << std::endl;
_buff.dealloc(p, T * sizeof(n));
}
Test:
std::vector<float, ContigAlloc<float>> vec;
vec.push_back(1.1f);
vec.push_back(1.9f);
Result in Release build is fine:
Alloc 1; type match: true
Alloc 2; type match: true
Deall 1; type match: true
Deall 2; type match: true
Result in Debug build is not fine:
Alloc 1; type match: false
Alloc 1; type match: true
Alloc 2; type match: true
Deall 1; type match: true
Deall 2; type match: true
Deall 1; type match: false
In the first call to allocate()
, T
= _Container_proxy