diff options
| author | Dave Hill <d@vehill.net> | 2018-11-05 15:39:41 -0800 |
|---|---|---|
| committer | Anna Gringauze <annagrin@microsoft.com> | 2018-11-05 15:39:41 -0800 |
| commit | c02ddae4bcff82b17826fe3127e835f5aa54b485 (patch) | |
| tree | 615de53bf823766b697746b0cbf2144076343d57 | |
| parent | 2bf9f137a6ff12aa53424fd7d86510247216acb8 (diff) | |
| download | platform_external_Microsoft-GSL-c02ddae4bcff82b17826fe3127e835f5aa54b485.tar.gz platform_external_Microsoft-GSL-c02ddae4bcff82b17826fe3127e835f5aa54b485.tar.bz2 platform_external_Microsoft-GSL-c02ddae4bcff82b17826fe3127e835f5aa54b485.zip | |
Span can be constructed from empty std::array safely (#686)
* Span std::array c'tor uses arr.data() instead of &arr[0]
- Fixes runtime issues when constructing from an empty std::array
* Construct span with std::data if C++17 detected
* Specialize span c'tor for std::array of length 0, set storage to nullptr
| -rw-r--r-- | include/gsl/span | 28 | ||||
| -rw-r--r-- | tests/span_tests.cpp | 8 |
2 files changed, 26 insertions, 10 deletions
diff --git a/include/gsl/span b/include/gsl/span index 8cb3dbe..b356ee9 100644 --- a/include/gsl/span +++ b/include/gsl/span @@ -394,17 +394,27 @@ public: : storage_(KnownNotNull{std::addressof(arr[0])}, details::extent_type<N>()) {} - template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>> - // GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug - constexpr span(std::array<ArrayElementType, N>& arr) noexcept - : storage_(arr.data(), details::extent_type<N>()) - {} + template <std::size_t N, class = std::enable_if_t<(N > 0)>> + constexpr span(std::array<std::remove_const_t<element_type>, N>& arr) noexcept + : storage_(KnownNotNull{arr.data()}, details::extent_type<N>()) + { + } - template <std::size_t N> - // GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug + constexpr span(std::array<std::remove_const_t<element_type>, 0>&) noexcept + : storage_(static_cast<pointer>(nullptr), details::extent_type<0>()) + { + } + + template <std::size_t N, class = std::enable_if_t<(N > 0)>> constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept - : storage_(arr.data(), details::extent_type<N>()) - {} + : storage_(KnownNotNull{arr.data()}, details::extent_type<N>()) + { + } + + constexpr span(const std::array<std::remove_const_t<element_type>, 0>&) noexcept + : storage_(static_cast<pointer>(nullptr), details::extent_type<0>()) + { + } // NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement // on Container to be a contiguous sequence container. diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 07a59c8..b38b4eb 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -452,7 +452,13 @@ TEST_CASE("from_std_array_constructor") CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data())); } - std::array<AddressOverloaded, 4> ao_arr{}; + { + std::array<int, 0> empty_arr{}; + span<int> s{empty_arr}; + CHECK((s.size() == 0 && s.empty())); + } + + std::array<AddressOverloaded, 4> ao_arr{}; { span<AddressOverloaded, 4> fs{ao_arr}; |
