2 // Copyright 2005-2007 Adobe Systems Incorporated
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
8 #ifndef BOOST_GIL_CONCEPTS_PIXEL_ITERATOR_HPP
9 #define BOOST_GIL_CONCEPTS_PIXEL_ITERATOR_HPP
11 #include <boost/gil/concepts/channel.hpp>
12 #include <boost/gil/concepts/color.hpp>
13 #include <boost/gil/concepts/concept_check.hpp>
14 #include <boost/gil/concepts/fwd.hpp>
15 #include <boost/gil/concepts/pixel.hpp>
16 #include <boost/gil/concepts/pixel_based.hpp>
18 #include <boost/iterator/iterator_concepts.hpp>
22 #include <type_traits>
24 #if defined(BOOST_CLANG)
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
29 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
30 #pragma GCC diagnostic push
31 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
34 namespace boost { namespace gil {
36 // Forward declarations
37 template <typename It> struct const_iterator_type;
38 template <typename It> struct iterator_is_mutable;
39 template <typename It> struct is_iterator_adaptor;
40 template <typename It, typename NewBaseIt> struct iterator_adaptor_rebind;
41 template <typename It> struct iterator_adaptor_get_base;
43 // These iterator mutability concepts are taken from Boost concept_check.hpp.
44 // Isolating mutability to result in faster compile time
47 // Preconditions: TT Models boost_concepts::ForwardTraversalConcept
49 struct ForwardIteratorIsMutableConcept
54 *i++ = tmp; // require postincrement and assignment
59 // Preconditions: TT Models boost::BidirectionalIteratorConcept
61 struct BidirectionalIteratorIsMutableConcept
65 gil_function_requires< ForwardIteratorIsMutableConcept<TT>>();
67 *i-- = tmp; // require postdecrement and assignment
72 // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept
74 struct RandomAccessIteratorIsMutableConcept
78 gil_function_requires<BidirectionalIteratorIsMutableConcept<TT>>();
80 typename std::iterator_traits<TT>::difference_type n = 0;
81 ignore_unused_variable_warning(n);
82 i[n] = *i; // require element access and assignment
87 // Iterators that can be used as the base of memory_based_step_iterator require some additional functions
88 // \tparam Iterator Models boost_concepts::RandomAccessTraversalConcept
89 template <typename Iterator>
90 struct RandomAccessIteratorIsMemoryBasedConcept
94 std::ptrdiff_t bs = memunit_step(it);
95 ignore_unused_variable_warning(bs);
97 it = memunit_advanced(it, 3);
98 std::ptrdiff_t bd = memunit_distance(it, it);
99 ignore_unused_variable_warning(bd);
101 memunit_advance(it,3);
102 // for performace you may also provide a customized implementation of memunit_advanced_ref
107 /// \tparam Iterator Models PixelIteratorConcept
108 template <typename Iterator>
109 struct PixelIteratorIsMutableConcept
113 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<Iterator>>();
115 using ref_t = typename std::remove_reference
117 typename std::iterator_traits<Iterator>::reference
119 using channel_t = typename element_type<ref_t>::type;
120 gil_function_requires<detail::ChannelIsMutableConcept<channel_t>>();
124 } // namespace detail
126 /// \ingroup PixelLocatorConcept
127 /// \brief Concept for locators and views that can define a type just like the given locator or view, except X and Y is swapped
129 /// concept HasTransposedTypeConcept<typename T>
131 /// typename transposed_type<T>;
132 /// where Metafunction<transposed_type<T> >;
135 template <typename T>
136 struct HasTransposedTypeConcept
140 using type = typename transposed_type<T>::type;
141 ignore_unused_variable_warning(type{});
145 /// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept
146 /// \ingroup PixelIteratorConcept
147 /// \brief STL iterator over pixels
149 /// \ingroup PixelIteratorConceptPixelIterator
150 /// \brief An STL random access traversal iterator over a model of PixelConcept.
152 /// GIL's iterators must also provide the following metafunctions:
153 /// - \p const_iterator_type<Iterator>: Returns a read-only equivalent of \p Iterator
154 /// - \p iterator_is_mutable<Iterator>: Returns whether the given iterator is read-only or mutable
155 /// - \p is_iterator_adaptor<Iterator>: Returns whether the given iterator is an adaptor over another iterator. See IteratorAdaptorConcept for additional requirements of adaptors.
158 /// concept PixelIteratorConcept<typename Iterator>
159 /// : boost_concepts::RandomAccessTraversalConcept<Iterator>, PixelBasedConcept<Iterator>
161 /// where PixelValueConcept<value_type>;
162 /// typename const_iterator_type<It>::type;
163 /// where PixelIteratorConcept<const_iterator_type<It>::type>;
164 /// static const bool iterator_is_mutable<It>::value;
165 /// static const bool is_iterator_adaptor<It>::value; // is it an iterator adaptor
168 template <typename Iterator>
169 struct PixelIteratorConcept
173 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator>>();
174 gil_function_requires<PixelBasedConcept<Iterator>>();
176 using value_type = typename std::iterator_traits<Iterator>::value_type;
177 gil_function_requires<PixelValueConcept<value_type>>();
179 using const_t = typename const_iterator_type<Iterator>::type;
180 static bool const is_mutable = iterator_is_mutable<Iterator>::value;
181 ignore_unused_variable_warning(is_mutable);
183 // immutable iterator must be constructible from (possibly mutable) iterator
184 const_t const_it(it);
185 ignore_unused_variable_warning(const_it);
187 check_base(typename is_iterator_adaptor<Iterator>::type());
190 void check_base(std::false_type) {}
192 void check_base(std::true_type)
194 using base_t = typename iterator_adaptor_get_base<Iterator>::type;
195 gil_function_requires<PixelIteratorConcept<base_t>>();
201 /// \brief Pixel iterator that allows for changing its pixel
202 /// \ingroup PixelIteratorConceptPixelIterator
204 /// concept MutablePixelIteratorConcept<PixelIteratorConcept Iterator>
205 /// : MutableRandomAccessIteratorConcept<Iterator> {};
207 template <typename Iterator>
208 struct MutablePixelIteratorConcept
212 gil_function_requires<PixelIteratorConcept<Iterator>>();
213 gil_function_requires<detail::PixelIteratorIsMutableConcept<Iterator>>();
217 /// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept
218 /// \ingroup PixelIteratorConcept
219 /// \brief Iterator that advances by a specified step
221 /// \ingroup PixelIteratorConceptStepIterator
222 /// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits)
224 /// concept MemoryBasedIteratorConcept<boost_concepts::RandomAccessTraversalConcept Iterator>
226 /// typename byte_to_memunit<Iterator>; where metafunction<byte_to_memunit<Iterator> >;
227 /// std::ptrdiff_t memunit_step(const Iterator&);
228 /// std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&);
229 /// void memunit_advance(Iterator&, std::ptrdiff_t diff);
230 /// Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; }
231 /// Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); }
234 template <typename Iterator>
235 struct MemoryBasedIteratorConcept
239 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator>>();
240 gil_function_requires<detail::RandomAccessIteratorIsMemoryBasedConcept<Iterator>>();
244 /// \ingroup PixelIteratorConceptStepIterator
245 /// \brief Step iterator concept
247 /// Step iterators are iterators that have a set_step method
249 /// concept StepIteratorConcept<boost_concepts::ForwardTraversalConcept Iterator>
251 /// template <Integral D>
252 /// void Iterator::set_step(D step);
255 template <typename Iterator>
256 struct StepIteratorConcept
260 gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator>>();
267 /// \ingroup PixelIteratorConceptStepIterator
268 /// \brief Step iterator that allows for modifying its current value
270 /// concept MutableStepIteratorConcept<Mutable_ForwardIteratorConcept Iterator>
271 /// : StepIteratorConcept<Iterator> {};
273 template <typename Iterator>
274 struct MutableStepIteratorConcept
278 gil_function_requires<StepIteratorConcept<Iterator>>();
279 gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator>>();
283 /// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept
284 /// \ingroup PixelIteratorConcept
285 /// \brief Adaptor over another iterator
287 /// \ingroup PixelIteratorConceptIteratorAdaptor
288 /// \brief Iterator adaptor is a forward iterator adapting another forward iterator.
290 /// In addition to GIL iterator requirements,
291 /// GIL iterator adaptors must provide the following metafunctions:
292 /// - \p is_iterator_adaptor<Iterator>: Returns \p std::true_type
293 /// - \p iterator_adaptor_get_base<Iterator>: Returns the base iterator type
294 /// - \p iterator_adaptor_rebind<Iterator,NewBase>: Replaces the base iterator with the new one
296 /// The adaptee can be obtained from the iterator via the "base()" method.
299 /// concept IteratorAdaptorConcept<boost_concepts::ForwardTraversalConcept Iterator>
301 /// where SameType<is_iterator_adaptor<Iterator>::type, std::true_type>;
303 /// typename iterator_adaptor_get_base<Iterator>;
304 /// where Metafunction<iterator_adaptor_get_base<Iterator> >;
305 /// where boost_concepts::ForwardTraversalConcept<iterator_adaptor_get_base<Iterator>::type>;
307 /// typename another_iterator;
308 /// typename iterator_adaptor_rebind<Iterator,another_iterator>::type;
309 /// where boost_concepts::ForwardTraversalConcept<another_iterator>;
310 /// where IteratorAdaptorConcept<iterator_adaptor_rebind<Iterator,another_iterator>::type>;
312 /// const iterator_adaptor_get_base<Iterator>::type& Iterator::base() const;
315 template <typename Iterator>
316 struct IteratorAdaptorConcept
320 gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator>>();
322 using base_t = typename iterator_adaptor_get_base<Iterator>::type;
323 gil_function_requires<boost_concepts::ForwardTraversalConcept<base_t>>();
325 static_assert(is_iterator_adaptor<Iterator>::value, "");
326 using rebind_t = typename iterator_adaptor_rebind<Iterator, void*>::type;
328 base_t base = it.base();
329 ignore_unused_variable_warning(base);
334 /// \brief Iterator adaptor that is mutable
335 /// \ingroup PixelIteratorConceptIteratorAdaptor
337 /// concept MutableIteratorAdaptorConcept<Mutable_ForwardIteratorConcept Iterator>
338 /// : IteratorAdaptorConcept<Iterator> {};
340 template <typename Iterator>
341 struct MutableIteratorAdaptorConcept
345 gil_function_requires<IteratorAdaptorConcept<Iterator>>();
346 gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator>>();
350 }} // namespace boost::gil
352 #if defined(BOOST_CLANG)
353 #pragma clang diagnostic pop
356 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
357 #pragma GCC diagnostic pop