00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_VALUE_STACK_HH
00028 # define MLN_VALUE_STACK_HH
00029
00033
00034 # include <mln/core/internal/image_value_morpher.hh>
00035
00036 # include <mln/algebra/vec.hh>
00037 # include <mln/value/set.hh>
00038 # include <mln/value/proxy.hh>
00039
00040
00041 namespace mln
00042 {
00043
00044
00045 namespace value { template <unsigned n, typename I> struct stack_image; }
00046
00047 namespace internal
00048 {
00049
00050
00053 template <unsigned n, typename I>
00054 struct data< value::stack_image<n, I> >
00055 {
00056 public:
00057 data(const algebra::vec<n,I>& imas);
00058 algebra::vec<n,I> imas_;
00059 I& ima_;
00060 };
00061
00062 }
00063
00064 namespace value
00065 {
00066
00067 namespace internal
00068 {
00069 template <unsigned n, typename I>
00070 struct helper_stack_image_lvalue_
00071 {
00072 typedef value::proxy< stack_image<n,I> > ret;
00073 static ret make(stack_image<n,I>& ima, const mln_psite(I)& p)
00074 {
00075 ret tmp(ima, p);
00076 return tmp;
00077 }
00078 };
00079
00080 template <unsigned n, typename I>
00081 struct helper_stack_image_lvalue_< n, const I >
00082 {
00083 typedef algebra::vec<n, mln_value(I)> ret;
00084 static ret make(stack_image<n, const I>& ima, const mln_psite(I)& p)
00085 {
00086 return ima.read_(p);
00087 }
00088 };
00089
00090
00091 }
00092
00093 }
00094
00095
00096 namespace trait
00097 {
00098
00099 template <unsigned n, typename I>
00100 struct image_< mln::value::stack_image<n, I> >
00101 : default_image_morpher< I,
00102 algebra::vec<n, mln_value(I)>,
00103 mln::value::stack_image<n, I> >
00104 {
00105
00106
00107 typedef trait::image::category::value_morpher category;
00108
00109 typedef trait::image::nature::vectorial nature;
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 typedef trait::image::speed::fast speed;
00124 };
00125
00126 }
00127
00128
00129 namespace value
00130 {
00144 template <unsigned n, typename I>
00145 struct stack_image
00146 : public mln::internal::image_value_morpher< I,
00147 algebra::vec<n, mln_value(I)>,
00148 stack_image<n,I> >
00149 {
00151 typedef mln_psite(I) psite;
00152
00154 typedef mln_domain(I) domain_t;
00155
00157 typedef algebra::vec<n, mln_value(I)> value;
00158
00163 typedef value rvalue;
00164
00166 typedef typename internal::helper_stack_image_lvalue_<n,I>::ret lvalue;
00167
00168
00170 typedef stack_image< n, tag::image_<I> > skeleton;
00171
00172
00175 stack_image(const algebra::vec<n,I>& imas);
00176 stack_image();
00178
00180 void init_(const algebra::vec<n,I>& imas);
00181
00183 bool is_valid() const;
00184
00186 rvalue operator()(const psite& p) const;
00187 rvalue read_(const psite& p) const;
00188
00190 lvalue operator()(const psite&);
00191 void write_(const psite& p, const value& v);
00192 };
00193
00195 template <typename I>
00196 stack_image<2, const I>
00197 stack(const Image<I>& ima1, const Image<I>& ima2);
00198
00199
00200 template <typename I>
00201 stack_image<2, I>
00202 stack(Image<I>& ima1, Image<I>& ima2);
00204
00205 }
00206
00207 # ifndef MLN_INCLUDE_ONLY
00208
00209 namespace internal
00210 {
00211
00212
00213 template <unsigned n, typename I>
00214 inline
00215 data< value::stack_image<n,I> >::data(const algebra::vec<n,I>& imas)
00216 : imas_(imas),
00217 ima_(imas_[0])
00218 {
00219 }
00220
00221 }
00222
00223
00224 namespace value
00225 {
00226
00227
00228 template <unsigned n, typename I>
00229 inline
00230 stack_image<n,I>::stack_image()
00231 {
00232 }
00233
00234 template <unsigned n, typename I>
00235 inline
00236 stack_image<n,I>::stack_image(const algebra::vec<n,I>& imas)
00237 {
00238 init_(imas);
00239 }
00240
00241 template <unsigned n, typename I>
00242 inline
00243 void
00244 stack_image<n,I>::init_(const algebra::vec<n,I>& imas)
00245 {
00246 this->data_ = new mln::internal::data< stack_image<n, I> >(imas);
00247 for (unsigned i = 0; i < n; ++i)
00248 {
00249 mln_precondition(imas[i].is_valid());
00250 }
00251 }
00252
00253 template <unsigned n, typename I>
00254 inline
00255 bool stack_image<n,I>::is_valid() const
00256 {
00257 for (unsigned i = 0; i < n; ++i)
00258 mln_invariant(this->data_->imas_[i].is_valid());
00259 return true;
00260 }
00261
00262 template <unsigned n, typename I>
00263 inline
00264 typename stack_image<n,I>::rvalue
00265 stack_image<n,I>::read_(const psite& p) const
00266 {
00267 mln_precondition(this->has(p));
00268 algebra::vec<n, mln_value(I)> tmp;
00269 for (unsigned i = 0; i < n; ++i)
00270 tmp[i] = this->data_->imas_[i].operator()(p);
00271 return tmp;
00272 }
00273
00274 template <unsigned n, typename I>
00275 inline
00276 typename stack_image<n,I>::rvalue
00277 stack_image<n,I>::operator()(const psite& p) const
00278 {
00279 return read_(p);
00280 }
00281
00282 template <unsigned n, typename I>
00283 inline
00284 void
00285 stack_image<n,I>::write_(const psite& p, const value& v)
00286 {
00287 mln_precondition(this->has(p));
00288
00289 for (unsigned i = 0; i < n; ++i)
00290 this->data_->imas_[i].operator()(p) = v[i];
00291 }
00292
00293 template <unsigned n, typename I>
00294 inline
00295 typename stack_image<n,I>::lvalue
00296 stack_image<n,I>::operator()(const psite& p)
00297 {
00298 return internal::helper_stack_image_lvalue_<n,I>::make(*this, p);
00299 }
00300
00301
00302
00303 template <typename I>
00304 inline
00305 stack_image<2, const I>
00306 stack(const Image<I>& ima1, const Image<I>& ima2)
00307 {
00308 mln_precondition(exact(ima1).domain() == exact(ima2).domain());
00309 algebra::vec<2, const I> imas;
00310 imas[0] = exact(ima1);
00311 imas[1] = exact(ima2);
00312 return imas;
00313 }
00314
00315 template <typename I>
00316 inline
00317 stack_image<2, I>
00318 stack(Image<I>& ima1, Image<I>& ima2)
00319 {
00320 mln_precondition(exact(ima1).domain() == exact(ima2).domain());
00321 algebra::vec<2, I> imas;
00322 imas[0] = exact(ima1);
00323 imas[1] = exact(ima2);
00324 return imas;
00325 }
00326
00327 }
00328
00329 # endif // ! MLN_INCLUDE_ONLY
00330
00331 }
00332
00333
00334 #endif // ! MLN_VALUE_STACK_HH