lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
move_reallocation_policy.h
00001 /*****************************************************/
00002 /* lean Containers              (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_CONTAINERS_MOVE_REALLOCATION_POLICY
00006 #define LEAN_CONTAINERS_MOVE_REALLOCATION_POLICY
00007 
00008 #include "../lean.h"
00009 
00010 namespace lean
00011 {
00012 namespace containers
00013 {
00014 
00016 
00019 template <class Container, int GrowthDenominator = 2>
00020 class move_reallocation_policy
00021 {
00022 private:
00023     typedef typename Container::iterator iterator;
00024 
00025 public:
00027     typedef typename Container::size_type size_type;
00028 
00031 
00037     static void reserve(Container &container, size_type newCapacity)
00038     {
00039         if (newCapacity > container.capacity())
00040         {
00041             Container newContainer;
00042 
00043             newContainer.reserve(newCapacity);
00044             newContainer.resize(container.size());
00045 
00046             for (iterator itOld = container.begin(), itNew = newContainer.begin();
00047                  itNew != newContainer.end(); ++itOld, ++itNew)
00048                 itNew->move(*itOld);
00049 
00050             using std::swap;
00051             swap(container, newContainer);
00052         }
00053 
00054         LEAN_ASSERT(newCapacity <= container.capacity());
00055     }
00056 
00059     static void pre_resize(Container &container, size_type newCount)
00060     {
00061         size_t capacity = container.capacity();
00062 
00063         if (newCount > capacity)
00064         {
00065             size_type capacityDelta = capacity / GrowthDenominator;
00066             size_type maxSize = container.max_size();
00067 
00068             // Mind overflow
00069             capacity = (maxSize - capacityDelta < capacity)
00070                 ? maxSize
00071                 : capacity + capacityDelta;
00072 
00073             if (capacity < newCount)
00074                 capacity = newCount;
00075 
00076             reserve(container, capacity);
00077         }
00078 
00079         LEAN_ASSERT(newCount <= container.capacity());
00080     }
00081 };
00082 
00083 } // namespace
00084 
00085 using containers::move_reallocation_policy;
00086 
00087 } // namespace
00088 
00089 #endif