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, class K>
37             class AssocVectorCompare : public C
38             {
39             typedef std::pair<K, Value>
40             Data;
41             typedef K first_argument_type;
42              
43             public:
44             AssocVectorCompare()
45             {}
46              
47 3241           AssocVectorCompare(const C& src) : C(src)
48 3241           {}
49              
50 85495563           bool operator()(const first_argument_type& lhs,
51             const first_argument_type& rhs) const
52 85495563           { 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 72438799           bool operator()(const Data& lhs,
58             const first_argument_type& rhs) const
59 72438799           { 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, K>
89             {
90             typedef std::vector<std::pair<K, V>, A> Base;
91             typedef Private::AssocVectorCompare<V, C, K> 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 Base::iterator iterator;
101             typedef typename Base::const_iterator const_iterator;
102             typedef typename Base::size_type size_type;
103             typedef typename Base::difference_type difference_type;
104             typedef typename Base::reverse_iterator reverse_iterator;
105             typedef typename Base::const_reverse_iterator const_reverse_iterator;
106              
107             class value_compare
108             : public std::function<bool(value_type, value_type)>
109             , private key_compare
110             {
111             friend class AssocVector;
112              
113             protected:
114             value_compare(key_compare pred) : key_compare(pred)
115             {}
116              
117             public:
118             bool operator()(const value_type& lhs, const value_type& rhs) const
119             { return key_compare::operator()(lhs.first, rhs.first); }
120             };
121              
122             // 23.3.1.1 construct/copy/destroy
123              
124 3241           explicit AssocVector(const key_compare& comp = key_compare(),
125             const A& alloc = A())
126 3241           : Base(alloc), MyCompare(comp)
127 3241           {}
128              
129             template <class InputIterator>
130             AssocVector(InputIterator first, InputIterator last,
131             const key_compare& comp = key_compare(),
132             const A& alloc = A())
133             : Base(first, last, alloc), MyCompare(comp)
134             {
135             MyCompare& me = *this;
136             std::sort(begin(), end(), me);
137             }
138              
139             AssocVector& operator=(const AssocVector& rhs)
140             {
141             AssocVector(rhs).swap(*this);
142             return *this;
143             }
144              
145             // iterators:
146             // The following are here because MWCW gets 'using' wrong
147 32914156           iterator begin() { return Base::begin(); }
148 4387458           const_iterator begin() const { return Base::begin(); }
149 80565874           iterator end() { return Base::end(); }
150 8655334           const_iterator end() const { return Base::end(); }
151             reverse_iterator rbegin() { return Base::rbegin(); }
152             const_reverse_iterator rbegin() const { return Base::rbegin(); }
153             reverse_iterator rend() { return Base::rend(); }
154             const_reverse_iterator rend() const { return Base::rend(); }
155              
156             // capacity:
157 0           bool empty() const { return Base::empty(); }
158             size_type size() const { return Base::size(); }
159             size_type max_size() { return Base::max_size(); }
160              
161             // 23.3.1.2 element access:
162 9604509           mapped_type& operator[](const key_type& key)
163 9604509 50         { return insert(value_type(key, mapped_type())).first->second; }
    50          
    50          
    50          
    50          
    50          
    50          
    50          
164              
165             // modifiers:
166 9604509           std::pair<iterator, bool> insert(const value_type& val)
167             {
168 9604509           bool found(true);
169 9604509 50         iterator i(lower_bound(val.first));
    50          
    50          
    50          
    50          
170              
171 9604509 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          
172             {
173 5401139 50         i = Base::insert(i, val);
    50          
    50          
    50          
    50          
174 5401139           found = false;
175             }
176 9604509           return std::make_pair(i, !found);
177             }
178             //Section [23.1.2], Table 69
179             //http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/libstdc++/23_containers/howto.html#4
180             iterator insert(iterator pos, const value_type& val)
181             {
182             if( (pos == begin() || this->operator()(*(pos-1),val)) &&
183             (pos == end() || this->operator()(val, *pos)) )
184             {
185             return Base::insert(pos, val);
186             }
187             return insert(val).first;
188             }
189              
190             template <class InputIterator>
191             void insert(InputIterator first, InputIterator last)
192             { for (; first != last; ++first) insert(*first); }
193              
194 4804236           void erase(iterator pos)
195 4804236 0         { Base::erase(pos); }
    50          
    0          
    50          
196              
197 3548967           size_type erase(const key_type& k)
198             {
199 3548967 50         iterator i(find(k));
200 3548967 50         if (i == end()) return 0;
201 3548967 50         erase(i);
202 3548967           return 1;
203             }
204              
205             void erase(iterator first, iterator last)
206             { Base::erase(first, last); }
207              
208             void swap(AssocVector& other)
209             {
210             Base::swap(other);
211             MyCompare& me = *this;
212             MyCompare& rhs = other;
213             std::swap(me, rhs);
214             }
215              
216 5           void clear()
217 5           { Base::clear(); }
218              
219             // observers:
220             key_compare key_comp() const
221             { return *this; }
222              
223             value_compare value_comp() const
224             {
225             const key_compare& comp = *this;
226             return value_compare(comp);
227             }
228              
229             // 23.3.1.3 map operations:
230 6821495           iterator find(const key_type& k)
231             {
232 6821495 50         iterator i(lower_bound(k));
    50          
    50          
    50          
    50          
233 6821495 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          
234             {
235 566170           i = end();
236             }
237 6821495           return i;
238             }
239              
240 952848           const_iterator find(const key_type& k) const
241             {
242 952848 0         const_iterator i(lower_bound(k));
    0          
    50          
243 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          
244             {
245 228242           i = end();
246             }
247 952848           return i;
248             }
249              
250             size_type count(const key_type& k) const
251             { return find(k) != end(); }
252              
253 16426004           iterator lower_bound(const key_type& k)
254             {
255 16426004           MyCompare& me = *this;
256 16426004           return std::lower_bound(begin(), end(), k, me);
257             }
258              
259 952848           const_iterator lower_bound(const key_type& k) const
260             {
261 952848           const MyCompare& me = *this;
262 952848           return std::lower_bound(begin(), end(), k, me);
263             }
264              
265             iterator upper_bound(const key_type& k)
266             {
267             MyCompare& me = *this;
268             return std::upper_bound(begin(), end(), k, me);
269             }
270              
271             const_iterator upper_bound(const key_type& k) const
272             {
273             const MyCompare& me = *this;
274             return std::upper_bound(begin(), end(), k, me);
275             }
276              
277             std::pair<iterator, iterator> equal_range(const key_type& k)
278             {
279             MyCompare& me = *this;
280             return std::equal_range(begin(), end(), k, me);
281             }
282              
283             std::pair<const_iterator, const_iterator> equal_range(
284             const key_type& k) const
285             {
286             const MyCompare& me = *this;
287             return std::equal_range(begin(), end(), k, me);
288             }
289              
290             template <class K1, class V1, class C1, class A1>
291             friend bool operator==(const AssocVector<K1, V1, C1, A1>& lhs,
292             const AssocVector<K1, V1, C1, A1>& rhs);
293              
294             bool operator<(const AssocVector& rhs) const
295             {
296             const Base& me = *this;
297             const Base& yo = rhs;
298             return me < yo;
299             }
300              
301             template <class K1, class V1, class C1, class A1>
302             friend bool operator!=(const AssocVector<K1, V1, C1, A1>& lhs,
303             const AssocVector<K1, V1, C1, A1>& rhs);
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              
318             template <class K, class V, class C, class A>
319             inline bool operator==(const AssocVector<K, V, C, A>& lhs,
320             const AssocVector<K, V, C, A>& rhs)
321             {
322             const std::vector<std::pair<K, V>, A>& me = lhs;
323             return me == rhs;
324             }
325              
326             template <class K, class V, class C, class A>
327             inline bool operator!=(const AssocVector<K, V, C, A>& lhs,
328             const AssocVector<K, V, C, A>& rhs)
329             { return !(lhs == rhs); }
330              
331             template <class K, class V, class C, class A>
332             inline bool operator>(const AssocVector<K, V, C, A>& lhs,
333             const AssocVector<K, V, C, A>& rhs)
334             { return rhs < lhs; }
335              
336             template <class K, class V, class C, class A>
337             inline bool operator>=(const AssocVector<K, V, C, A>& lhs,
338             const AssocVector<K, V, C, A>& rhs)
339             { return !(lhs < rhs); }
340              
341             template <class K, class V, class C, class A>
342             inline bool operator<=(const AssocVector<K, V, C, A>& lhs,
343             const AssocVector<K, V, C, A>& rhs)
344             { return !(rhs < lhs); }
345              
346              
347             // specialized algorithms:
348             template <class K, class V, class C, class A>
349             void swap(AssocVector<K, V, C, A>& lhs, AssocVector<K, V, C, A>& rhs)
350             { lhs.swap(rhs); }
351              
352             } // namespace Loki