IteratorsT.hh 10.5 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
/* ========================================================================= *
Jan Möbius's avatar
Jan Möbius committed
2 3
 *                                                                           *
 *                               OpenMesh                                    *
Jan Möbius's avatar
Jan Möbius committed
4
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
Jan Möbius's avatar
Typo  
Jan Möbius committed
5
 *           Department of Computer Graphics and Multimedia                  *
Jan Möbius's avatar
Jan Möbius committed
6 7
 *                          All rights reserved.                             *
 *                            www.openmesh.org                               *
Jan Möbius's avatar
Jan Möbius committed
8
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
9 10 11
 *---------------------------------------------------------------------------*
 * This file is part of OpenMesh.                                            *
 *---------------------------------------------------------------------------*
Jan Möbius's avatar
Jan Möbius committed
12
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
13 14 15
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
Jan Möbius's avatar
Jan Möbius committed
16
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
17 18
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
Jan Möbius's avatar
Jan Möbius committed
19
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
20 21 22
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
Jan Möbius's avatar
Jan Möbius committed
23
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
24 25 26
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
27
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
28 29 30 31 32 33 34 35 36 37 38
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39 40
 *                                                                           *
 * ========================================================================= */
41 42 43 44 45

/*===========================================================================*\
 *                                                                           *             
 *   $Revision$                                                         *
 *   $Date$                   *
Jan Möbius's avatar
Jan Möbius committed
46 47
 *                                                                           *
\*===========================================================================*/
48

Jan Möbius's avatar
Jan Möbius committed
49 50
#ifndef OPENMESH_ITERATORS_HH
#define OPENMESH_ITERATORS_HH
51

Jan Möbius's avatar
Jan Möbius committed
52 53 54 55 56 57 58 59 60 61 62 63
//=============================================================================
//
//  Iterators for PolyMesh/TriMesh
//
//=============================================================================



//== INCLUDES =================================================================

#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Mesh/Status.hh>
64
#include <cassert>
65
#include <cstddef>
Matthias Möller's avatar
Matthias Möller committed
66
#include <iterator>
Jan Möbius's avatar
Jan Möbius committed
67 68 69 70 71 72 73 74 75 76 77 78


//== NAMESPACES ===============================================================

namespace OpenMesh {
namespace Iterators {


//== FORWARD DECLARATIONS =====================================================


template <class Mesh> class ConstVertexIterT;
79
template <class Mesh> class VertexIterT;
Jan Möbius's avatar
Jan Möbius committed
80
template <class Mesh> class ConstHalfedgeIterT;
81
template <class Mesh> class HalfedgeIterT;
Jan Möbius's avatar
Jan Möbius committed
82
template <class Mesh> class ConstEdgeIterT;
83
template <class Mesh> class EdgeIterT;
Jan Möbius's avatar
Jan Möbius committed
84
template <class Mesh> class ConstFaceIterT;
85
template <class Mesh> class FaceIterT;
Jan Möbius's avatar
Jan Möbius committed
86 87


88
template <class Mesh, class ValueHandle, class MemberOwner, bool (MemberOwner::*PrimitiveStatusMember)() const, size_t (MemberOwner::*PrimitiveCountMember)() const>
89
class GenericIteratorT {
90
    public:
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
        //--- Typedefs ---

        typedef ValueHandle                     value_handle;
        typedef value_handle                    value_type;
        typedef std::bidirectional_iterator_tag iterator_category;
        typedef std::ptrdiff_t                  difference_type;
        typedef const value_type&               reference;
        typedef const value_type*               pointer;
        typedef const Mesh*                     mesh_ptr;
        typedef const Mesh&                     mesh_ref;

        /// Default constructor.
        GenericIteratorT()
        : mesh_(0), skip_bits_(0)
        {}

        /// Construct with mesh and a target handle.
        GenericIteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false)
        : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0)
        {
            if (_skip) enable_skipping();
        }

        /// Standard dereferencing operator.
        reference operator*() const {
            return hnd_;
        }

        /// Standard pointer operator.
        pointer operator->() const {
            return &hnd_;
        }

124 125 126 127 128
        /**
         * \brief Get the handle of the item the iterator refers to.
         * \deprecated 
         * This function clutters your code. Use dereferencing operators -> and * instead.
         */
129
        OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
130 131 132 133
        value_handle handle() const {
            return hnd_;
        }

134 135 136 137 138 139
        /**
         * \brief Cast to the handle of the item the iterator refers to.
         * \deprecated
         * Implicit casts of iterators are unsafe. Use dereferencing operators
         * -> and * instead.
         */
140
        OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
        operator value_handle() const {
            return hnd_;
        }

        /// Are two iterators equal? Only valid if they refer to the same mesh!
        bool operator==(const GenericIteratorT& _rhs) const {
            return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_));
        }

        /// Not equal?
        bool operator!=(const GenericIteratorT& _rhs) const {
            return !operator==(_rhs);
        }

        /// Standard pre-increment operator
        GenericIteratorT& operator++() {
            hnd_.__increment();
            if (skip_bits_)
                skip_fwd();
            return *this;
        }

163 164 165 166 167 168 169
        /// Standard post-increment operator
        GenericIteratorT operator++(int) {
            GenericIteratorT cpy(*this);
            ++(*this);
            return cpy;
        }

170
#if ((defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
        template<class T = value_handle>
        auto operator+=(int amount) ->
            typename std::enable_if<
                sizeof(decltype(std::declval<T>().__increment(amount))) >= 0,
                GenericIteratorT&>::type {
            static_assert(std::is_same<T, value_handle>::value,
                    "Template parameter must not deviate from default.");
            if (skip_bits_)
                throw std::logic_error("Skipping iterators do not support "
                        "random access.");
            hnd_.__increment(amount);
            return *this;
        }

        template<class T = value_handle>
        auto operator+(int rhs) ->
            typename std::enable_if<
                sizeof(decltype(std::declval<T>().__increment(rhs), void (), int {})) >= 0,
                GenericIteratorT>::type {
            static_assert(std::is_same<T, value_handle>::value,
                    "Template parameter must not deviate from default.");
            if (skip_bits_)
                throw std::logic_error("Skipping iterators do not support "
                        "random access.");
            GenericIteratorT result = *this;
            result.hnd_.__increment(rhs);
            return result;
        }
#endif

201 202 203 204 205 206 207 208
        /// Standard pre-decrement operator
        GenericIteratorT& operator--() {
            hnd_.__decrement();
            if (skip_bits_)
                skip_bwd();
            return *this;
        }

209 210 211 212 213 214 215
        /// Standard post-decrement operator
        GenericIteratorT operator--(int) {
            GenericIteratorT cpy(*this);
            --(*this);
            return cpy;
        }

216 217
        /// Turn on skipping: automatically skip deleted/hidden elements
        void enable_skipping() {
218
            if (mesh_ && (mesh_->*PrimitiveStatusMember)()) {
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
                Attributes::StatusInfo status;
                status.set_deleted(true);
                status.set_hidden(true);
                skip_bits_ = status.bits();
                skip_fwd();
            } else
                skip_bits_ = 0;
        }

        /// Turn on skipping: automatically skip deleted/hidden elements
        void disable_skipping() {
            skip_bits_ = 0;
        }

    private:

        void skip_fwd() {
            assert(mesh_ && skip_bits_);
237
            while ((hnd_.idx() < (signed) (mesh_->*PrimitiveCountMember)())
238 239 240 241 242 243 244 245 246 247 248 249 250 251
                    && (mesh_->status(hnd_).bits() & skip_bits_))
                hnd_.__increment();
        }

        void skip_bwd() {
            assert(mesh_ && skip_bits_);
            while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_))
                hnd_.__decrement();
        }

    protected:
        mesh_ptr mesh_;
        value_handle hnd_;
        unsigned int skip_bits_;
Jan Möbius's avatar
Jan Möbius committed
252 253 254 255 256 257 258 259
};

//=============================================================================
} // namespace Iterators
} // namespace OpenMesh
//=============================================================================
#endif 
//=============================================================================