diff --git a/test/unit-test/test-continuable-traverse-async.cpp b/test/unit-test/test-continuable-traverse-async.cpp index d321e9a..285eaca 100644 --- a/test/unit-test/test-continuable-traverse-async.cpp +++ b/test/unit-test/test-continuable-traverse-async.cpp @@ -22,65 +22,6 @@ **/ #include -#include -#include -#include -#include -#include - -#include - -#include "test-continuable.hpp" - -using std::get; -using std::make_tuple; -using std::tuple; - -using cti::async_traverse_complete_tag; -using cti::async_traverse_detach_tag; -using cti::async_traverse_visit_tag; -using cti::traverse_pack_async; - -struct my_visitor : std::enable_shared_from_this { - virtual ~my_visitor() = default; - - bool operator()(async_traverse_visit_tag, std::size_t i) { - (void)i; - return false; - } - - template - void operator()(async_traverse_detach_tag, std::size_t i, N&& next) { - (void)i; - next(); - } - - template - void operator()(async_traverse_complete_tag, T&& pack) { - (void)pack; - } -}; - -TEST(misc_as_test, my_test) { - cti::traverse_pack_async(my_visitor{}, 0, 1, 2); -} - -// Copyright (c) 2017 Denis Blank -// Copyright Andrey Semashev 2007 - 2013. -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -// TODO Remove the boost dependency - -/* -#include -#include -#include -#include -#include -#include - #include #include #include @@ -90,455 +31,323 @@ TEST(misc_as_test, my_test) { #include #include -#if defined(HPX_HAVE_CXX11_STD_ARRAY) -#include -#endif +#include +#include +#include -using hpx::util::async_traverse_complete_tag; -using hpx::util::async_traverse_detach_tag; -using hpx::util::async_traverse_visit_tag; -using hpx::util::make_tuple; -using hpx::util::traverse_pack_async; -using hpx::util::tuple; +#include "test-continuable.hpp" + +using std::get; +using std::make_tuple; +using std::tuple; + +using cti::async_traverse_complete_tag; +using cti::async_traverse_detach_tag; +using cti::async_traverse_in_place_tag; +using cti::async_traverse_visit_tag; +using cti::detail::util::unused; +using cti::traverse_pack_async; /// A tag which isn't accepted by any mapper -struct not_accepted_tag -{ -}; - -struct thread_safe_counter -{ - typedef hpx::util::atomic_count type; - - static unsigned int load(hpx::util::atomic_count const& counter) noexcept - { - return static_cast(static_cast(counter)); - } - - static void increment(hpx::util::atomic_count& counter) noexcept - { - ++counter; - } - - static unsigned int decrement(hpx::util::atomic_count& counter) noexcept - { - return static_cast(--counter); - } -}; - -template -class intrusive_ref_counter; - -template -void intrusive_ptr_add_ref( - intrusive_ref_counter const* p) noexcept; - -template -void intrusive_ptr_release( - intrusive_ref_counter const* p) noexcept; - -template -class intrusive_ref_counter -{ -private: - typedef typename CounterPolicy::type counter_type; - - mutable counter_type ref_counter; - -public: - intrusive_ref_counter() noexcept : ref_counter(1) {} - - unsigned int use_count() const noexcept - { - return CounterPolicy::load(ref_counter); - } - -protected: - ~intrusive_ref_counter() = default; - - friend void intrusive_ptr_add_ref( - intrusive_ref_counter const* p) - noexcept; - - friend void intrusive_ptr_release( - intrusive_ref_counter const* p) - noexcept; -}; - -template -inline void intrusive_ptr_add_ref( - intrusive_ref_counter const* p) noexcept -{ - CounterPolicy::increment(p->ref_counter); -} - -template -inline void intrusive_ptr_release( - intrusive_ref_counter const* p) noexcept -{ - if (CounterPolicy::decrement(p->ref_counter) == 0) - delete static_cast(p); -} +struct not_accepted_tag {}; template -class async_counter_base : public intrusive_ref_counter -{ - std::size_t counter_ = 0; +class async_counter_base : public std::enable_shared_from_this { + std::size_t counter_ = 0; public: - async_counter_base() = default; + async_counter_base() = default; - virtual ~async_counter_base() {} + virtual ~async_counter_base() { + } - std::size_t const& counter() const noexcept - { - return counter_; - } + std::size_t const& counter() const noexcept { + return counter_; + } - std::size_t& counter() noexcept - { - return counter_; - } + std::size_t& counter() noexcept { + return counter_; + } }; template struct async_increasing_int_sync_visitor - : async_counter_base> -{ - explicit async_increasing_int_sync_visitor(int dummy) {} + : async_counter_base> { + explicit async_increasing_int_sync_visitor(int /*dummy*/) { + } - bool operator()(async_traverse_visit_tag, std::size_t i) - { - EXPECT_EQ(i, this->counter()); - ++this->counter(); - return true; - } + bool operator()(async_traverse_visit_tag, std::size_t i) { + EXPECT_EQ(i, this->counter()); + ++this->counter(); + return true; + } - template - void operator()(async_traverse_detach_tag, std::size_t i, N&& next) - { - HPX_UNUSED(i); - HPX_UNUSED(next); + template + void operator()(async_traverse_detach_tag, std::size_t i, N&& next) { + unused(i); + unused(next); - // Should never be called! - HPX_TEST(false); - } + // Should never be called! + EXPECT_TRUE(false); + } - template - void operator()(async_traverse_complete_tag, T&& pack) - { - HPX_UNUSED(pack); + template + void operator()(async_traverse_complete_tag, T&& pack) { + unused(pack); - EXPECT_EQ(this->counter(), ArgCount); - ++this->counter(); - } + EXPECT_EQ(this->counter(), ArgCount); + ++this->counter(); + } }; template struct async_increasing_int_visitor - : async_counter_base> -{ - explicit async_increasing_int_visitor(int dummy) {} + : async_counter_base> { + explicit async_increasing_int_visitor(int /*dummy*/) { + } - bool operator()(async_traverse_visit_tag, std::size_t i) const - { - EXPECT_EQ(i, this->counter()); - return false; - } + bool operator()(async_traverse_visit_tag, std::size_t i) const { + EXPECT_EQ(i, this->counter()); + return false; + } - template - void operator()(async_traverse_detach_tag, std::size_t i, N&& next) - { - HPX_UNUSED(i); + template + void operator()(async_traverse_detach_tag, std::size_t i, N&& next) { + unused(i); - ++this->counter(); - std::forward(next)(); - } + ++this->counter(); + std::forward(next)(); + } - template - void operator()(async_traverse_complete_tag, T&& pack) - { - HPX_UNUSED(pack); + template + void operator()(async_traverse_complete_tag, T&& pack) { + unused(pack); - EXPECT_EQ(this->counter(), ArgCount); - ++this->counter(); - } + EXPECT_EQ(this->counter(), ArgCount); + ++this->counter(); + } }; template -void test_async_traversal_base(Args&&... args) -{ - // Test that every element is traversed in the correct order - // when we detach the control flow on every visit. - { - auto result = traverse_pack_async( - hpx::util::async_traverse_in_place_tag< - async_increasing_int_sync_visitor>{}, - 42, args...); - EXPECT_EQ(result->counter(), ArgCount + 1U); - } +void test_async_traversal_base(Args&&... args) { + // Test that every element is traversed in the correct order + // when we detach the control flow on every visit. + { + auto result = + traverse_pack_async(async_traverse_in_place_tag< + async_increasing_int_sync_visitor>{}, + 42, args...); + EXPECT_EQ(result->counter(), ArgCount + 1U); + } - // Test that every element is traversed in the correct order - // when we detach the control flow on every visit. - { - auto result = traverse_pack_async( - hpx::util::async_traverse_in_place_tag< - async_increasing_int_visitor>{}, - 42, args...); - EXPECT_EQ(result->counter(), ArgCount + 1U); - } + // Test that every element is traversed in the correct order + // when we detach the control flow on every visit. + { + auto result = traverse_pack_async( + async_traverse_in_place_tag>{}, + 42, args...); + EXPECT_EQ(result->counter(), ArgCount + 1U); + } } -static void test_async_traversal() -{ - // Just test everything using a casual int pack - test_async_traversal_base<4U>(not_accepted_tag{}, - 0U, - 1U, - not_accepted_tag{}, - 2U, - 3U, - not_accepted_tag{}); +void test_async_traversal() { + // Just test everything using a casual int pack + test_async_traversal_base<4U>(not_accepted_tag{}, 0U, 1U, not_accepted_tag{}, + 2U, 3U, not_accepted_tag{}); } template -void test_async_container_traversal_impl(ContainerFactory&& container_of) -{ - // Test by passing a containers in the middle - test_async_traversal_base<4U>(0U, container_of(1U, 2U), 3U); - // Test by splitting the pack in two containers - test_async_traversal_base<4U>(container_of(0U, 1U), container_of(2U, 3U)); - // Test by passing a huge containers to the traversal - test_async_traversal_base<4U>(container_of(0U, 1U, 2U, 3U)); +void test_async_container_traversal_impl(ContainerFactory&& container_of) { + // Test by passing a containers in the middle + test_async_traversal_base<4U>(0U, container_of(1U, 2U), 3U); + // Test by splitting the pack in two containers + test_async_traversal_base<4U>(container_of(0U, 1U), container_of(2U, 3U)); + // Test by passing a huge containers to the traversal + test_async_traversal_base<4U>(container_of(0U, 1U, 2U, 3U)); } template -struct common_container_factory -{ - template - T operator()(Args&&... args) - { - return T{std::forward(args)...}; - } +struct common_container_factory { + template + T operator()(Args&&... args) { + return T{std::forward(args)...}; + } }; -#if defined(HPX_HAVE_CXX11_STD_ARRAY) template -struct array_container_factory -{ - template > - Array operator()(Args&&... args) - { - return Array{{std::forward(args)...}}; - } +struct array_container_factory { + template > + Array operator()(Args&&... args) { + return Array{{std::forward(args)...}}; + } }; -#endif -static void test_async_container_traversal() -{ - { - common_container_factory> factory; - test_async_container_traversal_impl(factory); - } +void test_async_container_traversal() { + { + common_container_factory> factory; + test_async_container_traversal_impl(factory); + } - { - common_container_factory> factory; - test_async_container_traversal_impl(factory); - } + { + common_container_factory> factory; + test_async_container_traversal_impl(factory); + } - { - common_container_factory> factory; - test_async_container_traversal_impl(factory); - } + { + common_container_factory> factory; + test_async_container_traversal_impl(factory); + } -#if defined(HPX_HAVE_CXX11_STD_ARRAY) - { - array_container_factory factory; - test_async_container_traversal_impl(factory); - } -#endif + { + array_container_factory factory; + test_async_container_traversal_impl(factory); + } } -static void test_async_tuple_like_traversal() -{ - // Test by passing a tuple in the middle - test_async_traversal_base<4U>( - not_accepted_tag{}, 0U, make_tuple(1U, not_accepted_tag{}, 2U), 3U); - // Test by splitting the pack in two tuples - test_async_traversal_base<4U>( - make_tuple(0U, not_accepted_tag{}, 1U), make_tuple(2U, 3U)); - // Test by passing a huge tuple to the traversal - test_async_traversal_base<4U>(make_tuple(0U, 1U, 2U, 3U)); +void test_async_tuple_like_traversal() { + // Test by passing a tuple in the middle + test_async_traversal_base<4U>(not_accepted_tag{}, 0U, + make_tuple(1U, not_accepted_tag{}, 2U), 3U); + // Test by splitting the pack in two tuples + test_async_traversal_base<4U>(make_tuple(0U, not_accepted_tag{}, 1U), + make_tuple(2U, 3U)); + // Test by passing a huge tuple to the traversal + test_async_traversal_base<4U>(make_tuple(0U, 1U, 2U, 3U)); } -template ::type>> -Vector vector_of(T&& first, Args&&... args) -{ - return Vector{std::forward(first), std::forward(args)...}; +template ::type>> +Vector vector_of(T&& first, Args&&... args) { + return Vector{std::forward(first), std::forward(args)...}; } -static void test_async_mixed_traversal() -{ - using container_t = std::vector; +void test_async_mixed_traversal() { + using container_t = std::vector; - // Test hierarchies where container and tuple like types are mixed - test_async_traversal_base<4U>( - 0U, hpx::util::make_tuple(container_t{1U, 2U}), 3U); + // Test hierarchies where container and tuple like types are mixed + test_async_traversal_base<4U>(0U, make_tuple(container_t{1U, 2U}), 3U); - test_async_traversal_base<4U>( - hpx::util::make_tuple( - 0U, vector_of(not_accepted_tag{}), vector_of(vector_of(1U))), - make_tuple(2U, 3U)); + test_async_traversal_base<4U>( + make_tuple(0U, vector_of(not_accepted_tag{}), vector_of(vector_of(1U))), + make_tuple(2U, 3U)); - test_async_traversal_base<4U>( - vector_of(vector_of(make_tuple(0U, 1U, 2U, 3U)))); + test_async_traversal_base<4U>( + vector_of(vector_of(make_tuple(0U, 1U, 2U, 3U)))); } template struct async_unique_sync_visitor - : async_counter_base> -{ - explicit async_unique_sync_visitor(int dummy) {} + : async_counter_base> { + explicit async_unique_sync_visitor(int /*dummy*/) { + } - bool operator()(async_traverse_visit_tag, std::unique_ptr& i) - { - EXPECT_EQ(*i, this->counter()); - ++this->counter(); - return true; - } + bool operator()(async_traverse_visit_tag, std::unique_ptr& i) { + EXPECT_EQ(*i, this->counter()); + ++this->counter(); + return true; + } - template - void operator()(async_traverse_detach_tag, - std::unique_ptr& i, - N&& next) - { - HPX_UNUSED(i); - HPX_UNUSED(next); + template + void operator()(async_traverse_detach_tag, std::unique_ptr& i, + N&& next) { + unused(i); + unused(next); - // Should never be called! - HPX_TEST(false); - } + // Should never be called! + EXPECT_TRUE(false); + } - template - void operator()(async_traverse_complete_tag, T&& pack) - { - HPX_UNUSED(pack); + template + void operator()(async_traverse_complete_tag, T&& pack) { + unused(pack); - EXPECT_EQ(this->counter(), ArgCount); - ++this->counter(); - } + EXPECT_EQ(this->counter(), ArgCount); + ++this->counter(); + } }; template -struct async_unique_visitor : async_counter_base> -{ - explicit async_unique_visitor(int dummy) {} +struct async_unique_visitor + : async_counter_base> { + explicit async_unique_visitor(int /*dummy*/) { + } - bool operator()(async_traverse_visit_tag, - std::unique_ptr& i) const - { - EXPECT_EQ(*i, this->counter()); - return false; - } + bool operator()(async_traverse_visit_tag, + std::unique_ptr& i) const { + EXPECT_EQ(*i, this->counter()); + return false; + } - template - void operator()(async_traverse_detach_tag, - std::unique_ptr& i, - N&& next) - { - HPX_UNUSED(i); + template + void operator()(async_traverse_detach_tag, std::unique_ptr& i, + N&& next) { + unused(i); - ++this->counter(); - std::forward(next)(); - } + ++this->counter(); + std::forward(next)(); + } - template - void operator()(async_traverse_complete_tag, T&& pack) - { - HPX_UNUSED(pack); + template + void operator()(async_traverse_complete_tag, T&& pack) { + unused(pack); - EXPECT_EQ(this->counter(), ArgCount); - ++this->counter(); - } + EXPECT_EQ(this->counter(), ArgCount); + ++this->counter(); + } }; -static void test_async_move_only_traversal() -{ - auto const of = [](std::size_t i) { - return std::unique_ptr(new std::size_t(i)); - }; - - { - auto result = traverse_pack_async( - hpx::util::async_traverse_in_place_tag< - async_unique_sync_visitor<4>>{}, - 42, of(0), of(1), of(2), of(3)); - EXPECT_EQ(result->counter(), 5U); - } - - { - auto result = traverse_pack_async( - hpx::util::async_traverse_in_place_tag< - async_unique_visitor<4>>{}, - 42, of(0), of(1), of(2), of(3)); - EXPECT_EQ(result->counter(), 5U); - } +template +constexpr auto of(T i) { + return std::make_unique(i); } -struct invalidate_visitor : async_counter_base -{ - explicit invalidate_visitor(int dummy) {} +TEST(async_traverse_in_place, construct_inplace_sync) { + auto result = traverse_pack_async( + async_traverse_in_place_tag>{}, 42, of(0), + of(1), of(2), of(3)); + EXPECT_EQ(result->counter(), 5U); +} - bool operator()(async_traverse_visit_tag, std::shared_ptr& i) const - { - EXPECT_EQ(*i, 22); - return false; - } +TEST(async_traverse_in_place, construct_inplace_async) { + auto result = traverse_pack_async( + async_traverse_in_place_tag>{}, 42, of(0), of(1), + of(2), of(3)); + EXPECT_EQ(result->counter(), 5U); +} - template - void operator()(async_traverse_detach_tag, - std::shared_ptr& i, - N&& next) - { - HPX_UNUSED(i); +struct invalidate_visitor : async_counter_base { + explicit invalidate_visitor(int /*dummy*/) { + } - std::forward(next)(); - } + bool operator()(async_traverse_visit_tag, std::shared_ptr& i) const { + EXPECT_EQ(*i, 22); + return false; + } - // Test whether the passed pack was passed as r-value reference - void operator()(async_traverse_complete_tag, - tuple>&& pack) const - { - // Invalidate the moved object - tuple> moved = std::move(pack); + template + void operator()(async_traverse_detach_tag, std::shared_ptr& i, + N&& next) { + unused(i); - HPX_UNUSED(moved); - } + std::forward(next)(); + } + + // Test whether the passed pack was passed as r-value reference + void operator()(async_traverse_complete_tag, + tuple>&& pack) const { + // Invalidate the moved object + tuple> moved = std::move(pack); + + unused(moved); + } }; // Check whether the arguments are invalidated (moved out) when called -static void test_async_complete_invalidation() -{ - auto value = std::make_shared(22); +TEST(async_complete_invalidation, check_whether_frame_released) { + auto value = std::make_shared(22); - auto frame = traverse_pack_async( - hpx::util::async_traverse_in_place_tag{}, - 42, value); + auto frame = traverse_pack_async( + async_traverse_in_place_tag{}, 42, value); - EXPECT_EQ(value.use_count(), 1U); + EXPECT_EQ(value.use_count(), 1L); } - -int main(int, char**) -{ - test_async_traversal(); - test_async_container_traversal(); - test_async_tuple_like_traversal(); - test_async_mixed_traversal(); - test_async_move_only_traversal(); - test_async_complete_invalidation(); - - return hpx::util::report_errors(); -} -*/