forked from cel-expr/cel-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtypes.h
More file actions
156 lines (128 loc) · 4.85 KB
/
Copy pathtypes.h
File metadata and controls
156 lines (128 loc) · 4.85 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
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Helpers to work with sets of types.
#ifndef THIRD_PARTY_CEL_CPP_INTERNAL_TYPE_UTIL_H_
#define THIRD_PARTY_CEL_CPP_INTERNAL_TYPE_UTIL_H_
#include <tuple>
#include <type_traits>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "internal/port.h"
#include "internal/specialize.h"
namespace google {
namespace api {
namespace expr {
namespace internal {
// Short names for AND, OR and NOT.
template <typename... T>
using and_t = conjunction<T...>;
template <typename... T>
using or_t = disjunction<T...>;
template <typename T>
using not_t = negation<T>;
// Holder for a static list of types.
template <typename... Args>
using types = std::tuple<Args...>;
// Helper that defines 'value' to be the number of types in T.
template <typename T>
using types_size = std::tuple_size<T>;
template <typename... T>
using types_cat = decltype(std::tuple_cat(inst_of<decay_t<T>>()...));
// Helper that resolves to the Ith type in T.
template <std::size_t I, typename T>
using type_at = typename std::tuple_element<I, T>::type;
// Helper that defines 'value' to be true if there are no types in T.
template <typename T>
using types_empty = std::integral_constant<bool, types_size<T>::value == 0>;
// Helper that returns the index of the first occurrence of E in T.
template <typename E, typename T, std::size_t I = 0>
struct type_index {
static constexpr std::size_t value = -1;
};
template <typename E, std::size_t I, class... Types>
struct type_index<E, types<E, Types...>, I> {
static constexpr std::size_t value = I;
};
template <class E, class U, std::size_t I, class... Types>
struct type_index<E, std::tuple<U, Types...>, I>
: type_index<E, types<Types...>, I + 1> {};
// Helper that defines 'value' to be true if E occurs in T.
template <typename E, typename T>
using type_in = std::integral_constant<bool, type_index<E, T>::value !=
static_cast<std::size_t>(-1)>;
// A 'type map' lookup of `Key` in a map from Keys -> Values.
template <typename Key, typename Keys, typename Values>
using get_type = type_at<type_index<Key, Keys>::value, Values>;
// Helper definitions for packed types.
template <typename... Args>
using args_size = types_size<types<Args...>>;
template <typename... Args>
using args_empty = types_empty<types<Args...>>;
template <typename E, typename... Args>
using arg_in = type_in<E, types<Args...>>;
template <typename T, typename S>
using type_is = std::is_same<T, S>;
template <typename T, typename S>
using type_not = negation<type_is<T, S>>;
/**
* Tests if a type is a raw or smart pointer.
*
* Any type that defines overloads for * and -> is considered a smart pointer.
*/
template <typename T, typename = specialize>
struct is_ptr : std::is_pointer<decay_t<T>> {};
template <typename T>
struct is_ptr<T, specialize_for<decltype(&decay_t<T>::operator*),
decltype(&decay_t<T>::operator->)>>
: std::true_type {};
/**
* Tests if a type is convertible to absl::string_view.
*/
template <typename T>
using is_string = and_t<type_not<remove_cvref_t<T>, std::nullptr_t>,
std::is_convertible<T, absl::string_view>>;
/**
* Tests if a type is a signed integer type.
*/
template <typename T>
using is_int = conjunction<std::is_integral<remove_cvref_t<T>>,
std::is_signed<decay_t<T>>>;
/**
* Tests if a type is an unsigned integer type.
*/
template <typename T>
using is_uint =
conjunction<type_not<remove_cvref_t<T>, bool>, std::is_integral<decay_t<T>>,
std::is_unsigned<decay_t<T>>>;
/**
* Tests if a type is a floating point type.
*/
template <typename T>
using is_float = std::is_floating_point<decay_t<T>>;
template <typename T>
using is_numeric = or_t<is_int<T>, is_uint<T>, is_float<T>>;
// Containers define a "value_type" and "iterator".
// Note: The full spec can be found at
// https://en.cppreference.com/w/cpp/named_req/Container
template <typename T, typename = specialize>
struct is_container : public std::false_type {};
template <typename T>
struct is_container<T, specialize_for<typename remove_cvref_t<T>::value_type,
typename remove_cvref_t<T>::iterator>>
: public std::true_type {};
// Maps are containers that also define a "mapped_type".
template <typename T, typename = specialize>
struct is_map : public std::false_type {};
template <typename T>
struct is_map<T, specialize_for<typename remove_cvref_t<T>::mapped_type>>
: public is_container<T> {};
// Lists are containers that are not maps.
template <typename T>
using is_list = bool_constant<is_container<T>::value && !is_map<T>::value>;
// Used to create a compiler error when a specialized function/class is
// instantiated with an unsupported type.
template <typename... Args>
struct UnsupportedType;
} // namespace internal
} // namespace expr
} // namespace api
} // namespace google
#endif