summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibIPC/Concepts.h
blob: 99746e00c82019b0e6df08e389789a9e40ae2da7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
 * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <AK/HashMap.h>
#include <AK/Optional.h>
#include <AK/Variant.h>
#include <AK/Vector.h>
#include <LibCore/SharedCircularQueue.h>

#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<T> were declared as
// follows:
//
//     template<> ErrorOr<int> decode(Decoder& decoder);
//     template<typename T> ErrorOr<Vector<T>> decode(Decoder& decoder);
//
// Then decode<int>() 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).
namespace IPC::Concepts {

namespace Detail {

template<typename T>
constexpr inline bool IsHashMap = false;
template<typename K, typename V>
constexpr inline bool IsHashMap<HashMap<K, V>> = true;
template<typename K, typename V>
constexpr inline bool IsHashMap<OrderedHashMap<K, V>> = true;

template<typename T>
constexpr inline bool IsOptional = false;
template<typename T>
constexpr inline bool IsOptional<Optional<T>> = true;

template<typename T>
constexpr inline bool IsSharedSingleProducerCircularQueue = false;
template<typename T, size_t Size>
constexpr inline bool IsSharedSingleProducerCircularQueue<Core::SharedSingleProducerCircularQueue<T, Size>> = true;

template<typename T>
constexpr inline bool IsVariant = false;
template<typename... Ts>
constexpr inline bool IsVariant<Variant<Ts...>> = true;

template<typename T>
constexpr inline bool IsVector = false;
template<typename T>
constexpr inline bool IsVector<Vector<T>> = true;

}

template<typename T>
concept HashMap = Detail::IsHashMap<T>;

template<typename T>
concept Optional = Detail::IsOptional<T>;

template<typename T>
concept SharedSingleProducerCircularQueue = Detail::IsSharedSingleProducerCircularQueue<T>;

template<typename T>
concept Variant = Detail::IsVariant<T>;

template<typename T>
concept Vector = Detail::IsVector<T>;

}