// Copyright (C) 2020-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// .
#ifndef VC_TESTS_METAHELPERS_H_
#define VC_TESTS_METAHELPERS_H_
#include
#include
#include
namespace vir
{
namespace test
{
template
constexpr bool
operator_is_substitution_failure_impl(float)
{ return true; }
template
constexpr typename std::conditional(), std::declval()))>::type
operator_is_substitution_failure_impl(int)
{ return false; }
template
constexpr bool
operator_is_substitution_failure()
{ return operator_is_substitution_failure_impl(int()); }
template
constexpr auto
sfinae_is_callable_impl(int, F &&f) -> typename std::conditional<
true, std::true_type,
decltype(std::forward(f)(std::declval()...))>::type;
template
constexpr std::false_type
sfinae_is_callable_impl(float, const F &);
template
constexpr bool
sfinae_is_callable(F &&)
{
return decltype(
sfinae_is_callable_impl(int(), std::declval()))::value;
}
template
constexpr auto sfinae_is_callable_t(F &&f)
-> decltype(sfinae_is_callable_impl(int(), std::declval()));
template
constexpr bool
has_less_bits()
{ return std::__digits_v < std::__digits_v; }
} // namespace test
} // namespace vir
struct assignment
{
template
constexpr decltype(std::declval() = std::declval())
operator()(A &&a, B &&b) const noexcept(noexcept(
std::forward(a) = std::forward(b)))
{ return std::forward(a) = std::forward(b); }
};
struct bit_shift_left
{
template
constexpr decltype(std::declval() << std::declval())
operator()(A &&a, B &&b) const noexcept(noexcept(
std::forward(a) << std::forward(b)))
{ return std::forward(a) << std::forward(b); }
};
struct bit_shift_right
{
template
constexpr decltype(std::declval() >> std::declval())
operator()(A &&a, B &&b) const noexcept(noexcept(
std::forward(a) >> std::forward(b)))
{ return std::forward(a) >> std::forward(b); }
};
struct assign_modulus
{
template
constexpr decltype(std::declval() %= std::declval())
operator()(A &&a, B &&b) const noexcept(noexcept(
std::forward(a) %= std::forward(b)))
{ return std::forward(a) %= std::forward(b); }
};
struct assign_bit_and
{
template
constexpr decltype(std::declval() &= std::declval())
operator()(A &&a, B &&b) const noexcept(noexcept(
std::forward(a) &= std::forward(b)))
{ return std::forward(a) &= std::forward(b); }
};
struct assign_bit_or
{
template
constexpr decltype(std::declval() |= std::declval())
operator()(A &&a, B &&b) const noexcept(noexcept(
std::forward(a) |= std::forward(b)))
{ return std::forward(a) |= std::forward(b); }
};
struct assign_bit_xor
{
template
constexpr decltype(std::declval() ^= std::declval())
operator()(A &&a, B &&b) const noexcept(noexcept(
std::forward(a) ^= std::forward(b)))
{ return std::forward(a) ^= std::forward(b); }
};
struct assign_bit_shift_left
{
template
constexpr decltype(std::declval() <<= std::declval())
operator()(A &&a, B &&b) const noexcept(noexcept(
std::forward(a) <<= std::forward(b)))
{ return std::forward(a) <<= std::forward(b); }
};
struct assign_bit_shift_right
{
template
constexpr decltype(std::declval() >>= std::declval())
operator()(A &&a, B &&b) const noexcept(noexcept(
std::forward(a) >>= std::forward(b)))
{ return std::forward(a) >>= std::forward(b); }
};
template >
constexpr bool is_substitution_failure
= vir::test::operator_is_substitution_failure();
using vir::test::sfinae_is_callable;
using vir::test::has_less_bits;
#endif // VC_TESTS_METAHELPERS_H_