face_iter.hh 6.22 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library.  This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License version 2 as published by the
// Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// 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
// along with this library; see the file COPYING.  If not, write to
// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
// Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// 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.
// reasons why the executable file might be covered by the GNU General
// Public License.

28
29
#ifndef MLN_TOPO_FACE_ITER_HH
# define MLN_TOPO_FACE_ITER_HH
30

31
32
33
/// \file mln/topo/face_iter.hh
/// \brief Definition of forward and backward iterators on all the
/// faces of a complex.
34
35

# include <mln/topo/internal/complex_iter_base.hh>
Roland Levillain's avatar
Roland Levillain committed
36
# include <mln/topo/face.hh>
37

38
// FIXME: Factor a bit more? (Using complex_iter_base.)
39
40
41
42
43
44
45
46
47
48
49
50


namespace mln
{

  namespace topo
  {

    // Forward declaration.
    template <unsigned D> class complex;


51
52
53
    /*-------------------------.
    | topo::face_fwd_iter<D>.  |
    `-------------------------*/
54

55
    /// \brief Forward iterator on all the faces of an mln::complex<D>.
56
57
58
    ///
    /// \arg \p D The dimension of the complex this iterator belongs to.
    template <unsigned D>
59
60
    class face_fwd_iter
      : public internal::complex_iter_base< face<D>, face_fwd_iter<D> >
61
62
    {
    private:
63
      typedef face_fwd_iter<D> self_;
64
      typedef internal::complex_iter_base< face<D>, self_ > super_;
65
66
67
68
69
70
71
72

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

    public:
      /// Construction and assignment.
      /// \{
73
      face_fwd_iter();
74
      // FIXME: See comment in internal::complex_iter_base's default ctor
75
      face_fwd_iter(complex<D>& c);
76
77
78
79
80
81
82
83
84
85
86
      /// \}

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

    private:
87
      using super_::f_;
88
89
90
    };


91
92
93
    /*-------------------------.
    | topo::face_bkd_iter<D>.  |
    `-------------------------*/
94

95
    /// \brief Backward iterator on all the faces of an mln::complex<D>.
96
97
98
    ///
    /// \arg \p D The dimension of the complex this iterator belongs to.
    template <unsigned D>
99
100
    class face_bkd_iter
    : public internal::complex_iter_base< face<D>, face_bkd_iter<D> >
101
102
    {
    private:
103
      typedef face_bkd_iter<D> self_;
104
      typedef internal::complex_iter_base< face<D>, self_ > super_;
105
106
107
108
109
110
111
112

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

    public:
      /// Construction and assignment.
      /// \{
113
      face_bkd_iter();
114
      // FIXME: See comment in internal::complex_iter_base's default ctor
115
      face_bkd_iter(complex<D>& c);
116
117
118
119
120
121
122
123
124
125
126
      /// \}

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

    private:
127
      using super_::f_;
128
129
130
131
132
133
    };



# ifndef MLN_INCLUDE_ONLY

134
135
136
    /*-------------------------.
    | topo::face_fwd_iter<D>.  |
    `-------------------------*/
137
138
139

    template <unsigned D>
    inline
140
    face_fwd_iter<D>::face_fwd_iter()
141
142
143
144
145
146
      : super_()
    {
    }

    template <unsigned D>
    inline
147
    face_fwd_iter<D>::face_fwd_iter(complex<D>& c)
148
149
150
151
152
153
154
155
156
      : super_(c)
    {
      set_cplx(c);
      mln_postcondition(!is_valid());
    }

    template <unsigned D>
    inline
    void
157
    face_fwd_iter<D>::start()
158
    {
159
160
      f_.set_n(0u);
      f_.set_face_id(0u);
161
162
163
164
165
    }

    template <unsigned D>
    inline
    void
166
    face_fwd_iter<D>::next_()
167
168
169
    {
      if (is_valid())
	{
170
171
	  unsigned n = f_.n();
	  unsigned face_id = f_.face_id();
172

173
	  if (face_id + 1 < f_.cplx().nfaces(n))
174
	    /* FIXME: Provide accessor face::face_id() returning
175
176
	       a mutable reference?  This way, we could just write

177
	       ++f_.face_id();
178
179
180
181

	       instead of the following.

	       Or add {inc,add}_face_id() services.  */
182
	    f_.set_face_id(face_id + 1);
183
184
185
186
187
188
	  else
	    // Start to iterate on the faces of the next dimension if
	    // possible.
	    if (n <= D)
	      {
		// FIXME: Same remark as above.
189
190
		f_.set_n(n + 1);
		f_.set_face_id(0u);
191
192
193
194
195
196
197
	      }
	    else
	      invalidate();
	}
    }


198
199
200
    /*-------------------------.
    | topo::face_bkd_iter<D>.  |
    `-------------------------*/
201
202
203

    template <unsigned D>
    inline
204
    face_bkd_iter<D>::face_bkd_iter()
205
206
207
208
209
210
      : super_()
    {
    }

    template <unsigned D>
    inline
211
    face_bkd_iter<D>::face_bkd_iter(complex<D>& c)
212
213
214
215
216
217
218
219
220
      : super_(c)
    {
      set_cplx(c);
      mln_postcondition(!is_valid());
    }

    template <unsigned D>
    inline
    void
221
    face_bkd_iter<D>::start()
222
    {
223
224
      f_.set_n(D);
      f_.set_face_id(f_.cplx().template nfaces<D>() - 1);
225
226
227
228
229
    }

    template <unsigned D>
    inline
    void
230
    face_bkd_iter<D>::next_()
231
232
233
    {
      if (is_valid())
	{
234
235
	  unsigned n = f_.n();
	  unsigned face_id = f_.face_id();
236
237

	  if (face_id > 0)
238
	    /* FIXME: Provide accessor face::face_id() returning
239
240
	       a mutable reference?  This way, we could just write

241
	       ++f_.face_id();
242
243
244
245

	       instead of the following.

	       Or add {inc,add}_face_id() services.  */
246
	    f_.set_face_id(face_id - 1);
247
248
249
250
251
252
	  else
	    // Start to iterate on the faces of the previous dimension
	    // if it exists.
	    if (n > 0)
	      {
		// FIXME: Same remark as above.
253
254
		f_.set_n(n - 1);
		f_.set_face_id(f_.cplx().nfaces(n - 1) - 1);
255
256
257
258
259
260
261
262
263
264
265
266
	      }
	    else
	      invalidate();
	}
    }

# endif // ! MLN_INCLUDE_ONLY

  } // end of namespace mln::topo

} // end of namespace mln

267
#endif // ! MLN_TOPO_FACE_ITER_HH