1  // Copyright (C) 2015-2023 Free Software Foundation, Inc.
       2  //
       3  // This file is part of the GNU ISO C++ Library.  This library is free
       4  // software; you can redistribute it and/or modify it under the
       5  // terms of the GNU General Public License as published by the
       6  // Free Software Foundation; either version 3, or (at your option)
       7  // any later version.
       8  //
       9  // This library is distributed in the hope that it will be useful,
      10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12  // GNU General Public License for more details.
      13  //
      14  // You should have received a copy of the GNU General Public License along
      15  // with this library; see the file COPYING3.  If not see
      16  // <http://www.gnu.org/licenses/>.
      17  
      18  #include <type_traits>
      19  #include <testsuite_tr1.h>
      20  #include <utility>
      21  #include <array>
      22  #include <tuple>
      23  #include <queue>
      24  #include <stack>
      25  
      26  #if defined(test_std_is_swappable)
      27  #  ifndef __cpp_lib_is_swappable
      28  #   error "Feature-test macro for is_swappable missing"
      29  #  elif __cpp_lib_is_swappable != 201603
      30  #   error "Feature-test macro for is_swappable has wrong value"
      31  #  endif
      32  // Test std::is_swappable:
      33  template<class T>
      34  using is_swappable = std::is_swappable<T>;
      35  #elif defined(test_std_is_swappable_ext)
      36  // Test our __is_swappable extension:
      37  template<class T>
      38  using is_swappable = std::__is_swappable<T>;
      39  #else
      40  # error "Either test_std_is_swappable or test_std_is_swappable_ext" \
      41          "need to be defined"
      42  #endif
      43  
      44  namespace funny {
      45    struct F {};
      46    void swap(F&, F&) = delete;
      47    void swap(F(&)[5], F(&)[5]);
      48  
      49    struct F2
      50    {
      51      friend void swap(F2&, F2&) = delete;
      52    };
      53  
      54    struct F3
      55    {
      56      friend void swap(F3&, F3) {}
      57    };
      58  
      59    struct DummyCmp
      60    {
      61      template<class T>
      62        bool operator()(const T&, const T&) const
      63        { return false; }
      64    };
      65  }
      66  void test01()
      67  {
      68    using namespace __gnu_test;
      69    // Positive tests.
      70    static_assert(test_property<is_swappable, int>(true), "");
      71    static_assert(test_property<is_swappable, bool>(true), "");
      72    static_assert(test_property<is_swappable, decltype(nullptr)>(true), "");
      73    static_assert(test_property<is_swappable, int&>(true), "");
      74    static_assert(test_property<is_swappable, int&&>(true), "");
      75    static_assert(test_property<is_swappable, int[1]>(true), "");
      76    static_assert(test_property<is_swappable, int[1][2]>(true), "");
      77    static_assert(test_property<is_swappable, int[1][2][3]>(true), "");
      78    static_assert(test_property<is_swappable, int(&)[1]>(true), "");
      79    static_assert(test_property<is_swappable, funny::F[5]>(true), "");
      80    static_assert(test_property<is_swappable, funny::F3>(true), "");
      81    static_assert(test_property<is_swappable, funny::F3[1]>(true), "");
      82    static_assert(test_property<is_swappable, funny::F3[1][2]>(true), "");
      83    static_assert(test_property<is_swappable, funny::F3[1][2][3]>(true), "");
      84    static_assert(test_property<is_swappable,
      85      ThrowCopyConsClass>(true), "");
      86    static_assert(test_property<is_swappable, EnumType>(true), "");
      87    static_assert(test_property<is_swappable, PODType>(true), "");
      88    static_assert(test_property<is_swappable, UnionType>(true), "");
      89    static_assert(test_property<is_swappable, construct::SE>(true), "");
      90    static_assert(test_property<is_swappable, construct::Empty>(true), "");
      91    static_assert(test_property<is_swappable, void*>(true), "");
      92    static_assert(test_property<is_swappable, int const*>(true), "");
      93    static_assert(test_property<is_swappable, ClassType*>(true), "");
      94    static_assert(test_property<is_swappable, int ClassType::*>(true), "");
      95    static_assert(test_property<is_swappable,
      96      void (ClassType::*)()>(true), "");
      97    static_assert(test_property<is_swappable,
      98      construct::Nontrivial>(true), "");
      99    static_assert(test_property<is_swappable, construct::Any>(true), "");
     100    static_assert(test_property<is_swappable, construct::nAny>(true), "");
     101    static_assert(test_property<is_swappable,
     102  		std::pair<int, int>>(true), "");
     103    static_assert(test_property<is_swappable,
     104  		std::pair<int, int>[1]>(true), "");
     105    static_assert(test_property<is_swappable,
     106  		std::pair<int, int>[1][2]>(true), "");
     107    static_assert(test_property<is_swappable,
     108  		std::pair<int, int>[1][2][3]>(true), "");
     109    static_assert(test_property<is_swappable,
     110  		std::pair<construct::Nontrivial, construct::Nontrivial>>(true), "");
     111    static_assert(test_property<is_swappable,
     112  		std::tuple<int>>(true), "");
     113    static_assert(test_property<is_swappable,
     114  		std::tuple<int>[1]>(true), "");
     115    static_assert(test_property<is_swappable,
     116  		std::tuple<int>[1][2]>(true), "");
     117    static_assert(test_property<is_swappable,
     118  		std::tuple<int>[1][2][3]>(true), "");
     119    static_assert(test_property<is_swappable,
     120  		std::tuple<>>(true), "");
     121    static_assert(test_property<is_swappable,
     122  		std::tuple<>[1]>(true), "");
     123    static_assert(test_property<is_swappable,
     124  		std::tuple<>[1][2]>(true), "");
     125    static_assert(test_property<is_swappable,
     126  		std::tuple<>[1][2][3]>(true), "");
     127    static_assert(test_property<is_swappable,
     128  		std::tuple<construct::Nontrivial>>(true), "");
     129    static_assert(test_property<is_swappable,
     130  		std::array<int, 1>>(true), "");
     131    static_assert(test_property<is_swappable,
     132  		std::array<int, 1>[1]>(true), "");
     133    static_assert(test_property<is_swappable,
     134  		std::array<int, 1>[1][2]>(true), "");
     135    static_assert(test_property<is_swappable,
     136  		std::array<int, 1>[1][2][3]>(true), "");
     137    static_assert(test_property<is_swappable,
     138  		std::array<construct::Nontrivial, 1>>(true), "");
     139    static_assert(test_property<is_swappable,
     140          std::array<int, 0>>(true), "");
     141    static_assert(test_property<is_swappable,
     142          std::array<construct::DelCopy, 0>>(true), "");
     143    static_assert(test_property<is_swappable,
     144  		std::queue<int>>(true), "");
     145    static_assert(test_property<is_swappable,
     146  		std::queue<int>[1]>(true), "");
     147    static_assert(test_property<is_swappable,
     148  		std::queue<int>[1][2]>(true), "");
     149    static_assert(test_property<is_swappable,
     150  		std::queue<int>[1][2][3]>(true), "");
     151    static_assert(test_property<is_swappable,
     152  		std::queue<construct::Nontrivial>>(true), "");
     153    static_assert(test_property<is_swappable,
     154  		std::priority_queue<int>>(true), "");
     155    static_assert(test_property<is_swappable,
     156  		std::priority_queue<int>[1]>(true), "");
     157    static_assert(test_property<is_swappable,
     158  		std::priority_queue<int>[1][2]>(true), "");
     159    static_assert(test_property<is_swappable,
     160  		std::priority_queue<int>[1][2][3]>(true), "");
     161    static_assert(test_property<is_swappable,
     162  		std::priority_queue<construct::Nontrivial,
     163  				    std::vector<construct::Nontrivial>,
     164  				    funny::DummyCmp>>(true), "");
     165    static_assert(test_property<is_swappable,
     166  		std::stack<int>>(true), "");
     167    static_assert(test_property<is_swappable,
     168  		std::stack<int>[1]>(true), "");
     169    static_assert(test_property<is_swappable,
     170  		std::stack<int>[1][2]>(true), "");
     171    static_assert(test_property<is_swappable,
     172  		std::stack<int>[1][2][3]>(true), "");
     173    static_assert(test_property<is_swappable,
     174  		std::stack<construct::Nontrivial>>(true), "");
     175    // Negative tests.
     176    static_assert(test_property<is_swappable, void>(false), "");
     177    static_assert(test_property<is_swappable, const void>(false), "");
     178    static_assert(test_property<is_swappable, void()>(false), "");
     179    static_assert(test_property<is_swappable, void() const>(false), "");
     180    static_assert(test_property<is_swappable, void() volatile>(false), "");
     181    static_assert(test_property<is_swappable,
     182      void() const volatile>(false), "");
     183    static_assert(test_property<is_swappable, const int>(false), "");
     184    static_assert(test_property<is_swappable, const bool>(false), "");
     185    static_assert(test_property<is_swappable, int[]>(false), "");
     186    static_assert(test_property<is_swappable, const int[]>(false), "");
     187    static_assert(test_property<is_swappable, int[][1]>(false), "");
     188    static_assert(test_property<is_swappable, const int[1]>(false), "");
     189    static_assert(test_property<is_swappable, const int[1][2]>(false), "");
     190    static_assert(test_property<is_swappable, const int[1][2][3]>(false), "");
     191    static_assert(test_property<is_swappable, construct::DelCopy>(false), "");
     192    static_assert(test_property<is_swappable,
     193      construct::Abstract>(false), "");
     194    static_assert(test_property<is_swappable,
     195      construct::NontrivialUnion>(false), "");
     196    static_assert(test_property<is_swappable, funny::F>(false), "");
     197    static_assert(test_property<is_swappable, funny::F[1]>(false), "");
     198    static_assert(test_property<is_swappable, funny::F[1][2]>(false), "");
     199    static_assert(test_property<is_swappable, funny::F[1][2][3]>(false), "");
     200    static_assert(test_property<is_swappable, funny::F[4]>(false), "");
     201    static_assert(test_property<is_swappable, construct::DelCopy>(false), "");
     202    static_assert(test_property<is_swappable,
     203       DeletedCopyAssignClass>(false), "");
     204    static_assert(test_property<is_swappable,
     205       DeletedMoveAssignClass>(false), "");
     206    static_assert(test_property<is_swappable, funny::F2>(false), "");
     207    static_assert(test_property<is_swappable, funny::F2[1]>(false), "");
     208    static_assert(test_property<is_swappable, funny::F2[1][2]>(false), "");
     209    static_assert(test_property<is_swappable, funny::F2[1][2][3]>(false), "");
     210    static_assert(test_property<is_swappable, funny::F2[4]>(false), "");
     211    static_assert(test_property<is_swappable, funny::F2[5]>(false), "");
     212  }