Rename smart:: namespace to req::
[hiphop-php.git] / hphp / runtime / base / req-containers.h
blobc17ea8fe82bcea30e95c9da9be4e5e15077bb242
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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_
19 #include <cstdlib>
20 #include <deque>
21 #include <functional>
22 #include <map>
23 #include <memory>
24 #include <queue>
25 #include <stack>
26 #include <unordered_map>
27 #include <unordered_set>
28 #include <vector>
30 #include <boost/container/flat_map.hpp>
31 #include <limits>
32 #include <list>
33 #include <set>
34 #include <utility>
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.
54 * Usage:
55 * auto ptr = req::make_unique<Foo>(...);
56 * auto ptr = req::make_shared<Foo>(...);
59 template<class T>
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>(
65 Allocator<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>(
73 Allocator<T>(),
74 std::forward<Args>(args)...
78 #ifndef __APPLE__ // XXX: this affects codegen quality but not correctness
79 static_assert(
80 sizeof(unique_ptr<int>) == sizeof(std::unique_ptr<int>),
81 "req::unique_ptr pointer should not be larger than std::unique_ptr"
83 #endif
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>>;
97 template <class T>
98 using deque = std::deque<T,Allocator<T>>;
100 template <class T>
101 using vector = std::vector<T,Allocator<T>>;
103 template <class T, class Container = deque<T>>
104 using stack = std::stack<T, Container>;
106 template <class T>
107 using list = std::list<T,Allocator<T>>;
109 template <class 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>>>;
123 #else
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>>>;
130 #endif
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
145 * std::collection.
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
152 * aliases.
155 template <class T,
156 class U,
157 class V = std::hash<T>,
158 class W = std::equal_to<T>>
159 struct hash_map : std::unordered_map<
160 T, U, V, W,
161 Allocator<std::pair<const T,U>>
163 hash_map()
164 : std::unordered_map<
165 T, U, V, W,
166 Allocator<std::pair<const T,U>>
167 >(0)
171 template <class T,
172 class U,
173 class V = std::hash<T>,
174 class W = std::equal_to<T>>
175 struct hash_multimap : std::unordered_multimap<
176 T, U, V, W,
177 Allocator<std::pair<const T,U>>
179 hash_multimap()
180 : std::unordered_multimap<
181 T, U, V, W,
182 Allocator<std::pair<const T,U>>
183 >(0)
187 template <class T,
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> > {
191 hash_set()
192 : std::unordered_set<T,V,W,Allocator<T>>(0)
196 //////////////////////////////////////////////////////////////////////
200 #endif