#include <cstddef>
#include <memory>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <functional>
#include <cstdio>
template <class T>
struct custom_allocator {
typedef T value_type;
custom_allocator() noexcept {
printf("custom_allocator(): this=%p T=%lu\n", this, sizeof(T));
}
template <class U> custom_allocator (const custom_allocator<U>& a) noexcept {
printf("custom_allocator(<U>%p): this=%p T=%lu U=%lu\n", &a, this, sizeof(T), sizeof(U));
}
T* allocate (std::size_t n) {
void* p = malloc(n * sizeof(T));
printf("allocate(%lu): this=%p T=%lu ptr=%p\n", n, this, sizeof(T), p);
return static_cast<T*>(p);
}
void deallocate (T* p, std::size_t n) {
printf("deallocate(%p, %lu): this=%p\n", p, n, this);
free((void*)p);
}
};
template <class T, class U>
constexpr bool operator== (const custom_allocator<T>&, const custom_allocator<U>&) noexcept {
return ((sizeof(T) + 15) & ~15) == ((sizeof(U) + 15) & ~15);
}
template <class T, class U>
constexpr bool operator!= (const custom_allocator<T>& t, const custom_allocator<U>& u) noexcept {
return !(t == u);
}
struct s1 {
int x;
int y;
s1(int x = 0, int y = 0) : x(x), y(y) {
printf("s1(int=0, int=0): %d, %d\n", x, y);
}
s1(const s1& s) : x(s.x), y(s.y) {
printf("s1(const s1&): %d, %d\n", s.x, s.y);
}
bool operator== (const s1& s) const { return x == s.x && y == s.y; }
bool operator< (const s1& s) const { return x < s.x && y < s.y; }
struct hash {
bool operator() (const s1& s) const { return std::hash<int>()(s.x ^ s.y); }
};
};
int main () {
std::vector<s1> v1 = {{1, 2}, {3, 4}, {5, 6}};
printf("\n -- vector --\n");
std::vector<s1, custom_allocator<s1>> v(4);
v.insert(v.end(), v1.begin(), v1.end());
v.insert(v.end(), v1.begin(), v1.end());
printf("\n -- deque --\n");
std::deque<s1, custom_allocator<s1>> d(4);
d.insert(d.end(), v1.begin(), v1.end());
d.insert(d.end(), v1.begin(), v1.end());
printf("\n -- list --\n");
std::list<s1, custom_allocator<s1>> l(4);
l.insert(l.end(), v1.begin(), v1.end());
l.insert(l.end(), v1.begin(), v1.end());
printf("\n -- set --\n");
std::set<s1, std::less<s1>, custom_allocator<s1>> s;
s.insert(v1.begin(), v1.end());
s.insert(v1.begin(), v1.end());
printf("\n -- multiset --\n");
std::multiset<s1, std::less<s1>, custom_allocator<s1>> ms;
ms.insert(v1.begin(), v1.end());
ms.insert(v1.begin(), v1.end());
printf("\n -- unordered_set --\n");
std::unordered_set<s1, s1::hash, std::equal_to<s1>, custom_allocator<s1>> us;
us.insert(v1.begin(), v1.end());
us.insert(v1.begin(), v1.end());
printf("\n -- unordered_multiset --\n");
std::unordered_multiset<s1, s1::hash, std::equal_to<s1>, custom_allocator<s1>> ums;
ums.insert(v1.begin(), v1.end());
printf("\n -- finish --\n");
return 0;
}
gcc -Wextra -O2 -o explain_allocators explain_allocators.cpp -lstdc++ -std=c++11