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_COMPLEX_IMAGE_HH
00027 # define MLN_CORE_IMAGE_COMPLEX_IMAGE_HH
00028
00032
00033 # include <vector>
00034
00035 # include <mln/trait/images.hh>
00036
00037 # include <mln/core/internal/image_primary.hh>
00038 # include <mln/metal/vec.hh>
00039 # include <mln/core/site_set/p_complex.hh>
00040 # include <mln/core/site_set/complex_psite.hh>
00041 # include <mln/value/set.hh>
00042
00043
00044
00045
00046 # define mlc_unbool(V) \
00047 typename mln::internal::unbool<V>::ret
00048
00049 namespace mln
00050 {
00051
00052 namespace internal
00053 {
00054
00056 struct bool_proxy
00057 {
00058 public:
00059 bool_proxy() {}
00060 bool_proxy(bool b) : b_(b) {}
00061 bool& operator=(bool b) { b_ = b; return *this; }
00062
00063 operator bool&() { return b_; }
00064 operator const bool&() const { return b_; }
00065
00066 bool operator==(const bool_proxy& rhs) { return b_ == rhs.b_; }
00067 bool operator< (const bool_proxy& rhs) { return b_ < rhs.b_; }
00068
00069 private:
00071 bool b_;
00072 };
00073
00074 template <typename V> struct unbool { typedef V ret; };
00075 template <> struct unbool<bool> { typedef bool_proxy ret; };
00076
00077 }
00078
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088 namespace mln
00089 {
00090
00091
00092 template <unsigned D, typename G, typename V> class complex_image;
00093
00094 namespace internal
00095 {
00096
00098 template <unsigned D, typename G, typename V>
00099 struct data< complex_image<D, G, V> >
00100 {
00101 data(const p_complex<D, G>& pc,
00102 const metal::vec< D + 1, std::vector<V> >& values);
00103
00104 metal::vec< D + 1, std::vector< mlc_unbool(V) > > values_;
00105 const p_complex<D, G> pc_;
00106 };
00107
00108 }
00109
00110
00111 namespace trait
00112 {
00113
00114 template <unsigned D, typename G, typename V>
00115 struct image_< complex_image<D, G, V> >
00116 : default_image_< V, complex_image<D, G, V> >
00117 {
00118 typedef trait::image::category::primary category;
00119
00120
00121 typedef trait::image::speed::fast speed;
00122 typedef trait::image::size::regular size;
00123
00124
00125 typedef trait::image::value_access::direct value_access;
00126
00127
00128
00129 typedef trait::image::vw_io::none vw_io;
00130 typedef trait::image::vw_set::none vw_set;
00131 typedef trait::image::value_storage::disrupted value_storage;
00132 typedef trait::image::value_browsing::site_wise_only value_browsing;
00133 typedef trait::image::value_alignment::irrelevant value_alignment;
00134 typedef trait::image::value_io::read_write value_io;
00135
00136
00137 typedef trait::image::pw_io::read_write pw_io;
00138 typedef trait::image::localization::space localization;
00139
00140
00141
00142
00143 typedef typename trait::image::dimension::none dimension;
00144
00145
00146 typedef trait::image::ext_domain::none ext_domain;
00147 typedef trait::image::ext_value::irrelevant ext_value;
00148 typedef trait::image::ext_io::irrelevant ext_io;
00149 };
00150
00151 }
00152
00153
00163 template <unsigned D, typename G, typename V>
00164 class complex_image
00165 : public internal::image_primary< V, p_complex<D, G>,
00166 complex_image<D, G, V> >
00167 {
00168 public:
00170 static const unsigned dim = D;
00172 typedef G geom;
00174 typedef V value;
00175
00177 typedef V& lvalue;
00178
00180 typedef const V& rvalue;
00181
00183 typedef complex_image< D, tag::psite_<G>, tag::value_<V> > skeleton;
00184
00185 public:
00188 complex_image();
00189 complex_image(const p_complex<D, G>& pc);
00190 complex_image(const p_complex<D, G>& pc,
00191 const metal::vec< D + 1, std::vector<V> >& values);
00193
00195 void init_(const p_complex<D, G>& pc,
00196 const metal::vec< D + 1, std::vector<V> >& values);
00197
00199 rvalue operator()(const complex_psite<D, G>& p) const;
00201 lvalue operator()(const complex_psite<D, G>& p);
00202
00206 const p_complex<D, G>& domain() const;
00207
00209 const metal::vec<D + 1, std::vector< mlc_unbool(V) > >& values() const;
00211 };
00212
00213
00214 template <unsigned D, typename G, typename V, typename W>
00215 void init_(tag::image_t,
00216 complex_image<D, G, V>& target,
00217 const complex_image<D, G, W>& model);
00218
00219
00220 # ifndef MLN_INCLUDE_ONLY
00221
00222
00223
00224
00225
00226 template <unsigned D, typename G, typename V, typename W>
00227 inline
00228 void init_(tag::image_t,
00229 complex_image<D, G, V>& target,
00230 const complex_image<D, G, W>& model)
00231 {
00232 metal::vec<D + 1, std::vector<V> > values;
00233 for (unsigned i = 0; i <= D; ++i)
00234 values[i].resize(model.domain().nfaces_of_dim(i));
00235 target.init_(model.domain(), values);
00236 }
00237
00238
00239
00240
00241
00242 namespace internal
00243 {
00244 template <unsigned D, typename G, typename V>
00245 inline
00246 data< complex_image<D, G, V> >::data(const p_complex<D, G>& pc,
00247 const metal::vec< D + 1, std::vector<V> >& values)
00248 : pc_(pc)
00249 {
00250
00251
00252 for (unsigned i = 0; i <= D; ++i)
00253 {
00254 values_[i].reserve(values[i].size());
00255 values_[i].insert(values_[i].begin(),
00256 values[i].begin(), values[i].end());
00257 }
00258
00259
00260
00261
00262 # ifndef NDEBUG
00263 for (unsigned i = 0; i < D; ++i)
00264 mln_precondition(pc.nfaces_of_dim(i) == values[i].size());
00265 # endif // !NDEBUG
00266 }
00267
00268 }
00269
00270
00271
00272
00273
00274 template <unsigned D, typename G, typename V>
00275 inline
00276 complex_image<D, G, V>::complex_image()
00277 {
00278 }
00279
00280 template <unsigned D, typename G, typename V>
00281 inline
00282 complex_image<D, G, V>::complex_image(const p_complex<D, G>& pc)
00283 {
00284 metal::vec<D + 1, std::vector<V> > values;
00285 for (unsigned i = 0; i <= D; ++i)
00286 values[i].resize(pc.nfaces_of_dim(i));
00287 init_(pc, values);
00288 }
00289
00290 template <unsigned D, typename G, typename V>
00291 inline
00292 complex_image<D, G, V>::complex_image(const p_complex<D, G>& pc,
00293 const metal::vec< D + 1,
00294 std::vector<V> >& values)
00295 {
00296 init_(pc, values);
00297 }
00298
00299 template <unsigned D, typename G, typename V>
00300 inline
00301 void
00302 complex_image<D, G, V>::init_(const p_complex<D, G>& pc,
00303 const metal::vec< D + 1, std::vector<V> >& values)
00304 {
00305 mln_precondition(! this->is_valid());
00306 this->data_ =
00307 new internal::data< complex_image<D, G, V> >(pc, values);
00308 }
00309
00310
00311
00312
00313
00314 template <unsigned D, typename G, typename V>
00315 inline
00316 typename complex_image<D, G, V>::rvalue
00317 complex_image<D, G, V>::operator()(const complex_psite<D, G>& p) const
00318 {
00319 mln_precondition(this->data_->pc_.has(p));
00320 return this->data_->values_[p.n()][p.face_id()];
00321 }
00322
00323 template <unsigned D, typename G, typename V>
00324 inline
00325 typename complex_image<D, G, V>::lvalue
00326 complex_image<D, G, V>::operator()(const complex_psite<D, G>& p)
00327 {
00328 mln_precondition(this->data_->pc_.has(p));
00329 return this->data_->values_[p.n()][p.face_id()];
00330 }
00331
00332 template <unsigned D, typename G, typename V>
00333 inline
00334 const metal::vec< D + 1, std::vector< mlc_unbool(V) > >&
00335 complex_image<D, G, V>::values() const
00336 {
00337 return this->data_->values_;
00338 }
00339
00340 template <unsigned D, typename G, typename V>
00341 inline
00342 const p_complex<D, G>&
00343 complex_image<D, G, V>::domain() const
00344 {
00345 mln_precondition(this->is_valid());
00346 return this->data_->pc_;
00347 }
00348
00349 # endif // ! MLN_INCLUDE_ONLY
00350
00351 }
00352
00353 # undef mlc_unbool
00354
00355 #endif // ! MLN_CORE_IMAGE_COMPLEX_IMAGE_HH