Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_CORE_IMAGE_IMORPH_SAFE_HH 00028 # define MLN_CORE_IMAGE_IMORPH_SAFE_HH 00029 00036 00037 # include <mln/core/internal/image_identity.hh> 00038 00039 00040 00041 namespace mln 00042 { 00043 00044 // Forward declaration. 00045 template <typename I> class safe_image; 00046 00047 00048 namespace internal 00049 { 00050 00052 template <typename I> 00053 struct data< safe_image<I> > 00054 { 00055 data(I& ima, const mln_value(I)& default_value); 00056 00057 I ima_; 00058 mln_value(I) default_value_; 00059 }; 00060 00061 } // end of namespace mln::internal 00062 00063 00064 namespace trait 00065 { 00066 00067 template <typename I> 00068 struct image_< safe_image<I> > : image_< I > // Same as I except... 00069 { 00070 // ...these changes. 00071 typedef trait::image::category::identity_morpher category; 00072 typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest. 00073 }; 00074 00075 } // end of namespace mln::trait 00076 00077 00078 00082 // 00083 template <typename I> 00084 class safe_image : public internal::image_identity< I, mln_domain(I), safe_image<I> > 00085 { 00086 public: 00087 00089 typedef safe_image< tag::image_<I> > skeleton; 00090 00091 safe_image(); 00092 safe_image(I& ima); 00093 safe_image(I& ima, const mln_value(I)& default_value); 00094 00095 // Initialize an empty image. 00096 void init_(I& ima, const mln_value(I)& default_value); 00097 00098 mln_rvalue(I) operator()(const mln_psite(I)& p) const; 00099 00100 mln_morpher_lvalue(I) operator()(const mln_psite(I)& p); 00101 00103 operator safe_image<const I>() const; 00104 }; 00105 00106 00107 00108 template <typename I> 00109 safe_image<I> safe(Image<I>& ima, 00110 mln_value(I) default_value = mln_value(I)()); 00111 00112 template <typename I> 00113 safe_image<const I> safe(const Image<I>& ima, 00114 mln_value(I) default_value = mln_value(I)()); 00115 00116 00117 00118 # ifndef MLN_INCLUDE_ONLY 00119 00120 // internal::data< safe_image<I,S> > 00121 00122 namespace internal 00123 { 00124 00125 template <typename I> 00126 inline 00127 data< safe_image<I> >::data(I& ima, const mln_value(I)& default_value) 00128 : ima_(ima), 00129 default_value_(default_value) 00130 { 00131 } 00132 00133 } // end of namespace mln::internal 00134 00135 // safe_image<I> 00136 00137 template <typename I> 00138 inline 00139 safe_image<I>::safe_image() 00140 { 00141 } 00142 00143 template <typename I> 00144 inline 00145 safe_image<I>::safe_image(I& ima, const mln_value(I)& default_value) 00146 { 00147 mln_precondition(ima.is_valid()); 00148 init_(ima, default_value); 00149 } 00150 00151 template <typename I> 00152 inline 00153 safe_image<I>::safe_image(I& ima) 00154 { 00155 mln_precondition(ima.is_valid()); 00156 init_(ima, mln_value(I)()); 00157 } 00158 00159 template <typename I> 00160 inline 00161 void 00162 safe_image<I>::init_(I& ima, const mln_value(I)& default_value) 00163 { 00164 mln_precondition(! this->is_valid()); 00165 mln_precondition(ima.is_valid()); 00166 this->data_ = new internal::data< safe_image<I> >(ima, default_value); 00167 } 00168 00169 template <typename I> 00170 inline 00171 mln_rvalue(I) 00172 safe_image<I>::operator()(const mln_psite(I)& p) const 00173 { 00174 mln_precondition(this->is_valid()); 00175 if (! this->has(p)) 00176 return this->data_->default_value_; 00177 return this->data_->ima_(p); 00178 } 00179 00180 template <typename I> 00181 inline 00182 mln_morpher_lvalue(I) 00183 safe_image<I>::operator()(const mln_psite(I)& p) 00184 { 00185 mln_precondition(this->is_valid()); 00186 static mln_value(I) forget_it_; 00187 if (this->has(p)) 00188 return this->data_->ima_(p); 00189 else 00190 // A copy of data_->default_value_ is returned. 00191 return forget_it_ = this->data_->default_value_; 00192 } 00193 00194 template <typename I> 00195 inline 00196 safe_image<I>::operator safe_image<const I>() const 00197 { 00198 safe_image<const I> tmp(this->data_->ima_, this->data_->default_value_); 00199 return tmp; 00200 } 00201 00202 // safe 00203 00204 template <typename I> 00205 inline 00206 safe_image<I> safe(Image<I>& ima, 00207 mln_value(I) default_value) 00208 { 00209 safe_image<I> tmp(exact(ima), default_value); 00210 return tmp; 00211 } 00212 00213 template <typename I> 00214 inline 00215 safe_image<const I> safe(const Image<I>& ima, 00216 mln_value(I) default_value) 00217 { 00218 safe_image<const I> tmp(exact(ima), default_value); 00219 return tmp; 00220 } 00221 00222 # endif // ! MLN_INCLUDE_ONLY 00223 00224 } // end of namespace mln 00225 00226 00227 #endif // ! MLN_CORE_IMAGE_IMORPH_SAFE_HH