/* * Copyright (c) 2022, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #pragma once // These concepts are used to help the compiler distinguish between specializations that would be // ambiguous otherwise. For example, if the specializations for int and Vector were declared as // follows: // // template<> ErrorOr decode(Decoder& decoder); // template ErrorOr> decode(Decoder& decoder); // // Then decode() would be ambiguous because either declaration could work (the compiler would // not be able to distinguish if you wanted to decode an int or a Vector of int). // // They also serve to work around the inability to do partial function specialization in C++. namespace IPC::Concepts { namespace Detail { // Cannot use SpecializationOf with these templates because they have non-type parameters. See: // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1985r3.pdf template constexpr inline bool IsArray = false; template constexpr inline bool IsArray> = true; template constexpr inline bool IsVector = false; template constexpr inline bool IsVector> = true; template constexpr inline bool IsHashMap = false; template constexpr inline bool IsHashMap> = true; template constexpr inline bool IsSharedSingleProducerCircularQueue = false; template constexpr inline bool IsSharedSingleProducerCircularQueue> = true; } template concept Array = Detail::IsArray; template concept Vector = Detail::IsVector; template concept Span = SpecializationOf; template concept HashMap = Detail::IsHashMap; template concept SharedSingleProducerCircularQueue = Detail::IsSharedSingleProducerCircularQueue; template concept Optional = SpecializationOf; template concept Variant = SpecializationOf; }