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 #ifndef MLN_CORE_IMAGE_IMORPH_LAZY_IMAGE_HH
00027 # define MLN_CORE_IMAGE_IMORPH_LAZY_IMAGE_HH
00028
00032
00033
00034 # include <cmath>
00035
00036 # include <mln/core/internal/image_identity.hh>
00037 # include <mln/core/alias/box2d.hh>
00038
00039
00040 namespace mln
00041 {
00042
00043
00044 template <typename I, typename F, typename B> struct lazy_image;
00045
00046 namespace internal
00047 {
00048
00050 template <typename I, typename F, typename B>
00051 struct data< lazy_image<I,F,B> >
00052 {
00053 data(const F& fun_, const B& box);
00054
00055 mutable mln_ch_value(I,mln_result(F)) ima_;
00056 mutable mln_ch_value(I,bool) is_known;
00057 const F& fun;
00058 const B& bb_;
00059 };
00060
00061 }
00062
00063
00064
00065 namespace trait
00066 {
00067
00068 template <typename I, typename F, typename B>
00069 struct image_< lazy_image<I,F,B> > : default_image_morpher< I, mln_value(I),
00070 lazy_image<I,F,B> >
00071 {
00072 typedef trait::image::category::domain_morpher category;
00073 typedef trait::image::value_io::read_only value_io;
00074 };
00075
00076 }
00077
00078
00079
00091 template <typename I, typename F, typename B>
00092 struct lazy_image :
00093 public mln::internal::image_identity< mln_ch_value(I, mln_result(F)),
00094 mln_domain(I), lazy_image<I, F,B> >
00095 {
00096 typedef mln::internal::image_identity< mln_ch_value(I, mln_result(F)),
00097 mln_domain(I),
00098 lazy_image<I, F,B> > super_;
00099
00101 typedef mln_result(F) rvalue;
00102
00104 typedef mln_result(F) lvalue;
00105
00107 typedef lazy_image< tag::image_<I>, F, B > skeleton;
00108
00110 using super_::is_valid;
00111
00113 lazy_image();
00114
00116 lazy_image(const F& fun, const B& box);
00117
00119 void init_(const F& fun, const B& box);
00120
00122 const box<mln_psite(I)>& domain() const;
00123
00125 bool has(const mln_psite(I)&) const;
00126
00128 mln_result(F) operator()(const typename F::input& x) const;
00129
00131 mln_result(F) operator()(const typename F::input& x);
00132
00134 rvalue operator()(const mln_psite(I)& p) const;
00135
00137 lvalue operator()(const mln_psite(I)& p);
00138
00139 };
00140
00141
00142
00143 # ifndef MLN_INCLUDE_ONLY
00144
00145 namespace internal
00146 {
00147
00148
00149
00150 template <typename I, typename F, typename B>
00151 inline
00152 data< lazy_image<I,F,B> >::data(const F& fun, const B& box)
00153 : ima_(box), is_known(box), fun(fun), bb_(box)
00154 {
00155 }
00156
00157 }
00158
00159 template <typename I, typename F, typename B>
00160 inline
00161 lazy_image<I,F,B>::lazy_image(const F& fun, const B& box)
00162 {
00163 this->data_ = new internal::data< lazy_image<I,F,B> >(fun, box);
00164 }
00165
00166 template <typename I, typename F, typename B>
00167 inline
00168 void lazy_image<I,F,B>::init_(const F& fun, const B& box)
00169 {
00170 this->data_ = new internal::data< lazy_image<I,F,B> >(fun, box);
00171 }
00172
00173 template <typename I, typename F, typename B>
00174 inline
00175 bool lazy_image<I,F,B>::has(const mln_psite(I)& p) const
00176 {
00177 return this->data_->ima_.has(p);
00178 }
00179
00180 template <typename I, typename F, typename B>
00181 inline
00182 mln_result(F)
00183 lazy_image<I,F,B>::operator()(const typename F::input& p) const
00184 {
00185 mln_assertion(this->has(p));
00186 if (this->data_->is_known(p))
00187 return this->data_->ima_(p);
00188 this->data_->ima_(p) = this->data_->fun(p);
00189 this->data_->is_known(p) = true;
00190 return this->data_->ima_(p);
00191 }
00192
00193
00194 template <typename I, typename F, typename B>
00195 inline
00196 mln_result(F)
00197 lazy_image<I,F,B>::operator()(const typename F::input& p)
00198 {
00199 mln_assertion(this->has(p));
00200 if (this->data_->is_known(p))
00201 return this->data_->ima_(p);
00202 this->data_->ima_(p) = this->data_->fun(p);
00203 this->data_->is_known(p) = true;
00204 return this->data_->ima_(p);
00205 }
00206
00207 template <typename I, typename F, typename B>
00208 inline
00209 typename lazy_image<I,F,B>::rvalue
00210 lazy_image<I,F,B>::operator()(const mln_psite(I)& p) const
00211 {
00212 return (*this).operator()(convert::to< typename F::input >(p));
00213 }
00214
00215 template <typename I, typename F, typename B>
00216 inline
00217 typename lazy_image<I,F,B>::lvalue
00218 lazy_image<I,F,B>::operator()(const mln_psite(I)& p)
00219 {
00220 return (*this).operator()(convert::to< typename F::input >(p));
00221 }
00222
00223 template <typename I, typename F, typename B>
00224 inline
00225 const box<mln_psite(I)>&
00226 lazy_image<I,F,B>::domain() const
00227 {
00228 return this->data_->bb_;
00229 }
00230
00231 # endif // ! MLN_INCLUDE_ONLY
00232
00233 }
00234
00235
00236 #endif // ! MLN_CORE_IMAGE_IMORPH_LAZY_IMAGE_HH