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_DATA_MEMCPY__HH 00028 # define MLN_DATA_MEMCPY__HH 00029 00035 00036 # include <cstring> 00037 # include <mln/core/concept/image.hh> 00038 # include <mln/core/pixel.hh> 00039 # include <mln/metal/is_not_const.hh> 00040 # include <mln/opt/element.hh> 00041 00042 00043 00044 namespace mln 00045 { 00046 00047 namespace data 00048 { 00049 00065 template <typename Pd, typename Ps> 00066 void memcpy_(Generalized_Pixel<Pd>& dest, const Generalized_Pixel<Ps>& src, 00067 std::size_t n); 00068 00069 00070 # ifndef MLN_INCLUDE_ONLY 00071 00072 namespace impl 00073 { 00074 00075 template <typename Pd, typename Ps> 00076 inline 00077 void memcpy__(Pd& dest, const Ps& src, std::size_t n) 00078 { 00079 // trace::entering("data::impl::memcpy__"); 00080 00081 typedef mln_image(Pd) Id; 00082 typedef mln_image(Ps) Is; 00083 if (n == 0) 00084 return; // no-op 00085 00086 if (n == 1) 00087 { 00088 dest.val() = src.val(); // one assignment 00089 return; 00090 } 00091 00092 /* Careful, the code generated for this function by g++ 4.2 00093 with a high optimization level (`-O3') and without 00094 `-fno-strict-aliasing' might be wrong (at least with 00095 Debian's g++ 4.2 on IA-32)! Note that Debian's g++ 4.0, 00096 4.1, 4.3 and 4.4 are fine. 00097 00098 We used to trigger a warning when g++ 4.2 was detected, but 00099 we no longer do this since this warning was popping in 00100 virtually every compiler output and because this bug is 00101 limited to some specific use cases. Moreover, g++ 4.2 will 00102 be less and less used over time. */ 00103 if (sizeof(mln_value(Id)) == 1) 00104 { 00105 std::memcpy((void*) (&dest.val()), // violent casts 00106 (const void*) (&src.val()), 00107 n); 00108 } 00109 else 00110 { 00111 mln_value(Id)* p_d = &dest.val(); 00112 const mln_value(Is)* p_s = &src.val(); 00113 for (std::size_t i = 0; i < n; ++i) 00114 *p_d++ = *p_s++; 00115 } 00116 00117 // trace::exiting("data::impl::memcpy__"); 00118 } 00119 00120 } 00121 00122 template <typename Pd, typename Ps> 00123 inline 00124 void memcpy_(Generalized_Pixel<Pd>& dest_, 00125 const Generalized_Pixel<Ps>& src_, 00126 std::size_t n) 00127 { 00128 // trace::entering("data::memcpy_"); 00129 00130 typedef mln_image(Pd) Id; 00131 metal::is_not_const<Id>::check(); 00132 typedef mln_image(Ps) Is; 00133 Pd& dest = mln::internal::force_exact<Pd>(dest_); 00134 Ps& src = mln::internal::force_exact<Ps>(src_); 00135 00136 mln_precondition(sizeof(mln_value(Id)) == sizeof(mln_value(Is))); 00137 mln_precondition(dest.ima().is_valid()); 00138 mln_precondition(src.ima().is_valid()); 00139 00140 mln_precondition(&dest.val() >= &opt::element(dest.ima(), 0)); 00141 mln_precondition(&dest.val() < &opt::element(dest.ima(), 0) + 00142 opt::nelements(dest.ima())); 00143 00144 mln_precondition(&dest.val() + n <= &opt::element(dest.ima(), 0) + 00145 opt::nelements(dest.ima())); 00146 00147 mln_precondition(&src.val() >= &opt::element(src.ima(), 0)); 00148 mln_precondition(&src.val() < &opt::element(src.ima(), 0) + 00149 opt::nelements(src.ima())); 00150 mln_precondition(&src.val() + n <= &opt::element(src.ima(), 0) + 00151 opt::nelements(src.ima())); 00152 00153 impl::memcpy__(dest, src, n); 00154 00155 // trace::exiting("data::memcpy_"); 00156 } 00157 00158 # endif // ! MLN_INCLUDE_ONLY 00159 00160 } // end of namespace mln::data 00161 00162 } // end of namespace mln 00163 00164 00165 #endif // ! MLN_DATA_MEMCPY__HH