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