-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathVariadicTemplate.mpp
More file actions
57 lines (45 loc) · 1.87 KB
/
VariadicTemplate.mpp
File metadata and controls
57 lines (45 loc) · 1.87 KB
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
export module CppUtils.Type.VariadicTemplate;
import std;
import CppUtils.Type.Concept;
export namespace CppUtils::Type
{
template<std::size_t I, class... Types>
requires (I < sizeof...(Types))
using NthType = Types...[I];
template<class... Types>
using FirstType = NthType<0, Types...>;
template<class T, class... Types>
requires IsOneOf<T, Types...>
consteval auto getPosition() -> std::size_t
{
auto i = 0uz;
static_cast<void>(((++i, std::same_as<T, Types>) or ...));
return --i;
}
template<class T, class... Types>
struct Unique: std::type_identity<T>
{};
template<template<class...> class Container, class... Types, class Candidate, class... NextCandidates>
struct Unique<Container<Types...>, Candidate, NextCandidates...>:
std::conditional_t<(std::is_same_v<Candidate, Types> or ...),
Unique<Container<Types...>, NextCandidates...>,
Unique<Container<Types..., Candidate>, NextCandidates...>>
{};
template<template<class...> class Container, class... Types>
using UniqueType = typename Unique<Container<>, Types...>::type;
template<class... Types>
using UniqueVariant = UniqueType<std::variant, std::decay_t<Types>...>;
template<class... Types>
using UniqueTuple = UniqueType<std::tuple, Types...>;
template<template<class> class Trait, class T, class... Types>
struct Filter: std::type_identity<T>
{};
template<template<class> class Trait, template<class...> class Container, class... Types, class Candidate, class... NextCandidates>
struct Filter<Trait, Container<Types...>, Candidate, NextCandidates...>:
std::conditional_t<Trait<Candidate>::value,
Filter<Trait, Container<Types..., Candidate>, NextCandidates...>,
Filter<Trait, Container<Types...>, NextCandidates...>>
{};
template<template<class> class Trait, template<class...> class Container, class... Types>
using FilterType = typename Filter<Trait, Container<>, Types...>::type;
}