/* * Copyright (c) 2018-2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace AK { namespace Detail { template inline constexpr bool IsBadgeType = IsSame || IsBaseOf; } template class Badge; template class Badge { AK_MAKE_NONCOPYABLE(Badge); AK_MAKE_NONMOVABLE(Badge); public: using Type = T; // Friendship is not inherited, so derived classes mint Badge and // convert it to Badge. template requires(IsBaseOf && !IsSame) constexpr Badge(Badge const&) { } private: friend T; constexpr Badge() = default; }; // FIXME: These overloads are all because compiler support for `friend Ts...;` is limited. // Once compilers can do that, we should only need a single variadic template. template class Badge { AK_MAKE_NONCOPYABLE(Badge); AK_MAKE_NONMOVABLE(Badge); public: template requires(Detail::IsBadgeType || Detail::IsBadgeType) constexpr Badge(Badge const&) { } private: friend T; friend U; constexpr Badge() = default; }; template class Badge { AK_MAKE_NONCOPYABLE(Badge); AK_MAKE_NONMOVABLE(Badge); public: template requires(Detail::IsBadgeType || Detail::IsBadgeType || Detail::IsBadgeType) constexpr Badge(Badge const&) { } private: friend T; friend U; friend V; constexpr Badge() = default; }; template class Badge { AK_MAKE_NONCOPYABLE(Badge); AK_MAKE_NONMOVABLE(Badge); public: template requires(Detail::IsBadgeType || Detail::IsBadgeType || Detail::IsBadgeType || Detail::IsBadgeType) constexpr Badge(Badge const&) { } private: friend T; friend U; friend V; friend W; constexpr Badge() = default; }; template class Badge { AK_MAKE_NONCOPYABLE(Badge); AK_MAKE_NONMOVABLE(Badge); public: template requires(Detail::IsBadgeType || Detail::IsBadgeType || Detail::IsBadgeType || Detail::IsBadgeType || Detail::IsBadgeType) constexpr Badge(Badge const&) { } private: friend T; friend U; friend V; friend W; friend X; constexpr Badge() = default; }; } #if USING_AK_GLOBALLY using AK::Badge; #endif