// // Copyright 2005-2007 Adobe Systems Incorporated // // Distributed under the Boost Software License, Version 1.0 // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // #ifndef BOOST_GIL_CONCEPTS_PIXEL_ITERATOR_HPP #define BOOST_GIL_CONCEPTS_PIXEL_ITERATOR_HPP #include #include #include #include #include #include #include #include #include #include #if defined(BOOST_CLANG) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-local-typedefs" #endif #if defined(BOOST_GCC) && (BOOST_GCC >= 40900) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #endif namespace boost { namespace gil { // Forward declarations template struct const_iterator_type; template struct iterator_is_mutable; template struct is_iterator_adaptor; template struct iterator_adaptor_rebind; template struct iterator_adaptor_get_base; // These iterator mutability concepts are taken from Boost concept_check.hpp. // Isolating mutability to result in faster compile time namespace detail { // Preconditions: TT Models boost_concepts::ForwardTraversalConcept template struct ForwardIteratorIsMutableConcept { void constraints() { auto const tmp = *i; *i++ = tmp; // require postincrement and assignment } TT i; }; // Preconditions: TT Models boost::BidirectionalIteratorConcept template struct BidirectionalIteratorIsMutableConcept { void constraints() { gil_function_requires< ForwardIteratorIsMutableConcept>(); auto const tmp = *i; *i-- = tmp; // require postdecrement and assignment } TT i; }; // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept template struct RandomAccessIteratorIsMutableConcept { void constraints() { gil_function_requires>(); typename std::iterator_traits::difference_type n = 0; ignore_unused_variable_warning(n); i[n] = *i; // require element access and assignment } TT i; }; // Iterators that can be used as the base of memory_based_step_iterator require some additional functions // \tparam Iterator Models boost_concepts::RandomAccessTraversalConcept template struct RandomAccessIteratorIsMemoryBasedConcept { void constraints() { std::ptrdiff_t bs = memunit_step(it); ignore_unused_variable_warning(bs); it = memunit_advanced(it, 3); std::ptrdiff_t bd = memunit_distance(it, it); ignore_unused_variable_warning(bd); memunit_advance(it,3); // for performace you may also provide a customized implementation of memunit_advanced_ref } Iterator it; }; /// \tparam Iterator Models PixelIteratorConcept template struct PixelIteratorIsMutableConcept { void constraints() { gil_function_requires>(); using ref_t = typename std::remove_reference < typename std::iterator_traits::reference >::type; using channel_t = typename element_type::type; gil_function_requires>(); } }; } // namespace detail /// \ingroup PixelLocatorConcept /// \brief Concept for locators and views that can define a type just like the given locator or view, except X and Y is swapped /// \code /// concept HasTransposedTypeConcept /// { /// typename transposed_type; /// where Metafunction >; /// }; /// \endcode template struct HasTransposedTypeConcept { void constraints() { using type = typename transposed_type::type; ignore_unused_variable_warning(type{}); } }; /// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept /// \ingroup PixelIteratorConcept /// \brief STL iterator over pixels /// \ingroup PixelIteratorConceptPixelIterator /// \brief An STL random access traversal iterator over a model of PixelConcept. /// /// GIL's iterators must also provide the following metafunctions: /// - \p const_iterator_type: Returns a read-only equivalent of \p Iterator /// - \p iterator_is_mutable: Returns whether the given iterator is read-only or mutable /// - \p is_iterator_adaptor: Returns whether the given iterator is an adaptor over another iterator. See IteratorAdaptorConcept for additional requirements of adaptors. /// /// \code /// concept PixelIteratorConcept /// : boost_concepts::RandomAccessTraversalConcept, PixelBasedConcept /// { /// where PixelValueConcept; /// typename const_iterator_type::type; /// where PixelIteratorConcept::type>; /// static const bool iterator_is_mutable::value; /// static const bool is_iterator_adaptor::value; // is it an iterator adaptor /// }; /// \endcode template struct PixelIteratorConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); using value_type = typename std::iterator_traits::value_type; gil_function_requires>(); using const_t = typename const_iterator_type::type; static bool const is_mutable = iterator_is_mutable::value; ignore_unused_variable_warning(is_mutable); // immutable iterator must be constructible from (possibly mutable) iterator const_t const_it(it); ignore_unused_variable_warning(const_it); check_base(typename is_iterator_adaptor::type()); } void check_base(std::false_type) {} void check_base(std::true_type) { using base_t = typename iterator_adaptor_get_base::type; gil_function_requires>(); } Iterator it; }; /// \brief Pixel iterator that allows for changing its pixel /// \ingroup PixelIteratorConceptPixelIterator /// \code /// concept MutablePixelIteratorConcept /// : MutableRandomAccessIteratorConcept {}; /// \endcode template struct MutablePixelIteratorConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); } }; /// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept /// \ingroup PixelIteratorConcept /// \brief Iterator that advances by a specified step /// \ingroup PixelIteratorConceptStepIterator /// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits) /// \code /// concept MemoryBasedIteratorConcept /// { /// typename byte_to_memunit; where metafunction >; /// std::ptrdiff_t memunit_step(const Iterator&); /// std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&); /// void memunit_advance(Iterator&, std::ptrdiff_t diff); /// Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; } /// Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); } /// }; /// \endcode template struct MemoryBasedIteratorConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); } }; /// \ingroup PixelIteratorConceptStepIterator /// \brief Step iterator concept /// /// Step iterators are iterators that have a set_step method /// \code /// concept StepIteratorConcept /// { /// template /// void Iterator::set_step(D step); /// }; /// \endcode template struct StepIteratorConcept { void constraints() { gil_function_requires>(); it.set_step(0); } Iterator it; }; /// \ingroup PixelIteratorConceptStepIterator /// \brief Step iterator that allows for modifying its current value /// \code /// concept MutableStepIteratorConcept /// : StepIteratorConcept {}; /// \endcode template struct MutableStepIteratorConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); } }; /// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept /// \ingroup PixelIteratorConcept /// \brief Adaptor over another iterator /// \ingroup PixelIteratorConceptIteratorAdaptor /// \brief Iterator adaptor is a forward iterator adapting another forward iterator. /// /// In addition to GIL iterator requirements, /// GIL iterator adaptors must provide the following metafunctions: /// - \p is_iterator_adaptor: Returns \p std::true_type /// - \p iterator_adaptor_get_base: Returns the base iterator type /// - \p iterator_adaptor_rebind: Replaces the base iterator with the new one /// /// The adaptee can be obtained from the iterator via the "base()" method. /// /// \code /// concept IteratorAdaptorConcept /// { /// where SameType::type, std::true_type>; /// /// typename iterator_adaptor_get_base; /// where Metafunction >; /// where boost_concepts::ForwardTraversalConcept::type>; /// /// typename another_iterator; /// typename iterator_adaptor_rebind::type; /// where boost_concepts::ForwardTraversalConcept; /// where IteratorAdaptorConcept::type>; /// /// const iterator_adaptor_get_base::type& Iterator::base() const; /// }; /// \endcode template struct IteratorAdaptorConcept { void constraints() { gil_function_requires>(); using base_t = typename iterator_adaptor_get_base::type; gil_function_requires>(); static_assert(is_iterator_adaptor::value, ""); using rebind_t = typename iterator_adaptor_rebind::type; base_t base = it.base(); ignore_unused_variable_warning(base); } Iterator it; }; /// \brief Iterator adaptor that is mutable /// \ingroup PixelIteratorConceptIteratorAdaptor /// \code /// concept MutableIteratorAdaptorConcept /// : IteratorAdaptorConcept {}; /// \endcode template struct MutableIteratorAdaptorConcept { void constraints() { gil_function_requires>(); gil_function_requires>(); } }; }} // namespace boost::gil #if defined(BOOST_CLANG) #pragma clang diagnostic pop #endif #if defined(BOOST_GCC) && (BOOST_GCC >= 40900) #pragma GCC diagnostic pop #endif #endif