@@ -21,7 +21,9 @@ limitations under the License.
2121#include < photon/common/hash_combine.h>
2222#include < cstring>
2323#include < unordered_map>
24+ #include < unordered_set>
2425#include < map>
26+ #include < set>
2527
2628// string_key is a string_view with dedicated storage,
2729// primarily used as stored keys in std::map and std::unordered_map,
@@ -192,10 +194,8 @@ template<class T,
192194using unordered_map_string_key_case_insensitive = basic_map_string_key<
193195 std::unordered_map<string_key, T, Hasher, KeyEqual, Alloc>>;
194196
195- template <class T ,
196- class Pred = std::less<string_key>,
197- class Alloc = std::allocator<std::pair<const string_key,T>>>
198- class map_string_key : public basic_map_string_key <
197+ template <class T , class Pred , class Alloc >
198+ class ordered_map_string_key : public basic_map_string_key <
199199 std::map<string_key, T, Pred, Alloc>>
200200{
201201public:
@@ -225,6 +225,11 @@ class map_string_key : public basic_map_string_key<
225225 }
226226};
227227
228+ template <class T ,
229+ class Pred = std::less<string_key>,
230+ class Alloc = std::allocator<std::pair<const string_key,T>>>
231+ using map_string_key = ordered_map_string_key<T, Pred, Alloc>;
232+
228233class Less_CaseInsensitive {
229234public:
230235 bool operator ()(std::string_view a, std::string_view b) const {
@@ -239,8 +244,125 @@ class Less_CaseInsensitive {
239244template <class T ,
240245 class Pred = Less_CaseInsensitive,
241246 class Alloc = std::allocator<std::pair<const string_key,T>>>
242- using map_string_key_case_insensitive = basic_map_string_key<
243- std::map<string_key, T, Pred, Alloc>>;
247+ using map_string_key_case_insensitive = ordered_map_string_key<
248+ T, Pred, Alloc>;
249+
250+ // The basic class for sets with string keys, aims to avoid temp
251+ // std::string construction in queries, by accepting string_views.
252+ // S is the underlying set, either std::set or std::unordered_set
253+ template <class S >
254+ class basic_set_string_key : public S
255+ {
256+ public:
257+ using base = S;
258+ using typename base::const_iterator;
259+ using typename base::iterator;
260+ using typename base::size_type;
261+ using base::base;
262+
263+ using base::erase;
264+
265+ using key_type = std::string_view;
266+ using value_type = string_key;
267+
268+ iterator find ( const key_type& k )
269+ {
270+ return base::find ((const string_key&)k);
271+ }
272+ const_iterator find ( const key_type& k ) const
273+ {
274+ return base::find ((const string_key&)k);
275+ }
276+ size_type count ( const key_type& k ) const
277+ {
278+ return base::count ((const string_key&)k);
279+ }
280+ std::pair<iterator,iterator> equal_range ( const key_type& k )
281+ {
282+ return base::equal_range ((const string_key&)k);
283+ }
284+ std::pair<const_iterator,const_iterator> equal_range ( const key_type& k ) const
285+ {
286+ return base::equal_range ((const string_key&)k);
287+ }
288+ std::pair<iterator,bool > emplace ( const key_type& k )
289+ {
290+ return base::emplace ((const string_key&)k);
291+ }
292+ template <class ... Args>
293+ std::pair<iterator,bool > emplace ( const key_type& k, Args&&... args )
294+ {
295+ return base::emplace ((const string_key&)k, std::forward<Args>(args)...);
296+ }
297+ template <class ... Args>
298+ iterator emplace_hint ( const_iterator position, const key_type& k, Args&&... args )
299+ {
300+ return base::emplace_hint (position, (const string_key&)k, std::forward<Args>(args)...);
301+ }
302+ std::pair<iterator,bool > insert ( const key_type& k )
303+ {
304+ return emplace (k);
305+ }
306+ iterator insert ( const_iterator hint, const key_type& k )
307+ {
308+ return emplace_hint (hint, k);
309+ }
310+ size_type erase ( const std::string_view& k )
311+ {
312+ return base::erase ((const string_key&)k);
313+ }
314+ };
315+
316+ template <class Hasher = std::hash<std::string_view>,
317+ class KeyEqual = std::equal_to<std::string_view>,
318+ class Alloc = std::allocator<string_key>>
319+ using unordered_set_string_key = basic_set_string_key<
320+ std::unordered_set<string_key, Hasher, KeyEqual, Alloc>>;
321+
322+ template <class Hasher = Hasher_CaseInsensitive,
323+ class KeyEqual = Equal_CaseInsensitive,
324+ class Alloc = std::allocator<string_key>>
325+ using unordered_set_string_key_case_insensitive = basic_set_string_key<
326+ std::unordered_set<string_key, Hasher, KeyEqual, Alloc>>;
327+
328+ // ordered set with string keys, provides lower_bound/upper_bound
329+ template <class S >
330+ class ordered_set_string_key : public basic_set_string_key <S>
331+ {
332+ public:
333+ using base = basic_set_string_key<S>;
334+ using typename base::key_type;
335+ using typename base::const_iterator;
336+ using typename base::iterator;
337+ using base::base;
338+
339+ iterator lower_bound (const key_type& k)
340+ {
341+ return base::lower_bound ((const string_key&)k);
342+ }
343+ const_iterator lower_bound (const key_type& k) const
344+ {
345+ return base::lower_bound ((const string_key&)k);
346+ }
347+ iterator upper_bound (const key_type& k)
348+ {
349+ return base::upper_bound ((const string_key&)k);
350+ }
351+ const_iterator upper_bound (const key_type& k) const
352+ {
353+ return base::upper_bound ((const string_key&)k);
354+ }
355+ };
356+
357+ template <class Pred = std::less<string_key>,
358+ class Alloc = std::allocator<string_key>>
359+ using set_string_key = ordered_set_string_key<
360+ std::set<string_key, Pred, Alloc>>;
361+
362+ template <class Pred = Less_CaseInsensitive,
363+ class Alloc = std::allocator<string_key>>
364+ using set_string_key_case_insensitive = ordered_set_string_key<
365+ std::set<string_key, Pred, Alloc>>;
244366
245367// the String Key-Value (Mutable), stored together
246368// in a consecutive area, so as to save one allocation
0 commit comments