proxygen
TypeList.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cstddef>
20 #include <utility>
21 
22 #include <folly/Traits.h>
23 #include <folly/Utility.h>
24 
74 namespace folly {
75 namespace detail {
76 
80 template <bool B>
84 
89 template <class Fn, class... Ts>
90 using MetaApply = typename Fn::template apply<Ts...>;
91 
95 template <class... Ts>
96 struct TypeList {
100  using type = TypeList;
101 
105  static constexpr std::size_t size() noexcept {
106  return sizeof...(Ts);
107  }
108 
113  template <class Fn>
114  using apply = MetaApply<Fn, Ts...>;
115 };
116 
120 template <class T>
121 struct Type {
125  using type = T;
126 
131  template <class...>
132  using apply = T;
133 };
134 
138 struct Empty {};
139 
141 namespace impl {
142 template <bool B>
143 struct If_ {
144  template <class T, class U>
145  using apply = T;
146 };
147 template <>
148 struct If_<false> {
149  template <class T, class U>
150  using apply = U;
151 };
152 } // namespace impl
154 
158 template <bool If_, class Then, class Else>
159 using If = MetaApply<impl::If_<If_>, Then, Else>;
160 
169 template <template <class...> class C, class... Ts>
170 class MetaDefer {
171  template <template <class...> class D = C, class = D<Ts...>>
172  static char (&try_(int))[1];
173  static char (&try_(long))[2];
174  struct Result {
175  using type = C<Ts...>;
176  };
177 
178  public:
179  template <class... Us>
180  using apply = _t<If<sizeof(try_(0)) - 1 || sizeof...(Us), Empty, Result>>;
181 };
182 
189 template <class P, class Q>
190 struct MetaCompose {
191  template <class... Ts>
192  using apply = MetaApply<P, MetaApply<Q, Ts...>>;
193 };
194 
200 struct MetaIdentity {
201  template <class T>
202  using apply = T;
203 };
204 
210 template <template <class...> class C>
211 struct MetaQuote {
212  template <class... Ts>
213  using apply = MetaApply<MetaDefer<C, Ts...>>;
214 };
215 
217 // Specialization for TypeList since it doesn't need to go through MetaDefer
218 template <>
219 struct MetaQuote<TypeList> {
220  template <class... Ts>
221  using apply = TypeList<Ts...>;
222 };
224 
231 template <template <class...> class C>
233 
241 template <class Fn, class... Ts>
243  template <class... Us>
244  using apply = MetaApply<Fn, Ts..., Us...>;
245 };
246 
254 template <class Fn, class... Ts>
255 struct MetaBindBack {
256  template <class... Us>
257  using apply = MetaApply<Fn, Us..., Ts...>;
258 };
259 
268 template <class Fn>
270 
279 template <class Fn>
281 
289 template <class List, class... Ts>
291 
299 template <class List, class... Ts>
300 using TypePushFront =
302 
307 template <class Fn, class List>
309 
311 namespace impl {
312 template <class Fn>
313 struct TypeTransform_ {
314  template <class... Ts>
315  using apply = TypeList<MetaApply<Fn, Ts>...>;
316 };
317 } // namespace impl
319 
326 template <class List, class Fn>
328 
333 template <class Fn>
334 struct MetaFlip {
335  template <class A, class B>
337 };
338 
340 namespace impl {
341 template <class Fn>
342 struct FoldR_ {
343  template <class... Ts>
344  struct Lambda : MetaIdentity {};
345  template <class A, class... Ts>
346  struct Lambda<A, Ts...> {
347  template <class State>
348  using apply = MetaApply<Fn, A, MetaApply<Lambda<Ts...>, State>>;
349  };
350  template <class A, class B, class C, class D, class... Ts>
351  struct Lambda<A, B, C, D, Ts...> { // manually unroll 4 elements
352  template <class State>
353  using apply = MetaApply<
354  Fn,
355  A,
356  MetaApply<
357  Fn,
358  B,
359  MetaApply<
360  Fn,
361  C,
362  MetaApply<Fn, D, MetaApply<Lambda<Ts...>, State>>>>>;
363  };
364  template <class... Ts>
365  using apply = Lambda<Ts...>;
366 };
367 } // namespace impl
369 
379 template <class List, class State, class Fn>
381 
383 namespace impl {
384 template <class Fn>
385 struct FoldL_ {
386  template <class... Ts>
387  struct Lambda : MetaIdentity {};
388  template <class A, class... Ts>
389  struct Lambda<A, Ts...> {
390  template <class State>
391  using apply = MetaApply<Lambda<Ts...>, MetaApply<Fn, State, A>>;
392  };
393  template <class A, class B, class C, class D, class... Ts>
394  struct Lambda<A, B, C, D, Ts...> { // manually unroll 4 elements
395  template <class State>
396  using apply = MetaApply<
397  Lambda<Ts...>,
398  MetaApply<
399  Fn,
401  D>>;
402  };
403  template <class... Ts>
404  using apply = Lambda<Ts...>;
405 };
406 } // namespace impl
408 
418 template <class List, class State, class Fn>
420 
421 namespace impl {
422 template <class List>
423 struct Inherit_;
424 template <class... Ts>
425 struct Inherit_<TypeList<Ts...>> : Ts... {
426  using type = Inherit_;
427 };
428 } // namespace impl
429 
437 template <class List>
439 
441 namespace impl {
442 // Avoid instantiating std::is_base_of when we have an intrinsic.
443 #if defined(__GNUC__) || defined(_MSC_VER)
444 template <class T, class... Set>
446 #else
447 template <class T, class... Set>
448 using In_ = std::is_base_of<Type<T>, Inherit<TypeList<Type<Set>...>>>;
449 #endif
450 
451 template <class T>
452 struct InsertFront_ {
453  template <class... Set>
454  using apply =
455  If<In_<T, Set...>::value, TypeList<Set...>, TypeList<T, Set...>>;
456 };
457 
458 struct Unique_ {
459  template <class T, class List>
461 };
462 } // namespace impl
464 
474 template <class List>
475 using TypeUnique = TypeFold<List, TypeList<>, impl::Unique_>;
476 
486 template <class List>
487 using TypeReverseUnique =
489 
491 namespace impl {
492 template <class T>
493 struct AsTypeList_ {};
494 template <template <class...> class T, class... Ts>
495 struct AsTypeList_<T<Ts...>> {
496  using type = TypeList<Ts...>;
497 };
498 template <class T, T... Is>
499 struct AsTypeList_<folly::integer_sequence<T, Is...>> {
501 };
502 } // namespace impl
504 
513 template <class T>
515 
517 namespace impl {
518 // TODO For a list of N lists, this algorithm is O(N). It does no unrolling.
519 struct Join_ {
520  template <class Fn>
521  struct Lambda {
522  template <class... Ts>
523  using apply = MetaBindBack<Fn, Ts...>;
524  };
525  template <class List, class Fn>
527 };
528 } // namespace impl
530 
537 template <class List>
539 
548 template <class... Ts>
549 using TypeConcat = TypeJoin<TypeList<Ts...>>;
550 } // namespace detail
551 } // namespace folly
std::true_type True
Definition: TypeList.h:82
std::unique_ptr< int > A
MetaApply< Fn, Us..., Ts... > apply
Definition: TypeList.h:257
MetaApply< MetaDefer< C, Ts... >> apply
Definition: TypeList.h:213
MetaApply< Fn, B, A > apply
Definition: TypeList.h:336
MetaApply< P, MetaApply< Q, Ts... >> apply
Definition: TypeList.h:192
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
MetaApply< MetaApply< List, impl::FoldR_< Fn >>, State > TypeFold
Definition: TypeList.h:380
bool_constant< true > true_type
Definition: gtest-port.h:2210
TypeJoin< TypeList< Ts... >> TypeConcat
Definition: TypeList.h:549
std::false_type False
Definition: TypeList.h:83
_t< If< sizeof(try_(0))-1||sizeof...(Us), Empty, Result >> apply
Definition: TypeList.h:180
MetaApply< List, MetaBindBack< MetaQuote< TypeList >, Ts... >> TypePushBack
Definition: TypeList.h:290
MetaApply< impl::If_< If_ >, Then, Else > If
Definition: TypeList.h:159
State
See Core for details.
Definition: Core.h:43
MetaApply< List, MetaBindFront< MetaQuote< TypeList >, Ts... >> TypePushFront
Definition: TypeList.h:301
std::integral_constant< bool, B > bool_constant
Definition: Traits.h:145
#define D(name, bit)
Definition: CpuId.h:145
typename T::type _t
Definition: Traits.h:171
MetaApply< List, Fn > MetaUnpack
Definition: TypeList.h:308
MetaApply< Fn, Ts..., Us... > apply
Definition: TypeList.h:244
MetaApply< List, impl::TypeTransform_< Fn >> TypeTransform
Definition: TypeList.h:327
typename Fn::template apply< Ts... > MetaApply
Definition: TypeList.h:90
MetaApply< MetaApply< List, impl::FoldL_< Fn >>, State > TypeReverseFold
Definition: TypeList.h:419
#define C(name, bit)
Definition: CpuId.h:204
static constexpr std::size_t size() noexcept
Definition: TypeList.h:105
TypeReverseFold< List, TypeList<>, MetaFlip< impl::Unique_ >> TypeReverseUnique
Definition: TypeList.h:488
MetaApply< Fn, Ts... > apply
Definition: TypeList.h:114
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
bool_constant< false > false_type
Definition: gtest-port.h:2209
TypeFold< List, TypeList<>, impl::Unique_ > TypeUnique
Definition: TypeList.h:475
MetaApply< TypeFold< List, MetaQuote< TypeList >, impl::Join_ >> TypeJoin
Definition: TypeList.h:538
decltype(auto) constexpr apply(F &&func, Tuple &&tuple)
Definition: ApplyTuple.h:87
_t< impl::AsTypeList_< T >> AsTypeList
Definition: TypeList.h:514
#define B(name, bit)
Definition: CpuId.h:178