File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/auto/share/dist/Alien-Kiwisolver/include/kiwi/AssocVector.h
Criterion Covered Total %
statement 48 49 97.9
branch 105 202 51.9
condition n/a
subroutine n/a
pod n/a
total 153 251 60.9


line stmt bran cond sub pod time code
1             ////////////////////////////////////////////////////////////////////////////////
2             // The Loki Library
3             // Copyright (c) 2001 by Andrei Alexandrescu
4             // This code accompanies the book:
5             // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
6             // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
7             // Permission to use, copy, modify, distribute and sell this software for any
8             // purpose is hereby granted without fee, provided that the above copyright
9             // notice appear in all copies and that both that copyright notice and this
10             // permission notice appear in supporting documentation.
11             // The author or Addison-Wesley Longman make no representations about the
12             // suitability of this software for any purpose. It is provided "as is"
13             // without express or implied warranty.
14             ////////////////////////////////////////////////////////////////////////////////
15             // Updated 2019 by Matthieu Dartiailh for C++11 compliancy
16             ////////////////////////////////////////////////////////////////////////////////
17             #pragma once
18              
19             // $Id: AssocVector.h 765 2006-10-18 13:55:32Z syntheticpp $
20              
21              
22             #include <algorithm>
23             #include <functional>
24             #include <vector>
25             #include <utility>
26              
27             namespace Loki
28             {
29             ////////////////////////////////////////////////////////////////////////////////
30             // class template AssocVectorCompare
31             // Used by AssocVector
32             ////////////////////////////////////////////////////////////////////////////////
33              
34             namespace Private
35             {
36             template <class Value, class C>
37             class AssocVectorCompare : public C
38             {
39             typedef std::pair<typename C::first_argument_type, Value>
40             Data;
41             typedef typename C::first_argument_type first_argument_type;
42              
43             public:
44             AssocVectorCompare()
45             {}
46              
47 3241           AssocVectorCompare(const C& src) : C(src)
48 3241           {}
49              
50 85495293           bool operator()(const first_argument_type& lhs,
51             const first_argument_type& rhs) const
52 85495293           { return C::operator()(lhs, rhs); }
53              
54             bool operator()(const Data& lhs, const Data& rhs) const
55             { return operator()(lhs.first, rhs.first); }
56              
57 72438764           bool operator()(const Data& lhs,
58             const first_argument_type& rhs) const
59 72438764           { return operator()(lhs.first, rhs); }
60              
61             bool operator()(const first_argument_type& lhs,
62             const Data& rhs) const
63             { return operator()(lhs, rhs.first); }
64             };
65             }
66              
67             ////////////////////////////////////////////////////////////////////////////////
68             // class template AssocVector
69             // An associative vector built as a syntactic drop-in replacement for std::map
70             // BEWARE: AssocVector doesn't respect all map's guarantees, the most important
71             // being:
72             // * iterators are invalidated by insert and erase operations
73             // * the complexity of insert/erase is O(N) not O(log N)
74             // * value_type is std::pair<K, V> not std::pair<const K, V>
75             // * iterators are random
76             ////////////////////////////////////////////////////////////////////////////////
77              
78              
79             template
80             <
81             class K,
82             class V,
83             class C = std::less<K>,
84             class A = std::allocator< std::pair<K, V> >
85             >
86 9802           class AssocVector
87             : private std::vector< std::pair<K, V>, A >
88             , private Private::AssocVectorCompare<V, C>
89             {
90             typedef std::vector<std::pair<K, V>, A> Base;
91             typedef Private::AssocVectorCompare<V, C> MyCompare;
92              
93             public:
94             typedef K key_type;
95             typedef V mapped_type;
96             typedef typename Base::value_type value_type;
97              
98             typedef C key_compare;
99             typedef A allocator_type;
100             typedef typename A::reference reference;
101             typedef typename A::const_reference const_reference;
102             typedef typename Base::iterator iterator;
103             typedef typename Base::const_iterator const_iterator;
104             typedef typename Base::size_type size_type;
105             typedef typename Base::difference_type difference_type;
106             typedef typename A::pointer pointer;
107             typedef typename A::const_pointer const_pointer;
108             typedef typename Base::reverse_iterator reverse_iterator;
109             typedef typename Base::const_reverse_iterator const_reverse_iterator;
110              
111             class value_compare
112             : public std::function<bool(value_type, value_type)>
113             , private key_compare
114             {
115             friend class AssocVector;
116              
117             protected:
118             value_compare(key_compare pred) : key_compare(pred)
119             {}
120              
121             public:
122             bool operator()(const value_type& lhs, const value_type& rhs) const
123             { return key_compare::operator()(lhs.first, rhs.first); }
124             };
125              
126             // 23.3.1.1 construct/copy/destroy
127              
128 3241           explicit AssocVector(const key_compare& comp = key_compare(),
129             const A& alloc = A())
130 3241           : Base(alloc), MyCompare(comp)
131 3241           {}
132              
133             template <class InputIterator>
134             AssocVector(InputIterator first, InputIterator last,
135             const key_compare& comp = key_compare(),
136             const A& alloc = A())
137             : Base(first, last, alloc), MyCompare(comp)
138             {
139             MyCompare& me = *this;
140             std::sort(begin(), end(), me);
141             }
142              
143             AssocVector& operator=(const AssocVector& rhs)
144             {
145             AssocVector(rhs).swap(*this);
146             return *this;
147             }
148              
149             // iterators:
150             // The following are here because MWCW gets 'using' wrong
151 32914162           iterator begin() { return Base::begin(); }
152 4387460           const_iterator begin() const { return Base::begin(); }
153 80565778           iterator end() { return Base::end(); }
154 8655336           const_iterator end() const { return Base::end(); }
155             reverse_iterator rbegin() { return Base::rbegin(); }
156             const_reverse_iterator rbegin() const { return Base::rbegin(); }
157             reverse_iterator rend() { return Base::rend(); }
158             const_reverse_iterator rend() const { return Base::rend(); }
159              
160             // capacity:
161 0           bool empty() const { return Base::empty(); }
162             size_type size() const { return Base::size(); }
163             size_type max_size() { return Base::max_size(); }
164              
165             // 23.3.1.2 element access:
166 9604511           mapped_type& operator[](const key_type& key)
167 9604511 50         { return insert(value_type(key, mapped_type())).first->second; }
    50          
    50          
    50          
    50          
    50          
    50          
    50          
168              
169             // modifiers:
170 9604511           std::pair<iterator, bool> insert(const value_type& val)
171             {
172 9604511           bool found(true);
173 9604511 50         iterator i(lower_bound(val.first));
    50          
    50          
    50          
    50          
174              
175 9604511 100         if (i == end() || this->operator()(val.first, i->first))
    50          
    50          
    50          
    50          
    0          
    100          
    50          
    50          
    50          
    50          
    0          
    100          
    50          
    100          
    50          
    100          
    0          
    100          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
176             {
177 5401140 50         i = Base::insert(i, val);
    50          
    50          
    50          
    50          
178 5401140           found = false;
179             }
180 9604511           return std::make_pair(i, !found);
181             }
182             //Section [23.1.2], Table 69
183             //http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/libstdc++/23_containers/howto.html#4
184             iterator insert(iterator pos, const value_type& val)
185             {
186             if( (pos == begin() || this->operator()(*(pos-1),val)) &&
187             (pos == end() || this->operator()(val, *pos)) )
188             {
189             return Base::insert(pos, val);
190             }
191             return insert(val).first;
192             }
193              
194             template <class InputIterator>
195             void insert(InputIterator first, InputIterator last)
196             { for (; first != last; ++first) insert(*first); }
197              
198 4804237           void erase(iterator pos)
199 4804237 0         { Base::erase(pos); }
    50          
    0          
    50          
200              
201 3548968           size_type erase(const key_type& k)
202             {
203 3548968 50         iterator i(find(k));
204 3548968 50         if (i == end()) return 0;
205 3548968 50         erase(i);
206 3548968           return 1;
207             }
208              
209             void erase(iterator first, iterator last)
210             { Base::erase(first, last); }
211              
212             void swap(AssocVector& other)
213             {
214             Base::swap(other);
215             MyCompare& me = *this;
216             MyCompare& rhs = other;
217             std::swap(me, rhs);
218             }
219              
220 5           void clear()
221 5           { Base::clear(); }
222              
223             // observers:
224             key_compare key_comp() const
225             { return *this; }
226              
227             value_compare value_comp() const
228             {
229             const key_compare& comp = *this;
230             return value_compare(comp);
231             }
232              
233             // 23.3.1.3 map operations:
234 6821496           iterator find(const key_type& k)
235             {
236 6821496 50         iterator i(lower_bound(k));
    50          
    50          
    50          
    50          
237 6821496 100         if (i != end() && this->operator()(k, i->first))
    50          
    100          
    50          
    100          
    0          
    100          
    50          
    100          
    50          
    100          
    0          
    100          
    100          
    50          
    100          
    100          
    50          
    50          
    50          
    100          
    0          
    100          
    100          
    50          
    100          
238             {
239 566115           i = end();
240             }
241 6821496           return i;
242             }
243              
244 952848           const_iterator find(const key_type& k) const
245             {
246 952848 0         const_iterator i(lower_bound(k));
    0          
    50          
247 952848 0         if (i != end() && this->operator()(k, i->first))
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    100          
    50          
    100          
248             {
249 228242           i = end();
250             }
251 952848           return i;
252             }
253              
254             size_type count(const key_type& k) const
255             { return find(k) != end(); }
256              
257 16426007           iterator lower_bound(const key_type& k)
258             {
259 16426007           MyCompare& me = *this;
260 16426007           return std::lower_bound(begin(), end(), k, me);
261             }
262              
263 952848           const_iterator lower_bound(const key_type& k) const
264             {
265 952848           const MyCompare& me = *this;
266 952848           return std::lower_bound(begin(), end(), k, me);
267             }
268              
269             iterator upper_bound(const key_type& k)
270             {
271             MyCompare& me = *this;
272             return std::upper_bound(begin(), end(), k, me);
273             }
274              
275             const_iterator upper_bound(const key_type& k) const
276             {
277             const MyCompare& me = *this;
278             return std::upper_bound(begin(), end(), k, me);
279             }
280              
281             std::pair<iterator, iterator> equal_range(const key_type& k)
282             {
283             MyCompare& me = *this;
284             return std::equal_range(begin(), end(), k, me);
285             }
286              
287             std::pair<const_iterator, const_iterator> equal_range(
288             const key_type& k) const
289             {
290             const MyCompare& me = *this;
291             return std::equal_range(begin(), end(), k, me);
292             }
293              
294             template <class K1, class V1, class C1, class A1>
295             friend bool operator==(const AssocVector<K1, V1, C1, A1>& lhs,
296             const AssocVector<K1, V1, C1, A1>& rhs);
297              
298             bool operator<(const AssocVector& rhs) const
299             {
300             const Base& me = *this;
301             const Base& yo = rhs;
302             return me < yo;
303             }
304              
305             template <class K1, class V1, class C1, class A1>
306             friend bool operator!=(const AssocVector<K1, V1, C1, A1>& lhs,
307             const AssocVector<K1, V1, C1, A1>& rhs);
308              
309             template <class K1, class V1, class C1, class A1>
310             friend bool operator>(const AssocVector<K1, V1, C1, A1>& lhs,
311             const AssocVector<K1, V1, C1, A1>& rhs);
312              
313             template <class K1, class V1, class C1, class A1>
314             friend bool operator>=(const AssocVector<K1, V1, C1, A1>& lhs,
315             const AssocVector<K1, V1, C1, A1>& rhs);
316              
317             template <class K1, class V1, class C1, class A1>
318             friend bool operator<=(const AssocVector<K1, V1, C1, A1>& lhs,
319             const AssocVector<K1, V1, C1, A1>& rhs);
320             };
321              
322             template <class K, class V, class C, class A>
323             inline bool operator==(const AssocVector<K, V, C, A>& lhs,
324             const AssocVector<K, V, C, A>& rhs)
325             {
326             const std::vector<std::pair<K, V>, A>& me = lhs;
327             return me == rhs;
328             }
329              
330             template <class K, class V, class C, class A>
331             inline bool operator!=(const AssocVector<K, V, C, A>& lhs,
332             const AssocVector<K, V, C, A>& rhs)
333             { return !(lhs == rhs); }
334              
335             template <class K, class V, class C, class A>
336             inline bool operator>(const AssocVector<K, V, C, A>& lhs,
337             const AssocVector<K, V, C, A>& rhs)
338             { return rhs < lhs; }
339              
340             template <class K, class V, class C, class A>
341             inline bool operator>=(const AssocVector<K, V, C, A>& lhs,
342             const AssocVector<K, V, C, A>& rhs)
343             { return !(lhs < rhs); }
344              
345             template <class K, class V, class C, class A>
346             inline bool operator<=(const AssocVector<K, V, C, A>& lhs,
347             const AssocVector<K, V, C, A>& rhs)
348             { return !(rhs < lhs); }
349              
350              
351             // specialized algorithms:
352             template <class K, class V, class C, class A>
353             void swap(AssocVector<K, V, C, A>& lhs, AssocVector<K, V, C, A>& rhs)
354             { lhs.swap(rhs); }
355              
356             } // namespace Loki