proxygen
folly::for_each_detail Namespace Reference

Namespaces

 adl
 

Classes

struct  BeginAddTag
 
struct  IndexingTag
 
struct  IsMemberGetFound
 
struct  IsMemberGetFound< EnableIfMemberGetFound< T >, T >
 
struct  IsRange
 
struct  IsRange< EnableIfRange< T >, T >
 
struct  IsTuple
 
struct  IsTuple< EnableIfTuple< T >, T >
 
struct  RangeTag
 
struct  TupleTag
 

Typedefs

template<typename T >
using EnableIfMemberGetFound = void_t< decltype(std::declval< T >().template get< 0 >())>
 
template<typename Type , typename T = typename std::decay<Type>::type>
using EnableIfTuple = void_t< decltype(get_impl< 0 >(std::declval< T >())), decltype(std::tuple_size< T >::value)>
 
template<typename Type , typename T = typename std::decay<Type>::type>
using EnableIfRange = void_t< decltype(adl::adl_begin(std::declval< T >())), decltype(adl::adl_end(std::declval< T >()))>
 
template<typename Sequence >
using SequenceTag = std::conditional_t< IsRange< void, Sequence >::value, RangeTag, TupleTag >
 
template<typename Func , typename Item , typename Iter >
using ForEachImplTag = std::conditional_t< is_invocable< Func, Item, index_constant< 0 >, Iter >::value, index_constant< 3 >, std::conditional_t< is_invocable< Func, Item, index_constant< 0 >>::value, index_constant< 2 >, std::conditional_t< is_invocable< Func, Item >::value, index_constant< 1 >, void >>>
 

Enumerations

enum  LoopControl : bool { LoopControl::BREAK, LoopControl::CONTINUE }
 

Functions

template<std::size_t Index, typename Type , std::enable_if_t<!IsMemberGetFound< void, Type >::value, int > = 0>
auto get_impl (Type &&instance) -> decltype(adl::adl_get< Index >(static_cast< Type && >(instance)))
 
template<typename Func , typename... Args, std::enable_if_t< is_invocable_r< LoopControl, Func, Args... >::value, int > = 0>
LoopControl invoke_returning_loop_control (Func &&f, Args &&...a)
 
template<typename Sequence , typename Func >
void for_each_range_impl (index_constant< 3 >, Sequence &&range, Func &func)
 
template<typename Sequence , typename Func >
void for_each_range_impl (index_constant< 2 >, Sequence &&range, Func &func)
 
template<typename Sequence , typename Func >
void for_each_range_impl (index_constant< 1 >, Sequence &&range, Func &func)
 
template<typename Sequence , typename Func , std::size_t... Indices>
void for_each_tuple_impl (index_sequence< Indices... >, Sequence &&seq, Func &func)
 
template<typename Sequence , typename Func >
void for_each_tuple_impl (index_constant< 2 >, Sequence &&seq, Func &func)
 
template<typename Sequence , typename Func >
void for_each_tuple_impl (index_constant< 1 >, Sequence &&seq, Func &func)
 
template<typename Sequence , typename Func >
static void for_each_impl (TupleTag, Sequence &&range, Func &func)
 
template<typename Sequence , typename Func >
static void for_each_impl (RangeTag, Sequence &&range, Func &func)
 
template<typename Sequence , typename Index >
decltype(auto) fetch_impl (IndexingTag, Sequence &&sequence, Index &&index)
 
template<typename Sequence , typename Index >
decltype(auto) fetch_impl (BeginAddTag, Sequence &&sequence, Index index)
 
template<typename Sequence , typename Index >
decltype(auto) fetch_impl (TupleTag, Sequence &&sequence, Index index)
 
template<typename Sequence , typename Index >
decltype(auto) fetch_impl (RangeTag, Sequence &&sequence, Index &&index)
 

Detailed Description

The user should return loop_break and loop_continue if they want to iterate in such a way that they can preemptively stop the loop and break out when certain conditions are met.

Typedef Documentation

template<typename T >
using folly::for_each_detail::EnableIfMemberGetFound = typedef void_t<decltype(std::declval<T>().template get<0>())>

Enable if the tuple supports fetching via a member get<>()

Definition at line 69 of file Foreach-inl.h.

template<typename Type , typename T = typename std::decay<Type>::type>
using folly::for_each_detail::EnableIfRange = typedef void_t< decltype(adl::adl_begin(std::declval<T>())), decltype(adl::adl_end(std::declval<T>()))>

Check if the sequence is a range

Definition at line 115 of file Foreach-inl.h.

template<typename Type , typename T = typename std::decay<Type>::type>
using folly::for_each_detail::EnableIfTuple = typedef void_t< decltype(get_impl<0>(std::declval<T>())), decltype(std::tuple_size<T>::value)>

Check if the sequence is a tuple

Definition at line 103 of file Foreach-inl.h.

template<typename Func , typename Item , typename Iter >
using folly::for_each_detail::ForEachImplTag = typedef std::conditional_t< is_invocable<Func, Item, index_constant<0>, Iter>::value, index_constant<3>, std::conditional_t< is_invocable<Func, Item, index_constant<0>>::value, index_constant<2>, std::conditional_t< is_invocable<Func, Item>::value, index_constant<1>, void>>>

Definition at line 144 of file Foreach-inl.h.

template<typename Sequence >
using folly::for_each_detail::SequenceTag = typedef std::conditional_t<IsRange<void, Sequence>::value, RangeTag, TupleTag>

Should ideally check if it is a tuple and if not return void, but msvc fails

Definition at line 129 of file Foreach-inl.h.

Enumeration Type Documentation

Enumerator
BREAK 
CONTINUE 

Definition at line 94 of file Foreach.h.

Function Documentation

template<typename Sequence , typename Index >
decltype(auto) folly::for_each_detail::fetch_impl ( IndexingTag  ,
Sequence &&  sequence,
Index &&  index 
)

Definition at line 286 of file Foreach-inl.h.

Referenced by folly::fetch(), and fetch_impl().

286  {
287  return std::forward<Sequence>(sequence)[std::forward<Index>(index)];
288 }
template<typename Sequence , typename Index >
decltype(auto) folly::for_each_detail::fetch_impl ( BeginAddTag  ,
Sequence &&  sequence,
Index  index 
)

Definition at line 290 of file Foreach-inl.h.

References folly::for_each_detail::adl::adl_begin().

290  {
291  return *(adl::adl_begin(std::forward<Sequence>(sequence)) + index);
292 }
auto adl_begin(Type &&instance) -> decltype(begin(instance))
Definition: Foreach-inl.h:54
template<typename Sequence , typename Index >
decltype(auto) folly::for_each_detail::fetch_impl ( TupleTag  ,
Sequence &&  sequence,
Index  index 
)

Definition at line 295 of file Foreach-inl.h.

295  {
296  return get_impl<index>(std::forward<Sequence>(sequence));
297 }
template<typename Sequence , typename Index >
decltype(auto) folly::for_each_detail::fetch_impl ( RangeTag  ,
Sequence &&  sequence,
Index &&  index 
)

Definition at line 299 of file Foreach-inl.h.

References folly::for_each_detail::adl::adl_begin(), fetch_impl(), and value.

299  {
300  using iter = decltype(adl::adl_begin(std::declval<Sequence>()));
301  using iter_traits = std::iterator_traits<remove_cvref_t<iter>>;
302  using iter_cat = typename iter_traits::iterator_category;
303  using tag = std::conditional_t<
305  BeginAddTag,
306  IndexingTag>;
307  return fetch_impl(
308  tag{}, std::forward<Sequence>(sequence), std::forward<Index>(index));
309 }
static const char *const value
Definition: Conv.cpp:50
auto adl_begin(Type &&instance) -> decltype(begin(instance))
Definition: Foreach-inl.h:54
decltype(auto) fetch_impl(RangeTag, Sequence &&sequence, Index &&index)
Definition: Foreach-inl.h:299
template<typename Sequence , typename Func >
static void folly::for_each_detail::for_each_impl ( TupleTag  ,
Sequence &&  range,
Func func 
)
static

Top level handlers for the for_each loop, with one overload for tuples and one overload for ranges

This implies that if type is both a range and a tuple, it is treated as a range rather than as a tuple

Definition at line 270 of file Foreach-inl.h.

References for_each_tuple_impl(), folly::range(), type, and value.

270  {
271  using type = decltype(get_impl<0>(std::declval<Sequence>()));
272  using tag = ForEachImplTag<Func, type, void>;
273  static_assert(!std::is_same<tag, void>::value, "unknown invocability");
274  for_each_tuple_impl(tag{}, std::forward<Sequence>(range), func);
275 }
PskType type
Gen range(Value begin, Value end)
Definition: Base.h:467
static const char *const value
Definition: Conv.cpp:50
void for_each_tuple_impl(index_constant< 1 >, Sequence &&seq, Func &func)
Definition: Foreach-inl.h:252
template<typename Sequence , typename Func >
static void folly::for_each_detail::for_each_impl ( RangeTag  ,
Sequence &&  range,
Func func 
)
static

Definition at line 277 of file Foreach-inl.h.

References folly::for_each_detail::adl::adl_begin(), for_each_range_impl(), folly::range(), type, and value.

Referenced by folly::for_each().

277  {
278  using iter = decltype(adl::adl_begin(std::declval<Sequence>()));
279  using type = decltype(*std::declval<iter>());
280  using tag = ForEachImplTag<Func, type, iter>;
281  static_assert(!std::is_same<tag, void>::value, "unknown invocability");
282  for_each_range_impl(tag{}, std::forward<Sequence>(range), func);
283 }
PskType type
Gen range(Value begin, Value end)
Definition: Base.h:467
void for_each_range_impl(index_constant< 1 >, Sequence &&range, Func &func)
Definition: Foreach-inl.h:195
static const char *const value
Definition: Conv.cpp:50
auto adl_begin(Type &&instance) -> decltype(begin(instance))
Definition: Foreach-inl.h:54
template<typename Sequence , typename Func >
void folly::for_each_detail::for_each_range_impl ( index_constant< 3 >  ,
Sequence &&  range,
Func func 
)

Implementations for the runtime function

Definition at line 170 of file Foreach-inl.h.

References folly::for_each_detail::adl::adl_begin(), folly::for_each_detail::adl::adl_end(), folly::gen::first, invoke_returning_loop_control(), folly::loop_break, cpp.ast::next(), and folly::range().

Referenced by for_each_impl(), and for_each_range_impl().

170  {
171  auto first = adl::adl_begin(range);
172  auto last = adl::adl_end(range);
173  for (auto index = std::size_t{0}; first != last; ++index) {
174  auto next = std::next(first);
175  auto control = invoke_returning_loop_control(func, *first, index, first);
176  if (loop_break == control) {
177  break;
178  }
179  first = next;
180  }
181 }
LoopControl invoke_returning_loop_control(Func &&f, Args &&...a)
Definition: Foreach-inl.h:151
auto adl_end(Type &&instance) -> decltype(end(instance))
Definition: Foreach-inl.h:58
Gen range(Value begin, Value end)
Definition: Base.h:467
auto adl_begin(Type &&instance) -> decltype(begin(instance))
Definition: Foreach-inl.h:54
constexpr auto loop_break
Definition: Foreach.h:97
constexpr detail::First first
Definition: Base-inl.h:2553
def next(obj)
Definition: ast.py:58
template<typename Sequence , typename Func >
void folly::for_each_detail::for_each_range_impl ( index_constant< 2 >  ,
Sequence &&  range,
Func func 
)

Definition at line 183 of file Foreach-inl.h.

References for_each_range_impl(), and folly::range().

183  {
184  // make a three arg adaptor for the function passed in so that the main
185  // implementation function can be used
186  auto three_arg_adaptor = [&func](
187  auto&& ele, auto index, auto) -> decltype(auto) {
188  return func(std::forward<decltype(ele)>(ele), index);
189  };
191  index_constant<3>{}, std::forward<Sequence>(range), three_arg_adaptor);
192 }
Gen range(Value begin, Value end)
Definition: Base.h:467
void for_each_range_impl(index_constant< 1 >, Sequence &&range, Func &func)
Definition: Foreach-inl.h:195
template<typename Sequence , typename Func >
void folly::for_each_detail::for_each_range_impl ( index_constant< 1 >  ,
Sequence &&  range,
Func func 
)

Definition at line 195 of file Foreach-inl.h.

References for_each_range_impl(), and folly::range().

195  {
196  // make a three argument adaptor for the function passed in that just ignores
197  // the second and third argument
198  auto three_arg_adaptor = [&func](auto&& ele, auto, auto) -> decltype(auto) {
199  return func(std::forward<decltype(ele)>(ele));
200  };
202  index_constant<3>{}, std::forward<Sequence>(range), three_arg_adaptor);
203 }
Gen range(Value begin, Value end)
Definition: Base.h:467
void for_each_range_impl(index_constant< 1 >, Sequence &&range, Func &func)
Definition: Foreach-inl.h:195
template<typename Sequence , typename Func , std::size_t... Indices>
void folly::for_each_detail::for_each_tuple_impl ( index_sequence< Indices... >  ,
Sequence &&  seq,
Func func 
)

Handlers for iteration

Definition at line 209 of file Foreach-inl.h.

References testing::_, invoke_returning_loop_control(), folly::loop_continue, and folly::gen::seq().

Referenced by for_each_impl(), and for_each_tuple_impl().

212  {
213  using _ = int[];
214 
215  // unroll the loop in an initializer list construction parameter expansion
216  // pack
217  auto control = loop_continue;
218 
219  // cast to void to ignore the result; use the int[] initialization to do the
220  // loop execution, the ternary conditional will decide whether or not to
221  // evaluate the result
222  //
223  // if func does not return loop-control, expect the optimizer to see through
224  // invoke_returning_loop_control always returning loop_continue
225  void(
226  _{(((control == loop_continue)
227  ? (control = invoke_returning_loop_control(
228  func,
229  get_impl<Indices>(std::forward<Sequence>(seq)),
230  index_constant<Indices>{}))
231  : (loop_continue)),
232  0)...});
233 }
LoopControl invoke_returning_loop_control(Func &&f, Args &&...a)
Definition: Foreach-inl.h:151
constexpr auto loop_continue
Definition: Foreach.h:98
Gen seq(Value first, Value last)
Definition: Base.h:484
const internal::AnythingMatcher _
template<typename Sequence , typename Func >
void folly::for_each_detail::for_each_tuple_impl ( index_constant< 2 >  ,
Sequence &&  seq,
Func func 
)

The two top level compile time loop iteration functions handle the dispatch based on the number of arguments the passed in function can be passed, if 2 arguments can be passed then the implementation dispatches work further to the implementation classes above. If not then an adaptor is constructed which is passed on to the 2 argument specialization, which then in turn forwards implementation to the implementation classes above

Definition at line 244 of file Foreach-inl.h.

References for_each_tuple_impl(), folly::gen::seq(), folly::size(), and type.

244  {
245  // pass the length as an index sequence to the implementation as an
246  // optimization over manual template "tail recursion" unrolling
249  make_index_sequence<size::value>{}, std::forward<Sequence>(seq), func);
250 }
PskType type
Gen seq(Value first, Value last)
Definition: Base.h:484
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
void for_each_tuple_impl(index_constant< 1 >, Sequence &&seq, Func &func)
Definition: Foreach-inl.h:252
template<typename Sequence , typename Func >
void folly::for_each_detail::for_each_tuple_impl ( index_constant< 1 >  ,
Sequence &&  seq,
Func func 
)

Definition at line 252 of file Foreach-inl.h.

References for_each_tuple_impl(), and folly::gen::seq().

252  {
253  // make an adaptor for the function passed in, in case it can only be passed
254  // on argument
255  auto two_arg_adaptor = [&func](auto&& ele, auto) -> decltype(auto) {
256  return func(std::forward<decltype(ele)>(ele));
257  };
259  index_constant<2>{}, std::forward<Sequence>(seq), two_arg_adaptor);
260 }
Gen seq(Value first, Value last)
Definition: Base.h:484
void for_each_tuple_impl(index_constant< 1 >, Sequence &&seq, Func &func)
Definition: Foreach-inl.h:252
template<std::size_t Index, typename Type , std::enable_if_t<!IsMemberGetFound< void, Type >::value, int > = 0>
auto folly::for_each_detail::get_impl ( Type &&  instance) -> decltype(adl::adl_get<Index>(static_cast<Type&&>(instance)))

A get that tries member get<> first and if that is not found tries ADL get<>. This mechanism is as found in the structured bindings proposal here 11.5.3. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf

Definition at line 84 of file Foreach-inl.h.

References type, and value.

85  {
86  return adl::adl_get<Index>(static_cast<Type&&>(instance));
87 }
template<typename Func , typename... Args, std::enable_if_t< is_invocable_r< LoopControl, Func, Args... >::value, int > = 0>
LoopControl folly::for_each_detail::invoke_returning_loop_control ( Func &&  f,
Args &&...  a 
)

Definition at line 151 of file Foreach-inl.h.

References a, testing::Args(), f, folly::loop_continue, and folly::value().

Referenced by for_each_range_impl(), and for_each_tuple_impl().

151  {
152  return static_cast<Func&&>(f)(static_cast<Args&&>(a)...);
153 }
auto f
Function< void()> Func
Definition: Executor.h:27
char a