Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
memset_.hh
1 // Copyright (C) 2007, 2008, 2009 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_DATA_MEMSET__HH
28 # define MLN_DATA_MEMSET__HH
29 
33 
34 # include <cstring>
35 
36 # include <mln/core/concept/image.hh>
37 # include <mln/core/pixel.hh>
38 # include <mln/metal/is_not_const.hh>
39 # include <mln/opt/element.hh>
40 
41 
42 
43 namespace mln
44 {
45 
46  namespace data
47  {
48 
59  template <typename P>
60  void memset_(Generalized_Pixel<P>& pix,
61  const mln_value(P)& v, std::size_t n);
62 
75  template <typename I>
76  void memset_(I& input, const mln_psite(I)& p,
77  const mln_value(I)& v, std::size_t n);
78 
79 
80 # ifndef MLN_INCLUDE_ONLY
81 
82  namespace impl
83  {
84 
85  template <typename P>
86  inline
87  void memset__(P& pix, const mln_value(P)& v, std::size_t n)
88  {
89  trace::entering("data::impl::memset_");
90 
91  typedef mln_image(P) I;
92  if (n == 0)
93  {
94  return; // no-op
95  }
96 
97  if (n == 1)
98  {
99  pix.val() = v; // one assignment
100  return;
101  }
102 
103  if (sizeof(mln_value(I)) == 1)
104  {
105  /* Because of strict-aliasing rules, we cannot use
106 
107  *(const int*)(&v)
108 
109  as second argument for std::memset. Hence the use of
110  std::memcpy. See the `-fstrict-aliasing' entry in GCC's
111  documentation for more information. */
112  char c;
113  std::memcpy(&c, &v, 1);
114  std::memset((void*)(& pix.val()), c, n);
115  }
116  else
117  {
118  mln_value(I)* ptr = & pix.val();
119  for (std::size_t i = 0; i < n; ++i)
120  *ptr++ = v;
121  }
122 
123  trace::exiting("data::impl::memset_");
124  }
125 
126  } // end of namespace mln::data::impl
127 
128 
129  template <typename P>
130  inline
131  void memset_(Generalized_Pixel<P>& pix_,
132  const mln_value(P)& v, std::size_t n)
133  {
134  trace::entering("data::memset_");
135 
136  typedef mln_image(P) I;
137  metal::is_not_const<I>::check();
138 
139  P& pix = mln::internal::force_exact<P>(pix_);
140  mln_precondition(pix.ima().is_valid());
141  mln_precondition(& pix.val() >= & pix.ima()[0]);
142  mln_precondition(& pix.val() < & pix.ima()[0] +
143  opt::nelements(pix.ima()));
144  mln_precondition(& pix.val() + n <= & pix.ima()[0] +
145  opt::nelements(pix.ima()));
146 
147  impl::memset__(pix, v, n);
148 
149  trace::exiting("data::memset_");
150  }
151 
152  template <typename I>
153  inline
154  void memset_(I& input, const mln_psite(I)& p,
155  const mln_value(I)& v, std::size_t n)
156  {
157  trace::entering("data::memset_");
158 
159  mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check();
160 
161  mln_precondition(input.is_valid());
162  mln_precondition(input.has(p));
163  mln_precondition(input.index_of_point(p) + n <= opt::nelements(input));
164 
165  pixel<I> pix(input, p);
166  impl::memset__(pix, v, n);
167 
168  trace::exiting("data::memset_");
169  }
170 
171 # endif // ! MLN_INCLUDE_ONLY
172 
173  } // end of namespace mln::data
174 
175 } // end of namespace mln
176 
177 
178 #endif // ! MLN_DATA_MEMSET__HH