#if !defined UTIL_COPY_HPP #define UTIL_COPY_HPP #include #include #include #include "CipresCommlib/generic_type_mapping.hpp" #include "CipresCommlib/compile_assert.hpp" #if defined(HAVE_COMPILE_TIME_DISPATCH) template struct SupportsBitwiseCopy { enum {kResult = false}; }; template struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; // This file uses tricks discussed in Andrei Alexandrescu's book to // implement a call to memcpy for primitive types or any class which // has the statement template<> struct SupportsBitwiseCopy { enum {kResult = true}; }; // because of potential portability issues with TypeList, primitive types are // have SupportsBitwiseCopy specialized here by brute force enumeration class NullType {}; template class TypeTraits { private : template struct PointerTraits { enum {kResult = false}; enum {kCopyWithMemCopy = false}; // only allowing memcpy on bare pointers enum {kSizeOfPointee = 0}; // only allowing memcpy on bare pointers }; template struct PointerTraits { enum {kResult = true}; enum {kCopyWithMemCopy = SupportsBitwiseCopy::kResult}; enum {kSizeOfPointee = sizeof(U)}; }; template struct PointerTraits { enum {kResult = true}; enum {kCopyWithMemCopy = SupportsBitwiseCopy::kResult}; enum {kSizeOfPointee = sizeof(U)}; }; public: enum {kIsPointer = PointerTraits::kResult}; enum {kCanUseMemCpyOnPointee = PointerTraits::kCopyWithMemCopy}; enum {kPointeeSize = PointerTraits::kSizeOfPointee}; //only valid if kIsPointer !! // typedef PointerTraits::PointeeType PointeeType; }; template class Conversion { public: enum {kSameType = false}; }; template class Conversion { public: enum {kSameType = true}; }; template class Conversion { public: enum {kSameType = true}; }; template class Conversion { public: enum {kSameType = true}; }; enum CopyAlgoSeclector { kConservative, kFast }; template inline OutIt CopyImpl(InIt first, InIt last, OutIt resultP, Int2Type) { return std::copy(first, last, resultP); } template inline OutIt CopyImpl(InIt first, InIt last, OutIt resultP, Int2Type) { return (OutIt) std::memcpy(resultP, first, ((std::size_t) (last - first)) * sizeof(*first)); } template OutIt cip_copy(InIt first, InIt last, OutIt resultP) { enum { kUseMemCpy =(TypeTraits::kIsPointer && TypeTraits::kIsPointer && TypeTraits::kCanUseMemCpyOnPointee && TypeTraits::kCanUseMemCpyOnPointee && int(TypeTraits::kPointeeSize) == int(TypeTraits::kPointeeSize)) ? kFast : kConservative}; return CopyImpl(first, last, resultP, Int2Type()); } #else //HAVE_COMPILE_TIME_DISPATCH template inline OutIt cip_copy(InIt first, InIt last, OutIt resultP) { return std::copy(first, last, resultP); } #endif //HAVE_COMPILE_TIME_DISPATCH //adds an element from the first -> last array to the corresponding element in the result array template inline OutIt cip_iadd(InIt first, InIt last, OutIt resultP) { for (; first != last; ++first, ++resultP) *resultP += *first; return resultP; } //adds each element in resultP array with the correcpsonding element from the first -> last array template inline OutIt cip_imult(InIt first, InIt last, OutIt resultP) { for (; first != last; ++first, ++resultP) *resultP *= *first; return resultP; } #endif