Add a LICENSE file for folly
[folly.git] / folly / StlAllocator.h
1 /*
2  * Copyright 2012 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #ifndef FOLLY_STLALLOCATOR_H_
18 #define FOLLY_STLALLOCATOR_H_
19
20 #include <memory>
21
22 namespace folly {
23
24 /**
25  * Wrap a simple allocator into a STL-compliant allocator.
26  *
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.
33  *
34  * Note that the following allocator resembles the standard allocator
35  * quite well:
36  *
37  * class MallocAllocator {
38  *  public:
39  *   void* allocate(size_t size) {
40  *     void* p = malloc(size);
41  *     if (!p) throw std::bad_alloc();
42  *     return p;
43  *   }
44  *   void deallocate(void* p) {
45  *     free(p);
46  *   }
47  * };
48  */
49
50 // This would be so much simpler with std::allocator_traits, but gcc 4.6.2
51 // doesn't support it
52 template <class Alloc, class T> class StlAllocator;
53
54 template <class Alloc> class StlAllocator<Alloc, void> {
55  public:
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;
61   };
62 };
63
64 template <class Alloc, class T>
65 class StlAllocator {
66  public:
67   typedef T value_type;
68   typedef T* pointer;
69   typedef const T* const_pointer;
70   typedef T& reference;
71   typedef const T& const_reference;
72
73   typedef ptrdiff_t difference_type;
74   typedef size_t size_type;
75
76   StlAllocator() : alloc_(nullptr) { }
77   explicit StlAllocator(Alloc* alloc) : alloc_(alloc) { }
78
79   template <class U> StlAllocator(const StlAllocator<Alloc, U>& other)
80     : alloc_(other.alloc()) { }
81
82   T* allocate(size_t n, const void* hint = nullptr) {
83     return static_cast<T*>(alloc_->allocate(n * sizeof(T)));
84   }
85
86   void deallocate(T* p, size_t n) {
87     alloc_->deallocate(p);
88   }
89
90   size_t max_size() const {
91     return std::numeric_limits<size_t>::max();
92   }
93
94   T* address(T& x) const {
95     return std::addressof(x);
96   }
97
98   const T* address(const T& x) const {
99     return std::addressof(x);
100   }
101
102   template <class... Args>
103   void construct(T* p, Args&&... args) {
104     new (p) T(std::forward<Args>(args)...);
105   }
106
107   void destroy(T* p) {
108     p->~T();
109   }
110
111   Alloc* alloc() const {
112     return alloc_;
113   }
114
115   template <class U> struct rebind {
116     typedef StlAllocator<Alloc, U> other;
117   };
118
119  private:
120   Alloc* alloc_;
121 };
122
123 }  // namespace folly
124
125 #endif /* FOLLY_STLALLOCATOR_H_ */
126