|
Sierra Toolkit
Version of the Day
|
00001 #ifndef RDESTL_UTILITY_H 00002 #define RDESTL_UTILITY_H 00003 00004 #include <stk_util/util/rdestl_common.h> 00005 #include <new> 00006 00007 namespace rde 00008 { 00009 namespace internal 00010 { 00011 template<typename T> 00012 void copy_n(const T* first, size_t n, T* result, int_to_type<false>) 00013 { 00014 const T* last = first + n; 00015 //while (first != last) 00016 // *result++ = *first++; 00017 switch (n & 0x3) 00018 { 00019 case 0: 00020 while (first != last) 00021 { 00022 *result++ = *first++; 00023 case 3: *result++ = *first++; 00024 case 2: *result++ = *first++; 00025 case 1: *result++ = *first++; 00026 } 00027 } 00028 } 00029 template<typename T> 00030 void copy_n(const T* first, size_t n, T* result, int_to_type<true>) 00031 { 00032 RDE_ASSERT(result >= first + n || result < first); 00033 Sys::MemCpy(result, first, n * sizeof(T)); 00034 } 00035 00036 template<typename T> 00037 void copy(const T* first, const T* last, T* result, int_to_type<false>) 00038 { 00039 while (first != last) 00040 *result++ = *first++; 00041 } 00042 template<typename T> 00043 void copy(const T* first, const T* last, T* result, int_to_type<true>) 00044 { 00045 const size_t n = reinterpret_cast<const char*>(last) - reinterpret_cast<const char*>(first); 00046 Sys::MemCpy(result, first, n); 00047 } 00048 00049 template<typename T> RDE_FORCEINLINE 00050 void move_n(const T* from, size_t n, T* result, int_to_type<false>) 00051 { 00052 for (int i = int(n) - 1; i >= 0; --i) 00053 result[i] = from[i]; 00054 } 00055 template<typename T> RDE_FORCEINLINE 00056 void move_n(const T* first, size_t n, T* result, int_to_type<true>) 00057 { 00058 Sys::MemMove(result, first, n * sizeof(T)); 00059 } 00060 00061 template<typename T> RDE_FORCEINLINE 00062 void move(const T* first, const T* last, T* result, int_to_type<false>) 00063 { 00064 while (--last >= first) 00065 *result++ = *last; 00066 } 00067 template<typename T> RDE_FORCEINLINE 00068 void move(const T* first, const T* last, T* result, int_to_type<true>) 00069 { 00070 // Meh, MSVC does pretty stupid things here. 00071 //memmove(result, first, (last - first) * sizeof(T)); 00072 const size_t n = reinterpret_cast<const char*>(last) - reinterpret_cast<const char*>(first); 00073 //const size_t n = (last - first) * sizeof(T); 00074 Sys::MemMove(result, first, n); 00075 } 00076 00077 00078 template<typename T> 00079 void copy_construct_n(const T* first, size_t n, T* result, int_to_type<false>) 00080 { 00081 for (size_t i = 0; i < n; ++i) 00082 new (result + i) T(first[i]); 00083 } 00084 template<typename T> 00085 void copy_construct_n(const T* first, size_t n, T* result, int_to_type<true>) 00086 { 00087 RDE_ASSERT(result >= first + n || result < first); 00088 Sys::MemCpy(result, first, n * sizeof(T)); 00089 } 00090 00091 template<typename T> 00092 void destruct_n(T* first, size_t n, int_to_type<false>) 00093 { 00094 // For unknown reason MSVC cant see reference to first here... 00095 sizeof(first); 00096 for (size_t i = 0; i < n; ++i) 00097 (first + i)->~T(); 00098 } 00099 template<typename T> RDE_FORCEINLINE 00100 void destruct_n(T*, size_t, int_to_type<true>) 00101 { 00102 // Nothing to do, no destructor needed. 00103 } 00104 00105 template<typename T> 00106 void destruct(T* mem, int_to_type<false>) 00107 { 00109 mem->~T(); 00110 } 00111 template<typename T> RDE_FORCEINLINE 00112 void destruct(T*, int_to_type<true>) 00113 { 00114 // Nothing to do, no destructor needed. 00115 } 00116 00117 template<typename T> 00118 void construct(T* mem, int_to_type<false>) 00119 { 00120 new (mem) T(); 00121 } 00122 template<typename T> RDE_FORCEINLINE 00123 void construct(T*, int_to_type<true>) 00124 { 00125 // Nothing to do 00126 } 00127 00128 template<typename T> RDE_FORCEINLINE 00129 void copy_construct(T* mem, const T& orig, int_to_type<false>) 00130 { 00131 new (mem) T(orig); 00132 } 00133 template<typename T> RDE_FORCEINLINE 00134 void copy_construct(T* mem, const T& orig, int_to_type<true>) 00135 { 00136 mem[0] = orig; 00137 } 00138 00139 template<typename T> 00140 void construct_n(T* to, size_t count, int_to_type<false>) 00141 { 00142 sizeof(to); 00143 for (size_t i = 0; i < count; ++i) 00144 new (to + i) T(); 00145 } 00146 template<typename T> inline 00147 void construct_n(T*, int, int_to_type<true>) 00148 { 00149 // trivial ctor, nothing to do. 00150 } 00151 00152 // Tests if all elements in range are ordered according to pred. 00153 template<class TIter, class TPred> 00154 void test_ordering(TIter first, TIter last, const TPred& pred) 00155 { 00156 #if RDE_DEBUG 00157 if (first != last) 00158 { 00159 TIter next = first; 00160 if (++next != last) 00161 { 00162 RDE_ASSERT(pred(*first, *next)); 00163 first = next; 00164 } 00165 } 00166 #else 00167 sizeof(first); sizeof(last); sizeof(pred); 00168 #endif 00169 } 00170 00171 template<typename T1, typename T2, class TPred> inline 00172 bool debug_pred(const TPred& pred, const T1& a, const T2& b) 00173 { 00174 #if RDE_DEBUG 00175 if (pred(a, b)) 00176 { 00177 RDE_ASSERT(!pred(b, a)); 00178 return true; 00179 } 00180 else 00181 { 00182 return false; 00183 } 00184 #else 00185 return pred(a, b); 00186 #endif 00187 } 00188 } // namespace internal 00189 00190 } // namespace rde 00191 00192 //----------------------------------------------------------------------------- 00193 #endif // #ifndef RDESTL_UTILITY_H