2 * Copyright 2012 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef FOLLY_STLALLOCATOR_H_
18 #define FOLLY_STLALLOCATOR_H_
25 * Wrap a simple allocator into a STL-compliant allocator.
27 * The simple allocator must provide two methods:
28 * void* allocate(size_t size);
29 * void deallocate(void* ptr, size_t size);
30 * which, respectively, allocate a block of size bytes (aligned to the maximum
31 * alignment required on your system), throwing std::bad_alloc if the
32 * allocation can't be satisfied, and free a previously allocated block.
34 * Note that the following allocator resembles the standard allocator
37 * class MallocAllocator {
39 * void* allocate(size_t size) {
40 * void* p = malloc(size);
41 * if (!p) throw std::bad_alloc();
44 * void deallocate(void* p) {
50 // This would be so much simpler with std::allocator_traits, but gcc 4.6.2
52 template <class Alloc, class T> class StlAllocator;
54 template <class Alloc> class StlAllocator<Alloc, void> {
56 typedef void value_type;
57 typedef void* pointer;
58 typedef const void* const_pointer;
59 template <class U> struct rebind {
60 typedef StlAllocator<Alloc, U> other;
64 template <class Alloc, class T>
69 typedef const T* const_pointer;
71 typedef const T& const_reference;
73 typedef ptrdiff_t difference_type;
74 typedef size_t size_type;
76 StlAllocator() : alloc_(nullptr) { }
77 explicit StlAllocator(Alloc* alloc) : alloc_(alloc) { }
79 template <class U> StlAllocator(const StlAllocator<Alloc, U>& other)
80 : alloc_(other.alloc()) { }
82 T* allocate(size_t n, const void* hint = nullptr) {
83 return static_cast<T*>(alloc_->allocate(n * sizeof(T)));
86 void deallocate(T* p, size_t n) {
87 alloc_->deallocate(p);
90 size_t max_size() const {
91 return std::numeric_limits<size_t>::max();
94 T* address(T& x) const {
95 return std::addressof(x);
98 const T* address(const T& x) const {
99 return std::addressof(x);
102 template <class... Args>
103 void construct(T* p, Args&&... args) {
104 new (p) T(std::forward<Args>(args)...);
111 Alloc* alloc() const {
115 template <class U> struct rebind {
116 typedef StlAllocator<Alloc, U> other;
119 bool operator!=(const StlAllocator<Alloc, T>& other) const {
120 return alloc_ != other.alloc_;
123 bool operator==(const StlAllocator<Alloc, T>& other) const {
124 return alloc_ == other.alloc_;
133 #endif /* FOLLY_STLALLOCATOR_H_ */