Stefan Scholz / ETL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers memory.h Source File

memory.h

Go to the documentation of this file.
00001 ///\file
00002 
00003 /******************************************************************************
00004 The MIT License(MIT)
00005 
00006 Embedded Template Library.
00007 https://github.com/ETLCPP/etl
00008 http://www.etlcpp.com
00009 
00010 Copyright(c) 2017 jwellbelove
00011 
00012 Permission is hereby granted, free of charge, to any person obtaining a copy
00013 of this software and associated documentation files(the "Software"), to deal
00014 in the Software without restriction, including without limitation the rights
00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
00016 copies of the Software, and to permit persons to whom the Software is
00017 furnished to do so, subject to the following conditions :
00018 
00019 The above copyright notice and this permission notice shall be included in all
00020 copies or substantial portions of the Software.
00021 
00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00028 SOFTWARE.
00029 ******************************************************************************/
00030 
00031 #ifndef __ETL_MEMORY__
00032 #define __ETL_MEMORY__
00033 
00034 #include <iterator>
00035 #include <algorithm>
00036 
00037 #include "platform.h "
00038 #include "type_traits.h "
00039 
00040 ///\defgroup memory memory
00041 ///\ingroup etl
00042 namespace etl
00043 {
00044   //*****************************************************************************
00045   /// Gets the address of an object.
00046   ///\ingroup memory
00047   //*****************************************************************************
00048   template <typename T>
00049   T* addressof(T& t)
00050   {
00051       return reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile char&>(t)));
00052   }
00053 
00054   //*****************************************************************************
00055   /// Fills uninitialised memory range with a value.
00056   ///\ingroup memory
00057   //*****************************************************************************
00058   template <typename TOutputIterator, typename T>
00059   typename etl::enable_if<etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00060    uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
00061   {
00062     std::fill(o_begin, o_end, value);
00063 
00064     return o_end;
00065   }
00066 
00067   //*****************************************************************************
00068   /// Fills uninitialised memory range with a value.
00069   ///\ingroup memory
00070   //*****************************************************************************
00071   template <typename TOutputIterator, typename T>
00072   typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00073    uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
00074   {
00075     typedef typename std::iterator_traits<TOutputIterator>::value_type value_type;
00076 
00077     while (o_begin != o_end)
00078     {
00079       ::new (static_cast<void*>(etl::addressof(*o_begin))) value_type(value);
00080       ++o_begin;
00081     }
00082 
00083     return o_end;
00084   }
00085 
00086   //*****************************************************************************
00087   /// Fills uninitialised memory range with a value.
00088   /// Debug counter version.
00089   ///\ingroup memory
00090   //*****************************************************************************
00091   template <typename TOutputIterator, typename T, typename TCounter>
00092   typename etl::enable_if<etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00093    uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
00094   {
00095     count += std::distance(o_begin, o_end);
00096 
00097     std::fill(o_begin, o_end, value);
00098     
00099     return o_end;
00100   }
00101 
00102   //*****************************************************************************
00103   /// Fills uninitialised memory range with a value.
00104   /// Debug counter version.
00105   ///\ingroup memory
00106   //*****************************************************************************
00107   template <typename TOutputIterator, typename T, typename TCounter>
00108   typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00109    uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
00110   {
00111     count += std::distance(o_begin, o_end);
00112 
00113     etl::uninitialized_fill(o_begin, o_end, value);
00114 
00115     return o_end;
00116   }
00117 
00118   //*****************************************************************************
00119   /// Fills uninitialised memory with N values.
00120   ///\ingroup memory
00121   //*****************************************************************************
00122   template <typename TOutputIterator, typename TSize, typename T>
00123   inline TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value)
00124   {
00125     return etl::uninitialized_fill(o_begin, o_begin + n, value);
00126   }
00127 
00128   //*****************************************************************************
00129   /// Fills uninitialised memory with N values.
00130   /// Debug counter version.
00131   ///\ingroup memory
00132   //*****************************************************************************
00133   template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
00134   inline TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count)
00135   {
00136     count += n;
00137 
00138     return etl::uninitialized_fill(o_begin, o_begin + n, value);
00139   }
00140 
00141   //*****************************************************************************
00142   /// Copies a range of objects to uninitialised memory.
00143   ///\ingroup memory
00144   //*****************************************************************************
00145   template <typename TInputIterator, typename TOutputIterator>
00146   typename etl::enable_if<etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00147    uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
00148   {
00149     return std::copy(i_begin, i_end, o_begin);
00150   }
00151 
00152   //*****************************************************************************
00153   /// Copies a range of objects to uninitialised memory.
00154   ///\ingroup memory
00155   //*****************************************************************************
00156   template <typename TInputIterator, typename TOutputIterator>
00157   typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00158    uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
00159   {
00160     typedef typename std::iterator_traits<TOutputIterator>::value_type value_type;
00161 
00162     TOutputIterator o_end = o_begin;
00163 
00164     while (i_begin != i_end)
00165     {
00166       ::new (static_cast<void*>(etl::addressof(*o_end))) value_type(*i_begin);
00167       ++i_begin;
00168       ++o_end;
00169     }
00170 
00171     return o_end;
00172   }
00173 
00174   //*****************************************************************************
00175   /// Copies a range of objects to uninitialised memory.
00176   /// Debug counter version.
00177   ///\ingroup memory
00178   //*****************************************************************************
00179   template <typename TInputIterator, typename TOutputIterator, typename TCounter>
00180   typename etl::enable_if<etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00181    uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
00182   {
00183     TOutputIterator o_end = std::copy(i_begin, i_end, o_begin);
00184     count += std::distance(o_begin, o_end);
00185 
00186     return o_end;
00187   }
00188 
00189   //*****************************************************************************
00190   /// Copies a range of objects to uninitialised memory.
00191   /// Debug counter version.
00192   ///\ingroup memory
00193   //*****************************************************************************
00194   template <typename TInputIterator, typename TOutputIterator, typename TCounter>
00195   typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00196    uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
00197   {
00198     TOutputIterator o_end = etl::uninitialized_copy(i_begin, i_end, o_begin);
00199 
00200     count += std::distance(o_begin, o_end);
00201 
00202     return o_end;
00203   }
00204 
00205   //*****************************************************************************
00206   /// Copies N objects to uninitialised memory.
00207   ///\ingroup memory
00208   //*****************************************************************************
00209   template <typename TInputIterator, typename TSize, typename TOutputIterator>
00210   inline TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
00211   {
00212     return etl::uninitialized_copy(i_begin, i_begin + n, o_begin);
00213   }
00214 
00215   //*****************************************************************************
00216   /// Copies N objects to uninitialised memory.
00217   /// Debug counter version.
00218   ///\ingroup memory
00219   //*****************************************************************************
00220   template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
00221   inline TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
00222   {
00223     count += n;
00224 
00225     return etl::uninitialized_copy(i_begin, i_begin + n, o_begin);
00226   }
00227 
00228   //*****************************************************************************
00229   /// Default contruct an item at address p.
00230   ///\ingroup memory
00231   //*****************************************************************************
00232   template <typename T>
00233   typename etl::enable_if<etl::is_trivially_constructible<T>::value, void>::type
00234    create_default_at(T* /*p*/)
00235   {
00236   }
00237 
00238   //*****************************************************************************
00239   /// Default contruct an item at address p.
00240   ///\ingroup memory
00241   //*****************************************************************************
00242   template <typename T, typename TCounter>
00243   typename etl::enable_if<etl::is_trivially_constructible<T>::value, void>::type
00244    create_default_at(T* /*p*/, TCounter& count)
00245   {
00246     ++count;
00247   }
00248 
00249   //*****************************************************************************
00250   /// Default contruct an item at address p.
00251   ///\ingroup memory
00252   //*****************************************************************************
00253   template <typename T>
00254   typename etl::enable_if<!etl::is_trivially_constructible<T>::value, void>::type
00255    create_default_at(T* p)
00256   {
00257     ::new (p) T;
00258   }
00259 
00260   //*****************************************************************************
00261   /// Default contruct an item at address p.
00262   ///\ingroup memory
00263   //*****************************************************************************
00264   template <typename T, typename TCounter>
00265   typename etl::enable_if<!etl::is_trivially_constructible<T>::value, void>::type
00266    create_default_at(T* p, TCounter& count)
00267   {
00268     ::new (p) T;
00269     ++count;
00270   }
00271 
00272   //*****************************************************************************
00273   /// Default initialises a range of objects to uninitialised memory.
00274   ///\ingroup memory
00275   //*****************************************************************************
00276   template <typename TOutputIterator>
00277   typename etl::enable_if<etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, void>::type
00278    uninitialized_default_construct(TOutputIterator /*o_begin*/, TOutputIterator /*o_end*/)
00279   {
00280   }
00281 
00282   //*****************************************************************************
00283   /// Default initialises a range of objects to uninitialised memory.
00284   ///\ingroup memory
00285   //*****************************************************************************
00286   template <typename TOutputIterator>
00287   typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, void>::type
00288    uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end)
00289   {
00290     typedef typename std::iterator_traits<TOutputIterator>::value_type value_type;
00291 
00292     while (o_begin != o_end)
00293     {
00294       ::new (static_cast<void*>(etl::addressof(*o_begin))) value_type;
00295       ++o_begin;
00296     }
00297   }
00298 
00299   //*****************************************************************************
00300   /// Default initialises a range of objects to uninitialised memory.
00301   /// Debug counter version.
00302   ///\ingroup memory
00303   //*****************************************************************************
00304   template <typename TOutputIterator, typename TCounter>
00305   typename etl::enable_if<etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, void>::type
00306    uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
00307   {
00308     count = std::distance(o_begin, o_end);
00309   }
00310 
00311   //*****************************************************************************
00312   /// Default initialises a range of objects to uninitialised memory.
00313   /// Debug counter version.
00314   ///\ingroup memory
00315   //*****************************************************************************
00316   template <typename TOutputIterator, typename TCounter>
00317   typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, void>::type
00318    uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
00319   {
00320     count += std::distance(o_begin, o_end);
00321 
00322     etl::uninitialized_default_construct(o_begin, o_end);
00323   }
00324 
00325   //*****************************************************************************
00326   /// Default initialises N objects to uninitialised memory.
00327   ///\ingroup memory
00328   //*****************************************************************************
00329   template <typename TOutputIterator, typename TSize>
00330   typename etl::enable_if<etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00331    uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
00332   {
00333     TOutputIterator o_end = o_begin + n;
00334 
00335     return o_end;
00336   }
00337 
00338   //*****************************************************************************
00339   /// Default initialises N objects to uninitialised memory.
00340   ///\ingroup memory
00341   //*****************************************************************************
00342   template <typename TOutputIterator, typename TSize>  
00343   typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00344    uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
00345   {
00346     TOutputIterator o_end = o_begin + n;
00347 
00348     etl::uninitialized_default_construct(o_begin, o_end);
00349 
00350     return o_end;
00351   }
00352 
00353   //*****************************************************************************
00354   /// Default initialises N objects to uninitialised memory.
00355   /// Debug counter version.
00356   ///\ingroup memory
00357   //*****************************************************************************
00358   template <typename TOutputIterator, typename TSize, typename TCounter>
00359   typename etl::enable_if<etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00360    uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
00361   {
00362     TOutputIterator o_end = o_begin + n;
00363 
00364     count += n;
00365 
00366     return o_end;
00367   }
00368 
00369   //*****************************************************************************
00370   /// Default initialises N objects to uninitialised memory.
00371   /// Debug counter version.
00372   ///\ingroup memory
00373   //*****************************************************************************
00374   template <typename TOutputIterator, typename TSize, typename TCounter>
00375   typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
00376    uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
00377   {
00378     TOutputIterator o_end = o_begin + n;
00379 
00380     etl::uninitialized_default_construct(o_begin, o_end);
00381 
00382     count += n;
00383 
00384     return o_end;
00385   }
00386 
00387   //*****************************************************************************
00388   /// Value construct an item at address p.
00389   ///\ingroup memory
00390   //*****************************************************************************
00391   template <typename T>
00392   inline void create_value_at(T* p)
00393   {
00394     ::new (p) T();
00395   }
00396 
00397   //*****************************************************************************
00398   /// Value construct an item at address p.
00399   ///\ingroup memory
00400   //*****************************************************************************
00401   template <typename T, typename TCounter>
00402   inline void create_value_at(T* p, TCounter& count)
00403   {
00404     ::new (p) T();
00405     ++count;
00406   }
00407 
00408   //*****************************************************************************
00409   /// Copy construct an item at address p.
00410   ///\ingroup memory
00411   //*****************************************************************************
00412   template <typename T>
00413   inline void create_copy_at(T* p, const T& value)
00414   {
00415     ::new (p) T(value);
00416   }
00417 
00418   //*****************************************************************************
00419   /// Copy construct an item at address p.
00420   ///\ingroup memory
00421   //*****************************************************************************
00422   template <typename T, typename TCounter>
00423   inline void create_copy_at(T* p, const T& value, TCounter& count)
00424   {
00425     ::new (p) T(value);
00426     ++count;
00427   }
00428 
00429   //*****************************************************************************
00430   /// Construct an item at address p.
00431   ///\ingroup memory
00432   //*****************************************************************************
00433   template <typename T>
00434   inline T& make_default_at(T* p)
00435   {
00436     ::new (p) T();
00437     return *reinterpret_cast<T*>(p);
00438   }
00439 
00440   //*****************************************************************************
00441   /// Construct an item at address p.
00442   ///\ingroup memory
00443   //*****************************************************************************
00444   template <typename T, typename TCounter>
00445   inline T& make_default_at(T* p, TCounter& count)
00446   {
00447     ::new (p) T();
00448     ++count;
00449     return *reinterpret_cast<T*>(p);
00450   }
00451 
00452   //*****************************************************************************
00453   /// Construct an item at address p.
00454   ///\ingroup memory
00455   //*****************************************************************************
00456   template <typename T>
00457   inline T& make_copy_at(T* p, const T& other)
00458   {
00459     ::new (p) T(other);
00460     return *reinterpret_cast<T*>(p);
00461   }
00462 
00463   //*****************************************************************************
00464   /// Construct an item at address p.
00465   ///\ingroup memory
00466   //*****************************************************************************
00467   template <typename T, typename TCounter>
00468   inline T& make_copy_at(T* p, const T& other, TCounter& count)
00469   {
00470     ::new (p) T(other);
00471     ++count;
00472     return *reinterpret_cast<T*>(p);
00473   }
00474 
00475   //*****************************************************************************
00476   /// Construct an item at address p.
00477   ///\ingroup memory
00478   //*****************************************************************************
00479   template <typename T, typename TParameter>
00480   inline T& make_value_at(T* p, const TParameter& value)
00481   {
00482     ::new (p) T(value);
00483     return *reinterpret_cast<T*>(p);
00484   }
00485 
00486   //*****************************************************************************
00487   /// Construct an item at address p.
00488   ///\ingroup memory
00489   //*****************************************************************************
00490   template <typename T, typename TParameter, typename TCounter>
00491   inline T& make_value_at(T* p, const TParameter& value, TCounter& count)
00492   {
00493     ::new (p) T(value);
00494     ++count;
00495     return *reinterpret_cast<T*>(p);
00496   }
00497 
00498   //*****************************************************************************
00499   /// Default initialises a range of objects to uninitialised memory.
00500   ///\ingroup memory
00501   //*****************************************************************************
00502   template <typename TOutputIterator>
00503   typename etl::enable_if<etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, void>::type
00504    uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
00505   {
00506     typedef typename std::iterator_traits<TOutputIterator>::value_type value_type;
00507 
00508     std::fill(o_begin, o_end, value_type());
00509   }
00510 
00511   //*****************************************************************************
00512   /// Default initialises a range of objects to uninitialised memory.
00513   ///\ingroup memory
00514   //*****************************************************************************
00515   template <typename TOutputIterator>
00516   typename etl::enable_if<!etl::is_trivially_constructible<typename std::iterator_traits<TOutputIterator>::value_type>::value, void>::type
00517    uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
00518   {
00519     typedef typename std::iterator_traits<TOutputIterator>::value_type value_type;
00520 
00521     while (o_begin != o_end)
00522     {
00523       ::new (static_cast<void*>(etl::addressof(*o_begin))) value_type();
00524       ++o_begin;
00525     }
00526   }
00527 
00528   //*****************************************************************************
00529   /// Default initialises a range of objects to uninitialised memory.
00530   /// Debug counter version.
00531   ///\ingroup memory
00532   //*****************************************************************************
00533   template <typename TOutputIterator, typename TCounter>
00534   void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
00535   {
00536     count += std::distance(o_begin, o_end);
00537 
00538     etl::uninitialized_value_construct(o_begin, o_end);
00539   }
00540 
00541   //*****************************************************************************
00542   /// Default initialises N objects to uninitialised memory.
00543   ///\ingroup memory
00544   //*****************************************************************************
00545   template <typename TOutputIterator, typename TSize>
00546   TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
00547   {
00548     TOutputIterator o_end = o_begin + n;
00549 
00550     etl::uninitialized_value_construct(o_begin, o_end);
00551 
00552     return o_end;
00553   }
00554 
00555   //*****************************************************************************
00556   /// Default initialises N objects to uninitialised memory.
00557   /// Debug counter version.
00558   ///\ingroup memory
00559   //*****************************************************************************
00560   template <typename TOutputIterator, typename TSize, typename TCounter>
00561   TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
00562   {
00563     TOutputIterator o_end = o_begin + n;
00564 
00565     etl::uninitialized_value_construct(o_begin, o_end);
00566 
00567     count += n;
00568 
00569     return o_end;
00570   }
00571 
00572   //*****************************************************************************
00573   /// Destroys an item at address p.
00574   ///\ingroup memory
00575   //*****************************************************************************
00576   template <typename T>
00577   typename etl::enable_if<etl::is_trivially_destructible<T>::value, void>::type
00578    destroy_at(T* /*p*/)
00579   {
00580   }
00581 
00582   //*****************************************************************************
00583   /// Destroys an item at address p.
00584   ///\ingroup memory
00585   //*****************************************************************************
00586   template <typename T>
00587   typename etl::enable_if<!etl::is_trivially_destructible<T>::value, void>::type
00588    destroy_at(T* p)
00589   {
00590     p->~T();
00591   }
00592 
00593   //*****************************************************************************
00594   /// Destroys an item at address p.
00595   /// Debug counter version.
00596   ///\ingroup memory
00597   //*****************************************************************************
00598   template <typename T, typename TCounter>
00599   typename etl::enable_if<etl::is_trivially_destructible<T>::value, void>::type
00600    destroy_at(T* /*p*/, TCounter& count)
00601   {
00602     --count;
00603   }
00604 
00605   //*****************************************************************************
00606   /// Destroys an item at address p.
00607   /// Debug counter version.
00608   ///\ingroup memory
00609   //*****************************************************************************
00610   template <typename T, typename TCounter>
00611   typename etl::enable_if<!etl::is_trivially_destructible<T>::value, void>::type
00612    destroy_at(T* p, TCounter& count)
00613   {
00614     p->~T();
00615     --count;
00616   }
00617 
00618   //*****************************************************************************
00619   /// Destroys a range of items.
00620   ///\ingroup memory
00621   //*****************************************************************************
00622   template <typename TIterator>
00623   typename etl::enable_if<etl::is_trivially_destructible<typename std::iterator_traits<TIterator>::value_type>::value, void>::type
00624    destroy(TIterator /*i_begin*/, TIterator /*i_end*/)
00625   {
00626   }
00627 
00628   //*****************************************************************************
00629   /// Destroys a range of items.
00630   ///\ingroup memory
00631   //*****************************************************************************
00632   template <typename TIterator>
00633   typename etl::enable_if<!etl::is_trivially_destructible<typename std::iterator_traits<TIterator>::value_type>::value, void>::type
00634    destroy(TIterator i_begin, TIterator i_end)
00635   {
00636     while (i_begin != i_end)
00637     {
00638       etl::destroy_at(etl::addressof(*i_begin));
00639       ++i_begin;
00640     }
00641   }
00642 
00643   //*****************************************************************************
00644   /// Destroys a range of items.
00645   /// Debug counter version.
00646   ///\ingroup memory
00647   //*****************************************************************************
00648   template <typename TIterator, typename TCounter>
00649   typename etl::enable_if<etl::is_trivially_destructible<typename std::iterator_traits<TIterator>::value_type>::value, void>::type
00650    destroy(TIterator i_begin, TIterator i_end, TCounter& count)
00651   {
00652     count -= std::distance(i_begin, i_end);
00653   }
00654 
00655   //*****************************************************************************
00656   /// Destroys a range of items.
00657   /// Debug counter version.
00658   ///\ingroup memory
00659   //*****************************************************************************
00660   template <typename TIterator, typename TCounter>
00661   typename etl::enable_if<!etl::is_trivially_destructible<typename std::iterator_traits<TIterator>::value_type>::value, void>::type
00662    destroy(TIterator i_begin, TIterator i_end, TCounter& count)
00663   {
00664     count -= std::distance(i_begin, i_end);
00665 
00666     while (i_begin != i_end)
00667     {
00668       etl::destroy_at(etl::addressof(*i_begin));
00669       ++i_begin;
00670     }
00671   }
00672 
00673   //*****************************************************************************
00674   /// Destroys a number of items.
00675   ///\ingroup memory
00676   //*****************************************************************************
00677   template <typename TIterator, typename TSize>
00678   typename etl::enable_if<etl::is_trivially_destructible<typename std::iterator_traits<TIterator>::value_type>::value, TIterator>::type
00679    destroy_n(TIterator i_begin, TSize n)
00680   {
00681     return i_begin + n;
00682   }
00683 
00684   //*****************************************************************************
00685   /// Destroys a number of items.
00686   ///\ingroup memory
00687   //*****************************************************************************
00688   template <typename TIterator, typename TSize>
00689   typename etl::enable_if<!etl::is_trivially_destructible<typename std::iterator_traits<TIterator>::value_type>::value, TIterator>::type
00690    destroy_n(TIterator i_begin, TSize n)
00691   {
00692     while (n > 0)
00693     {
00694       etl::destroy_at(etl::addressof(*i_begin));
00695       ++i_begin;
00696       --n;
00697     }
00698 
00699     return i_begin;
00700   }
00701 
00702   //*****************************************************************************
00703   /// Destroys a number of items.
00704   /// Debug counter version.
00705   ///\ingroup memory
00706   //*****************************************************************************
00707   template <typename TIterator, typename TSize, typename TCounter>
00708   typename etl::enable_if<etl::is_trivially_destructible<typename std::iterator_traits<TIterator>::value_type>::value, TIterator>::type
00709    destroy_n(TIterator i_begin, TSize n, TCounter& count)
00710   {
00711     count -= n;
00712     return i_begin + n;
00713   }
00714 
00715   //*****************************************************************************
00716   /// Destroys a number of items.
00717   /// Debug counter version.
00718   ///\ingroup memory
00719   //*****************************************************************************
00720   template <typename TIterator, typename TSize, typename TCounter>
00721   typename etl::enable_if<!etl::is_trivially_destructible<typename std::iterator_traits<TIterator>::value_type>::value, TIterator>::type
00722    destroy_n(TIterator i_begin, TSize n, TCounter& count)
00723   {
00724     count -= n;
00725 
00726     while (n > 0)
00727     {
00728       etl::destroy_at(etl::addressof(*i_begin));
00729       ++i_begin;
00730       --n;
00731     }
00732 
00733     return i_begin;
00734   }
00735 
00736   //*****************************************************************************
00737   /// Copy constructs a derived class to an address.
00738   ///\tparam T The derived type.
00739   ///\ingroup memory
00740   //*****************************************************************************
00741   template <typename T>
00742   struct create_copy
00743   {
00744     void create_copy_at(void* p)
00745     {
00746       new (p) T(static_cast<const T&>(*this));
00747     }
00748 
00749     template <typename TCounter>
00750     void create_copy_at(void* p, TCounter& count)
00751     {
00752       new (p) T(static_cast<const T&>(*this));
00753       ++count;
00754     }
00755 
00756     T& make_copy_at(void* p)
00757     {
00758       new (p) T(static_cast<const T&>(*this));
00759       return *reinterpret_cast<T*>(p);
00760     }
00761 
00762     template <typename TCounter>
00763     T& make_copy_at(void* p, TCounter& count)
00764     {
00765       new (p) T(static_cast<const T&>(*this));
00766       ++count;
00767       return *reinterpret_cast<T*>(p);
00768     }
00769   };
00770 }
00771 
00772 #endif
00773