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