$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
internal/comp.hh
1 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_TRAIT_VALUE_INTERNAL_COMP_HH
27 # define MLN_TRAIT_VALUE_INTERNAL_COMP_HH
28 
35 
36 # include <mln/metal/bool.hh>
37 # include <mln/metal/if.hh>
38 
39 
40 
41 
42 namespace mln
43 {
44 
45  namespace trait
46  {
47 
48 
49  // Forward declaration.
50  template <typename V> struct value_;
51 
52 
53  namespace value
54  {
55 
56  namespace internal
57  {
58 
59  // bind_comp< T, i >
60 
61  template <typename T, typename Tr, unsigned i>
62  struct bind_comp;
63 
64  template <typename T, typename Tr>
65  struct bind_comp< T, Tr, 0 >
66  {
67  typedef typename Tr::comp_0 ret;
68  static ret on(const T& v)
69  {
70  return Tr::get_comp_0(v);
71  }
72  };
73 
74  template <typename T, typename Tr>
75  struct bind_comp< T, Tr, 1 >
76  {
77  typedef typename Tr::comp_1 ret;
78  static ret on(const T& v)
79  {
80  return Tr::get_comp_1(v);
81  }
82  };
83 
84  template <typename T, typename Tr>
85  struct bind_comp< T, Tr, 2 >
86  {
87  typedef typename Tr::comp_2 ret;
88  static ret on(const T& v)
89  {
90  return Tr::get_comp_2(v);
91  }
92  };
93 
94  template <typename T, typename Tr>
95  struct bind_comp< T, Tr, 3 >
96  {
97  typedef typename Tr::comp_3 ret;
98  static ret on(const T& v)
99  {
100  return Tr::get_comp_3(v);
101  }
102  };
103 
104  template <typename T, typename Tr>
105  struct bind_comp< T, Tr, 4 >
106  {
107  typedef typename Tr::comp_4 ret;
108  static ret on(const T& v)
109  {
110  return Tr::get_comp_4(v);
111  }
112  };
113 
114  template <typename T, typename Tr>
115  struct bind_comp< T, Tr, 5 >
116  {
117  typedef typename Tr::comp_5 ret;
118  static ret on(const T& v)
119  {
120  return Tr::get_comp_5(v);
121  }
122  };
123 
124  template <typename T, typename Tr>
125  struct bind_comp< T, Tr, 6 >
126  {
127  typedef typename Tr::comp_6 ret;
128  static ret on(const T& v)
129  {
130  return Tr::get_comp_6(v);
131  }
132  };
133 
134  template <typename T, typename Tr>
135  struct bind_comp< T, Tr, 7 >
136  {
137  typedef typename Tr::comp_7 ret;
138  static ret on(const T& v)
139  {
140  return Tr::get_comp_7(v);
141  }
142  };
143 
144  template <typename T, typename Tr>
145  struct bind_comp< T, Tr, 8 >
146  {
147  typedef typename Tr::comp_8 ret;
148  static ret on(const T& v)
149  {
150  return Tr::get_comp_8(v);
151  }
152  };
153 
154  template <typename T, typename Tr>
155  struct bind_comp< T, Tr, 9 >
156  {
157  typedef typename Tr::comp_9 ret;
158  static ret on(const T& v)
159  {
160  return Tr::get_comp_9(v);
161  }
162  };
163 
164 
165  // get_comp< T, i, dim >
166 
167  template <typename T, typename C, typename Tr, unsigned i>
168  struct get_comp_helper
169  {
170  typedef C ret;
171  static ret on(const T& v)
172  {
173  return v[i];
174  }
175  };
176 
177  template <typename T, typename Tr, unsigned i>
178  struct get_comp_helper< T, void, Tr, i >
179  {
180  typedef bind_comp<T, Tr, i> helper;
181  typedef typename helper::ret ret;
182  static ret on(const T& v)
183  {
184  return helper::on(v);
185  }
186  };
187 
188 
189  // Technical note:
190  //
191  // We distinguish between a type T being a C-array type (T =
192  // U[dim]) and T a "regular" type (meaning "not a C-array
193  // type"). We have two stages to help g++-3.3 which has
194  // difficulty in solving such partial specializations.
195 
196  // Regular case.
197 
198  template <typename T, unsigned i, unsigned dim>
199  struct get_comp_with_regular_
200  {
201  typedef mln::trait::value_<T> Tr;
202  typedef typename Tr::comp C;
203  typedef get_comp_helper<T, C, Tr, i> helper;
204  typedef typename helper::ret ret;
205 
206  static ret on(const T& v)
207  {
208  return helper::on(v);
209  }
210  };
211 
212  template <typename T>
213  struct get_comp_with_regular_< T, 0, 1 >
214  {
215  typedef T ret;
216 
217  static ret on(const T& v)
218  {
219  return v;
220  }
221  };
222 
223  template <typename T, unsigned i, unsigned dim>
224  struct get_comp : get_comp_with_regular_<T, i, dim>
225  {
226  };
227 
228  // C-array case.
229 
230  template <typename T, unsigned i, unsigned dim>
231  struct get_comp_with_C_array
232  {
233  typedef T ret;
234 
235  static ret on(const T (&v)[dim])
236  {
237  return v[i];
238  }
239  };
240 
241  template <typename T, unsigned i, unsigned dim>
242  struct get_comp< T[dim], i, dim > : get_comp_with_C_array<T, i, dim>
243  {
244  };
245 
246 
247 
248  // comp< T, i >
249 
250  template <typename T, unsigned i>
251  struct comp
252  : private metal::bool_< (i < mln::trait::value_<T>::dim) >::check_t
253  {
254  enum { dim = mln::trait::value_<T>::dim };
255  typedef get_comp<T, i, dim> helper;
256  typedef typename helper::ret ret;
257 
258  static ret on(const T& v)
259  {
260  return helper::on(v);
261  }
262  };
263 
264  } // end of namespace mln::trait::value::internal
265 
266  } // end of namespace mln::trait::value
267 
268  } // end of namespace mln::trait
269 
270 } // end of namespace mln
271 
272 
273 
274 #endif // ! MLN_TRAIT_VALUE_INTERNAL_COMP_HH