Add span deduction guide for types with data() and size(). (#1550)

* Add span deduction guide for types with data() and size().

This enables span construct with type deduction from containers which support
.data() and .size(), primarily vector.
---------

Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
Marco Nilsson 2026-08-13 16:41:12 +02:00 committed by GitHub
parent 9fcbb0af47
commit 7ee5a661b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 0 deletions

View File

@ -1509,6 +1509,11 @@ namespace etl
template <typename T, size_t Size> template <typename T, size_t Size>
span(const std::array<T, Size>&) -> span<const T, Size>; span(const std::array<T, Size>&) -> span<const T, Size>;
#endif #endif
// Any other type that supports data() and size() member functions
template <typename TContainer, typename = etl::enable_if_t<etl::has_data<TContainer>::value && etl::has_size<TContainer>::value
&& etl::is_lvalue_reference<TContainer&&>::value>>
span(TContainer&&) -> span<etl::remove_pointer_t<decltype(etl::declval<TContainer&>().data())>, etl::dynamic_extent>;
#endif #endif
//************************************************************************* //*************************************************************************

View File

@ -983,6 +983,51 @@ namespace
CHECK((std::is_same_v<const int* const, std::remove_reference_t<decltype(pspan4_ext.front())>>)); CHECK((std::is_same_v<const int* const, std::remove_reference_t<decltype(pspan4_ext.front())>>));
} }
//*************************************************************************
TEST(test_template_deduction_guide_for_std_vector)
{
std::vector<int> data = {1, 2, 3, 4};
const std::vector<int> data2 = {1, 2, 3, 4};
etl::span span = data;
etl::span span2 = data2;
CHECK_EQUAL(etl::dynamic_extent, span.extent);
CHECK_EQUAL(ETL_OR_STD17::size(data), span.size());
CHECK_EQUAL(etl::dynamic_extent, span2.extent);
CHECK_EQUAL(ETL_OR_STD17::size(data2), span2.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(span.front())>>));
CHECK((std::is_same_v<const int, std::remove_reference_t<decltype(span2.front())>>));
}
//*************************************************************************
TEST(test_template_deduction_guide_for_type_with_data_and_size)
{
struct DataAndSize
{
int buffer[4] = {1, 2, 3, 4};
int* data()
{
return buffer;
}
size_t size() const
{
return 4U;
}
using value_type = int;
};
DataAndSize data;
etl::span span = data;
CHECK_EQUAL(etl::dynamic_extent, span.extent);
CHECK_EQUAL(data.size(), span.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(span.front())>>));
}
//************************************************************************* //*************************************************************************
TEST(test_template_deduction_guide_for_iterators) TEST(test_template_deduction_guide_for_iterators)
{ {