Skip to content

Commit 7994108

Browse files
misccoldionne
authored andcommitted
[libc++][span] SFINAE span default constructor on Extent == 0
The default constructor of a static span requires _Extent == 0 so SFINAE it out rather than using a static_assert Differential Revision: https://reviews.llvm.org/D71994
1 parent d061685 commit 7994108

File tree

3 files changed

+10
-8
lines changed

3 files changed

+10
-8
lines changed

libcxx/include/span

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ public:
200200
static constexpr size_type extent = _Extent;
201201

202202
// [span.cons], span constructors, copy, assignment, and destructor
203-
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}
204-
{ static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); }
203+
template <size_t _Sz = _Extent, enable_if_t<_Sz == 0, nullptr_t> = nullptr>
204+
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {}
205205

206206
constexpr span (const span&) noexcept = default;
207207
constexpr span& operator=(const span&) noexcept = default;

libcxx/test/std/containers/views/span.cons/default.fail.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// constexpr span() noexcept;
1414
//
1515
// Remarks: This constructor shall not participate in overload resolution
16-
// unless Extent <= 0 is true.
16+
// unless Extent == 0 || Extent == dynamic_extent is true.
1717

1818

1919
#include <span>
@@ -24,10 +24,7 @@
2424

2525
int main(int, char**)
2626
{
27-
std::span<int, 2> s; // expected-error-re@span:* {{static_assert failed{{( due to requirement '.*')?}} "Can't default construct a statically sized span with size > 0"}}
28-
29-
// TODO: This is what I want:
30-
// eXpected-error {{no matching constructor for initialization of 'std::span<int, 2>'}}
27+
std::span<int, 2> s; // expected-error {{no matching constructor for initialization of 'std::span<int, 2>'}}
3128

3229
return 0;
3330
}

libcxx/test/std/containers/views/span.cons/default.pass.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <span>
1616
#include <cassert>
1717
#include <string>
18+
#include <type_traits>
1819

1920
#include "test_macros.h"
2021

@@ -79,5 +80,9 @@ int main(int, char**)
7980

8081
checkCV();
8182

82-
return 0;
83+
static_assert( std::is_default_constructible_v<std::span<int, std::dynamic_extent>>, "");
84+
static_assert( std::is_default_constructible_v<std::span<int, 0>>, "");
85+
static_assert(!std::is_default_constructible_v<std::span<int, 2>>, "");
86+
87+
return 0;
8388
}

0 commit comments

Comments
 (0)