// 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_