// Example program
#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
template <class T>
class static_allocator {
public:
typedef T value_type;
using propagate_on_container_copy_assignment = std::true_type; // for consistency
using propagate_on_container_move_assignment = std::true_type; // to avoid the pessimization
using propagate_on_container_swap = std::true_type; // to avoid the undefined behavior
static_allocator(const std::size_t size) :
m_size(size), m_preallocated(static_cast<T*>(::operator new(size*sizeof(T))))
{}
static_allocator(const static_allocator<T>&) = delete;
T& operator=(const static_allocator<T>&) = delete;
static_allocator(static_allocator<T>&& other) noexcept {
m_size = other.m_size;
m_preallocated = other.m_preallocated;
other.m_preallocated = nullptr;
}
T& operator=(static_allocator<T>&& other) noexcept {
m_size = other.m_size;
m_preallocated = other.m_preallocated;
other.m_preallocated = nullptr;
return *this;
}
T* allocate (const std::size_t n) {
// Throwing bad alloc if size exceeds allocated memory or if memory was moved.
if(n > m_size || !m_preallocated) {
throw std::bad_alloc();
}
return m_preallocated;
}
void deallocate (T*, const std::size_t) {/*no op*/}
std::size_t max_size() const {
return m_size;
}
private:
std::size_t m_size;
T * m_preallocated;
};
int main()
{
std::vector<int, static_allocator<int>> vvv(static_allocator<int>(3));
}