/** @file iterator.hpp * Implementation of adaptors to help common * objects manipulation */ #pragma once #include #include namespace cdt{ template struct type_if_else{}; template struct type_if_else{ typedef A type; }; template struct type_if_else{ typedef B type; }; /* * adaptors for CGAL * ----------------- */ template class vertices_iterator_adaptor{ protected: T& m_reference; public: explicit vertices_iterator_adaptor(T& a_reference) noexcept : m_reference(a_reference) {} virtual ~vertices_iterator_adaptor() = default; auto begin() { return m_reference.vertices_begin(); } auto begin() const { return m_reference.vertices_begin(); } auto end() { return m_reference.vertices_end(); } auto end() const { return m_reference.vertices_end(); } }; template class holes_iterator_adaptor{ protected: T& m_reference; public: explicit holes_iterator_adaptor(T& a_reference) noexcept : m_reference(a_reference) {} virtual ~holes_iterator_adaptor() = default; auto begin() { return m_reference.holes_begin(); } auto begin() const { return m_reference.holes_begin(); } auto end() { return m_reference.holes_end(); } auto end() const { return m_reference.holes_end(); } }; template class edges_iterator_adaptor{ protected: T& m_reference; public: explicit edges_iterator_adaptor(T& a_reference) noexcept : m_reference(a_reference) {} virtual ~edges_iterator_adaptor() = default; auto begin() { return m_reference.edges_begin(); } auto begin() const { return m_reference.edges_begin(); } auto end() { return m_reference.edges_end(); } auto end() const { return m_reference.edges_end(); } }; /** * build an adaptor to transverse the vertices of a * CGAL object. */ template auto vertices(T& ref) { return vertices_iterator_adaptor{ref}; } /** * build an adaptor to transverse the holes of a * CGAL object. */ template auto holes(T& ref) { return holes_iterator_adaptor{ref}; } /** * build an adaptor to transverse the edges of a * CGAL object. */ template auto edges(T& ref) { return edges_iterator_adaptor{ref}; } /* * adaptors for opencv * ------------------- */ template class pixels_iterator_adaptor{ public: pixels_iterator_adaptor() = delete; virtual ~pixels_iterator_adaptor() = default; explicit pixels_iterator_adaptor(M& a_reference) noexcept : m_reference(a_reference) {} auto begin() { return m_reference.template begin(); } auto begin() const { return m_reference.template begin(); } auto end() { return m_reference.template end(); } auto end() const { return m_reference.template end(); } protected: M& m_reference; }; /** * build an adaptor to transverse the pixels of an opencv image */ template auto pixels(cv::Mat& img) { return pixels_iterator_adaptor(img); } /** * build an adaptor to transverse the pixels of an opencv image */ template auto pixels(cv::Mat const& img) { return pixels_iterator_adaptor(img); } template class pixel_point_iterator : public I { protected: // type of the reference that will be returned in operator* using return_reference_type = typename type_if_else< std::is_same>::value, T, T const >::type; public: pixel_point_iterator() = delete; virtual ~pixel_point_iterator() = default; pixel_point_iterator( I it, cv::Point2i& a_coordinate, M& a_img) : I(it), m_coordinate(a_coordinate), m_rows(a_img.rows), m_cols(a_img.cols) {} pixel_point_iterator& operator++() { ++m_coordinate.x; if(m_coordinate.x == m_cols){ m_coordinate.x = 0; ++m_coordinate.y; } I::operator++(); return *this; } pixel_point_iterator operator++(int) { ++m_coordinate.x; if(m_coordinate.x == m_cols){ m_coordinate.x = 0; ++m_coordinate.y; } I::operator++(0); return *this; } std::tuple operator*() { return { I::operator*(), m_coordinate }; } protected: cv::Point2i& m_coordinate; int32_t m_rows; int32_t m_cols; }; template class pixel_point_iterator_adaptor{ public: pixel_point_iterator_adaptor() = delete; virtual ~pixel_point_iterator_adaptor() = default; pixel_point_iterator_adaptor(M& a_img) : m_reference(a_img), m_point{0, 0} {} auto begin() { return pixel_point_iterator( m_reference.template begin(), m_point, m_reference ); } auto begin() const { return pixel_point_iterator( m_reference.template begin(), m_point, m_reference ); } auto end() { return pixel_point_iterator( m_reference.template end(), m_point, m_reference ); } auto end() const { return pixel_point_iterator( m_reference.template end(), m_point, m_reference ); } protected: M& m_reference; cv::Point2i m_point; }; /** * build an adaptor to transverse the pixels and the coordinate * of an opencv image */ template auto pixels_at(cv::Mat& img) { return pixel_point_iterator_adaptor< T, cv::MatIterator_, cv::Mat >(img); } /** * build an adaptor to transverse the pixels and the coordinate * of an opencv image */ template auto pixels_at(cv::Mat const& img) { return pixel_point_iterator_adaptor< T, cv::MatConstIterator_, cv::Mat const >(img); } }