Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 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 // Forward declaration. 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 } // end of namespace mln::internal 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 } // end of namespace mln::trait 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 // internal::data< lazy_image<I,S> > 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 } // end of namespace mln::internal 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 } // end of namespace mln 00234 00235 00236 #endif // ! MLN_CORE_IMAGE_IMORPH_LAZY_IMAGE_HH