diff --git a/src/memory.h b/src/memory.h index c858194b..0fba9d67 100644 --- a/src/memory.h +++ b/src/memory.h @@ -37,18 +37,28 @@ SOFTWARE. ///\ingroup etl namespace etl { + //***************************************************************************** + /// Gets the address of an object. + ///\ingroup memory + //***************************************************************************** + template + T* addressof(T& t) + { + return reinterpret_cast(&const_cast(reinterpret_cast(t))); + } + //***************************************************************************** /// Fills uninitialised memory range with a value. ///\ingroup memory //***************************************************************************** - template - TIterator uninitialized_fill(TIterator o_begin, TIterator o_end, const T& value) + template + TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value) { - typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::value_type value_type; while (o_begin != o_end) { - ::new (static_cast(&*o_begin)) value_type(value); + ::new (static_cast(etl::addressof(*o_begin))) value_type(value); ++o_begin; } @@ -57,16 +67,17 @@ namespace etl //***************************************************************************** /// Fills uninitialised memory range with a value. + /// Debug counter version. ///\ingroup memory //***************************************************************************** - template - TIterator uninitialized_fill(TIterator o_begin, TIterator o_end, const T& value, TCounter& count) + template + TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count) { - typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::value_type value_type; while (o_begin != o_end) { - ::new (static_cast(&*o_begin)) value_type(value); + ::new (static_cast(etl::addressof(*o_begin))) value_type(value); ++o_begin; ++count; } @@ -78,18 +89,19 @@ namespace etl /// Fills uninitialised memory with N values. ///\ingroup memory //***************************************************************************** - template - TIterator uninitialized_fill_n(TIterator o_begin, TSize n, const T& value) + template + TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value) { return etl::uninitialized_fill(o_begin, o_begin + n, value); } //***************************************************************************** /// Fills uninitialised memory with N values. + /// Debug counter version. ///\ingroup memory //***************************************************************************** - template - TIterator uninitialized_fill_n(TIterator o_begin, TSize n, const T& value, TCounter& count) + template + TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count) { return etl::uninitialized_fill(o_begin, o_begin + n, value, count); } @@ -105,7 +117,7 @@ namespace etl while (i_begin != i_end) { - ::new (static_cast(&*o_begin)) value_type(*i_begin); + ::new (static_cast(etl::addressof(*o_begin))) value_type(*i_begin); ++i_begin; ++o_begin; } @@ -115,6 +127,7 @@ namespace etl //***************************************************************************** /// Copies a range of objects to uninitialised memory. + /// Debug counter version. ///\ingroup memory //***************************************************************************** template @@ -124,7 +137,7 @@ namespace etl while (i_begin != i_end) { - ::new (static_cast(&*o_begin)) value_type(*i_begin); + ::new (static_cast(etl::addressof(*o_begin))) value_type(*i_begin); ++i_begin; ++o_begin; ++count; @@ -145,6 +158,7 @@ namespace etl //***************************************************************************** /// Copies N objects to uninitialised memory. + /// Debug counter version. ///\ingroup memory //***************************************************************************** template @@ -152,6 +166,220 @@ namespace etl { return etl::uninitialized_copy(i_begin, i_begin + n, o_begin, count); } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + void uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end) + { + typedef typename std::iterator_traits::value_type value_type; + + while (o_begin != o_end) + { + ::new (static_cast(etl::addressof(*o_begin))) value_type; + ++o_begin; + } + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + void uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count) + { + typedef typename std::iterator_traits::value_type value_type; + + while (o_begin != o_end) + { + ::new (static_cast(etl::addressof(*o_begin))) value_type; + ++o_begin; + ++count; + } + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n) + { + TOutputIterator o_end = o_begin + n; + + etl::uninitialized_default_construct(o_begin, o_end); + + return o_end; + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count) + { + TOutputIterator o_end = o_begin + n; + + etl::uninitialized_default_construct(o_begin, o_end, count); + + return o_end; + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end) + { + typedef typename std::iterator_traits::value_type value_type; + + while (o_begin != o_end) + { + ::new (static_cast(etl::addressof(*o_begin))) value_type(); + ++o_begin; + } + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count) + { + typedef typename std::iterator_traits::value_type value_type; + + while (o_begin != o_end) + { + ::new (static_cast(etl::addressof(*o_begin))) value_type(); + ++o_begin; + ++count; + } + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n) + { + TOutputIterator o_end = o_begin + n; + + etl::uninitialized_value_construct(o_begin, o_end); + + return o_end; + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count) + { + TOutputIterator o_end = o_begin + n; + + etl::uninitialized_value_construct(o_begin, o_end, count); + + return o_end; + } + + //***************************************************************************** + /// Destroys an item at address p. + ///\ingroup memory + //***************************************************************************** + template + inline void destroy_at(T* p) + { + p->~T(); + } + + //***************************************************************************** + /// Destroys an item at address p. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + inline void destroy_at(T* p, TCounter& count) + { + p->~T(); + --count; + } + + //***************************************************************************** + /// Destroys a range of items. + ///\ingroup memory + //***************************************************************************** + template + void destroy(TIterator i_begin, TIterator i_end) + { + while (i_begin != i_end) + { + etl::destroy_at(etl::addressof(*i_begin)); + ++i_begin; + } + } + + //***************************************************************************** + /// Destroys a range of items. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + void destroy(TIterator i_begin, TIterator i_end, TCounter& count) + { + while (i_begin != i_end) + { + etl::destroy_at(etl::addressof(*i_begin)); + ++i_begin; + --count; + } + } + + //***************************************************************************** + /// Destroys a number of items. + ///\ingroup memory + //***************************************************************************** + template + TIterator destroy_n(TIterator i_begin, TSize n) + { + while (n > 0) + { + etl::destroy_at(etl::addressof(*i_begin)); + ++i_begin; + --n; + } + + return i_begin; + } + + //***************************************************************************** + /// Destroys a number of items. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + TIterator destroy_n(TIterator i_begin, TSize n, TCounter& count) + { + while (n > 0) + { + etl::destroy_at(etl::addressof(*i_begin)); + ++i_begin; + --n; + --count; + } + + return i_begin; + } } #endif