-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtype.h
136 lines (98 loc) · 3.22 KB
/
type.h
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#pragma once
// type_eq //
template<typename lhs, typename rhs>
constexpr bool type_eq = false;
template<typename type>
constexpr bool type_eq<type, type> = true;
// is_ptr //
template<typename type>
constexpr bool is_ptr = false;
template<typename type>
constexpr bool is_ptr<type*> = true;
template<typename type>
constexpr bool is_ptr<type* const> = true;
// is_ref //
template<typename type>
constexpr bool is_ref = false;
template<typename type>
constexpr bool is_ref<type&> = true;
// is_by_copy //
template<typename type>
constexpr bool is_by_copy = !is_ptr<type> && !is_ref<type>;
// is_const //
template<typename type>
constexpr bool is_const = false;
template<typename type>
constexpr bool is_const<type const> = true;
// is_instantiation //
template<template<typename> typename temp, typename type>
constexpr bool is_instantiation = false;
template<template<typename> typename temp, typename type>
constexpr bool is_instantiation<temp, temp<type>> = true;
// remove_ref //
namespace {
template<typename t>
struct remove_ref_struct { using type = t; };
template<typename t>
struct remove_ref_struct<t&> { using type = t; };
}
template<typename t>
using remove_ref = typename remove_ref_struct<t>::type;
// remove_ptr //
namespace {
template<typename t>
struct remove_ptr_struct { using type = t; };
template<typename t>
struct remove_ptr_struct<t*> { using type = t; };
}
template<typename t>
using remove_ptr = typename remove_ptr_struct<t>::type;
// remove_const //
namespace {
template<typename t>
struct remove_const_struct { using type = t; };
template<typename t>
struct remove_const_struct<t const> { using type = t; };
template<typename t>
struct remove_const_struct<t* const> { using type = t; };
template<typename t>
struct remove_const_struct<t const* const> { using type = t; };
}
template<typename t>
using remove_const = typename remove_const_struct<t>::type;
// remove_const_from_ptr //
template<typename t>
using remove_const_from_ptr = remove_const<remove_ptr<t>>*;
// remove_const_from_ref //
template<typename t>
using remove_const_from_ref = remove_const<remove_ref<t>>&;
// branch //
namespace {
template<bool b, typename t, typename f>
struct branch_struct;
template<typename t, typename f>
struct branch_struct<true, t, f> { using type = t; };
template<typename t, typename f>
struct branch_struct<false, t, f> { using type = f; };
}
template<bool b, typename t, typename f>
using branch = typename branch_struct<b, t, f>::type;
// concepts //
template<typename type>
concept by_copy = is_by_copy<type>;
template<typename type>
concept non_const_by_copy = is_by_copy<type> && !is_const<type>;
template<typename type>
concept const_by_copy = is_by_copy<type> && is_const<type>;
template<typename type>
concept ptr = is_ptr<type>;
template<typename type>
concept non_const_ptr = is_ptr<type> && !is_const<remove_ptr<type>>;
template<typename type>
concept const_ptr = is_ptr<type> && is_const<remove_ptr<type>>;
template<typename type>
concept ref = is_ref<type>;
template<typename type>
concept non_const_ref = is_ref<type> && !is_const<remove_ref<type>>;
template<typename type>
concept const_ref = is_ref<type> && is_const<remove_ref<type>>;