OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_INTERNAL_H_ | |
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_INTERNAL_H_ | |
7 | |
8 #include <map> | |
9 | |
10 #include "mojo/public/cpp/bindings/array.h" | |
11 #include "mojo/public/cpp/bindings/lib/template_util.h" | |
12 | |
13 namespace mojo { | |
14 namespace internal { | |
15 | |
16 template <typename Key, typename Value, bool kValueIsMoveOnlyType> | |
17 struct MapTraits {}; | |
18 | |
19 template <typename Key, typename Value> | |
20 struct MapTraits<Key, Value, false> { | |
21 // Map keys can't be move only types. | |
22 static_assert(!internal::IsMoveOnlyType<Key>::value, | |
23 "Map keys can not be move only types."); | |
24 | |
25 typedef Key KeyStorageType; | |
26 typedef Key& KeyRefType; | |
27 typedef const Key& KeyConstRefType; | |
28 typedef KeyConstRefType KeyForwardType; | |
29 | |
30 typedef Value ValueStorageType; | |
31 typedef Value& ValueRefType; | |
32 typedef const Value& ValueConstRefType; | |
33 typedef ValueConstRefType ValueForwardType; | |
34 | |
35 static inline void InitializeFrom( | |
36 std::map<KeyStorageType, ValueStorageType>* m, | |
37 mojo::Array<Key> keys, | |
38 mojo::Array<Value> values) { | |
39 for (size_t i = 0; i < keys.size(); ++i) | |
40 Insert(m, keys[i], values[i]); | |
41 } | |
42 static inline void Decompose(std::map<KeyStorageType, ValueStorageType>* m, | |
43 mojo::Array<Key>* keys, | |
44 mojo::Array<Value>* values) { | |
45 keys->resize(m->size()); | |
46 values->resize(m->size()); | |
47 int i = 0; | |
48 for (typename std::map<KeyStorageType, ValueStorageType>::iterator | |
49 it = m->begin(); | |
50 it != m->end(); | |
51 ++it, ++i) { | |
52 (*keys)[i] = it->first; | |
53 (*values)[i] = it->second; | |
54 } | |
55 } | |
56 static inline void Finalize(std::map<KeyStorageType, ValueStorageType>* m) {} | |
57 static inline ValueRefType at(std::map<KeyStorageType, ValueStorageType>* m, | |
58 KeyForwardType key) { | |
59 // We don't have C++11 library support yet, so we have to emulate the crash | |
60 // on a non-existent key. | |
61 auto it = m->find(key); | |
62 MOJO_CHECK(it != m->end()); | |
63 return it->second; | |
64 } | |
65 static inline ValueConstRefType at( | |
66 const std::map<KeyStorageType, ValueStorageType>* m, | |
67 KeyForwardType key) { | |
68 // We don't have C++11 library support yet, so we have to emulate the crash | |
69 // on a non-existent key. | |
70 auto it = m->find(key); | |
71 MOJO_CHECK(it != m->end()); | |
72 return it->second; | |
73 } | |
74 static inline ValueRefType GetOrInsert( | |
75 std::map<KeyStorageType, ValueStorageType>* m, | |
76 KeyForwardType key) { | |
77 // This is the backing for the index operator (operator[]). | |
78 return (*m)[key]; | |
79 } | |
80 static inline void Insert(std::map<KeyStorageType, ValueStorageType>* m, | |
81 KeyForwardType key, | |
82 ValueForwardType value) { | |
83 m->insert(std::make_pair(key, value)); | |
84 } | |
85 static inline KeyConstRefType GetKey( | |
86 const typename std::map<KeyStorageType, ValueStorageType>::const_iterator& | |
87 it) { | |
88 return it->first; | |
89 } | |
90 static inline ValueConstRefType GetValue( | |
91 const typename std::map<KeyStorageType, ValueStorageType>::const_iterator& | |
92 it) { | |
93 return it->second; | |
94 } | |
95 static inline ValueRefType GetValue( | |
96 const typename std::map<KeyStorageType, ValueStorageType>::iterator& it) { | |
97 return it->second; | |
98 } | |
99 static inline void Clone( | |
100 const std::map<KeyStorageType, ValueStorageType>& src, | |
101 std::map<KeyStorageType, ValueStorageType>* dst) { | |
102 dst->clear(); | |
103 for (auto it = src.begin(); it != src.end(); ++it) | |
104 dst->insert(*it); | |
105 } | |
106 }; | |
107 | |
108 template <typename Key, typename Value> | |
109 struct MapTraits<Key, Value, true> { | |
110 // Map keys can't be move only types. | |
111 static_assert(!internal::IsMoveOnlyType<Key>::value, | |
112 "Map keys can not be move only types."); | |
113 | |
114 typedef Key KeyStorageType; | |
115 typedef Key& KeyRefType; | |
116 typedef const Key& KeyConstRefType; | |
117 typedef KeyConstRefType KeyForwardType; | |
118 | |
119 struct ValueStorageType { | |
120 // Make 8-byte aligned. | |
121 char buf[sizeof(Value) + (8 - (sizeof(Value) % 8)) % 8]; | |
122 }; | |
123 typedef Value& ValueRefType; | |
124 typedef const Value& ValueConstRefType; | |
125 typedef Value ValueForwardType; | |
126 | |
127 static inline void InitializeFrom( | |
128 std::map<KeyStorageType, ValueStorageType>* m, | |
129 mojo::Array<Key> keys, | |
130 mojo::Array<Value> values) { | |
131 for (size_t i = 0; i < keys.size(); ++i) | |
132 Insert(m, keys[i], values[i]); | |
133 } | |
134 static inline void Decompose(std::map<KeyStorageType, ValueStorageType>* m, | |
135 mojo::Array<Key>* keys, | |
136 mojo::Array<Value>* values) { | |
137 keys->resize(m->size()); | |
138 values->resize(m->size()); | |
139 int i = 0; | |
140 for (typename std::map<KeyStorageType, ValueStorageType>::iterator | |
141 it = m->begin(); | |
142 it != m->end(); | |
143 ++it, ++i) { | |
144 (*keys)[i] = it->first; | |
145 (*values)[i] = GetValue(it).Pass(); | |
146 } | |
147 } | |
148 static inline void Finalize(std::map<KeyStorageType, ValueStorageType>* m) { | |
149 for (auto& pair : *m) | |
150 reinterpret_cast<Value*>(pair.second.buf)->~Value(); | |
151 } | |
152 static inline ValueRefType at(std::map<KeyStorageType, ValueStorageType>* m, | |
153 KeyForwardType key) { | |
154 // We don't have C++11 library support yet, so we have to emulate the crash | |
155 // on a non-existent key. | |
156 auto it = m->find(key); | |
157 MOJO_CHECK(it != m->end()); | |
158 return GetValue(it); | |
159 } | |
160 static inline ValueConstRefType at( | |
161 const std::map<KeyStorageType, ValueStorageType>* m, | |
162 KeyForwardType key) { | |
163 // We don't have C++11 library support yet, so we have to emulate the crash | |
164 // on a non-existent key. | |
165 auto it = m->find(key); | |
166 MOJO_CHECK(it != m->end()); | |
167 return GetValue(it); | |
168 } | |
169 static inline ValueRefType GetOrInsert( | |
170 std::map<KeyStorageType, ValueStorageType>* m, | |
171 KeyForwardType key) { | |
172 // This is the backing for the index operator (operator[]). | |
173 auto it = m->find(key); | |
174 if (it == m->end()) { | |
175 it = m->insert(std::make_pair(key, ValueStorageType())).first; | |
176 new (it->second.buf) Value(); | |
177 } | |
178 | |
179 return GetValue(it); | |
180 } | |
181 static inline void Insert(std::map<KeyStorageType, ValueStorageType>* m, | |
182 KeyForwardType key, | |
183 ValueRefType value) { | |
184 // STL insert() doesn't insert |value| if |key| is already part of |m|. We | |
185 // have to use operator[] to initialize into the storage buffer, but we | |
186 // have to do a manual check so that we don't overwrite an existing object. | |
187 auto it = m->find(key); | |
188 if (it == m->end()) | |
189 new ((*m)[key].buf) Value(value.Pass()); | |
190 } | |
191 static inline KeyConstRefType GetKey( | |
192 const typename std::map<KeyStorageType, ValueStorageType>::const_iterator& | |
193 it) { | |
194 return it->first; | |
195 } | |
196 static inline ValueConstRefType GetValue( | |
197 const typename std::map<KeyStorageType, ValueStorageType>::const_iterator& | |
198 it) { | |
199 return *reinterpret_cast<const Value*>(it->second.buf); | |
200 } | |
201 static inline ValueRefType GetValue( | |
202 const typename std::map<KeyStorageType, ValueStorageType>::iterator& it) { | |
203 return *reinterpret_cast<Value*>(it->second.buf); | |
204 } | |
205 static inline void Clone( | |
206 const std::map<KeyStorageType, ValueStorageType>& src, | |
207 std::map<KeyStorageType, ValueStorageType>* dst) { | |
208 Finalize(dst); | |
209 dst->clear(); | |
210 for (auto it = src.begin(); it != src.end(); ++it) | |
211 new ((*dst)[it->first].buf) Value(GetValue(it).Clone()); | |
212 } | |
213 }; | |
214 | |
215 } // namespace internal | |
216 } // namespace mojo | |
217 | |
218 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_INTERNAL_H_ | |
OLD | NEW |