diff --git a/include/etl/span.h b/include/etl/span.h index b0f7aaf8..d948c355 100644 --- a/include/etl/span.h +++ b/include/etl/span.h @@ -1509,6 +1509,11 @@ namespace etl template span(const std::array&) -> span; #endif + + // Any other type that supports data() and size() member functions + template ::value && etl::has_size::value + && etl::is_lvalue_reference::value>> + span(TContainer&&) -> span().data())>, etl::dynamic_extent>; #endif //************************************************************************* diff --git a/test/test_span_dynamic_extent.cpp b/test/test_span_dynamic_extent.cpp index b19a4032..05f56880 100644 --- a/test/test_span_dynamic_extent.cpp +++ b/test/test_span_dynamic_extent.cpp @@ -983,6 +983,51 @@ namespace CHECK((std::is_same_v>)); } + //************************************************************************* + TEST(test_template_deduction_guide_for_std_vector) + { + std::vector data = {1, 2, 3, 4}; + const std::vector 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>)); + CHECK((std::is_same_v>)); + } + + //************************************************************************* + 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>)); + } + //************************************************************************* TEST(test_template_deduction_guide_for_iterators) {