00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if !defined NXS_UTIL_COPY_H
00024 #define NXS_UTIL_COPY_H
00025 #include <algorithm>
00026 #include <cstring>
00027
00028 #if defined(_MSC_VER)
00029 # undef HAVE_COMPILE_TIME_DISPATCH
00030 #else
00031 # define HAVE_COMPILE_TIME_DISPATCH
00032 #endif
00033
00043
00044 template<int v>
00045 class Int2Type
00046 {
00047 public:
00048 enum {value = v};
00049 };
00050
00051 typedef Int2Type<true> TrueAsAType;
00052 typedef Int2Type<false> FalseAsAType;
00053
00063
00064 template<typename T>
00065 class Type2Type
00066 {
00067 public:
00068 typedef T OriginalType;
00069 };
00070
00071
00072 namespace ncl
00073 {
00074 namespace hidden
00075 {
00076
00077 template<bool> struct CompileTimeChecker
00078 {
00079 CompileTimeChecker(...);
00080 };
00081
00082 template<> struct CompileTimeChecker<false>{};
00083 }
00084 }
00085
00118 #define COMPILE_TIME_ASSERT(condition, msg) {class ERROR_##msg {}; (void)sizeof(ncl::hidden::CompileTimeChecker<(condition)>(ERROR_##msg()));}
00119
00120 #if defined(HAVE_COMPILE_TIME_DISPATCH)
00121 template<typename T> struct SupportsBitwiseCopy { enum {kResult = false}; };
00122 template<typename T> struct SupportsBitwiseCopy<T*> { enum {kResult = true}; };
00123 template<> struct SupportsBitwiseCopy<short int> { enum {kResult = true}; };
00124 template<> struct SupportsBitwiseCopy<int> { enum {kResult = true}; };
00125 template<> struct SupportsBitwiseCopy<char> { enum {kResult = true}; };
00126 template<> struct SupportsBitwiseCopy<long int> { enum {kResult = true}; };
00127 template<> struct SupportsBitwiseCopy<double> { enum {kResult = true}; };
00128 template<> struct SupportsBitwiseCopy<unsigned short int> { enum {kResult = true}; };
00129 template<> struct SupportsBitwiseCopy<unsigned int> { enum {kResult = true}; };
00130 template<> struct SupportsBitwiseCopy<unsigned char> { enum {kResult = true}; };
00131 template<> struct SupportsBitwiseCopy<unsigned long int> { enum {kResult = true}; };
00132 template<> struct SupportsBitwiseCopy<bool> { enum {kResult = true}; };
00133 template<> struct SupportsBitwiseCopy<wchar_t> { enum {kResult = true}; };
00134 template<> struct SupportsBitwiseCopy<float> { enum {kResult = true}; };
00135 template<> struct SupportsBitwiseCopy<long double> { enum {kResult = true}; };
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 class NullType {};
00146
00147 template <typename T>
00148 class TypeTraits
00149 {
00150 private :
00151 template <class U> struct PointerTraits
00152 {
00153 enum {kResult = false};
00154 enum {kCopyWithMemCopy = false};
00155 enum {kSizeOfPointee = 0};
00156 };
00157 template <class U> struct PointerTraits<U*>
00158 {
00159 enum {kResult = true};
00160 enum {kCopyWithMemCopy = SupportsBitwiseCopy<U>::kResult};
00161 enum {kSizeOfPointee = sizeof(U)};
00162 };
00163 template <class U> struct PointerTraits<const U*>
00164 {
00165 enum {kResult = true};
00166 enum {kCopyWithMemCopy = SupportsBitwiseCopy<U>::kResult};
00167 enum {kSizeOfPointee = sizeof(U)};
00168 };
00169 public:
00170 enum {kIsPointer = PointerTraits<T>::kResult};
00171 enum {kCanUseMemCpyOnPointee = PointerTraits<T>::kCopyWithMemCopy};
00172 enum {kPointeeSize = PointerTraits<T>::kSizeOfPointee};
00173
00174 };
00175
00176 template<class T, class U>
00177 class Conversion
00178 {
00179 public:
00180 enum {kSameType = false};
00181 };
00182
00183 template<class T>
00184 class Conversion<T,T>
00185 {
00186 public:
00187 enum {kSameType = true};
00188 };
00189
00190 template<class T>
00191 class Conversion<const T*,T*>
00192 {
00193 public:
00194 enum {kSameType = true};
00195 };
00196
00197 template<class T>
00198 class Conversion<T*, const T*>
00199 {
00200 public:
00201 enum {kSameType = true};
00202 };
00203
00204 enum CopyAlgoSeclector
00205 {
00206 kConservative,
00207 kFast
00208 };
00209
00210 template <typename InIt, typename OutIt>
00211 inline OutIt CopyImpl(InIt first, InIt last, OutIt resultP, Int2Type<kConservative>)
00212 {
00213 return std::copy(first, last, resultP);
00214 }
00215
00216 template <typename InIt, typename OutIt>
00217 inline OutIt CopyImpl(InIt first, InIt last, OutIt resultP, Int2Type<kFast>)
00218 {
00219 return (OutIt) std::memcpy(resultP, first, ((std::size_t) (last - first)) * sizeof(*first));
00220 }
00221
00222 template <typename InIt, typename OutIt>
00223 OutIt ncl_copy(InIt first, InIt last, OutIt resultP)
00224 {
00225 enum { kUseMemCpy =(TypeTraits<InIt>::kIsPointer &&
00226 TypeTraits<OutIt>::kIsPointer &&
00227 TypeTraits<InIt>::kCanUseMemCpyOnPointee &&
00228 TypeTraits<OutIt>::kCanUseMemCpyOnPointee &&
00229 int(TypeTraits<InIt>::kPointeeSize) == int(TypeTraits<OutIt>::kPointeeSize)) ? kFast : kConservative};
00230 return CopyImpl(first, last, resultP, Int2Type<kUseMemCpy>());
00231 }
00232
00233 #else //HAVE_COMPILE_TIME_DISPATCH
00234
00235 template <typename InIt, typename OutIt>
00236 inline OutIt ncl_copy(InIt first, InIt last, OutIt resultP)
00237 {
00238 return std::copy(first, last, resultP);
00239 }
00240
00241 #endif //HAVE_COMPILE_TIME_DISPATCH
00242
00243
00244
00245 template <typename InIt, typename OutIt>
00246 inline OutIt ncl_iadd(InIt first, InIt last, OutIt resultP)
00247 {
00248 for (; first != last; ++first, ++resultP)
00249 *resultP += *first;
00250 return resultP;
00251 }
00252
00253
00254 template <typename InIt, typename OutIt>
00255 inline OutIt ncl_imult(InIt first, InIt last, OutIt resultP)
00256 {
00257 for (; first != last; ++first, ++resultP)
00258 *resultP *= *first;
00259 return resultP;
00260 }
00261
00262
00263 #endif
00264