AK: Allow Badge to accept multiple types
This lets public APIs name several authorized classes. Callers no longer need duplicate overloads for one badge.
This commit is contained in:
parent
ae04222247
commit
ad3d65b834
3 changed files with 165 additions and 2 deletions
57
AK/Badge.h
57
AK/Badge.h
|
|
@ -11,8 +11,11 @@
|
|||
|
||||
namespace AK {
|
||||
|
||||
template<typename...>
|
||||
class Badge;
|
||||
|
||||
template<typename T>
|
||||
class Badge {
|
||||
class Badge<T> {
|
||||
AK_MAKE_NONCOPYABLE(Badge);
|
||||
AK_MAKE_NONMOVABLE(Badge);
|
||||
|
||||
|
|
@ -24,6 +27,58 @@ private:
|
|||
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<typename T, typename U>
|
||||
class Badge<T, U> {
|
||||
AK_MAKE_NONCOPYABLE(Badge);
|
||||
AK_MAKE_NONMOVABLE(Badge);
|
||||
|
||||
private:
|
||||
friend T;
|
||||
friend U;
|
||||
constexpr Badge() = default;
|
||||
};
|
||||
|
||||
template<typename T, typename U, typename V>
|
||||
class Badge<T, U, V> {
|
||||
AK_MAKE_NONCOPYABLE(Badge);
|
||||
AK_MAKE_NONMOVABLE(Badge);
|
||||
|
||||
private:
|
||||
friend T;
|
||||
friend U;
|
||||
friend V;
|
||||
constexpr Badge() = default;
|
||||
};
|
||||
|
||||
template<typename T, typename U, typename V, typename W>
|
||||
class Badge<T, U, V, W> {
|
||||
AK_MAKE_NONCOPYABLE(Badge);
|
||||
AK_MAKE_NONMOVABLE(Badge);
|
||||
|
||||
private:
|
||||
friend T;
|
||||
friend U;
|
||||
friend V;
|
||||
friend W;
|
||||
constexpr Badge() = default;
|
||||
};
|
||||
|
||||
template<typename T, typename U, typename V, typename W, typename X>
|
||||
class Badge<T, U, V, W, X> {
|
||||
AK_MAKE_NONCOPYABLE(Badge);
|
||||
AK_MAKE_NONMOVABLE(Badge);
|
||||
|
||||
private:
|
||||
friend T;
|
||||
friend U;
|
||||
friend V;
|
||||
friend W;
|
||||
friend X;
|
||||
constexpr Badge() = default;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#if USING_AK_GLOBALLY
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class HashMap;
|
|||
template<typename K, typename V, typename KeyTraits = Traits<K>, typename ValueTraits = Traits<V>>
|
||||
using OrderedHashMap = HashMap<K, V, KeyTraits, ValueTraits, true>;
|
||||
|
||||
template<typename T>
|
||||
template<typename... Ts>
|
||||
class Badge;
|
||||
|
||||
template<typename T>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,115 @@
|
|||
|
||||
#include <AK/Badge.h>
|
||||
|
||||
namespace {
|
||||
|
||||
struct MultipleBadgeUserA {
|
||||
static void call_two_argument_badge();
|
||||
static void call_three_argument_badge();
|
||||
static void call_four_argument_badge();
|
||||
static void call_five_argument_badge();
|
||||
};
|
||||
|
||||
struct MultipleBadgeUserB {
|
||||
static void call_two_argument_badge();
|
||||
};
|
||||
|
||||
struct MultipleBadgeUserC {
|
||||
static void call_three_argument_badge();
|
||||
};
|
||||
|
||||
struct MultipleBadgeUserD {
|
||||
static void call_four_argument_badge();
|
||||
};
|
||||
|
||||
struct MultipleBadgeUserE {
|
||||
static void call_five_argument_badge();
|
||||
};
|
||||
|
||||
struct UnrelatedBadgeUser {
|
||||
};
|
||||
|
||||
static void accepts_two_argument_badge(Badge<MultipleBadgeUserA, MultipleBadgeUserB>)
|
||||
{
|
||||
}
|
||||
|
||||
static void accepts_three_argument_badge(Badge<MultipleBadgeUserA, MultipleBadgeUserB, MultipleBadgeUserC>)
|
||||
{
|
||||
}
|
||||
|
||||
static void accepts_four_argument_badge(Badge<MultipleBadgeUserA, MultipleBadgeUserB, MultipleBadgeUserC, MultipleBadgeUserD>)
|
||||
{
|
||||
}
|
||||
|
||||
static void accepts_five_argument_badge(Badge<MultipleBadgeUserA, MultipleBadgeUserB, MultipleBadgeUserC, MultipleBadgeUserD, MultipleBadgeUserE>)
|
||||
{
|
||||
}
|
||||
|
||||
void MultipleBadgeUserA::call_two_argument_badge()
|
||||
{
|
||||
accepts_two_argument_badge({});
|
||||
}
|
||||
|
||||
void MultipleBadgeUserA::call_three_argument_badge()
|
||||
{
|
||||
accepts_three_argument_badge({});
|
||||
}
|
||||
|
||||
void MultipleBadgeUserA::call_four_argument_badge()
|
||||
{
|
||||
accepts_four_argument_badge({});
|
||||
}
|
||||
|
||||
void MultipleBadgeUserA::call_five_argument_badge()
|
||||
{
|
||||
accepts_five_argument_badge({});
|
||||
}
|
||||
|
||||
void MultipleBadgeUserB::call_two_argument_badge()
|
||||
{
|
||||
accepts_two_argument_badge({});
|
||||
}
|
||||
|
||||
void MultipleBadgeUserC::call_three_argument_badge()
|
||||
{
|
||||
accepts_three_argument_badge({});
|
||||
}
|
||||
|
||||
void MultipleBadgeUserD::call_four_argument_badge()
|
||||
{
|
||||
accepts_four_argument_badge({});
|
||||
}
|
||||
|
||||
void MultipleBadgeUserE::call_five_argument_badge()
|
||||
{
|
||||
accepts_five_argument_badge({});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE(should_provide_underlying_type)
|
||||
{
|
||||
static_assert(IsSame<int, Badge<int>::Type>);
|
||||
}
|
||||
|
||||
TEST_CASE(should_allow_multiple_underlying_types)
|
||||
{
|
||||
static_assert(!IsConstructible<Badge<MultipleBadgeUserA, MultipleBadgeUserB>>);
|
||||
static_assert(!IsConstructible<Badge<MultipleBadgeUserA, MultipleBadgeUserB, MultipleBadgeUserC>>);
|
||||
static_assert(!IsConstructible<Badge<MultipleBadgeUserA, MultipleBadgeUserB, MultipleBadgeUserC, MultipleBadgeUserD>>);
|
||||
static_assert(!IsConstructible<Badge<MultipleBadgeUserA, MultipleBadgeUserB>, Badge<MultipleBadgeUserA>>);
|
||||
static_assert(!IsConstructible<Badge<MultipleBadgeUserA, MultipleBadgeUserB, MultipleBadgeUserC, MultipleBadgeUserD, MultipleBadgeUserE>>);
|
||||
static_assert(!IsConstructible<
|
||||
Badge<MultipleBadgeUserA, MultipleBadgeUserB, MultipleBadgeUserC, MultipleBadgeUserD, MultipleBadgeUserE>,
|
||||
Badge<MultipleBadgeUserA> const&>);
|
||||
static_assert(!IsConstructible<Badge<MultipleBadgeUserA, MultipleBadgeUserB>, Badge<UnrelatedBadgeUser>>);
|
||||
|
||||
MultipleBadgeUserA::call_two_argument_badge();
|
||||
MultipleBadgeUserA::call_three_argument_badge();
|
||||
MultipleBadgeUserA::call_four_argument_badge();
|
||||
MultipleBadgeUserA::call_five_argument_badge();
|
||||
MultipleBadgeUserB::call_two_argument_badge();
|
||||
MultipleBadgeUserC::call_three_argument_badge();
|
||||
MultipleBadgeUserD::call_four_argument_badge();
|
||||
MultipleBadgeUserE::call_five_argument_badge();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue