$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
memcpy_.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_DATA_MEMCPY__HH
28 # define MLN_DATA_MEMCPY__HH
29 
35 
36 # include <cstring>
37 # include <mln/core/concept/image.hh>
38 # include <mln/core/pixel.hh>
39 # include <mln/metal/is_not_const.hh>
40 # include <mln/opt/element.hh>
41 
42 
43 
44 namespace mln
45 {
46 
47  namespace data
48  {
49 
65  template <typename Pd, typename Ps>
66  void memcpy_(Generalized_Pixel<Pd>& dest, const Generalized_Pixel<Ps>& src,
67  std::size_t n);
68 
69 
70 # ifndef MLN_INCLUDE_ONLY
71 
72  namespace impl
73  {
74 
75  template <typename Pd, typename Ps>
76  inline
77  void memcpy__(Pd& dest, const Ps& src, std::size_t n)
78  {
79  // mln_trace("data::impl::memcpy__");
80 
81  typedef mln_image(Pd) Id;
82  typedef mln_image(Ps) Is;
83  if (n == 0)
84  return; // no-op
85 
86  if (n == 1)
87  {
88  dest.val() = src.val(); // one assignment
89  return;
90  }
91 
92  /* Careful, the code generated for this function by g++ 4.2
93  with a high optimization level (`-O3') and without
94  `-fno-strict-aliasing' might be wrong (at least with
95  Debian's g++ 4.2 on IA-32)! Note that Debian's g++ 4.0,
96  4.1, 4.3 and 4.4 are fine.
97 
98  We used to trigger a warning when g++ 4.2 was detected, but
99  we no longer do this since this warning was popping in
100  virtually every compiler output and because this bug is
101  limited to some specific use cases. Moreover, g++ 4.2 will
102  be less and less used over time. */
103  if (sizeof(mln_value(Id)) == 1)
104  {
105  std::memcpy((void*) (&dest.val()), // violent casts
106  (const void*) (&src.val()),
107  n);
108  }
109  else
110  {
111  mln_value(Id)* p_d = &dest.val();
112  const mln_value(Is)* p_s = &src.val();
113  for (std::size_t i = 0; i < n; ++i)
114  *p_d++ = *p_s++;
115  }
116 
117  }
118 
119  }
120 
121  template <typename Pd, typename Ps>
122  inline
123  void memcpy_(Generalized_Pixel<Pd>& dest_,
124  const Generalized_Pixel<Ps>& src_,
125  std::size_t n)
126  {
127  // mln_trace("data::memcpy_");
128 
129  typedef mln_image(Pd) Id;
130  metal::is_not_const<Id>::check();
131  typedef mln_image(Ps) Is;
132  Pd& dest = mln::internal::force_exact<Pd>(dest_);
133  Ps& src = mln::internal::force_exact<Ps>(src_);
134 
135  mln_precondition(sizeof(mln_value(Id)) == sizeof(mln_value(Is)));
136  mln_precondition(dest.ima().is_valid());
137  mln_precondition(src.ima().is_valid());
138 
139  mln_precondition(&dest.val() >= &opt::element(dest.ima(), 0));
140  mln_precondition(&dest.val() < &opt::element(dest.ima(), 0) +
141  opt::nelements(dest.ima()));
142 
143  mln_precondition(&dest.val() + n <= &opt::element(dest.ima(), 0) +
144  opt::nelements(dest.ima()));
145 
146  mln_precondition(&src.val() >= &opt::element(src.ima(), 0));
147  mln_precondition(&src.val() < &opt::element(src.ima(), 0) +
148  opt::nelements(src.ima()));
149  mln_precondition(&src.val() + n <= &opt::element(src.ima(), 0) +
150  opt::nelements(src.ima()));
151 
152  impl::memcpy__(dest, src, n);
153 
154  }
155 
156 # endif // ! MLN_INCLUDE_ONLY
157 
158  } // end of namespace mln::data
159 
160 } // end of namespace mln
161 
162 
163 #endif // ! MLN_DATA_MEMCPY__HH