Chris@16
|
1 /*-----------------------------------------------------------------------------+
|
Chris@16
|
2 Copyright (c) 2008-2010: Joachim Faulhaber
|
Chris@16
|
3 +------------------------------------------------------------------------------+
|
Chris@16
|
4 Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
5 (See accompanying file LICENCE.txt or copy at
|
Chris@16
|
6 http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 +-----------------------------------------------------------------------------*/
|
Chris@16
|
8 #ifndef BOOST_ICL_INTERVAL_MAP_ALGO_HPP_JOFA_100730
|
Chris@16
|
9 #define BOOST_ICL_INTERVAL_MAP_ALGO_HPP_JOFA_100730
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
12 #include <boost/mpl/not.hpp>
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/icl/type_traits/is_total.hpp>
|
Chris@16
|
15 #include <boost/icl/type_traits/is_map.hpp>
|
Chris@16
|
16 #include <boost/icl/detail/notate.hpp>
|
Chris@16
|
17 #include <boost/icl/detail/relation_state.hpp>
|
Chris@16
|
18 #include <boost/icl/type_traits/identity_element.hpp>
|
Chris@16
|
19 #include <boost/icl/interval_combining_style.hpp>
|
Chris@16
|
20 #include <boost/icl/detail/element_comparer.hpp>
|
Chris@16
|
21 #include <boost/icl/detail/interval_subset_comparer.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 namespace boost{namespace icl
|
Chris@16
|
24 {
|
Chris@16
|
25
|
Chris@16
|
26
|
Chris@16
|
27 namespace Interval_Map
|
Chris@16
|
28 {
|
Chris@16
|
29 using namespace segmental;
|
Chris@16
|
30
|
Chris@16
|
31 template<class IntervalMapT>
|
Chris@16
|
32 bool is_joinable(const IntervalMapT& container,
|
Chris@16
|
33 typename IntervalMapT::const_iterator first,
|
Chris@16
|
34 typename IntervalMapT::const_iterator past)
|
Chris@16
|
35 {
|
Chris@16
|
36 if(first == container.end())
|
Chris@16
|
37 return true;
|
Chris@16
|
38
|
Chris@16
|
39 typename IntervalMapT::const_iterator it_ = first, next_ = first;
|
Chris@16
|
40 ++next_;
|
Chris@16
|
41
|
Chris@16
|
42 const typename IntervalMapT::codomain_type& co_value
|
Chris@16
|
43 = icl::co_value<IntervalMapT>(first);
|
Chris@16
|
44 while(it_ != past)
|
Chris@16
|
45 {
|
Chris@16
|
46 if(icl::co_value<IntervalMapT>(next_) != co_value)
|
Chris@16
|
47 return false;
|
Chris@16
|
48 if(!icl::touches(key_value<IntervalMapT>(it_++),
|
Chris@16
|
49 key_value<IntervalMapT>(next_++)))
|
Chris@16
|
50 return false;
|
Chris@16
|
51 }
|
Chris@16
|
52
|
Chris@16
|
53 return true;
|
Chris@16
|
54 }
|
Chris@16
|
55
|
Chris@16
|
56 //------------------------------------------------------------------------------
|
Chris@16
|
57 //- Containedness of key objects
|
Chris@16
|
58 //------------------------------------------------------------------------------
|
Chris@16
|
59
|
Chris@16
|
60 //- domain_type ----------------------------------------------------------------
|
Chris@16
|
61 template<class IntervalMapT>
|
Chris@16
|
62 typename enable_if<mpl::not_<is_total<IntervalMapT> >, bool>::type
|
Chris@16
|
63 contains(const IntervalMapT& container,
|
Chris@16
|
64 const typename IntervalMapT::domain_type& key)
|
Chris@16
|
65 {
|
Chris@16
|
66 return container.find(key) != container.end();
|
Chris@16
|
67 }
|
Chris@16
|
68
|
Chris@16
|
69 template<class IntervalMapT>
|
Chris@16
|
70 typename enable_if<is_total<IntervalMapT>, bool>::type
|
Chris@16
|
71 contains(const IntervalMapT&,
|
Chris@16
|
72 const typename IntervalMapT::domain_type&)
|
Chris@16
|
73 {
|
Chris@16
|
74 return true;
|
Chris@16
|
75 }
|
Chris@16
|
76
|
Chris@16
|
77 //- interval_type --------------------------------------------------------------
|
Chris@16
|
78 template<class IntervalMapT>
|
Chris@16
|
79 typename enable_if<mpl::not_<is_total<IntervalMapT> >, bool>::type
|
Chris@16
|
80 contains(const IntervalMapT& container,
|
Chris@16
|
81 const typename IntervalMapT::interval_type& sub_interval)
|
Chris@16
|
82 {
|
Chris@16
|
83 typedef typename IntervalMapT::const_iterator const_iterator;
|
Chris@16
|
84 if(icl::is_empty(sub_interval))
|
Chris@16
|
85 return true;
|
Chris@16
|
86
|
Chris@16
|
87 std::pair<const_iterator, const_iterator> exterior = container.equal_range(sub_interval);
|
Chris@16
|
88 if(exterior.first == exterior.second)
|
Chris@16
|
89 return false;
|
Chris@16
|
90
|
Chris@16
|
91 const_iterator last_overlap = prior(exterior.second);
|
Chris@16
|
92
|
Chris@16
|
93 return
|
Chris@16
|
94 icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
|
Chris@16
|
95 && Interval_Set::is_joinable(container, exterior.first, last_overlap);
|
Chris@16
|
96 }
|
Chris@16
|
97
|
Chris@16
|
98 template<class IntervalMapT>
|
Chris@16
|
99 typename enable_if<is_total<IntervalMapT>, bool>::type
|
Chris@16
|
100 contains(const IntervalMapT&,
|
Chris@16
|
101 const typename IntervalMapT::interval_type&)
|
Chris@16
|
102 {
|
Chris@16
|
103 return true;
|
Chris@16
|
104 }
|
Chris@16
|
105
|
Chris@16
|
106 //- set_type -------------------------------------------------------------------
|
Chris@16
|
107 template<class IntervalMapT, class IntervalSetT>
|
Chris@16
|
108 typename enable_if<mpl::and_<mpl::not_<is_total<IntervalMapT> >
|
Chris@16
|
109 ,is_interval_set<IntervalSetT> >, bool>::type
|
Chris@16
|
110 contains(const IntervalMapT& super_map, const IntervalSetT& sub_set)
|
Chris@16
|
111 {
|
Chris@16
|
112 return Interval_Set::within(sub_set, super_map);
|
Chris@16
|
113 }
|
Chris@16
|
114
|
Chris@16
|
115 template<class IntervalMapT, class IntervalSetT>
|
Chris@16
|
116 typename enable_if<mpl::and_<is_total<IntervalMapT>
|
Chris@16
|
117 ,is_interval_set<IntervalSetT> >, bool>::type
|
Chris@16
|
118 contains(const IntervalMapT&, const IntervalSetT&)
|
Chris@16
|
119 {
|
Chris@16
|
120 return true;
|
Chris@16
|
121 }
|
Chris@16
|
122
|
Chris@16
|
123
|
Chris@16
|
124 //------------------------------------------------------------------------------
|
Chris@16
|
125 //- Containedness of sub objects
|
Chris@16
|
126 //------------------------------------------------------------------------------
|
Chris@16
|
127
|
Chris@16
|
128 template<class IntervalMapT>
|
Chris@16
|
129 bool contains(const IntervalMapT& container,
|
Chris@16
|
130 const typename IntervalMapT::element_type& key_value_pair)
|
Chris@16
|
131 {
|
Chris@16
|
132 typename IntervalMapT::const_iterator it_ = container.find(key_value_pair.key);
|
Chris@16
|
133 return it_ != container.end() && (*it_).second == key_value_pair.data;
|
Chris@16
|
134 }
|
Chris@16
|
135
|
Chris@16
|
136 template<class IntervalMapT>
|
Chris@16
|
137 bool contains(const IntervalMapT& container,
|
Chris@16
|
138 const typename IntervalMapT::segment_type sub_segment)
|
Chris@16
|
139 {
|
Chris@16
|
140 typedef typename IntervalMapT::const_iterator const_iterator;
|
Chris@16
|
141 typename IntervalMapT::interval_type sub_interval = sub_segment.first;
|
Chris@16
|
142 if(icl::is_empty(sub_interval))
|
Chris@16
|
143 return true;
|
Chris@16
|
144
|
Chris@16
|
145 std::pair<const_iterator, const_iterator> exterior = container.equal_range(sub_interval);
|
Chris@16
|
146 if(exterior.first == exterior.second)
|
Chris@16
|
147 return false;
|
Chris@16
|
148
|
Chris@16
|
149 const_iterator last_overlap = prior(exterior.second);
|
Chris@16
|
150
|
Chris@16
|
151 if(!(sub_segment.second == exterior.first->second) )
|
Chris@16
|
152 return false;
|
Chris@16
|
153
|
Chris@16
|
154 return
|
Chris@16
|
155 icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
|
Chris@16
|
156 && Interval_Map::is_joinable(container, exterior.first, last_overlap);
|
Chris@16
|
157 }
|
Chris@16
|
158
|
Chris@16
|
159
|
Chris@16
|
160 template<class IntervalMapT>
|
Chris@16
|
161 bool contains(const IntervalMapT& super, const IntervalMapT& sub)
|
Chris@16
|
162 {
|
Chris@16
|
163 return Interval_Set::within(sub, super);
|
Chris@16
|
164 }
|
Chris@16
|
165
|
Chris@16
|
166 } // namespace Interval_Map
|
Chris@16
|
167
|
Chris@16
|
168 }} // namespace icl boost
|
Chris@16
|
169
|
Chris@16
|
170 #endif
|
Chris@16
|
171
|