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 // template <class T, size_t N> void swap(array<T,N>& x, array<T,N>& y);
125a83710eSEric Fiselier
135a83710eSEric Fiselier #include <array>
145a83710eSEric Fiselier #include <cassert>
155a83710eSEric Fiselier
16f07dd8d0SEric Fiselier #include "test_macros.h"
172decfad7SEric Fiselier
18f07dd8d0SEric Fiselier struct NonSwappable {
NonSwappableNonSwappable19*77b9abfcSLouis Dionne TEST_CONSTEXPR NonSwappable() { }
20f07dd8d0SEric Fiselier private:
21f07dd8d0SEric Fiselier NonSwappable(NonSwappable const&);
22f07dd8d0SEric Fiselier NonSwappable& operator=(NonSwappable const&);
23f07dd8d0SEric Fiselier };
24f07dd8d0SEric Fiselier
25f07dd8d0SEric Fiselier template <class Tp>
26f07dd8d0SEric Fiselier decltype(swap(std::declval<Tp>(), std::declval<Tp>()))
27f07dd8d0SEric Fiselier can_swap_imp(int);
28f07dd8d0SEric Fiselier
29f07dd8d0SEric Fiselier template <class Tp>
30f07dd8d0SEric Fiselier std::false_type can_swap_imp(...);
31f07dd8d0SEric Fiselier
32f07dd8d0SEric Fiselier template <class Tp>
33f07dd8d0SEric Fiselier struct can_swap : std::is_same<decltype(can_swap_imp<Tp>(0)), void> { };
34f07dd8d0SEric Fiselier
tests()35*77b9abfcSLouis Dionne TEST_CONSTEXPR_CXX20 bool tests()
365a83710eSEric Fiselier {
375a83710eSEric Fiselier {
385a83710eSEric Fiselier typedef double T;
395a83710eSEric Fiselier typedef std::array<T, 3> C;
405a83710eSEric Fiselier C c1 = {1, 2, 3.5};
415a83710eSEric Fiselier C c2 = {4, 5, 6.5};
425a83710eSEric Fiselier swap(c1, c2);
435a83710eSEric Fiselier assert(c1.size() == 3);
445a83710eSEric Fiselier assert(c1[0] == 4);
455a83710eSEric Fiselier assert(c1[1] == 5);
465a83710eSEric Fiselier assert(c1[2] == 6.5);
475a83710eSEric Fiselier assert(c2.size() == 3);
485a83710eSEric Fiselier assert(c2[0] == 1);
495a83710eSEric Fiselier assert(c2[1] == 2);
505a83710eSEric Fiselier assert(c2[2] == 3.5);
515a83710eSEric Fiselier }
525a83710eSEric Fiselier {
535a83710eSEric Fiselier typedef double T;
545a83710eSEric Fiselier typedef std::array<T, 0> C;
555a83710eSEric Fiselier C c1 = {};
565a83710eSEric Fiselier C c2 = {};
575a83710eSEric Fiselier swap(c1, c2);
585a83710eSEric Fiselier assert(c1.size() == 0);
595a83710eSEric Fiselier assert(c2.size() == 0);
605a83710eSEric Fiselier }
61f07dd8d0SEric Fiselier {
62f07dd8d0SEric Fiselier typedef NonSwappable T;
63f07dd8d0SEric Fiselier typedef std::array<T, 0> C0;
64f07dd8d0SEric Fiselier static_assert(can_swap<C0&>::value, "");
65f07dd8d0SEric Fiselier C0 l = {};
66f07dd8d0SEric Fiselier C0 r = {};
67f07dd8d0SEric Fiselier swap(l, r);
68f07dd8d0SEric Fiselier #if TEST_STD_VER >= 11
69f07dd8d0SEric Fiselier static_assert(noexcept(swap(l, r)), "");
70f07dd8d0SEric Fiselier #endif
71f07dd8d0SEric Fiselier }
72b7f045fcSEric Fiselier #if TEST_STD_VER >= 11
73b7f045fcSEric Fiselier {
74b7f045fcSEric Fiselier // NonSwappable is still considered swappable in C++03 because there
75b7f045fcSEric Fiselier // is no access control SFINAE.
76b7f045fcSEric Fiselier typedef NonSwappable T;
77b7f045fcSEric Fiselier typedef std::array<T, 42> C1;
78b7f045fcSEric Fiselier static_assert(!can_swap<C1&>::value, "");
79b7f045fcSEric Fiselier }
80b7f045fcSEric Fiselier #endif
812df59c50SJF Bastien
82*77b9abfcSLouis Dionne return true;
83*77b9abfcSLouis Dionne }
84*77b9abfcSLouis Dionne
main(int,char **)85*77b9abfcSLouis Dionne int main(int, char**)
86*77b9abfcSLouis Dionne {
87*77b9abfcSLouis Dionne tests();
88*77b9abfcSLouis Dionne #if TEST_STD_VER >= 20
89*77b9abfcSLouis Dionne static_assert(tests(), "");
90*77b9abfcSLouis Dionne #endif
912df59c50SJF Bastien return 0;
925a83710eSEric Fiselier }
93