mirror of
https://github.com/ETLCPP/etl.git
synced 2026-07-30 16:26:17 +08:00
Only enable the assign and insert member functions for class ivector<… (#1467)
* Only enable the assign and insert member functions for class ivector<T*> & class ivector<const T*> 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 <john.wellbelove@etlcpp.com>
This commit is contained in:
parent
04b7004110
commit
55429eddd2
@ -70,6 +70,13 @@ namespace etl
|
|||||||
|
|
||||||
typedef pvoidvector base_t;
|
typedef pvoidvector base_t;
|
||||||
|
|
||||||
|
template <typename TIterator>
|
||||||
|
struct is_compatible_iterator
|
||||||
|
: etl::integral_constant<bool, etl::is_pointer<typename etl::iterator_traits<TIterator>::value_type>::value
|
||||||
|
&& etl::is_convertible<typename etl::iterator_traits<TIterator>::value_type, value_type>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//*********************************************************************
|
//*********************************************************************
|
||||||
@ -320,7 +327,7 @@ namespace etl
|
|||||||
///\param last The iterator to the last element + 1.
|
///\param last The iterator to the last element + 1.
|
||||||
//*********************************************************************
|
//*********************************************************************
|
||||||
template <typename TIterator>
|
template <typename TIterator>
|
||||||
void assign(TIterator first, TIterator last)
|
typename etl::enable_if< is_compatible_iterator<TIterator>::value, void>::type assign(TIterator first, TIterator last)
|
||||||
{
|
{
|
||||||
base_t::assign(first, last);
|
base_t::assign(first, last);
|
||||||
}
|
}
|
||||||
@ -440,8 +447,8 @@ namespace etl
|
|||||||
///\param first The first element to add.
|
///\param first The first element to add.
|
||||||
///\param last The last + 1 element to add.
|
///\param last The last + 1 element to add.
|
||||||
//*********************************************************************
|
//*********************************************************************
|
||||||
template <class TIterator>
|
template <typename TIterator>
|
||||||
void insert(const_iterator position, TIterator first, TIterator last)
|
typename etl::enable_if< is_compatible_iterator<TIterator>::value, void>::type insert(const_iterator position, TIterator first, TIterator last)
|
||||||
{
|
{
|
||||||
base_t::insert(base_t::iterator(position), first, last);
|
base_t::insert(base_t::iterator(position), first, last);
|
||||||
}
|
}
|
||||||
@ -573,6 +580,13 @@ namespace etl
|
|||||||
|
|
||||||
typedef pvoidvector base_t;
|
typedef pvoidvector base_t;
|
||||||
|
|
||||||
|
template <typename TIterator>
|
||||||
|
struct is_compatible_iterator
|
||||||
|
: etl::integral_constant<bool, etl::is_pointer<typename etl::iterator_traits<TIterator>::value_type>::value
|
||||||
|
&& etl::is_convertible<typename etl::iterator_traits<TIterator>::value_type, value_type>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//*********************************************************************
|
//*********************************************************************
|
||||||
@ -823,7 +837,7 @@ namespace etl
|
|||||||
///\param last The iterator to the last element + 1.
|
///\param last The iterator to the last element + 1.
|
||||||
//*********************************************************************
|
//*********************************************************************
|
||||||
template <typename TIterator>
|
template <typename TIterator>
|
||||||
void assign(TIterator first, TIterator last)
|
typename etl::enable_if< is_compatible_iterator<TIterator>::value, void>::type assign(TIterator first, TIterator last)
|
||||||
{
|
{
|
||||||
base_t::assign(first, last);
|
base_t::assign(first, last);
|
||||||
}
|
}
|
||||||
@ -901,8 +915,8 @@ namespace etl
|
|||||||
///\param first The first element to add.
|
///\param first The first element to add.
|
||||||
///\param last The last + 1 element to add.
|
///\param last The last + 1 element to add.
|
||||||
//*********************************************************************
|
//*********************************************************************
|
||||||
template <class TIterator>
|
template <typename TIterator>
|
||||||
void insert(const_iterator position, TIterator first, TIterator last)
|
typename etl::enable_if< is_compatible_iterator<TIterator>::value, void>::type insert(const_iterator position, TIterator first, TIterator last)
|
||||||
{
|
{
|
||||||
base_t::insert(base_t::iterator(position), first, last);
|
base_t::insert(base_t::iterator(position), first, last);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1683,5 +1683,48 @@ namespace
|
|||||||
CHECK(etl_data2.size() == swap_other_data.size());
|
CHECK(etl_data2.size() == swap_other_data.size());
|
||||||
CHECK(etl_data2.max_size() == other_size);
|
CHECK(etl_data2.max_size() == other_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename TContainer, typename TIterator, typename = void>
|
||||||
|
struct is_assign_callable : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TContainer, typename TIterator>
|
||||||
|
struct is_assign_callable<TContainer, TIterator,
|
||||||
|
etl::void_t<decltype(std::declval<TContainer&>().assign(std::declval<TIterator>(), std::declval<TIterator>()))>>
|
||||||
|
: std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TContainer, typename TIterator1, typename TIterator2, typename = void>
|
||||||
|
struct is_insert_callable : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TContainer, typename TIterator1, typename TIterator2>
|
||||||
|
struct is_insert_callable<
|
||||||
|
TContainer, TIterator1, TIterator2,
|
||||||
|
etl::void_t<decltype(std::declval<TContainer&>().insert(std::declval<TIterator1>(), std::declval<TIterator2>(), std::declval<TIterator2>()))>>
|
||||||
|
: 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<SomeStruct*, 4>;
|
||||||
|
using Iterator1Type = etl::vector<SomeStruct*, 4>::iterator;
|
||||||
|
using Iterator2Type = etl::vector<SomeStruct, 4>::const_iterator;
|
||||||
|
|
||||||
|
constexpr bool can_assign = is_assign_callable<ContainerType, Iterator2Type>::value;
|
||||||
|
CHECK_FALSE(can_assign);
|
||||||
|
|
||||||
|
constexpr bool can_insert = is_insert_callable<ContainerType, Iterator1Type, Iterator2Type>::value;
|
||||||
|
CHECK_FALSE(can_insert);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user