15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier 
95a83710eSEric Fiselier // <array>
105a83710eSEric Fiselier 
115a83710eSEric Fiselier // T *data();
125a83710eSEric Fiselier 
135a83710eSEric Fiselier #include <array>
145a83710eSEric Fiselier #include <cassert>
15c019b30aSLouis Dionne #include <cstddef>       // for std::max_align_t
16c019b30aSLouis Dionne 
1759cdf90aSEric Fiselier #include "test_macros.h"
185a83710eSEric Fiselier 
19db49965aSMarshall Clow struct NoDefault {
2077b9abfcSLouis Dionne     TEST_CONSTEXPR NoDefault(int) { }
21db49965aSMarshall Clow };
22db49965aSMarshall Clow 
2398f77828SJoerg Sonnenberger #if TEST_STD_VER < 11
2498f77828SJoerg Sonnenberger struct natural_alignment {
2598f77828SJoerg Sonnenberger     long t1;
2698f77828SJoerg Sonnenberger     long long t2;
2798f77828SJoerg Sonnenberger     double t3;
2898f77828SJoerg Sonnenberger     long double t4;
2998f77828SJoerg Sonnenberger };
3098f77828SJoerg Sonnenberger #endif
31db49965aSMarshall Clow 
3277b9abfcSLouis Dionne TEST_CONSTEXPR_CXX17 bool tests()
335a83710eSEric Fiselier {
345a83710eSEric Fiselier     {
355a83710eSEric Fiselier         typedef double T;
365a83710eSEric Fiselier         typedef std::array<T, 3> C;
375a83710eSEric Fiselier         C c = {1, 2, 3.5};
38*ff94bd1bSKonstantin Boyarinov         ASSERT_NOEXCEPT(c.data());
395a83710eSEric Fiselier         T* p = c.data();
405a83710eSEric Fiselier         assert(p[0] == 1);
415a83710eSEric Fiselier         assert(p[1] == 2);
425a83710eSEric Fiselier         assert(p[2] == 3.5);
435a83710eSEric Fiselier     }
445a83710eSEric Fiselier     {
455a83710eSEric Fiselier         typedef double T;
465a83710eSEric Fiselier         typedef std::array<T, 0> C;
475a83710eSEric Fiselier         C c = {};
48*ff94bd1bSKonstantin Boyarinov         ASSERT_NOEXCEPT(c.data());
495a83710eSEric Fiselier         T* p = c.data();
507265ff92SLouis Dionne         (void)p;
5159cdf90aSEric Fiselier     }
5259cdf90aSEric Fiselier     {
5359cdf90aSEric Fiselier         typedef double T;
5459cdf90aSEric Fiselier         typedef std::array<const T, 0> C;
5559cdf90aSEric Fiselier         C c = {{}};
56*ff94bd1bSKonstantin Boyarinov         ASSERT_NOEXCEPT(c.data());
5759cdf90aSEric Fiselier         const T* p = c.data();
587265ff92SLouis Dionne         (void)p;
5959cdf90aSEric Fiselier         static_assert((std::is_same<decltype(c.data()), const T*>::value), "");
6077b9abfcSLouis Dionne     }
6177b9abfcSLouis Dionne     {
6277b9abfcSLouis Dionne         typedef NoDefault T;
6377b9abfcSLouis Dionne         typedef std::array<T, 0> C;
6477b9abfcSLouis Dionne         C c = {};
65*ff94bd1bSKonstantin Boyarinov         ASSERT_NOEXCEPT(c.data());
6677b9abfcSLouis Dionne         T* p = c.data();
677265ff92SLouis Dionne         (void)p;
6859cdf90aSEric Fiselier     }
6959cdf90aSEric Fiselier     {
7077b9abfcSLouis Dionne         std::array<int, 5> c = {0, 1, 2, 3, 4};
7177b9abfcSLouis Dionne         assert(c.data() == &c[0]);
7277b9abfcSLouis Dionne         assert(*c.data() == c[0]);
7377b9abfcSLouis Dionne     }
7477b9abfcSLouis Dionne 
7577b9abfcSLouis Dionne     return true;
7677b9abfcSLouis Dionne }
7777b9abfcSLouis Dionne 
7877b9abfcSLouis Dionne int main(int, char**)
7977b9abfcSLouis Dionne {
8077b9abfcSLouis Dionne     tests();
8177b9abfcSLouis Dionne #if TEST_STD_VER >= 17
8277b9abfcSLouis Dionne     static_assert(tests(), "");
8377b9abfcSLouis Dionne #endif
8477b9abfcSLouis Dionne 
8577b9abfcSLouis Dionne     // Test the alignment of data()
8677b9abfcSLouis Dionne     {
8798f77828SJoerg Sonnenberger #if TEST_STD_VER < 11
8898f77828SJoerg Sonnenberger         typedef natural_alignment T;
8998f77828SJoerg Sonnenberger #else
9059cdf90aSEric Fiselier         typedef std::max_align_t T;
9198f77828SJoerg Sonnenberger #endif
9259cdf90aSEric Fiselier         typedef std::array<T, 0> C;
9359cdf90aSEric Fiselier         const C c = {};
9459cdf90aSEric Fiselier         const T* p = c.data();
9559cdf90aSEric Fiselier         std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(p);
9698f77828SJoerg Sonnenberger         assert(pint % TEST_ALIGNOF(T) == 0);
9759cdf90aSEric Fiselier     }
982df59c50SJF Bastien     return 0;
995a83710eSEric Fiselier }
100