proxygen
Combine-inl.h
Go to the documentation of this file.
1 /*
2  * Copyright 2014-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 #ifndef FOLLY_GEN_COMBINE_H_
18 #error This file may only be included from folly/gen/Combine.h
19 #endif
20 
21 #include <iterator>
22 #include <system_error>
23 #include <tuple>
24 #include <type_traits>
25 
26 namespace folly {
27 namespace gen {
28 namespace detail {
29 
36 template <class Container>
37 class Interleave : public Operator<Interleave<Container>> {
38  // see comment about copies in CopiedSource
39  const std::shared_ptr<const Container> container_;
40 
41  public:
42  explicit Interleave(Container container)
43  : container_(new Container(std::move(container))) {}
44 
45  template <class Value, class Source>
46  class Generator : public GenImpl<Value, Generator<Value, Source>> {
47  Source source_;
48  const std::shared_ptr<const Container> container_;
49  typedef const typename Container::value_type& ConstRefType;
50 
51  static_assert(
53  "Only matching types may be interleaved");
54 
55  public:
56  explicit Generator(
57  Source source,
58  const std::shared_ptr<const Container> container)
59  : source_(std::move(source)), container_(container) {}
60 
61  template <class Handler>
62  bool apply(Handler&& handler) const {
63  auto iter = container_->begin();
64  return source_.apply([&](const Value& value) -> bool {
65  if (iter == container_->end()) {
66  return false;
67  }
68  if (!handler(value)) {
69  return false;
70  }
71  if (!handler(*iter)) {
72  return false;
73  }
74  iter++;
75  return true;
76  });
77  }
78  };
79 
80  template <class Value2, class Source, class Gen = Generator<Value2, Source>>
81  Gen compose(GenImpl<Value2, Source>&& source) const {
82  return Gen(std::move(source.self()), container_);
83  }
84 
85  template <class Value2, class Source, class Gen = Generator<Value2, Source>>
86  Gen compose(const GenImpl<Value2, Source>& source) const {
87  return Gen(source.self(), container_);
88  }
89 };
90 
98 template <class Container>
99 class Zip : public Operator<Zip<Container>> {
100  // see comment about copies in CopiedSource
101  const std::shared_ptr<const Container> container_;
102 
103  public:
104  explicit Zip(Container container)
105  : container_(new Container(std::move(container))) {}
106 
107  template <
108  class Value1,
109  class Source,
110  class Value2 = decltype(*std::begin(*container_)),
111  class Result = std::tuple<
112  typename std::decay<Value1>::type,
113  typename std::decay<Value2>::type>>
114  class Generator
115  : public GenImpl<Result, Generator<Value1, Source, Value2, Result>> {
116  Source source_;
117  const std::shared_ptr<const Container> container_;
118 
119  public:
120  explicit Generator(
121  Source source,
122  const std::shared_ptr<const Container> container)
123  : source_(std::move(source)), container_(container) {}
124 
125  template <class Handler>
126  bool apply(Handler&& handler) const {
127  auto iter = container_->begin();
128  return (source_.apply([&](Value1 value) -> bool {
129  if (iter == container_->end()) {
130  return false;
131  }
132  if (!handler(std::make_tuple(std::forward<Value1>(value), *iter))) {
133  return false;
134  }
135  ++iter;
136  return true;
137  }));
138  }
139  };
140 
141  template <class Source, class Value, class Gen = Generator<Value, Source>>
142  Gen compose(GenImpl<Value, Source>&& source) const {
143  return Gen(std::move(source.self()), container_);
144  }
145 
146  template <class Source, class Value, class Gen = Generator<Value, Source>>
147  Gen compose(const GenImpl<Value, Source>& source) const {
148  return Gen(source.self(), container_);
149  }
150 };
151 
152 template <class... Types1, class... Types2>
153 auto add_to_tuple(std::tuple<Types1...> t1, std::tuple<Types2...> t2)
154  -> std::tuple<Types1..., Types2...> {
155  return std::tuple_cat(std::move(t1), std::move(t2));
156 }
157 
158 template <class... Types1, class Type2>
159 auto add_to_tuple(std::tuple<Types1...> t1, Type2&& t2) -> decltype(
160  std::tuple_cat(std::move(t1), std::make_tuple(std::forward<Type2>(t2)))) {
161  return std::tuple_cat(
162  std::move(t1), std::make_tuple(std::forward<Type2>(t2)));
163 }
164 
165 template <class Type1, class... Types2>
166 auto add_to_tuple(Type1&& t1, std::tuple<Types2...> t2) -> decltype(
167  std::tuple_cat(std::make_tuple(std::forward<Type1>(t1)), std::move(t2))) {
168  return std::tuple_cat(
169  std::make_tuple(std::forward<Type1>(t1)), std::move(t2));
170 }
171 
172 template <class Type1, class Type2>
173 auto add_to_tuple(Type1&& t1, Type2&& t2) -> decltype(
174  std::make_tuple(std::forward<Type1>(t1), std::forward<Type2>(t2))) {
175  return std::make_tuple(std::forward<Type1>(t1), std::forward<Type2>(t2));
176 }
177 
178 // Merges a 2-tuple into a single tuple (get<0> could already be a tuple)
179 class MergeTuples {
180  public:
181  template <class Tuple>
182  auto operator()(Tuple&& value) const -> decltype(add_to_tuple(
183  std::get<0>(std::forward<Tuple>(value)),
184  std::get<1>(std::forward<Tuple>(value)))) {
185  static_assert(
186  std::tuple_size<typename std::remove_reference<Tuple>::type>::value ==
187  2,
188  "Can only merge tuples of size 2");
189  return add_to_tuple(
190  std::get<0>(std::forward<Tuple>(value)),
191  std::get<1>(std::forward<Tuple>(value)));
192  }
193 };
194 
195 } // namespace detail
196 
197 // TODO(mcurtiss): support zip() for N>1 operands. Because of variadic problems,
198 // this might not be easily possible until gcc4.8 is available.
199 template <
200  class Source,
202 Zip zip(Source&& source) {
203  return Zip(std::forward<Source>(source));
204 }
205 
206 } // namespace gen
207 } // namespace folly
const std::shared_ptr< const Container > container_
Definition: Combine-inl.h:101
Interleave(Container container)
Definition: Combine-inl.h:42
bool apply(Handler &&handler) const
Definition: Combine-inl.h:62
bool apply(Handler &&handler) const
Definition: Combine-inl.h:126
Zip zip(Source &&source)
Definition: Combine-inl.h:202
Gen compose(const GenImpl< Value, Source > &source) const
Definition: Combine-inl.h:147
PskType type
Get get()
Definition: Base.h:702
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
auto begin(TestAdlIterable &instance)
Definition: ForeachTest.cpp:56
auto add_to_tuple(std::tuple< Types1... > t1, std::tuple< Types2... > t2) -> std::tuple< Types1..., Types2... >
Definition: Combine-inl.h:153
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
tuple make_tuple()
Definition: gtest-tuple.h:675
Generator(Source source, const std::shared_ptr< const Container > container)
Definition: Combine-inl.h:56
void handler(int, siginfo_t *, void *)
Gen compose(const GenImpl< Value2, Source > &source) const
Definition: Combine-inl.h:86
const Container::value_type & ConstRefType
Definition: Combine-inl.h:49
Generator(Source source, const std::shared_ptr< const Container > container)
Definition: Combine-inl.h:120
bool Value(const T &value, M matcher)
auto operator()(Tuple &&value) const -> decltype(add_to_tuple(std::get< 0 >(std::forward< Tuple >(value)), std::get< 1 >(std::forward< Tuple >(value))))
Definition: Combine-inl.h:182
static const char *const value
Definition: Conv.cpp:50
Gen compose(GenImpl< Value2, Source > &&source) const
Definition: Combine-inl.h:81
if(FOLLY_USE_SYMBOLIZER) add_library(folly_exception_tracer_base ExceptionTracer.cpp StackTrace.cpp) apply_folly_compile_options_to_target(folly_exception_tracer_base) target_link_libraries(folly_exception_tracer_base PUBLIC folly) add_library(folly_exception_tracer ExceptionStackTraceLib.cpp ExceptionTracerLib.cpp) apply_folly_compile_options_to_target(folly_exception_tracer) target_link_libraries(folly_exception_tracer PUBLIC folly_exception_tracer_base) add_library(folly_exception_counter ExceptionCounterLib.cpp) apply_folly_compile_options_to_target(folly_exception_counter) target_link_libraries(folly_exception_counter PUBLIC folly_exception_tracer) install(FILES ExceptionAbi.h ExceptionCounterLib.h ExceptionTracer.h ExceptionTracerLib.h StackTrace.h DESTINATION $
Definition: CMakeLists.txt:1
const std::shared_ptr< const Container > container_
Definition: Combine-inl.h:48
const std::shared_ptr< const Container > container_
Definition: Combine-inl.h:39
const Self & self() const
Definition: Core-inl.h:71
const
Definition: upload.py:398
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
const std::shared_ptr< const Container > container_
Definition: Combine-inl.h:117
Zip(Container container)
Definition: Combine-inl.h:104
Gen compose(GenImpl< Value, Source > &&source) const
Definition: Combine-inl.h:142