diff --git a/src/platform.h b/src/platform.h index 2f27b5a9..7887f354 100644 --- a/src/platform.h +++ b/src/platform.h @@ -83,6 +83,12 @@ SOFTWARE. #define ETL_STATIC_ASSERT_SUPPORTED #endif +// Check to see if the compiler supports C++11 type traits. +#if (defined(ETL_COMPILER_MICROSOFT) && (_MSC_VER >= 1600)) || \ + (defined(ETL_COMPILER_GCC) && (__cplusplus >= 201103L)) +#define ETL_C11_TYPE_TRAITS_SUPPORTED +#endif + // Some targets do not support 8bit types. #define ETL_8BIT_SUPPORT (CHAR_BIT == 8) diff --git a/src/private/pvoidvector.h b/src/private/pvoidvector.h index 3d1b0cb1..d34e447f 100644 --- a/src/private/pvoidvector.h +++ b/src/private/pvoidvector.h @@ -464,7 +464,7 @@ namespace etl std::copy(first, last, position); p_end += count; } - + //********************************************************************* /// Erases an element. ///\param i_element Iterator to the element. @@ -566,6 +566,17 @@ namespace etl p_end = p_buffer; } + //************************************************************************* + /// Fix the internal pointers after a low level memory copy. + //************************************************************************* + void fixup(void** p_buffer_) + { + uintptr_t length = p_end - p_buffer; + + p_buffer = p_buffer_; + p_end = p_buffer_ + length; + } + void** p_buffer; void** p_end; diff --git a/src/vector.h b/src/vector.h index 5b78b160..24f77d16 100644 --- a/src/vector.h +++ b/src/vector.h @@ -33,6 +33,10 @@ SOFTWARE. #define __ETL_IN_VECTOR_H__ +#ifdef ETL_C11_TYPE_TRAITS_SUPPORTED +#include +#endif + #include #include #include @@ -402,7 +406,7 @@ namespace etl initialise(); -#if defined(ETL_DEBUG) +#if defined(ETL_DEBUG) p_end = etl::uninitialized_copy(first, last, p_buffer, construct_count); #else p_end = etl::uninitialized_copy(first, last, p_buffer); @@ -421,7 +425,7 @@ namespace etl initialise(); -#if defined(ETL_DEBUG) +#if defined(ETL_DEBUG) p_end = etl::uninitialized_fill_n(p_buffer, n, value, construct_count); #else p_end = etl::uninitialized_fill_n(p_buffer, n, value); @@ -751,7 +755,7 @@ namespace etl etl::destroy(p_end - n_delete, p_end, construct_count); #else etl::destroy(p_end - n_delete, p_end); -#endif +#endif p_end -= n_delete; } @@ -833,14 +837,24 @@ namespace etl p_end = p_buffer; } + //************************************************************************* + /// Fix the internal pointers after a low level memory copy. + //************************************************************************* + void fixup(T* p_buffer_) + { + uintptr_t length = p_end - p_buffer; + p_buffer = p_buffer_; + p_end = p_buffer_ + length; + } + private: pointer p_buffer; ///< Pointer to the start of the buffer. pointer p_end; ///< Pointer to one past the last element in the buffer. - //********************************************************************* - /// Create a new element with a default value at the back. - //********************************************************************* + //********************************************************************* + /// Create a new element with a default value at the back. + //********************************************************************* inline void create_back() { #if defined(ETL_DEBUG) @@ -1048,11 +1062,23 @@ namespace etl return *this; } + //************************************************************************* + /// Fix the internal pointers after a low level memory copy. + //************************************************************************* + void fixup() + { + #ifdef ETL_C11_TYPE_TRAITS_SUPPORTED + ETL_STATIC_ASSERT(std::is_trivially_copyable::value, "The stored type is not compatible with a low level copy"); + #endif + + etl::ivector::fixup(buffer); + } + private: typename etl::aligned_storage::value>::type buffer; }; - + //*************************************************************************** /// A vector implementation that uses a fixed size buffer. ///\tparam T The element type. @@ -1133,6 +1159,14 @@ namespace etl return *this; } + //************************************************************************* + /// Fix the internal pointers after a low level memory copy. + //************************************************************************* + void fixup() + { + etl::ivector::fixup(buffer); + } + private: typename etl::aligned_storage::value>::type buffer;