Line data Source code
1 : // Boost.Range library
2 : //
3 : // Copyright Neil Groves & Thorsten Ottosen & Pavol Droba 2003-2004.
4 : // Use, modification and distribution is subject to the Boost Software
5 : // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 : // http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // For more information, see http://www.boost.org/libs/range/
9 : //
10 : // Credits:
11 : // 'michel' reported Trac 9072 which included a patch for allowing references
12 : // to function types.
13 : //
14 : #ifndef BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
15 : #define BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
16 :
17 : #include <boost/config.hpp> // Define __STL_CONFIG_H, if appropriate.
18 : #include <boost/detail/workaround.hpp>
19 :
20 : #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
21 : #pragma warning( push )
22 : #pragma warning( disable : 4996 )
23 : #endif
24 :
25 : #include <boost/assert.hpp>
26 : #include <boost/iterator/iterator_traits.hpp>
27 : #include <boost/iterator/iterator_facade.hpp>
28 : #include <boost/mpl/if.hpp>
29 : #include <boost/mpl/not.hpp>
30 : #include <boost/mpl/or.hpp>
31 : #include <boost/type_traits/is_abstract.hpp>
32 : #include <boost/type_traits/is_array.hpp>
33 : #include <boost/type_traits/is_base_and_derived.hpp>
34 : #include <boost/type_traits/is_convertible.hpp>
35 : #include <boost/type_traits/is_function.hpp>
36 : #include <boost/type_traits/is_pointer.hpp>
37 : #include <boost/type_traits/is_same.hpp>
38 : #include <boost/range/functions.hpp>
39 : #include <boost/range/iterator.hpp>
40 : #include <boost/range/difference_type.hpp>
41 : #include <boost/range/has_range_iterator.hpp>
42 : #include <boost/range/algorithm/equal.hpp>
43 : #include <boost/range/detail/safe_bool.hpp>
44 : #include <boost/utility/enable_if.hpp>
45 : #include <boost/next_prior.hpp>
46 : #include <iterator>
47 : #include <algorithm>
48 : #include <cstddef>
49 :
50 : /*! \file
51 : Defines the \c iterator_class and related functions.
52 : \c iterator_range is a simple wrapper of iterator pair idiom. It provides
53 : a rich subset of Container interface.
54 : */
55 :
56 :
57 : namespace boost
58 : {
59 : namespace iterator_range_detail
60 : {
61 : //
62 : // The functions adl_begin and adl_end are implemented in a separate
63 : // class for gcc-2.9x
64 : //
65 : template<class IteratorT>
66 : struct iterator_range_impl {
67 : template< class ForwardRange >
68 194639 : static IteratorT adl_begin( ForwardRange& r )
69 : {
70 194639 : return IteratorT( boost::begin( r ) );
71 : }
72 :
73 : template< class ForwardRange >
74 194639 : static IteratorT adl_end( ForwardRange& r )
75 : {
76 194639 : return IteratorT( boost::end( r ) );
77 : }
78 : };
79 :
80 : template< class Left, class Right >
81 : inline bool less_than( const Left& l, const Right& r )
82 : {
83 : return std::lexicographical_compare( boost::begin(l),
84 : boost::end(l),
85 : boost::begin(r),
86 : boost::end(r) );
87 : }
88 :
89 : template< class Left, class Right >
90 : inline bool greater_than( const Left& l, const Right& r )
91 : {
92 : return iterator_range_detail::less_than(r,l);
93 : }
94 :
95 : template< class Left, class Right >
96 : inline bool less_or_equal_than( const Left& l, const Right& r )
97 : {
98 : return !iterator_range_detail::less_than(r,l);
99 : }
100 :
101 : template< class Left, class Right >
102 : inline bool greater_or_equal_than( const Left& l, const Right& r )
103 : {
104 : return !iterator_range_detail::less_than(l,r);
105 : }
106 :
107 : // This version is maintained since it is used in other boost libraries
108 : // such as Boost.Assign
109 : template< class Left, class Right >
110 : inline bool equal(const Left& l, const Right& r)
111 : {
112 : return boost::equal(l, r);
113 : }
114 :
115 : struct range_tag
116 : {
117 : };
118 :
119 : struct const_range_tag
120 : {
121 : };
122 :
123 : struct iterator_range_tag
124 : {
125 : };
126 :
127 : typedef char (&incrementable_t)[1];
128 : typedef char (&bidirectional_t)[2];
129 : typedef char (&random_access_t)[3];
130 :
131 : incrementable_t test_traversal_tag(boost::incrementable_traversal_tag);
132 : bidirectional_t test_traversal_tag(boost::bidirectional_traversal_tag);
133 : random_access_t test_traversal_tag(boost::random_access_traversal_tag);
134 :
135 : template<std::size_t S>
136 : struct pure_iterator_traversal_impl
137 : {
138 : typedef boost::incrementable_traversal_tag type;
139 : };
140 :
141 : template<>
142 : struct pure_iterator_traversal_impl<sizeof(bidirectional_t)>
143 : {
144 : typedef boost::bidirectional_traversal_tag type;
145 : };
146 :
147 : template<>
148 : struct pure_iterator_traversal_impl<sizeof(random_access_t)>
149 : {
150 : typedef boost::random_access_traversal_tag type;
151 : };
152 :
153 : template<typename IteratorT>
154 : struct pure_iterator_traversal
155 : {
156 : typedef
157 : BOOST_DEDUCED_TYPENAME iterator_traversal<IteratorT>::type
158 : traversal_t;
159 : BOOST_STATIC_CONSTANT(
160 : std::size_t,
161 : traversal_i = sizeof(iterator_range_detail::test_traversal_tag((traversal_t())))
162 : );
163 : typedef
164 : BOOST_DEDUCED_TYPENAME pure_iterator_traversal_impl<traversal_i>::type
165 : type;
166 : };
167 :
168 : template<class IteratorT, class TraversalTag>
169 2147 : class iterator_range_base
170 : : public iterator_range_tag
171 : {
172 : typedef range_detail::safe_bool<
173 : IteratorT iterator_range_base<IteratorT, TraversalTag>::*
174 : > safe_bool_t;
175 :
176 : typedef iterator_range_base<IteratorT, TraversalTag> type;
177 :
178 : protected:
179 : typedef iterator_range_impl<IteratorT> impl;
180 :
181 : public:
182 : typedef BOOST_DEDUCED_TYPENAME
183 : safe_bool_t::unspecified_bool_type unspecified_bool_type;
184 :
185 : typedef BOOST_DEDUCED_TYPENAME
186 : iterator_value<IteratorT>::type value_type;
187 :
188 : typedef BOOST_DEDUCED_TYPENAME
189 : iterator_difference<IteratorT>::type difference_type;
190 :
191 : typedef std::size_t size_type; // note: must be unsigned
192 :
193 : // Needed because value-type is the same for
194 : // const and non-const iterators
195 : typedef BOOST_DEDUCED_TYPENAME
196 : iterator_reference<IteratorT>::type reference;
197 :
198 : //! const_iterator type
199 : /*!
200 : There is no distinction between const_iterator and iterator.
201 : These typedefs are provides to fulfill container interface
202 : */
203 : typedef IteratorT const_iterator;
204 : //! iterator type
205 : typedef IteratorT iterator;
206 :
207 : protected:
208 0 : iterator_range_base()
209 : : m_Begin()
210 0 : , m_End()
211 : {
212 : }
213 :
214 : template<class Iterator>
215 207178 : iterator_range_base(Iterator Begin, Iterator End)
216 : : m_Begin(Begin)
217 11977 : , m_End(End)
218 : {
219 : }
220 :
221 : public:
222 224115 : IteratorT begin() const
223 : {
224 3219 : return m_Begin;
225 : }
226 :
227 281943 : IteratorT end() const
228 : {
229 6781 : return m_End;
230 : }
231 :
232 562 : bool empty() const
233 : {
234 562 : return m_Begin == m_End;
235 : }
236 :
237 0 : operator unspecified_bool_type() const
238 : {
239 0 : return safe_bool_t::to_unspecified_bool(
240 0 : m_Begin != m_End, &iterator_range_base::m_Begin);
241 : }
242 :
243 0 : bool operator!() const
244 : {
245 0 : return empty();
246 : }
247 :
248 : bool equal(const iterator_range_base& r) const
249 : {
250 : return m_Begin == r.m_Begin && m_End == r.m_End;
251 : }
252 :
253 : reference front() const
254 : {
255 : BOOST_ASSERT(!empty());
256 : return *m_Begin;
257 : }
258 :
259 : void drop_front()
260 : {
261 : BOOST_ASSERT(!empty());
262 : ++m_Begin;
263 : }
264 :
265 : void drop_front(difference_type n)
266 : {
267 : BOOST_ASSERT(n >= difference_type());
268 : std::advance(this->m_Begin, n);
269 : }
270 :
271 : // Deprecated
272 : void pop_front() { drop_front(); }
273 :
274 : protected:
275 : template<class Iterator>
276 0 : void assign(Iterator first, Iterator last)
277 : {
278 0 : m_Begin = first;
279 0 : m_End = last;
280 : }
281 :
282 : template<class SinglePassRange>
283 : void assign(const SinglePassRange& r)
284 : {
285 : m_Begin = impl::adl_begin(r);
286 : m_End = impl::adl_end(r);
287 : }
288 :
289 : template<class SinglePassRange>
290 : void assign(SinglePassRange& r)
291 : {
292 : m_Begin = impl::adl_begin(r);
293 : m_End = impl::adl_end(r);
294 : }
295 :
296 : IteratorT m_Begin;
297 : IteratorT m_End;
298 : };
299 :
300 : template<class IteratorT>
301 2147 : class iterator_range_base<IteratorT, bidirectional_traversal_tag>
302 : : public iterator_range_base<IteratorT, incrementable_traversal_tag>
303 : {
304 : typedef iterator_range_base<IteratorT, incrementable_traversal_tag> base_type;
305 :
306 : protected:
307 0 : iterator_range_base()
308 0 : {
309 : }
310 :
311 : template<class Iterator>
312 207178 : iterator_range_base(Iterator first, Iterator last)
313 11822 : : base_type(first, last)
314 : {
315 : }
316 :
317 : public:
318 : typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type;
319 : typedef BOOST_DEDUCED_TYPENAME base_type::reference reference;
320 :
321 : reference back() const
322 : {
323 : BOOST_ASSERT(!this->empty());
324 : return *boost::prior(this->m_End);
325 : }
326 :
327 : void drop_back()
328 : {
329 : BOOST_ASSERT(!this->empty());
330 : --this->m_End;
331 : }
332 :
333 : void drop_back(difference_type n)
334 : {
335 : BOOST_ASSERT(n >= difference_type());
336 : std::advance(this->m_End, -n);
337 : }
338 :
339 : // Deprecated
340 : void pop_back() { drop_back(); }
341 : };
342 :
343 : template<class IteratorT>
344 : class iterator_range_base<IteratorT, random_access_traversal_tag>
345 : : public iterator_range_base<IteratorT, bidirectional_traversal_tag>
346 : {
347 : typedef iterator_range_base<
348 : IteratorT, bidirectional_traversal_tag> base_type;
349 :
350 : public:
351 : typedef BOOST_DEDUCED_TYPENAME
352 : boost::mpl::if_<
353 : boost::mpl::or_<
354 : boost::is_abstract<
355 : BOOST_DEDUCED_TYPENAME base_type::value_type
356 : >,
357 : boost::is_array<
358 : BOOST_DEDUCED_TYPENAME base_type::value_type
359 : >,
360 : boost::is_function<
361 : BOOST_DEDUCED_TYPENAME base_type::value_type
362 : >
363 : >,
364 : BOOST_DEDUCED_TYPENAME base_type::reference,
365 : BOOST_DEDUCED_TYPENAME base_type::value_type
366 : >::type abstract_value_type;
367 :
368 : // Rationale:
369 : // typedef these here to reduce verbiage in the implementation of this
370 : // type.
371 : typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type;
372 : typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type;
373 : typedef BOOST_DEDUCED_TYPENAME base_type::reference reference;
374 :
375 : protected:
376 0 : iterator_range_base()
377 0 : {
378 : }
379 :
380 : template<class Iterator>
381 195763 : iterator_range_base(Iterator first, Iterator last)
382 1479 : : base_type(first, last)
383 : {
384 : }
385 :
386 : public:
387 : reference operator[](difference_type at) const
388 : {
389 : BOOST_ASSERT(at >= 0);
390 : BOOST_ASSERT(static_cast<typename base_type::size_type>(at) < size());
391 : return this->m_Begin[at];
392 : }
393 :
394 : //
395 : // When storing transform iterators, operator[]()
396 : // fails because it returns by reference. Therefore
397 : // operator()() is provided for these cases.
398 : //
399 : abstract_value_type operator()(difference_type at) const
400 : {
401 : BOOST_ASSERT(at >= 0);
402 : BOOST_ASSERT(static_cast<typename base_type::size_type>(at) < size());
403 : return this->m_Begin[at];
404 : }
405 :
406 0 : BOOST_DEDUCED_TYPENAME base_type::size_type size() const
407 : {
408 0 : return this->m_End - this->m_Begin;
409 : }
410 : };
411 :
412 : }
413 :
414 : // iterator range template class -----------------------------------------//
415 :
416 : //! iterator_range class
417 : /*!
418 : An \c iterator_range delimits a range in a sequence by beginning and ending iterators.
419 : An iterator_range can be passed to an algorithm which requires a sequence as an input.
420 : For example, the \c toupper() function may be used most frequently on strings,
421 : but can also be used on iterator_ranges:
422 :
423 : \code
424 : boost::tolower( find( s, "UPPERCASE STRING" ) );
425 : \endcode
426 :
427 : Many algorithms working with sequences take a pair of iterators,
428 : delimiting a working range, as an arguments. The \c iterator_range class is an
429 : encapsulation of a range identified by a pair of iterators.
430 : It provides a collection interface,
431 : so it is possible to pass an instance to an algorithm requiring a collection as an input.
432 : */
433 : template<class IteratorT>
434 2147 : class iterator_range
435 : : public iterator_range_detail::iterator_range_base<
436 : IteratorT,
437 : BOOST_DEDUCED_TYPENAME iterator_range_detail::pure_iterator_traversal<IteratorT>::type
438 : >
439 : {
440 : typedef iterator_range_detail::iterator_range_base<
441 : IteratorT,
442 : BOOST_DEDUCED_TYPENAME iterator_range_detail::pure_iterator_traversal<IteratorT>::type
443 : > base_type;
444 :
445 : template<class Source>
446 : struct is_compatible_range_
447 : : is_convertible<
448 : BOOST_DEDUCED_TYPENAME mpl::eval_if<
449 : has_range_iterator<Source>,
450 : range_iterator<Source>,
451 : mpl::identity<void>
452 : >::type,
453 : BOOST_DEDUCED_TYPENAME base_type::iterator
454 : >
455 : {
456 : };
457 :
458 : template<class Source>
459 : struct is_compatible_range
460 : : mpl::and_<
461 : mpl::not_<
462 : is_convertible<
463 : Source,
464 : BOOST_DEDUCED_TYPENAME base_type::iterator
465 : >
466 : >,
467 : is_compatible_range_<Source>
468 : >
469 : {
470 : };
471 :
472 : protected:
473 : typedef iterator_range_detail::iterator_range_impl<IteratorT> impl;
474 :
475 : public:
476 : typedef iterator_range<IteratorT> type;
477 :
478 0 : iterator_range()
479 0 : {
480 : }
481 :
482 : template<class Iterator>
483 12894 : iterator_range(Iterator first, Iterator last)
484 11822 : : base_type(first, last)
485 : {
486 : }
487 :
488 : template<class SinglePassRange>
489 0 : iterator_range(
490 : const SinglePassRange& r,
491 : BOOST_DEDUCED_TYPENAME ::boost::enable_if<
492 : is_compatible_range<const SinglePassRange>
493 : >::type* = 0
494 : )
495 0 : : base_type(impl::adl_begin(r), impl::adl_end(r))
496 : {
497 : }
498 :
499 : template<class SinglePassRange>
500 0 : iterator_range(
501 : SinglePassRange& r,
502 : BOOST_DEDUCED_TYPENAME ::boost::enable_if<
503 : is_compatible_range<SinglePassRange>
504 : >::type* = 0
505 : )
506 0 : : base_type(impl::adl_begin(r), impl::adl_end(r))
507 : {
508 : }
509 :
510 : template<class SinglePassRange>
511 194639 : iterator_range(const SinglePassRange& r,
512 : iterator_range_detail::const_range_tag)
513 194639 : : base_type(impl::adl_begin(r), impl::adl_end(r))
514 : {
515 : }
516 :
517 : template<class SinglePassRange>
518 0 : iterator_range(SinglePassRange& r,
519 : iterator_range_detail::range_tag)
520 0 : : base_type(impl::adl_begin(r), impl::adl_end(r))
521 : {
522 : }
523 :
524 : template<class Iterator>
525 : iterator_range& operator=(const iterator_range<Iterator>& other)
526 : {
527 : this->assign(other.begin(), other.end());
528 : return *this;
529 : }
530 :
531 : template<class Iterator>
532 0 : iterator_range& operator=(iterator_range<Iterator>& other)
533 : {
534 0 : this->assign(other.begin(), other.end());
535 : return *this;
536 : }
537 :
538 : template<class SinglePassRange>
539 : iterator_range& operator=(SinglePassRange& r)
540 : {
541 : this->assign(r);
542 : return *this;
543 : }
544 :
545 : template<class SinglePassRange>
546 : iterator_range& operator=(const SinglePassRange& r)
547 : {
548 : this->assign(r);
549 : return *this;
550 : }
551 :
552 : iterator_range& advance_begin(
553 : BOOST_DEDUCED_TYPENAME base_type::difference_type n)
554 : {
555 : std::advance(this->m_Begin, n);
556 : return *this;
557 : }
558 :
559 : iterator_range& advance_end(
560 : BOOST_DEDUCED_TYPENAME base_type::difference_type n)
561 : {
562 : std::advance(this->m_End, n);
563 : return *this;
564 : }
565 :
566 : protected:
567 : //
568 : // Allow subclasses an easy way to access the
569 : // base type
570 : //
571 : typedef iterator_range iterator_range_;
572 : };
573 :
574 : // iterator range free-standing operators ---------------------------//
575 :
576 : /////////////////////////////////////////////////////////////////////
577 : // comparison operators
578 : /////////////////////////////////////////////////////////////////////
579 :
580 : template< class IteratorT, class ForwardRange >
581 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
582 : mpl::not_<is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
583 : bool
584 : >::type
585 : operator==( const ForwardRange& l, const iterator_range<IteratorT>& r )
586 : {
587 : return boost::equal( l, r );
588 : }
589 :
590 : template< class IteratorT, class ForwardRange >
591 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
592 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
593 : bool
594 : >::type
595 : operator!=( const ForwardRange& l, const iterator_range<IteratorT>& r )
596 : {
597 : return !boost::equal( l, r );
598 : }
599 :
600 : template< class IteratorT, class ForwardRange >
601 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
602 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
603 : bool
604 : >::type
605 : operator<( const ForwardRange& l, const iterator_range<IteratorT>& r )
606 : {
607 : return iterator_range_detail::less_than( l, r );
608 : }
609 :
610 : template< class IteratorT, class ForwardRange >
611 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
612 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
613 : bool
614 : >::type
615 : operator<=( const ForwardRange& l, const iterator_range<IteratorT>& r )
616 : {
617 : return iterator_range_detail::less_or_equal_than( l, r );
618 : }
619 :
620 : template< class IteratorT, class ForwardRange >
621 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
622 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
623 : bool
624 : >::type
625 : operator>( const ForwardRange& l, const iterator_range<IteratorT>& r )
626 : {
627 : return iterator_range_detail::greater_than( l, r );
628 : }
629 :
630 : template< class IteratorT, class ForwardRange >
631 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
632 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
633 : bool
634 : >::type
635 : operator>=( const ForwardRange& l, const iterator_range<IteratorT>& r )
636 : {
637 : return iterator_range_detail::greater_or_equal_than( l, r );
638 : }
639 :
640 : #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
641 : #else
642 : template< class Iterator1T, class Iterator2T >
643 : inline bool
644 0 : operator==( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
645 : {
646 0 : return boost::equal( l, r );
647 : }
648 :
649 : template< class IteratorT, class ForwardRange >
650 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
651 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
652 : bool
653 : >::type
654 : operator==( const iterator_range<IteratorT>& l, const ForwardRange& r )
655 : {
656 : return boost::equal( l, r );
657 : }
658 :
659 :
660 : template< class Iterator1T, class Iterator2T >
661 : inline bool
662 : operator!=( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
663 : {
664 : return !boost::equal( l, r );
665 : }
666 :
667 : template< class IteratorT, class ForwardRange >
668 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
669 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
670 : bool
671 : >::type
672 : operator!=( const iterator_range<IteratorT>& l, const ForwardRange& r )
673 : {
674 : return !boost::equal( l, r );
675 : }
676 :
677 :
678 : template< class Iterator1T, class Iterator2T >
679 : inline bool
680 : operator<( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
681 : {
682 : return iterator_range_detail::less_than( l, r );
683 : }
684 :
685 : template< class IteratorT, class ForwardRange >
686 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
687 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
688 : bool
689 : >::type
690 : operator<( const iterator_range<IteratorT>& l, const ForwardRange& r )
691 : {
692 : return iterator_range_detail::less_than( l, r );
693 : }
694 :
695 : template< class Iterator1T, class Iterator2T >
696 : inline bool
697 : operator<=( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
698 : {
699 : return iterator_range_detail::less_or_equal_than( l, r );
700 : }
701 :
702 : template< class IteratorT, class ForwardRange >
703 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
704 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
705 : bool
706 : >::type
707 : operator<=( const iterator_range<IteratorT>& l, const ForwardRange& r )
708 : {
709 : return iterator_range_detail::less_or_equal_than( l, r );
710 : }
711 :
712 : template< class Iterator1T, class Iterator2T >
713 : inline bool
714 : operator>( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
715 : {
716 : return iterator_range_detail::greater_than( l, r );
717 : }
718 :
719 : template< class IteratorT, class ForwardRange >
720 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
721 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
722 : bool
723 : >::type
724 : operator>( const iterator_range<IteratorT>& l, const ForwardRange& r )
725 : {
726 : return iterator_range_detail::greater_than( l, r );
727 : }
728 :
729 : template< class Iterator1T, class Iterator2T >
730 : inline bool
731 : operator>=( const iterator_range<Iterator1T>& l, const iterator_range<Iterator2T>& r )
732 : {
733 : return iterator_range_detail::greater_or_equal_than( l, r );
734 : }
735 :
736 : template< class IteratorT, class ForwardRange >
737 : inline BOOST_DEDUCED_TYPENAME boost::enable_if<
738 : mpl::not_<boost::is_base_and_derived<iterator_range_detail::iterator_range_tag, ForwardRange> >,
739 : bool
740 : >::type
741 : operator>=( const iterator_range<IteratorT>& l, const ForwardRange& r )
742 : {
743 : return iterator_range_detail::greater_or_equal_than( l, r );
744 : }
745 :
746 : #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
747 :
748 : // iterator range utilities -----------------------------------------//
749 :
750 : //! iterator_range construct helper
751 : /*!
752 : Construct an \c iterator_range from a pair of iterators
753 :
754 : \param Begin A begin iterator
755 : \param End An end iterator
756 : \return iterator_range object
757 : */
758 : template< typename IteratorT >
759 : inline iterator_range< IteratorT >
760 0 : make_iterator_range( IteratorT Begin, IteratorT End )
761 : {
762 0 : return iterator_range<IteratorT>( Begin, End );
763 : }
764 :
765 : template<typename IteratorT, typename IntegerT>
766 : inline iterator_range<IteratorT>
767 : make_iterator_range_n(IteratorT first, IntegerT n)
768 : {
769 : return iterator_range<IteratorT>(first, boost::next(first, n));
770 : }
771 :
772 : #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
773 :
774 : template< typename Range >
775 : inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
776 : make_iterator_range( Range& r )
777 : {
778 : return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
779 : ( boost::begin( r ), boost::end( r ) );
780 : }
781 :
782 : #else
783 : //! iterator_range construct helper
784 : /*!
785 : Construct an \c iterator_range from a \c Range containing the begin
786 : and end iterators.
787 : */
788 : template< class ForwardRange >
789 : inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
790 0 : make_iterator_range( ForwardRange& r )
791 : {
792 : return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
793 0 : ( r, iterator_range_detail::range_tag() );
794 : }
795 :
796 : template< class ForwardRange >
797 : inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
798 194639 : make_iterator_range( const ForwardRange& r )
799 : {
800 : return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
801 194639 : ( r, iterator_range_detail::const_range_tag() );
802 : }
803 :
804 : #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
805 :
806 : namespace iterator_range_detail
807 : {
808 : template< class Range >
809 : inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
810 : make_range_impl( Range& r,
811 : BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
812 : BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
813 : {
814 : //
815 : // Not worth the effort
816 : //
817 : //if( advance_begin == 0 && advance_end == 0 )
818 : // return make_iterator_range( r );
819 : //
820 :
821 : BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
822 : new_begin = boost::begin( r ),
823 : new_end = boost::end( r );
824 : std::advance( new_begin, advance_begin );
825 : std::advance( new_end, advance_end );
826 : return make_iterator_range( new_begin, new_end );
827 : }
828 : }
829 :
830 : #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
831 :
832 : template< class Range >
833 : inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
834 : make_iterator_range( Range& r,
835 : BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
836 : BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
837 : {
838 : return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
839 : }
840 :
841 : #else
842 :
843 : template< class Range >
844 : inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
845 : make_iterator_range( Range& r,
846 : BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
847 : BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
848 : {
849 : return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
850 : }
851 :
852 : template< class Range >
853 : inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type >
854 : make_iterator_range( const Range& r,
855 : BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
856 : BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
857 : {
858 : return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
859 : }
860 :
861 : #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
862 :
863 : //! copy a range into a sequence
864 : /*!
865 : Construct a new sequence of the specified type from the elements
866 : in the given range
867 :
868 : \param Range An input range
869 : \return New sequence
870 : */
871 : template< typename SeqT, typename Range >
872 0 : inline SeqT copy_range( const Range& r )
873 : {
874 0 : return SeqT( boost::begin( r ), boost::end( r ) );
875 : }
876 :
877 : } // namespace 'boost'
878 :
879 : #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
880 : #pragma warning( pop )
881 : #endif
882 :
883 : #endif
884 :
|