Add the public headers for both traversal strategies

This commit is contained in:
Denis Blank 2018-02-05 23:10:12 +01:00
parent 7d0e68ad9b
commit 6a8919c63d
5 changed files with 235 additions and 8 deletions

View File

@ -0,0 +1,119 @@
/*
/~` _ _ _|_. _ _ |_ | _
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v2.0.0
Copyright(c) 2015 - 2018 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**/
#ifndef CONTINUABLE_TRAVERSE_ASYNC_HPP_INCLUDED
#define CONTINUABLE_TRAVERSE_ASYNC_HPP_INCLUDED
#include <continuable/detail/traverse-async.hpp>
#include <utility>
namespace cti {
/// A tag which is passed to the `operator()` of the visitor
/// if an element is visited synchronously.
using detail::async_traverse_visit_tag;
/// A tag which is passed to the `operator()` of the visitor
/// if an element is visited after the traversal was detached.
using detail::async_traverse_detach_tag;
/// A tag which is passed to the `operator()` of the visitor
/// if the asynchronous pack traversal was finished.
using detail::async_traverse_complete_tag;
/// A tag to identify that a mapper shall be constructed in-place
/// from the first argument passed.
using detail::async_traverse_in_place_tag;
/// Traverses the pack with the given visitor in an asynchronous way.
///
/// 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:
/// ```cpp
/// struct my_async_visitor
/// {
/// /// The synchronous overload is called for each object,
/// /// it may return false to suspend the current control.
/// /// In that case the overload below is called.
/// template <typename T>
/// bool operator()(async_traverse_visit_tag, T&& element)
/// {
/// return true;
/// }
///
/// /// The asynchronous overload this is called when the
/// /// synchronous overload returned false.
/// /// In addition to the current visited element the overload is
/// /// called with a contnuation callable object which resumes the
/// /// traversal when it's called later.
/// /// The continuation next may be stored and called later or
/// /// dropped completely to abort the traversal early.
/// template <typename T, typename N>
/// void operator()(async_traverse_detach_tag, T&& element, N&& next)
/// {
/// }
///
/// /// The overload is called when the traversal was finished.
/// /// As argument the whole pack is passed over which we
/// /// traversed asynchrnously.
/// template <typename T>
/// void operator()(async_traverse_complete_tag, T&& pack)
/// {
/// }
/// };
/// ```
///
/// \param 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!
///
/// \param pack The arbitrary parameter pack which is traversed
/// asynchronously. Nested objects inside containers and
/// tuple like types are traversed recursively.
///
/// \returns A boost::intrusive_ptr that references an instance of
/// the given visitor object.
///
/// See `traverse_pack` for a detailed description about the
/// traversal behaviour and capabilities.
///
template <typename Visitor, typename... T>
auto traverse_pack_async(Visitor&& visitor, T&&... pack)
-> decltype(detail::apply_pack_transform_async(
std::forward<Visitor>(visitor), std::forward<T>(pack)...)) {
return detail::apply_pack_transform_async(std::forward<Visitor>(visitor),
std::forward<T>(pack)...);
}
} // namespace cti
#endif // CONTINUABLE_TRAVERSE_ASYNC_HPP_INCLUDED

View File

@ -0,0 +1,106 @@
/*
/~` _ _ _|_. _ _ |_ | _
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v2.0.0
Copyright(c) 2015 - 2018 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**/
#ifndef CONTINUABLE_TRAVERSE_HPP_INCLUDED
#define CONTINUABLE_TRAVERSE_HPP_INCLUDED
#include <tuple>
#include <type_traits>
#include <utility>
#include <continuable/detail/traverse.hpp>
namespace cti {
/// Maps the pack with the given mapper.
///
/// This function tries to visit all plain elements which may be wrapped in:
/// - homogeneous containers (`std::vector`, `std::list`)
/// - heterogenous containers `(hpx::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.
///
/// ```cpp
/// // Maps all integers to floats
/// map_pack([](int value) {
/// return float(value);
/// },
/// 1, hpx::util::make_tuple(2, std::vector<int>{3, 4}), 5);
/// ```
///
/// \throws std::exception like objects which are thrown by an
/// invocation to the mapper.
///
/// \param mapper A callable object, which accept an arbitrary type
/// and maps it to another type or the same one.
///
/// \param 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 `hpx::tuple`.
///
template <typename Mapper, typename... T>
auto map_pack(Mapper&& mapper, T&&... pack)
-> decltype(detail::apply_pack_transform(detail::strategy_remap_tag{},
std::forward<Mapper>(mapper),
std::forward<T>(pack)...)) {
return detail::apply_pack_transform(detail::strategy_remap_tag{},
std::forward<Mapper>(mapper),
std::forward<T>(pack)...);
}
/// 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... T>
constexpr detail::spreading::spread_box<typename std::decay<T>::type...>
spread_this(T&&... args) {
return detail::spreading::spread_box<typename std::decay<T>::type...>(
util::make_tuple(std::forward<T>(args)...));
}
/// 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.
template <typename Mapper, typename... T>
void traverse_pack(Mapper&& mapper, T&&... pack) {
detail::apply_pack_transform(detail::strategy_traverse_tag{},
std::forward<Mapper>(mapper),
std::forward<T>(pack)...);
}
} // namespace cti
#endif // CONTINUABLE_TRAVERSE_HPP_INCLUDED

View File

@ -28,8 +28,8 @@
SOFTWARE.
**/
#ifndef CONTINUABLE_DETAIL_PACK_TRAVERSAL_ASYNC_HPP_INCLUDED
#define CONTINUABLE_DETAIL_PACK_TRAVERSAL_ASYNC_HPP_INCLUDED
#ifndef CONTINUABLE_DETAIL_TRAVERSE_ASYNC_HPP_INCLUDED
#define CONTINUABLE_DETAIL_TRAVERSE_ASYNC_HPP_INCLUDED
#include <atomic>
#include <cassert>
@ -558,4 +558,4 @@ auto apply_pack_transform_async(Visitor&& visitor, Args&&... args) ->
} // namespace detail
} // namespace cti
#endif // CONTINUABLE_DETAIL_PACK_TRAVERSAL_ASYNC_HPP_INCLUDED
#endif // CONTINUABLE_DETAIL_TRAVERSE_ASYNC_HPP_INCLUDED

View File

@ -28,8 +28,8 @@
SOFTWARE.
**/
#ifndef CONTINUABLE_DETAIL_PACK_TRAVERSAL_HPP_INCLUDED
#define CONTINUABLE_DETAIL_PACK_TRAVERSAL_HPP_INCLUDED
#ifndef CONTINUABLE_DETAIL_TRAVERSE_HPP_INCLUDED
#define CONTINUABLE_DETAIL_TRAVERSE_HPP_INCLUDED
#include <cstddef>
#include <iterator>
@ -842,4 +842,4 @@ auto apply_pack_transform(Strategy strategy, Mapper&& mapper, T&&... pack)
} // namespace detail
} // namespace cti
#endif // CONTINUABLE_DETAIL_PACK_TRAVERSAL_HPP_INCLUDED
#endif // CONTINUABLE_DETAIL_TRAVERSE_HPP_INCLUDED

View File

@ -5,6 +5,8 @@ set(LIB_SOURCES
${CMAKE_SOURCE_DIR}/include/continuable/continuable-trait.hpp
${CMAKE_SOURCE_DIR}/include/continuable/continuable-promise-base.hpp
${CMAKE_SOURCE_DIR}/include/continuable/continuable-transforms.hpp
${CMAKE_SOURCE_DIR}/include/continuable/continuable-traverse.hpp
${CMAKE_SOURCE_DIR}/include/continuable/continuable-traverse-async.hpp
${CMAKE_SOURCE_DIR}/include/continuable/continuable-testing.hpp)
set(LIB_SOURCES_DETAIL
${CMAKE_SOURCE_DIR}/include/continuable/detail/awaiting.hpp
@ -13,8 +15,8 @@ set(LIB_SOURCES_DETAIL
${CMAKE_SOURCE_DIR}/include/continuable/detail/expected.hpp
${CMAKE_SOURCE_DIR}/include/continuable/detail/hints.hpp
${CMAKE_SOURCE_DIR}/include/continuable/detail/container-category.hpp
${CMAKE_SOURCE_DIR}/include/continuable/detail/pack-traversal.hpp
${CMAKE_SOURCE_DIR}/include/continuable/detail/pack-traversal-async.hpp
${CMAKE_SOURCE_DIR}/include/continuable/detail/traverse.hpp
${CMAKE_SOURCE_DIR}/include/continuable/detail/traverse-async.hpp
${CMAKE_SOURCE_DIR}/include/continuable/detail/features.hpp
${CMAKE_SOURCE_DIR}/include/continuable/detail/traits.hpp
${CMAKE_SOURCE_DIR}/include/continuable/detail/transforms.hpp