Skip to content

Commit 793713e

Browse files
authored
Specially handle array<T, 0> for non-default-constructible T (microsoft#2296)
1 parent e89128e commit 793713e

File tree

3 files changed

+17
-21
lines changed

3 files changed

+17
-21
lines changed

stl/inc/array

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,8 @@ template <class _First, class... _Rest>
615615
array(_First, _Rest...) -> array<typename _Enforce_same<_First, _Rest...>::type, 1 + sizeof...(_Rest)>;
616616
#endif // _HAS_CXX17
617617

618+
struct _Empty_array_element {};
619+
618620
template <class _Ty>
619621
class array<_Ty, 0> {
620622
public:
@@ -728,47 +730,47 @@ public:
728730
_STL_REPORT_ERROR("array subscript out of range");
729731
#endif // _CONTAINER_DEBUG_LEVEL > 0
730732

731-
return _Elems[0];
733+
return *data();
732734
}
733735

734736
_NODISCARD const_reference operator[](size_type) const noexcept /* strengthened */ {
735737
#if _CONTAINER_DEBUG_LEVEL > 0
736738
_STL_REPORT_ERROR("array subscript out of range");
737739
#endif // _CONTAINER_DEBUG_LEVEL > 0
738740

739-
return _Elems[0];
741+
return *data();
740742
}
741743

742744
_NODISCARD reference front() noexcept /* strengthened */ {
743745
#if _CONTAINER_DEBUG_LEVEL > 0
744746
_STL_REPORT_ERROR("array<T, 0>::front() invalid");
745747
#endif // _CONTAINER_DEBUG_LEVEL > 0
746748

747-
return _Elems[0];
749+
return *data();
748750
}
749751

750752
_NODISCARD const_reference front() const noexcept /* strengthened */ {
751753
#if _CONTAINER_DEBUG_LEVEL > 0
752754
_STL_REPORT_ERROR("array<T, 0>::front() invalid");
753755
#endif // _CONTAINER_DEBUG_LEVEL > 0
754756

755-
return _Elems[0];
757+
return *data();
756758
}
757759

758760
_NODISCARD reference back() noexcept /* strengthened */ {
759761
#if _CONTAINER_DEBUG_LEVEL > 0
760762
_STL_REPORT_ERROR("array<T, 0>::back() invalid");
761763
#endif // _CONTAINER_DEBUG_LEVEL > 0
762764

763-
return _Elems[0];
765+
return *data();
764766
}
765767

766768
_NODISCARD const_reference back() const noexcept /* strengthened */ {
767769
#if _CONTAINER_DEBUG_LEVEL > 0
768770
_STL_REPORT_ERROR("array<T, 0>::back() invalid");
769771
#endif // _CONTAINER_DEBUG_LEVEL > 0
770772

771-
return _Elems[0];
773+
return *data();
772774
}
773775

774776
_NODISCARD _CONSTEXPR17 _Ty* data() noexcept {
@@ -783,7 +785,9 @@ public:
783785
_Xout_of_range("invalid array<T, 0> subscript");
784786
}
785787

786-
_Ty _Elems[1];
788+
conditional_t<disjunction_v<is_default_constructible<_Ty>, _Is_implicitly_default_constructible<_Ty>>, _Ty,
789+
_Empty_array_element>
790+
_Elems[1];
787791
};
788792

789793
template <class _Ty, size_t _Size, enable_if_t<_Size == 0 || _Is_swappable<_Ty>::value, int> = 0>

tests/libcxx/expected_results.txt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ std/language.support/support.limits/support.limits.general/concepts.version.pass
6969
# Bogus test believes that optional<non_constexpr_destructor> cannot be a literal type
7070
std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp:0 FAIL
7171

72+
# Bogus test believes that copyability of array<T, 0> must be the same as array<T, 1>
73+
std/containers/sequences/array/array.cons/implicit_copy.pass.cpp FAIL
74+
7275

7376
# *** INTERACTIONS WITH CONTEST / C1XX THAT UPSTREAM LIKELY WON'T FIX ***
7477
# Tracked by VSO-593630 "<filesystem> Enable libcxx filesystem tests"
@@ -343,13 +346,6 @@ std/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp FAIL
343346
std/containers/sequences/array/array.fill/fill.fail.cpp FAIL
344347
std/containers/sequences/array/array.swap/swap.fail.cpp FAIL
345348

346-
# GH-942 <array>: std::array<T,0> doesn't compile - when type is not default constructible
347-
std/containers/sequences/array/array.cons/implicit_copy.pass.cpp FAIL
348-
std/containers/sequences/array/array.cons/initialization.pass.cpp FAIL
349-
std/containers/sequences/array/array.data/data_const.pass.cpp FAIL
350-
std/containers/sequences/array/array.data/data.pass.cpp FAIL
351-
std/containers/sequences/array/iterators.pass.cpp FAIL
352-
353349
# GH-1006 <algorithm>: debug checks for predicates are observable
354350
std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp FAIL
355351
std/algorithms/alg.sorting/alg.min.max/minmax_init_list_comp.pass.cpp FAIL

tests/libcxx/skipped_tests.txt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ language.support\support.limits\support.limits.general\concepts.version.pass.cpp
6969
# Bogus test believes that optional<non_constexpr_destructor> cannot be a literal type
7070
utilities\optional\optional.object\optional.object.dtor\dtor.pass.cpp
7171

72+
# Bogus test believes that copyability of array<T, 0> must be the same as array<T, 1>
73+
containers\sequences\array\array.cons\implicit_copy.pass.cpp
74+
7275

7376
# *** INTERACTIONS WITH CONTEST / C1XX THAT UPSTREAM LIKELY WON'T FIX ***
7477
# Tracked by VSO-593630 "<filesystem> Enable libcxx filesystem tests"
@@ -343,13 +346,6 @@ input.output\file.streams\fstreams\filebuf.virtuals\underflow.pass.cpp
343346
containers\sequences\array\array.fill\fill.fail.cpp
344347
containers\sequences\array\array.swap\swap.fail.cpp
345348

346-
# GH-942 <array>: std::array<T,0> doesn't compile - when type is not default constructible
347-
containers\sequences\array\array.cons\implicit_copy.pass.cpp
348-
containers\sequences\array\array.cons\initialization.pass.cpp
349-
containers\sequences\array\array.data\data_const.pass.cpp
350-
containers\sequences\array\array.data\data.pass.cpp
351-
containers\sequences\array\iterators.pass.cpp
352-
353349
# GH-1006 <algorithm>: debug checks for predicates are observable
354350
algorithms\alg.sorting\alg.merge\inplace_merge_comp.pass.cpp
355351
algorithms\alg.sorting\alg.min.max\minmax_init_list_comp.pass.cpp

0 commit comments

Comments
 (0)