2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_RUNTIME_BASE_MEMORY_HEAP_CONTAINERS_H_
17 #define incl_HPHP_RUNTIME_BASE_MEMORY_HEAP_CONTAINERS_H_
26 #include <unordered_map>
27 #include <unordered_set>
30 #include <boost/container/flat_map.hpp>
36 #include "hphp/runtime/base/memory-manager.h"
38 namespace HPHP
{ namespace req
{
40 //////////////////////////////////////////////////////////////////////
43 * Defines a family of types similar to std:: collections and
44 * pointers, except using the request-local allocator.
46 * Replace std:: with req:: if you know the data is request-local.
50 * Shorthands to create std::unique_ptr or std::shared_ptr to a
51 * heap-allocated object. Memory will be request-scoped; the pointer
52 * wrapper remembers how to properly delete the object with req::Allocator.
55 * auto ptr = req::make_unique<Foo>(...);
56 * auto ptr = req::make_shared<Foo>(...);
60 using unique_ptr
= typename
folly::AllocatorUniquePtr
<T
,Allocator
<T
>>::type
;
62 template<class T
, class... Args
>
63 unique_ptr
<T
> make_unique(Args
&&... args
) {
64 return folly::allocate_unique
<T
>(
66 std::forward
<Args
>(args
)...
70 template<class T
, class... Args
>
71 std::shared_ptr
<T
> make_shared(Args
&&... args
) {
72 return std::allocate_shared
<T
>(
74 std::forward
<Args
>(args
)...
78 #ifndef __APPLE__ // XXX: this affects codegen quality but not correctness
80 sizeof(unique_ptr
<int>) == sizeof(std::unique_ptr
<int>),
81 "req::unique_ptr pointer should not be larger than std::unique_ptr"
85 template <class Key
, class T
, class Compare
= std::less
<Key
>>
86 using map
= std::map
<Key
, T
, Compare
, Allocator
<std::pair
<const Key
,T
>>>;
88 template <class Key
, class T
, class Compare
= std::less
<Key
>>
89 using multimap
= std::multimap
<Key
,T
,Compare
,Allocator
<std::pair
<const Key
,T
>>>;
91 template <class T
, class Compare
= std::less
<T
>>
92 using set
= std::set
<T
, Compare
, Allocator
<T
>>;
94 template <class T
, class Compare
= std::less
<T
>>
95 using multiset
= std::set
<T
, Compare
, Allocator
<T
>>;
98 using deque
= std::deque
<T
,Allocator
<T
>>;
101 using vector
= std::vector
<T
,Allocator
<T
>>;
103 template <class T
, class Container
= deque
<T
>>
104 using stack
= std::stack
<T
, Container
>;
107 using list
= std::list
<T
,Allocator
<T
>>;
110 using queue
= std::queue
<T
, deque
<T
>>;
112 template <class T
, class Compare
= std::less
<T
>>
113 using priority_queue
= std::priority_queue
<T
, vector
<T
>, Compare
>;
115 #ifdef HAVE_BOOST1_49
116 // These classes are oddly broken in older boost versions.
117 template<class K
, class V
, class Pred
= std::less
<K
>>
118 using flat_map
= boost::container::flat_map
<K
,V
,Pred
,Allocator
<std::pair
<K
,V
>>>;
120 template<class K
, class V
, class Pred
= std::less
<K
>>
121 using flat_multimap
=
122 boost::container::flat_multimap
<K
,V
,Pred
,Allocator
<std::pair
<K
,V
>>>;
124 template <class Key
, class T
, class Compare
= std::less
<Key
>>
125 using flat_map
= std::map
<Key
, T
, Compare
, Allocator
<std::pair
<const Key
,T
>>>;
127 template <class Key
, class T
, class Compare
= std::less
<Key
>>
128 using flat_multimap
=
129 std::multimap
<Key
,T
,Compare
,Allocator
<std::pair
<const Key
,T
>>>;
132 template<class K
, class Pred
= std::less
<K
>>
133 using flat_set
= boost::container::flat_set
<K
, Pred
, Allocator
<K
>>;
135 template<class K
, class Pref
= std::less
<K
>>
136 using flat_multiset
= boost::container::flat_multiset
<K
, Pref
, Allocator
<K
>>;
139 * We are deriving from the std::collection classes to get
140 * req::collection classes that use request-heap allocation. To avoid the
141 * various issues involved with deriving from value types, we want to
142 * make sure that there are no references to the base classes here
143 * other than the ones below. That way we know that a pointer to a
144 * req::collection can never decay to a pointer to a
147 * Derivation from value types is generally bad. We also add no
148 * functionality to the derived class. Your code will not get past
149 * code review if you try to do so.
151 * When we upgrade compilers we can change these to C++11 type
157 class V
= std::hash
<T
>,
158 class W
= std::equal_to
<T
>>
159 struct hash_map
: std::unordered_map
<
161 Allocator
<std::pair
<const T
,U
>>
164 : std::unordered_map
<
166 Allocator
<std::pair
<const T
,U
>>
173 class V
= std::hash
<T
>,
174 class W
= std::equal_to
<T
>>
175 struct hash_multimap
: std::unordered_multimap
<
177 Allocator
<std::pair
<const T
,U
>>
180 : std::unordered_multimap
<
182 Allocator
<std::pair
<const T
,U
>>
188 class V
= std::hash
<T
>,
189 class W
= std::equal_to
<T
>>
190 struct hash_set
: std::unordered_set
<T
,V
,W
,Allocator
<T
> > {
192 : std::unordered_set
<T
,V
,W
,Allocator
<T
>>(0)
196 //////////////////////////////////////////////////////////////////////