Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/icl/map.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /*-----------------------------------------------------------------------------+ | |
2 Copyright (c) 2007-2011: Joachim Faulhaber | |
3 +------------------------------------------------------------------------------+ | |
4 Distributed under the Boost Software License, Version 1.0. | |
5 (See accompanying file LICENCE.txt or copy at | |
6 http://www.boost.org/LICENSE_1_0.txt) | |
7 +-----------------------------------------------------------------------------*/ | |
8 #ifndef BOOST_ICL_MAP_HPP_JOFA_070519 | |
9 #define BOOST_ICL_MAP_HPP_JOFA_070519 | |
10 | |
11 #include <boost/icl/impl_config.hpp> | |
12 | |
13 #if defined(ICL_USE_BOOST_MOVE_IMPLEMENTATION) | |
14 # include <boost/container/map.hpp> | |
15 # include <boost/container/set.hpp> | |
16 #elif defined(ICL_USE_STD_IMPLEMENTATION) | |
17 # include <map> | |
18 # include <set> | |
19 #else // Default for implementing containers | |
20 # include <map> | |
21 # include <set> | |
22 #endif | |
23 | |
24 #include <string> | |
25 #include <boost/type_traits/ice.hpp> | |
26 #include <boost/call_traits.hpp> | |
27 #include <boost/icl/detail/notate.hpp> | |
28 #include <boost/icl/detail/design_config.hpp> | |
29 #include <boost/icl/detail/concept_check.hpp> | |
30 #include <boost/icl/detail/on_absorbtion.hpp> | |
31 #include <boost/icl/type_traits/is_map.hpp> | |
32 #include <boost/icl/type_traits/absorbs_identities.hpp> | |
33 #include <boost/icl/type_traits/is_total.hpp> | |
34 #include <boost/icl/type_traits/is_element_container.hpp> | |
35 #include <boost/icl/type_traits/has_inverse.hpp> | |
36 #include <boost/icl/type_traits/to_string.hpp> | |
37 | |
38 #include <boost/icl/associative_element_container.hpp> | |
39 #include <boost/icl/functors.hpp> | |
40 | |
41 namespace boost{namespace icl | |
42 { | |
43 | |
44 struct partial_absorber | |
45 { | |
46 enum { absorbs_identities = true }; | |
47 enum { is_total = false }; | |
48 }; | |
49 | |
50 template<> | |
51 inline std::string type_to_string<partial_absorber>::apply() { return "@0"; } | |
52 | |
53 struct partial_enricher | |
54 { | |
55 enum { absorbs_identities = false }; | |
56 enum { is_total = false }; | |
57 }; | |
58 | |
59 template<> | |
60 inline std::string type_to_string<partial_enricher>::apply() { return "e0"; } | |
61 | |
62 struct total_absorber | |
63 { | |
64 enum { absorbs_identities = true }; | |
65 enum { is_total = true }; | |
66 }; | |
67 | |
68 template<> | |
69 inline std::string type_to_string<total_absorber>::apply() { return "^0"; } | |
70 | |
71 struct total_enricher | |
72 { | |
73 enum { absorbs_identities = false }; | |
74 enum { is_total = true }; | |
75 }; | |
76 | |
77 template<> | |
78 inline std::string type_to_string<total_enricher>::apply() { return "e^0"; } | |
79 | |
80 | |
81 | |
82 /** \brief Addable, subractable and intersectable maps */ | |
83 template | |
84 < | |
85 typename DomainT, | |
86 typename CodomainT, | |
87 class Traits = icl::partial_absorber, | |
88 ICL_COMPARE Compare = ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, DomainT), | |
89 ICL_COMBINE Combine = ICL_COMBINE_INSTANCE(icl::inplace_plus, CodomainT), | |
90 ICL_SECTION Section = ICL_SECTION_INSTANCE(icl::inter_section, CodomainT), | |
91 ICL_ALLOC Alloc = std::allocator | |
92 > | |
93 class map: private ICL_IMPL_SPACE::map<DomainT, CodomainT, ICL_COMPARE_DOMAIN(Compare,DomainT), | |
94 Alloc<std::pair<const DomainT, CodomainT> > > | |
95 { | |
96 public: | |
97 typedef Alloc<typename std::pair<const DomainT, CodomainT> > allocator_type; | |
98 | |
99 typedef typename icl::map<DomainT,CodomainT,Traits, Compare,Combine,Section,Alloc> type; | |
100 typedef typename ICL_IMPL_SPACE::map<DomainT, CodomainT, ICL_COMPARE_DOMAIN(Compare,DomainT), | |
101 allocator_type> base_type; | |
102 | |
103 typedef Traits traits; | |
104 | |
105 public: | |
106 typedef DomainT domain_type; | |
107 typedef typename boost::call_traits<DomainT>::param_type domain_param; | |
108 typedef DomainT key_type; | |
109 typedef CodomainT codomain_type; | |
110 typedef CodomainT mapped_type; | |
111 typedef CodomainT data_type; | |
112 typedef std::pair<const DomainT, CodomainT> element_type; | |
113 typedef std::pair<const DomainT, CodomainT> value_type; | |
114 typedef ICL_COMPARE_DOMAIN(Compare,DomainT) domain_compare; | |
115 typedef ICL_COMBINE_CODOMAIN(Combine,CodomainT) codomain_combine; | |
116 typedef domain_compare key_compare; | |
117 typedef ICL_COMPARE_DOMAIN(Compare,element_type) element_compare; | |
118 typedef typename inverse<codomain_combine >::type inverse_codomain_combine; | |
119 typedef typename mpl::if_ | |
120 <has_set_semantics<codomain_type> | |
121 , ICL_SECTION_CODOMAIN(Section,CodomainT) | |
122 , codomain_combine | |
123 >::type codomain_intersect; | |
124 typedef typename inverse<codomain_intersect>::type inverse_codomain_intersect; | |
125 typedef typename base_type::value_compare value_compare; | |
126 | |
127 typedef typename ICL_IMPL_SPACE::set<DomainT, domain_compare, Alloc<DomainT> > set_type; | |
128 typedef set_type key_object_type; | |
129 | |
130 | |
131 BOOST_STATIC_CONSTANT(bool, _total = (Traits::is_total)); | |
132 BOOST_STATIC_CONSTANT(bool, _absorbs = (Traits::absorbs_identities)); | |
133 BOOST_STATIC_CONSTANT(bool, | |
134 total_invertible = (mpl::and_<is_total<type>, has_inverse<codomain_type> >::value)); | |
135 | |
136 typedef on_absorbtion<type,codomain_combine,Traits::absorbs_identities> | |
137 on_identity_absorbtion; | |
138 | |
139 public: | |
140 typedef typename base_type::pointer pointer; | |
141 typedef typename base_type::const_pointer const_pointer; | |
142 typedef typename base_type::reference reference; | |
143 typedef typename base_type::const_reference const_reference; | |
144 typedef typename base_type::iterator iterator; | |
145 typedef typename base_type::const_iterator const_iterator; | |
146 typedef typename base_type::size_type size_type; | |
147 typedef typename base_type::difference_type difference_type; | |
148 typedef typename base_type::reverse_iterator reverse_iterator; | |
149 typedef typename base_type::const_reverse_iterator const_reverse_iterator; | |
150 | |
151 public: | |
152 BOOST_STATIC_CONSTANT(bool, | |
153 is_total_invertible = ( Traits::is_total | |
154 && has_inverse<codomain_type>::value)); | |
155 | |
156 BOOST_STATIC_CONSTANT(int, fineness = 4); | |
157 | |
158 public: | |
159 //========================================================================== | |
160 //= Construct, copy, destruct | |
161 //========================================================================== | |
162 map() | |
163 { | |
164 BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>)); | |
165 BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>)); | |
166 BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>)); | |
167 BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>)); | |
168 } | |
169 | |
170 map(const key_compare& comp): base_type(comp){} | |
171 | |
172 template <class InputIterator> | |
173 map(InputIterator first, InputIterator past) | |
174 : base_type(first,past){} | |
175 | |
176 template <class InputIterator> | |
177 map(InputIterator first, InputIterator past, const key_compare& comp) | |
178 : base_type(first,past,comp) | |
179 {} | |
180 | |
181 map(const map& src) | |
182 : base_type(src) | |
183 { | |
184 BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>)); | |
185 BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>)); | |
186 BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>)); | |
187 BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>)); | |
188 } | |
189 | |
190 explicit map(const element_type& key_value_pair): base_type::map() | |
191 { | |
192 insert(key_value_pair); | |
193 } | |
194 | |
195 map& operator = (const map& src) | |
196 { | |
197 base_type::operator=(src); | |
198 return *this; | |
199 } | |
200 | |
201 # ifndef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
202 //========================================================================== | |
203 //= Move semantics | |
204 //========================================================================== | |
205 | |
206 map(map&& src) | |
207 : base_type(boost::move(src)) | |
208 { | |
209 BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>)); | |
210 BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>)); | |
211 BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>)); | |
212 BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>)); | |
213 } | |
214 | |
215 map& operator = (map&& src) | |
216 { | |
217 base_type::operator=(src); | |
218 return *this; | |
219 } | |
220 //========================================================================== | |
221 # endif // BOOST_ICL_NO_CXX11_RVALUE_REFERENCES | |
222 | |
223 void swap(map& src) { base_type::swap(src); } | |
224 | |
225 //========================================================================== | |
226 using base_type::empty; | |
227 using base_type::clear; | |
228 | |
229 using base_type::begin; | |
230 using base_type::end; | |
231 using base_type::rbegin; | |
232 using base_type::rend; | |
233 | |
234 using base_type::size; | |
235 using base_type::max_size; | |
236 | |
237 using base_type::key_comp; | |
238 using base_type::value_comp; | |
239 | |
240 using base_type::erase; | |
241 using base_type::find; | |
242 using base_type::count; | |
243 | |
244 using base_type::lower_bound; | |
245 using base_type::upper_bound; | |
246 using base_type::equal_range; | |
247 | |
248 using base_type::operator[]; | |
249 | |
250 public: | |
251 //========================================================================== | |
252 //= Containedness | |
253 //========================================================================== | |
254 | |
255 template<class SubObject> | |
256 bool contains(const SubObject& sub)const | |
257 { return icl::contains(*this, sub); } | |
258 | |
259 bool within(const map& super)const | |
260 { return icl::contains(super, *this); } | |
261 | |
262 //========================================================================== | |
263 //= Size | |
264 //========================================================================== | |
265 /** \c iterative_size() yields the number of elements that is visited | |
266 throu complete iteration. For interval sets \c iterative_size() is | |
267 different from \c size(). */ | |
268 std::size_t iterative_size()const { return base_type::size(); } | |
269 | |
270 //========================================================================== | |
271 //= Selection | |
272 //========================================================================== | |
273 | |
274 /** Total select function. */ | |
275 codomain_type operator()(const domain_type& key)const | |
276 { | |
277 const_iterator it = find(key); | |
278 return it==end() ? identity_element<codomain_type>::value() | |
279 : it->second; | |
280 } | |
281 | |
282 //========================================================================== | |
283 //= Addition | |
284 //========================================================================== | |
285 /** \c add inserts \c value_pair into the map if it's key does | |
286 not exist in the map. | |
287 If \c value_pairs's key value exists in the map, it's data | |
288 value is added to the data value already found in the map. */ | |
289 map& add(const value_type& value_pair) | |
290 { | |
291 return _add<codomain_combine>(value_pair); | |
292 } | |
293 | |
294 /** \c add add \c value_pair into the map using \c prior as a hint to | |
295 insert \c value_pair after the position \c prior is pointing to. */ | |
296 iterator add(iterator prior, const value_type& value_pair) | |
297 { | |
298 return _add<codomain_combine>(prior, value_pair); | |
299 } | |
300 | |
301 //========================================================================== | |
302 //= Subtraction | |
303 //========================================================================== | |
304 /** If the \c value_pair's key value is in the map, it's data value is | |
305 subtraced from the data value stored in the map. */ | |
306 map& subtract(const element_type& value_pair) | |
307 { | |
308 on_invertible<type, is_total_invertible> | |
309 ::subtract(*this, value_pair); | |
310 return *this; | |
311 } | |
312 | |
313 map& subtract(const domain_type& key) | |
314 { | |
315 icl::erase(*this, key); | |
316 return *this; | |
317 } | |
318 | |
319 //========================================================================== | |
320 //= Insertion, erasure | |
321 //========================================================================== | |
322 std::pair<iterator,bool> insert(const value_type& value_pair) | |
323 { | |
324 if(on_identity_absorbtion::is_absorbable(value_pair.second)) | |
325 return std::pair<iterator,bool>(end(),true); | |
326 else | |
327 return base_type::insert(value_pair); | |
328 } | |
329 | |
330 iterator insert(iterator prior, const value_type& value_pair) | |
331 { | |
332 if(on_identity_absorbtion::is_absorbable(value_pair.second)) | |
333 return end(); | |
334 else | |
335 return base_type::insert(prior, value_pair); | |
336 } | |
337 | |
338 template<class Iterator> | |
339 iterator insert(Iterator first, Iterator last) | |
340 { | |
341 iterator prior = end(), it = first; | |
342 while(it != last) | |
343 prior = this->insert(prior, *it++); | |
344 } | |
345 | |
346 /** With <tt>key_value_pair = (k,v)</tt> set value \c v for key \c k */ | |
347 map& set(const element_type& key_value_pair) | |
348 { | |
349 return icl::set_at(*this, key_value_pair); | |
350 } | |
351 | |
352 /** erase \c key_value_pair from the map. | |
353 Erase only if, the exact value content \c val is stored for the given key. */ | |
354 size_type erase(const element_type& key_value_pair) | |
355 { | |
356 return icl::erase(*this, key_value_pair); | |
357 } | |
358 | |
359 //========================================================================== | |
360 //= Intersection | |
361 //========================================================================== | |
362 /** The intersection of \c key_value_pair and \c *this map is added to \c section. */ | |
363 void add_intersection(map& section, const element_type& key_value_pair)const | |
364 { | |
365 on_definedness<type, Traits::is_total> | |
366 ::add_intersection(section, *this, key_value_pair); | |
367 } | |
368 | |
369 //========================================================================== | |
370 //= Symmetric difference | |
371 //========================================================================== | |
372 | |
373 map& flip(const element_type& operand) | |
374 { | |
375 on_total_absorbable<type,_total,_absorbs>::flip(*this, operand); | |
376 return *this; | |
377 } | |
378 | |
379 private: | |
380 template<class Combiner> | |
381 map& _add(const element_type& value_pair); | |
382 | |
383 template<class Combiner> | |
384 iterator _add(iterator prior, const element_type& value_pair); | |
385 | |
386 template<class Combiner> | |
387 map& _subtract(const element_type& value_pair); | |
388 | |
389 template<class FragmentT> | |
390 void total_add_intersection(type& section, const FragmentT& fragment)const | |
391 { | |
392 section += *this; | |
393 section.add(fragment); | |
394 } | |
395 | |
396 void partial_add_intersection(type& section, const element_type& operand)const | |
397 { | |
398 const_iterator it_ = find(operand.first); | |
399 if(it_ != end()) | |
400 { | |
401 section.template _add<codomain_combine >(*it_); | |
402 section.template _add<codomain_intersect>(operand); | |
403 } | |
404 } | |
405 | |
406 | |
407 private: | |
408 //-------------------------------------------------------------------------- | |
409 template<class Type, bool is_total_invertible> | |
410 struct on_invertible; | |
411 | |
412 template<class Type> | |
413 struct on_invertible<Type, true> | |
414 { | |
415 typedef typename Type::element_type element_type; | |
416 typedef typename Type::inverse_codomain_combine inverse_codomain_combine; | |
417 | |
418 static void subtract(Type& object, const element_type& operand) | |
419 { object.template _add<inverse_codomain_combine>(operand); } | |
420 }; | |
421 | |
422 template<class Type> | |
423 struct on_invertible<Type, false> | |
424 { | |
425 typedef typename Type::element_type element_type; | |
426 typedef typename Type::inverse_codomain_combine inverse_codomain_combine; | |
427 | |
428 static void subtract(Type& object, const element_type& operand) | |
429 { object.template _subtract<inverse_codomain_combine>(operand); } | |
430 }; | |
431 | |
432 friend struct on_invertible<type, true>; | |
433 friend struct on_invertible<type, false>; | |
434 //-------------------------------------------------------------------------- | |
435 | |
436 //-------------------------------------------------------------------------- | |
437 template<class Type, bool is_total> | |
438 struct on_definedness; | |
439 | |
440 template<class Type> | |
441 struct on_definedness<Type, true> | |
442 { | |
443 static void add_intersection(Type& section, const Type& object, | |
444 const element_type& operand) | |
445 { object.total_add_intersection(section, operand); } | |
446 }; | |
447 | |
448 template<class Type> | |
449 struct on_definedness<Type, false> | |
450 { | |
451 static void add_intersection(Type& section, const Type& object, | |
452 const element_type& operand) | |
453 { object.partial_add_intersection(section, operand); } | |
454 }; | |
455 | |
456 friend struct on_definedness<type, true>; | |
457 friend struct on_definedness<type, false>; | |
458 //-------------------------------------------------------------------------- | |
459 | |
460 //-------------------------------------------------------------------------- | |
461 template<class Type, bool has_set_semantics, bool absorbs_identities> | |
462 struct on_codomain_model; | |
463 | |
464 template<class Type> | |
465 struct on_codomain_model<Type, false, false> | |
466 { // !codomain_is_set, !absorbs_identities | |
467 static void subtract(Type&, typename Type::iterator it_, | |
468 const typename Type::codomain_type& ) | |
469 { (*it_).second = identity_element<typename Type::codomain_type>::value(); } | |
470 }; | |
471 | |
472 template<class Type> | |
473 struct on_codomain_model<Type, false, true> | |
474 { // !codomain_is_set, absorbs_identities | |
475 static void subtract(Type& object, typename Type::iterator it_, | |
476 const typename Type::codomain_type& ) | |
477 { object.erase(it_); } | |
478 }; | |
479 | |
480 template<class Type> | |
481 struct on_codomain_model<Type, true, false> | |
482 { // !codomain_is_set, !absorbs_identities | |
483 typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect; | |
484 static void subtract(Type&, typename Type::iterator it_, | |
485 const typename Type::codomain_type& co_value) | |
486 { | |
487 inverse_codomain_intersect()((*it_).second, co_value); | |
488 } | |
489 }; | |
490 | |
491 template<class Type> | |
492 struct on_codomain_model<Type, true, true> | |
493 { // !codomain_is_set, absorbs_identities | |
494 typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect; | |
495 static void subtract(Type& object, typename Type::iterator it_, | |
496 const typename Type::codomain_type& co_value) | |
497 { | |
498 inverse_codomain_intersect()((*it_).second, co_value); | |
499 if((*it_).second == identity_element<codomain_type>::value()) | |
500 object.erase(it_); | |
501 } | |
502 }; | |
503 //-------------------------------------------------------------------------- | |
504 | |
505 //-------------------------------------------------------------------------- | |
506 template<class Type, bool is_total, bool absorbs_identities> | |
507 struct on_total_absorbable; | |
508 | |
509 template<class Type> | |
510 struct on_total_absorbable<Type, true, true> | |
511 { | |
512 typedef typename Type::element_type element_type; | |
513 static void flip(Type& object, const typename Type::element_type&) | |
514 { icl::clear(object); } | |
515 }; | |
516 | |
517 template<class Type> | |
518 struct on_total_absorbable<Type, true, false> | |
519 { | |
520 typedef typename Type::element_type element_type; | |
521 typedef typename Type::codomain_type codomain_type; | |
522 | |
523 static void flip(Type& object, const element_type& operand) | |
524 { | |
525 object.add(operand); | |
526 ICL_FORALL(typename Type, it_, object) | |
527 (*it_).second = identity_element<codomain_type>::value(); | |
528 } | |
529 }; | |
530 | |
531 template<class Type> | |
532 struct on_total_absorbable<Type, false, true> | |
533 { // !is_total, absorbs_identities | |
534 typedef typename Type::element_type element_type; | |
535 typedef typename Type::codomain_type codomain_type; | |
536 typedef typename Type::iterator iterator; | |
537 typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect; | |
538 | |
539 static void flip(Type& object, const element_type& operand) | |
540 { | |
541 std::pair<iterator,bool> insertion = object.insert(operand); | |
542 if(!insertion.second) | |
543 on_codomain_model<Type, has_set_semantics<codomain_type>::value, true> | |
544 ::subtract(object, insertion.first, operand.second); | |
545 } | |
546 }; | |
547 | |
548 template<class Type> | |
549 struct on_total_absorbable<Type, false, false> | |
550 { // !is_total !absorbs_identities | |
551 typedef typename Type::element_type element_type; | |
552 typedef typename Type::codomain_type codomain_type; | |
553 typedef typename Type::iterator iterator; | |
554 typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect; | |
555 | |
556 static void flip(Type& object, const element_type& operand) | |
557 { | |
558 std::pair<iterator,bool> insertion = object.insert(operand); | |
559 if(!insertion.second) | |
560 on_codomain_model<Type, has_set_semantics<codomain_type>::value, false> | |
561 ::subtract(object, insertion.first, operand.second); | |
562 } | |
563 }; | |
564 | |
565 friend struct on_total_absorbable<type, true, true >; | |
566 friend struct on_total_absorbable<type, false, true >; | |
567 friend struct on_total_absorbable<type, true, false>; | |
568 friend struct on_total_absorbable<type, false, false>; | |
569 //-------------------------------------------------------------------------- | |
570 }; | |
571 | |
572 | |
573 | |
574 //============================================================================== | |
575 //= Addition<ElementMap> | |
576 //============================================================================== | |
577 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc> | |
578 template <class Combiner> | |
579 map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>& | |
580 map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> | |
581 ::_add(const element_type& addend) | |
582 { | |
583 typedef typename on_absorbtion | |
584 <type,Combiner,absorbs_identities<type>::value>::type on_absorbtion_; | |
585 | |
586 const codomain_type& co_val = addend.second; | |
587 if(on_absorbtion_::is_absorbable(co_val)) | |
588 return *this; | |
589 | |
590 std::pair<iterator,bool> insertion | |
591 = base_type::insert(value_type(addend.first, version<Combiner>()(co_val))); | |
592 | |
593 if(!insertion.second) | |
594 { | |
595 iterator it = insertion.first; | |
596 Combiner()((*it).second, co_val); | |
597 | |
598 if(on_absorbtion_::is_absorbable((*it).second)) | |
599 erase(it); | |
600 } | |
601 return *this; | |
602 } | |
603 | |
604 | |
605 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc> | |
606 template <class Combiner> | |
607 typename map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>::iterator | |
608 map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> | |
609 ::_add(iterator prior_, const value_type& addend) | |
610 { | |
611 typedef typename on_absorbtion | |
612 <type,Combiner,absorbs_identities<type>::value>::type on_absorbtion_; | |
613 | |
614 const codomain_type& co_val = addend.second; | |
615 if(on_absorbtion_::is_absorbable(co_val)) | |
616 return end(); | |
617 | |
618 iterator inserted_ | |
619 = base_type::insert(prior_, | |
620 value_type(addend.first, Combiner::identity_element())); | |
621 Combiner()((*inserted_).second, addend.second); | |
622 | |
623 if(on_absorbtion_::is_absorbable((*inserted_).second)) | |
624 { | |
625 erase(inserted_); | |
626 return end(); | |
627 } | |
628 else | |
629 return inserted_; | |
630 } | |
631 | |
632 | |
633 //============================================================================== | |
634 //= Subtraction<ElementMap> | |
635 //============================================================================== | |
636 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc> | |
637 template <class Combiner> | |
638 map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>& | |
639 map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>::_subtract(const value_type& minuend) | |
640 { | |
641 typedef typename on_absorbtion | |
642 <type,Combiner,absorbs_identities<type>::value>::type on_absorbtion_; | |
643 | |
644 iterator it_ = find(minuend.first); | |
645 if(it_ != end()) | |
646 { | |
647 Combiner()((*it_).second, minuend.second); | |
648 if(on_absorbtion_::is_absorbable((*it_).second)) | |
649 erase(it_); | |
650 } | |
651 return *this; | |
652 } | |
653 | |
654 | |
655 //----------------------------------------------------------------------------- | |
656 // type traits | |
657 //----------------------------------------------------------------------------- | |
658 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc> | |
659 struct is_map<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> > | |
660 { | |
661 typedef is_map<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> > type; | |
662 BOOST_STATIC_CONSTANT(bool, value = true); | |
663 }; | |
664 | |
665 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc> | |
666 struct has_inverse<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> > | |
667 { | |
668 typedef has_inverse<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> > type; | |
669 BOOST_STATIC_CONSTANT(bool, value = (has_inverse<CodomainT>::value)); | |
670 }; | |
671 | |
672 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc> | |
673 struct absorbs_identities<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> > | |
674 { | |
675 typedef absorbs_identities type; | |
676 BOOST_STATIC_CONSTANT(int, value = Traits::absorbs_identities); | |
677 }; | |
678 | |
679 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc> | |
680 struct is_total<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> > | |
681 { | |
682 typedef is_total type; | |
683 BOOST_STATIC_CONSTANT(int, value = Traits::is_total); | |
684 }; | |
685 | |
686 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc> | |
687 struct type_to_string<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> > | |
688 { | |
689 static std::string apply() | |
690 { | |
691 return "map<"+ type_to_string<DomainT>::apply() + "," | |
692 + type_to_string<CodomainT>::apply() + "," | |
693 + type_to_string<Traits>::apply() +">"; | |
694 } | |
695 }; | |
696 | |
697 | |
698 | |
699 }} // namespace icl boost | |
700 | |
701 #endif // BOOST_ICL_MAP_HPP_JOFA_070519 | |
702 |