Traversal module

provides functions to traverse and remap nested packs.

Contents

Typedefs

using async_traverse_visit_tag = detail::traversal::async_traverse_visit_tag
A tag which is passed to the operator() of the visitor if an element is visited synchronously through traverse_pack_async.
using async_traverse_detach_tag = detail::traversal::async_traverse_detach_tag
A tag which is passed to the operator() of the visitor if an element is visited after the traversal was detached through traverse_pack_async.
using async_traverse_complete_tag = detail::traversal::async_traverse_complete_tag
A tag which is passed to the operator() of the visitor if the asynchronous pack traversal was finished through traverse_pack_async.
template<typename T>
using async_traverse_in_place_tag = detail::traversal::async_traverse_in_place_tag<T>
A tag to identify that a mapper shall be constructed in-place from the first argument passed to traverse_pack_async.

Functions

template<typename Visitor, typename... T>
auto traverse_pack_async(Visitor&& visitor, T && ... pack) -> auto
Traverses the pack with the given visitor in an asynchronous way.
template<typename Mapper, typename... T>
auto map_pack(Mapper&& mapper, T && ... pack) -> decltype(auto)
Maps the pack with the given mapper.
template<typename... T>
auto spread_this(T && ... args) -> detail::traversal::spreading::spread_box<std::decay_t<T>...> constexpr noexcept(…)
Indicate that the result shall be spread across the parent container if possible. This can be used to create a mapper function used in map_pack that maps one element to an arbitrary count (1:n).
template<typename Mapper, typename... T>
void traverse_pack(Mapper&& mapper, T && ... pack)
Traverses the pack with the given visitor.

Typedef documentation

using async_traverse_visit_tag = detail::traversal::async_traverse_visit_tag

A tag which is passed to the operator() of the visitor if an element is visited synchronously through traverse_pack_async.

using async_traverse_detach_tag = detail::traversal::async_traverse_detach_tag

A tag which is passed to the operator() of the visitor if an element is visited after the traversal was detached through traverse_pack_async.

using async_traverse_complete_tag = detail::traversal::async_traverse_complete_tag

A tag which is passed to the operator() of the visitor if the asynchronous pack traversal was finished through traverse_pack_async.

template<typename T>
using async_traverse_in_place_tag = detail::traversal::async_traverse_in_place_tag<T>

A tag to identify that a mapper shall be constructed in-place from the first argument passed to traverse_pack_async.

Function documentation

template<typename Visitor, typename... T>
auto traverse_pack_async(Visitor&& visitor, T && ... pack)

Traverses the pack with the given visitor in an asynchronous way.

Parameters
visitor A visitor object which provides the three operator() overloads that were described above. Additionally the visitor must be compatible for referencing it from a boost::intrusive_ptr. The visitor should must have a virtual destructor!
pack The arbitrary parameter pack which is traversed asynchronously. Nested objects inside containers and tuple like types are traversed recursively.
Returns A std::shared_ptr that references an instance of the given visitor object.

This function works in the same way as traverse_pack, however, we are able to suspend and continue the traversal at later time. Thus we require a visitor callable object which provides three operator() overloads as depicted by the code sample below:

struct my_async_visitor {
  template <typename T>
  bool operator()(async_traverse_visit_tag, T&& element) {
    return true;
  }

  template <typename T, typename N>
  void operator()(async_traverse_detach_tag, T&& element, N&& next) {
  }

  template <typename T>
  void operator()(async_traverse_complete_tag, T&& pack) {
  }
};

See traverse_pack for a detailed description about the traversal behaviour and capabilities.

template<typename Mapper, typename... T>
decltype(auto) map_pack(Mapper&& mapper, T && ... pack)

Maps the pack with the given mapper.

Parameters
mapper A callable object, which accept an arbitrary type and maps it to another type or the same one.
pack An arbitrary variadic pack which may contain any type.
Returns The mapped element or in case the pack contains multiple elements, the pack is wrapped into a std::tuple.
Exceptions
std::exception like objects which are thrown by an invocation to the mapper.

This function tries to visit all plain elements which may be wrapped in:

  • homogeneous containers (std::vector, std::list)
  • heterogenous containers (std::tuple, std::pair, std::array) and re-assembles the pack with the result of the mapper. Mapping from one type to a different one is supported.

Elements that aren't accepted by the mapper are routed through and preserved through the hierarchy.

// Maps all integers to floats
map_pack([](int value) {
  return float(value);
},
1, std::make_tuple(2, std::vector<int>{3, 4}), 5);

template<typename... T>
detail::traversal::spreading::spread_box<std::decay_t<T>...> spread_this(T && ... args) constexpr noexcept(…)

Indicate that the result shall be spread across the parent container if possible. This can be used to create a mapper function used in map_pack that maps one element to an arbitrary count (1:n).

template<typename Mapper, typename... T>
void traverse_pack(Mapper&& mapper, T && ... pack)

Traverses the pack with the given visitor.

This function works in the same way as map_pack, however, the result of the mapper isn't preserved.

See map_pack for a detailed description.