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 
1177b9abfcSLouis Dionne // iterator begin() noexcept;                         // constexpr in C++17
1277b9abfcSLouis Dionne // const_iterator begin() const noexcept;             // constexpr in C++17
1377b9abfcSLouis Dionne // iterator end() noexcept;                           // constexpr in C++17
1477b9abfcSLouis Dionne // const_iterator end() const noexcept;               // constexpr in C++17
1577b9abfcSLouis Dionne //
1677b9abfcSLouis Dionne // reverse_iterator rbegin() noexcept;                // constexpr in C++17
1777b9abfcSLouis Dionne // const_reverse_iterator rbegin() const noexcept;    // constexpr in C++17
1877b9abfcSLouis Dionne // reverse_iterator rend() noexcept;                  // constexpr in C++17
1977b9abfcSLouis Dionne // const_reverse_iterator rend() const noexcept;      // constexpr in C++17
2077b9abfcSLouis Dionne //
2177b9abfcSLouis Dionne // const_iterator cbegin() const noexcept;            // constexpr in C++17
2277b9abfcSLouis Dionne // const_iterator cend() const noexcept;              // constexpr in C++17
2377b9abfcSLouis Dionne // const_reverse_iterator crbegin() const noexcept;   // constexpr in C++17
2477b9abfcSLouis Dionne // const_reverse_iterator crend() const noexcept;     // constexpr in C++17
255a83710eSEric Fiselier 
265a83710eSEric Fiselier #include <array>
275a83710eSEric Fiselier #include <iterator>
285a83710eSEric Fiselier #include <cassert>
295a83710eSEric Fiselier 
300f901c7eSStephan T. Lavavej #include "test_macros.h"
310f901c7eSStephan T. Lavavej 
3277b9abfcSLouis Dionne struct NoDefault {
NoDefaultNoDefault3377b9abfcSLouis Dionne     TEST_CONSTEXPR NoDefault(int) { }
3477b9abfcSLouis Dionne };
3577b9abfcSLouis Dionne 
36*ff94bd1bSKonstantin Boyarinov template <class T>
check_noexcept(T & c)37*ff94bd1bSKonstantin Boyarinov TEST_CONSTEXPR_CXX17 void check_noexcept(T& c) {
38*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(c.begin());
39*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(c.end());
40*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(c.cbegin());
41*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(c.cend());
42*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(c.rbegin());
43*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(c.rend());
44*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(c.crbegin());
45*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(c.crend());
46*ff94bd1bSKonstantin Boyarinov 
47*ff94bd1bSKonstantin Boyarinov     const T& cc = c; (void)cc;
48*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(cc.begin());
49*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(cc.end());
50*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(cc.rbegin());
51*ff94bd1bSKonstantin Boyarinov     ASSERT_NOEXCEPT(cc.rend());
52*ff94bd1bSKonstantin Boyarinov }
53*ff94bd1bSKonstantin Boyarinov 
tests()5477b9abfcSLouis Dionne TEST_CONSTEXPR_CXX17 bool tests()
555a83710eSEric Fiselier {
565a83710eSEric Fiselier     {
575a83710eSEric Fiselier         typedef std::array<int, 5> C;
5877b9abfcSLouis Dionne         C array = {};
59*ff94bd1bSKonstantin Boyarinov         check_noexcept(array);
6077b9abfcSLouis Dionne         typename C::iterator i = array.begin();
6177b9abfcSLouis Dionne         typename C::const_iterator j = array.cbegin();
625a83710eSEric Fiselier         assert(i == j);
635a83710eSEric Fiselier     }
645a83710eSEric Fiselier     {
655a83710eSEric Fiselier         typedef std::array<int, 0> C;
6677b9abfcSLouis Dionne         C array = {};
67*ff94bd1bSKonstantin Boyarinov         check_noexcept(array);
6877b9abfcSLouis Dionne         typename C::iterator i = array.begin();
6977b9abfcSLouis Dionne         typename C::const_iterator j = array.cbegin();
705a83710eSEric Fiselier         assert(i == j);
715a83710eSEric Fiselier     }
725a83710eSEric Fiselier 
7377b9abfcSLouis Dionne     {
7477b9abfcSLouis Dionne         typedef std::array<int, 0> C;
7577b9abfcSLouis Dionne         C array = {};
76*ff94bd1bSKonstantin Boyarinov         check_noexcept(array);
7777b9abfcSLouis Dionne         typename C::iterator i = array.begin();
7877b9abfcSLouis Dionne         typename C::const_iterator j = array.cbegin();
7977b9abfcSLouis Dionne         assert(i == array.end());
8077b9abfcSLouis Dionne         assert(j == array.cend());
8177b9abfcSLouis Dionne     }
8277b9abfcSLouis Dionne     {
8377b9abfcSLouis Dionne         typedef std::array<int, 1> C;
8477b9abfcSLouis Dionne         C array = {1};
85*ff94bd1bSKonstantin Boyarinov         check_noexcept(array);
8677b9abfcSLouis Dionne         typename C::iterator i = array.begin();
8777b9abfcSLouis Dionne         assert(*i == 1);
8877b9abfcSLouis Dionne         assert(&*i == array.data());
8977b9abfcSLouis Dionne         *i = 99;
9077b9abfcSLouis Dionne         assert(array[0] == 99);
9177b9abfcSLouis Dionne     }
9277b9abfcSLouis Dionne     {
9377b9abfcSLouis Dionne         typedef std::array<int, 2> C;
9477b9abfcSLouis Dionne         C array = {1, 2};
95*ff94bd1bSKonstantin Boyarinov         check_noexcept(array);
9677b9abfcSLouis Dionne         typename C::iterator i = array.begin();
9777b9abfcSLouis Dionne         assert(*i == 1);
9877b9abfcSLouis Dionne         assert(&*i == array.data());
9977b9abfcSLouis Dionne         *i = 99;
10077b9abfcSLouis Dionne         assert(array[0] == 99);
10177b9abfcSLouis Dionne         assert(array[1] == 2);
10277b9abfcSLouis Dionne     }
10377b9abfcSLouis Dionne     {
10477b9abfcSLouis Dionne         typedef std::array<double, 3> C;
10577b9abfcSLouis Dionne         C array = {1, 2, 3.5};
106*ff94bd1bSKonstantin Boyarinov         check_noexcept(array);
10777b9abfcSLouis Dionne         typename C::iterator i = array.begin();
10877b9abfcSLouis Dionne         assert(*i == 1);
10977b9abfcSLouis Dionne         assert(&*i == array.data());
11077b9abfcSLouis Dionne         *i = 5.5;
11177b9abfcSLouis Dionne         assert(array[0] == 5.5);
11277b9abfcSLouis Dionne         assert(array[1] == 2.0);
11377b9abfcSLouis Dionne     }
11477b9abfcSLouis Dionne     {
11577b9abfcSLouis Dionne         typedef std::array<NoDefault, 0> C;
11677b9abfcSLouis Dionne         C array = {};
11777b9abfcSLouis Dionne         typename C::iterator ib = array.begin();
11877b9abfcSLouis Dionne         typename C::iterator ie = array.end();
11977b9abfcSLouis Dionne         assert(ib == ie);
12077b9abfcSLouis Dionne     }
12177b9abfcSLouis Dionne 
12277b9abfcSLouis Dionne #if TEST_STD_VER >= 14
1235a83710eSEric Fiselier     { // N3644 testing
1245a83710eSEric Fiselier         {
1255a83710eSEric Fiselier             typedef std::array<int, 5> C;
1265a83710eSEric Fiselier             C::iterator ii1{}, ii2{};
1275a83710eSEric Fiselier             C::iterator ii4 = ii1;
1285a83710eSEric Fiselier             C::const_iterator cii{};
1295a83710eSEric Fiselier             assert(ii1 == ii2);
1305a83710eSEric Fiselier             assert(ii1 == ii4);
1315a83710eSEric Fiselier             assert(ii1 == cii);
1325a83710eSEric Fiselier 
1335a83710eSEric Fiselier             assert(!(ii1 != ii2));
1345a83710eSEric Fiselier             assert(!(ii1 != cii));
1355a83710eSEric Fiselier 
13677b9abfcSLouis Dionne             C c = {};
137*ff94bd1bSKonstantin Boyarinov             check_noexcept(c);
1385a83710eSEric Fiselier             assert(c.begin()   == std::begin(c));
1395a83710eSEric Fiselier             assert(c.cbegin()  == std::cbegin(c));
1405a83710eSEric Fiselier             assert(c.rbegin()  == std::rbegin(c));
1415a83710eSEric Fiselier             assert(c.crbegin() == std::crbegin(c));
1425a83710eSEric Fiselier             assert(c.end()     == std::end(c));
1435a83710eSEric Fiselier             assert(c.cend()    == std::cend(c));
1445a83710eSEric Fiselier             assert(c.rend()    == std::rend(c));
1455a83710eSEric Fiselier             assert(c.crend()   == std::crend(c));
1465a83710eSEric Fiselier 
1475a83710eSEric Fiselier             assert(std::begin(c)   != std::end(c));
1485a83710eSEric Fiselier             assert(std::rbegin(c)  != std::rend(c));
1495a83710eSEric Fiselier             assert(std::cbegin(c)  != std::cend(c));
1505a83710eSEric Fiselier             assert(std::crbegin(c) != std::crend(c));
1515a83710eSEric Fiselier         }
1525a83710eSEric Fiselier         {
1535a83710eSEric Fiselier             typedef std::array<int, 0> C;
1545a83710eSEric Fiselier             C::iterator ii1{}, ii2{};
1555a83710eSEric Fiselier             C::iterator ii4 = ii1;
1565a83710eSEric Fiselier             C::const_iterator cii{};
1575a83710eSEric Fiselier             assert(ii1 == ii2);
1585a83710eSEric Fiselier             assert(ii1 == ii4);
1595a83710eSEric Fiselier 
1605a83710eSEric Fiselier             assert(!(ii1 != ii2));
1615a83710eSEric Fiselier 
1625a83710eSEric Fiselier             assert( (ii1 == cii));
1635a83710eSEric Fiselier             assert( (cii == ii1));
1645a83710eSEric Fiselier             assert(!(ii1 != cii));
1655a83710eSEric Fiselier             assert(!(cii != ii1));
1665a83710eSEric Fiselier             assert(!(ii1 <  cii));
1675a83710eSEric Fiselier             assert(!(cii <  ii1));
1685a83710eSEric Fiselier             assert( (ii1 <= cii));
1695a83710eSEric Fiselier             assert( (cii <= ii1));
1705a83710eSEric Fiselier             assert(!(ii1 >  cii));
1715a83710eSEric Fiselier             assert(!(cii >  ii1));
1725a83710eSEric Fiselier             assert( (ii1 >= cii));
1735a83710eSEric Fiselier             assert( (cii >= ii1));
1745a83710eSEric Fiselier             assert(cii - ii1 == 0);
1755a83710eSEric Fiselier             assert(ii1 - cii == 0);
1765a83710eSEric Fiselier 
17777b9abfcSLouis Dionne             C c = {};
178*ff94bd1bSKonstantin Boyarinov             check_noexcept(c);
1795a83710eSEric Fiselier             assert(c.begin()   == std::begin(c));
1805a83710eSEric Fiselier             assert(c.cbegin()  == std::cbegin(c));
1815a83710eSEric Fiselier             assert(c.rbegin()  == std::rbegin(c));
1825a83710eSEric Fiselier             assert(c.crbegin() == std::crbegin(c));
1835a83710eSEric Fiselier             assert(c.end()     == std::end(c));
1845a83710eSEric Fiselier             assert(c.cend()    == std::cend(c));
1855a83710eSEric Fiselier             assert(c.rend()    == std::rend(c));
1865a83710eSEric Fiselier             assert(c.crend()   == std::crend(c));
1875a83710eSEric Fiselier 
1885a83710eSEric Fiselier             assert(std::begin(c)   == std::end(c));
1895a83710eSEric Fiselier             assert(std::rbegin(c)  == std::rend(c));
1905a83710eSEric Fiselier             assert(std::cbegin(c)  == std::cend(c));
1915a83710eSEric Fiselier             assert(std::crbegin(c) == std::crend(c));
1925a83710eSEric Fiselier         }
1935a83710eSEric Fiselier     }
1945a83710eSEric Fiselier #endif
19577b9abfcSLouis Dionne     return true;
196020b623aSMarshall Clow }
1972df59c50SJF Bastien 
main(int,char **)19877b9abfcSLouis Dionne int main(int, char**)
19977b9abfcSLouis Dionne {
20077b9abfcSLouis Dionne     tests();
20177b9abfcSLouis Dionne #if TEST_STD_VER >= 17
20277b9abfcSLouis Dionne     static_assert(tests(), "");
20377b9abfcSLouis Dionne #endif
2042df59c50SJF Bastien   return 0;
2055a83710eSEric Fiselier }
206