File Coverage

src/panda/string_map.h
Criterion Covered Total %
statement 23 23 100.0
branch 14 26 53.8
condition n/a
subroutine n/a
pod n/a
total 37 49 75.5


line stmt bran cond sub pod time code
1             #pragma once
2             #include "string.h"
3             #include "string_view.h"
4             #include
5             #include
6             #include
7              
8             /*
9             * panda::string_map and panda::string_multimap are wrappers around STL's versions in case if keys are panda::string.
10             * The goal is to make it possible to call some STL's methods with string_view
11             */
12              
13             namespace panda {
14              
15             template , class Allocator = std::allocator>>
16 28           class string_map : public std::map {
17             private:
18             template
19             static inline std::true_type _is_base_string (panda::basic_string const volatile) { return std::true_type(); }
20             static inline std::false_type _is_base_string (...) { return std::false_type(); }
21              
22             static_assert(decltype(_is_base_string(Key()))::value, "Key must be based on panda::basic_string");
23              
24             using Base = std::map;
25             using SVKey = basic_string_view;
26              
27 21           static Key _key_from_sv (const SVKey& key) {
28             typedef typename Key::value_type FakeCharLiteral[1];
29 21           Key tmp(*(const FakeCharLiteral*)key.data());
30 21           tmp.length(key.length());
31 21           return tmp;
32             }
33             public:
34             using typename Base::key_type;
35             using typename Base::mapped_type;
36             using typename Base::value_type;
37             using typename Base::size_type;
38             using typename Base::difference_type;
39             using typename Base::key_compare;
40             using typename Base::allocator_type;
41             using typename Base::reference;
42             using typename Base::const_reference;
43             using typename Base::pointer;
44             using typename Base::const_pointer;
45             using typename Base::iterator;
46             using typename Base::const_iterator;
47             using typename Base::reverse_iterator;
48             using typename Base::const_reverse_iterator;
49              
50             using Base::Base;
51             using Base::at;
52             using Base::find;
53             using Base::count;
54             using Base::erase;
55             using Base::equal_range;
56             using Base::lower_bound;
57             using Base::upper_bound;
58              
59             template ::value>::type>
60 5 100         T& at (X key) { return at(_key_from_sv(key)); }
61              
62             template ::value>::type>
63             const T& at (X key) const { return at(_key_from_sv(key)); }
64              
65             template ::value>::type>
66 4 50         iterator find (X key) { return find(_key_from_sv(key)); }
67              
68             template ::value>::type>
69             const_iterator find (X key) const { return find(_key_from_sv(key)); }
70              
71             template ::value>::type>
72 3 50         size_type count (X key) const { return count(_key_from_sv(key)); }
73              
74             template ::value>::type>
75 3 50         size_type erase (X key) { return erase(_key_from_sv(key)); }
76              
77             template ::value>::type>
78 3 50         std::pair equal_range (X key) { return equal_range(_key_from_sv(key)); }
79              
80             template ::value>::type>
81             std::pair equal_range (X key) const { return equal_range(_key_from_sv(key)); }
82              
83             template ::value>::type>
84 2 50         iterator lower_bound (X key) { return lower_bound(_key_from_sv(key)); }
85              
86             template ::value>::type>
87             const_iterator lower_bound (X key) const { return lower_bound(_key_from_sv(key)); }
88              
89             template ::value>::type>
90 2 50         iterator upper_bound (X key) { return upper_bound(_key_from_sv(key)); }
91              
92             template ::value>::type>
93             const_iterator upper_bound (X key) const { return upper_bound(_key_from_sv(key)); }
94              
95             };
96              
97             template , class Allocator = std::allocator>>
98 24           class string_multimap : public std::multimap {
99             private:
100             template
101             static inline std::true_type _is_base_string (panda::basic_string const volatile) { return std::true_type(); }
102             static inline std::false_type _is_base_string (...) { return std::false_type(); }
103              
104             static_assert(decltype(_is_base_string(Key()))::value, "Key must be based on panda::basic_string");
105              
106             using Base = std::multimap;
107             using SVKey = basic_string_view;
108              
109 18           static Key _key_from_sv (const SVKey& key) {
110             typedef typename Key::value_type FakeCharLiteral[1];
111 18           Key tmp(*(const FakeCharLiteral*)key.data());
112 18           tmp.length(key.length());
113 18           return tmp;
114             }
115             public:
116             using typename Base::key_type;
117             using typename Base::mapped_type;
118             using typename Base::value_type;
119             using typename Base::size_type;
120             using typename Base::difference_type;
121             using typename Base::key_compare;
122             using typename Base::allocator_type;
123             using typename Base::reference;
124             using typename Base::const_reference;
125             using typename Base::pointer;
126             using typename Base::const_pointer;
127             using typename Base::iterator;
128             using typename Base::const_iterator;
129             using typename Base::reverse_iterator;
130             using typename Base::const_reverse_iterator;
131              
132             using Base::Base;
133             using Base::find;
134             using Base::count;
135             using Base::erase;
136             using Base::equal_range;
137             using Base::lower_bound;
138             using Base::upper_bound;
139              
140             template ::value>::type>
141 5 50         iterator find (X key) { return find(_key_from_sv(key)); }
142              
143             template ::value>::type>
144             const_iterator find (X key) const { return find(_key_from_sv(key)); }
145              
146             template ::value>::type>
147 3 50         size_type count (X key) const { return count(_key_from_sv(key)); }
148              
149             template ::value>::type>
150 3 50         size_type erase (X key) { return erase(_key_from_sv(key)); }
151              
152             template ::value>::type>
153 3 50         std::pair equal_range (X key) { return equal_range(_key_from_sv(key)); }
154              
155             template ::value>::type>
156             std::pair equal_range (X key) const { return equal_range(_key_from_sv(key)); }
157              
158             template ::value>::type>
159 2 50         iterator lower_bound (X key) { return lower_bound(_key_from_sv(key)); }
160              
161             template ::value>::type>
162             const_iterator lower_bound (X key) const { return lower_bound(_key_from_sv(key)); }
163              
164             template ::value>::type>
165 2 50         iterator upper_bound (X key) { return upper_bound(_key_from_sv(key)); }
166              
167             template ::value>::type>
168             const_iterator upper_bound (X key) const { return upper_bound(_key_from_sv(key)); }
169              
170             };
171              
172             }