mirror of
https://github.com/Naios/continuable.git
synced 2026-02-11 04:39:50 +08:00
Implement the missing checks for container categories
This commit is contained in:
parent
09f9da3e0e
commit
f0b25956b9
@ -71,19 +71,19 @@ namespace cti {
|
|||||||
///
|
///
|
||||||
template <typename Mapper, typename... T>
|
template <typename Mapper, typename... T>
|
||||||
auto map_pack(Mapper&& mapper, T&&... pack) {
|
auto map_pack(Mapper&& mapper, T&&... pack) {
|
||||||
return detail::traversal::apply_pack_transform(
|
return detail::traversal::transform(detail::traversal::strategy_remap_tag{},
|
||||||
detail::traversal::strategy_remap_tag{}, std::forward<Mapper>(mapper),
|
std::forward<Mapper>(mapper),
|
||||||
std::forward<T>(pack)...);
|
std::forward<T>(pack)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicate that the result shall be spread across the parent container
|
/// Indicate that the result shall be spread across the parent container
|
||||||
/// if possible. This can be used to create a mapper function used
|
/// 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).
|
/// in map_pack that maps one element to an arbitrary count (1:n).
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
constexpr auto spread_this(T&&... args) {
|
constexpr auto spread_this(T&&... args) noexcept(
|
||||||
return detail::traversal::spreading::spread_box<
|
noexcept(std::make_tuple(std::forward<T>(args)...))) {
|
||||||
typename std::decay<T>::type...>(
|
using type = detail::traversal::spreading::spread_box<std::decay_t<T>...>;
|
||||||
std::make_tuple(std::forward<T>(args)...));
|
return type(std::make_tuple(std::forward<T>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Traverses the pack with the given visitor.
|
/// Traverses the pack with the given visitor.
|
||||||
@ -94,9 +94,9 @@ constexpr auto spread_this(T&&... args) {
|
|||||||
/// See `map_pack` for a detailed description.
|
/// See `map_pack` for a detailed description.
|
||||||
template <typename Mapper, typename... T>
|
template <typename Mapper, typename... T>
|
||||||
void traverse_pack(Mapper&& mapper, T&&... pack) {
|
void traverse_pack(Mapper&& mapper, T&&... pack) {
|
||||||
detail::traversal::apply_pack_transform(
|
detail::traversal::transform(detail::traversal::strategy_traverse_tag{},
|
||||||
detail::traversal::strategy_traverse_tag{}, std::forward<Mapper>(mapper),
|
std::forward<Mapper>(mapper),
|
||||||
std::forward<T>(pack)...);
|
std::forward<T>(pack)...);
|
||||||
}
|
}
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|
||||||
|
|||||||
@ -31,9 +31,36 @@
|
|||||||
#ifndef CONTINUABLE_DETAIL_CONTAINER_CATEGORY_HPP_INCLUDED
|
#ifndef CONTINUABLE_DETAIL_CONTAINER_CATEGORY_HPP_INCLUDED
|
||||||
#define CONTINUABLE_DETAIL_CONTAINER_CATEGORY_HPP_INCLUDED
|
#define CONTINUABLE_DETAIL_CONTAINER_CATEGORY_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <continuable/detail/traits.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace traversal {
|
namespace traversal {
|
||||||
|
namespace detail {
|
||||||
|
/// Deduces to a true type if the given parameter T
|
||||||
|
/// has a begin() and end() method.
|
||||||
|
// TODO Find out whether we should use std::begin and std::end instead, which
|
||||||
|
// could cause issues with plain arrays.
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct is_range : std::false_type {};
|
||||||
|
template <typename T>
|
||||||
|
struct is_range<T, traits::void_t<decltype(std::declval<T>().begin() ==
|
||||||
|
std::declval<T>().end())>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
/// Deduces to a true type if the given parameter T
|
||||||
|
/// is accessible through std::tuple_size.
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct is_tuple_like : std::false_type {};
|
||||||
|
template <typename T>
|
||||||
|
struct is_tuple_like<T, traits::void_t<decltype(std::tuple_size<T>::value)>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
/// A tag for dispatching based on the tuple like
|
/// A tag for dispatching based on the tuple like
|
||||||
/// or container properties of a type.
|
/// or container properties of a type.
|
||||||
template <bool IsContainer, bool IsTupleLike>
|
template <bool IsContainer, bool IsTupleLike>
|
||||||
@ -42,9 +69,8 @@ struct container_category_tag {};
|
|||||||
/// Deduces to the container_category_tag of the given type T.
|
/// Deduces to the container_category_tag of the given type T.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using container_category_of_t =
|
using container_category_of_t =
|
||||||
container_category_tag<false, // TODO traits::is_range<T>::value,
|
container_category_tag<detail::is_range<T>::value,
|
||||||
false // TODO traits::is_tuple_like<T>::value
|
detail::is_tuple_like<T>::value>;
|
||||||
>;
|
|
||||||
} // namespace traversal
|
} // namespace traversal
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|||||||
@ -833,11 +833,7 @@ public:
|
|||||||
|
|
||||||
/// Traverses the given pack with the given mapper and strategy
|
/// Traverses the given pack with the given mapper and strategy
|
||||||
template <typename Strategy, typename Mapper, typename... T>
|
template <typename Strategy, typename Mapper, typename... T>
|
||||||
auto apply_pack_transform(Strategy strategy, Mapper&& mapper, T&&... pack)
|
auto transform(Strategy strategy, Mapper&& mapper, T&&... pack) {
|
||||||
-> decltype(
|
|
||||||
std::declval<
|
|
||||||
mapping_helper<Strategy, typename std::decay<Mapper>::type>>()
|
|
||||||
.init_traverse(strategy, std::forward<T>(pack)...)) {
|
|
||||||
mapping_helper<Strategy, typename std::decay<Mapper>::type> helper(
|
mapping_helper<Strategy, typename std::decay<Mapper>::type> helper(
|
||||||
std::forward<Mapper>(mapper));
|
std::forward<Mapper>(mapper));
|
||||||
return helper.init_traverse(strategy, std::forward<T>(pack)...);
|
return helper.init_traverse(strategy, std::forward<T>(pack)...);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user