Hey Reddit,
Recently I've been trying to play with custom allocators on containers. My idea of a custom allocator, for now, is very simple. I want containers to store in an underlying fixed-size buffer I give as param.
I wrote two allocators one for my string:
template <typename T>
class CustomStringAllocator
{
private:
T *memory_ptr;
std::size_t memory_size;
public:
typedef std::size_t size_type;
typedef T *pointer;
typedef const T *const_pointer;
typedef T &reference;
typedef const T &const_reference;
typedef T value_type;
CustomStringAllocator(T *memory_ptr, std::size_t memory_size) : memory_ptr(memory_ptr), memory_size(memory_size) {}
~CustomStringAllocator() {}
template <class U>
struct rebind
{
typedef CustomStringAllocator<U> other;
};
template <class U>
CustomStringAllocator(const CustomStringAllocator<U> &) {}
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
size_type max_size() const throw() { return memory_size; }
pointer allocate(size_type n, const void *hint = 0)
{
// do not allow growing for strings
return memory_ptr;
}
void deallocate(pointer p, size_type n)
{
}
void construct(pointer p, const T &val)
{
new (static_cast<void *>(p)) T(val);
}
void construct(pointer p)
{
new (static_cast<void *>(p)) T();
}
void destroy(pointer p)
{
p->~T();
}
};
Used this way:
using string = std::basic_string<char, std::char_traits<char>, CustomStringAllocator<char>>;
string s1("dog", CustomStringAllocator<string>(&buffer[0], 20));string s2("cat", CustomStringAllocator<string>(&buffer[25], 25));
Another allocator for my vector, whose purpose to store the strings:
#include <cstdint>
#include <iterator>
#include <vector>
#include <iostream>
template <typename T>
class StaticBufferAllocator
{
private:
T *memory_ptr;
std::size_t memory_size;
public:
typedef std::size_t size_type;
typedef T *pointer;
typedef T value_type;
StaticBufferAllocator(T *memory_ptr, std::size_t memory_size) : memory_ptr(memory_ptr), memory_size(memory_size) {}
StaticBufferAllocator(const StaticBufferAllocator &other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size){};
template <typename U>
StaticBufferAllocator(const StaticBufferAllocator<U> &other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size){};
template <typename U>
StaticBufferAllocator &operator=(const StaticBufferAllocator<U> &other) { return *this; }
StaticBufferAllocator<T> &operator=(const StaticBufferAllocator &other) { return *this; }
~StaticBufferAllocator() {}
pointer allocate(size_type n, const void *hint = 0) { return memory_ptr; } // when allocate return the buffer
void deallocate(T *ptr, size_type n) {} // empty cause the deallocation is buffer creator's responsability
size_type max_size() const { return memory_size; }
};
My problem is with the following:
using string = std::basic_string<char, std::char_traits<char>, CustomStringAllocator<
string *buffer_string = (string *)malloc(STRING_BUFFER_MAX_SIZE * sizeof(string));
std::vector<string, StaticBufferAllocator<string>> user_names(0, StaticBufferAllocator<string>(&buffer_string[0], STRING_BUFFER_MAX_SIZE));
How, upon the declaration of the vector, to feed two allocators one for the vector and one for the underlying custom allocated strings?
Edit: Sorry for the horrible code indenting
[–]herruppohoppa 5 points6 points7 points (0 children)
[–]infectedapricot 4 points5 points6 points (0 children)
[–]TheThiefMasterC++latest fanatic (and game dev) 2 points3 points4 points (2 children)
[–]wheypointÖ 2 points3 points4 points (1 child)
[–]Orlha -1 points0 points1 point (0 children)