/*-----------------------------------------------------------------------------+ Copyright (c) 2011-2011: Joachim Faulhaber +------------------------------------------------------------------------------+ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENCE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +-----------------------------------------------------------------------------*/ #ifndef BOOST_ICL_CONCEPT_INTERVAL_ASSOCIATOR_BASE_HPP_JOFA_110301 #define BOOST_ICL_CONCEPT_INTERVAL_ASSOCIATOR_BASE_HPP_JOFA_110301 #include #include #include #include #include #include namespace boost{ namespace icl { //============================================================================== //= Selection //============================================================================== template inline typename enable_if , is_discrete::type> > , typename Type::const_iterator>::type find(const Type& object, const typename domain_type_of::type& key_val) { //CL typedef typename Type::const_iterator const_iterator; typedef typename Type::interval_type interval_type; return object.find(icl::detail::unit_trail(key_val)); } template inline typename enable_if , is_continuous::type> , has_dynamic_bounds::type> > , typename Type::const_iterator>::type find(const Type& object, const typename domain_type_of::type& key_val) { //CL typedef typename Type::const_iterator const_iterator; typedef typename Type::interval_type interval_type; return object.find(icl::singleton(key_val)); } template inline typename enable_if , is_continuous::type> , is_static_right_open::type> , boost::detail::is_incrementable::type> > , typename Type::const_iterator>::type find(const Type& object, const typename domain_type_of::type& key_val) { typedef typename Type::const_iterator const_iterator; typedef typename Type::interval_type interval_type; const_iterator first_collision = object.lower_bound(icl::detail::unit_trail(key_val)); // A part of the unit_trail(key_value)-interval may be found in the container, that // does not contain key_value. Therefore we have to check for its existence: return ( first_collision == object.end() || icl::contains(key_value(first_collision), key_val) ) ? first_collision : object.end(); } template inline typename enable_if , is_continuous::type> , is_static_left_open::type> , boost::detail::is_incrementable::type> > , typename Type::const_iterator>::type find(const Type& object, const typename domain_type_of::type& key_val) { typedef typename Type::const_iterator const_iterator; typedef typename Type::interval_type interval_type; const_iterator last_collision = object.upper_bound(icl::detail::unit_trail(key_val)); if(last_collision != object.begin()) --last_collision; // A part of the unit_trail(key_value)-interval may be found in the container, that // does not contain key_value. Therefore we have to check for its existence: return ( last_collision == object.end() || icl::contains(key_value(last_collision), key_val) ) ? last_collision : object.end(); } // NOTE: find(object, key) won't compile if key is of continuous type that does // not implement in(de)crementation (e.g. std::string). template inline typename enable_if< is_interval_container , typename Type::const_iterator>::type find(const Type& object, const typename interval_type_of::type& inter_val) { return object.find(inter_val); } //============================================================================== //= Morphisms //============================================================================== template typename enable_if, Type>::type& join(Type& object) { typedef typename Type::interval_type interval_type; typedef typename Type::iterator iterator; iterator it_ = object.begin(); if(it_ == object.end()) return object; iterator next_ = it_; next_++; while(next_ != object.end()) { if( segmental::is_joinable(it_, next_) ) { iterator fst_mem = it_; // hold the first member // Go on while touching members are found it_++; next_++; while( next_ != object.end() && segmental::is_joinable(it_, next_) ) { it_++; next_++; } // finally we arrive at the end of a sequence of joinable intervals // and it points to the last member of that sequence const_cast(key_value(it_)) = hull(key_value(it_), key_value(fst_mem)); object.erase(fst_mem, it_); it_++; next_=it_; if(next_!=object.end()) next_++; } else { it_++; next_++; } } return object; } }} // namespace boost icl #endif