Chris@16
|
1 /*-----------------------------------------------------------------------------+
|
Chris@16
|
2 Copyright (c) 2010-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_CONCEPT_INTERVAL_ASSOCIATOR_HPP_JOFA_100920
|
Chris@16
|
9 #define BOOST_ICL_CONCEPT_INTERVAL_ASSOCIATOR_HPP_JOFA_100920
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/icl/type_traits/domain_type_of.hpp>
|
Chris@16
|
12 #include <boost/icl/type_traits/interval_type_of.hpp>
|
Chris@16
|
13 #include <boost/icl/type_traits/is_combinable.hpp>
|
Chris@16
|
14 #include <boost/icl/detail/set_algo.hpp>
|
Chris@16
|
15 #include <boost/icl/detail/map_algo.hpp>
|
Chris@16
|
16 #include <boost/icl/detail/interval_set_algo.hpp>
|
Chris@16
|
17 #include <boost/icl/detail/interval_map_algo.hpp>
|
Chris@16
|
18 #include <boost/icl/concept/interval.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 namespace boost{ namespace icl
|
Chris@16
|
21 {
|
Chris@16
|
22
|
Chris@16
|
23 //==============================================================================
|
Chris@16
|
24 //= Containedness<IntervalSet|IntervalMap>
|
Chris@16
|
25 //==============================================================================
|
Chris@16
|
26 //------------------------------------------------------------------------------
|
Chris@16
|
27 //- bool within(c T&, c P&) T={Set,Map} P={e i b p S M}
|
Chris@16
|
28 //------------------------------------------------------------------------------
|
Chris@16
|
29 template<class SubT, class SuperT>
|
Chris@16
|
30 typename enable_if<is_interval_container<SuperT>, bool>::type
|
Chris@16
|
31 within(const SubT& sub, const SuperT& super)
|
Chris@16
|
32 {
|
Chris@16
|
33 return icl::contains(super, sub);
|
Chris@16
|
34 }
|
Chris@16
|
35
|
Chris@16
|
36 //==============================================================================
|
Chris@16
|
37 //= Equivalences and Orderings<IntervalSet|IntervalMap>
|
Chris@16
|
38 //==============================================================================
|
Chris@16
|
39 template<class Type>
|
Chris@16
|
40 inline typename enable_if<is_interval_container<Type>, bool>::type
|
Chris@16
|
41 operator == (const Type& left, const Type& right)
|
Chris@16
|
42 {
|
Chris@16
|
43 return Set::lexicographical_equal(left, right);
|
Chris@16
|
44 }
|
Chris@16
|
45
|
Chris@16
|
46 template<class Type>
|
Chris@16
|
47 inline typename enable_if<is_interval_container<Type>, bool>::type
|
Chris@16
|
48 operator < (const Type& left, const Type& right)
|
Chris@16
|
49 {
|
Chris@16
|
50 typedef typename Type::segment_compare segment_compare;
|
Chris@16
|
51 return std::lexicographical_compare(
|
Chris@16
|
52 left.begin(), left.end(), right.begin(), right.end(),
|
Chris@16
|
53 segment_compare()
|
Chris@16
|
54 );
|
Chris@16
|
55 }
|
Chris@16
|
56
|
Chris@16
|
57 /** Returns true, if \c left and \c right contain the same elements.
|
Chris@16
|
58 Complexity: linear. */
|
Chris@16
|
59 template<class LeftT, class RightT>
|
Chris@16
|
60 typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type
|
Chris@16
|
61 is_element_equal(const LeftT& left, const RightT& right)
|
Chris@16
|
62 {
|
Chris@16
|
63 return Interval_Set::is_element_equal(left, right);
|
Chris@16
|
64 }
|
Chris@16
|
65
|
Chris@16
|
66 /** Returns true, if \c left is lexicographically less than \c right.
|
Chris@16
|
67 Intervals are interpreted as sequence of elements.
|
Chris@16
|
68 Complexity: linear. */
|
Chris@16
|
69 template<class LeftT, class RightT>
|
Chris@16
|
70 typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type
|
Chris@16
|
71 is_element_less(const LeftT& left, const RightT& right)
|
Chris@16
|
72 {
|
Chris@16
|
73 return Interval_Set::is_element_less(left, right);
|
Chris@16
|
74 }
|
Chris@16
|
75
|
Chris@16
|
76 /** Returns true, if \c left is lexicographically greater than \c right.
|
Chris@16
|
77 Intervals are interpreted as sequence of elements.
|
Chris@16
|
78 Complexity: linear. */
|
Chris@16
|
79 template<class LeftT, class RightT>
|
Chris@16
|
80 typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type
|
Chris@16
|
81 is_element_greater(const LeftT& left, const RightT& right)
|
Chris@16
|
82 {
|
Chris@16
|
83 return Interval_Set::is_element_greater(left, right);
|
Chris@16
|
84 }
|
Chris@16
|
85
|
Chris@16
|
86 //------------------------------------------------------------------------------
|
Chris@16
|
87 template<class LeftT, class RightT>
|
Chris@16
|
88 typename enable_if<is_inter_combinable<LeftT, RightT>, int>::type
|
Chris@16
|
89 inclusion_compare(const LeftT& left, const RightT& right)
|
Chris@16
|
90 {
|
Chris@16
|
91 return Interval_Set::subset_compare(left, right,
|
Chris@16
|
92 left.begin(), left.end(),
|
Chris@16
|
93 right.begin(), right.end());
|
Chris@16
|
94 }
|
Chris@16
|
95
|
Chris@16
|
96 //------------------------------------------------------------------------------
|
Chris@16
|
97 template<class LeftT, class RightT>
|
Chris@16
|
98 typename enable_if< is_concept_compatible<is_interval_map, LeftT, RightT>,
|
Chris@16
|
99 bool >::type
|
Chris@16
|
100 is_distinct_equal(const LeftT& left, const RightT& right)
|
Chris@16
|
101 {
|
Chris@16
|
102 return Map::lexicographical_distinct_equal(left, right);
|
Chris@16
|
103 }
|
Chris@16
|
104
|
Chris@16
|
105 //==============================================================================
|
Chris@16
|
106 //= Size<IntervalSet|IntervalMap>
|
Chris@16
|
107 //==============================================================================
|
Chris@16
|
108 template<class Type>
|
Chris@16
|
109 typename enable_if<is_interval_container<Type>, std::size_t>::type
|
Chris@16
|
110 iterative_size(const Type& object)
|
Chris@16
|
111 {
|
Chris@16
|
112 return object.iterative_size();
|
Chris@16
|
113 }
|
Chris@16
|
114
|
Chris@16
|
115 template<class Type>
|
Chris@16
|
116 typename enable_if
|
Chris@16
|
117 < mpl::and_< is_interval_container<Type>
|
Chris@16
|
118 , is_discrete<typename Type::domain_type> >
|
Chris@16
|
119 , typename Type::size_type
|
Chris@16
|
120 >::type
|
Chris@16
|
121 cardinality(const Type& object)
|
Chris@16
|
122 {
|
Chris@16
|
123 typedef typename Type::size_type size_type;
|
Chris@16
|
124 typedef typename Type::interval_type interval_type;
|
Chris@16
|
125
|
Chris@16
|
126 size_type size = identity_element<size_type>::value();
|
Chris@16
|
127 ICL_const_FORALL(typename Type, it, object)
|
Chris@16
|
128 size += icl::cardinality(key_value<Type>(it));
|
Chris@16
|
129 return size;
|
Chris@16
|
130
|
Chris@16
|
131 }
|
Chris@16
|
132
|
Chris@16
|
133 template<class Type>
|
Chris@16
|
134 typename enable_if
|
Chris@16
|
135 < mpl::and_< is_interval_container<Type>
|
Chris@16
|
136 , mpl::not_<is_discrete<typename Type::domain_type> > >
|
Chris@16
|
137 , typename Type::size_type
|
Chris@16
|
138 >::type
|
Chris@16
|
139 cardinality(const Type& object)
|
Chris@16
|
140 {
|
Chris@16
|
141 typedef typename Type::size_type size_type;
|
Chris@16
|
142 typedef typename Type::interval_type interval_type;
|
Chris@16
|
143
|
Chris@16
|
144 size_type size = identity_element<size_type>::value();
|
Chris@16
|
145 size_type interval_size;
|
Chris@16
|
146 ICL_const_FORALL(typename Type, it, object)
|
Chris@16
|
147 {
|
Chris@16
|
148 interval_size = icl::cardinality(key_value<Type>(it));
|
Chris@16
|
149 if(interval_size == icl::infinity<size_type>::value())
|
Chris@16
|
150 return interval_size;
|
Chris@16
|
151 else
|
Chris@16
|
152 size += interval_size;
|
Chris@16
|
153 }
|
Chris@16
|
154 return size;
|
Chris@16
|
155 }
|
Chris@16
|
156
|
Chris@16
|
157 template<class Type>
|
Chris@16
|
158 inline typename enable_if<is_interval_container<Type>, typename Type::size_type>::type
|
Chris@16
|
159 size(const Type& object)
|
Chris@16
|
160 {
|
Chris@16
|
161 return icl::cardinality(object);
|
Chris@16
|
162 }
|
Chris@16
|
163
|
Chris@16
|
164 template<class Type>
|
Chris@16
|
165 typename enable_if<is_interval_container<Type>, typename Type::difference_type>::type
|
Chris@16
|
166 length(const Type& object)
|
Chris@16
|
167 {
|
Chris@16
|
168 typedef typename Type::difference_type difference_type;
|
Chris@16
|
169 typedef typename Type::const_iterator const_iterator;
|
Chris@16
|
170 difference_type length = identity_element<difference_type>::value();
|
Chris@16
|
171 const_iterator it_ = object.begin();
|
Chris@16
|
172
|
Chris@16
|
173 while(it_ != object.end())
|
Chris@16
|
174 length += icl::length(key_value<Type>(it_++));
|
Chris@16
|
175 return length;
|
Chris@16
|
176 }
|
Chris@16
|
177
|
Chris@16
|
178 template<class Type>
|
Chris@16
|
179 typename enable_if<is_interval_container<Type>, std::size_t>::type
|
Chris@16
|
180 interval_count(const Type& object)
|
Chris@16
|
181 {
|
Chris@16
|
182 return icl::iterative_size(object);
|
Chris@16
|
183 }
|
Chris@16
|
184
|
Chris@16
|
185
|
Chris@16
|
186 template<class Type>
|
Chris@16
|
187 typename enable_if< is_interval_container<Type>
|
Chris@16
|
188 , typename Type::difference_type >::type
|
Chris@16
|
189 distance(const Type& object)
|
Chris@16
|
190 {
|
Chris@16
|
191 typedef typename Type::difference_type DiffT;
|
Chris@16
|
192 typedef typename Type::const_iterator const_iterator;
|
Chris@16
|
193 const_iterator it_ = object.begin(), pred_;
|
Chris@16
|
194 DiffT dist = identity_element<DiffT>::value();
|
Chris@16
|
195
|
Chris@16
|
196 if(it_ != object.end())
|
Chris@16
|
197 pred_ = it_++;
|
Chris@16
|
198
|
Chris@16
|
199 while(it_ != object.end())
|
Chris@16
|
200 dist += icl::distance(key_value<Type>(pred_++), key_value<Type>(it_++));
|
Chris@16
|
201
|
Chris@16
|
202 return dist;
|
Chris@16
|
203 }
|
Chris@16
|
204
|
Chris@16
|
205 //==============================================================================
|
Chris@16
|
206 //= Range<IntervalSet|IntervalMap>
|
Chris@16
|
207 //==============================================================================
|
Chris@16
|
208 template<class Type>
|
Chris@16
|
209 typename enable_if<is_interval_container<Type>,
|
Chris@16
|
210 typename Type::interval_type>::type
|
Chris@16
|
211 hull(const Type& object)
|
Chris@16
|
212 {
|
Chris@16
|
213 return
|
Chris@16
|
214 icl::is_empty(object)
|
Chris@16
|
215 ? identity_element<typename Type::interval_type>::value()
|
Chris@16
|
216 : icl::hull( key_value<Type>(object.begin()),
|
Chris@16
|
217 key_value<Type>(object.rbegin()) );
|
Chris@16
|
218 }
|
Chris@16
|
219
|
Chris@16
|
220 template<class Type>
|
Chris@16
|
221 typename enable_if<is_interval_container<Type>,
|
Chris@16
|
222 typename domain_type_of<Type>::type>::type
|
Chris@16
|
223 lower(const Type& object)
|
Chris@16
|
224 {
|
Chris@16
|
225 typedef typename domain_type_of<Type>::type DomainT;
|
Chris@16
|
226 return
|
Chris@16
|
227 icl::is_empty(object)
|
Chris@16
|
228 ? unit_element<DomainT>::value()
|
Chris@16
|
229 : icl::lower( key_value<Type>(object.begin()) );
|
Chris@16
|
230 }
|
Chris@16
|
231
|
Chris@16
|
232 template<class Type>
|
Chris@16
|
233 typename enable_if<is_interval_container<Type>,
|
Chris@16
|
234 typename domain_type_of<Type>::type>::type
|
Chris@16
|
235 upper(const Type& object)
|
Chris@16
|
236 {
|
Chris@16
|
237 typedef typename domain_type_of<Type>::type DomainT;
|
Chris@16
|
238 return
|
Chris@16
|
239 icl::is_empty(object)
|
Chris@16
|
240 ? identity_element<DomainT>::value()
|
Chris@16
|
241 : icl::upper( key_value<Type>(object.rbegin()) );
|
Chris@16
|
242 }
|
Chris@16
|
243
|
Chris@16
|
244 //------------------------------------------------------------------------------
|
Chris@16
|
245 template<class Type>
|
Chris@16
|
246 typename enable_if
|
Chris@16
|
247 < mpl::and_< is_interval_container<Type>
|
Chris@16
|
248 , is_discrete<typename domain_type_of<Type>::type> >
|
Chris@16
|
249 , typename domain_type_of<Type>::type>::type
|
Chris@16
|
250 first(const Type& object)
|
Chris@16
|
251 {
|
Chris@16
|
252 typedef typename domain_type_of<Type>::type DomainT;
|
Chris@16
|
253 return
|
Chris@16
|
254 icl::is_empty(object)
|
Chris@16
|
255 ? unit_element<DomainT>::value()
|
Chris@16
|
256 : icl::first( key_value<Type>(object.begin()) );
|
Chris@16
|
257 }
|
Chris@16
|
258
|
Chris@16
|
259 template<class Type>
|
Chris@16
|
260 typename enable_if
|
Chris@16
|
261 < mpl::and_< is_interval_container<Type>
|
Chris@16
|
262 , is_discrete<typename domain_type_of<Type>::type> >
|
Chris@16
|
263 , typename domain_type_of<Type>::type>::type
|
Chris@16
|
264 last(const Type& object)
|
Chris@16
|
265 {
|
Chris@16
|
266 typedef typename domain_type_of<Type>::type DomainT;
|
Chris@16
|
267 return
|
Chris@16
|
268 icl::is_empty(object)
|
Chris@16
|
269 ? identity_element<DomainT>::value()
|
Chris@16
|
270 : icl::last( key_value<Type>(object.rbegin()) );
|
Chris@16
|
271 }
|
Chris@16
|
272
|
Chris@16
|
273
|
Chris@16
|
274 //==============================================================================
|
Chris@16
|
275 //= Addition<IntervalSet|IntervalMap>
|
Chris@16
|
276 //==============================================================================
|
Chris@16
|
277 //------------------------------------------------------------------------------
|
Chris@16
|
278 //- T& op +=(T&, c P&) T:{S}|{M} P:{e i}|{b p}
|
Chris@16
|
279 //------------------------------------------------------------------------------
|
Chris@16
|
280 /* \par \b Requires: \c OperandT is an addable derivative type of \c Type.
|
Chris@16
|
281 \b Effects: \c operand is added to \c object.
|
Chris@16
|
282 \par \b Returns: A reference to \c object.
|
Chris@16
|
283 \b Complexity:
|
Chris@16
|
284 \code
|
Chris@16
|
285 \ OperandT:
|
Chris@16
|
286 \ element segment
|
Chris@16
|
287 Type:
|
Chris@16
|
288 interval container O(log n) O(n)
|
Chris@16
|
289
|
Chris@16
|
290 interval_set amortized
|
Chris@16
|
291 spearate_interval_set O(log n)
|
Chris@16
|
292
|
Chris@16
|
293 n = object.interval_count()
|
Chris@16
|
294 \endcode
|
Chris@16
|
295
|
Chris@16
|
296 For the addition of \b elements or \b segments
|
Chris@16
|
297 complexity is \b logarithmic or \b linear respectively.
|
Chris@16
|
298 For \c interval_sets and \c separate_interval_sets addition of segments
|
Chris@16
|
299 is \b amortized \b logarithmic.
|
Chris@16
|
300 */
|
Chris@16
|
301 template<class Type, class OperandT>
|
Chris@16
|
302 typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type&
|
Chris@16
|
303 operator += (Type& object, const OperandT& operand)
|
Chris@16
|
304 {
|
Chris@16
|
305 return icl::add(object, operand);
|
Chris@16
|
306 }
|
Chris@16
|
307
|
Chris@16
|
308
|
Chris@16
|
309 //------------------------------------------------------------------------------
|
Chris@16
|
310 //- T& op +=(T&, c P&) T:{S}|{M} P:{S'}|{M'}
|
Chris@16
|
311 //------------------------------------------------------------------------------
|
Chris@16
|
312 /** \par \b Requires: \c OperandT is an interval container addable to \c Type.
|
Chris@16
|
313 \b Effects: \c operand is added to \c object.
|
Chris@16
|
314 \par \b Returns: A reference to \c object.
|
Chris@16
|
315 \b Complexity: loglinear */
|
Chris@16
|
316 template<class Type, class OperandT>
|
Chris@16
|
317 typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type&
|
Chris@16
|
318 operator += (Type& object, const OperandT& operand)
|
Chris@16
|
319 {
|
Chris@16
|
320 typename Type::iterator prior_ = object.end();
|
Chris@16
|
321 ICL_const_FORALL(typename OperandT, elem_, operand)
|
Chris@16
|
322 prior_ = icl::add(object, prior_, *elem_);
|
Chris@16
|
323
|
Chris@16
|
324 return object;
|
Chris@16
|
325 }
|
Chris@16
|
326
|
Chris@16
|
327
|
Chris@16
|
328 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
329 //------------------------------------------------------------------------------
|
Chris@16
|
330 //- T op + (T, c P&) T:{S}|{M} P:{e i S}|{b p M}
|
Chris@16
|
331 //------------------------------------------------------------------------------
|
Chris@16
|
332 /** \par \b Requires: \c object and \c operand are addable.
|
Chris@16
|
333 \b Effects: \c operand is added to \c object.
|
Chris@16
|
334 \par \b Efficieny: There is one additional copy of
|
Chris@16
|
335 \c Type \c object compared to inplace \c operator \c += */
|
Chris@16
|
336 template<class Type, class OperandT>
|
Chris@16
|
337 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
338 operator + (Type object, const OperandT& operand)
|
Chris@16
|
339 {
|
Chris@16
|
340 return object += operand;
|
Chris@16
|
341 }
|
Chris@16
|
342
|
Chris@16
|
343 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
344
|
Chris@16
|
345 template<class Type, class OperandT>
|
Chris@16
|
346 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
347 operator + (const Type& object, const OperandT& operand)
|
Chris@16
|
348 {
|
Chris@16
|
349 Type temp = object;
|
Chris@16
|
350 return boost::move(temp += operand);
|
Chris@16
|
351 }
|
Chris@16
|
352
|
Chris@16
|
353 template<class Type, class OperandT>
|
Chris@16
|
354 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
355 operator + (Type&& object, const OperandT& operand)
|
Chris@16
|
356 {
|
Chris@16
|
357 return boost::move(object += operand);
|
Chris@16
|
358 }
|
Chris@16
|
359
|
Chris@16
|
360 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
361
|
Chris@16
|
362 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
363 //------------------------------------------------------------------------------
|
Chris@16
|
364 //- T op + (c P&, T) T:{S}|{M} P:{e i S'}|{b p M'}
|
Chris@16
|
365 //------------------------------------------------------------------------------
|
Chris@16
|
366 /** \par \b Requires: \c object and \c operand are addable.
|
Chris@16
|
367 \b Effects: \c operand is added to \c object.
|
Chris@16
|
368 \par \b Efficieny: There is one additional copy of
|
Chris@16
|
369 \c Type \c object compared to inplace \c operator \c += */
|
Chris@16
|
370 template<class Type, class OperandT>
|
Chris@16
|
371 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
372 operator + (const OperandT& operand, Type object)
|
Chris@16
|
373 {
|
Chris@16
|
374 return object += operand;
|
Chris@16
|
375 }
|
Chris@16
|
376
|
Chris@16
|
377 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
378
|
Chris@16
|
379 template<class Type, class OperandT>
|
Chris@16
|
380 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
381 operator + (const OperandT& operand, const Type& object)
|
Chris@16
|
382 {
|
Chris@16
|
383 Type temp = object;
|
Chris@16
|
384 return boost::move(temp += operand);
|
Chris@16
|
385 }
|
Chris@16
|
386
|
Chris@16
|
387 template<class Type, class OperandT>
|
Chris@16
|
388 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
389 operator + (const OperandT& operand, Type&& object)
|
Chris@16
|
390 {
|
Chris@16
|
391 return boost::move(object += operand);
|
Chris@16
|
392 }
|
Chris@16
|
393
|
Chris@16
|
394 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
395
|
Chris@16
|
396 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
397 //------------------------------------------------------------------------------
|
Chris@16
|
398 //- T op + (T, c P&) T:{S}|{M} P:{S}|{M}
|
Chris@16
|
399 //------------------------------------------------------------------------------
|
Chris@16
|
400 /** \par \b Requires: \c object and \c operand are addable.
|
Chris@16
|
401 \b Effects: \c operand is added to \c object.
|
Chris@16
|
402 \par \b Efficieny: There is one additional copy of
|
Chris@16
|
403 \c Type \c object compared to inplace \c operator \c += */
|
Chris@16
|
404 template<class Type>
|
Chris@16
|
405 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
406 operator + (Type object, const Type& operand)
|
Chris@16
|
407 {
|
Chris@16
|
408 return object += operand;
|
Chris@16
|
409 }
|
Chris@16
|
410
|
Chris@16
|
411 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
412
|
Chris@16
|
413 template<class Type>
|
Chris@16
|
414 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
415 operator + (const Type& object, const Type& operand)
|
Chris@16
|
416 {
|
Chris@16
|
417 Type temp = object;
|
Chris@16
|
418 return boost::move(temp += operand);
|
Chris@16
|
419 }
|
Chris@16
|
420
|
Chris@16
|
421 template<class Type>
|
Chris@16
|
422 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
423 operator + (Type&& object, const Type& operand)
|
Chris@16
|
424 {
|
Chris@16
|
425 return boost::move(object += operand);
|
Chris@16
|
426 }
|
Chris@16
|
427
|
Chris@16
|
428 template<class Type>
|
Chris@16
|
429 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
430 operator + (const Type& operand, Type&& object)
|
Chris@16
|
431 {
|
Chris@16
|
432 return boost::move(object += operand);
|
Chris@16
|
433 }
|
Chris@16
|
434
|
Chris@16
|
435 template<class Type>
|
Chris@16
|
436 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
437 operator + (Type&& object, Type&& operand)
|
Chris@16
|
438 {
|
Chris@16
|
439 return boost::move(object += operand);
|
Chris@16
|
440 }
|
Chris@16
|
441
|
Chris@16
|
442 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
443
|
Chris@16
|
444 //------------------------------------------------------------------------------
|
Chris@16
|
445 //- Addition |=, |
|
Chris@16
|
446 //------------------------------------------------------------------------------
|
Chris@16
|
447
|
Chris@16
|
448 //------------------------------------------------------------------------------
|
Chris@16
|
449 //- T& op |=(c P&) T:{S}|{M} P:{e i}|{b p}
|
Chris@16
|
450 //------------------------------------------------------------------------------
|
Chris@16
|
451 /** \par \b Requires: Types \c Type and \c OperandT are addable.
|
Chris@16
|
452 \par \b Effects: \c operand is added to \c object.
|
Chris@16
|
453 \par \b Returns: A reference to \c object.
|
Chris@16
|
454 \b Complexity:
|
Chris@16
|
455 \code
|
Chris@16
|
456 \ OperandT: interval
|
Chris@16
|
457 \ element segment container
|
Chris@16
|
458 Type:
|
Chris@16
|
459 interval container O(log n) O(n) O(m log(n+m))
|
Chris@16
|
460
|
Chris@16
|
461 interval_set amortized
|
Chris@16
|
462 spearate_interval_set O(log n)
|
Chris@16
|
463
|
Chris@16
|
464 n = object.interval_count()
|
Chris@16
|
465 m = operand.interval_count()
|
Chris@16
|
466 \endcode
|
Chris@16
|
467
|
Chris@16
|
468 For the addition of \b elements, \b segments and \b interval \b containers
|
Chris@16
|
469 complexity is \b logarithmic, \b linear and \b loglinear respectively.
|
Chris@16
|
470 For \c interval_sets and \c separate_interval_sets addition of segments
|
Chris@16
|
471 is \b amortized \b logarithmic.
|
Chris@16
|
472 */
|
Chris@16
|
473 template<class Type, class OperandT>
|
Chris@16
|
474 typename enable_if<is_right_intra_combinable<Type, OperandT>, Type>::type&
|
Chris@16
|
475 operator |= (Type& object, const OperandT& operand)
|
Chris@16
|
476 {
|
Chris@16
|
477 return object += operand;
|
Chris@16
|
478 }
|
Chris@16
|
479
|
Chris@16
|
480 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
481 //------------------------------------------------------------------------------
|
Chris@16
|
482 //- T op | (T, c P&) T:{S}|{M} P:{e i S}|{b p M}
|
Chris@16
|
483 //------------------------------------------------------------------------------
|
Chris@16
|
484 /** \par \b Requires: \c object and \c operand are addable.
|
Chris@16
|
485 \b Effects: \c operand is added to \c object.
|
Chris@16
|
486 \par \b Efficieny: There is one additional copy of
|
Chris@16
|
487 \c Type \c object compared to inplace \c operator \c |= */
|
Chris@16
|
488 template<class Type, class OperandT>
|
Chris@16
|
489 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
490 operator | (Type object, const OperandT& operand)
|
Chris@16
|
491 {
|
Chris@16
|
492 return object += operand;
|
Chris@16
|
493 }
|
Chris@16
|
494
|
Chris@16
|
495 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
496
|
Chris@16
|
497 template<class Type, class OperandT>
|
Chris@16
|
498 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
499 operator | (const Type& object, const OperandT& operand)
|
Chris@16
|
500 {
|
Chris@16
|
501 Type temp = object;
|
Chris@16
|
502 return boost::move(temp += operand);
|
Chris@16
|
503 }
|
Chris@16
|
504
|
Chris@16
|
505 template<class Type, class OperandT>
|
Chris@16
|
506 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
507 operator | (Type&& object, const OperandT& operand)
|
Chris@16
|
508 {
|
Chris@16
|
509 return boost::move(object += operand);
|
Chris@16
|
510 }
|
Chris@16
|
511
|
Chris@16
|
512 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
513
|
Chris@16
|
514 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
515 //------------------------------------------------------------------------------
|
Chris@16
|
516 //- T op | (T, c P&) T:{S}|{M} P:{S}|{M}
|
Chris@16
|
517 //------------------------------------------------------------------------------
|
Chris@16
|
518 /** \par \b Requires: \c object and \c operand are addable.
|
Chris@16
|
519 \b Effects: \c operand is added to \c object.
|
Chris@16
|
520 \par \b Efficieny: There is one additional copy of
|
Chris@16
|
521 \c Type \c object compared to inplace \c operator \c |= */
|
Chris@16
|
522 template<class Type, class OperandT>
|
Chris@16
|
523 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
524 operator | (const OperandT& operand, Type object)
|
Chris@16
|
525 {
|
Chris@16
|
526 return object += operand;
|
Chris@16
|
527 }
|
Chris@16
|
528
|
Chris@16
|
529 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
530
|
Chris@16
|
531 template<class Type, class OperandT>
|
Chris@16
|
532 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
533 operator | (const OperandT& operand, const Type& object)
|
Chris@16
|
534 {
|
Chris@16
|
535 Type temp = object;
|
Chris@16
|
536 return boost::move(temp += operand);
|
Chris@16
|
537 }
|
Chris@16
|
538
|
Chris@16
|
539 template<class Type, class OperandT>
|
Chris@16
|
540 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
541 operator | (const OperandT& operand, Type&& object)
|
Chris@16
|
542 {
|
Chris@16
|
543 return boost::move(object += operand);
|
Chris@16
|
544 }
|
Chris@16
|
545
|
Chris@16
|
546 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
547
|
Chris@16
|
548 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
549 //------------------------------------------------------------------------------
|
Chris@16
|
550 //- T op | (T, c P&) T:{S}|{M} P:{S}|{M}
|
Chris@16
|
551 //------------------------------------------------------------------------------
|
Chris@16
|
552 /** \par \b Requires: \c object and \c operand are addable.
|
Chris@16
|
553 \b Effects: \c operand is added to \c object.
|
Chris@16
|
554 \par \b Efficieny: There is one additional copy of
|
Chris@16
|
555 \c Type \c object compared to inplace \c operator \c |= */
|
Chris@16
|
556 template<class Type>
|
Chris@16
|
557 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
558 operator | (Type object, const Type& operand)
|
Chris@16
|
559 {
|
Chris@16
|
560 return object += operand;
|
Chris@16
|
561 }
|
Chris@16
|
562 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
563
|
Chris@16
|
564 template<class Type>
|
Chris@16
|
565 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
566 operator | (const Type& object, const Type& operand)
|
Chris@16
|
567 {
|
Chris@16
|
568 Type temp = object;
|
Chris@16
|
569 return boost::move(temp += operand);
|
Chris@16
|
570 }
|
Chris@16
|
571
|
Chris@16
|
572 template<class Type>
|
Chris@16
|
573 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
574 operator | (Type&& object, const Type& operand)
|
Chris@16
|
575 {
|
Chris@16
|
576 return boost::move(object += operand);
|
Chris@16
|
577 }
|
Chris@16
|
578
|
Chris@16
|
579 template<class Type>
|
Chris@16
|
580 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
581 operator | (const Type& operand, Type&& object)
|
Chris@16
|
582 {
|
Chris@16
|
583 return boost::move(object += operand);
|
Chris@16
|
584 }
|
Chris@16
|
585
|
Chris@16
|
586 template<class Type>
|
Chris@16
|
587 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
588 operator | (Type&& object, Type&& operand)
|
Chris@16
|
589 {
|
Chris@16
|
590 return boost::move(object += operand);
|
Chris@16
|
591 }
|
Chris@16
|
592
|
Chris@16
|
593 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
594
|
Chris@16
|
595
|
Chris@16
|
596 //==============================================================================
|
Chris@16
|
597 //= Insertion<IntervalSet|IntervalSet>
|
Chris@16
|
598 //==============================================================================
|
Chris@16
|
599 //------------------------------------------------------------------------------
|
Chris@16
|
600 //- T& insert(T&, c P&) T:{S}|{M} P:{S'}|{M'}
|
Chris@16
|
601 //------------------------------------------------------------------------------
|
Chris@16
|
602 template<class Type, class OperandT>
|
Chris@16
|
603 typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type&
|
Chris@16
|
604 insert(Type& object, const OperandT& operand)
|
Chris@16
|
605 {
|
Chris@16
|
606 typename Type::iterator prior_ = object.end();
|
Chris@16
|
607 ICL_const_FORALL(typename OperandT, elem_, operand)
|
Chris@16
|
608 insert(object, prior_, *elem_);
|
Chris@16
|
609
|
Chris@16
|
610 return object;
|
Chris@16
|
611 }
|
Chris@16
|
612
|
Chris@16
|
613 //==============================================================================
|
Chris@16
|
614 //= Erasure<IntervalSet|IntervalSet>
|
Chris@16
|
615 //==============================================================================
|
Chris@16
|
616 //------------------------------------------------------------------------------
|
Chris@16
|
617 //- T& erase(T&, c P&) T:{S}|{M} P:{S'}|{S' M'}
|
Chris@16
|
618 //------------------------------------------------------------------------------
|
Chris@16
|
619 template<class Type, class OperandT>
|
Chris@16
|
620 typename enable_if<combines_right_to_interval_container<Type, OperandT>,
|
Chris@16
|
621 Type>::type&
|
Chris@16
|
622 erase(Type& object, const OperandT& operand)
|
Chris@16
|
623 {
|
Chris@16
|
624 typedef typename OperandT::const_iterator const_iterator;
|
Chris@16
|
625
|
Chris@16
|
626 if(icl::is_empty(operand))
|
Chris@16
|
627 return object;
|
Chris@16
|
628
|
Chris@16
|
629 const_iterator common_lwb, common_upb;
|
Chris@16
|
630 if(!Set::common_range(common_lwb, common_upb, operand, object))
|
Chris@16
|
631 return object;
|
Chris@16
|
632
|
Chris@16
|
633 const_iterator it_ = common_lwb;
|
Chris@16
|
634 while(it_ != common_upb)
|
Chris@16
|
635 icl::erase(object, *it_++);
|
Chris@16
|
636
|
Chris@16
|
637 return object;
|
Chris@16
|
638 }
|
Chris@16
|
639
|
Chris@16
|
640 //==============================================================================
|
Chris@16
|
641 //= Subtraction<IntervalSet|IntervalSet>
|
Chris@16
|
642 //==============================================================================
|
Chris@16
|
643 //------------------------------------------------------------------------------
|
Chris@16
|
644 //- T& op -= (c P&) T:{M} P:{M'}
|
Chris@16
|
645 //------------------------------------------------------------------------------
|
Chris@16
|
646 /** \par \b Requires: Types \c Type and \c OperandT are subtractable.
|
Chris@16
|
647 \par \b Effects: \c operand is subtracted from \c object.
|
Chris@16
|
648 \par \b Returns: A reference to \c object.
|
Chris@16
|
649 \b Complexity:
|
Chris@16
|
650 \code
|
Chris@16
|
651 \ OperandT: interval
|
Chris@16
|
652 \ element segment container
|
Chris@16
|
653 Type:
|
Chris@16
|
654 interval container O(log n) O(n) O(m log(n+m))
|
Chris@16
|
655
|
Chris@16
|
656 amortized
|
Chris@16
|
657 interval_sets O(log n)
|
Chris@16
|
658
|
Chris@16
|
659 n = object.interval_count()
|
Chris@16
|
660 m = operand.interval_count()
|
Chris@16
|
661 \endcode
|
Chris@16
|
662
|
Chris@16
|
663 For the subtraction of \em elements, \b segments and \b interval \b containers
|
Chris@16
|
664 complexity is \b logarithmic, \b linear and \b loglinear respectively.
|
Chris@16
|
665 For interval sets subtraction of segments
|
Chris@16
|
666 is \b amortized \b logarithmic.
|
Chris@16
|
667 */
|
Chris@16
|
668 template<class Type, class OperandT>
|
Chris@16
|
669 typename enable_if<is_concept_compatible<is_interval_map, Type, OperandT>,
|
Chris@16
|
670 Type>::type&
|
Chris@16
|
671 operator -=(Type& object, const OperandT& operand)
|
Chris@16
|
672 {
|
Chris@16
|
673 ICL_const_FORALL(typename OperandT, elem_, operand)
|
Chris@16
|
674 icl::subtract(object, *elem_);
|
Chris@16
|
675
|
Chris@16
|
676 return object;
|
Chris@16
|
677 }
|
Chris@16
|
678
|
Chris@16
|
679 //------------------------------------------------------------------------------
|
Chris@16
|
680 //- T& op -= (c P&) T:{S}|{M} P:{e i}|{b p}
|
Chris@16
|
681 //------------------------------------------------------------------------------
|
Chris@16
|
682 template<class Type, class OperandT>
|
Chris@16
|
683 typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type&
|
Chris@16
|
684 operator -= (Type& object, const OperandT& operand)
|
Chris@16
|
685 {
|
Chris@16
|
686 return icl::subtract(object, operand);
|
Chris@16
|
687 }
|
Chris@16
|
688
|
Chris@16
|
689 //------------------------------------------------------------------------------
|
Chris@16
|
690 //- T& op -= (c P&) T:{M} P:{e i}
|
Chris@16
|
691 //------------------------------------------------------------------------------
|
Chris@16
|
692 template<class Type, class OperandT>
|
Chris@16
|
693 typename enable_if<is_cross_derivative<Type, OperandT>, Type>::type&
|
Chris@16
|
694 operator -= (Type& object, const OperandT& operand)
|
Chris@16
|
695 {
|
Chris@16
|
696 return icl::erase(object, operand);
|
Chris@16
|
697 }
|
Chris@16
|
698
|
Chris@16
|
699 //------------------------------------------------------------------------------
|
Chris@16
|
700 //- T& op -= (c P&) T:{S M} P:{S'}
|
Chris@16
|
701 //------------------------------------------------------------------------------
|
Chris@16
|
702 template<class Type, class IntervalSetT>
|
Chris@16
|
703 typename enable_if<combines_right_to_interval_set<Type, IntervalSetT>,
|
Chris@16
|
704 Type>::type&
|
Chris@16
|
705 operator -= (Type& object, const IntervalSetT& operand)
|
Chris@16
|
706 {
|
Chris@16
|
707 return erase(object, operand);
|
Chris@16
|
708 }
|
Chris@16
|
709
|
Chris@16
|
710 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
711 //------------------------------------------------------------------------------
|
Chris@16
|
712 //- T op - (T, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'}
|
Chris@16
|
713 //------------------------------------------------------------------------------
|
Chris@16
|
714 template<class Type, class OperandT>
|
Chris@16
|
715 typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
716 operator - (Type object, const OperandT& operand)
|
Chris@16
|
717 {
|
Chris@16
|
718 return object -= operand;
|
Chris@16
|
719 }
|
Chris@16
|
720
|
Chris@16
|
721 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
722
|
Chris@16
|
723 template<class Type, class OperandT>
|
Chris@16
|
724 typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
725 operator - (const Type& object, const OperandT& operand)
|
Chris@16
|
726 {
|
Chris@16
|
727 Type temp = object;
|
Chris@16
|
728 return boost::move(temp -= operand);
|
Chris@16
|
729 }
|
Chris@16
|
730
|
Chris@16
|
731 template<class Type, class OperandT>
|
Chris@16
|
732 typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
733 operator - (Type&& object, const OperandT& operand)
|
Chris@16
|
734 {
|
Chris@16
|
735 return boost::move(object -= operand);
|
Chris@16
|
736 }
|
Chris@16
|
737
|
Chris@16
|
738 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
739
|
Chris@16
|
740 //==============================================================================
|
Chris@16
|
741 //= Intersection<IntervalSet|IntervalSet>
|
Chris@16
|
742 //==============================================================================
|
Chris@16
|
743 //------------------------------------------------------------------------------
|
Chris@16
|
744 //- void add_intersection(T&, c T&, c P&) T:{S M} P:{S'}
|
Chris@16
|
745 //------------------------------------------------------------------------------
|
Chris@16
|
746 template<class Type, class OperandT>
|
Chris@16
|
747 typename enable_if<mpl::and_<is_interval_set<Type>,
|
Chris@16
|
748 combines_right_to_interval_set<Type, OperandT> >,
|
Chris@16
|
749 void>::type
|
Chris@16
|
750 add_intersection(Type& section, const Type& object, const OperandT& operand)
|
Chris@16
|
751 {
|
Chris@16
|
752 typedef typename OperandT::const_iterator const_iterator;
|
Chris@16
|
753
|
Chris@16
|
754 if(operand.empty())
|
Chris@16
|
755 return;
|
Chris@16
|
756
|
Chris@16
|
757 const_iterator common_lwb, common_upb;
|
Chris@16
|
758 if(!Set::common_range(common_lwb, common_upb, operand, object))
|
Chris@16
|
759 return;
|
Chris@16
|
760
|
Chris@16
|
761 const_iterator it_ = common_lwb;
|
Chris@16
|
762 while(it_ != common_upb)
|
Chris@16
|
763 icl::add_intersection(section, object, key_value<OperandT>(it_++));
|
Chris@16
|
764 }
|
Chris@16
|
765
|
Chris@16
|
766 //------------------------------------------------------------------------------
|
Chris@16
|
767 //- T& op &=(T&, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'}
|
Chris@16
|
768 //------------------------------------------------------------------------------
|
Chris@16
|
769 template<class Type, class OperandT>
|
Chris@16
|
770 typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type&
|
Chris@16
|
771 operator &= (Type& object, const OperandT& operand)
|
Chris@16
|
772 {
|
Chris@16
|
773 Type intersection;
|
Chris@16
|
774 add_intersection(intersection, object, operand);
|
Chris@16
|
775 object.swap(intersection);
|
Chris@16
|
776 return object;
|
Chris@16
|
777 }
|
Chris@16
|
778
|
Chris@16
|
779 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
780 //------------------------------------------------------------------------------
|
Chris@16
|
781 //- T op & (T, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'} S<S' M<M' <:coarser
|
Chris@16
|
782 //------------------------------------------------------------------------------
|
Chris@16
|
783 template<class Type, class OperandT>
|
Chris@16
|
784 typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
785 operator & (Type object, const OperandT& operand)
|
Chris@16
|
786 {
|
Chris@16
|
787 return object &= operand;
|
Chris@16
|
788 }
|
Chris@16
|
789
|
Chris@16
|
790 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
791
|
Chris@16
|
792 template<class Type, class OperandT>
|
Chris@16
|
793 typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
794 operator & (const Type& object, const OperandT& operand)
|
Chris@16
|
795 {
|
Chris@16
|
796 Type temp = object;
|
Chris@16
|
797 return boost::move(temp &= operand);
|
Chris@16
|
798 }
|
Chris@16
|
799
|
Chris@16
|
800 template<class Type, class OperandT>
|
Chris@16
|
801 typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
802 operator & (Type&& object, const OperandT& operand)
|
Chris@16
|
803 {
|
Chris@16
|
804 return boost::move(object &= operand);
|
Chris@16
|
805 }
|
Chris@16
|
806
|
Chris@16
|
807 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
808
|
Chris@16
|
809 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
810 //------------------------------------------------------------------------------
|
Chris@16
|
811 //- T op & (c P&, T) T:{S}|{M} P:{e i S'}|{e i b p S' M'} S<S' M<M' <:coarser
|
Chris@16
|
812 //------------------------------------------------------------------------------
|
Chris@16
|
813 template<class Type, class OperandT>
|
Chris@16
|
814 typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
815 operator & (const OperandT& operand, Type object)
|
Chris@16
|
816 {
|
Chris@16
|
817 return object &= operand;
|
Chris@16
|
818 }
|
Chris@16
|
819
|
Chris@16
|
820 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
821
|
Chris@16
|
822 template<class Type, class OperandT>
|
Chris@16
|
823 typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
824 operator & (const OperandT& operand, const Type& object)
|
Chris@16
|
825 {
|
Chris@16
|
826 Type temp = object;
|
Chris@16
|
827 return boost::move(temp &= operand);
|
Chris@16
|
828 }
|
Chris@16
|
829
|
Chris@16
|
830 template<class Type, class OperandT>
|
Chris@16
|
831 typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
832 operator & (const OperandT& operand, Type&& object)
|
Chris@16
|
833 {
|
Chris@16
|
834 return boost::move(object &= operand);
|
Chris@16
|
835 }
|
Chris@16
|
836
|
Chris@16
|
837 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
838
|
Chris@16
|
839 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
840 //------------------------------------------------------------------------------
|
Chris@16
|
841 //- T op & (T, c T&) T:{S M}
|
Chris@16
|
842 //------------------------------------------------------------------------------
|
Chris@16
|
843 template<class Type>
|
Chris@16
|
844 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
845 operator & (Type object, const Type& operand)
|
Chris@16
|
846 {
|
Chris@16
|
847 return object &= operand;
|
Chris@16
|
848 }
|
Chris@16
|
849
|
Chris@16
|
850 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
851
|
Chris@16
|
852 template<class Type>
|
Chris@16
|
853 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
854 operator & (const Type& object, const Type& operand)
|
Chris@16
|
855 {
|
Chris@16
|
856 Type temp = object;
|
Chris@16
|
857 return boost::move(temp &= operand);
|
Chris@16
|
858 }
|
Chris@16
|
859
|
Chris@16
|
860 template<class Type>
|
Chris@16
|
861 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
862 operator & (Type&& object, const Type& operand)
|
Chris@16
|
863 {
|
Chris@16
|
864 return boost::move(object &= operand);
|
Chris@16
|
865 }
|
Chris@16
|
866
|
Chris@16
|
867 template<class Type>
|
Chris@16
|
868 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
869 operator & (const Type& operand, Type&& object)
|
Chris@16
|
870 {
|
Chris@16
|
871 return boost::move(object &= operand);
|
Chris@16
|
872 }
|
Chris@16
|
873
|
Chris@16
|
874 template<class Type>
|
Chris@16
|
875 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
876 operator & (Type&& object, Type&& operand)
|
Chris@16
|
877 {
|
Chris@16
|
878 return boost::move(object &= operand);
|
Chris@16
|
879 }
|
Chris@16
|
880
|
Chris@16
|
881 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
882
|
Chris@16
|
883 //------------------------------------------------------------------------------
|
Chris@16
|
884 //- intersects<IntervalSet|IntervalMap>
|
Chris@16
|
885 //------------------------------------------------------------------------------
|
Chris@16
|
886 //------------------------------------------------------------------------------
|
Chris@16
|
887 //- bool intersects(c T&, c P&) T:{S}|{M} P:{e i}
|
Chris@16
|
888 //------------------------------------------------------------------------------
|
Chris@16
|
889 template<class Type, class CoType>
|
Chris@16
|
890 typename enable_if<mpl::and_< is_interval_container<Type>
|
Chris@16
|
891 , boost::is_same<CoType, typename domain_type_of<Type>::type> >,
|
Chris@16
|
892 bool>::type
|
Chris@16
|
893 intersects(const Type& left, const CoType& right)
|
Chris@16
|
894 {
|
Chris@16
|
895 return icl::contains(left, right);
|
Chris@16
|
896 }
|
Chris@16
|
897
|
Chris@16
|
898 template<class Type, class CoType>
|
Chris@16
|
899 typename enable_if<mpl::and_< is_interval_container<Type>
|
Chris@16
|
900 , boost::is_same<CoType, typename interval_type_of<Type>::type> >,
|
Chris@16
|
901 bool>::type
|
Chris@16
|
902 intersects(const Type& left, const CoType& right)
|
Chris@16
|
903 {
|
Chris@16
|
904 return icl::find(left, right) != left.end();
|
Chris@16
|
905 }
|
Chris@16
|
906
|
Chris@16
|
907
|
Chris@16
|
908 template<class LeftT, class RightT>
|
Chris@16
|
909 typename enable_if< mpl::and_< is_intra_combinable<LeftT, RightT>
|
Chris@16
|
910 , mpl::or_<is_total<LeftT>, is_total<RightT> > >
|
Chris@16
|
911 , bool>::type
|
Chris@16
|
912 intersects(const LeftT&, const RightT&)
|
Chris@16
|
913 {
|
Chris@16
|
914 return true;
|
Chris@16
|
915 }
|
Chris@16
|
916
|
Chris@16
|
917 template<class LeftT, class RightT>
|
Chris@16
|
918 typename enable_if< mpl::and_< is_intra_combinable<LeftT, RightT>
|
Chris@16
|
919 , mpl::not_<mpl::or_< is_total<LeftT>
|
Chris@16
|
920 , is_total<RightT> > > >
|
Chris@16
|
921 , bool>::type
|
Chris@16
|
922 intersects(const LeftT& left, const RightT& right)
|
Chris@16
|
923 {
|
Chris@16
|
924 typedef typename RightT::const_iterator const_iterator;
|
Chris@16
|
925 LeftT intersection;
|
Chris@16
|
926
|
Chris@16
|
927 const_iterator right_common_lower_, right_common_upper_;
|
Chris@16
|
928 if(!Set::common_range(right_common_lower_, right_common_upper_, right, left))
|
Chris@16
|
929 return false;
|
Chris@16
|
930
|
Chris@16
|
931 const_iterator it_ = right_common_lower_;
|
Chris@16
|
932 while(it_ != right_common_upper_)
|
Chris@16
|
933 {
|
Chris@16
|
934 icl::add_intersection(intersection, left, *it_++);
|
Chris@16
|
935 if(!icl::is_empty(intersection))
|
Chris@16
|
936 return true;
|
Chris@16
|
937 }
|
Chris@16
|
938 return false;
|
Chris@16
|
939 }
|
Chris@16
|
940
|
Chris@16
|
941 template<class LeftT, class RightT>
|
Chris@16
|
942 typename enable_if<is_cross_combinable<LeftT, RightT>, bool>::type
|
Chris@16
|
943 intersects(const LeftT& left, const RightT& right)
|
Chris@16
|
944 {
|
Chris@16
|
945 typedef typename RightT::const_iterator const_iterator;
|
Chris@16
|
946 LeftT intersection;
|
Chris@16
|
947
|
Chris@16
|
948 if(icl::is_empty(left) || icl::is_empty(right))
|
Chris@16
|
949 return false;
|
Chris@16
|
950
|
Chris@16
|
951 const_iterator right_common_lower_, right_common_upper_;
|
Chris@16
|
952 if(!Set::common_range(right_common_lower_, right_common_upper_, right, left))
|
Chris@16
|
953 return false;
|
Chris@16
|
954
|
Chris@16
|
955 typename RightT::const_iterator it_ = right_common_lower_;
|
Chris@16
|
956 while(it_ != right_common_upper_)
|
Chris@16
|
957 {
|
Chris@16
|
958 icl::add_intersection(intersection, left, key_value<RightT>(it_++));
|
Chris@16
|
959 if(!icl::is_empty(intersection))
|
Chris@16
|
960 return true;
|
Chris@16
|
961 }
|
Chris@16
|
962
|
Chris@16
|
963 return false;
|
Chris@16
|
964 }
|
Chris@16
|
965
|
Chris@16
|
966 /** \b Returns true, if \c left and \c right have no common elements.
|
Chris@16
|
967 Intervals are interpreted as sequence of elements.
|
Chris@16
|
968 \b Complexity: loglinear, if \c left and \c right are interval containers. */
|
Chris@16
|
969 template<class LeftT, class RightT>
|
Chris@16
|
970 typename enable_if<is_inter_combinable<LeftT, RightT>, bool>::type
|
Chris@16
|
971 disjoint(const LeftT& left, const RightT& right)
|
Chris@16
|
972 {
|
Chris@16
|
973 return !intersects(left, right);
|
Chris@16
|
974 }
|
Chris@16
|
975
|
Chris@16
|
976 /** \b Returns true, if \c left and \c right have no common elements.
|
Chris@16
|
977 Intervals are interpreted as sequence of elements.
|
Chris@16
|
978 \b Complexity: logarithmic, if \c AssociateT is an element type \c Type::element_type.
|
Chris@16
|
979 linear, if \c AssociateT is a segment type \c Type::segment_type. */
|
Chris@16
|
980 template<class Type, class AssociateT>
|
Chris@16
|
981 typename enable_if<is_inter_derivative<Type, AssociateT>, bool>::type
|
Chris@16
|
982 disjoint(const Type& left, const AssociateT& right)
|
Chris@16
|
983 {
|
Chris@16
|
984 return !intersects(left,right);
|
Chris@16
|
985 }
|
Chris@16
|
986
|
Chris@16
|
987
|
Chris@16
|
988 //==============================================================================
|
Chris@16
|
989 //= Symmetric difference<IntervalSet|IntervalSet>
|
Chris@16
|
990 //==============================================================================
|
Chris@16
|
991 //------------------------------------------------------------------------------
|
Chris@16
|
992 //- Symmetric difference ^=, ^
|
Chris@16
|
993 //------------------------------------------------------------------------------
|
Chris@16
|
994 //------------------------------------------------------------------------------
|
Chris@16
|
995 //- T& op ^=(T&, c P&) T:{S}|{M} P:{S'}|{M'}
|
Chris@16
|
996 //------------------------------------------------------------------------------
|
Chris@16
|
997 template<class Type, class OperandT>
|
Chris@16
|
998 typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type&
|
Chris@16
|
999 operator ^= (Type& object, const OperandT& operand)
|
Chris@16
|
1000 {
|
Chris@16
|
1001 return icl::flip(object, operand);
|
Chris@16
|
1002 }
|
Chris@16
|
1003
|
Chris@16
|
1004 //------------------------------------------------------------------------------
|
Chris@16
|
1005 //- T& op ^=(T&, c P&) T:{S}|{M} P:{e i}|{b p}
|
Chris@16
|
1006 //------------------------------------------------------------------------------
|
Chris@16
|
1007 template<class Type, class OperandT>
|
Chris@16
|
1008 typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type&
|
Chris@16
|
1009 operator ^= (Type& object, const OperandT& operand)
|
Chris@16
|
1010 {
|
Chris@16
|
1011 return icl::flip(object, operand);
|
Chris@16
|
1012 }
|
Chris@16
|
1013
|
Chris@16
|
1014 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1015 //------------------------------------------------------------------------------
|
Chris@16
|
1016 //- T op ^ (T, c P&) T:{S}|{M} P:{e i S'}|{b p M'} S<S' M<M' <:coarser
|
Chris@16
|
1017 //------------------------------------------------------------------------------
|
Chris@16
|
1018 template<class Type, class OperandT>
|
Chris@16
|
1019 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
1020 operator ^ (Type object, const OperandT& operand)
|
Chris@16
|
1021 {
|
Chris@16
|
1022 return object ^= operand;
|
Chris@16
|
1023 }
|
Chris@16
|
1024
|
Chris@16
|
1025 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1026
|
Chris@16
|
1027 template<class Type, class OperandT>
|
Chris@16
|
1028 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
1029 operator ^ (const Type& object, const OperandT& operand)
|
Chris@16
|
1030 {
|
Chris@16
|
1031 Type temp = object;
|
Chris@16
|
1032 return boost::move(temp ^= operand);
|
Chris@16
|
1033 }
|
Chris@16
|
1034
|
Chris@16
|
1035 template<class Type, class OperandT>
|
Chris@16
|
1036 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
1037 operator ^ (Type&& object, const OperandT& operand)
|
Chris@16
|
1038 {
|
Chris@16
|
1039 return boost::move(object ^= operand);
|
Chris@16
|
1040 }
|
Chris@16
|
1041
|
Chris@16
|
1042 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1043
|
Chris@16
|
1044 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1045 //------------------------------------------------------------------------------
|
Chris@16
|
1046 //- T op ^ (c P&, T) T:{S}|{M} P:{e i S'}|{b p M'} S<S' M<M' <:coarser
|
Chris@16
|
1047 //------------------------------------------------------------------------------
|
Chris@16
|
1048 template<class Type, class OperandT>
|
Chris@16
|
1049 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
1050 operator ^ (const OperandT& operand, Type object)
|
Chris@16
|
1051 {
|
Chris@16
|
1052 return object ^= operand;
|
Chris@16
|
1053 }
|
Chris@16
|
1054
|
Chris@16
|
1055 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1056
|
Chris@16
|
1057 template<class Type, class OperandT>
|
Chris@16
|
1058 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
1059 operator ^ (const OperandT& operand, const Type& object)
|
Chris@16
|
1060 {
|
Chris@16
|
1061 Type temp = object;
|
Chris@16
|
1062 return boost::move(temp ^= operand);
|
Chris@16
|
1063 }
|
Chris@16
|
1064
|
Chris@16
|
1065 template<class Type, class OperandT>
|
Chris@16
|
1066 typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
|
Chris@16
|
1067 operator ^ (const OperandT& operand, Type&& object)
|
Chris@16
|
1068 {
|
Chris@16
|
1069 return boost::move(object ^= operand);
|
Chris@16
|
1070 }
|
Chris@16
|
1071
|
Chris@16
|
1072 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1073
|
Chris@16
|
1074 #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1075 //------------------------------------------------------------------------------
|
Chris@16
|
1076 //- T op ^ (T, c T&) T:{S M}
|
Chris@16
|
1077 //------------------------------------------------------------------------------
|
Chris@16
|
1078 template<class Type>
|
Chris@16
|
1079 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
1080 operator ^ (typename Type::overloadable_type object, const Type& operand)
|
Chris@16
|
1081 {
|
Chris@16
|
1082 return object ^= operand;
|
Chris@16
|
1083 }
|
Chris@16
|
1084
|
Chris@16
|
1085 #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1086
|
Chris@16
|
1087 template<class Type>
|
Chris@16
|
1088 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
1089 operator ^ (const Type& object, const Type& operand)
|
Chris@16
|
1090 {
|
Chris@16
|
1091 Type temp = object;
|
Chris@16
|
1092 return boost::move(temp ^= operand);
|
Chris@16
|
1093 }
|
Chris@16
|
1094
|
Chris@16
|
1095 template<class Type>
|
Chris@16
|
1096 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
1097 operator ^ (Type&& object, const Type& operand)
|
Chris@16
|
1098 {
|
Chris@16
|
1099 return boost::move(object ^= operand);
|
Chris@16
|
1100 }
|
Chris@16
|
1101
|
Chris@16
|
1102 template<class Type>
|
Chris@16
|
1103 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
1104 operator ^ (const Type& operand, Type&& object)
|
Chris@16
|
1105 {
|
Chris@16
|
1106 return boost::move(object ^= operand);
|
Chris@16
|
1107 }
|
Chris@16
|
1108
|
Chris@16
|
1109 template<class Type>
|
Chris@16
|
1110 typename enable_if<is_interval_container<Type>, Type>::type
|
Chris@16
|
1111 operator ^ (Type&& object, Type&& operand)
|
Chris@16
|
1112 {
|
Chris@16
|
1113 return boost::move(object ^= operand);
|
Chris@16
|
1114 }
|
Chris@16
|
1115
|
Chris@16
|
1116 #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1117
|
Chris@16
|
1118 //==========================================================================
|
Chris@16
|
1119 //= Element Iteration <IntervalSet|IntervalMap>
|
Chris@16
|
1120 //==========================================================================
|
Chris@16
|
1121 //--------------------------------------------------------------------------
|
Chris@16
|
1122 //- Forward
|
Chris@16
|
1123 //--------------------------------------------------------------------------
|
Chris@16
|
1124 template<class Type>
|
Chris@16
|
1125 typename enable_if
|
Chris@16
|
1126 <mpl::and_< is_interval_container<Type>
|
Chris@16
|
1127 , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
|
Chris@16
|
1128 typename Type::element_iterator>::type
|
Chris@16
|
1129 elements_begin(Type& object)
|
Chris@16
|
1130 {
|
Chris@16
|
1131 return typename Type::element_iterator(object.begin());
|
Chris@16
|
1132 }
|
Chris@16
|
1133
|
Chris@16
|
1134 template<class Type>
|
Chris@16
|
1135 typename enable_if
|
Chris@16
|
1136 <mpl::and_< is_interval_container<Type>
|
Chris@16
|
1137 , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
|
Chris@16
|
1138 typename Type::element_iterator>::type
|
Chris@16
|
1139 elements_end(Type& object)
|
Chris@16
|
1140 {
|
Chris@16
|
1141 return typename Type::element_iterator(object.end());
|
Chris@16
|
1142 }
|
Chris@16
|
1143
|
Chris@16
|
1144 template<class Type>
|
Chris@16
|
1145 typename enable_if
|
Chris@16
|
1146 <mpl::and_< is_interval_container<Type>
|
Chris@16
|
1147 , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
|
Chris@16
|
1148 typename Type::element_const_iterator>::type
|
Chris@16
|
1149 elements_begin(const Type& object)
|
Chris@16
|
1150 {
|
Chris@16
|
1151 return typename Type::element_const_iterator(object.begin());
|
Chris@16
|
1152 }
|
Chris@16
|
1153
|
Chris@16
|
1154 template<class Type>
|
Chris@16
|
1155 typename enable_if
|
Chris@16
|
1156 <mpl::and_< is_interval_container<Type>
|
Chris@16
|
1157 , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
|
Chris@16
|
1158 typename Type::element_const_iterator>::type
|
Chris@16
|
1159 elements_end(const Type& object)
|
Chris@16
|
1160 {
|
Chris@16
|
1161 return typename Type::element_const_iterator(object.end());
|
Chris@16
|
1162 }
|
Chris@16
|
1163
|
Chris@16
|
1164 //--------------------------------------------------------------------------
|
Chris@16
|
1165 //- Reverse
|
Chris@16
|
1166 //--------------------------------------------------------------------------
|
Chris@16
|
1167 template<class Type>
|
Chris@16
|
1168 typename enable_if
|
Chris@16
|
1169 <mpl::and_< is_interval_container<Type>
|
Chris@16
|
1170 , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
|
Chris@16
|
1171 typename Type::element_reverse_iterator>::type
|
Chris@16
|
1172 elements_rbegin(Type& object)
|
Chris@16
|
1173 {
|
Chris@16
|
1174 return typename Type::element_reverse_iterator(object.rbegin());
|
Chris@16
|
1175 }
|
Chris@16
|
1176
|
Chris@16
|
1177 template<class Type>
|
Chris@16
|
1178 typename enable_if
|
Chris@16
|
1179 <mpl::and_< is_interval_container<Type>
|
Chris@16
|
1180 , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
|
Chris@16
|
1181 typename Type::element_reverse_iterator>::type
|
Chris@16
|
1182 elements_rend(Type& object)
|
Chris@16
|
1183 {
|
Chris@16
|
1184 return typename Type::element_reverse_iterator(object.rend());
|
Chris@16
|
1185 }
|
Chris@16
|
1186
|
Chris@16
|
1187 template<class Type>
|
Chris@16
|
1188 typename enable_if
|
Chris@16
|
1189 <mpl::and_< is_interval_container<Type>
|
Chris@16
|
1190 , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
|
Chris@16
|
1191 typename Type::element_const_reverse_iterator>::type
|
Chris@16
|
1192 elements_rbegin(const Type& object)
|
Chris@16
|
1193 {
|
Chris@16
|
1194 return typename Type::element_const_reverse_iterator(object.rbegin());
|
Chris@16
|
1195 }
|
Chris@16
|
1196
|
Chris@16
|
1197 template<class Type>
|
Chris@16
|
1198 typename enable_if
|
Chris@16
|
1199 <mpl::and_< is_interval_container<Type>
|
Chris@16
|
1200 , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
|
Chris@16
|
1201 typename Type::element_const_reverse_iterator>::type
|
Chris@16
|
1202 elements_rend(const Type& object)
|
Chris@16
|
1203 {
|
Chris@16
|
1204 return typename Type::element_const_reverse_iterator(object.rend());
|
Chris@16
|
1205 }
|
Chris@16
|
1206
|
Chris@16
|
1207 }} // namespace boost icl
|
Chris@16
|
1208
|
Chris@16
|
1209 #endif
|
Chris@16
|
1210
|
Chris@16
|
1211
|