Chris@16
|
1 /*-----------------------------------------------------------------------------+
|
Chris@16
|
2 Copyright (c) 2010-2010: Joachim Faulhaber
|
Chris@16
|
3 +------------------------------------------------------------------------------+
|
Chris@16
|
4 Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
5 (See accompanying file LICENCE.txt or copy at
|
Chris@16
|
6 http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 +-----------------------------------------------------------------------------*/
|
Chris@16
|
8 #ifndef BOOST_ICL_CONCEPT_ELEMENT_ASSOCIATOR_HPP_JOFA_100921
|
Chris@16
|
9 #define BOOST_ICL_CONCEPT_ELEMENT_ASSOCIATOR_HPP_JOFA_100921
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/config.hpp>
|
Chris@16
|
12 #include <boost/icl/type_traits/is_associative_element_container.hpp>
|
Chris@16
|
13 #include <boost/icl/type_traits/is_key_container_of.hpp>
|
Chris@16
|
14 #include <boost/icl/type_traits/is_combinable.hpp>
|
Chris@16
|
15 #include <boost/icl/detail/subset_comparer.hpp>
|
Chris@16
|
16 #include <boost/icl/concept/element_set.hpp>
|
Chris@16
|
17 #include <boost/icl/concept/element_map.hpp>
|
Chris@16
|
18
|
Chris@16
|
19 namespace boost{ namespace icl
|
Chris@16
|
20 {
|
Chris@16
|
21
|
Chris@16
|
22 //==============================================================================
|
Chris@16
|
23 //= Size
|
Chris@16
|
24 //==============================================================================
|
Chris@16
|
25 template<class Type>
|
Chris@16
|
26 typename enable_if<is_element_container<Type>, std::size_t>::type
|
Chris@16
|
27 iterative_size(const Type& object)
|
Chris@16
|
28 {
|
Chris@16
|
29 return object.size();
|
Chris@16
|
30 }
|
Chris@16
|
31
|
Chris@16
|
32 template<class Type>
|
Chris@16
|
33 typename enable_if<is_associative_element_container<Type>, typename Type::size_type>::type
|
Chris@16
|
34 size(const Type& object)
|
Chris@16
|
35 {
|
Chris@16
|
36 return icl::iterative_size(object);
|
Chris@16
|
37 }
|
Chris@16
|
38
|
Chris@16
|
39 template<class Type>
|
Chris@16
|
40 typename enable_if<is_associative_element_container<Type>, typename Type::size_type>::type
|
Chris@16
|
41 cardinality(const Type& object)
|
Chris@16
|
42 {
|
Chris@16
|
43 return icl::iterative_size(object);
|
Chris@16
|
44 }
|
Chris@16
|
45
|
Chris@16
|
46
|
Chris@16
|
47 //==============================================================================
|
Chris@16
|
48 //= Containedness<ElementSet|ElementMap>
|
Chris@16
|
49 //==============================================================================
|
Chris@16
|
50 //------------------------------------------------------------------------------
|
Chris@16
|
51 //- bool within(c P&, c T&) T:{s}|{m} P:{e}|{i} fragment_types|key_types
|
Chris@16
|
52 //------------------------------------------------------------------------------
|
Chris@16
|
53 /** Checks if a key is in the associative container */
|
Chris@16
|
54 template<class Type>
|
Chris@16
|
55 typename enable_if<is_associative_element_container<Type>, bool>::type
|
Chris@16
|
56 within(const typename Type::key_type& key, const Type& super)
|
Chris@16
|
57 {
|
Chris@16
|
58 return !(super.find(key) == super.end());
|
Chris@16
|
59 }
|
Chris@16
|
60
|
Chris@16
|
61 //------------------------------------------------------------------------------
|
Chris@16
|
62 //- bool within(c P&, c T&) T:{s}|{m} P:{s'} fragment_types|key_types
|
Chris@16
|
63 //------------------------------------------------------------------------------
|
Chris@16
|
64 template<class SubT, class SuperT>
|
Chris@16
|
65 typename enable_if<mpl::and_< is_associative_element_container<SuperT>
|
Chris@16
|
66 , is_key_container_of<SubT, SuperT> >,
|
Chris@16
|
67 bool>::type
|
Chris@16
|
68 within(const SubT& sub, const SuperT& super)
|
Chris@16
|
69 {
|
Chris@16
|
70 if(icl::is_empty(sub)) return true;
|
Chris@16
|
71 if(icl::is_empty(super)) return false;
|
Chris@16
|
72 if(icl::size(super) < icl::size(sub)) return false;
|
Chris@16
|
73
|
Chris@16
|
74 typename SubT::const_iterator common_lwb_;
|
Chris@16
|
75 typename SubT::const_iterator common_upb_;
|
Chris@16
|
76 if(!Set::common_range(common_lwb_, common_upb_, sub, super))
|
Chris@16
|
77 return false;
|
Chris@16
|
78
|
Chris@16
|
79 typename SubT::const_iterator sub_ = sub.begin();
|
Chris@16
|
80 typename SuperT::const_iterator super_;
|
Chris@16
|
81 while(sub_ != sub.end())
|
Chris@16
|
82 {
|
Chris@16
|
83 super_ = super.find(key_value<SubT>(sub_));
|
Chris@16
|
84 if(super_ == super.end())
|
Chris@16
|
85 return false;
|
Chris@16
|
86 else if(!co_equal(sub_, super_, &sub, &super))
|
Chris@16
|
87 return false;
|
Chris@16
|
88
|
Chris@16
|
89 ++sub_;
|
Chris@16
|
90 }
|
Chris@16
|
91 return true;
|
Chris@16
|
92 }
|
Chris@16
|
93
|
Chris@16
|
94 //------------------------------------------------------------------------------
|
Chris@16
|
95 //- bool contains(c T&, c P&) T:{s}|{m} P:{e}|{i} fragment_types|key_types
|
Chris@16
|
96 //------------------------------------------------------------------------------
|
Chris@16
|
97 template<class Type>
|
Chris@16
|
98 typename enable_if<is_associative_element_container<Type>, bool>::type
|
Chris@16
|
99 contains(const Type& super, const typename Type::key_type& key)
|
Chris@16
|
100 {
|
Chris@16
|
101 return icl::within(key, super);
|
Chris@16
|
102 }
|
Chris@16
|
103
|
Chris@16
|
104 //------------------------------------------------------------------------------
|
Chris@16
|
105 //- bool contains(c T&, c P&) T:{s}|{m} P:{s'} fragment_types|key_types
|
Chris@16
|
106 //------------------------------------------------------------------------------
|
Chris@16
|
107 template<class SubT, class SuperT>
|
Chris@16
|
108 typename enable_if<mpl::and_< is_associative_element_container<SuperT>
|
Chris@16
|
109 , is_key_container_of<SubT, SuperT> >,
|
Chris@16
|
110 bool>::type
|
Chris@16
|
111 contains(const SuperT& super, const SubT& sub)
|
Chris@16
|
112 {
|
Chris@16
|
113 return icl::within(sub, super);
|
Chris@16
|
114 }
|
Chris@16
|
115
|
Chris@16
|
116 //==============================================================================
|
Chris@16
|
117 //= Equivalences and Orderings
|
Chris@16
|
118 //==============================================================================
|
Chris@16
|
119
|
Chris@16
|
120 #ifdef BOOST_MSVC
|
Chris@16
|
121 #pragma warning(push)
|
Chris@16
|
122 #pragma warning(disable:4996) //'std::equal': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
|
Chris@16
|
123 #endif // I do guarantee here that I am using the parameters correctly :)
|
Chris@16
|
124
|
Chris@16
|
125 /** Standard equality, which is lexicographical equality of the sets
|
Chris@16
|
126 as sequences, that are given by their Compare order. */
|
Chris@16
|
127 template<class Type>
|
Chris@16
|
128 inline typename enable_if<is_associative_element_container<Type>, bool>::type
|
Chris@16
|
129 operator == (const Type& left, const Type& right)
|
Chris@16
|
130 {
|
Chris@16
|
131 return left.size() == right.size()
|
Chris@16
|
132 && std::equal(left.begin(), left.end(), right.begin());
|
Chris@16
|
133 }
|
Chris@16
|
134
|
Chris@16
|
135 #ifdef BOOST_MSVC
|
Chris@16
|
136 #pragma warning(pop)
|
Chris@16
|
137 #endif
|
Chris@16
|
138
|
Chris@16
|
139 template<class Type>
|
Chris@16
|
140 inline typename enable_if<is_associative_element_container<Type>, bool>::type
|
Chris@16
|
141 is_element_equal(const Type& left, const Type& right)
|
Chris@16
|
142 { return left == right; }
|
Chris@16
|
143
|
Chris@16
|
144
|
Chris@16
|
145 /* Strict weak less ordering which is given by the Compare order */
|
Chris@16
|
146 template<class Type>
|
Chris@16
|
147 inline typename enable_if<is_associative_element_container<Type>, bool>::type
|
Chris@16
|
148 operator < (const Type& left, const Type& right)
|
Chris@16
|
149 {
|
Chris@16
|
150 return std::lexicographical_compare(
|
Chris@16
|
151 left.begin(), left.end(), right.begin(), right.end(),
|
Chris@16
|
152 typename Type::element_compare()
|
Chris@16
|
153 );
|
Chris@16
|
154 }
|
Chris@16
|
155
|
Chris@16
|
156 template<class LeftT, class RightT>
|
Chris@16
|
157 typename enable_if<is_concept_equivalent<is_element_container,LeftT, RightT>,
|
Chris@16
|
158 int>::type
|
Chris@16
|
159 inclusion_compare(const LeftT& left, const RightT& right)
|
Chris@16
|
160 {
|
Chris@16
|
161 return Set::subset_compare(left, right,
|
Chris@16
|
162 left.begin(), left.end(),
|
Chris@16
|
163 right.begin(), right.end());
|
Chris@16
|
164 }
|
Chris@16
|
165
|
Chris@16
|
166 //==============================================================================
|
Chris@16
|
167 //= Addition
|
Chris@16
|
168 //==============================================================================
|
Chris@16
|
169 template <class Type>
|
Chris@16
|
170 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
171 operator += (Type& object, const typename Type::value_type& operand)
|
Chris@16
|
172 {
|
Chris@16
|
173 return icl::add(object, operand);
|
Chris@16
|
174 }
|
Chris@16
|
175
|
Chris@16
|
176 template <class Type>
|
Chris@16
|
177 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
178 operator + (Type object, const typename Type::value_type& operand)
|
Chris@16
|
179 {
|
Chris@16
|
180 return object += operand;
|
Chris@16
|
181 }
|
Chris@16
|
182
|
Chris@16
|
183 template <class Type>
|
Chris@16
|
184 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
185 operator + (const typename Type::value_type& operand, Type object)
|
Chris@16
|
186 {
|
Chris@16
|
187 return object += operand;
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 template <class Type>
|
Chris@16
|
191 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
192 operator += (Type& object, const Type& operand)
|
Chris@16
|
193 {
|
Chris@16
|
194 if(&object == &operand)
|
Chris@16
|
195 return object;
|
Chris@16
|
196
|
Chris@16
|
197 typename Type::iterator prior_ = object.end();
|
Chris@16
|
198 ICL_const_FORALL(typename Type, it_, operand)
|
Chris@16
|
199 prior_ = icl::add(object, prior_, *it_);
|
Chris@16
|
200
|
Chris@16
|
201 return object;
|
Chris@16
|
202 }
|
Chris@16
|
203
|
Chris@16
|
204 template <class Type>
|
Chris@16
|
205 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
206 operator + (Type object, const Type& operand)
|
Chris@16
|
207 {
|
Chris@16
|
208 return object += operand;
|
Chris@16
|
209 }
|
Chris@16
|
210
|
Chris@16
|
211 //==============================================================================
|
Chris@16
|
212 template <class Type>
|
Chris@16
|
213 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
214 operator |= (Type& object, const typename Type::value_type& operand)
|
Chris@16
|
215 {
|
Chris@16
|
216 return icl::add(object, operand);
|
Chris@16
|
217 }
|
Chris@16
|
218
|
Chris@16
|
219 template <class Type>
|
Chris@16
|
220 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
221 operator | (Type object, const typename Type::value_type& operand)
|
Chris@16
|
222 {
|
Chris@16
|
223 return object += operand;
|
Chris@16
|
224 }
|
Chris@16
|
225
|
Chris@16
|
226 template <class Type>
|
Chris@16
|
227 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
228 operator | (const typename Type::value_type& operand, Type object)
|
Chris@16
|
229 {
|
Chris@16
|
230 return object += operand;
|
Chris@16
|
231 }
|
Chris@16
|
232
|
Chris@16
|
233 template <class Type>
|
Chris@16
|
234 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
235 operator |= (Type& object, const Type& operand)
|
Chris@16
|
236 {
|
Chris@16
|
237 return object += operand;
|
Chris@16
|
238 }
|
Chris@16
|
239
|
Chris@16
|
240 template <class Type>
|
Chris@16
|
241 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
242 operator | (Type object, const Type& operand)
|
Chris@16
|
243 {
|
Chris@16
|
244 return object += operand;
|
Chris@16
|
245 }
|
Chris@16
|
246
|
Chris@16
|
247
|
Chris@16
|
248 //==============================================================================
|
Chris@16
|
249 //= Insertion
|
Chris@16
|
250 //==============================================================================
|
Chris@16
|
251 //------------------------------------------------------------------------------
|
Chris@16
|
252 //- V insert(T&, c P&) T:{s}|{m} P:{e}|{b} fragment_type
|
Chris@16
|
253 //------------------------------------------------------------------------------
|
Chris@16
|
254 template<class Type>
|
Chris@16
|
255 typename enable_if<is_associative_element_container<Type>,
|
Chris@16
|
256 std::pair<typename Type::iterator,bool> >::type
|
Chris@16
|
257 insert(Type& object, const typename Type::value_type& operand)
|
Chris@16
|
258 {
|
Chris@16
|
259 return object.insert(operand);
|
Chris@16
|
260 }
|
Chris@16
|
261
|
Chris@16
|
262 template<class Type>
|
Chris@16
|
263 typename enable_if<is_associative_element_container<Type>,
|
Chris@16
|
264 typename Type::iterator>::type
|
Chris@16
|
265 insert(Type& object, typename Type::iterator prior,
|
Chris@16
|
266 const typename Type::value_type& operand)
|
Chris@16
|
267 {
|
Chris@16
|
268 return object.insert(prior, operand);
|
Chris@16
|
269 }
|
Chris@16
|
270
|
Chris@16
|
271 //------------------------------------------------------------------------------
|
Chris@16
|
272 //- T insert(T&, c T&) T:{s m} map fragment_type
|
Chris@16
|
273 //------------------------------------------------------------------------------
|
Chris@16
|
274 template<class Type>
|
Chris@16
|
275 typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
276 insert(Type& object, const Type& addend)
|
Chris@16
|
277 {
|
Chris@16
|
278 typedef typename Type::iterator iterator;
|
Chris@16
|
279
|
Chris@16
|
280 iterator prior_ = object.end();
|
Chris@16
|
281 ICL_const_FORALL(typename Type, elem_, addend)
|
Chris@16
|
282 icl::insert(object, prior_, *elem_);
|
Chris@16
|
283
|
Chris@16
|
284 return object;
|
Chris@16
|
285 }
|
Chris@16
|
286
|
Chris@16
|
287
|
Chris@16
|
288 //==============================================================================
|
Chris@16
|
289 //= Erasure
|
Chris@16
|
290 //==============================================================================
|
Chris@16
|
291 template<class Type>
|
Chris@16
|
292 typename enable_if<is_associative_element_container<Type>, typename Type::size_type>::type
|
Chris@16
|
293 erase(Type& object, const typename Type::key_type& key_value)
|
Chris@16
|
294 {
|
Chris@16
|
295 typedef typename Type::size_type size_type;
|
Chris@16
|
296 typename Type::iterator it_ = object.find(key_value);
|
Chris@16
|
297 if(it_ != object.end())
|
Chris@16
|
298 {
|
Chris@16
|
299 object.erase(it_);
|
Chris@16
|
300 return unit_element<size_type>::value();
|
Chris@16
|
301 }
|
Chris@16
|
302 return identity_element<size_type>::value();
|
Chris@16
|
303 }
|
Chris@16
|
304
|
Chris@16
|
305 template<class Type>
|
Chris@16
|
306 typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
307 erase(Type& object, const Type& erasure)
|
Chris@16
|
308 {
|
Chris@16
|
309 ICL_const_FORALL(typename Type, elem_, erasure)
|
Chris@16
|
310 icl::erase(object, *elem_);
|
Chris@16
|
311
|
Chris@16
|
312 return object;
|
Chris@16
|
313 }
|
Chris@16
|
314
|
Chris@16
|
315
|
Chris@16
|
316
|
Chris@16
|
317 //==============================================================================
|
Chris@16
|
318 //= Subtraction<ElementSet|ElementMap>
|
Chris@16
|
319 //==============================================================================
|
Chris@16
|
320 template <class Type>
|
Chris@16
|
321 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
322 operator -= (Type& object, const typename Type::value_type& operand)
|
Chris@16
|
323 {
|
Chris@16
|
324 return icl::subtract(object, operand);
|
Chris@16
|
325 }
|
Chris@16
|
326
|
Chris@16
|
327 template <class Type>
|
Chris@16
|
328 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
329 operator - (Type object, const typename Type::value_type& operand)
|
Chris@16
|
330 {
|
Chris@16
|
331 return object -= operand;
|
Chris@16
|
332 }
|
Chris@16
|
333
|
Chris@16
|
334 template <class Type>
|
Chris@16
|
335 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
336 operator -= (Type& object, const Type& subtrahend)
|
Chris@16
|
337 {
|
Chris@16
|
338 ICL_const_FORALL(typename Type, it_, subtrahend)
|
Chris@16
|
339 icl::subtract(object, *it_);
|
Chris@16
|
340
|
Chris@16
|
341 return object;
|
Chris@16
|
342 }
|
Chris@16
|
343
|
Chris@16
|
344 template <class Type>
|
Chris@16
|
345 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
346 operator - (Type object, const Type& subtrahend)
|
Chris@16
|
347 {
|
Chris@16
|
348 return object -= subtrahend;
|
Chris@16
|
349 }
|
Chris@16
|
350
|
Chris@16
|
351
|
Chris@16
|
352 //==============================================================================
|
Chris@16
|
353 //= Intersection
|
Chris@16
|
354 //==============================================================================
|
Chris@16
|
355 //------------------------------------------------------------------------------
|
Chris@16
|
356 //- void add_intersection(T&, c T&, c P&) T:{s}{m} P:{e}{e} key_type
|
Chris@16
|
357 //------------------------------------------------------------------------------
|
Chris@16
|
358 template<class Type>
|
Chris@16
|
359 inline typename enable_if<is_associative_element_container<Type>, void>::type
|
Chris@16
|
360 add_intersection(Type& section, const Type& object,
|
Chris@16
|
361 const typename Type::key_type& operand)
|
Chris@16
|
362 {
|
Chris@16
|
363 typedef typename Type::const_iterator const_iterator;
|
Chris@16
|
364 const_iterator it_ = object.find(operand);
|
Chris@16
|
365 if(it_ != object.end())
|
Chris@16
|
366 icl::add(section, *it_);
|
Chris@16
|
367 }
|
Chris@16
|
368
|
Chris@16
|
369 //------------------------------------------------------------------------------
|
Chris@16
|
370 //- void add_intersection(T&, c T&, c P&) T:{s}{m} P:{s}{s} set key_type
|
Chris@16
|
371 //------------------------------------------------------------------------------
|
Chris@16
|
372 template<class Type>
|
Chris@16
|
373 inline typename enable_if<is_associative_element_container<Type>, void>::type
|
Chris@16
|
374 add_intersection(Type& section, const Type& object,
|
Chris@16
|
375 const typename key_container_type_of<Type>::type& operand)
|
Chris@16
|
376 {
|
Chris@16
|
377 typedef typename key_container_type_of<Type>::type key_container_type;
|
Chris@16
|
378 typedef typename key_container_type::const_iterator const_iterator;
|
Chris@16
|
379 const_iterator common_lwb_, common_upb_;
|
Chris@16
|
380 if(!Set::common_range(common_lwb_, common_upb_, operand, object))
|
Chris@16
|
381 return;
|
Chris@16
|
382
|
Chris@16
|
383 const_iterator sec_ = common_lwb_;
|
Chris@16
|
384 while(sec_ != common_upb_)
|
Chris@16
|
385 add_intersection(section, object, *sec_++);
|
Chris@16
|
386 }
|
Chris@16
|
387
|
Chris@16
|
388 //------------------------------------------------------------------------------
|
Chris@16
|
389 //- Intersection<ElementMap|ElementSet>
|
Chris@16
|
390 //------------------------------------------------------------------------------
|
Chris@16
|
391 template<class Type>
|
Chris@16
|
392 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
393 operator &= (Type& object, const typename Type::key_type& operand)
|
Chris@16
|
394 {
|
Chris@16
|
395 Type section;
|
Chris@16
|
396 add_intersection(section, object, operand);
|
Chris@16
|
397 object.swap(section);
|
Chris@16
|
398 return object;
|
Chris@16
|
399 }
|
Chris@16
|
400
|
Chris@16
|
401 template<class Type>
|
Chris@16
|
402 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
403 operator & (Type object, const typename Type::key_type& operand)
|
Chris@16
|
404 {
|
Chris@16
|
405 return object &= operand;
|
Chris@16
|
406 }
|
Chris@16
|
407
|
Chris@16
|
408 template<class Type>
|
Chris@16
|
409 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
410 operator & (const typename Type::key_type& operand, Type object)
|
Chris@16
|
411 {
|
Chris@16
|
412 return object &= operand;
|
Chris@16
|
413 }
|
Chris@16
|
414
|
Chris@16
|
415 template<class Type>
|
Chris@16
|
416 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
417 operator &= (Type& object, const typename key_container_type_of<Type>::type& operand)
|
Chris@16
|
418 {
|
Chris@16
|
419 Type section;
|
Chris@16
|
420 add_intersection(section, object, operand);
|
Chris@16
|
421 object.swap(section);
|
Chris@16
|
422 return object;
|
Chris@16
|
423 }
|
Chris@16
|
424
|
Chris@16
|
425 template<class Type>
|
Chris@16
|
426 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
427 operator & (Type object, const Type& operand)
|
Chris@16
|
428 {
|
Chris@16
|
429 return object &= operand;
|
Chris@16
|
430 }
|
Chris@16
|
431 //------------------------------------------------------------------------------
|
Chris@16
|
432
|
Chris@16
|
433 template<class Type, class CoType>
|
Chris@16
|
434 inline typename enable_if<is_associative_element_container<Type>, bool>::type
|
Chris@16
|
435 disjoint(const Type& left, const Type& right)
|
Chris@16
|
436 {
|
Chris@16
|
437 return !intersects(left, right);
|
Chris@16
|
438 }
|
Chris@16
|
439
|
Chris@16
|
440 //==============================================================================
|
Chris@16
|
441 //= Symmetric difference<ElementSet|ElementMap>
|
Chris@16
|
442 //==============================================================================
|
Chris@16
|
443 template<class Type>
|
Chris@16
|
444 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
445 operator ^ (Type object, const typename Type::value_type& operand)
|
Chris@16
|
446 {
|
Chris@16
|
447 return icl::flip(object, operand);
|
Chris@16
|
448 }
|
Chris@16
|
449
|
Chris@16
|
450 template<class Type>
|
Chris@16
|
451 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
452 operator ^ (const typename Type::value_type& operand, Type object)
|
Chris@16
|
453 {
|
Chris@16
|
454 return icl::flip(object, operand);
|
Chris@16
|
455 }
|
Chris@16
|
456
|
Chris@16
|
457 template<class Type>
|
Chris@16
|
458 inline typename enable_if<is_associative_element_container<Type>, Type>::type
|
Chris@16
|
459 operator ^ (Type object, const Type& operand)
|
Chris@16
|
460 {
|
Chris@16
|
461 return object ^= operand;
|
Chris@16
|
462 }
|
Chris@16
|
463
|
Chris@16
|
464
|
Chris@16
|
465 //==============================================================================
|
Chris@16
|
466 //= Manipulation by predicates
|
Chris@16
|
467 //==============================================================================
|
Chris@16
|
468 template<class Type, class Predicate>
|
Chris@16
|
469 typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
470 erase_if(const Predicate& pred, Type& object)
|
Chris@16
|
471 {
|
Chris@16
|
472 typename Type::iterator it_ = object.begin();
|
Chris@16
|
473 while(it_ != object.end())
|
Chris@16
|
474 if(pred(*it_))
|
Chris@16
|
475 icl::erase(object, it_++);
|
Chris@16
|
476 else ++it_;
|
Chris@16
|
477 return object;
|
Chris@16
|
478 }
|
Chris@16
|
479
|
Chris@16
|
480 template<class Type, class Predicate>
|
Chris@16
|
481 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
482 add_if(const Predicate& pred, Type& object, const Type& src)
|
Chris@16
|
483 {
|
Chris@16
|
484 typename Type::const_iterator it_ = src.begin();
|
Chris@16
|
485 while(it_ != src.end())
|
Chris@16
|
486 if(pred(*it_))
|
Chris@16
|
487 icl::add(object, *it_++);
|
Chris@16
|
488
|
Chris@16
|
489 return object;
|
Chris@16
|
490 }
|
Chris@16
|
491
|
Chris@16
|
492 template<class Type, class Predicate>
|
Chris@16
|
493 inline typename enable_if<is_associative_element_container<Type>, Type>::type&
|
Chris@16
|
494 assign_if(const Predicate& pred, Type& object, const Type& src)
|
Chris@16
|
495 {
|
Chris@16
|
496 icl::clear(object);
|
Chris@16
|
497 return add_if(object, src, pred);
|
Chris@16
|
498 }
|
Chris@16
|
499
|
Chris@16
|
500
|
Chris@16
|
501
|
Chris@16
|
502 }} // namespace boost icl
|
Chris@16
|
503
|
Chris@16
|
504 #endif
|
Chris@16
|
505
|
Chris@16
|
506
|