@@ -34,27 +34,6 @@ struct array_value_type<T> {
3434 using type = T;
3535};
3636
37- struct monostate {
38- // Cannot be a hidden friend to work around
39- // https://github.com/llvm/llvm-project/issues/123815
40- auto operator <=>(monostate const &) const & = default ;
41- };
42-
43- template <std::size_t size>
44- struct array_trait {
45- template <typename T>
46- using type = T[size];
47- };
48-
49- template <>
50- struct array_trait <0 > {
51- template <typename >
52- using type = monostate;
53- };
54-
55- template <typename T, std::size_t size>
56- using array_type = typename array_trait<size>::template type<T>;
57-
5837export template <typename T, array_size_type<T> size_, array_size_type<T>... sizes>
5938struct array {
6039 using value_type = typename array_value_type<T, sizes...>::type;
@@ -63,18 +42,10 @@ struct array {
6342 return bounded::constant<size_>;
6443 }
6544 constexpr auto data () const -> value_type const * {
66- if constexpr (size () != 0 ) {
67- return m_value;
68- } else {
69- return nullptr ;
70- }
45+ return m_value;
7146 }
7247 constexpr auto data () -> value_type * {
73- if constexpr (size () != 0 ) {
74- return m_value;
75- } else {
76- return nullptr ;
77- }
48+ return m_value;
7849 }
7950
8051 OPERATORS_BRACKET_SEQUENCE_RANGE_DEFINITIONS
@@ -96,7 +67,46 @@ struct array {
9667
9768 // Consider this private. It must be public for the class to be an
9869 // aggregate
99- [[no_unique_address]] array_type<value_type, static_cast <std::size_t >(size_)> m_value;
70+ c_array<value_type, static_cast <std::size_t >(size_)> m_value;
71+ };
72+
73+ template <typename T, array_size_type<T> size_> requires (size_ == 0_bi)
74+ struct array<T, size_> {
75+ private:
76+ struct monostate {
77+ friend auto operator <=>(monostate, monostate) = default ;
78+ };
79+ public:
80+ using value_type = T;
81+
82+ static constexpr auto size () -> bounded::constant_t <0 > {
83+ return 0_bi;
84+ }
85+ constexpr auto data () const -> value_type const * {
86+ return nullptr ;
87+ }
88+ constexpr auto data () -> value_type * {
89+ return nullptr ;
90+ }
91+
92+ friend auto operator <=>(array, array) = default ;
93+
94+ constexpr operator std::span<T const >() const {
95+ return std::span<T const >(data (), 0 );
96+ }
97+ constexpr operator std::span<T>() {
98+ return std::span<T const >(data (), 0 );
99+ }
100+ constexpr operator std::span<T const , 0 >() const {
101+ return std::span<T const , 0 >(data (), 0 );
102+ }
103+ constexpr operator std::span<T, 0 >() {
104+ return std::span<T const , 0 >(data (), 0 );
105+ }
106+
107+ // Consider this private. It must be public for the class to be an
108+ // aggregate
109+ [[no_unique_address]] monostate m_value;
100110};
101111
102112template <typename ... Args>
0 commit comments