/* * SPDX-FileCopyrightText: Dora "cat" * SPDX-License-Identifier: MPL-2.0 * * This Source Code Form is subject to the terms of the Mozilla Public License, * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef GUARD_TOURMALINE_CONCEPTS_H #define GUARD_TOURMALINE_CONCEPTS_H #include #include #include #include namespace Tourmaline::Concepts { template concept Hashable = std::equality_comparable && requires(T x) { { std::hash{}(x) } -> std::convertible_to; }; template concept Either = std::same_as || std::same_as; // Oh C++ and your jank template struct _opposite_of { using type = std::conditional_t, Type2, Type1>; }; template requires Either using OppositeOf = _opposite_of::type; // heavily inspired by // https://github.com/aminroosta/sqlite_modern_cpp/blob/master/hdr/sqlite_modern_cpp/utility/function_traits.h template struct FunctionTraits; template struct FunctionTraits : public FunctionTraits< decltype(&std::remove_reference_t::operator())> {}; template struct FunctionTraits : FunctionTraits {}; template struct FunctionTraits : FunctionTraits {}; template struct FunctionTraits { using returnType = Return; using arguments = std::tuple; template using argument = std::tuple_element_t; static constexpr std::size_t argumentCount = sizeof...(Arguments); }; } // namespace Tourmaline::Concepts #endif