From a147500dee85092fbfbf755123553f412a218ec2 Mon Sep 17 00:00:00 2001 From: Pavel Holoborodko Date: Sun, 25 Aug 2013 18:00:28 +0900 Subject: [PATCH] Added smart_memmove with support of non-POD scalars (e.g. needed in SparseBlock.h). --- Eigen/src/Core/util/Memory.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index 451535a0c..3a357e079 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -6,6 +6,7 @@ // Copyright (C) 2009 Kenneth Riddile // Copyright (C) 2010 Hauke Heibel // Copyright (C) 2010 Thomas Capricelli +// Copyright (C) 2013 Pavel Holoborodko // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed @@ -514,6 +515,34 @@ template struct smart_copy_helper { { std::copy(start, end, target); } }; +// intelligent memmove. falls back to std::memmove for POD types, uses std::copy otherwise. +template struct smart_memmove_helper; + +template void smart_memmove(const T* start, const T* end, T* target) +{ + smart_memmove_helper::RequireInitialization>::run(start, end, target); +} + +template struct smart_memmove_helper { + static inline void run(const T* start, const T* end, T* target) + { std::memmove(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); } +}; + +template struct smart_memmove_helper { + static inline void run(const T* start, const T* end, T* target) + { + if (uintptr_t(target) < uintptr_t(start)) + { + std::copy(start, end, target); + } + else + { + std::ptrdiff_t count = (std::ptrdiff_t(end)-std::ptrdiff_t(start)) / sizeof(T); + std::copy_backward(start, end, target + count); + } + } +}; + /***************************************************************************** *** Implementation of runtime stack allocation (falling back to malloc) ***