Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:23

0001 /*-----------------------------------------------------------------------------+
0002 Copyright (c) 2007-2011: Joachim Faulhaber
0003 +------------------------------------------------------------------------------+
0004    Distributed under the Boost Software License, Version 1.0.
0005       (See accompanying file LICENCE.txt or copy at
0006            http://www.boost.org/LICENSE_1_0.txt)
0007 +-----------------------------------------------------------------------------*/
0008 #ifndef BOOST_ICL_MAP_HPP_JOFA_070519
0009 #define BOOST_ICL_MAP_HPP_JOFA_070519
0010 
0011 #include <boost/icl/impl_config.hpp>
0012 
0013 #if defined(ICL_USE_BOOST_MOVE_IMPLEMENTATION)
0014 #   include <boost/container/map.hpp>
0015 #   include <boost/container/set.hpp>
0016 #elif defined(ICL_USE_STD_IMPLEMENTATION)
0017 #   include <map>
0018 #   include <set>
0019 #else // Default for implementing containers
0020 #   include <map>
0021 #   include <set>
0022 #endif
0023 
0024 #include <string>
0025 #include <boost/call_traits.hpp>
0026 #include <boost/icl/detail/notate.hpp>
0027 #include <boost/icl/detail/design_config.hpp>
0028 #include <boost/icl/detail/concept_check.hpp>
0029 #include <boost/icl/detail/on_absorbtion.hpp>
0030 #include <boost/icl/type_traits/is_map.hpp>
0031 #include <boost/icl/type_traits/absorbs_identities.hpp>
0032 #include <boost/icl/type_traits/is_total.hpp>
0033 #include <boost/icl/type_traits/is_element_container.hpp>
0034 #include <boost/icl/type_traits/has_inverse.hpp>
0035 
0036 #include <boost/icl/associative_element_container.hpp>
0037 #include <boost/icl/functors.hpp>
0038 #include <boost/icl/type_traits/to_string.hpp>
0039 
0040 namespace boost{namespace icl
0041 {
0042 
0043 struct partial_absorber
0044 {
0045     enum { absorbs_identities = true };
0046     enum { is_total = false };
0047 };
0048 
0049 template<>
0050 inline std::string type_to_string<partial_absorber>::apply() { return "@0"; }
0051 
0052 struct partial_enricher
0053 {
0054     enum { absorbs_identities = false };
0055     enum { is_total = false };
0056 };
0057 
0058 template<>
0059 inline std::string type_to_string<partial_enricher>::apply() { return "e0"; }
0060 
0061 struct total_absorber
0062 {
0063     enum { absorbs_identities = true };
0064     enum { is_total = true };
0065 };
0066 
0067 template<>
0068 inline std::string type_to_string<total_absorber>::apply() { return "^0"; }
0069 
0070 struct total_enricher
0071 {
0072     enum { absorbs_identities = false };
0073     enum { is_total = true };
0074 };
0075 
0076 template<>
0077 inline std::string type_to_string<total_enricher>::apply() { return "e^0"; }
0078 
0079 
0080 
0081 /** \brief Addable, subractable and intersectable maps */
0082 template
0083 <
0084     typename DomainT,
0085     typename CodomainT,
0086     class Traits = icl::partial_absorber,
0087     ICL_COMPARE Compare = ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, DomainT),
0088     ICL_COMBINE Combine = ICL_COMBINE_INSTANCE(icl::inplace_plus, CodomainT),
0089     ICL_SECTION Section = ICL_SECTION_INSTANCE(icl::inter_section, CodomainT),
0090     ICL_ALLOC   Alloc   = std::allocator
0091 >
0092 class map: private ICL_IMPL_SPACE::map<DomainT, CodomainT, ICL_COMPARE_DOMAIN(Compare,DomainT),
0093                                        Alloc<std::pair<const DomainT, CodomainT> > >
0094 {
0095 public:
0096     typedef Alloc<typename std::pair<const DomainT, CodomainT> >  allocator_type;
0097 
0098     typedef typename icl::map<DomainT,CodomainT,Traits, Compare,Combine,Section,Alloc> type;
0099     typedef typename ICL_IMPL_SPACE::map<DomainT, CodomainT, ICL_COMPARE_DOMAIN(Compare,DomainT),
0100                                          allocator_type>   base_type;
0101 
0102     typedef Traits traits;
0103 
0104 public:
0105     typedef DomainT                                     domain_type;
0106     typedef typename boost::call_traits<DomainT>::param_type domain_param;
0107     typedef DomainT                                     key_type;
0108     typedef CodomainT                                   codomain_type;
0109     typedef CodomainT                                   mapped_type;
0110     typedef CodomainT                                   data_type;
0111     typedef std::pair<const DomainT, CodomainT>         element_type;
0112     typedef std::pair<const DomainT, CodomainT>         value_type;
0113     typedef ICL_COMPARE_DOMAIN(Compare,DomainT)         domain_compare;
0114     typedef ICL_COMBINE_CODOMAIN(Combine,CodomainT)     codomain_combine;
0115     typedef domain_compare                              key_compare;
0116     typedef ICL_COMPARE_DOMAIN(Compare,element_type)    element_compare;
0117     typedef typename inverse<codomain_combine >::type   inverse_codomain_combine;
0118     typedef typename mpl::if_
0119         <has_set_semantics<codomain_type>
0120         , ICL_SECTION_CODOMAIN(Section,CodomainT)
0121         , codomain_combine
0122         >::type                                         codomain_intersect;
0123     typedef typename inverse<codomain_intersect>::type  inverse_codomain_intersect;
0124     typedef typename base_type::value_compare           value_compare;
0125 
0126     typedef typename ICL_IMPL_SPACE::set<DomainT, domain_compare, Alloc<DomainT> > set_type;
0127     typedef set_type                                       key_object_type;
0128 
0129 
0130     BOOST_STATIC_CONSTANT(bool, _total   = (Traits::is_total));
0131     BOOST_STATIC_CONSTANT(bool, _absorbs = (Traits::absorbs_identities));
0132     BOOST_STATIC_CONSTANT(bool,
0133         total_invertible = (mpl::and_<is_total<type>, has_inverse<codomain_type> >::value));
0134 
0135     typedef on_absorbtion<type,codomain_combine,Traits::absorbs_identities>
0136                                                         on_identity_absorbtion;
0137 
0138 public:
0139     typedef typename base_type::pointer                 pointer;
0140     typedef typename base_type::const_pointer           const_pointer;
0141     typedef typename base_type::reference               reference;
0142     typedef typename base_type::const_reference         const_reference;
0143     typedef typename base_type::iterator                iterator;
0144     typedef typename base_type::const_iterator          const_iterator;
0145     typedef typename base_type::size_type               size_type;
0146     typedef typename base_type::difference_type         difference_type;
0147     typedef typename base_type::reverse_iterator        reverse_iterator;
0148     typedef typename base_type::const_reverse_iterator  const_reverse_iterator;
0149 
0150 public:
0151     BOOST_STATIC_CONSTANT(bool,
0152         is_total_invertible = (   Traits::is_total
0153                                && has_inverse<codomain_type>::value));
0154 
0155     BOOST_STATIC_CONSTANT(int, fineness = 4);
0156 
0157 public:
0158     //==========================================================================
0159     //= Construct, copy, destruct
0160     //==========================================================================
0161     map()
0162     {
0163         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
0164         BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
0165         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
0166         BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
0167     }
0168 
0169     map(const key_compare& comp): base_type(comp){}
0170 
0171     template <class InputIterator>
0172     map(InputIterator first, InputIterator past)
0173         : base_type(first,past){}
0174 
0175     template <class InputIterator>
0176     map(InputIterator first, InputIterator past, const key_compare& comp)
0177         : base_type(first,past,comp)
0178     {}
0179 
0180     map(const map& src)
0181         : base_type(src)
0182     {
0183         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
0184         BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
0185         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
0186         BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
0187     }
0188 
0189     explicit map(const element_type& key_value_pair): base_type::map()
0190     {
0191         insert(key_value_pair);
0192     }
0193 
0194 #   ifndef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
0195     //==========================================================================
0196     //= Move semantics
0197     //==========================================================================
0198 
0199     map(map&& src)
0200         : base_type(boost::move(src))
0201     {
0202         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
0203         BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
0204         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
0205         BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
0206     }
0207 
0208     map& operator = (map src)
0209     {
0210         base_type::operator=(boost::move(src));
0211         return *this;
0212     }
0213     //==========================================================================
0214 #   else
0215 
0216     map& operator = (const map& src)
0217     {
0218         base_type::operator=(src);
0219         return *this;
0220     }
0221 
0222 #   endif // BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
0223 
0224     void swap(map& src) { base_type::swap(src); }
0225 
0226     //==========================================================================
0227     using base_type::empty;
0228     using base_type::clear;
0229 
0230     using base_type::begin;
0231     using base_type::end;
0232     using base_type::rbegin;
0233     using base_type::rend;
0234 
0235     using base_type::size;
0236     using base_type::max_size;
0237 
0238     using base_type::key_comp;
0239     using base_type::value_comp;
0240 
0241     using base_type::erase;
0242     using base_type::find;
0243     using base_type::count;
0244 
0245     using base_type::lower_bound;
0246     using base_type::upper_bound;
0247     using base_type::equal_range;
0248 
0249     using base_type::operator[];
0250 
0251 public:
0252     //==========================================================================
0253     //= Containedness
0254     //==========================================================================
0255 
0256     template<class SubObject>
0257     bool contains(const SubObject& sub)const
0258     { return icl::contains(*this, sub); }
0259 
0260     bool within(const map& super)const
0261     { return icl::contains(super, *this); }
0262 
0263     //==========================================================================
0264     //= Size
0265     //==========================================================================
0266     /** \c iterative_size() yields the number of elements that is visited
0267         throu complete iteration. For interval sets \c iterative_size() is
0268         different from \c size(). */
0269     std::size_t iterative_size()const { return base_type::size(); }
0270 
0271     //==========================================================================
0272     //= Selection
0273     //==========================================================================
0274 
0275     /** Total select function. */
0276     codomain_type operator()(const domain_type& key)const
0277     {
0278         const_iterator it = find(key);
0279         return it==end() ? identity_element<codomain_type>::value()
0280                          : it->second;
0281     }
0282 
0283     //==========================================================================
0284     //= Addition
0285     //==========================================================================
0286     /** \c add inserts \c value_pair into the map if it's key does
0287         not exist in the map.
0288         If \c value_pairs's key value exists in the map, it's data
0289         value is added to the data value already found in the map. */
0290     map& add(const value_type& value_pair)
0291     {
0292         return _add<codomain_combine>(value_pair);
0293     }
0294 
0295     /** \c add add \c value_pair into the map using \c prior as a hint to
0296         insert \c value_pair after the position \c prior is pointing to. */
0297     iterator add(iterator prior, const value_type& value_pair)
0298     {
0299         return _add<codomain_combine>(prior, value_pair);
0300     }
0301 
0302     //==========================================================================
0303     //= Subtraction
0304     //==========================================================================
0305     /** If the \c value_pair's key value is in the map, it's data value is
0306         subtraced from the data value stored in the map. */
0307     map& subtract(const element_type& value_pair)
0308     {
0309         on_invertible<type, is_total_invertible>
0310             ::subtract(*this, value_pair);
0311         return *this;
0312     }
0313 
0314     map& subtract(const domain_type& key)
0315     {
0316         icl::erase(*this, key);
0317         return *this;
0318     }
0319 
0320     //==========================================================================
0321     //= Insertion, erasure
0322     //==========================================================================
0323     std::pair<iterator,bool> insert(const value_type& value_pair)
0324     {
0325         if(on_identity_absorbtion::is_absorbable(value_pair.second))
0326             return std::pair<iterator,bool>(end(),true);
0327         else
0328             return base_type::insert(value_pair);
0329     }
0330 
0331     iterator insert(iterator prior, const value_type& value_pair)
0332     {
0333         if(on_identity_absorbtion::is_absorbable(value_pair.second))
0334             return end();
0335         else
0336             return base_type::insert(prior, value_pair);
0337     }
0338 
0339     template<class Iterator>
0340     iterator insert(Iterator first, Iterator last)
0341     {
0342         iterator prior = end(), it = first;
0343         while(it != last)
0344             prior = this->insert(prior, *it++);
0345     }
0346 
0347     /** With <tt>key_value_pair = (k,v)</tt> set value \c v for key \c k */
0348     map& set(const element_type& key_value_pair)
0349     {
0350         return icl::set_at(*this, key_value_pair);
0351     }
0352 
0353     /** erase \c key_value_pair from the map.
0354         Erase only if, the exact value content \c val is stored for the given key. */
0355     size_type erase(const element_type& key_value_pair)
0356     {
0357         return icl::erase(*this, key_value_pair);
0358     }
0359 
0360     //==========================================================================
0361     //= Intersection
0362     //==========================================================================
0363     /** The intersection of \c key_value_pair and \c *this map is added to \c section. */
0364     void add_intersection(map& section, const element_type& key_value_pair)const
0365     {
0366         on_definedness<type, Traits::is_total>
0367             ::add_intersection(section, *this, key_value_pair);
0368     }
0369 
0370     //==========================================================================
0371     //= Symmetric difference
0372     //==========================================================================
0373 
0374     map& flip(const element_type& operand)
0375     {
0376         on_total_absorbable<type,_total,_absorbs>::flip(*this, operand);
0377         return *this;
0378     }
0379 
0380 private:
0381     template<class Combiner>
0382     map& _add(const element_type& value_pair);
0383 
0384     template<class Combiner>
0385     iterator _add(iterator prior, const element_type& value_pair);
0386 
0387     template<class Combiner>
0388     map& _subtract(const element_type& value_pair);
0389 
0390     template<class FragmentT>
0391     void total_add_intersection(type& section, const FragmentT& fragment)const
0392     {
0393         section += *this;
0394         section.add(fragment);
0395     }
0396 
0397     void partial_add_intersection(type& section, const element_type& operand)const
0398     {
0399         const_iterator it_ = find(operand.first);
0400         if(it_ != end())
0401         {
0402             section.template _add<codomain_combine  >(*it_);
0403             section.template _add<codomain_intersect>(operand);
0404         }
0405     }
0406 
0407 
0408 private:
0409     //--------------------------------------------------------------------------
0410     template<class Type, bool is_total_invertible>
0411     struct on_invertible;
0412 
0413     template<class Type>
0414     struct on_invertible<Type, true>
0415     {
0416         typedef typename Type::element_type element_type;
0417         typedef typename Type::inverse_codomain_combine inverse_codomain_combine;
0418 
0419         static void subtract(Type& object, const element_type& operand)
0420         { object.template _add<inverse_codomain_combine>(operand); }
0421     };
0422 
0423     template<class Type>
0424     struct on_invertible<Type, false>
0425     {
0426         typedef typename Type::element_type element_type;
0427         typedef typename Type::inverse_codomain_combine inverse_codomain_combine;
0428 
0429         static void subtract(Type& object, const element_type& operand)
0430         { object.template _subtract<inverse_codomain_combine>(operand); }
0431     };
0432 
0433     friend struct on_invertible<type, true>;
0434     friend struct on_invertible<type, false>;
0435     //--------------------------------------------------------------------------
0436 
0437     //--------------------------------------------------------------------------
0438     template<class Type, bool is_total>
0439     struct on_definedness;
0440 
0441     template<class Type>
0442     struct on_definedness<Type, true>
0443     {
0444         static void add_intersection(Type& section, const Type& object,
0445                                      const element_type& operand)
0446         { object.total_add_intersection(section, operand); }
0447     };
0448 
0449     template<class Type>
0450     struct on_definedness<Type, false>
0451     {
0452         static void add_intersection(Type& section, const Type& object,
0453                                      const element_type& operand)
0454         { object.partial_add_intersection(section, operand); }
0455     };
0456 
0457     friend struct on_definedness<type, true>;
0458     friend struct on_definedness<type, false>;
0459     //--------------------------------------------------------------------------
0460 
0461     //--------------------------------------------------------------------------
0462     template<class Type, bool has_set_semantics, bool absorbs_identities>
0463     struct on_codomain_model;
0464 
0465     template<class Type>
0466     struct on_codomain_model<Type, false, false>
0467     {                // !codomain_is_set, !absorbs_identities
0468         static void subtract(Type&, typename Type::iterator it_,
0469                               const typename Type::codomain_type& )
0470         { (*it_).second = identity_element<typename Type::codomain_type>::value(); }
0471     };
0472 
0473     template<class Type>
0474     struct on_codomain_model<Type, false, true>
0475     {                // !codomain_is_set, absorbs_identities
0476         static void subtract(Type& object, typename Type::iterator       it_,
0477                                      const typename Type::codomain_type&     )
0478         { object.erase(it_); }
0479     };
0480 
0481     template<class Type>
0482     struct on_codomain_model<Type, true, false>
0483     {               // !codomain_is_set, !absorbs_identities
0484         typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;
0485         static void subtract(Type&, typename Type::iterator       it_,
0486                               const typename Type::codomain_type& co_value)
0487         {
0488             inverse_codomain_intersect()((*it_).second, co_value);
0489         }
0490     };
0491 
0492     template<class Type>
0493     struct on_codomain_model<Type, true, true>
0494     {               // !codomain_is_set, absorbs_identities
0495         typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;
0496         static void subtract(Type& object, typename Type::iterator       it_,
0497                                      const typename Type::codomain_type& co_value)
0498         {
0499             inverse_codomain_intersect()((*it_).second, co_value);
0500             if((*it_).second == identity_element<codomain_type>::value())
0501                 object.erase(it_);
0502         }
0503     };
0504     //--------------------------------------------------------------------------
0505 
0506     //--------------------------------------------------------------------------
0507     template<class Type, bool is_total, bool absorbs_identities>
0508     struct on_total_absorbable;
0509 
0510     template<class Type>
0511     struct on_total_absorbable<Type, true, true>
0512     {
0513         typedef typename Type::element_type  element_type;
0514         static void flip(Type& object, const typename Type::element_type&)
0515         { icl::clear(object); }
0516     };
0517 
0518     template<class Type>
0519     struct on_total_absorbable<Type, true, false>
0520     {
0521         typedef typename Type::element_type  element_type;
0522         typedef typename Type::codomain_type codomain_type;
0523 
0524         static void flip(Type& object, const element_type& operand)
0525         {
0526             object.add(operand);
0527             ICL_FORALL(typename Type, it_, object)
0528                 (*it_).second = identity_element<codomain_type>::value();
0529         }
0530     };
0531 
0532     template<class Type>
0533     struct on_total_absorbable<Type, false, true>
0534     {                         // !is_total, absorbs_identities
0535         typedef typename Type::element_type   element_type;
0536         typedef typename Type::codomain_type  codomain_type;
0537         typedef typename Type::iterator       iterator;
0538         typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;
0539 
0540         static void flip(Type& object, const element_type& operand)
0541         {
0542             std::pair<iterator,bool> insertion = object.insert(operand);
0543             if(!insertion.second)
0544                 on_codomain_model<Type, has_set_semantics<codomain_type>::value, true>
0545                 ::subtract(object, insertion.first, operand.second);
0546         }
0547     };
0548 
0549     template<class Type>
0550     struct on_total_absorbable<Type, false, false>
0551     {                         // !is_total  !absorbs_identities
0552         typedef typename Type::element_type   element_type;
0553         typedef typename Type::codomain_type  codomain_type;
0554         typedef typename Type::iterator       iterator;
0555         typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;
0556 
0557         static void flip(Type& object, const element_type& operand)
0558         {
0559             std::pair<iterator,bool> insertion = object.insert(operand);
0560             if(!insertion.second)
0561                 on_codomain_model<Type, has_set_semantics<codomain_type>::value, false>
0562                 ::subtract(object, insertion.first, operand.second);
0563         }
0564     };
0565 
0566     friend struct on_total_absorbable<type, true,  true >;
0567     friend struct on_total_absorbable<type, false, true >;
0568     friend struct on_total_absorbable<type, true,  false>;
0569     friend struct on_total_absorbable<type, false, false>;
0570     //--------------------------------------------------------------------------
0571 };
0572 
0573 
0574 
0575 //==============================================================================
0576 //= Addition<ElementMap>
0577 //==============================================================================
0578 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc>
0579     template <class Combiner>
0580 map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>&
0581     map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>
0582     ::_add(const element_type& addend)
0583 {
0584     typedef typename on_absorbtion
0585         <type,Combiner,absorbs_identities<type>::value>::type on_absorbtion_;
0586 
0587     const codomain_type& co_val    = addend.second;
0588     if(on_absorbtion_::is_absorbable(co_val))
0589         return *this;
0590 
0591     std::pair<iterator,bool> insertion
0592         = base_type::insert(value_type(addend.first, version<Combiner>()(co_val)));
0593 
0594     if(!insertion.second)
0595     {
0596         iterator it = insertion.first;
0597         Combiner()((*it).second, co_val);
0598 
0599         if(on_absorbtion_::is_absorbable((*it).second))
0600             erase(it);
0601     }
0602     return *this;
0603 }
0604 
0605 
0606 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc>
0607     template <class Combiner>
0608 typename map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>::iterator
0609     map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>
0610     ::_add(iterator prior_, const value_type& addend)
0611 {
0612     typedef typename on_absorbtion
0613         <type,Combiner,absorbs_identities<type>::value>::type on_absorbtion_;
0614 
0615     const codomain_type& co_val    = addend.second;
0616     if(on_absorbtion_::is_absorbable(co_val))
0617         return end();
0618 
0619     iterator inserted_
0620         = base_type::insert(prior_,
0621                             value_type(addend.first, Combiner::identity_element()));
0622     Combiner()((*inserted_).second, addend.second);
0623 
0624     if(on_absorbtion_::is_absorbable((*inserted_).second))
0625     {
0626         erase(inserted_);
0627         return end();
0628     }
0629     else
0630         return inserted_;
0631 }
0632 
0633 
0634 //==============================================================================
0635 //= Subtraction<ElementMap>
0636 //==============================================================================
0637 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc>
0638     template <class Combiner>
0639 map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>&
0640     map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc>::_subtract(const value_type& minuend)
0641 {
0642     typedef typename on_absorbtion
0643         <type,Combiner,absorbs_identities<type>::value>::type on_absorbtion_;
0644 
0645     iterator it_ = find(minuend.first);
0646     if(it_ != end())
0647     {
0648         Combiner()((*it_).second, minuend.second);
0649         if(on_absorbtion_::is_absorbable((*it_).second))
0650             erase(it_);
0651     }
0652     return *this;
0653 }
0654 
0655 
0656 //-----------------------------------------------------------------------------
0657 // type traits
0658 //-----------------------------------------------------------------------------
0659 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc>
0660 struct is_map<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> >
0661 {
0662     typedef is_map<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> > type;
0663     BOOST_STATIC_CONSTANT(bool, value = true);
0664 };
0665 
0666 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc>
0667 struct has_inverse<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> >
0668 {
0669     typedef has_inverse<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> > type;
0670     BOOST_STATIC_CONSTANT(bool, value = (has_inverse<CodomainT>::value));
0671 };
0672 
0673 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc>
0674 struct absorbs_identities<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> >
0675 {
0676     typedef absorbs_identities type;
0677     BOOST_STATIC_CONSTANT(int, value = Traits::absorbs_identities);
0678 };
0679 
0680 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc>
0681 struct is_total<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> >
0682 {
0683     typedef is_total type;
0684     BOOST_STATIC_CONSTANT(int, value = Traits::is_total);
0685 };
0686 
0687 template <class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_ALLOC Alloc>
0688 struct type_to_string<icl::map<DomainT,CodomainT,Traits,Compare,Combine,Section,Alloc> >
0689 {
0690     static std::string apply()
0691     {
0692         return "map<"+ type_to_string<DomainT>::apply()  + ","
0693                      + type_to_string<CodomainT>::apply() + ","
0694                      + type_to_string<Traits>::apply() +">";
0695     }
0696 };
0697 
0698 
0699 
0700 }} // namespace icl boost
0701 
0702 #endif // BOOST_ICL_MAP_HPP_JOFA_070519