Last active
May 2, 2019 14:52
-
-
Save HungMingWu/4c633fcea591904795c44dcc4bb81d31 to your computer and use it in GitHub Desktop.
A workable C++11 Allocator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <iostream> | |
#include <atomic> | |
#include <memory> | |
namespace my { | |
std::atomic_int g_memory_used{ 0 }; | |
template <typename T> | |
class Allocator : public std::allocator<T> { | |
private: | |
using Base = std::allocator<T>; | |
using Pointer = typename std::allocator_traits<Base>::pointer; | |
using SizeType = typename std::allocator_traits<Base>::size_type; | |
public: | |
Allocator() = default; | |
template <typename U> | |
Allocator(const Allocator<U>& other) : Base(other) {} | |
template <typename U> | |
struct rebind { | |
using other = Allocator<U>; | |
}; | |
Pointer allocate(SizeType n) | |
{ | |
g_memory_used.fetch_add(n * sizeof(T)); | |
return Base::allocate(n); | |
} | |
void deallocate(Pointer p, SizeType n) | |
{ | |
g_memory_used.fetch_sub(n * sizeof(T)); | |
return Base::deallocate(p, n); | |
} | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Allocator.h" | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <list> | |
#include <set> | |
template <template <typename T, typename AllocT> typename ContainerT> | |
void test() | |
{ | |
std::cout << __PRETTY_FUNCTION__ << "\n"; | |
std::cout << "Memory usage before: " << my::g_memory_used.load() << "\n"; | |
ContainerT<int, my::Allocator<int>> cont; | |
for (int i = 0; i < 10; i++) { | |
cont.insert(end(cont), i); | |
} | |
std::cout << "Memory usage after: " << my::g_memory_used.load() << "\n"; | |
} | |
template <typename T, typename AllocT> | |
using SetWithDefaultComparator = std::set<T, std::less<T>, AllocT>; | |
struct Obj { | |
std::string in; | |
int v; | |
Obj(std::string input, int v_) : in(input), v(v_) { | |
std::cout << "Obj::Obj\n"; | |
} | |
~Obj() { | |
std::cout << "Obj::~Obj\n"; | |
} | |
}; | |
int main() | |
{ | |
test<std::vector>(); | |
test<std::list>(); | |
test<SetWithDefaultComparator>(); | |
my::Allocator<Obj> alloc; | |
std::allocate_shared<Obj>(alloc, "123", 14); | |
std::allocate_shared<Obj>(alloc, "17", 14); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment