From 55429eddd2ca155bb7016e7e2e2bf76a3ebe13b6 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 20 Jun 2026 10:26:03 +0100 Subject: [PATCH] =?UTF-8?q?Only=20enable=20the=20assign=20and=20insert=20m?= =?UTF-8?q?ember=20functions=20for=20class=20ivector<=E2=80=A6=20(#1467)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Only enable the assign and insert member functions for class ivector & class ivector when the value_type the iterator references is a pointer to T. * Imporoved enable_if for assign and insert. * clang-format * std::void_t -> etl::void_t * Made enable_if condition into a common class struct --------- Co-authored-by: John Wellbelove --- include/etl/private/ivectorpointer.h | 26 +++++++++++++---- test/test_vector.cpp | 43 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/include/etl/private/ivectorpointer.h b/include/etl/private/ivectorpointer.h index 2c212b09..c28bab62 100644 --- a/include/etl/private/ivectorpointer.h +++ b/include/etl/private/ivectorpointer.h @@ -70,6 +70,13 @@ namespace etl typedef pvoidvector base_t; + template + struct is_compatible_iterator + : etl::integral_constant::value_type>::value + && etl::is_convertible::value_type, value_type>::value> + { + }; + public: //********************************************************************* @@ -320,7 +327,7 @@ namespace etl ///\param last The iterator to the last element + 1. //********************************************************************* template - void assign(TIterator first, TIterator last) + typename etl::enable_if< is_compatible_iterator::value, void>::type assign(TIterator first, TIterator last) { base_t::assign(first, last); } @@ -440,8 +447,8 @@ namespace etl ///\param first The first element to add. ///\param last The last + 1 element to add. //********************************************************************* - template - void insert(const_iterator position, TIterator first, TIterator last) + template + typename etl::enable_if< is_compatible_iterator::value, void>::type insert(const_iterator position, TIterator first, TIterator last) { base_t::insert(base_t::iterator(position), first, last); } @@ -573,6 +580,13 @@ namespace etl typedef pvoidvector base_t; + template + struct is_compatible_iterator + : etl::integral_constant::value_type>::value + && etl::is_convertible::value_type, value_type>::value> + { + }; + public: //********************************************************************* @@ -823,7 +837,7 @@ namespace etl ///\param last The iterator to the last element + 1. //********************************************************************* template - void assign(TIterator first, TIterator last) + typename etl::enable_if< is_compatible_iterator::value, void>::type assign(TIterator first, TIterator last) { base_t::assign(first, last); } @@ -901,8 +915,8 @@ namespace etl ///\param first The first element to add. ///\param last The last + 1 element to add. //********************************************************************* - template - void insert(const_iterator position, TIterator first, TIterator last) + template + typename etl::enable_if< is_compatible_iterator::value, void>::type insert(const_iterator position, TIterator first, TIterator last) { base_t::insert(base_t::iterator(position), first, last); } diff --git a/test/test_vector.cpp b/test/test_vector.cpp index ed3e416b..49f84e80 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -1683,5 +1683,48 @@ namespace CHECK(etl_data2.size() == swap_other_data.size()); CHECK(etl_data2.max_size() == other_size); } + + //************************************************************************* + template + struct is_assign_callable : std::false_type + { + }; + + template + struct is_assign_callable().assign(std::declval(), std::declval()))>> + : std::true_type + { + }; + + template + struct is_insert_callable : std::false_type + { + }; + + template + struct is_insert_callable< + TContainer, TIterator1, TIterator2, + etl::void_t().insert(std::declval(), std::declval(), std::declval()))>> + : std::true_type + { + }; + TEST_FIXTURE(SetupFixture, test_issue_1464_etl_vector_insert_allows_inserting_an_incompatible_type) + { + struct SomeStruct + { + int foo; + }; + + using ContainerType = etl::vector; + using Iterator1Type = etl::vector::iterator; + using Iterator2Type = etl::vector::const_iterator; + + constexpr bool can_assign = is_assign_callable::value; + CHECK_FALSE(can_assign); + + constexpr bool can_insert = is_insert_callable::value; + CHECK_FALSE(can_insert); + } } } // namespace