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