Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
safe.hh
1 // Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_CORE_IMAGE_IMORPH_SAFE_HH
28 # define MLN_CORE_IMAGE_IMORPH_SAFE_HH
29 
36 
37 # include <mln/core/internal/image_identity.hh>
38 
39 
40 
41 namespace mln
42 {
43 
44  // Forward declaration.
45  template <typename I> class safe_image;
46 
47 
48  namespace internal
49  {
50 
52  template <typename I>
53  struct data< safe_image<I> >
54  {
55  data(I& ima, const mln_value(I)& default_value);
56 
57  I ima_;
58  mln_value(I) default_value_;
59  };
60 
61  } // end of namespace mln::internal
62 
63 
64  namespace trait
65  {
66 
67  template <typename I>
68  struct image_< safe_image<I> > : image_< I > // Same as I except...
69  {
70  // ...these changes.
71  typedef trait::image::category::identity_morpher category;
72  typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
73  };
74 
75  } // end of namespace mln::trait
76 
77 
78 
82  //
83  template <typename I>
84  class safe_image : public internal::image_identity< I, mln_domain(I), safe_image<I> >
85  {
86  public:
87 
90 
91  safe_image();
92  safe_image(I& ima);
93  safe_image(I& ima, const mln_value(I)& default_value);
94 
95  // Initialize an empty image.
96  void init_(I& ima, const mln_value(I)& default_value);
97 
98  mln_rvalue(I) operator()(const mln_psite(I)& p) const;
99 
100  mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
101 
103  operator safe_image<const I>() const;
104  };
105 
106 
107 
108  template <typename I>
109  safe_image<I> safe(Image<I>& ima,
110  mln_value(I) default_value = mln_value(I)());
111 
112  template <typename I>
113  safe_image<const I> safe(const Image<I>& ima,
114  mln_value(I) default_value = mln_value(I)());
115 
116 
117 
118 # ifndef MLN_INCLUDE_ONLY
119 
120  // internal::data< safe_image<I,S> >
121 
122  namespace internal
123  {
124 
125  template <typename I>
126  inline
127  data< safe_image<I> >::data(I& ima, const mln_value(I)& default_value)
128  : ima_(ima),
129  default_value_(default_value)
130  {
131  }
132 
133  } // end of namespace mln::internal
134 
135  // safe_image<I>
136 
137  template <typename I>
138  inline
139  safe_image<I>::safe_image()
140  {
141  }
142 
143  template <typename I>
144  inline
145  safe_image<I>::safe_image(I& ima, const mln_value(I)& default_value)
146  {
147  mln_precondition(ima.is_valid());
148  init_(ima, default_value);
149  }
150 
151  template <typename I>
152  inline
153  safe_image<I>::safe_image(I& ima)
154  {
155  mln_precondition(ima.is_valid());
156  init_(ima, mln_value(I)());
157  }
158 
159  template <typename I>
160  inline
161  void
162  safe_image<I>::init_(I& ima, const mln_value(I)& default_value)
163  {
164  mln_precondition(! this->is_valid());
165  mln_precondition(ima.is_valid());
166  this->data_ = new internal::data< safe_image<I> >(ima, default_value);
167  }
168 
169  template <typename I>
170  inline
171  mln_rvalue(I)
172  safe_image<I>::operator()(const mln_psite(I)& p) const
173  {
174  mln_precondition(this->is_valid());
175  if (! this->has(p))
176  return this->data_->default_value_;
177  return this->data_->ima_(p);
178  }
179 
180  template <typename I>
181  inline
182  mln_morpher_lvalue(I)
183  safe_image<I>::operator()(const mln_psite(I)& p)
184  {
185  mln_precondition(this->is_valid());
186  static mln_value(I) forget_it_;
187  if (this->has(p))
188  return this->data_->ima_(p);
189  else
190  // A copy of data_->default_value_ is returned.
191  return forget_it_ = this->data_->default_value_;
192  }
193 
194  template <typename I>
195  inline
196  safe_image<I>::operator safe_image<const I>() const
197  {
198  safe_image<const I> tmp(this->data_->ima_, this->data_->default_value_);
199  return tmp;
200  }
201 
202  // safe
203 
204  template <typename I>
205  inline
206  safe_image<I> safe(Image<I>& ima,
207  mln_value(I) default_value)
208  {
209  safe_image<I> tmp(exact(ima), default_value);
210  return tmp;
211  }
212 
213  template <typename I>
214  inline
215  safe_image<const I> safe(const Image<I>& ima,
216  mln_value(I) default_value)
217  {
218  safe_image<const I> tmp(exact(ima), default_value);
219  return tmp;
220  }
221 
222 # endif // ! MLN_INCLUDE_ONLY
223 
224 } // end of namespace mln
225 
226 
227 #endif // ! MLN_CORE_IMAGE_IMORPH_SAFE_HH