mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Started on transitioning to unref
This commit is contained in:
parent
a9d4ee5ba8
commit
d62eec2632
@ -97,10 +97,10 @@ public:
|
|||||||
/// given iterator tuple.
|
/// given iterator tuple.
|
||||||
template <typename Frame, typename State>
|
template <typename Frame, typename State>
|
||||||
auto make_resume_traversal_callable(Frame&& frame, State&& state)
|
auto make_resume_traversal_callable(Frame&& frame, State&& state)
|
||||||
-> resume_traversal_callable<typename std::decay<Frame>::type,
|
-> resume_traversal_callable<traits::unref_t<Frame>,
|
||||||
typename std::decay<State>::type> {
|
traits::unref_t<State>> {
|
||||||
return resume_traversal_callable<typename std::decay<Frame>::type,
|
return resume_traversal_callable<traits::unref_t<Frame>,
|
||||||
typename std::decay<State>::type>(
|
traits::unref_t<State>>(
|
||||||
std::forward<Frame>(frame), std::forward<State>(state));
|
std::forward<Frame>(frame), std::forward<State>(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,8 +292,8 @@ struct dynamic_async_range {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using dynamic_async_range_of_t = dynamic_async_range<
|
using dynamic_async_range_of_t = dynamic_async_range<
|
||||||
typename std::decay<decltype(std::begin(std::declval<T>()))>::type,
|
traits::unref_t<decltype(std::begin(std::declval<T>()))>,
|
||||||
typename std::decay<decltype(std::end(std::declval<T>()))>::type>;
|
traits::unref_t<decltype(std::end(std::declval<T>()))>>;
|
||||||
|
|
||||||
/// Returns a dynamic range for the given type
|
/// Returns a dynamic range for the given type
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -337,9 +337,8 @@ public:
|
|||||||
auto hierarchy = std::tuple_cat(
|
auto hierarchy = std::tuple_cat(
|
||||||
std::make_tuple(std::forward<Parent>(parent)), hierarchy_);
|
std::make_tuple(std::forward<Parent>(parent)), hierarchy_);
|
||||||
|
|
||||||
return async_traversal_point<Frame, typename std::decay<Parent>::type,
|
return async_traversal_point<Frame, traits::unref_t<Parent>, Hierarchy...>(
|
||||||
Hierarchy...>(frame_, std::move(hierarchy),
|
frame_, std::move(hierarchy), detached_);
|
||||||
detached_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Forks the current traversal point and continues the child
|
/// Forks the current traversal point and continues the child
|
||||||
@ -405,7 +404,7 @@ public:
|
|||||||
/// Async traverse the current iterator
|
/// Async traverse the current iterator
|
||||||
template <typename Current>
|
template <typename Current>
|
||||||
void async_traverse_one(Current&& current) {
|
void async_traverse_one(Current&& current) {
|
||||||
using ElementType = typename std::decay<decltype(*current)>::type;
|
using ElementType = traits::unref_t<decltype(*current)>;
|
||||||
return async_traverse_one_impl(container_category_of_t<ElementType>{},
|
return async_traverse_one_impl(container_category_of_t<ElementType>{},
|
||||||
std::forward<Current>(current));
|
std::forward<Current>(current));
|
||||||
}
|
}
|
||||||
@ -453,8 +452,8 @@ public:
|
|||||||
/// given frame and hierarchy
|
/// given frame and hierarchy
|
||||||
template <typename Frame, typename... Hierarchy>
|
template <typename Frame, typename... Hierarchy>
|
||||||
using traversal_point_of_t =
|
using traversal_point_of_t =
|
||||||
async_traversal_point<typename std::decay<Frame>::type,
|
async_traversal_point<traits::unref_t<Frame>,
|
||||||
typename std::decay<Hierarchy>::type...>;
|
traits::unref_t<Hierarchy>...>;
|
||||||
|
|
||||||
/// A callable object which is capable of resuming an asynchronous
|
/// A callable object which is capable of resuming an asynchronous
|
||||||
/// pack traversal.
|
/// pack traversal.
|
||||||
@ -528,8 +527,8 @@ template <typename Visitor, typename... Args>
|
|||||||
struct async_traversal_types {
|
struct async_traversal_types {
|
||||||
/// Deduces to the async traversal frame type of the given
|
/// Deduces to the async traversal frame type of the given
|
||||||
/// traversal arguments and mapper
|
/// traversal arguments and mapper
|
||||||
using frame_t = async_traversal_frame<typename std::decay<Visitor>::type,
|
using frame_t =
|
||||||
typename std::decay<Args>::type...>;
|
async_traversal_frame<traits::unref_t<Visitor>, traits::unref_t<Args>...>;
|
||||||
|
|
||||||
/// The type of the demoted visitor type
|
/// The type of the demoted visitor type
|
||||||
using visitor_t = Visitor;
|
using visitor_t = Visitor;
|
||||||
|
|||||||
@ -169,8 +169,7 @@ struct flat_arraylizer {
|
|||||||
/// Deduces to the array type when the array is instantiated
|
/// Deduces to the array type when the array is instantiated
|
||||||
/// with the given arguments.
|
/// with the given arguments.
|
||||||
template <typename First, typename... Rest>
|
template <typename First, typename... Rest>
|
||||||
using array_type_of_t =
|
using array_type_of_t = Type<traits::unref_t<First>, 1 + sizeof...(Rest)>;
|
||||||
Type<typename std::decay<First>::type, 1 + sizeof...(Rest)>;
|
|
||||||
|
|
||||||
// We overload with one argument here so Clang and GCC don't
|
// We overload with one argument here so Clang and GCC don't
|
||||||
// have any issues with overloading against zero arguments.
|
// have any issues with overloading against zero arguments.
|
||||||
@ -408,8 +407,8 @@ using element_of_t = typename std::conditional<
|
|||||||
/// if the type is a l-value or r-value reference.
|
/// if the type is a l-value or r-value reference.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using dereferenced_of_t =
|
using dereferenced_of_t =
|
||||||
typename std::conditional<std::is_reference<T>::value,
|
typename std::conditional<std::is_reference<T>::value, traits::unref_t<T>,
|
||||||
typename std::decay<T>::type, T>::type;
|
T>::type;
|
||||||
|
|
||||||
/// Returns the type which is resulting if the mapping is applied to
|
/// Returns the type which is resulting if the mapping is applied to
|
||||||
/// an element in the container.
|
/// an element in the container.
|
||||||
@ -423,8 +422,8 @@ using mapped_type_from_t = dereferenced_of_t<spreading::unpacked_of_t<decltype(
|
|||||||
|
|
||||||
/// Deduces to a true_type if the mapping maps to zero elements.
|
/// Deduces to a true_type if the mapping maps to zero elements.
|
||||||
template <typename T, typename M>
|
template <typename T, typename M>
|
||||||
using is_empty_mapped = spreading::is_empty_spread<typename std::decay<decltype(
|
using is_empty_mapped = spreading::is_empty_spread<traits::unref_t<decltype(
|
||||||
std::declval<M>()(std::declval<element_of_t<T>>()))>::type>;
|
std::declval<M>()(std::declval<element_of_t<T>>()))>>;
|
||||||
|
|
||||||
/// We are allowed to reuse the container if we map to the same
|
/// We are allowed to reuse the container if we map to the same
|
||||||
/// type we are accepting and when we have
|
/// type we are accepting and when we have
|
||||||
@ -472,10 +471,9 @@ template <typename M, typename T>
|
|||||||
auto remap_container(container_mapping_tag<false, false>, M&& mapper,
|
auto remap_container(container_mapping_tag<false, false>, M&& mapper,
|
||||||
T&& container)
|
T&& container)
|
||||||
-> decltype(rebind_container<mapped_type_from_t<T, M>>(container)) {
|
-> decltype(rebind_container<mapped_type_from_t<T, M>>(container)) {
|
||||||
static_assert(
|
static_assert(has_push_back<traits::unref_t<T>, element_of_t<T>>::value,
|
||||||
has_push_back<typename std::decay<T>::type, element_of_t<T>>::value,
|
"Can only remap containers that provide a push_back "
|
||||||
"Can only remap containers that provide a push_back "
|
"method!");
|
||||||
"method!");
|
|
||||||
|
|
||||||
// Create the new container, which is capable of holding
|
// Create the new container, which is capable of holding
|
||||||
// the remappped types.
|
// the remappped types.
|
||||||
@ -503,7 +501,7 @@ auto remap_container(container_mapping_tag<false, false>, M&& mapper,
|
|||||||
/// type we accepted such as int -> int.
|
/// type we accepted such as int -> int.
|
||||||
template <typename M, typename T>
|
template <typename M, typename T>
|
||||||
auto remap_container(container_mapping_tag<false, true>, M&& mapper,
|
auto remap_container(container_mapping_tag<false, true>, M&& mapper,
|
||||||
T&& container) -> typename std::decay<T>::type {
|
T&& container) -> traits::unref_t<T> {
|
||||||
for (auto&& val : container_accessor_of(std::forward<T>(container))) {
|
for (auto&& val : container_accessor_of(std::forward<T>(container))) {
|
||||||
val = spreading::unpack(
|
val = spreading::unpack(
|
||||||
std::forward<M>(mapper)(std::forward<decltype(val)>(val)));
|
std::forward<M>(mapper)(std::forward<decltype(val)>(val)));
|
||||||
@ -629,12 +627,11 @@ struct tuple_like_remapper<
|
|||||||
/// different types.
|
/// different types.
|
||||||
template <typename Strategy, typename T, typename M>
|
template <typename Strategy, typename T, typename M>
|
||||||
auto remap(Strategy, T&& container, M&& mapper) -> decltype(traits::unpack(
|
auto remap(Strategy, T&& container, M&& mapper) -> decltype(traits::unpack(
|
||||||
std::declval<tuple_like_remapper<Strategy, typename std::decay<M>::type,
|
std::declval<tuple_like_remapper<Strategy, traits::unref_t<M>,
|
||||||
typename std::decay<T>::type>>(),
|
traits::unref_t<T>>>(),
|
||||||
std::forward<T>(container))) {
|
std::forward<T>(container))) {
|
||||||
return traits::unpack(
|
return traits::unpack(
|
||||||
tuple_like_remapper<Strategy, typename std::decay<M>::type,
|
tuple_like_remapper<Strategy, traits::unref_t<M>, traits::unref_t<T>>{
|
||||||
typename std::decay<T>::type>{
|
|
||||||
std::forward<M>(mapper)},
|
std::forward<M>(mapper)},
|
||||||
std::forward<T>(container));
|
std::forward<T>(container));
|
||||||
}
|
}
|
||||||
@ -645,7 +642,7 @@ auto remap(Strategy, T&& container, M&& mapper) -> decltype(traits::unpack(
|
|||||||
template <typename Strategy>
|
template <typename Strategy>
|
||||||
struct mapping_strategy_base {
|
struct mapping_strategy_base {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto may_void(T&& element) const -> typename std::decay<T>::type {
|
auto may_void(T&& element) const -> traits::unref_t<T> {
|
||||||
return std::forward<T>(element);
|
return std::forward<T>(element);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -803,19 +800,19 @@ class mapping_helper : protected mapping_strategy_base<Strategy> {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
auto traverse(Strategy, T&& element)
|
auto traverse(Strategy, T&& element)
|
||||||
-> decltype(std::declval<mapping_helper>().match(
|
-> decltype(std::declval<mapping_helper>().match(
|
||||||
std::declval<container_category_of_t<typename std::decay<T>::type>>(),
|
std::declval<container_category_of_t<traits::unref_t<T>>>(),
|
||||||
std::declval<T>()));
|
std::declval<T>()));
|
||||||
|
|
||||||
/// \copybrief traverse
|
/// \copybrief traverse
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto try_traverse(Strategy, T&& element)
|
auto try_traverse(Strategy, T&& element)
|
||||||
-> decltype(std::declval<mapping_helper>().try_match(
|
-> decltype(std::declval<mapping_helper>().try_match(
|
||||||
std::declval<container_category_of_t<typename std::decay<T>::type>>(),
|
std::declval<container_category_of_t<traits::unref_t<T>>>(),
|
||||||
std::declval<T>())) {
|
std::declval<T>())) {
|
||||||
// We use tag dispatching here, to categorize the type T whether
|
// We use tag dispatching here, to categorize the type T whether
|
||||||
// it satisfies the container or tuple like requirements.
|
// it satisfies the container or tuple like requirements.
|
||||||
// Then we can choose the underlying implementation accordingly.
|
// Then we can choose the underlying implementation accordingly.
|
||||||
return try_match(container_category_of_t<typename std::decay<T>::type>{},
|
return try_match(container_category_of_t<traits::unref_t<T>>{},
|
||||||
std::forward<T>(element));
|
std::forward<T>(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,7 +858,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>
|
||||||
decltype(auto) transform(Strategy strategy, Mapper&& mapper, T&&... pack) {
|
decltype(auto) transform(Strategy strategy, Mapper&& mapper, T&&... pack) {
|
||||||
mapping_helper<Strategy, typename std::decay<Mapper>::type> helper(
|
mapping_helper<Strategy, traits::unref_t<Mapper>> 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)...);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,6 +40,12 @@
|
|||||||
namespace cti {
|
namespace cti {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace traits {
|
namespace traits {
|
||||||
|
/// Removes all references and qualifiers from the given type T,
|
||||||
|
/// since traits::unref_t has too much overhead through checking for
|
||||||
|
/// function pointers and arrays.
|
||||||
|
template <typename T>
|
||||||
|
using unref_t = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
struct index_of_impl;
|
struct index_of_impl;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user