• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

memcpy_.hh

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

Generated on Tue Oct 4 2011 15:24:05 for Milena (Olena) by  doxygen 1.7.1