n_face_iter.hh 7.64 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
29

#ifndef MLN_TOPO_N_FACE_ITER_HH
# define MLN_TOPO_N_FACE_ITER_HH

30
/// \file
Guillaume Lazzara's avatar
Guillaume Lazzara committed
31
///
32
33
/// \brief Definition of forward and backward iterators on all the \a
/// n-faces of a complex, \a n being a dynamic value.
34

35
# include <mln/topo/internal/complex_set_iterator_base.hh>
36
37
# include <mln/topo/face.hh>

Guillaume Lazzara's avatar
Guillaume Lazzara committed
38
// \todo Factor a bit more? (Using complex_set_iterator_base.)
39
40
41
42
43
44
45
46
47
48
49

// FIXME: Rename the old commplex_faces_{fwd,bkd}_iter as
// static_n_face_{fwd,bkd}_iter.


namespace mln
{

  namespace topo
  {

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

Guillaume Lazzara's avatar
Guillaume Lazzara committed
53
54
55
56
57
58
59
60
61
    namespace internal
    {

      // Forward declaration.
      template <typename F, typename E>
      class complex_set_iterator_base;

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

62
63
64
65
66

    /*---------------------------.
    | topo::n_face_fwd_iter<D>.  |
    `---------------------------*/

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

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

    public:
      /// Construction and assignment.
      /// \{
      n_face_fwd_iter();
90
91
      // FIXME: See comment in internal::complex_set_iterator_base's
      // default ctor.
92
93
94
95
96
97
98
99
100
101
102
      n_face_fwd_iter(complex<D>& c, unsigned n);
      /// \}

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

Guillaume Lazzara's avatar
Guillaume Lazzara committed
103
      /// Accessors.
104
105
106
107
108
109
110
      ///
      /// Shortcuts to face_'s accessors.
      /// \{
      unsigned n() const;
      void set_n (unsigned n);
      /// \}

111
112
113
114
    private:
      /// Partially invalidate the iterator (don't alter its dimension).
      void invalidate_face_id_();

115
    private:
116
      using super_::f_;
117
118
119
120
121
122
123
    };


    /*---------------------------.
    | topo::n_face_bkd_iter<D>.  |
    `---------------------------*/

Guillaume Lazzara's avatar
Guillaume Lazzara committed
124
    /// Backward iterator on all the faces of an mln::complex<D>.
125
    ///
126
    /// \tparam D The dimension of the complex this iterator belongs to.
127
128
    template <unsigned D>
    class n_face_bkd_iter
129
      : public internal::complex_set_iterator_base< topo::face<D>,
130
						    n_face_bkd_iter<D> >
131
    {
132
      // Tech note: we use topo::face to help g++-2.95.
133
134
    private:
      typedef n_face_bkd_iter<D> self_;
135
      typedef internal::complex_set_iterator_base< topo::face<D>, self_ > super_;
136
137
138
139
140
141
142
143
144

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

    public:
      /// Construction and assignment.
      /// \{
      n_face_bkd_iter();
145
146
      // FIXME: See comment in internal::complex_set_iterator_base's
      // default ctor.
147
148
149
150
151
152
153
154
155
156
157
      n_face_bkd_iter(complex<D>& c, unsigned n);
      /// \}

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

Guillaume Lazzara's avatar
Guillaume Lazzara committed
158
      /// Accessors.
159
160
161
162
163
164
165
      ///
      /// Shortcuts to face_'s accessors.
      /// \{
      unsigned n() const;
      void set_n (unsigned n);
      /// \}

166
167
168
169
    private:
      /// Partially invalidate the iterator (don't alter its dimension).
      void invalidate_face_id_();

170
    private:
171
      using super_::f_;
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    };



# ifndef MLN_INCLUDE_ONLY

    /*---------------------------.
    | topo::n_face_fwd_iter<D>.  |
    `---------------------------*/

    template <unsigned D>
    inline
    n_face_fwd_iter<D>::n_face_fwd_iter()
      : super_()
    {
    }

    template <unsigned D>
    inline
    n_face_fwd_iter<D>::n_face_fwd_iter(complex<D>& c, unsigned n)
      : super_(c)
    {
      mln_precondition(n <= D);
195
      this->set_cplx(c);
196
197
198
199
200
201
202
203
204
      set_n(n);
      mln_postcondition(!is_valid());
    }

    template <unsigned D>
    inline
    void
    n_face_fwd_iter<D>::start()
    {
205
      f_.set_face_id(0u);
206
207
208
209
210
211
212
213
214
    }

    template <unsigned D>
    inline
    void
    n_face_fwd_iter<D>::next_()
    {
      if (is_valid())
	{
215
	  if (f_.face_id() + 1 < f_.cplx().nfaces_of_dim(n()))
216
	    f_.inc_face_id();
217
	  else
218
219
220
221
	    /* Don't invalidate the whole face if we have reached the
	       last face of the dimension---this would lose the
	       dimension.  Instead, invalidate the face_id only.  */
	    invalidate_face_id_();
222
223
224
	}
    }

225
226
227
228
229
    template <unsigned D>
    inline
    void
    n_face_fwd_iter<D>::invalidate_face_id_()
    {
230
      f_.set_face_id(f_.cplx().nfaces_of_dim(n()));
231
232
    }

233
234
235
236
237
    template <unsigned D>
    inline
    unsigned
    n_face_fwd_iter<D>::n() const
    {
238
      return f_.n();
239
240
241
242
243
244
245
246
    }

    template <unsigned D>
    inline
    void
    n_face_fwd_iter<D>::set_n(unsigned n)
    {
      mln_precondition(n <= D);
247
      f_.set_n(n);
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
    }


    /*---------------------------.
    | topo::n_face_bkd_iter<D>.  |
    `---------------------------*/

    template <unsigned D>
    inline
    n_face_bkd_iter<D>::n_face_bkd_iter()
      : super_()
    {
    }

    template <unsigned D>
    inline
    n_face_bkd_iter<D>::n_face_bkd_iter(complex<D>& c, unsigned n)
      : super_(c)
    {
      mln_precondition(n <= D);
      set_cplx(c);
      set_n(n);
      mln_postcondition(!is_valid());
    }

    template <unsigned D>
    inline
    void
    n_face_bkd_iter<D>::start()
    {
278
      f_.set_face_id(f_.cplx().nfaces_of_dim(n()) - 1);
279
280
281
282
283
284
285
286
287
    }

    template <unsigned D>
    inline
    void
    n_face_bkd_iter<D>::next_()
    {
      if (is_valid())
	{
288
289
	  if (f_.face_id() > 0)
	    f_.dec_face_id();
290
	  else
291
292
293
294
	    /* Don't invalidate the whole face if we have reached the
	       last face of the dimension---this would lose the
	       dimension.  Instead, invalidate the face_id only.  */
	    invalidate_face_id_();
295
296
297
	}
    }

298
299
300
301
302
    template <unsigned D>
    inline
    void
    n_face_bkd_iter<D>::invalidate_face_id_()
    {
303
      f_.set_face_id(f_.cplx().nfaces_of_dim(n()));
304
305
    }

306
307
308
309
310
    template <unsigned D>
    inline
    unsigned
    n_face_bkd_iter<D>::n() const
    {
311
      return f_.n();
312
313
314
315
316
317
318
319
    }

    template <unsigned D>
    inline
    void
    n_face_bkd_iter<D>::set_n(unsigned n)
    {
      mln_precondition(n <= D);
320
      f_.set_n(n);
321
322
323
324
325
326
327
328
329
    }

# endif // ! MLN_INCLUDE_ONLY

  } // end of namespace mln::topo

} // end of namespace mln

#endif // ! MLN_TOPO_N_FACE_ITER_HH