#if !defined NXS_COPY_H #define NXS_COPY_H #include "phycas/phycas.h" #include #include #include "ncl/misc/generic_type_mapping.hpp" #if 0 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 Copy_n_Impl(InIt first, OutIt resultP, unsigned n, Int2Type) { for (unsigned i = 0; i < n; ++i) { *resultP = *first; ++first; ++resultP; } return resultP; } template inline OutIt Copy_n_Impl(InIt first, OutIt resultP, unsigned n, Int2Type) { # if !defined (NDEBUG) InIt temp = resultP; //this statement is used to generate a warning if InIt and OutIt, don't point to the sametype # endif return (OutIt) std::memcpy(resultP, first, n * sizeof(*first)); } 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) { # if !defined (NDEBUG) InIt temp = resultP; //this statement is used to generate a warning if InIt and OutIt, don't point to the sametype # endif return (OutIt) std::memcpy(resultP, first, ((std::size_t) (last - first)) * sizeof(*first)); } // In Phorest and NCL we are explicitly casting safe casts and maximizing compiler cast warnings. // because of this the // template OutIt nxs_copy(InIt first, InIt last, OutIt resultP) { enum { kUseMemCpy =(TypeTraits::kIsPointer && TypeTraits::kIsPointer && TypeTraits::kCanUseMemCpyOnPointee && TypeTraits::kCanUseMemCpyOnPointee && TypeTraits::kPointeeSize == TypeTraits::kPointeeSize) ? kFast : kConservative}; return CopyImpl(first, last, resultP, Int2Type()); } // In Phorest and NCL we are explicitly casting safe casts and maximizing compiler cast warnings. // because of this the // template OutIt nxs_copy_n(InIt first, OutIt resultP, unsigned n) { enum { kUseMemCpy =(TypeTraits::kIsPointer && TypeTraits::kIsPointer && TypeTraits::kCanUseMemCpyOnPointee && TypeTraits::kCanUseMemCpyOnPointee && TypeTraits::kPointeeSize == TypeTraits::kPointeeSize) ? kFast : kConservative}; return Copy_n_Impl(first, resultP, n, Int2Type()); } #else template inline OutIt nxs_copy(InIt first, InIt last, OutIt resultP) { return std::copy(first, last, resultP); } template OutIt nxs_copy_n(InIt first, OutIt resultP, unsigned n) { for (unsigned i = 0; i < n; ++i) *resultP++ = *first++; return resultP; } #endif #endif