text:
#ifndef BOOST_ICL_INTERVAL_BASE_MAP_HPP_JOFA_990223
#define BOOST_ICL_INTERVAL_BASE_MAP_HPP_JOFA_990223

#include <limits>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>

#include <boost/icl/detail/notate.hpp>
#include <boost/icl/detail/design_config.hpp>
#include <boost/icl/detail/on_absorbtion.hpp>
#include <boost/icl/detail/interval_map_algo.hpp>

#include <boost/icl/associative_interval_container.hpp>

#include <boost/icl/type_traits/is_interval_splitter.hpp>
#include <boost/icl/map.hpp>

namespace boost{namespace icl
{

template<class DomainT, class CodomainT>
struct mapping_pair
{
    DomainT   key;
    CodomainT data;

    mapping_pair():key(), data(){}

    mapping_pair(const DomainT& key_value, const CodomainT& data_value)
        :key(key_value), data(data_value){}

    mapping_pair(const std::pair<DomainT,CodomainT>& std_pair)
        :key(std_pair.first), data(std_pair.second){}
};

/** \brief Implements a map as a map of intervals (base class) */
template
<
    class SubType,
    typename DomainT,
    typename CodomainT,
    class Traits = icl::partial_absorber,
    ICL_COMPARE Compare  = ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, DomainT),
    ICL_COMBINE Combine  = ICL_COMBINE_INSTANCE(icl::inplace_plus, CodomainT),
    ICL_SECTION Section  = ICL_SECTION_INSTANCE(icl::inter_section, CodomainT),
    ICL_INTERVAL(ICL_COMPARE) Interval = ICL_INTERVAL_INSTANCE(ICL_INTERVAL_DEFAULT, DomainT, Compare),
    ICL_ALLOC   Alloc    = std::allocator
>
class interval_base_map
{
public:
    //==========================================================================
    //= Associated types
    //==========================================================================
    typedef interval_base_map<SubType,DomainT,CodomainT,
                              Traits,Compare,Combine,Section,Interval,Alloc>
                              type;

    /// The designated \e derived or \e sub_type of this base class
    typedef SubType sub_type;

    /// Auxilliary type for overloadresolution
    typedef type overloadable_type;

    /// Traits of an itl map
    typedef Traits traits;

    //--------------------------------------------------------------------------
    //- Associated types: Related types
    //--------------------------------------------------------------------------
    /// The atomized type representing the corresponding container of elements
    typedef typename icl::map<DomainT,CodomainT,
                              Traits,Compare,Combine,Section,Alloc> atomized_type;

    //--------------------------------------------------------------------------
    //- Associated types: Data
    //--------------------------------------------------------------------------
    /// Domain type (type of the keys) of the map
    typedef DomainT   domain_type;
    typedef typename boost::call_traits<DomainT>::param_type domain_param;
    /// Domain type (type of the keys) of the map
    typedef CodomainT codomain_type;
    /// Auxiliary type to help the compiler resolve ambiguities when using std::make_pair
    typedef mapping_pair<domain_type,codomain_type> domain_mapping_type;
    /// Conceptual is a map a set of elements of type \c element_type
    typedef domain_mapping_type element_type;
    /// The interval type of the map
    typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
    /// Auxiliary type for overload resolution
    typedef std::pair<interval_type,CodomainT> interval_mapping_type;
    /// Type of an interval containers segment, that is spanned by an interval
    typedef std::pair<interval_type,CodomainT> segment_type;

    //--------------------------------------------------------------------------
    //- Associated types: Size
    //--------------------------------------------------------------------------
    /// The difference type of an interval which is sometimes different form the domain_type
    typedef typename difference_type_of<domain_type>::type difference_type;
    /// The size type of an interval which is mostly std::size_t
    typedef typename size_type_of<domain_type>::type size_type;

    //--------------------------------------------------------------------------
    //- Associated types: Functors
    //--------------------------------------------------------------------------
    /// Comparison functor for domain values
    typedef ICL_COMPARE_DOMAIN(Compare,DomainT)      domain_compare;
    typedef ICL_COMPARE_DOMAIN(Compare,segment_type) segment_compare;
    /// Combine functor for codomain value aggregation
    typedef ICL_COMBINE_CODOMAIN(Combine,CodomainT)  codomain_combine;
    /// Inverse Combine functor for codomain value aggregation
    typedef typename inverse<codomain_combine>::type inverse_codomain_combine;
    /// Intersection functor for codomain values

    typedef typename mpl::if_
    <has_set_semantics<codomain_type>
    , ICL_SECTION_CODOMAIN(Section,CodomainT)
    , codomain_combine
    >::type                                            codomain_intersect;

    /// Inverse Combine functor for codomain value intersection
    typedef typename inverse<codomain_intersect>::type inverse_codomain_intersect;

    /// Comparison functor for intervals which are keys as well
    typedef exclusive_less_than<interval_type> interval_compare;

    /// Comparison functor for keys
    typedef exclusive_less_than<interval_type> key_compare;

    //--------------------------------------------------------------------------
    //- Associated types: Implementation and stl related
    //--------------------------------------------------------------------------
    /// The allocator type of the set
    typedef Alloc<std::pair<const interval_type, codomain_type> >
        allocator_type;

    /// Container type for the implementation
    typedef ICL_IMPL_SPACE::map<interval_type,codomain_type,
                                key_compare,allocator_type> ImplMapT;

    /// key type of the implementing container
    typedef typename ImplMapT::key_type   key_type;
    /// value type of the implementing container
    typedef typename ImplMapT::value_type value_type;
    /// data type of the implementing container
    typedef typename ImplMapT::value_type::second_type data_type;

    /// pointer type
    typedef typename ImplMapT::pointer         pointer;
    /// const pointer type
    typedef typename ImplMapT::const_pointer   const_pointer;
    /// reference type
    typedef typename ImplMapT::reference       reference;
    /// const reference type
    typedef typename ImplMapT::const_reference const_reference;

    /// iterator for iteration over intervals
    typedef typename ImplMapT::iterator iterator;
    /// const_iterator for iteration over intervals
    typedef typename ImplMapT::const_iterator const_iterator;
    /// iterator for reverse iteration over intervals
    typedef typename ImplMapT::reverse_iterator reverse_iterator;
    /// const_iterator for iteration over intervals
    typedef typename ImplMapT::const_reverse_iterator const_reverse_iterator;

    /// element iterator: Depreciated, see documentation.
    typedef boost::icl::element_iterator<iterator> element_iterator;
    /// const element iterator: Depreciated, see documentation.
    typedef boost::icl::element_iterator<const_iterator> element_const_iterator;
    /// element reverse iterator: Depreciated, see documentation.
    typedef boost::icl::element_iterator<reverse_iterator> element_reverse_iterator;
    /// element const reverse iterator: Depreciated, see documentation.
    typedef boost::icl::element_iterator<const_reverse_iterator> element_const_reverse_iterator;

    typedef typename on_absorbtion<type, codomain_combine,
                                Traits::absorbs_identities>::type on_codomain_absorbtion;

public:
    BOOST_STATIC_CONSTANT(bool,
        is_total_invertible = (   Traits::is_total
                               && has_inverse<codomain_type>::value));

    BOOST_STATIC_CONSTANT(int, fineness = 0);

public:

    //==========================================================================
    //= Construct, copy, destruct
    //==========================================================================
    /** Default constructor for the empty object */
    interval_base_map()
    {
        BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
        BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
        BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
        BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
    }

    /** Copy constructor */
    interval_base_map(const interval_base_map& src): _map(src._map)
    {
        BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
        BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
        BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
        BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
    }

#   ifndef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
    //==========================================================================
    //= Move semantics
    //==========================================================================

    /** Move constructor */
    interval_base_map(interval_base_map&& src): _map(boost::move(src._map))
    {
        BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
        BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
        BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
        BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
    }

    /** Move assignment operator */
    interval_base_map& operator = (interval_base_map src)
    {                           //call by value sice 'src' is a "sink value"
        this->_map = boost::move(src._map);
        return *this;
    }

    //==========================================================================
#   else

    /** Copy assignment operator */
    interval_base_map& operator = (const interval_base_map& src)
    {
        this->_map = src._map;
        return *this;
    }

#   endif // BOOST_ICL_NO_CXX11_RVALUE_REFERENCES

    /** swap the content of containers */
    void swap(interval_base_map& object) { _map.swap(object._map); }

    //==========================================================================
    //= Containedness
    //==========================================================================
    /** clear the map */
    void clear() { icl::clear(*that()); }

    /** is the map empty? */
    bool empty()const { return icl::is_empty(*that()); }

    //==========================================================================
    //= Size
    //==========================================================================
    /** An interval map's size is it's cardinality */
    size_type size()const
    {
        return icl::cardinality(*that());
    }

    /** Size of the iteration over this container */
    std::size_t iterative_size()const
    {
        return _map.size();
    }

    //==========================================================================
    //= Selection
    //==========================================================================

    /** Find the interval value pair, that contains \c key */
    const_iterator find(const domain_type& key_value)const
    {
        return icl::find(*this, key_value);
    }

    /** Find the first interval value pair, that collides with interval
        \c key_interval */
    const_iterator find(const interval_type& key_interval)const
    {
        return _map.find(key_interval);
    }

    /** Total select function. */
    codomain_type operator()(const domain_type& key_value)const
    {
        const_iterator it_ = icl::find(*this, key_value);
        return it_==end() ? identity_element<codomain_type>::value()
                          : (*it_).second;
    }

    //==========================================================================
    //= Addition
    //==========================================================================

    /** Addition of a key value pair to the map */
    SubType& add(const element_type& key_value_pair)
    {
        return icl::add(*that(), key_value_pair);
    }

    /** Addition of an interval value pair to the map. */
    SubType& add(const segment_type& interval_value_pair)
    {
        this->template _add<codomain_combine>(interval_value_pair);
        return *that();
    }

    /** Addition of an interval value pair \c interval_value_pair to the map.
        Iterator \c prior_ is a hint to the position \c interval_value_pair can be
        inserted after. */
    iterator add(iterator prior_, const segment_type& interval_value_pair)
    {
        return this->template _add<codomain_combine>(prior_, interval_value_pair);
    }

    //==========================================================================
    //= Subtraction
    //==========================================================================
    /** Subtraction of a key value pair from the map */
    SubType& subtract(const element_type& key_value_pair)
    {
        return icl::subtract(*that(), key_value_pair);
    }

    /** Subtraction of an interval value pair from the map. */
    SubType& subtract(const segment_type& interval_value_pair)
    {
        on_invertible<type, is_total_invertible>
            ::subtract(*that(), interval_value_pair);
        return *that();
    }

    //==========================================================================
    //= Insertion
    //==========================================================================
    /** Insertion of a \c key_value_pair into the map. */
    SubType& insert(const element_type& key_value_pair)
    {
        return icl::insert(*that(), key_value_pair);
    }

    /** Insertion of an \c interval_value_pair into the map. */
    SubType& insert(const segment_type& interval_value_pair)
    {
        _insert(interval_value_pair);
        return *that();
    }

    /** Insertion of an \c interval_value_pair into the map. Iterator \c prior_.
        serves as a hint to insert after the element \c prior point to. */
    iterator insert(iterator prior, const segment_type& interval_value_pair)
    {
        return _insert(prior, interval_value_pair);
    }

    /** With <tt>key_value_pair = (k,v)</tt> set value \c v for key \c k */
    SubType& set(const element_type& key_value_pair)
    {
        return icl::set_at(*that(), key_value_pair);
    }

    /** With <tt>interval_value_pair = (I,v)</tt> set value \c v
        for all keys in interval \c I in the map. */
    SubType& set(const segment_type& interval_value_pair)
    {
        return icl::set_at(*that(), interval_value_pair);
    }

    //==========================================================================
    //= Erasure
    //==========================================================================
    /** Erase a \c key_value_pair from the map. */
    SubType& erase(const element_type& key_value_pair)
    {
        icl::erase(*that(), key_value_pair);
        return *that();
    }

    /** Erase an \c interval_value_pair from the map. */
    SubType& erase(const segment_type& interval_value_pair);

    /** Erase a key value pair for \c key. */
    SubType& erase(const domain_type& key)
    {
        return icl::erase(*that(), key);
    }

    /** Erase all value pairs within the range of the
        interval <tt>inter_val</tt> from the map.   */
    SubType& erase(const interval_type& inter_val);

    /** Erase all value pairs within the range of the interval that iterator
        \c position points to. */
    void erase(iterator position){ this->_map.erase(position); }

    /** Erase all value pairs for a range of iterators <tt>[first,past)</tt>. */
    void erase(iterator first, iterator past){ this->_map.erase(first, past); }

    //==========================================================================
    //= Intersection
    //==========================================================================
    /** The intersection of \c interval_value_pair and \c *this map is added to \c section. */
    void add_intersection(SubType& section, const segment_type& interval_value_pair)const
    {
        on_definedness<SubType, Traits::is_total>
            ::add_intersection(section, *that(), interval_value_pair);
    }

    //==========================================================================
    //= Symmetric difference
    //==========================================================================
    /** If \c *this map contains \c key_value_pair it is erased, otherwise it is added. */
    SubType& flip(const element_type& key_value_pair)
    {
        return icl::flip(*that(), key_value_pair);
    }

    /** If \c *this map contains \c interval_value_pair it is erased, otherwise it is added. */
    SubType& flip(const segment_type& interval_value_pair)
    {
        on_total_absorbable<SubType, Traits::is_total, Traits::absorbs_identities>
            ::flip(*that(), interval_value_pair);
        return *that();
    }

    //==========================================================================
    //= Iterator related
    //==========================================================================

    iterator lower_bound(const key_type& interval)
    { return _map.lower_bound(interval); }

    iterator upper_bound(const key_type& interval)
    { return _map.upper_bound(interval); }

    const_iterator lower_bound(const key_type& interval)const
    { return _map.lower_bound(interval); }

    const_iterator upper_bound(const key_type& interval)const
    { return _map.upper_bound(interval); }

    std::pair<iterator,iterator> equal_range(const key_type& interval)
    {
        return std::pair<iterator,iterator>
               (lower_bound(interval), upper_bound(interval));
    }

    std::pair<const_iterator,const_iterator>
        equal_range(const key_type& interval)const
    {
        return std::pair<const_iterator,const_iterator>
               (lower_bound(interval), upper_bound(interval));
    }

    iterator begin() { return _map.begin(); }
    iterator end()   { return _map.end(); }
    const_iterator begin()const { return _map.begin(); }
    const_iterator end()const   { return _map.end(); }
    reverse_iterator rbegin() { return _map.rbegin(); }
    reverse_iterator rend()   { return _map.rend(); }
    const_reverse_iterator rbegin()const { return _map.rbegin(); }
    const_reverse_iterator rend()const   { return _map.rend(); }

private:
    template<class Combiner>
    iterator _add(const segment_type& interval_value_pair);

    template<class Combiner>
    iterator _add(iterator prior_, const segment_type& interval_value_pair);

    template<class Combiner>
    void _subtract(const segment_type& interval_value_pair);

    iterator _insert(const segment_type& interval_value_pair);
    iterator _insert(iterator prior_, const segment_type& interval_value_pair);

private:
    template<class Combiner>
    void add_segment(const interval_type& inter_val, const CodomainT& co_val, iterator& it_);

    template<class Combiner>
    void add_main(interval_type& inter_val, const CodomainT& co_val,
                  iterator& it_, const iterator& last_);

    template<class Combiner>
    void add_rear(const interval_type& inter_val, const CodomainT& co_val, iterator& it_);

    void add_front(const interval_type& inter_val, iterator& first_);

private:
    void subtract_front(const interval_type& inter_val, iterator& first_);

    template<class Combiner>
    void subtract_main(const CodomainT& co_val, iterator& it_, const iterator& last_);

    template<class Combiner>
    void subtract_rear(interval_type& inter_val, const CodomainT& co_val, iterator& it_);

private:
    void insert_main(const interval_type&, const CodomainT&, iterator&, const iterator&);
    void erase_rest (      interval_type&, const CodomainT&, iterator&, const iterator&);

    template<class FragmentT>
    void total_add_intersection(SubType& section, const FragmentT& fragment)const
    {
        section += *that();
        section.add(fragment);
    }

    void partial_add_intersection(SubType& section, const segment_type& operand)const
    {
        interval_type inter_val = operand.first;
        if(icl::is_empty(inter_val))
            return;

        std::pair<const_iterator, const_iterator> exterior = equal_range(inter_val);
        if(exterior.first == exterior.second)
            return;

        for(const_iterator it_=exterior.first; it_ != exterior.second; it_++)
        {
            interval_type common_interval = (*it_).first & inter_val;
            if(!icl::is_empty(common_interval))
            {
                section.template _add<codomain_combine>  (value_type(common_interval, (*it_).second) );
                section.template _add<codomain_intersect>(value_type(common_interval, operand.second));
            }
        }
    }

    void partial_add_intersection(SubType& section, const element_type& operand)const
    {
        partial_add_intersection(section, make_segment<type>(operand));
    }

protected:

    template <class Combiner>
    iterator gap_insert(iterator prior_, const interval_type& inter_val,
                                         const codomain_type& co_val   )
    {
        // inter_val is not conained in this map. Insertion will be successful
        BOOST_ASSERT(this->_map.find(inter_val) == this->_map.end());
        BOOST_ASSERT((!on_absorbtion<type,Combiner,Traits::absorbs_identities>::is_absorbable(co_val)));
        return this->_map.insert(prior_, value_type(inter_val, version<Combiner>()(co_val)));
    }

    template <class Combiner>
    std::pair<iterator, bool>
    add_at(const iterator& prior_, const interval_type& inter_val,
                                   const codomain_type& co_val   )
    {
        // Never try to insert an identity element into an identity element absorber here:
        BOOST_ASSERT((!(on_absorbtion<type,Combiner,Traits::absorbs_identities>::is_absorbable(co_val))));

        iterator inserted_
            = this->_map.insert(prior_, value_type(inter_val, Combiner::identity_element()));

        if((*inserted_).first == inter_val && (*inserted_).second == Combiner::identity_element())
        {
            Combiner()((*inserted_).second, co_val);
            return std::pair<iterator,bool>(inserted_, true);
        }
        else
            return std::pair<iterator,bool>(inserted_, false);
    }

    std::pair<iterator, bool>
    insert_at(const iterator& prior_, const interval_type& inter_val,
                                      const codomain_type& co_val   )
    {
        iterator inserted_
            = this->_map.insert(prior_, value_type(inter_val, co_val));

        if(inserted_ == prior_)
            return std::pair<iterator,bool>(inserted_, false);
        else if((*inserted_).first == inter_val)
            return std::pair<iterator,bool>(inserted_, true);
        else
            return std::pair<iterator,bool>(inserted_, false);
    }

protected:
    sub_type* that() { return static_cast<sub_type*>(this); }
    const sub_type* that()const { return static_cast<const sub_type*>(this); }

protected:
    ImplMapT _map;

private:
    //--------------------------------------------------------------------------
    template<class Type, bool is_total_invertible>
    struct on_invertible;

    template<class Type>
    struct on_invertible<Type, true>
    {
        typedef typename Type::segment_type segment_type;
        typedef typename Type::inverse_codomain_combine inverse_codomain_combine;

        static void subtract(Type& object, const segment_type& operand)
        { object.template _add<inverse_codomain_combine>(operand); }
    };

    template<class Type>
    struct on_invertible<Type, false>
    {
        typedef typename Type::segment_type segment_type;
        typedef typename Type::inverse_codomain_combine inverse_codomain_combine;

        static void subtract(Type& object, const segment_type& operand)
        { object.template _subtract<inverse_codomain_combine>(operand); }
    };

    friend struct on_invertible<type, true>;
    friend struct on_invertible<type, false>;
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    template<class Type, bool is_total>
    struct on_definedness;

    template<class Type>
    struct on_definedness<Type, true>
    {
        static void add_intersection(Type& section, const Type& object,
                                     const segment_type& operand)
        { object.total_add_intersection(section, operand); }
    };

    template<class Type>
    struct on_definedness<Type, false>
    {
        static void add_intersection(Type& section, const Type& object,
                                     const segment_type& operand)
        { object.partial_add_intersection(section, operand); }
    };

    friend struct on_definedness<type, true>;
    friend struct on_definedness<type, false>;
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    template<class Type, bool has_set_semantics>
    struct on_codomain_model;

    template<class Type>
    struct on_codomain_model<Type, true>
    {
        typedef typename Type::interval_type interval_type;
        typedef typename Type::codomain_type codomain_type;
        typedef typename Type::segment_type  segment_type;
        typedef typename Type::codomain_combine codomain_combine;
        typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;

        static void add(Type& intersection, interval_type& common_interval,
                        const codomain_type& flip_value, const codomain_type& co_value)
        {
            codomain_type common_value = flip_value;
            inverse_codomain_intersect()(common_value, co_value);
            intersection.template
                _add<codomain_combine>(segment_type(common_interval, common_value));
        }
    };

    template<class Type>
    struct on_codomain_model<Type, false>
    {
        typedef typename Type::interval_type interval_type;
        typedef typename Type::codomain_type codomain_type;
        typedef typename Type::segment_type  segment_type;
        typedef typename Type::codomain_combine codomain_combine;

        static void add(Type& intersection, interval_type& common_interval,
                        const codomain_type&, const codomain_type&)
        {
            intersection.template
              _add<codomain_combine>(segment_type(common_interval,
                                                  identity_element<codomain_type>::value()));
        }
    };

    friend struct on_codomain_model<type, true>;
    friend struct on_codomain_model<type, false>;
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    template<class Type, bool is_total, bool absorbs_identities>
    struct on_total_absorbable;

    template<class Type>
    struct on_total_absorbable<Type, true, true>
    {
        static void flip(Type& object, const typename Type::segment_type&)
        { icl::clear(object); }
    };

#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant
#endif

    template<class Type>
    struct on_total_absorbable<Type, true, false>
    {
        typedef typename Type::segment_type  segment_type;
        typedef typename Type::codomain_type codomain_type;

        static void flip(Type& object, const segment_type& operand)
        {
            object += operand;
            ICL_FORALL(typename Type, it_, object)
                (*it_).second = identity_element<codomain_type>::value();

            if(mpl::not_<is_interval_splitter<Type> >::value)
                icl::join(object);
        }
    };

#ifdef BOOST_MSVC
#pragma warning(pop)
#endif

    template<class Type, bool absorbs_identities>
    struct on_total_absorbable<Type, false, absorbs_identities>
    {
        typedef typename Type::segment_type   segment_type;
        typedef typename Type::codomain_type  codomain_type;
        typedef typename Type::interval_type  interval_type;
        typedef typename Type::value_type     value_type;
        typedef typename Type::const_iterator const_iterator;
        typedef typename Type::set_type       set_type;
        typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;

        static void flip(Type& object, const segment_type& interval_value_pair)
        {
            // That which is common shall be subtracted
            // That which is not shall be added
            // So interval_value_pair has to be 'complementary added' or flipped
            interval_type span = interval_value_pair.first;
            std::pair<const_iterator, const_iterator> exterior
                = object.equal_range(span);

            const_iterator first_ = exterior.first;
            const_iterator end_   = exterior.second;

            interval_type covered, left_over, common_interval;
            const codomain_type& x_value = interval_value_pair.second;
            const_iterator it_ = first_;

            set_type eraser;
            Type     intersection;

            while(it_ != end_  )
            {
                const codomain_type& co_value = (*it_).second;
                covered = (*it_++).first;
                //[a      ...  : span
                //     [b ...  : covered
                //[a  b)       : left_over
                left_over = right_subtract(span, covered);

                //That which is common ...
                common_interval = span & covered;
                if(!icl::is_empty(common_interval))
                {
                    // ... shall be subtracted
                    icl::add(eraser, common_interval);

                    on_codomain_model<Type, has_set_semantics<codomain_type>::value>
                        ::add(intersection, common_interval, x_value, co_value);
                }

                icl::add(object, value_type(left_over, x_value)); //That which is not shall be added
                // Because this is a collision free addition I don't have to distinguish codomain_types.

                //...      d) : span
                //... c)      : covered
                //     [c  d) : span'
                span = left_subtract(span, covered);
            }

            //If span is not empty here, it is not in the set so it shall be added
            icl::add(object, value_type(span, x_value));

            //finally rewrite the common segments
            icl::erase(object, eraser);
            object += intersection;
        }
    };
    //--------------------------------------------------------------------------
} ;

//==============================================================================
//= Addition detail
//==============================================================================
template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::add_front(const interval_type& inter_val, iterator& first_)
{
    // If the collision sequence has a left residual 'left_resid' it will
    // be split, to provide a standardized start of algorithms:
    // The addend interval 'inter_val' covers the beginning of the collision sequence.

    // only for the first there can be a left_resid: a part of *first_ left of inter_val
    interval_type left_resid = right_subtract((*first_).first, inter_val);

    if(!icl::is_empty(left_resid))
    {   //            [------------ . . .
        // [left_resid---first_ --- . . .
        iterator prior_ = cyclic_prior(*this, first_);
        const_cast<interval_type&>((*first_).first)
            = left_subtract((*first_).first, left_resid);
        //NOTE: Only splitting
        this->_map.insert(prior_, segment_type(left_resid, (*first_).second));
    }
    //POST:
    // [----- inter_val ---- . . .
    // ...[-- first_ --...
}

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
    template<class Combiner>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::add_segment(const interval_type& inter_val, const CodomainT& co_val, iterator& it_)
{
    interval_type lead_gap = right_subtract(inter_val, (*it_).first);
    if(!icl::is_empty(lead_gap))
    {
        // [lead_gap--- . . .
        //          [-- it_ ...
        iterator prior_ = it_==this->_map.begin()? it_ : prior(it_);
        iterator inserted_ = this->template gap_insert<Combiner>(prior_, lead_gap, co_val);
        that()->handle_inserted(prior_, inserted_);
    }

    // . . . --------- . . . addend interval
    //      [-- it_ --)      has a common part with the first overval
    Combiner()((*it_).second, co_val);
    that()->template handle_left_combined<Combiner>(it_++);
}

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
    template<class Combiner>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::add_main(interval_type& inter_val, const CodomainT& co_val,
               iterator& it_, const iterator& last_)
{
    interval_type cur_interval;
    while(it_!=last_)
    {
        cur_interval = (*it_).first ;
        add_segment<Combiner>(inter_val, co_val, it_);
        // shrink interval
        inter_val = left_subtract(inter_val, cur_interval);
    }
}

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
    template<class Combiner>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::add_rear(const interval_type& inter_val, const CodomainT& co_val, iterator& it_)
{
    iterator prior_ = cyclic_prior(*that(), it_);
    interval_type cur_itv = (*it_).first ;

    interval_type lead_gap = right_subtract(inter_val, cur_itv);
    if(!icl::is_empty(lead_gap))
    {   //         [lead_gap--- . . .
        // [prior)          [-- it_ ...
        iterator inserted_ = this->template gap_insert<Combiner>(prior_, lead_gap, co_val);
        that()->handle_inserted(prior_, inserted_);
    }

    interval_type end_gap = left_subtract(inter_val, cur_itv);
    if(!icl::is_empty(end_gap))
    {
        // [----------------end_gap)
        //  . . . -- it_ --)
        Combiner()((*it_).second, co_val);
        that()->template gap_insert_at<Combiner>(it_, prior_, end_gap, co_val);
    }
    else
    {
        // only for the last there can be a right_resid: a part of *it_ right of x
        interval_type right_resid = left_subtract(cur_itv, inter_val);

        if(icl::is_empty(right_resid))
        {
            // [---------------)
            //      [-- it_ ---)
            Combiner()((*it_).second, co_val);
            that()->template handle_preceeded_combined<Combiner>(prior_, it_);
        }
        else
        {
            // [--------------)
            //      [-- it_ --right_resid)
            const_cast<interval_type&>((*it_).first) = right_subtract((*it_).first, right_resid);

            //NOTE: This is NOT an insertion that has to take care for correct application of
            // the Combiner functor. It only reestablished that state after splitting the
            // 'it_' interval value pair. Using _map_insert<Combiner> does not work here.
            iterator insertion_ = this->_map.insert(it_, value_type(right_resid, (*it_).second));
            that()->handle_reinserted(insertion_);

            Combiner()((*it_).second, co_val);
            that()->template handle_preceeded_combined<Combiner>(insertion_, it_);
        }
    }
}

//==============================================================================
//= Addition
//==============================================================================
template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
    template<class Combiner>
inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
    interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::_add(const segment_type& addend)
{
    typedef typename on_absorbtion<type,Combiner,
                                absorbs_identities<type>::value>::type on_absorbtion_;

    const interval_type& inter_val = addend.first;
    if(icl::is_empty(inter_val))
        return this->_map.end();

    const codomain_type& co_val = addend.second;
    if(on_absorbtion_::is_absorbable(co_val))
        return this->_map.end();

    std::pair<iterator,bool> insertion
        = this->_map.insert(value_type(inter_val, version<Combiner>()(co_val)));

    if(insertion.second)
        return that()->handle_inserted(insertion.first);
    else
    {
        // Detect the first and the end iterator of the collision sequence
        iterator first_ = this->_map.lower_bound(inter_val),
                 last_  = prior(this->_map.upper_bound(inter_val));
        //assert(end_ == this->_map.upper_bound(inter_val));
        iterator it_ = first_;
        interval_type rest_interval = inter_val;

        add_front         (rest_interval,         it_       );
        add_main<Combiner>(rest_interval, co_val, it_, last_);
        add_rear<Combiner>(rest_interval, co_val, it_       );
        return it_;
    }
}

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
    template<class Combiner>
inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
    interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::_add(iterator prior_, const segment_type& addend)
{
    typedef typename on_absorbtion<type,Combiner,
                                absorbs_identities<type>::value>::type on_absorbtion_;

    const interval_type& inter_val = addend.first;
    if(icl::is_empty(inter_val))
        return prior_;

    const codomain_type& co_val = addend.second;
    if(on_absorbtion_::is_absorbable(co_val))
        return prior_;

    std::pair<iterator,bool> insertion
        = add_at<Combiner>(prior_, inter_val, co_val);

    if(insertion.second)
        return that()->handle_inserted(insertion.first);
    else
    {
        // Detect the first and the end iterator of the collision sequence
        std::pair<iterator,iterator> overlap = equal_range(inter_val);
        iterator it_   = overlap.first,
                 last_ = prior(overlap.second);
        interval_type rest_interval = inter_val;

        add_front         (rest_interval,         it_       );
        add_main<Combiner>(rest_interval, co_val, it_, last_);
        add_rear<Combiner>(rest_interval, co_val, it_       );
        return it_;
    }
}

//==============================================================================
//= Subtraction detail
//==============================================================================

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::subtract_front(const interval_type& inter_val, iterator& it_)
{
    interval_type left_resid = right_subtract((*it_).first, inter_val);

    if(!icl::is_empty(left_resid)) //                     [--- inter_val ---)
    {                              //[prior_) [left_resid)[--- it_ . . .
        iterator prior_ = cyclic_prior(*this, it_);
        const_cast<interval_type&>((*it_).first) = left_subtract((*it_).first, left_resid);
        this->_map.insert(prior_, value_type(left_resid, (*it_).second));
        // The segemnt *it_ is split at inter_val.first(), so as an invariant
        // segment *it_ is always "under" inter_val and a left_resid is empty.
    }
}

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
    template<class Combiner>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::subtract_main(const CodomainT& co_val, iterator& it_, const iterator& last_)
{
    while(it_ != last_)
    {
        Combiner()((*it_).second, co_val);
        that()->template handle_left_combined<Combiner>(it_++);
    }
}

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
    template<class Combiner>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::subtract_rear(interval_type& inter_val, const CodomainT& co_val, iterator& it_)
{
    interval_type right_resid = left_subtract((*it_).first, inter_val);

    if(icl::is_empty(right_resid))
    {
        Combiner()((*it_).second, co_val);
        that()->template handle_combined<Combiner>(it_);
    }
    else
    {
        const_cast<interval_type&>((*it_).first) = right_subtract((*it_).first, right_resid);
        iterator next_ = this->_map.insert(it_, value_type(right_resid, (*it_).second));
        Combiner()((*it_).second, co_val);
        that()->template handle_succeeded_combined<Combiner>(it_, next_);
    }
}

//==============================================================================
//= Subtraction
//==============================================================================
template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
    template<class Combiner>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::_subtract(const segment_type& minuend)
{
    interval_type inter_val = minuend.first;
    if(icl::is_empty(inter_val))
        return;

    const codomain_type& co_val = minuend.second;
    if(on_absorbtion<type,Combiner,Traits::absorbs_identities>::is_absorbable(co_val))
        return;

    std::pair<iterator, iterator> exterior = equal_range(inter_val);
    if(exterior.first == exterior.second)
        return;

    iterator last_  = prior(exterior.second);
    iterator it_    = exterior.first;
    subtract_front          (inter_val,         it_       );
    subtract_main <Combiner>(           co_val, it_, last_);
    subtract_rear <Combiner>(inter_val, co_val, it_       );
}

//==============================================================================
//= Insertion
//==============================================================================
template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::insert_main(const interval_type& inter_val, const CodomainT& co_val,
                  iterator& it_, const iterator& last_)
{
    iterator end_   = boost::next(last_);
    iterator prior_ = cyclic_prior(*this,it_), inserted_;
    interval_type rest_interval = inter_val, left_gap, cur_itv;
    interval_type last_interval = last_ ->first;

    while(it_ != end_  )
    {
        cur_itv = (*it_).first ;
        left_gap = right_subtract(rest_interval, cur_itv);

        if(!icl::is_empty(left_gap))
        {
            inserted_ = this->_map.insert(prior_, value_type(left_gap, co_val));
            it_ = that()->handle_inserted(inserted_);
        }

        // shrink interval
        rest_interval = left_subtract(rest_interval, cur_itv);
        prior_ = it_;
        ++it_;
    }

    //insert_rear(rest_interval, co_val, last_):
    interval_type end_gap = left_subtract(rest_interval, last_interval);
    if(!icl::is_empty(end_gap))
    {
        inserted_ = this->_map.insert(prior_, value_type(end_gap, co_val));
        it_ = that()->handle_inserted(inserted_);
    }
    else
        it_ = prior_;
}

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
    interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::_insert(const segment_type& addend)
{
    interval_type inter_val = addend.first;
    if(icl::is_empty(inter_val))
        return this->_map.end();

    const codomain_type& co_val = addend.second;
    if(on_codomain_absorbtion::is_absorbable(co_val))
        return this->_map.end();

    std::pair<iterator,bool> insertion = this->_map.insert(addend);

    if(insertion.second)
        return that()->handle_inserted(insertion.first);
    else
    {
        // Detect the first and the end iterator of the collision sequence
        iterator first_ = this->_map.lower_bound(inter_val),
                 last_  = prior(this->_map.upper_bound(inter_val));
        //assert((++last_) == this->_map.upper_bound(inter_val));
        iterator it_ = first_;
        insert_main(inter_val, co_val, it_, last_);
        return it_;
    }
}

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
    interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::_insert(iterator prior_, const segment_type& addend)
{
    interval_type inter_val = addend.first;
    if(icl::is_empty(inter_val))
        return prior_;

    const codomain_type& co_val = addend.second;
    if(on_codomain_absorbtion::is_absorbable(co_val))
        return prior_;

    std::pair<iterator,bool> insertion = insert_at(prior_, inter_val, co_val);

    if(insertion.second)
        return that()->handle_inserted(insertion.first);
    {
        // Detect the first and the end iterator of the collision sequence
        std::pair<iterator,iterator> overlap = equal_range(inter_val);
        iterator it_    = overlap.first,
                 last_  = prior(overlap.second);
        insert_main(inter_val, co_val, it_, last_);
        return it_;
    }
}

//==============================================================================
//= Erasure segment_type
//==============================================================================
template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::erase_rest(interval_type& inter_val, const CodomainT& co_val,
                 iterator& it_, const iterator& last_)
{
    // For all intervals within loop: (*it_).first are contained_in inter_val
    while(it_ != last_)
        if((*it_).second == co_val)
            this->_map.erase(it_++);
        else it_++;

    //erase_rear:
    if((*it_).second == co_val)
    {
        interval_type right_resid = left_subtract((*it_).first, inter_val);
        if(icl::is_empty(right_resid))
            this->_map.erase(it_);
        else
            const_cast<interval_type&>((*it_).first) = right_resid;
    }
}

template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
inline SubType& interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::erase(const segment_type& minuend)
{
    interval_type inter_val = minuend.first;
    if(icl::is_empty(inter_val))
        return *that();

    const codomain_type& co_val = minuend.second;
    if(on_codomain_absorbtion::is_absorbable(co_val))
        return *that();

    std::pair<iterator,iterator> exterior = equal_range(inter_val);
    if(exterior.first == exterior.second)
        return *that();

    iterator first_ = exterior.first, end_ = exterior.second,
             last_  = cyclic_prior(*this, end_);
    iterator second_= first_; ++second_;

    if(first_ == last_)
    {   //     [----inter_val----)
        //   .....first_==last_.....
        // only for the last there can be a right_resid: a part of *it_ right of minuend
        interval_type right_resid = left_subtract((*first_).first, inter_val);

        if((*first_).second == co_val)
        {
            interval_type left_resid = right_subtract((*first_).first, inter_val);
            if(!icl::is_empty(left_resid)) //            [----inter_val----)
            {                              // [left_resid)..first_==last_......
                const_cast<interval_type&>((*first_).first) = left_resid;
                if(!icl::is_empty(right_resid))
                    this->_map.insert(first_, value_type(right_resid, co_val));
            }
            else if(!icl::is_empty(right_resid))
                const_cast<interval_type&>((*first_).first) = right_resid;
            else
                this->_map.erase(first_);
        }
    }
    else
    {
        // first AND NOT last
        if((*first_).second == co_val)
        {
            interval_type left_resid = right_subtract((*first_).first, inter_val);
            if(icl::is_empty(left_resid))
                this->_map.erase(first_);
            else
                const_cast<interval_type&>((*first_).first) = left_resid;
        }

        erase_rest(inter_val, co_val, second_, last_);
    }

     return *that();
}

//==============================================================================
//= Erasure key_type
//==============================================================================
template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
inline SubType& interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
    ::erase(const interval_type& minuend)
{
    if(icl::is_empty(minuend))
        return *that();

    std::pair<iterator, iterator> exterior = equal_range(minuend);
    if(exterior.first == exterior.second)
        return *that();

    iterator first_ = exterior.first,
             end_   = exterior.second,
             last_  = prior(end_);

    interval_type left_resid  = right_subtract((*first_).first, minuend);
    interval_type right_resid =  left_subtract(last_ ->first, minuend);

    if(first_ == last_ )
        if(!icl::is_empty(left_resid))
        {
            const_cast<interval_type&>((*first_).first) = left_resid;
            if(!icl::is_empty(right_resid))
                this->_map.insert(first_, value_type(right_resid, (*first_).second));
        }
        else if(!icl::is_empty(right_resid))
            const_cast<interval_type&>((*first_).first) = left_subtract((*first_).first, minuend);
        else
            this->_map.erase(first_);
    else
    {   //            [-------- minuend ---------)
        // [left_resid   fst)   . . . .    [lst  right_resid)
        iterator second_= first_; ++second_;

        iterator start_ = icl::is_empty(left_resid)? first_: second_;
        iterator stop_  = icl::is_empty(right_resid)? end_  : last_ ;
        this->_map.erase(start_, stop_); //erase [start_, stop_)

        if(!icl::is_empty(left_resid))
            const_cast<interval_type&>((*first_).first) = left_resid;

        if(!icl::is_empty(right_resid))
            const_cast<interval_type&>(last_ ->first) = right_resid;
    }

    return *that();
}

//-----------------------------------------------------------------------------
// type traits
//-----------------------------------------------------------------------------
template
<
    class SubType,
    class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc
>
struct is_map<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
{
    typedef is_map<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
    BOOST_STATIC_CONSTANT(bool, value = true);
};

template
<
    class SubType,
    class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc
>
struct has_inverse<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
{
    typedef has_inverse<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
    BOOST_STATIC_CONSTANT(bool, value = (has_inverse<CodomainT>::value));
};

template
<
    class SubType,
    class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc
>
struct is_interval_container<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
{
    typedef is_interval_container<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
    BOOST_STATIC_CONSTANT(bool, value = true);
};

template
<
    class SubType,
    class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc
>
struct absorbs_identities<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
{
    typedef absorbs_identities<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
    BOOST_STATIC_CONSTANT(bool, value = (Traits::absorbs_identities));
};

template
<
    class SubType,
    class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc
>
struct is_total<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
{
    typedef is_total<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
    BOOST_STATIC_CONSTANT(bool, value = (Traits::is_total));
};

}} // namespace icl boost

#endif

redpajama_set_name: RedPajamaGithub


text:
lip gloss custom packaging
Tag: lip gloss custom packaging
AyushiChoudhary Aug 20, 2021 0 8
mariasmith Jan 7, 2022 0 8
10 SEO Trends to Watch Out for in 2023
This article will reveal to you the 10 SEO trends to look forward to this 2023
ESSAY ON HOW CULTURAL VALUE ORIENTATION WOULD AFFECT THE...
Essay on culture and influence on vision 2063, Malawi vision 2063 essay, Culture...
Enjoy the best call of duty game and play with your friends. Select the best call...
How to increase Adsense Google adsense (CPC) in 2022 in...
A 10 step guide to increase your Adsense earnings this 2022. Adsense ads are among...
What are workout supplements and how you should select...
Workout supplements are something that is consumed to improve the fitness of the...

redpajama_set_name: RedPajamaCommonCrawl


text:
Ditch the Label
#StopAsianHate Support Hub
Report Online Abuse
#StopAsianHate
Free Resources For Educators
Tag: gender queer
'Gender is a Much More Beautifully Complex Thing Than Society Would Have You Believe'
Post author By Ditch the Label
2 Comments on 'Gender is a Much More Beautifully Complex Thing Than Society Would Have You Believe'
Vesper blogs about identifying as non-binary
Life would be easier if it came with a guidebook.
If it did, maybe it wouldn't have taken me 27 years to realise that I didn't actually have to subscribe to society's assertion that everyone is either male or female. At the very least, ripping the book to shreds in a fit of rage would have made for great stress relief. Then again, had there been such a book I probably wouldn't have grown up to be the person that I am today and I wouldn't change that for the world.
Hello, my name's Vesper. I'm a 31 year old non-binary person who's here today to tell you that gender is a much more beautifully complex thing than society would have you believe. That some people, such as myself, are neither male nor female but a different gender(s) entirely.
"Some people, such as myself, are neither male nor female"
Unlike some who struggled with the gender that society assigned them at birth from a young age, I grew up not actively thinking about gender. While I wasn't oblivious to society categorising me as one thing as opposed to another, I was content to shrug off society's assumptions. It wasn't until adolescence when the background noise from society and my peers became increasingly difficult to ignore. It wasn't until over a decade of denial and inner conflict later that I happened to come across the word "genderqueer" when researching my sexuality and all things LGBT+, which of course included the word "transgender," a word I'd never heard of before.
The instant I discovered that there are, in fact, more genders than male and female, everything changed. While this may sound cliché and exaggeratory, the best way I can describe it is that it was like having gone through life for 27 years without glasses not realising just how blurred my vision had been until finally seeing it in focus with glasses for the first time. Everything made perfect sense! I was (am) neither male nor female, but a different gender entirely! I am maverique, one of many non-binary genders which are neither male nor female.
"I ran into criticism and rejection of genderqueer and non-binary people"
It wasn't long at all before I started trying to immerse myself in LGBTQIA spaces online and no sooner had I done so than I ran into criticism and rejection of genderqueer and non-binary people. As someone who was brand new to discussion of sexuality and gender in general, it was incredibly hard not to internalise such negativity, especially since it was coming from people who I saw as my "senior" in the community. At the time, it was especially hard because the internet was my only means of accessing LGBTQIA spaces. Feeling under attack in the only space that I had caused me a lot of pain. However, having finally found words and a sense of commonality that made me feel comfortable in myself for the first time in my life, I sure as hell wasn't about to let take that away from me. I chose to retreat from such spaces and create my own on Tumblr and YouTube.
[full-width-figure image="https://www.ditchthelabel.org/wp-content/uploads/2016/09/vv.jpg"]
It's been 4 years since I was first able to put a word to my gender. A lot has changed and yet it hasn't at the same time. I've watched as so much growth has taken place within online non-binary and genderqueer communities and even as the identities themselves have grown and changed. In 4 (relatively short) years, I've also seen online LGBTQIA communities in general grow, change and yet remain the same. There have seemingly been shifts in the negativity and bullying, but at the end of the day it's essentially the exact same hurtful thing it has always been, sadly. Unlike before, however, I now have access to offline LGBTQIA spaces. I'm also out to select family members and friends, which has brought with it new challenges.
"I actually never intended to come out to anyone in my extremely religious family"
Truth be told, I actually never intended to come out to anyone in my extremely religious family. I ended up being outed time and time again in part thanks to my own social media presence. Make no mistake, being outed is a pleasant experience and I do wish things had happened differently, but 2 years after my first outing to my minister of a mother, I'm finally in a place where I can look back on it all and be glad to be where I am now. My being non-binary continues to be the biggest thing that my family struggles to understand and come to terms with about me, but things have improved a lot in 2 years.
Navigating LGBTQIA spaces as someone who is neither male nor female continues to be very challenging at times. That said, every day awareness and support of non-binary people grows. More than ever, non-binary people are carving out spaces for ourselves and I'm incredibly grateful for this. It means that even when faced with negativity elsewhere, there are spaces for us to retreat to for support and affirmation when need be. I'm so proud of how far things have come for non-binary people in 4 short years. There is still a long way to go, but I'm more confident than ever that we'll get there.
"Self-care and self-awareness are perhaps two of the most important things I've learned since coming out to myself"
To exist in this world as a non-binary person is a challenge. Even more than that, life itself is an act of defiance. There are days when that fact makes it all the harder to get through the day, but there are also days when that fact can be empowering for me, making me love myself and everything that I am all the more.
Self-care and self-awareness are perhaps two of the most important things I've learned since coming out to myself. If you're non-binary, genderqueer or otherwise struggling to navigate and survive in this society that we live in, I encourage you to take time out of life for yourself. Shut everyone and everything else out and check-in with yourself. Acknowledge how you're feeling, allow yourself to feel that way and love yourself because of, or in spite of it. Be kind to yourself because you're just being you and you're doing your best. That's more than enough.
Society in general, including the LGBTQIA community, has a lot of learning to do. In the meantime, keep being as awesome as you are. Let those of us who are in a position to try and help society learn, who are able to offer support/encouragement to others, do our thing.
"Navigating LGBTQIA spaces as someone who is neither male nor female continues to be very challenging at times"
Perhaps you're reading this not as a non-binary person yourself, but as someone who's curious and wants to learn more. There's a lot that someone who isn't non-binary can do to support those who are, but in my humble opinion one of the biggest things you can do is listen. Tips on what you can do to be a good ally to non-binary people can be found in the things that we say.
I may be but one non-binary person among many, but I'm one non-binary person among many who can genuinely say that things have gotten better for them and who is determined to help support and raise awareness for non-binary people. Stay strong! And hit me up anytime.
Written by Vesper
Follow Vesper on YouTube
How do I tell my parents Im Bi?
Hey guys, I am writting this because I am planning on becoming a DTL Mentor at the school I attend but I have no I dea what I am doing
I have a crush on a trans guy that is my friend...what would happened if I said I love you to him?
I need advice from my friends,or anyone
Feeling angry
Hey guys, I am writting this because I really feel like punching my ex in the face but I don't want him to resent e for the rest of my life or get in to trouble at school. WWYD?
if you guys want to talk to me ^^
hey guys I am not really good at introductions but here it is: my name is Leaf and I am 15 years old and I am trans bi and poly and I love to make new friends, drawing and reading. I dont really like to talk to homophobics that much and I am here if […]
I am planning on coming out to my friends as bi pretty soon does anyone know a good way to? allso this is the second time i am trying to post this so if u see 2 sorry
idk what to write in this
How to Deal with "New Year, New Me" Pressure
5 Pieces of Advice Every Uni Student Needs Ahead of January Exams
Blue Monday – A Short Guide To Surviving the Most Depressing Day of the Year
SAY HEY!
Tags gender, gender queer, lgbt, non-binary, queer, religious parents
Gender Sexuality
'I Often Wondered If We Were the Result of a Medical Experiment': Alec Butler on Being Born Intersex
No Comments on 'I Often Wondered If We Were the Result of a Medical Experiment': Alec Butler on Being Born Intersex
Award-winning playwright, filmmaker and published author Alec Butler was born intersex and now identifies as trans. Here they blog about their experiences.
*Note to Reader: Alec uses pronouns I/we throughout the article
This moment right now is our proudest moment, to be an award winning playwright and filmmaker, a published author, a budding scholar at one of the most prestigious research universities in the world, is a dream I dreamed for myself for years.
We were born with an intersex condition over fifty years ago; there was no closet for someone like us growing up. We were both teased and threatened about whether we were a boy or a girl every day at school; bullied on a regular basis in the locker-lined hallways. The teachers did nothing; my parents worried about whether I would end up dead. Instead of dwelling on a reality where we were not wanted, we found solace in writing and making art, reading stacks of books at the local library, biding our time until we were in a position to leave a community where we were not wanted.
I left home on a quest to find other people like us, aware that there were gods/goddesses like me in myths only according to what we were reading in the encyclopedias at the library. In the Greek myths, Teresias, the doubled sexed seer caught my imagination.
"The teachers did nothing; my parents worried about whether I would end up dead."
In the mid 1980's I moved to Toronto, Canada where I lived as a butch lesbian for decades, making a name for myself as a playwright in the queer Canadian theatre scene, writing, producing and directing plays about lesbian life in the big city. Getting nominated for a national drama award while at the same time couch surfing with friends because we were homeless. Such is the precarious life of marginalised artists in this society.
In the late 1990's while performing a monologue by Pussy Boy, a film character I was developing at the "Counting Past Two Festival", the first literary and film festival featuring the work of trans people in Canada is where I heard the word "intersex" for the first time, struck a deep chord in the core of our being.
I researched the many intersex conditions that exist on the worldwide web.
A memory of my mother telling me about a drug her doctor made her take while she was pregnant with us bubbled to the surface. I realised we were born with the one intersex condition caused by medical intervention in utero, lucky us. I often wondered if we were the result of a medical experiment when I was a kid. Thoughts that inspired many sci-fi short stories in my mind, turns out we were not too far off the mark. Since those young fantasies of being special, or an alien from another planet, I discovered that people like us, people who identify with both genders, or none, have existed since human beings have existed, that we were worshipped as deities, that masses of people performed special rituals in our honour, we had sacred and practical roles in the community, we were wanted and desired.
"I realised we were born with the one intersex condition caused by medical intervention"
In North America before colonisation, First Nations recognised people like us as healers and teachers called Two-Spirits. Our mixed race family background is a result of colonisation of Canada; our ancestors are First Nations, French, Irish, as well as African on my mother's side, my grandmother Nanny, was a descendent of the first 250 slaves brought to Cape Breton, a small island on the east coast of Canada. It was on this island in New France where the first point of contact between European and Indigenous people was established, the island where Fortress Louisburg was built 400 years ago, a huge military complex that controlled the trade routes of the New World. In was from our favourite beach at Kennington Cove that Captain Cook launched his curriculum trip around the globe in the 18th Century.
In the 1960's a section of Fortress Louisburg was rebuilt as a tourist attraction, my father worked there as a carpenter. We lived a twenty-minute car ride down the road from what was once the epicentre of the colonisation, the main port of resource extraction from North America on behalf of the King of France. Today the colonisation continues unabated, it is still in progress. The colonised mind is the root of the mentality of people that bully; colonisation is the birthplace of feeling entitled to take what does not belong to you without asking.
Over the years, since coming out as trans we have made it our mission to decolonize our mind and our community, but the forces of colonisation have been at this for hundreds of years, destroying not only the land, cultures, food and living resources, the very spirits of the indigenous people they encountered and in the process almost wiped out the many beautiful gender expressions that have existed since the dawn of humanity.
We need to remember as Two-Spirit, gender queer, non-binary people that we are the descendants of these LGBTQI2S ancestors who were almost exterminated but they did not succeed because we are still here, that we exist as flesh, blood, guts and bones, mind and spirit, living lives of purpose and pride, we are not just myths in stories from the past.
If I had a message to give to my past self from what I know now it would be to love myself more, by using my voice more not just bury myself in books, thoughts and dreams about how it could be different, although dreaming is an important stage in decolonizing the mind, it is equally important to speak up and act. It's now the 21st century, trans people have made unprecedented gains in getting their humans rights recognised but a vicious backlash has ensued in response, black trans woman bare the brunt of the backlash, Trans Day of Remembrance is a mass communal memorial to the hundreds we lose to violence every year. So speaking up, not being a bystander when witnessing abuse is more crucial than ever, not just for trans people but for all people who are bullied.
Tags Alec Butler, gender, gender queer, intersex, non-binary, trans, transgender
Report Cyberbullying
Sign up for free tips, guides and stories from people just like you!
Talk To Somebody Now
Join our community with likeminded people & trained support mentors to help you
Copyright © 2021 Ditch the Label Youth Charity. Registered in England, No. 08387544. Registered Charity No. 1156329.
Cookie Policy Privacy Policy Legal
This website uses cookies to improve user experience. To find out how to change your settings, go to our Cookie Policy.


Let us help you locate a dealership near you.
Need Service? We'll be glad to help schedule you a Service Appointment.
Let us help you find a vehicle that fits your needs.
DARCARS Automotive Group is a family of dealerships serving drivers throughout Maryland, Virginia, Washington D.C., Florida, and beyond.
When you step into the showroom of a DARCARS dealership, you can expect an excellent selection of new and used cars, and a friendly and knowledgeable team to help you every step of the way; from the first test drive, to financing, to driving off in a car that's right for you. Our dealerships also offer onsite state-of-the-art service centers for all your auto maintenance and repairs. DARCARS technicians are dedicated to keeping your vehicle running smoothly and efficiently for years to come.
DARCARS is proud to offer a variety of brands at our dealerships throughout the Virginia, Maryland, and Washington D.C. areas, including Jeep, Nissan, Toyota, Dodge, and Chrysler. If you don't see the vehicle you want in our current inventory, let us know - we will get it for you. Stop by one of our dealerships and get behind the wheel of the new Volvo, Volkswagen, Ford, Kia, or Ram that you've had your eye on.
Use our website for all of your automotive needs throughout Virginia, Maryland, Washington D.C., and Florida, from new model research and viewing inventory to exploring financing options. View current incentives online and submit a secure online finance application to secure a loan or lease today. Locate your nearest DARCARS service or collision center and schedule an appointment online.
There are thousands of reasons to choose DARCARS Pre-Owned, and our used inventory is one of them. We have an extensive inventory of pre-owned vehicles available for you to choose from at our 22 locations, including over 500 certified vehicles and over 2000 used cars for sale across our dealerships.
No matter what you're looking for in your next vehicle, you can find a great fit among our used cars. We have a variety of makes, models and body styles available for you to choose from; with so many options, every driver can find a great fit.
All of our used cars have been inspected to ensure they are in great shape and our certified pre-owned models have undergone manufacturer-approved inspections for guaranteed quality. When you buy a used car at a DARCARS Pre-Owned dealership, you can expect a safe and reliable ride.
If you're interested in learning more about the used cars and certified pre-owned vehicles we have available, don't hesitate to stop by one of our DARCARS Pre-Owned dealerships. We would be happy to answer your questions and show you our available models at any one of our locations so you can find the vehicle that's perfect for you.
At our family of DARCARS dealerships, we make your personal experience a priority by providing a pleasant, hassle-free environment whether you're purchasing a vehicle or bringing your car into one of our service centers. Our team is dedicated to being helpful, professional, and courteous at all times. We proudly serve drivers from Silver Spring, Washington DC, College Park, Laurel, Gaithersburg, Rockville, and beyond.


Do Maghreb film producers have a language problem in the Arab Middle East?
Most Maghreb film producers and directors do not see a convincing reason for the difficulty of distribution of their films.
Film producers in Tunisia, Algeria and Morocco have endeavoured to produce a good number of documentaries and feature films, both short and long. However, overlooking Arab and foreign cinema festivals, Maghreb cinema is scarcely present as commercial cinematic offerings in most Arab countries.
Moroccan Raouf Sabahi, a first-time director whose feature film "Hayat" toured in dozens of festivals and won many awards, and Algerian director Yasmine Chouikh, whose "To the End of Time" received an award at the Oran Festival, both said Arab Middle East film distributors should keep an open mind to the marketability of Maghreb films.
Sabahi said Moroccan cinema has, since the early 1990s, seen significant improvement in quality and thematic orientation because of a new generation of filmmakers. He said Moroccan cinema still suffers from some shortcomings, such as the lack scripts and visual identity for Moroccan films.
Moroccan cinema's biggest problem, though, he said, is distribution. Movie theatres in Morocco are closing due to piracy, of course, but also because Moroccan films being proposed have an inward-looking character, the type of films labelled arthouse cinema and, in general, are not meant for a wide audience.
"Concerning external distribution," Sabahi said, "the argument that the Moroccan dialect is too difficult to understand, as they say in Arab countries, is no longer convincing, in my opinion.
Sabahi pointed out that the Egyptian dialect was presented on Moroccan television, so much so that people in their 30s can understand it perfectly. Since Egyptian shows have been removed from Moroccan TV schedules, younger Moroccans could not understand the Egyptian dialect.
Later, as Syrian dramas flourished on Moroccan TV, people slowly became used to the Syrian accent and vernacular. The same could be said of television and cinema works from Gulf countries.
In the final analysis, viewers outside Morocco are either apathetic or too lazy to try to understand Moroccan dialect.
Chouikh said: "When we think about distributing any film, whether in Algeria or anywhere else, one must first think about how a film will be distributed in its own country.
As for external distribution, Chouikh said it was a tough problem because filmmakers do not have enough experience in the field. Whether in Arab or foreign countries, distribution is an independent domain.
"Before, when I heard the Egyptian, Gulf or even Syrian dialects, I did not understand a thing but after being exposed to these dialects through film, I learned and started to understand. If there had been a tradition of watching Algerian film, it would have facilitated understanding the Algerian dialect," Chouikh said.
"Today most Arab films have Arabic subtitles. I did just that in my long feature film, 'To the End of Time,' when it was shown in Cairo as part of a women's film festival," she said.
Lama Tayara is a Syrian writer.


OTTAWA — After representing Canada at the Olympic Games and winning multiple international medals, Chantal Van Landeghem and Dominique Bouchard have decided to hang up their goggles.
Van Landeghem and Bouchard were key parts of the national team as Canada built towards the success of the Rio 2016 Olympic Games.
Winnipeg's Van Landeghem played a critical role in setting up the Canadian women to a bronze-medal celebration in the 4×100-m freestyle relay at the Rio 2016 Olympic Games. The national record swim was Canada's first women's freestyle relay medal in 40 years.
"Obviously the Olympics were a huge highlight but in general just racing is probably the aspect of swimming I'll miss most, I just loved that feeling of adrenalin behind the blocks. The opportunity to get to represent my country on the highest stage for me was probably one of the greatest honours of all," Van Landeghem said.
The 23-year-old from Winnipeg built a solid international resume throughout her career. She made her first national team in 2011, and jumped onto the gold-medal step of the podium twice at the Toronto 2015 Pan American Games. She set a Pan Am Games and Canadian record to win the 100-m freestyle, and swam the anchor leg of the 4×100-m freestyle relay that won gold and set Pan Am Games and Canadian records. She also swam the freestyle leg of the 4×100-m medley relay that earned silver. Later that summer she added a Canadian record in the 50-m freestyle on the way to a fifth-place finish at the FINA World Championships. But she says it's not about the medals, which she keeps in storage.
Van Landeghem graduated from the University of Georgia in 2017 as a First Honor Graduate status with an overall GPA of 4.0, becoming the first UGA student-athlete to win the Dean William Tate Award in recognition of a perfect GPA. She added two more bronze medals to her collection at the 2017 FINA worlds, helping the mixed 4×100-m freestyle and mixed 4×100-m medley relays to the podium in Budapest.
"I wanted to leave on a really high note which I think I'm doing and looking back only with fond memories," Van Landeghem said.
Walking away from the pool will allow her to focus on her Master's degree in clinical psychology at the University of Manitoba, which she started in the fall after moving back home. She hopes to be able to contribute to the sport in the future, perhaps as a mental performance consultant.
Bouchard, of North Bay, Ont., was also a member of Canada's high-powered women's swim squad that was named Canadian Press Team of the Year in 2016.
The 26-year-old reached the semifinals in both the 100- and 200-metre backstroke events at the 2016 Olympic Summer Games. She also hopped onto the podium at the 2015 Pan American Games where she claimed the silver medal behind Hilary Caldwell in the thrilling 200-m backstroke where the Canadians celebrated a one-two finish. She also swam the morning heats of the 4×100-m freestyle relay and 4×100-m medley relay to earn gold and silver medals. Bouchard then went on to finish sixth in the 200 back at world championships.
After such a strong 2015, she was disappointed to finish ninth in the 200 in Rio, leaving her just outside the final. She then just missed making the 2017 team, and her year got even more complicated when she experienced back problems, and then was diagnosed with deep vein thrombosis in her right leg.
Although she now has a clean bill of health, the burning desire to train to her limits in the pool had waned.
"I was kind of waiting for that feeling to come back but it never did. I think it was the right time, and Canada's not lacking any backstrokers," she added with a laugh, noting Olympic medallists Caldwell and Kylie Masse, who set a world record to win the 100 at worlds this summer, with young swimmers such as Taylor Ruck and Jade Hannah coming on strong.
A four-time All-American while swimming at the University of Missouri, she still holds the school record in the 200-yard back from her second-place finish in 2013. Bouchard has returned to Sudbury, Ont., after completing a Master's in Health Administration. She is applying to medical schools and has done some youth coaching clinics with Martha McCabe's Head to Head initiative while contemplating her next move.
"Both Dominique and Chantal will be missed, however, we are all better for their involvement on our national teams," Atkinson added.


text:
ASAP usually stands for "as soon as possible".

ASAP may also refer to:

Arts and media

Music

Performers
 ASAP (band), a hard rock band fronted by Adrian Smith
 ASAP Ferg (born 1988), American hip hop recording artist from Harlem, New York
 ASAP Mob, a recording group from Harlem, New York
 ASAP Rocky (born 1988), rapper from Harlem, New York

Recordings
 "ASAP" (Bardot song), 2001
 "ASAP" (STAYC song), 2021
 "ASAP" (T.I. song), 2005
 "ASAP", a song from the Lena Meyer-Landrut album Stardust
 "A.S.A.P.", a song by Hikaru Utada, 2002
 "A.S.A.P.", a song from the Two Steps from Hell album Legend
 "Get Back (ASAP)", a 2011 song by Alexandra Stan

Other media
 ASAP (Philippine TV program), a Philippine television variety show (All-Star Sunday Afternoon Party) which has aired on ABS-CBN since 1995
 Asap (web portal), an Associated Press multimedia news portal

Businesses and organizations
 Academics Stand Against Poverty, an international anti-poverty organization
 Aircraft Sales and Parts, an American kit aircraft and parts manufacturer
 Applied Security Analysis Program, an investment education program at the University of Wisconsin–Madison School of Business
 Aerospace Safety Advisory Panel, an independent NASA safety panel
 ASAP, Inc., a southern U.S.-based food delivery company

Science and technology
 AcceleratedSAP software, from SAP AG
 Another Slight Atari Player, an open-source player of Atari SAP music format
 Asynchronous array of simple processors, AsAP processor architecture
 Atypical small acinar proliferation, a diagnosis on prostate biopsy that carries an increased risk of finding prostate cancer on re-biopsy

See also
STAT

redpajama_set_name: RedPajamaWikipedia