From 66be7b3b64b44c4ded741ce6b7c1ede487a840c3 Mon Sep 17 00:00:00 2001 From: Martin Moene Date: Sun, 1 Nov 2020 20:58:19 +0100 Subject: [PATCH] Fix span iterator deduction guide (#61, thanks @Ryan-rsm-McKenzie) --- README.md | 1 + include/nonstd/span.hpp | 6 ++++-- test/span.t.cpp | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 32c2dc7..ac0e89d 100644 --- a/README.md +++ b/README.md @@ -430,6 +430,7 @@ span<>: Allows to construct from a non-null pointer to const and a size span<>: Allows to construct from a temporary pointer and a size span<>: Allows to construct from a temporary pointer to const and a size span<>: Allows to construct from any pointer and a zero size +span<>: Allows to construct from an iterator and a size via an iterator deduction guide (C++17) span<>: Allows to construct from a C-array span<>: Allows to construct from a const C-array span<>: Allows to construct from a C-array with size via decay to pointer (potentially dangerous) diff --git a/include/nonstd/span.hpp b/include/nonstd/span.hpp index 536bbce..7490b79 100644 --- a/include/nonstd/span.hpp +++ b/include/nonstd/span.hpp @@ -661,8 +661,10 @@ using nonstd::byte; namespace std20 { +#if span_HAVE( DEDUCTION_GUIDES ) template< class T > -struct iter_reference { typedef T type; }; +using iter_reference_t = decltype( *std::declval() ); +#endif } // namespace std20 @@ -1268,7 +1270,7 @@ span( Container const & ) -> span; // iterator: constraints: It satisfies contiguous_­iterator. template< class It, class EndOrSize > -span( It, EndOrSize ) -> span< typename std11::remove_reference< typename std20::iter_reference::type >::type >; +span( It, EndOrSize ) -> span< typename std11::remove_reference< typename std20::iter_reference_t >::type >; #endif // span_HAVE( DEDUCTION_GUIDES ) diff --git a/test/span.t.cpp b/test/span.t.cpp index 08132ec..de38a98 100644 --- a/test/span.t.cpp +++ b/test/span.t.cpp @@ -248,6 +248,20 @@ CASE( "span<>: Allows to construct from any pointer and a zero size" ) EXPECT_NO_THROW( F::nonnull() ); } +CASE( "span<>: Allows to construct from an iterator and a size via an iterator deduction guide (C++17)" ) +{ +#if span_HAVE( DEDUCTION_GUIDES ) + char const * argv[] = { "prog", "arg1", "arg2" }; + int const argc = DIMENSION_OF( argv ); + + span args(argv, argc); + + EXPECT( span.length() == DIMENSION_OF( argv ) ); +#else + EXPECT( !!"iterator deduction guide is not available (no C++17)" ); +#endif +} + CASE( "span<>: Allows to construct from a C-array" ) { int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, };