You can always create a dispenser that works with STL. If it works with STL, it should work with boost, since you can pass gain distributors to STL containers.
Considering the above, a distributor that can allocate to a specified memory address AND has a size limit specified by you can be written as follows:
#include <iostream> #include <vector> template<typename T> class CAllocator { private: std::size_t size; T* data = nullptr; public: typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef T value_type; CAllocator() {} CAllocator(pointer data_ptr, size_type max_size) noexcept : size(max_size), data(data_ptr) {}; template<typename U> CAllocator(const CAllocator<U>& other) noexcept {}; CAllocator(const CAllocator &other) : size(other.size), data(other.data) {} template<typename U> struct rebind {typedef CAllocator<U> other;}; pointer allocate(size_type n, const void* hint = 0) {return &data[0];} void deallocate(void* ptr, size_type n) {} size_type max_size() const {return size;} }; template <typename T, typename U> inline bool operator == (const CAllocator<T>&, const CAllocator<U>&) {return true;} template <typename T, typename U> inline bool operator != (const CAllocator<T>& a, const CAllocator<U>& b) {return !(a == b);} int main() { const int size = 1024 / 4; int ptr[size]; std::vector<int, CAllocator<int>> vec(CAllocator<int>(&ptr[0], size)); int ptr2[size]; std::vector<int, CAllocator<int>> vec2(CAllocator<int>(&ptr2[0], size)); vec.push_back(10); vec.push_back(20); vec2.push_back(30); vec2.push_back(40); for (std::size_t i = 0; i < vec2.size(); ++i) { int* val = &ptr2[i]; std::cout<<*val<<"\n"; } std::cout<<"\n\n"; vec2 = vec; for (std::size_t i = 0; i < vec2.size(); ++i) { int* val = &ptr2[i]; std::cout<<*val<<"\n"; } std::cout<<"\n\n"; vec2.clear(); vec2.push_back(100); vec2.push_back(200); for (std::size_t i = 0; i < vec2.size(); ++i) { int* val = &ptr2[i]; std::cout<<*val<<"\n"; } }
This allocator ensures that all memory is allocated to the specified address. No more than what you specify, the freedom of allocation can be allocated if you want whether it is on the stack or heap.
You can create your own pool or use std::unique_ptr as a pool for one container.
EDIT: For strings, you will need a sizeof(_Rep_base) offset sizeof(_Rep_base) . See Why is std :: string highlighting twice?
and http://ideone.com/QWtxWg
It is defined as:
struct _Rep_base { std::size_t _M_length; std::size_t _M_capacity; _Atomic_word _M_refcount; };
So, an example would look like this:
struct Repbase { std::size_t length; std::size_t capacity; std::int16_t refcount; }; int main() { typedef std::basic_string<char, std::char_traits<char>, CAllocator<char>> CAString; const int size = 1024; char ptr[size] = {0}; CAString str(CAllocator<char>(&ptr[0], size)); str = "Hello"; std::cout<<&ptr[sizeof(Repbase)]; }