15 #ifndef GRPC_CORE_LIB_GPRPP_TABLE_H
16 #define GRPC_CORE_LIB_GPRPP_TABLE_H
22 #include <initializer_list>
24 #include <type_traits>
27 #include "absl/meta/type_traits.h"
28 #include "absl/utility/utility.h"
35 namespace table_detail {
38 template <
typename... Ts>
41 template <
typename T,
typename... Ts>
56 template <
size_t I,
typename... Ts>
59 template <
typename T,
typename... Ts>
65 template <
size_t I,
typename T,
typename... Ts>
79 template <
typename Needle,
typename... Haystack>
82 template <
typename Needle,
typename Straw,
typename... RestOfHaystack>
84 static constexpr
size_t N =
88 template <
typename Needle>
90 static constexpr
size_t N = 0;
93 template <
typename Needle,
typename... Haystack>
101 template <
typename Ignored,
typename Needle,
typename... Haystack>
104 template <
typename Needle,
typename Straw,
typename... RestOfHaystack>
106 Needle, Straw, RestOfHaystack...> {
108 static constexpr
size_t N = 0;
110 template <
typename Needle,
typename Straw,
typename... RestOfHaystack>
112 Needle, Straw, RestOfHaystack...> {
115 static constexpr
size_t N =
124 template <
typename Needle,
typename... Haystack>
133 template <
size_t I,
typename... Ts>
136 template <
typename T,
typename... Ts>
140 template <
size_t I,
typename T,
typename... Ts>
143 template <
size_t I,
typename... Ts>
147 template <
typename T>
162 template <
typename T>
170 template <
typename... Ts>
201 std::forward<Table>(rhs));
209 std::forward<Table>(rhs));
215 template <
typename T>
217 return has<index_of<T>()>();
228 template <
typename T>
230 return get<index_of<T>()>();
235 template <
typename T>
236 const T*
get()
const {
237 return get<index_of<T>()>();
242 TypeIndex<I>*
get() {
243 if (has<I>())
return element_ptr<I>();
249 const TypeIndex<I>*
get()
const {
250 if (has<I>())
return element_ptr<I>();
255 template <
typename T>
257 return get_or_create<index_of<T>()>();
262 TypeIndex<I>* get_or_create() {
263 auto*
p = element_ptr<I>();
264 if (!set_present<I>(
true)) {
265 new (
p) TypeIndex<I>();
267 return element_ptr<I>();
271 template <
typename T,
typename...
Args>
273 return set<index_of<T>()>(std::forward<Args>(
args)...);
277 template <
size_t I,
typename...
Args>
279 auto*
p = element_ptr<I>();
280 if (set_present<I>(
true)) {
281 TypeIndex<I> replacement(std::forward<Args>(
args)...);
284 new (
p) TypeIndex<I>(std::forward<Args>(
args)...);
290 TypeIndex<I>*
set(TypeIndex<I>&&
value) {
291 auto*
p = element_ptr<I>();
292 if (set_present<I>(
true)) {
293 *
p = std::forward<TypeIndex<I>>(
value);
301 template <
typename T>
303 clear<index_of<T>()>();
309 if (set_present<I>(
false)) {
310 using T = TypeIndex<I>;
311 element_ptr<I>()->~T();
316 template <
typename F>
341 template <
typename T>
373 template <
bool or_clear,
size_t I>
375 if (
auto* p = rhs.get<
I>()) {
377 }
else if (or_clear) {
385 template <
bool or_clear,
size_t I>
387 if (
auto* p = rhs.get<
I>()) {
389 }
else if (or_clear) {
395 template <
size_t I,
typename F>
397 if (
auto* p = get<I>()) {
404 template <
size_t...
I>
406 table_detail::do_these_things<int>(
412 template <
bool or_clear,
size_t...
I>
414 table_detail::do_these_things<int>({(CopyIf<or_clear, I>(rhs), 1)...});
419 template <
bool or_clear,
size_t...
I>
421 table_detail::do_these_things<int>(
422 {(MoveIf<or_clear, I>(std::forward<Table>(rhs)), 1)...});
426 template <
typename F,
size_t...
I>
428 table_detail::do_these_things<int>({(CallIf<I>(&f), 1)...});
431 template <
size_t...
I>
433 table_detail::do_these_things<int>({(clear<I>(), 1)...});
444 #endif // GRPC_CORE_LIB_GPRPP_TABLE_H