2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * @file IteratorFunctions.ih
19 * @author Tristan Roussillon (\c tristan.roussillon@liris.cnrs.fr )
20 * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
24 * Implementation of inline methods defined in IteratorFunctions.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 //////////////////////////////////////////////////////////////////////////////
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
38 //-----------------------------------------------------------------------------
39 template< typename IC>
40 bool DGtal::isEmpty( const IC& itb, const IC& ite )
42 return !detail::isNotEmpty<IC>( itb, ite, typename IteratorCirculatorTraits<IC>::Type() );
45 //-----------------------------------------------------------------------------
46 template< typename IC>
47 bool DGtal::isNotEmpty( const IC& itb, const IC& ite )
49 return detail::isNotEmpty<IC>( itb, ite, typename IteratorCirculatorTraits<IC>::Type() );
52 //-----------------------------------------------------------------------------
53 template< typename IC >
54 bool DGtal::detail::isNotEmpty( const IC& itb, const IC& ite, IteratorType )
59 //-----------------------------------------------------------------------------
60 template< typename IC >
61 bool DGtal::detail::isNotEmpty( const IC& c1, const IC& c2, CirculatorType )
63 // Using isValid method does not work adapters of circulators
64 // (eg. reverse circulators), which does not have any isValid method
65 // That's why we choose the following method:
66 IC c; //c is necessarily not valid
67 //if c1 or c2 is equal to a not valid circulator,
68 //then the underlying range is necessarily empty
69 return ( (c1 != c) && (c2 != c) );
72 //-----------------------------------------------------------------------------
74 void DGtal::advanceIterator(IC& ic,
75 typename IteratorCirculatorTraits<IC>::Difference n)
77 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<IC> ));
79 typedef typename IteratorCirculatorTraits<IC>::Category Category;
80 DGtal::detail::advanceIterator( ic, n, Category() );
83 //-----------------------------------------------------------------------------
85 void DGtal::detail::advanceIterator(IC& ic,
86 typename IteratorCirculatorTraits<IC>::Difference n,
89 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<IC> ));
100 //-----------------------------------------------------------------------------
101 template<typename IC>
102 void DGtal::detail::advanceIterator(IC& ic,
103 typename IteratorCirculatorTraits<IC>::Difference n,
104 RandomAccessCategory)
106 BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<IC> ));
111 //-----------------------------------------------------------------------------
112 template<typename IC>
113 typename DGtal::IteratorCirculatorTraits<IC>::Difference
114 DGtal::rangeSize(const IC& itb, const IC& ite)
116 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<IC> ));
118 typedef typename IteratorCirculatorTraits<IC>::Type Type;
119 typedef typename IteratorCirculatorTraits<IC>::Category Category;
120 return DGtal::detail::rangeSize( itb, ite, Type(), Category() );
123 //-----------------------------------------------------------------------------
124 template<typename IC>
125 typename DGtal::IteratorCirculatorTraits<IC>::Difference
126 DGtal::subRangeSize(const IC& itb, const IC& ite)
128 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<IC> ));
130 typedef typename IteratorCirculatorTraits<IC>::Category Category;
131 return DGtal::detail::rangeSize( itb, ite, IteratorType(), Category() );
134 //-----------------------------------------------------------------------------
136 typename DGtal::IteratorCirculatorTraits<I>::Difference
137 DGtal::detail::rangeSize(const I& itb, const I& ite, IteratorType, ForwardCategory)
139 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<I> ));
143 typename DGtal::IteratorCirculatorTraits<I>::Difference counter = 0;
152 //-----------------------------------------------------------------------------
154 typename DGtal::IteratorCirculatorTraits<C>::Difference
155 DGtal::detail::rangeSize(const C& cb, const C& ce, CirculatorType, ForwardCategory)
157 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<C> ));
159 if (isNotEmpty(cb, ce))
163 typename DGtal::IteratorCirculatorTraits<C>::Difference counter = 0;
177 //-----------------------------------------------------------------------------
179 typename DGtal::IteratorCirculatorTraits<I>::Difference
180 DGtal::detail::rangeSize(const I& itb, const I& ite, IteratorType, RandomAccessCategory)
182 BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> ));
183 ASSERT( itb <= ite );
188 //-----------------------------------------------------------------------------
190 typename DGtal::IteratorCirculatorTraits<C>::Difference
191 DGtal::detail::rangeSize(const C& cb, const C& ce, CirculatorType, RandomAccessCategory)
193 BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<C> ));
195 if (isNotEmpty(cb, ce))
201 return ( (ce - c) + 1 );
214 //-----------------------------------------------------------------------------
215 template<typename IC>
216 IC DGtal::rangeMiddle(const IC& itb, const IC& ite)
218 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<IC> ));
220 typedef typename IteratorCirculatorTraits<IC>::Type Type;
221 typedef typename IteratorCirculatorTraits<IC>::Category Category;
222 return DGtal::detail::rangeMiddle( itb, ite, Type(), Category() );
225 //-----------------------------------------------------------------------------
226 template<typename IC>
227 IC DGtal::subRangeMiddle(const IC& itb, const IC& ite)
229 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<IC> ));
231 typedef typename IteratorCirculatorTraits<IC>::Category Category;
232 return DGtal::detail::rangeMiddle( itb, ite, IteratorType(), Category() );
235 //-----------------------------------------------------------------------------
237 I DGtal::detail::rangeMiddle(const I& itb, const I& ite, IteratorType, ForwardCategory)
239 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<I> ));
242 typename DGtal::IteratorCirculatorTraits<I>::Difference s
243 = DGtal::detail::rangeSize(itb, ite, IteratorType(), ForwardCategory());
245 typename DGtal::IteratorCirculatorTraits<I>::Difference m
247 //advance until the middle
249 DGtal::detail::advanceIterator(i, m, ForwardCategory());
253 //-----------------------------------------------------------------------------
255 C DGtal::detail::rangeMiddle(const C& cb, const C& ce, CirculatorType, ForwardCategory)
257 BOOST_CONCEPT_ASSERT(( boost_concepts::ForwardTraversalConcept<C> ));
260 typename DGtal::IteratorCirculatorTraits<C>::Difference s
261 = DGtal::detail::rangeSize(cb, ce, CirculatorType(), ForwardCategory());
263 typename DGtal::IteratorCirculatorTraits<C>::Difference m
265 //advance until the middle
267 DGtal::detail::advanceIterator(c, m, ForwardCategory());
271 //-----------------------------------------------------------------------------
273 I DGtal::detail::rangeMiddle(const I& itb, const I& ite, IteratorType, BidirectionalCategory)
275 BOOST_CONCEPT_ASSERT(( boost_concepts::BidirectionalTraversalConcept<I> ));
293 //-----------------------------------------------------------------------------
295 C DGtal::detail::rangeMiddle(const C& cb, const C& ce, CirculatorType, BidirectionalCategory)
297 BOOST_CONCEPT_ASSERT(( boost_concepts::BidirectionalTraversalConcept<C> ));
299 if (isNotEmpty(cb, ce))
321 //-----------------------------------------------------------------------------
323 I DGtal::detail::rangeMiddle(const I& itb, const I& ite, IteratorType, RandomAccessCategory)
325 BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> ));
326 ASSERT( itb <= ite );
328 return ( itb + (ite-itb)/2 );
331 //-----------------------------------------------------------------------------
333 C DGtal::detail::rangeMiddle(const C& cb, const C& ce, CirculatorType, RandomAccessCategory)
335 BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<C> ));
337 typename DGtal::IteratorCirculatorTraits<C>::Difference s
338 = DGtal::detail::rangeSize(cb, ce, CirculatorType(), RandomAccessCategory());
339 return ( cb + (s/2) );
343 ///////////////////////////////////////////////////////////////////////////////