proxygen
TupleOps.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015-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 <limits>
20 #include <tuple>
21 #include <type_traits>
22 
23 // tupleRange<start, n>(tuple): select n elements starting at index start
24 // in the given tuple
25 // tupleRange<start>(tuple): select all elements starting at index start
26 // until the end of the given tuple
27 // tuplePrepend(x, tuple): return a tuple obtained by prepending x to the
28 // given tuple.
29 //
30 // In Lisp lingo, std::get<0> is car, tupleRange<1> is cdr, and tuplePrepend
31 // is cons.
32 
33 namespace folly {
34 
35 // TemplateSeq<T, ...> is a type parametrized by sizeof...(Xs) values of type
36 // T. Used to destructure the values into a template parameter pack;
37 // see the example in TupleSelect, below.
38 template <class T, T... xs>
39 struct TemplateSeq {
40  template <T x>
41  using Prepend = TemplateSeq<T, x, xs...>;
42 };
43 
44 // TemplateRange<T, start, n>::type is
45 // TemplateSeq<T, start+1, start+2, ..., start+n-1>
46 template <class T, T start, T n, class Enable = void>
48 
49 template <class T, T start, T n>
50 struct TemplateRange<T, start, n, typename std::enable_if<(n > 0)>::type> {
51  using type =
52  typename TemplateRange<T, start + 1, n - 1>::type::template Prepend<
53  start>;
54 };
55 
56 template <class T, T start, T n>
57 struct TemplateRange<T, start, n, typename std::enable_if<(n <= 0)>::type> {
59 };
60 
61 // Similar to TemplateRange, given a tuple T,
62 // TemplateTupleRange<T, start, n>::type is
63 // TemplateSeq<size_t, start, start+1, ..., start+k-1>
64 // where k = min(tuple_size<T>::value - start, n)
65 // (that is, it's a TemplateSeq of at most n elements, but won't extend
66 // past the end of the given tuple)
67 template <
68  class T,
69  std::size_t start = 0,
70  std::size_t n = std::numeric_limits<std::size_t>::max(),
71  std::size_t size =
73  class Enable = typename std::enable_if<(start <= size)>::type>
75  using type = typename TemplateRange<
76  std::size_t,
77  start,
78  (n <= size - start ? n : size - start)>::type;
79 };
80 
81 namespace detail {
82 
83 // Helper class to select a subset of a tuple
84 template <class S>
85 struct TupleSelect;
86 template <std::size_t... Ns>
87 struct TupleSelect<TemplateSeq<std::size_t, Ns...>> {
88  template <class T>
89  static auto select(T&& v)
90  -> decltype(std::make_tuple(std::get<Ns>(std::forward<T>(v))...)) {
91  return std::make_tuple(std::get<Ns>(std::forward<T>(v))...);
92  }
93 };
94 
95 } // namespace detail
96 
97 // Return a tuple consisting of the elements at a range of indices.
98 //
99 // Use as tupleRange<start, n>(t) to return a tuple of (at most) n
100 // elements starting at index start in tuple t.
101 // If only start is specified (tupleRange<start>(t)), returns all elements
102 // starting at index start until the end of the tuple t.
103 // Won't compile if start > size of t.
104 // Will return fewer elements (size - start) if start + n > size of t.
105 template <
106  std::size_t start = 0,
107  std::size_t n = std::numeric_limits<std::size_t>::max(),
108  class T,
109  class Seq = typename TemplateTupleRange<T, start, n>::type>
110 auto tupleRange(T&& v)
111  -> decltype(detail::TupleSelect<Seq>::select(std::forward<T>(v))) {
112  return detail::TupleSelect<Seq>::select(std::forward<T>(v));
113 }
114 
115 // Return a tuple obtained by prepending car to the tuple cdr.
116 template <class T, class U>
117 auto tuplePrepend(T&& car, U&& cdr) -> decltype(std::tuple_cat(
118  std::make_tuple(std::forward<T>(car)),
119  std::forward<U>(cdr))) {
120  return std::tuple_cat(
121  std::make_tuple(std::forward<T>(car)), std::forward<U>(cdr));
122 }
123 
124 } // namespace folly
auto tupleRange(T &&v) -> decltype(detail::TupleSelect< Seq >::select(std::forward< T >(v)))
Definition: TupleOps.h:110
LogLevel max
Definition: LogLevel.cpp:31
PskType type
const int x
STL namespace.
static auto select(T &&v) -> decltype(std::make_tuple(std::get< Ns >(std::forward< T >(v))...))
Definition: TupleOps.h:89
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
tuple make_tuple()
Definition: gtest-tuple.h:675
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
auto start
auto tuplePrepend(T &&car, U &&cdr) -> decltype(std::tuple_cat(std::make_tuple(std::forward< T >(car)), std::forward< U >(cdr)))
Definition: TupleOps.h:117
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
typename TemplateRange< std::size_t, start,(n<=size-start?n:size-start)>::type type
Definition: TupleOps.h:78
typename TemplateRange< T, start+1, n-1 >::type::template Prepend< start > type
Definition: TupleOps.h:53
TemplateSeq< T, x, xs... > Prepend
Definition: TupleOps.h:41