The code is composed of the following:
_Vector_impl
: a std::allocator
that imitates a std::vector
or a stl container, it is our custom container keeping reference to data set (the input array or stl container)
wrapRawArray
: a function for turning array[]
into our custom container
#include <iostream>
#include <vector>
#include <string>
using namespace std;
template<typename _Tp, typename _Alloc>
struct _Vector_base
{
struct _Vector_impl : public _Alloc
{
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
// etc
};
// etc
};
template<class T>
using vectorType = vector<T, allocator<T>>;
template<class T>
using vectorImpl = typename _Vector_base<T, allocator<T>>::_Vector_impl;
template<typename T, size_t N>
bool wrapRawArray(T(&_array)[N], vectorType<T>* _container)
{
vectorImpl<T>* vectImpl = (vectorImpl<T>*)((void*)_container);
vectImpl->_M_start = _array;
vectImpl->_M_finish = vectImpl->_M_end_of_storage = vectImpl->_M_start + N;
return true;
}
template<typename T>
void releaseRawArray(vectorType<T>* _container) {
vectorImpl<T>* vectImpl = (vectorImpl<T>*)((void*)_container);
vectImpl->_M_finish = vectImpl->_M_end_of_storage = vectImpl->_M_start = nullptr;
}
template<class Container, typename T>
class ProxyContainer
{
Container* container{ nullptr };
size_t size;
bool isRawArray{ false };
static string errorMessage;
public:
explicit ProxyContainer(Container& _container)
:container(&_container), size(_container.size()), isRawArray(false) {}
template<size_t N>
explicit ProxyContainer(T(&_array)[N])
:container(new Container) {
size = N;
isRawArray = wrapRawArray<T>(_array, container);
}
~ProxyContainer() {
if (isRawArray) {
releaseRawArray<T>(container);
if (container) {
delete container;
container = nullptr;
}
}
}
T& operator[](size_t index) {
if (index >= size) {
throw out_of_range(ProxyContainer<Container, T>::errorMessage
+ to_string(index));
}
return container->at(index);
}
void changeModel(Container& _container) {
container = &_container;
size = _container.size();
isRawArray = false;
}
};
int main()
{
// Raw array
int arr[] = { 1,2,3 };
ProxyContainer<vector<int>, int> proxyForRawArray(arr);
proxyForRawArray[1] = 9; // throws out of bound error, the code shows runtime error at stl <vector> file line 1906 where at() function break due to container is sized 0 and input index is 1.
}
The problem obvious lie in class _Vector_impl
which did not realize the allocator. First time using this std::allocator
class I have no idea what need to override or do.
New contributor
Mary Guty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
4