From d62eec2632a7c6fe88cfd5f7884a49d4df52cc3c Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Sun, 18 Nov 2018 19:00:38 +0100 Subject: [PATCH] Started on transitioning to unref --- .../detail/traversal/traverse-async.hpp | 27 +++++++------- .../continuable/detail/traversal/traverse.hpp | 37 +++++++++---------- include/continuable/detail/utility/traits.hpp | 6 +++ 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/include/continuable/detail/traversal/traverse-async.hpp b/include/continuable/detail/traversal/traverse-async.hpp index bc67c43..9774810 100644 --- a/include/continuable/detail/traversal/traverse-async.hpp +++ b/include/continuable/detail/traversal/traverse-async.hpp @@ -97,10 +97,10 @@ public: /// given iterator tuple. template auto make_resume_traversal_callable(Frame&& frame, State&& state) - -> resume_traversal_callable::type, - typename std::decay::type> { - return resume_traversal_callable::type, - typename std::decay::type>( + -> resume_traversal_callable, + traits::unref_t> { + return resume_traversal_callable, + traits::unref_t>( std::forward(frame), std::forward(state)); } @@ -292,8 +292,8 @@ struct dynamic_async_range { template using dynamic_async_range_of_t = dynamic_async_range< - typename std::decay()))>::type, - typename std::decay()))>::type>; + traits::unref_t()))>, + traits::unref_t()))>>; /// Returns a dynamic range for the given type template @@ -337,9 +337,8 @@ public: auto hierarchy = std::tuple_cat( std::make_tuple(std::forward(parent)), hierarchy_); - return async_traversal_point::type, - Hierarchy...>(frame_, std::move(hierarchy), - detached_); + return async_traversal_point, Hierarchy...>( + frame_, std::move(hierarchy), detached_); } /// Forks the current traversal point and continues the child @@ -405,7 +404,7 @@ public: /// Async traverse the current iterator template void async_traverse_one(Current&& current) { - using ElementType = typename std::decay::type; + using ElementType = traits::unref_t; return async_traverse_one_impl(container_category_of_t{}, std::forward(current)); } @@ -453,8 +452,8 @@ public: /// given frame and hierarchy template using traversal_point_of_t = - async_traversal_point::type, - typename std::decay::type...>; + async_traversal_point, + traits::unref_t...>; /// A callable object which is capable of resuming an asynchronous /// pack traversal. @@ -528,8 +527,8 @@ template struct async_traversal_types { /// Deduces to the async traversal frame type of the given /// traversal arguments and mapper - using frame_t = async_traversal_frame::type, - typename std::decay::type...>; + using frame_t = + async_traversal_frame, traits::unref_t...>; /// The type of the demoted visitor type using visitor_t = Visitor; diff --git a/include/continuable/detail/traversal/traverse.hpp b/include/continuable/detail/traversal/traverse.hpp index e58dbb1..697ca4d 100644 --- a/include/continuable/detail/traversal/traverse.hpp +++ b/include/continuable/detail/traversal/traverse.hpp @@ -169,8 +169,7 @@ struct flat_arraylizer { /// Deduces to the array type when the array is instantiated /// with the given arguments. template - using array_type_of_t = - Type::type, 1 + sizeof...(Rest)>; + using array_type_of_t = Type, 1 + sizeof...(Rest)>; // We overload with one argument here so Clang and GCC don't // 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. template using dereferenced_of_t = - typename std::conditional::value, - typename std::decay::type, T>::type; + typename std::conditional::value, traits::unref_t, + T>::type; /// Returns the type which is resulting if the mapping is applied to /// an element in the container. @@ -423,8 +422,8 @@ using mapped_type_from_t = dereferenced_of_t -using is_empty_mapped = spreading::is_empty_spread()(std::declval>()))>::type>; +using is_empty_mapped = spreading::is_empty_spread()(std::declval>()))>>; /// We are allowed to reuse the container if we map to the same /// type we are accepting and when we have @@ -472,10 +471,9 @@ template auto remap_container(container_mapping_tag, M&& mapper, T&& container) -> decltype(rebind_container>(container)) { - static_assert( - has_push_back::type, element_of_t>::value, - "Can only remap containers that provide a push_back " - "method!"); + static_assert(has_push_back, element_of_t>::value, + "Can only remap containers that provide a push_back " + "method!"); // Create the new container, which is capable of holding // the remappped types. @@ -503,7 +501,7 @@ auto remap_container(container_mapping_tag, M&& mapper, /// type we accepted such as int -> int. template auto remap_container(container_mapping_tag, M&& mapper, - T&& container) -> typename std::decay::type { + T&& container) -> traits::unref_t { for (auto&& val : container_accessor_of(std::forward(container))) { val = spreading::unpack( std::forward(mapper)(std::forward(val))); @@ -629,12 +627,11 @@ struct tuple_like_remapper< /// different types. template auto remap(Strategy, T&& container, M&& mapper) -> decltype(traits::unpack( - std::declval::type, - typename std::decay::type>>(), + std::declval, + traits::unref_t>>(), std::forward(container))) { return traits::unpack( - tuple_like_remapper::type, - typename std::decay::type>{ + tuple_like_remapper, traits::unref_t>{ std::forward(mapper)}, std::forward(container)); } @@ -645,7 +642,7 @@ auto remap(Strategy, T&& container, M&& mapper) -> decltype(traits::unpack( template struct mapping_strategy_base { template - auto may_void(T&& element) const -> typename std::decay::type { + auto may_void(T&& element) const -> traits::unref_t { return std::forward(element); } }; @@ -803,19 +800,19 @@ class mapping_helper : protected mapping_strategy_base { template auto traverse(Strategy, T&& element) -> decltype(std::declval().match( - std::declval::type>>(), + std::declval>>(), std::declval())); /// \copybrief traverse template auto try_traverse(Strategy, T&& element) -> decltype(std::declval().try_match( - std::declval::type>>(), + std::declval>>(), std::declval())) { // We use tag dispatching here, to categorize the type T whether // it satisfies the container or tuple like requirements. // Then we can choose the underlying implementation accordingly. - return try_match(container_category_of_t::type>{}, + return try_match(container_category_of_t>{}, std::forward(element)); } @@ -861,7 +858,7 @@ public: /// Traverses the given pack with the given mapper and strategy template decltype(auto) transform(Strategy strategy, Mapper&& mapper, T&&... pack) { - mapping_helper::type> helper( + mapping_helper> helper( std::forward(mapper)); return helper.init_traverse(strategy, std::forward(pack)...); } diff --git a/include/continuable/detail/utility/traits.hpp b/include/continuable/detail/utility/traits.hpp index a9e2736..3150f37 100644 --- a/include/continuable/detail/utility/traits.hpp +++ b/include/continuable/detail/utility/traits.hpp @@ -40,6 +40,12 @@ namespace cti { namespace detail { 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 +using unref_t = std::remove_cv_t>; + namespace detail { template struct index_of_impl;