Sierra Toolkit Version of the Day
utility_rdestl.h
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines