(root)/
gcc-13.2.0/
libstdc++-v3/
testsuite/
experimental/
simd/
tests/
bits/
metahelpers.h
       1  // Copyright (C) 2020-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  #ifndef VC_TESTS_METAHELPERS_H_
      19  #define VC_TESTS_METAHELPERS_H_
      20  
      21  #include <functional>
      22  #include <type_traits>
      23  #include <utility>
      24  
      25  namespace vir
      26  {
      27    namespace test
      28    {
      29      template <class A, class B, class Op>
      30        constexpr bool
      31        operator_is_substitution_failure_impl(float)
      32        { return true; }
      33  
      34      template <class A, class B, class Op>
      35        constexpr typename std::conditional<true, bool, decltype(
      36  	  Op()(std::declval<A>(), std::declval<B>()))>::type
      37        operator_is_substitution_failure_impl(int)
      38        { return false; }
      39  
      40      template <class... Ts>
      41        constexpr bool
      42        operator_is_substitution_failure()
      43        { return operator_is_substitution_failure_impl<Ts...>(int()); }
      44  
      45      template <class... Args, class F>
      46        constexpr auto
      47        sfinae_is_callable_impl(int, F &&f) -> typename std::conditional<
      48  	true, std::true_type,
      49  	decltype(std::forward<F>(f)(std::declval<Args>()...))>::type;
      50  
      51      template <class... Args, class F>
      52        constexpr std::false_type
      53        sfinae_is_callable_impl(float, const F &);
      54  
      55      template <class... Args, class F>
      56        constexpr bool
      57        sfinae_is_callable(F &&)
      58        {
      59  	return decltype(
      60  	    sfinae_is_callable_impl<Args...>(int(), std::declval<F>()))::value;
      61        }
      62  
      63      template <class... Args, class F>
      64        constexpr auto sfinae_is_callable_t(F &&f)
      65  	-> decltype(sfinae_is_callable_impl<Args...>(int(), std::declval<F>()));
      66  
      67      template <class A, class B>
      68        constexpr bool
      69        has_less_bits()
      70        { return std::__digits_v<A> < std::__digits_v<B>; }
      71  
      72    }  // namespace test
      73  }  // namespace vir
      74  
      75  struct assignment
      76  {
      77    template <class A, class B>
      78      constexpr decltype(std::declval<A>() = std::declval<B>())
      79      operator()(A &&a, B &&b) const noexcept(noexcept(
      80  	std::forward<A>(a) = std::forward<B>(b)))
      81      { return std::forward<A>(a) = std::forward<B>(b); }
      82  };
      83  
      84  struct bit_shift_left
      85  {
      86    template <class A, class B>
      87      constexpr decltype(std::declval<A>() << std::declval<B>())
      88      operator()(A &&a, B &&b) const noexcept(noexcept(
      89  	std::forward<A>(a) << std::forward<B>(b)))
      90      { return std::forward<A>(a) << std::forward<B>(b); }
      91  };
      92  
      93  struct bit_shift_right
      94  {
      95    template <class A, class B>
      96      constexpr decltype(std::declval<A>() >> std::declval<B>())
      97      operator()(A &&a, B &&b) const noexcept(noexcept(
      98  	std::forward<A>(a) >> std::forward<B>(b)))
      99      { return std::forward<A>(a) >> std::forward<B>(b); }
     100  };
     101  
     102  struct assign_modulus
     103  {
     104    template <class A, class B>
     105      constexpr decltype(std::declval<A>() %= std::declval<B>())
     106      operator()(A &&a, B &&b) const noexcept(noexcept(
     107  	std::forward<A>(a) %= std::forward<B>(b)))
     108      { return std::forward<A>(a) %= std::forward<B>(b); }
     109  };
     110  
     111  struct assign_bit_and
     112  {
     113    template <class A, class B>
     114      constexpr decltype(std::declval<A>() &= std::declval<B>())
     115      operator()(A &&a, B &&b) const noexcept(noexcept(
     116  	std::forward<A>(a) &= std::forward<B>(b)))
     117      { return std::forward<A>(a) &= std::forward<B>(b); }
     118  };
     119  
     120  struct assign_bit_or
     121  {
     122    template <class A, class B>
     123      constexpr decltype(std::declval<A>() |= std::declval<B>())
     124      operator()(A &&a, B &&b) const noexcept(noexcept(
     125  	std::forward<A>(a) |= std::forward<B>(b)))
     126      { return std::forward<A>(a) |= std::forward<B>(b); }
     127  };
     128  
     129  struct assign_bit_xor
     130  {
     131    template <class A, class B>
     132      constexpr decltype(std::declval<A>() ^= std::declval<B>())
     133      operator()(A &&a, B &&b) const noexcept(noexcept(
     134  	std::forward<A>(a) ^= std::forward<B>(b)))
     135      { return std::forward<A>(a) ^= std::forward<B>(b); }
     136  };
     137  
     138  struct assign_bit_shift_left
     139  {
     140    template <class A, class B>
     141      constexpr decltype(std::declval<A>() <<= std::declval<B>())
     142      operator()(A &&a, B &&b) const noexcept(noexcept(
     143  	std::forward<A>(a) <<= std::forward<B>(b)))
     144      { return std::forward<A>(a) <<= std::forward<B>(b); }
     145  };
     146  
     147  struct assign_bit_shift_right
     148  {
     149    template <class A, class B>
     150      constexpr decltype(std::declval<A>() >>= std::declval<B>())
     151      operator()(A &&a, B &&b) const noexcept(noexcept(
     152  	std::forward<A>(a) >>= std::forward<B>(b)))
     153      { return std::forward<A>(a) >>= std::forward<B>(b); }
     154  };
     155  
     156  template <class A, class B, class Op = std::plus<>>
     157    constexpr bool is_substitution_failure
     158      = vir::test::operator_is_substitution_failure<A, B, Op>();
     159  
     160  using vir::test::sfinae_is_callable;
     161  
     162  using vir::test::has_less_bits;
     163  
     164  #endif  // VC_TESTS_METAHELPERS_H_