face_iter.hh 5.99 KB
Newer Older
1
2
// Copyright (C) 2008, 2009, 2013 EPITA Research and Development
// Laboratory (LRDE)
3
//
4
// This file is part of Olena.
5
//
6
7
8
9
10
// Olena is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, version 2 of the License.
//
// Olena is distributed in the hope that it will be useful,
11
12
13
14
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
16
// along with Olena.  If not, see <http://www.gnu.org/licenses/>.
17
18
//
// As a special exception, you may use this file as part of a free
19
// software project without restriction.  Specifically, if other files
20
// instantiate templates or use macros or inline functions from this
21
22
23
24
25
// file, or you compile this file and link it with other files to produce
// an executable, this file does not by itself cause the resulting
// executable to be covered by the GNU General Public License.  This
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
26

27
28
#ifndef MLN_TOPO_FACE_ITER_HH
# define MLN_TOPO_FACE_ITER_HH
29

30
/// \file
31
32
///
/// \brief Definition of forward and backward iterators on all the
33
/// faces of a complex.
34

35
# include <mln/topo/internal/complex_set_iterator_base.hh>
Roland Levillain's avatar
Roland Levillain committed
36
# include <mln/topo/face.hh>
Guillaume Lazzara's avatar
Guillaume Lazzara committed
37
# include <mln/topo/face_iter.hh>
38

39
// FIXME: Factor a bit more? (Using complex_set_iterator_base.)
40
41
42
43
44
45
46
47


namespace mln
{

  namespace topo
  {

Guillaume Lazzara's avatar
Guillaume Lazzara committed
48
    // Forward declarations.
49
50
    template <unsigned D> class complex;

Guillaume Lazzara's avatar
Guillaume Lazzara committed
51
52
53
54
55
56
57
58
    namespace internal
    {

      template <typename F, typename E>
      class complex_set_iterator_base;

    } // end of namespace mln::topo::internal

59

60
61
62
    /*-------------------------.
    | topo::face_fwd_iter<D>.  |
    `-------------------------*/
63

64
65
    /// \brief Forward iterator on all the faces of an
    /// mln::complex<D>.
66
    ///
67
    /// \tparam D The dimension of the complex this iterator belongs to.
68
    //
69
    template <unsigned D>
70
    class face_fwd_iter
71
      : public internal::complex_set_iterator_base< topo::face<D>, face_fwd_iter<D> >
72
    {
73
      // Tech note: we use topo::face to help g++-2.95.
74
    private:
75
      typedef face_fwd_iter<D> self_;
76
      typedef internal::complex_set_iterator_base< topo::face<D>, self_ > super_;
77
78
79
80
81
82
83
84

    public:
      using super_::is_valid;
      using super_::invalidate;

    public:
      /// Construction and assignment.
      /// \{
85
      face_fwd_iter();
86
87
      // FIXME: See comment in internal::complex_set_iterator_base's
      // default ctor.
88
      face_fwd_iter(complex<D>& c);
89
90
91
92
93
94
95
96
97
98
99
      /// \}

      /// Manipulation.
      /// \{
      /// Test if the iterator is valid.
      void start();
      /// Go to the next point.
      void next_();
      /// \}

    private:
100
      using super_::f_;
101
102
103
    };


104
105
106
    /*-------------------------.
    | topo::face_bkd_iter<D>.  |
    `-------------------------*/
107

108
    /// \brief Backward iterator on all the faces of an mln::complex<D>.
109
    ///
110
    /// \tparam D The dimension of the complex this iterator belongs to.
111
    //
112
    template <unsigned D>
113
    class face_bkd_iter
114
    : public internal::complex_set_iterator_base< topo::face<D>, face_bkd_iter<D> >
115
    {
116
      // Tech note: we use topo::face to help g++-2.95.
117
    private:
118
      typedef face_bkd_iter<D> self_;
119
      typedef internal::complex_set_iterator_base< topo::face<D>, self_ > super_;
120
121
122
123
124
125
126
127

    public:
      using super_::is_valid;
      using super_::invalidate;

    public:
      /// Construction and assignment.
      /// \{
128
      face_bkd_iter();
129
130
      // FIXME: See comment in internal::complex_set_iterator_base's
      // default ctor.
131
      face_bkd_iter(complex<D>& c);
132
133
134
135
136
137
138
139
140
141
142
      /// \}

      /// Manipulation.
      /// \{
      /// Start an iteration.
      void start();
      /// Go to the next point.
      void next_();
      /// \}

    private:
143
      using super_::f_;
144
145
146
147
148
149
    };



# ifndef MLN_INCLUDE_ONLY

150
151
152
    /*-------------------------.
    | topo::face_fwd_iter<D>.  |
    `-------------------------*/
153
154
155

    template <unsigned D>
    inline
156
    face_fwd_iter<D>::face_fwd_iter()
157
158
159
160
161
162
      : super_()
    {
    }

    template <unsigned D>
    inline
163
    face_fwd_iter<D>::face_fwd_iter(complex<D>& c)
164
165
      : super_(c)
    {
166
      this->set_cplx(c);
167
168
169
170
171
172
      mln_postcondition(!is_valid());
    }

    template <unsigned D>
    inline
    void
173
    face_fwd_iter<D>::start()
174
    {
175
176
      f_.set_n(0u);
      f_.set_face_id(0u);
177
178
179
180
181
    }

    template <unsigned D>
    inline
    void
182
    face_fwd_iter<D>::next_()
183
184
185
    {
      if (is_valid())
	{
186
	  if (f_.face_id() + 1 < f_.cplx().nfaces_of_dim(f_.n()))
187
	    f_.inc_face_id();
188
189
190
	  else
	    // Start to iterate on the faces of the next dimension if
	    // possible.
191
	    if (f_.n() <= D)
192
	      {
193
		f_.inc_n();
194
		f_.set_face_id(0u);
195
196
197
198
199
200
201
	      }
	    else
	      invalidate();
	}
    }


202
203
204
    /*-------------------------.
    | topo::face_bkd_iter<D>.  |
    `-------------------------*/
205
206
207

    template <unsigned D>
    inline
208
    face_bkd_iter<D>::face_bkd_iter()
209
210
211
212
213
214
      : super_()
    {
    }

    template <unsigned D>
    inline
215
    face_bkd_iter<D>::face_bkd_iter(complex<D>& c)
216
217
      : super_(c)
    {
218
      this->set_cplx(c);
219
220
221
222
223
224
      mln_postcondition(!is_valid());
    }

    template <unsigned D>
    inline
    void
225
    face_bkd_iter<D>::start()
226
    {
227
      f_.set_n(D);
228
      f_.set_face_id(f_.cplx().template nfaces_of_static_dim<D>() - 1);
229
230
231
232
233
    }

    template <unsigned D>
    inline
    void
234
    face_bkd_iter<D>::next_()
235
236
237
    {
      if (is_valid())
	{
238
239
	  if (f_.face_id() > 0)
	    f_.dec_face_id();
240
241
242
	  else
	    // Start to iterate on the faces of the previous dimension
	    // if it exists.
243
	    if (f_.n() > 0)
244
	      {
245
		f_.dec_n();
246
		f_.set_face_id(f_.cplx().nfaces_of_dim(f_.n()) - 1);
247
248
249
250
251
252
253
254
255
256
257
258
	      }
	    else
	      invalidate();
	}
    }

# endif // ! MLN_INCLUDE_ONLY

  } // end of namespace mln::topo

} // end of namespace mln

259
#endif // ! MLN_TOPO_FACE_ITER_HH