diff --git a/include/etl/iterator.h b/include/etl/iterator.h index 263ab5c6..cda84758 100644 --- a/include/etl/iterator.h +++ b/include/etl/iterator.h @@ -68,9 +68,22 @@ namespace etl //*************************************************************************** // iterator_traits - // For anything not a fundamental type. - template ::value, void>::type> +#if ETL_USING_CPP11 + + // Primary template: falls through to std::iterator_traits when STL is available (C++20+), + // otherwise empty (SFINAE-safe fallback for iterators without nested typedefs). + template struct iterator_traits + #if ETL_USING_STL && ETL_USING_CPP20 + : std::iterator_traits + #endif + { + }; + + // Specialization for iterators that define the standard nested typedefs. + template + struct iterator_traits> { typedef typename TIterator::iterator_category iterator_category; typedef typename TIterator::value_type value_type; @@ -79,6 +92,14 @@ namespace etl typedef typename TIterator::reference reference; }; + #if ETL_USING_STL && ETL_USING_CPP20 + // Specialization for std::common_iterator (C++20). + template + struct iterator_traits, void> : std::iterator_traits> + { + }; + #endif + // For pointers. template struct iterator_traits @@ -101,6 +122,43 @@ namespace etl typedef const T& reference; }; +#else // C++03 + + // Primary template: unconditionally extracts nested typedefs. + template + struct iterator_traits + { + typedef typename TIterator::iterator_category iterator_category; + typedef typename TIterator::value_type value_type; + typedef typename TIterator::difference_type difference_type; + typedef typename TIterator::pointer pointer; + typedef typename TIterator::reference reference; + }; + + // For pointers. + template + struct iterator_traits + { + typedef ETL_OR_STD::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef typename etl::remove_cv::type* pointer; + typedef T& reference; + }; + + // For const pointers. + template + struct iterator_traits + { + typedef ETL_OR_STD::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef const typename etl::remove_cv::type* pointer; + typedef const T& reference; + }; + +#endif + //*************************************************************************** // advance template diff --git a/include/etl/vector.h b/include/etl/vector.h index 73540e2b..016171b2 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -390,9 +390,11 @@ namespace etl template typename etl::enable_if::value, void>::type assign(TIterator first, TIterator last) { +#if ETL_USING_CPP11 ETL_STATIC_ASSERT((etl::is_same::type, - typename etl::remove_cv< typename etl::iterator_traits< TIterator>::value_type>::type>::value), + typename etl::remove_cv::type>::type>::value), "Iterator type does not match container type"); +#endif #if ETL_IS_DEBUG_BUILD difference_type d = etl::distance(first, last); @@ -895,12 +897,11 @@ namespace etl etl::move_backward(p_buffer + insert_begin, p_buffer + insert_begin + copy_old_n, p_buffer + insert_end + copy_old_n); // Copy construct new. - typedef typename etl::iterator_traits::difference_type diff_t; - etl::uninitialized_copy(first + static_cast(copy_new_n), first + static_cast(copy_new_n + construct_new_n), p_end); + etl::uninitialized_copy(first + static_cast(copy_new_n), first + static_cast(copy_new_n + construct_new_n), p_end); ETL_ADD_DEBUG_COUNT(construct_new_n); // Copy new. - etl::copy(first, first + static_cast(copy_new_n), p_buffer + insert_begin); + etl::copy(first, first + static_cast(copy_new_n), p_buffer + insert_begin); p_end += count; }