From fb3c9cf78098cac8dbc4254b6e92eb95d1f60243 Mon Sep 17 00:00:00 2001 From: Sean Parent Date: Tue, 2 Feb 2021 10:06:40 -0800 Subject: [PATCH 01/10] backport to C++14 --- CMakeLists.txt | 8 +- conanfile.py | 8 +- setup_xcode.sh => setup_xcode_cpp14.sh | 2 +- setup_xcode_cpp17.sh | 10 ++ stlab/concurrency/channel.hpp | 136 +++++++++++++++++++---- stlab/concurrency/config.hpp | 9 ++ stlab/concurrency/config_task_system.hpp | 37 ++++-- stlab/concurrency/future.hpp | 73 ++++++------ stlab/concurrency/optional.hpp | 8 +- stlab/concurrency/task.hpp | 23 ++-- stlab/concurrency/utility.hpp | 4 +- stlab/concurrency/variant.hpp | 2 + stlab/forest_algorithms.hpp | 4 +- test/channel_tests.cpp | 11 +- test/executor_test.cpp | 44 +++++--- test/forest_test.cpp | 9 +- test/future_recover_tests.cpp | 20 ++-- test/future_tests.cpp | 15 +-- 18 files changed, 292 insertions(+), 131 deletions(-) rename setup_xcode.sh => setup_xcode_cpp14.sh (54%) create mode 100755 setup_xcode_cpp17.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 53da464b1..15e751228 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,8 @@ endif() project( stlab VERSION 1.5.6 LANGUAGES CXX ) -set(CMAKE_CXX_STANDARD 17) +# Overriden from Conan? +# set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) include( CTest ) @@ -67,7 +68,7 @@ add_library( stlab::stlab ALIAS stlab ) # features ensures that the corresponding C++ standard flag is populated in # targets linking to stlab. # -target_compile_features( stlab INTERFACE cxx_std_17 ) +# target_compile_features( stlab INTERFACE cxx_std_14) # # The include directory for stlab can be expected to vary between build @@ -106,6 +107,9 @@ if( EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) # conanfile.txt # conan_basic_setup( TARGETS KEEP_RPATHS ) + + # REVISIT (sparent) : This should not be necessary but appears to be + set(CMAKE_CXX_STANDARD ${CONAN_SETTINGS_COMPILER_CPPSTD}) endif() if ( stlab.testing OR stlab.boost_variant OR stlab.boost_optional ) diff --git a/conanfile.py b/conanfile.py index 113613a93..86e069154 100644 --- a/conanfile.py +++ b/conanfile.py @@ -109,7 +109,8 @@ def _configure_boost(self): def _fix_boost_components(self): if self.settings.os != "Macos": return if self.settings.compiler != "apple-clang": return - if float(str(self.settings.compiler.version)) >= 12: return + + if (float(str(self.settings.compiler.version)) >= 12) and not ((self.settings.compiler.cppstd == "14") or (self.settings.compiler.cppstd == "gnu14")): return # # On Apple we have to force the usage of boost.variant, because Apple's implementation of C++17 is not complete. @@ -171,6 +172,8 @@ def _configure_task_system(self): def configure(self): ConanFile.configure(self) + tools.check_min_cppstd(self, "14") + self._fix_boost_components() if self._use_boost(): @@ -195,11 +198,10 @@ def build(self): cmake.configure() cmake.build() cmake.test(output_on_failure=True) - + def package(self): self.copy("*.hpp") def imports(self): self.copy("*.dll", "./bin", "bin") self.copy("*.dylib", "./bin", "lib") - diff --git a/setup_xcode.sh b/setup_xcode_cpp14.sh similarity index 54% rename from setup_xcode.sh rename to setup_xcode_cpp14.sh index 1eb5f41f8..0336aad9f 100755 --- a/setup_xcode.sh +++ b/setup_xcode_cpp14.sh @@ -3,7 +3,7 @@ mkdir -p build pushd build -conan install .. --build=missing -s build_type=Debug +conan install .. --build=missing -s build_type=Debug -o testing=True -s compiler.cppstd=14 cmake -GXcode -D CMAKE_BUILD_TYPE=debug -D stlab_testing=ON .. diff --git a/setup_xcode_cpp17.sh b/setup_xcode_cpp17.sh new file mode 100755 index 000000000..90ffe88ac --- /dev/null +++ b/setup_xcode_cpp17.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +mkdir -p build +pushd build + +conan install .. --build=missing -s build_type=Debug -o testing=True -s compiler.cppstd=17 + +cmake -GXcode -D CMAKE_BUILD_TYPE=debug -D stlab_testing=ON .. + +popd diff --git a/stlab/concurrency/channel.hpp b/stlab/concurrency/channel.hpp index 6f002ac5d..2e7ce9d49 100755 --- a/stlab/concurrency/channel.hpp +++ b/stlab/concurrency/channel.hpp @@ -229,15 +229,21 @@ struct invoke_variant_dispatcher { template <> struct invoke_variant_dispatcher<1> { template - static auto invoke_(F&& f, T& t) { - if constexpr (std::is_same::value) { - return; - } else if constexpr (std::is_same::value) { - return std::forward(f)(); - } else { - return std::forward(f)(std::move(stlab::get(std::get<0>(t)))); - } + static auto invoke_(F&&, T&) -> std::enable_if_t::value, void> { + return; } + template + static auto invoke_(F&& f, T&) -> std::enable_if_t::value, + decltype(std::forward(f)())> { + return std::forward(f)(); + } + template + static auto invoke_(F&& f, T& t) -> std::enable_if_t< + !(std::is_same::value || std::is_same::value), + decltype(std::forward(f)(std::move(stlab::get(std::get<0>(t)))))> { + return std::forward(f)(std::move(stlab::get(std::get<0>(t)))); + } + template static auto invoke(F&& f, T& t) { return invoke_>(std::forward(f), t); @@ -699,7 +705,7 @@ struct downstream< _data = std::forward(f); } - void clear() { _data = nullopt; } + void clear() { _data = stlab::nullopt; } std::size_t size() const { return 1; } @@ -828,7 +834,7 @@ struct shared_process if (do_final) { std::unique_lock lock(_downstream_mutex); _downstream.clear(); // This will propagate the close to anything downstream - _process = nullopt; + _process = stlab::nullopt; } } @@ -910,8 +916,14 @@ struct shared_process return bool(message); } + /* + REVISIT (sparent) : Next two cases are nearly identical, complicated by the need to + remove constexpr if to support C++14. + */ + template - auto step() -> std::enable_if_t>> { + auto step() -> std::enable_if_t> && + !has_process_await_v, Args...>> { // in case that the timeout function is just been executed then we have to re-schedule // the current run lock_t lock(_timeout_function_control, std::try_to_lock); @@ -926,12 +938,90 @@ struct shared_process is done on yield() */ try { - if constexpr (has_process_await_v, Args...>) { - while (get_process_state(_process).first == process_state::await) { - if (!dequeue()) break; - } + if (get_process_state(_process).first == process_state::await) return; + + // Workaround until we can use structured bindings + auto tmp = get_process_state(_process); + const auto& state = tmp.first; + const auto& duration = tmp.second; + + /* + Once we hit yield, go ahead and call it. If the yield is delayed then schedule it. + This process will be considered running until it executes. + */ + if (state == process_state::yield) { + if (std::chrono::duration_cast(duration) <= + std::chrono::nanoseconds::min()) + broadcast(unwrap(*_process).yield()); + else + execute_at(duration, + _executor)([_weak_this = make_weak_ptr(this->shared_from_this())] { + auto _this = _weak_this.lock(); + if (!_this) return; + _this->try_broadcast(); + }); + } + + /* + We are in an await state and the queue is empty. + + If we await forever then task_done() leaving us in an await state. + else if we await with an expired timeout then go ahead and yield now. + else schedule a timeout when we will yield if not canceled by intervening await. + */ + else if (std::chrono::duration_cast(duration) == + std::chrono::nanoseconds::max()) { + task_done(); + } else if (std::chrono::duration_cast(duration) <= + std::chrono::nanoseconds::min()) { + broadcast(unwrap(*_process).yield()); } else { - if (get_process_state(_process).first == process_state::await) return; + /* Schedule a timeout. */ + _timeout_function_active = true; + execute_at(duration, + _executor)([_weak_this = make_weak_ptr(this->shared_from_this())] { + auto _this = _weak_this.lock(); + // It may be that the complete channel is gone in the meanwhile + if (!_this) return; + + // try_lock can fail spuriously + while (true) { + lock_t lock(_this->_timeout_function_control, std::try_to_lock); + if (!lock) continue; + + // we were cancelled + if (get_process_state(_this->_process).first != process_state::yield) { + _this->try_broadcast(); + _this->_timeout_function_active = false; + } + return; + } + }); + } + } catch (...) { // this catches exceptions during _process.await() and _process.yield() + broadcast(std::move(std::current_exception())); + } + } + + template + auto step() -> std::enable_if_t> && + has_process_await_v, Args...>> { + // in case that the timeout function is just been executed then we have to re-schedule + // the current run + lock_t lock(_timeout_function_control, std::try_to_lock); + if (!lock) { + run(); + return; + } + _timeout_function_active = false; + + /* + While we are waiting we will flush the queue. The assumption here is that work + is done on yield() + */ + try { + while (get_process_state(_process).first == process_state::await) { + if (!dequeue()) break; } // Workaround until we can use structured bindings @@ -944,7 +1034,8 @@ struct shared_process This process will be considered running until it executes. */ if (state == process_state::yield) { - if (std::chrono::duration_cast(duration) <= std::chrono::nanoseconds::min()) + if (std::chrono::duration_cast(duration) <= + std::chrono::nanoseconds::min()) broadcast(unwrap(*_process).yield()); else execute_at(duration, @@ -962,14 +1053,17 @@ struct shared_process else if we await with an expired timeout then go ahead and yield now. else schedule a timeout when we will yield if not canceled by intervening await. */ - else if (std::chrono::duration_cast(duration) == std::chrono::nanoseconds::max()) { + else if (std::chrono::duration_cast(duration) == + std::chrono::nanoseconds::max()) { task_done(); - } else if (std::chrono::duration_cast(duration) <= std::chrono::nanoseconds::min()) { + } else if (std::chrono::duration_cast(duration) <= + std::chrono::nanoseconds::min()) { broadcast(unwrap(*_process).yield()); } else { /* Schedule a timeout. */ _timeout_function_active = true; - execute_at(duration, _executor)([_weak_this = make_weak_ptr(this->shared_from_this())] { + execute_at(duration, + _executor)([_weak_this = make_weak_ptr(this->shared_from_this())] { auto _this = _weak_this.lock(); // It may be that the complete channel is gone in the meanwhile if (!_this) return; @@ -1367,7 +1461,7 @@ detail::annotated_process operator&(detail::annotated_process&& a, buffer_ /**************************************************************************************************/ template -class [[nodiscard]] receiver { +class STLAB_NODISCARD() receiver { using ptr_t = std::shared_ptr>; ptr_t _p; diff --git a/stlab/concurrency/config.hpp b/stlab/concurrency/config.hpp index fe1a58840..1cecd5baa 100644 --- a/stlab/concurrency/config.hpp +++ b/stlab/concurrency/config.hpp @@ -61,6 +61,15 @@ #endif #endif +/**************************************************************************************************/ + +#if __cplusplus < 201703L +#define STLAB_NODISCARD() +#else +#define STLAB_NODISCARD() [[nodiscard]] +#endif + + /**************************************************************************************************/ #endif // STLAB_CONCURRENCY_CONFIG_HPP diff --git a/stlab/concurrency/config_task_system.hpp b/stlab/concurrency/config_task_system.hpp index 46b9a84d0..42e10061c 100644 --- a/stlab/concurrency/config_task_system.hpp +++ b/stlab/concurrency/config_task_system.hpp @@ -46,31 +46,48 @@ #else - #if __APPLE__ + #if defined(__APPLE__) #undef STLAB_TASK_SYSTEM_PRIVATE_LIBDISPATCH #define STLAB_TASK_SYSTEM_PRIVATE_LIBDISPATCH() 1 - #elif __EMSCRIPTEN__ + #elif defined(__EMSCRIPTEN__) - #undef STLAB_TASK_SYSTEM_PRIVATE_EMSCRIPTEN - #define STLAB_TASK_SYSTEM_PRIVATE_EMSCRIPTEN() 1 + #if defined(__EMSCRIPTEN_PTHREADS__) - #elif __pnacl__ + #undef STLAB_TASK_SYSTEM_PRIVATE_PORTABLE + #define STLAB_TASK_SYSTEM_PRIVATE_PORTABLE() 1 + + #else + + #undef STLAB_TASK_SYSTEM_PRIVATE_EMSCRIPTEN + #define STLAB_TASK_SYSTEM_PRIVATE_EMSCRIPTEN() 1 + + #endif + + #elif defined(__pnacl__) #undef STLAB_TASK_SYSTEM_PRIVATE_PNACL #define STLAB_TASK_SYSTEM_PRIVATE_PNACL() 1 - #elif _MSC_VER + #elif defined(_MSC_VER) #undef STLAB_TASK_SYSTEM_PRIVATE_WINDOWS #define STLAB_TASK_SYSTEM_PRIVATE_WINDOWS() 1 #else - - #undef STLAB_TASK_SYSTEM_PRIVATE_PORTABLE - #define STLAB_TASK_SYSTEM_PRIVATE_PORTABLE() 1 - + #if defined(__has_include) + #if __has_include() + #undef STLAB_TASK_SYSTEM_PRIVATE_LIBDISPATCH + #define STLAB_TASK_SYSTEM_PRIVATE_LIBDISPATCH() 1 + #else + #undef STLAB_TASK_SYSTEM_PRIVATE_PORTABLE + #define STLAB_TASK_SYSTEM_PRIVATE_PORTABLE() 1 + #endif + #else + #undef STLAB_TASK_SYSTEM_PRIVATE_PORTABLE + #define STLAB_TASK_SYSTEM_PRIVATE_PORTABLE() 1 + #endif #endif #endif diff --git a/stlab/concurrency/future.hpp b/stlab/concurrency/future.hpp index 0a8d75282..16d98abd7 100755 --- a/stlab/concurrency/future.hpp +++ b/stlab/concurrency/future.hpp @@ -80,6 +80,17 @@ inline const char* Future_error_map( /**************************************************************************************************/ +// This could be lifted into a common header if needed in other places +#if __cplusplus < 201703L +template +using result_t = std::result_of_t; +#else +template +using result_t = std::invoke_result_t; +#endif + +/**************************************************************************************************/ + } // namespace detail /**************************************************************************************************/ @@ -131,12 +142,12 @@ struct result_of_when_all_t; template struct result_of_when_all_t { - using result_type = std::invoke_result_t; + using result_type = detail::result_t; }; template struct result_of_when_all_t { - using result_type = std::invoke_result_t&>; + using result_type = detail::result_t&>; }; template @@ -144,12 +155,12 @@ struct result_of_when_any_t; template struct result_of_when_any_t { - using result_type = std::invoke_result_t; + using result_type = detail::result_t; }; template struct result_of_when_any_t { - using result_type = std::invoke_result_t; + using result_type = detail::result_t; }; template @@ -292,7 +303,7 @@ struct shared_base> : std::enable_shared_from_this auto recover(E executor, F&& f) { - auto p = package>()>( + auto p = package>()>( executor, [_f = std::forward(f), _p = future(this->shared_from_this())]() mutable { return std::move(_f)(std::move(_p)); }); @@ -329,7 +340,7 @@ struct shared_base> : std::enable_shared_from_this(executor), std::forward(f)); - auto p = package>()>( + auto p = package>()>( executor, [_f = std::forward(f), _p = future(this->shared_from_this())]() mutable { return _f(std::move(_p)); }); @@ -453,7 +464,7 @@ struct shared_base> : std::enable_shared_from_this< template auto recover_r(bool, E executor, F&& f) { // rvalue case unique is assumed. - auto p = package>()>( + auto p = package>()>( executor, [_f = std::forward(f), _p = future(this->shared_from_this())]() { return _f(std::move(_p)); }); @@ -556,7 +567,7 @@ struct shared_base : std::enable_shared_from_this> { } template - auto recover(E&& executor, F&& f) -> future>>>; + auto recover(E&& executor, F&& f) -> future>>>; template auto recover_r(bool, F&& f) { @@ -710,7 +721,7 @@ class packaged_task { /**************************************************************************************************/ template -class [[nodiscard]] future> { +class STLAB_NODISCARD() future> { using ptr_t = std::shared_ptr>; ptr_t _p; @@ -846,7 +857,7 @@ class [[nodiscard]] future> { /**************************************************************************************************/ template <> -class [[nodiscard]] future { +class STLAB_NODISCARD() future { using ptr_t = std::shared_ptr>; ptr_t _p; @@ -980,7 +991,7 @@ class [[nodiscard]] future { /**************************************************************************************************/ template -class [[nodiscard]] future> { +class STLAB_NODISCARD() future> { using ptr_t = std::shared_ptr>; ptr_t _p; @@ -1131,7 +1142,7 @@ struct when_all_shared { void done(FF&& f) { auto run{ false }; { - std::unique_lock lock{ _guard }; + std::unique_lock lock{ _guard }; if (!_exception) { assign_ready_future::assign(std::get(_args), std::forward(f)); if (--_remaining == 0) run = true; @@ -1143,7 +1154,7 @@ struct when_all_shared { void failure(std::exception_ptr error) { auto run{ false }; { - std::unique_lock lock{ _guard }; + std::unique_lock lock{ _guard }; if (!_exception) { for (auto& h : _holds) h.reset(); @@ -1170,7 +1181,7 @@ struct when_any_shared { void failure(std::exception_ptr error) { auto run{ false }; { - std::unique_lock lock{ _guard }; + std::unique_lock lock{ _guard }; if (--_remaining == 0) { _exception = std::move(error); run = true; @@ -1183,7 +1194,7 @@ struct when_any_shared { void done(FF&& f) { auto run{ false }; { - std::unique_lock lock{ _guard }; + std::unique_lock lock{ _guard }; if (_index == std::numeric_limits::max()) { _arg = std::move(*std::forward(f).get_try()); _index = index; @@ -1212,7 +1223,7 @@ struct when_any_shared { void failure(std::exception_ptr error) { auto run{ false }; - std::unique_lock lock{ _guard }; + std::unique_lock lock{ _guard }; { if (--_remaining == 0) { _exception = std::move(error); @@ -1226,7 +1237,7 @@ struct when_any_shared { void done(FF&&) { auto run{ false }; { - std::unique_lock lock{ _guard }; + std::unique_lock lock{ _guard }; if (_index == std::numeric_limits::max()) { _index = index; run = true; @@ -1275,13 +1286,13 @@ void attach_when_arg_(E&& executor, std::shared_ptr

& p, T a) { auto p = _w.lock(); if (!p) return; - if (auto ex = x.exception(); ex) { + if (auto ex = x.exception()) { p->failure(ex); } else { p->template done(std::move(x)); } }); - std::unique_lock lock{ p->_guard }; + std::unique_lock lock{ p->_guard }; p->_holds[i] = std::move(holds); } @@ -1322,7 +1333,7 @@ template struct make_when_any { template static auto make(E executor, F f, future arg, future... args) { - using result_t = std::invoke_result_t; + using result_t = detail::result_t; auto shared = std::make_shared>(); auto p = package(executor, [_f = std::move(f), _p = shared] { @@ -1342,7 +1353,7 @@ template <> struct make_when_any { template static auto make(E executor, F&& f, future... args) { - using result_t = std::invoke_result_t; + using result_t = detail::result_t; auto shared = std::make_shared>(); auto p = package(executor, [_f = std::forward(f), _p = shared] { @@ -1479,7 +1490,7 @@ struct single_trigger { static bool go(C& context, F&& f, size_t index) { auto run{ false }; { - std::unique_lock lock{ context._guard }; + std::unique_lock lock{ context._guard }; if (!context._single_event) { for (auto i = 0u; i < context._holds.size(); ++i) { if (i != index) context._holds[i].reset(); @@ -1504,7 +1515,7 @@ struct all_trigger { static bool go(C& context, F&& f, size_t index) { auto run{ false }; { - std::unique_lock lock{ context._guard }; + std::unique_lock lock{ context._guard }; context.apply(std::forward(f), index); if (--context._remaining == 0) run = true; } @@ -1515,7 +1526,7 @@ struct all_trigger { static bool go(C& context, std::exception_ptr error, size_t index) { auto run{ false }; { - std::unique_lock lock{ context._guard }; + std::unique_lock lock{ context._guard }; if (--context._remaining == 0) { context.apply(std::move(error), index); run = true; @@ -1559,14 +1570,14 @@ void attach_tasks(size_t index, E executor, const std::shared_ptr& context, T auto&& hold = std::forward(a).recover(std::move(executor), [_context = make_weak_ptr(context), _i = index](auto x) { auto p = _context.lock(); if (!p) return; - if (auto ex = x.exception(); ex) { + if (auto ex = x.exception()) { p->failure(ex, _i); } else { p->done(std::move(x), _i); } }); - std::unique_lock guard(context->_guard); + std::unique_lock guard(context->_guard); context->_holds[index] = std::move(hold); } @@ -1672,8 +1683,8 @@ auto when_any(E executor, F&& f, std::pair range) { template auto async(E executor, F&& f, Args&&... args) - -> future, std::decay_t...>> { - using result_type = std::invoke_result_t, std::decay_t...>; + -> future, std::decay_t...>> { + using result_type = detail::result_t, std::decay_t...>; auto p = package( executor, std::bind( @@ -1785,7 +1796,7 @@ struct value_> { sb._reduction_helper.value = std::move(*sb._result) .recover([_p = sb.shared_from_this()](future f) { - if (auto ex = std::move(f).exception(); ex) { + if (auto ex = std::move(f).exception()) { _p->_exception = ex; proceed(*_p); throw future_error(future_error_codes::reduction_failed); @@ -1840,8 +1851,8 @@ void shared_base::set_value(F& f, Args&&... args) { template auto shared_base::recover(E&& executor, F&& f) - -> future>>> { - auto p = package>()>( + -> future>>> { + auto p = package>()>( executor, [_f = std::forward(f), _p = future(this->shared_from_this())]() mutable { return _f(_p); }); diff --git a/stlab/concurrency/optional.hpp b/stlab/concurrency/optional.hpp index 2efcf91e5..eb087f96c 100644 --- a/stlab/concurrency/optional.hpp +++ b/stlab/concurrency/optional.hpp @@ -27,7 +27,13 @@ #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_STD() #elif __has_include() #include - #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_STD_EXPERIMENTAL() + #if defined(__cpp_lib_experimental_optional) + #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_STD_EXPERIMENTAL() + #else + #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_BOOST() + #endif + #else + #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_BOOST() #endif #else #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_BOOST() diff --git a/stlab/concurrency/task.hpp b/stlab/concurrency/task.hpp index 274bfb26e..6e478f1f7 100644 --- a/stlab/concurrency/task.hpp +++ b/stlab/concurrency/task.hpp @@ -37,18 +37,19 @@ class task; template class task { - template - constexpr static auto is_empty(const F& f){ - if constexpr (std::is_pointer>::value || + template + constexpr static bool maybe_empty = std::is_pointer>::value || std::is_member_pointer>::value || - std::is_same, std::decay_t>::value) - { - return !f; - } - else - { - return false; - } + std::is_same, std::decay_t>::value; + + template + constexpr static auto is_empty(const F& f) -> std::enable_if_t, bool> { + return !f; + } + + template + constexpr static auto is_empty(const F&) -> std::enable_if_t, bool> { + return false; } struct concept_t { diff --git a/stlab/concurrency/utility.hpp b/stlab/concurrency/utility.hpp index 7b1862221..97a74a009 100644 --- a/stlab/concurrency/utility.hpp +++ b/stlab/concurrency/utility.hpp @@ -165,7 +165,7 @@ inline void blocking_get(future x) { std::condition_variable condition; std::mutex m; auto hold = std::move(x).recover(immediate_executor, [&](auto&& r) { - if (auto ex = std::forward(r).exception(); ex) error = ex; + if (auto ex = std::forward(r).exception()) error = ex; { std::unique_lock lock(m); flag = true; @@ -190,7 +190,7 @@ inline bool blocking_get(future x, const std::chrono::nanoseconds& timeout if (!state) { return; } - if (auto ex = r.exception(); ex) state->error = ex; + if (auto ex = r.exception()) state->error = ex; { std::unique_lock lock(state->m); state->flag = true; diff --git a/stlab/concurrency/variant.hpp b/stlab/concurrency/variant.hpp index 69247f176..4730af5c2 100644 --- a/stlab/concurrency/variant.hpp +++ b/stlab/concurrency/variant.hpp @@ -24,6 +24,8 @@ #if __has_include() && STLAB_CPP_VERSION_AT_LEAST(17) #include #define STLAB_VARIANT_PRIVATE_SELECTION() STLAB_VARIANT_PRIVATE_STD() + #else + #define STLAB_VARIANT_PRIVATE_SELECTION() STLAB_VARIANT_PRIVATE_BOOST() #endif #else #define STLAB_VARIANT_PRIVATE_SELECTION() STLAB_VARIANT_PRIVATE_BOOST() diff --git a/stlab/forest_algorithms.hpp b/stlab/forest_algorithms.hpp index 3a73fd101..e463d5028 100644 --- a/stlab/forest_algorithms.hpp +++ b/stlab/forest_algorithms.hpp @@ -72,7 +72,7 @@ struct transcribe_iterator { template auto transcriber(Container& c) { - return transcribe_iterator(c, c.begin()); + return transcribe_iterator(c, c.begin()); } /**************************************************************************************************/ @@ -115,7 +115,7 @@ auto flatten(I first, I last, O out) { if (is_leading(first)) { *out++ = *first; } else { - *out++ = std::nullopt; + *out++ = nullopt; } } return out; diff --git a/test/channel_tests.cpp b/test/channel_tests.cpp index 4d417de69..9e2c5075a 100755 --- a/test/channel_tests.cpp +++ b/test/channel_tests.cpp @@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(int_channel_with_2_sized_buffer) { auto receive = channel(q.executor()); queue valuesInFlight; - generator myGenerator(valuesInFlight); + generator> myGenerator(valuesInFlight); echo myEcho; auto r2 = move(receive) | ref(myGenerator) | @@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(int_channel_with_3_sized_buffer) { auto receive = channel(q.executor()); queue valuesInFlight; - generator myGenerator(valuesInFlight); + generator> myGenerator(valuesInFlight); echo myEcho; auto r2 = move(receive) | ref(myGenerator) | @@ -454,12 +454,13 @@ BOOST_AUTO_TEST_CASE(int_channel_with_split_different_sized_buffer) { queue valuesInFlight1; queue valuesInFlight2; - generator myGenerator1(valuesInFlight1); - generator myGenerator2(valuesInFlight2); + generator> myGenerator1(valuesInFlight1); + generator> myGenerator2(valuesInFlight2); auto receive = channel(q.executor()); - auto g = move(receive) | generator(valuesInFlight1, valuesInFlight2); + auto g = + move(receive) | generator, queue>(valuesInFlight1, valuesInFlight2); auto r1 = g | (buffer_size{ bs.first } &echo()) | [&valuesInFlight1](auto x) { BOOST_REQUIRE_EQUAL(x, valuesInFlight1.front()); diff --git a/test/executor_test.cpp b/test/executor_test.cpp index a48c1cc1e..79d19a899 100644 --- a/test/executor_test.cpp +++ b/test/executor_test.cpp @@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(all_low_prio_tasks_are_executed) { for (auto i = 0; i < 10; ++i) { queue.executor()([_i = i, &m, &results] { - unique_lock block{m}; + unique_lock block{m}; results.push_back(_i); }); } @@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE(all_default_prio_tasks_get_executed) { for (auto i = 0; i < 10; ++i) { queue.executor()([_i = i, &m, &results] { - unique_lock block{m}; + unique_lock block{m}; results.push_back(_i); }); } @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(all_high_prio_tasks_get_executed) { for (auto i = 0; i < 10; ++i) { queue.executor()([_i = i, &m, &results] { - unique_lock block{m}; + unique_lock block{m}; results.push_back(_i); }); } @@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(task_system_restarts_after_it_went_pending) { default_executor([&]{ rest(); { - unique_lock block{m}; + unique_lock block{m}; done = true; } cv.notify_one(); @@ -161,7 +161,7 @@ BOOST_AUTO_TEST_CASE(task_system_restarts_after_it_went_pending) { { - unique_lock block{m}; + unique_lock block{m}; while (!done) { cv.wait(block); } @@ -170,14 +170,14 @@ BOOST_AUTO_TEST_CASE(task_system_restarts_after_it_went_pending) { default_executor([&] { rest(); { - unique_lock block{m}; + unique_lock block{m}; done = false; cv.notify_one(); } }); { - unique_lock block{m}; + unique_lock block{m}; while (done) { cv.wait(block); } @@ -191,7 +191,7 @@ namespace auto fiboN{ 1000 }; const auto iterations = 100'000; const auto startCount = 100; - atomic_int workToDo = (iterations - startCount) * 3; + atomic_int workToDo{(iterations - startCount) * 3}; const auto expectedWork = startCount * 3 + workToDo; atomic_int highCount{0}; atomic_int defaultCount{0}; @@ -218,17 +218,27 @@ namespace ++_currentPrioCount; } + template + auto schedule_increment() -> std::enable_if_t { + return static_cast(highCount <= taskRunning && defaultCount <= taskRunning); + } + + template + auto schedule_increment() -> std::enable_if_t { + return static_cast(highCount <= taskRunning); + } + + template + auto schedule_increment() -> std::enable_if_t { + return 0; + } + void operator()() { --_currentPrioCount; ++taskRunning; - if constexpr (P == stlab::detail::executor_priority::low) - _correctScheduleCount += static_cast(highCount <= taskRunning && defaultCount <= taskRunning); - - if constexpr (P == stlab::detail::executor_priority::medium) { - _correctScheduleCount += static_cast(highCount <= taskRunning); - } + _correctScheduleCount += schedule_increment

(); fibonacci(fiboN); @@ -279,7 +289,7 @@ BOOST_AUTO_TEST_CASE(MeasureTiming) { std::vector results; const auto iterations = 300'000; results.resize(iterations * 3); - atomic_bool done = false; + atomic_bool done{false}; condition_variable ready; atomic_int counter{0}; @@ -306,7 +316,7 @@ BOOST_AUTO_TEST_CASE(MeasureTiming) { mutex block; low_executor([&] { { - unique_lock lock{block}; + unique_lock lock{block}; done = true; ready.notify_one(); @@ -314,7 +324,7 @@ BOOST_AUTO_TEST_CASE(MeasureTiming) { }); - unique_lock lock{block}; + unique_lock lock{block}; while (!done) ready.wait(lock); auto stop = std::chrono::high_resolution_clock::now(); diff --git a/test/forest_test.cpp b/test/forest_test.cpp index ef99b70d5..cb3f5a12f 100644 --- a/test/forest_test.cpp +++ b/test/forest_test.cpp @@ -129,7 +129,7 @@ auto to_string(const std::string& x) { } template <> -auto to_string(const std::optional& x) { +auto to_string(const stlab::optional& x) { return x ? to_string(*x) : "?"; } @@ -285,12 +285,13 @@ BOOST_AUTO_TEST_CASE(child_traversal) { BOOST_CHECK(to_string(child_range(parent)) == expected); - if constexpr (false) { // I'm not sure reverse_child_iterator ever worked. + #if 0 + // I'm not sure reverse_child_iterator ever worked. forest::reverse_child_iterator first{child_begin(parent)}; forest::reverse_child_iterator last{child_end(parent)}; std::string result{to_string(first, last)}; BOOST_CHECK(result == expected); - } + #endif } /**************************************************************************************************/ @@ -460,7 +461,7 @@ BOOST_AUTO_TEST_CASE(test_transcribe_forest) { BOOST_AUTO_TEST_CASE(test_flatten) { auto f1{big_test_forest()}; - std::vector> flat; + std::vector> flat; forests::flatten(f1.begin(), f1.end(), std::back_inserter(flat)); diff --git a/test/future_recover_tests.cpp b/test/future_recover_tests.cpp index cea68f52a..20c3e77f8 100644 --- a/test/future_recover_tests.cpp +++ b/test/future_recover_tests.cpp @@ -899,9 +899,8 @@ BOOST_AUTO_TEST_CASE(future_recover_int_with_broken_promise) { { auto check{false}; sut = [&check]() { - auto [promise, future]{package(immediate_executor, [](int x) { return x; })}; - (void)promise; - return future.recover([&check](const auto& f) { + auto p{package(immediate_executor, [](int x) { return x; })}; + return p.second.recover([&check](const auto& f) { check = true; try { return *f.get_try(); @@ -917,9 +916,8 @@ BOOST_AUTO_TEST_CASE(future_recover_int_with_broken_promise) { { auto check{false}; sut = [&check]() { - auto [promise, future]{package(immediate_executor, [](int x) { return x; })}; - (void)promise; - return future ^ [&check](const auto& f) { + auto p{package(immediate_executor, [](int x) { return x; })}; + return p.second ^ [&check](const auto& f) { check = true; try { return *f.get_try(); @@ -1158,10 +1156,9 @@ BOOST_AUTO_TEST_CASE(future_recover_move_only_with_broken_promise) { { auto check{false}; sut = [&check]() { - auto [promise, future]{ + auto p{ package(immediate_executor, [](move_only x) { return x; })}; - (void)promise; - return std::move(future).recover([&check](auto f) { + return std::move(p.second).recover([&check](auto f) { check = true; try { return *std::move(f.get_try()); @@ -1177,10 +1174,9 @@ BOOST_AUTO_TEST_CASE(future_recover_move_only_with_broken_promise) { { auto check{false}; sut = [&check]() { - auto [promise, future]{ + auto p{ package(immediate_executor, [](move_only x) { return x; })}; - (void)promise; - return std::move(future) ^ [&check](auto f) { + return std::move(p.second) ^ [&check](auto f) { check = true; try { return *std::move(f.get_try()); diff --git a/test/future_tests.cpp b/test/future_tests.cpp index a4dca9750..a9951c23d 100644 --- a/test/future_tests.cpp +++ b/test/future_tests.cpp @@ -537,9 +537,8 @@ BOOST_AUTO_TEST_CASE(future_int_detach_without_execution) { annotate_counters counter; bool check = true; { - auto [promise, future] = package(immediate_executor, [] { return 42; }); - future.then([a = annotate(counter), &_check = check](int) { _check = false; }).detach(); - (void)promise; + auto p = package(immediate_executor, [] { return 42; }); + p.second.then([a = annotate(counter), &_check = check](int) { _check = false; }).detach(); } std::cout << counter; @@ -552,10 +551,9 @@ BOOST_AUTO_TEST_CASE(future_move_only_detach_without_execution) { annotate_counters counter; bool check = true; { - auto [promise, future] = package(immediate_executor, [] { return move_only{42}; }); - auto r = std::move(future).then([a = annotate(counter), &_check = check](auto&&) { _check = false; }); + auto p = package(immediate_executor, [] { return move_only{42}; }); + auto r = std::move(p.second).then([a = annotate(counter), &_check = check](auto&&) { _check = false; }); r.detach(); - (void)promise; } std::cout << counter; @@ -568,9 +566,8 @@ BOOST_AUTO_TEST_CASE(future_void_detach_without_execution) { annotate_counters counter; bool check = true; { - auto [promise, future] = package(immediate_executor, [] {}); - future.then([a = annotate(counter), &_check = check]() { _check = false; }).detach(); - (void)promise; + auto p = package(immediate_executor, [] {}); + p.second.then([a = annotate(counter), &_check = check]() { _check = false; }).detach(); } std::cout << counter; From 787f1b5208d4d8d82cca2ca348cae3075d22bbaa Mon Sep 17 00:00:00 2001 From: Felix Petriconi Date: Tue, 2 Feb 2021 22:45:39 +0100 Subject: [PATCH 02/10] Fix compile issue in C++14 on Visual Studio 2017 and 2019 --- test/channel_functor_tests.cpp | 37 ++-- test/channel_merge_round_robin_tests.cpp | 59 +++-- test/channel_merge_unordered_tests.cpp | 47 ++-- test/channel_merge_zip_with_tests.cpp | 75 ++++--- test/channel_process_tests.cpp | 89 ++++---- test/channel_test_helper.hpp | 2 + test/channel_tests.cpp | 264 +++++++++++------------ 7 files changed, 282 insertions(+), 291 deletions(-) diff --git a/test/channel_functor_tests.cpp b/test/channel_functor_tests.cpp index cefb921c7..c454428ac 100644 --- a/test/channel_functor_tests.cpp +++ b/test/channel_functor_tests.cpp @@ -17,10 +17,9 @@ #include "channel_test_helper.hpp" -using namespace stlab; -using namespace channel_test_helper; -using channel_test_fixture_int_1 = channel_test_fixture; + +using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_SUITE(int_channel_void_functor, channel_test_fixture_int_1) @@ -148,20 +147,22 @@ BOOST_AUTO_TEST_CASE(int_channel_split_int_functor_async) { BOOST_AUTO_TEST_SUITE_END() -using channel_test_fixture_move_only_1 = channel_test_fixture; + +using channel_test_fixture_move_only_1 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_SUITE(move_only_channel_void_functor, channel_test_fixture_move_only_1) + BOOST_AUTO_TEST_CASE(move_only_int_channel_void_functor) { BOOST_TEST_MESSAGE("move only int channel void functor"); std::atomic_int result{0}; - auto check = _receive[0] | [&](move_only x) { result += x.member(); }; + auto check = _receive[0] | [&](stlab::move_only x) { result += x.member(); }; _receive[0].set_ready(); for (int i = 0; i < 10; ++i) { - _send[0](move_only(1)); + _send[0](stlab::move_only(1)); } wait_until_done([&]() { return result == 10; }); @@ -173,13 +174,13 @@ BOOST_AUTO_TEST_CASE(move_only_int_channel_void_functor_async) { std::atomic_int result{0}; - auto check = _receive[0] | [&](move_only x) { result += x.member(); }; + auto check = _receive[0] | [&](stlab::move_only x) { result += x.member(); }; _receive[0].set_ready(); - std::vector> f; + std::vector> f; f.reserve(10); for (int i = 0; i < 10; ++i) { - f.push_back(async(default_executor, [& _send = _send[0]] { _send(move_only(1)); })); + f.push_back(stlab::async(stlab::default_executor, [& _send = _send[0]] { _send(stlab::move_only(1)); })); } wait_until_done([&]() { return result == 10; }); @@ -191,12 +192,12 @@ BOOST_AUTO_TEST_CASE(move_only_int_channel_int_functor) { std::atomic_int result{0}; - auto check = _receive[0] | [](move_only x) { return move_only(2 * x.member()); } | - [&](move_only x) { result += x.member(); }; + auto check = _receive[0] | [](stlab::move_only x) { return stlab::move_only(2 * x.member()); } | + [&](stlab::move_only x) { result += x.member(); }; _receive[0].set_ready(); for (int i = 0; i < 10; ++i) { - _send[0](move_only(1)); + _send[0](stlab::move_only(1)); } wait_until_done([&]() { return result >= 20; }); @@ -204,19 +205,20 @@ BOOST_AUTO_TEST_CASE(move_only_int_channel_int_functor) { BOOST_REQUIRE_EQUAL(20, result); } + BOOST_AUTO_TEST_CASE(move_only_int_channel_int_functor_async) { BOOST_TEST_MESSAGE("move only int channel int functor asynchronously"); std::atomic_int result{0}; - auto check = _receive[0] | [](move_only x) { return move_only(2 * x.member()); } | - [&](move_only x) { result += x.member(); }; + auto check = _receive[0] | [](stlab::move_only x) { return stlab::move_only(2 * x.member()); } | + [&](stlab::move_only x) { result += x.member(); }; _receive[0].set_ready(); - std::vector> f; + std::vector> f; f.reserve(10); for (int i = 0; i < 10; ++i) { - f.push_back(async(default_executor, [& _send = _send[0]] { _send(move_only(1)); })); + f.push_back(stlab::async(stlab::default_executor, [& _send = _send[0]] { _send(stlab::move_only(1)); })); } wait_until_done([&]() { return result >= 20; }); @@ -224,4 +226,5 @@ BOOST_AUTO_TEST_CASE(move_only_int_channel_int_functor_async) { BOOST_REQUIRE_EQUAL(20, result); } -BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/channel_merge_round_robin_tests.cpp b/test/channel_merge_round_robin_tests.cpp index fc8a233eb..08e2a2245 100644 --- a/test/channel_merge_round_robin_tests.cpp +++ b/test/channel_merge_round_robin_tests.cpp @@ -16,17 +16,14 @@ #include "channel_test_helper.hpp" -using namespace stlab; -using namespace channel_test_helper; - -using channel_test_fixture_int_1 = channel_test_fixture; +using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_one_value, channel_test_fixture_int_1) { BOOST_TEST_MESSAGE("int merge round robin channel void functor one value one value"); std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result = x; }, _receive[0]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result = x; }, _receive[0]); _receive[0].set_ready(); _send[0](1); @@ -41,10 +38,10 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_one_value_asy std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result = x; }, _receive[0]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result = x; }, _receive[0]); _receive[0].set_ready(); - auto f = async(default_executor, [_sender = _send[0]] { _sender(1); }); + auto f = stlab::async(stlab::default_executor, [_sender = _send[0]] { _sender(1); }); wait_until_done([&]() { return result != 0; }); @@ -56,7 +53,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_many_values, std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0]); _receive[0].set_ready(); for (auto i = 1; i <= 100; ++i) @@ -75,12 +72,12 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_many_values_a std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0]); _receive[0].set_ready(); - std::vector> f(100); + std::vector> f(100); for (auto i = 1; i <= 100; ++i) { - f.push_back(async(default_executor, [_sender = _send[0], i] { _sender(i); })); + f.push_back(stlab::async(stlab::default_executor, [_sender = _send[0], i] { _sender(i); })); } auto expected = 100 * (100 + 1) / 2; @@ -89,7 +86,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_many_values_a BOOST_REQUIRE_EQUAL(expected, result); } -using channel_test_fixture_int_2 = channel_test_fixture; +using channel_test_fixture_int_2 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_one_value, channel_test_fixture_int_2) { @@ -97,7 +94,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_one std::atomic_int result{0}; int incrementer{1}; - auto check = merge_channel(default_executor, + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += incrementer * x; ++incrementer; @@ -121,7 +118,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_one std::atomic_int result{0}; int incrementer{1}; - auto check = merge_channel(default_executor, + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += incrementer * x; ++incrementer; @@ -131,7 +128,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_one _receive[0].set_ready(); _receive[1].set_ready(); auto f = - async(default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference + stlab::async(stlab::default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference _send1(2); _send2(3); }); @@ -148,7 +145,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man std::atomic_int result{0}; int incrementer{1}; - auto check = merge_channel(default_executor, + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += incrementer * x; ++incrementer; @@ -170,7 +167,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man BOOST_REQUIRE_EQUAL(expectation, result); } -using channel_test_fixture_pair_2 = channel_test_fixture, 5>; +using channel_test_fixture_pair_2 = channel_test_helper::channel_test_fixture, 5>; BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_many_values_async, channel_test_fixture_pair_2) { @@ -180,7 +177,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man std::atomic_bool zipped_ok{true}; std::size_t expected_input{0}; - auto check = merge_channel(default_executor, + auto check = stlab::merge_channel(stlab::default_executor, [&](std::pair x) { result += x.first; zipped_ok = zipped_ok && (x.second == expected_input); @@ -190,12 +187,12 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man _receive[0].set_ready(); _receive[1].set_ready(); - std::vector> f(200); + std::vector> f(200); for (auto i = 1; i <= 200; i += 2) { - f.push_back(async(default_executor, [& _send1 = _send[0], _i = i] { + f.push_back(stlab::async(stlab::default_executor, [& _send1 = _send[0], _i = i] { _send1(std::make_pair(_i, std::size_t(0))); })); - f.push_back(async(default_executor, [& _send2 = _send[1], _i = i] { + f.push_back(stlab::async(stlab::default_executor, [& _send2 = _send[1], _i = i] { _send2(std::make_pair(_i + 1, std::size_t(1))); })); } @@ -208,7 +205,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man BOOST_REQUIRE_EQUAL(expectation, result); } -using channel_test_fixture_int_5 = channel_test_fixture; +using channel_test_fixture_int_5 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor, channel_test_fixture_int_5) { BOOST_TEST_MESSAGE("int merge round robin channel same type void functor"); @@ -216,12 +213,12 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor, ch std::atomic_int result{0}; std::atomic_int incrementer{1}; - auto check = merge_channel(default_executor, - [&](int x) { - result += incrementer * x; - ++incrementer; - }, - _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]); + auto check = stlab::merge_channel(stlab::default_executor, + [&](int x) { + result += incrementer * x; + ++incrementer; + }, + _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]); for (auto& r : _receive) r.set_ready(); @@ -242,7 +239,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_asy std::atomic_int result{0}; std::atomic_int incrementer{1}; - auto check = merge_channel(default_executor, + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += incrementer * x; ++incrementer; @@ -252,9 +249,9 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_asy for (auto& r : _receive) r.set_ready(); - std::vector> f(5); + std::vector> f(5); for (auto i = 0; i < 5; i++) { - f.push_back(async(default_executor, [_send = _send[i], _i = i] { _send(_i + 2); })); + f.push_back(stlab::async(stlab::default_executor, [_send = _send[i], _i = i] { _send(_i + 2); })); } const auto expected = 2 * 1 + 3 * 2 + 4 * 3 + 5 * 4 + 6 * 5; diff --git a/test/channel_merge_unordered_tests.cpp b/test/channel_merge_unordered_tests.cpp index bc5f35734..aad8ef7bc 100644 --- a/test/channel_merge_unordered_tests.cpp +++ b/test/channel_merge_unordered_tests.cpp @@ -14,17 +14,14 @@ #include "channel_test_helper.hpp" -using namespace stlab; -using namespace channel_test_helper; - -using channel_test_fixture_int_1 = channel_test_fixture; +using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_one_value, channel_test_fixture_int_1) { BOOST_TEST_MESSAGE("int merge unordered_t channel void functor one value one value"); std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result = x; }, _receive[0]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result = x; }, _receive[0]); _receive[0].set_ready(); _send[0](1); @@ -40,10 +37,10 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_one_value_async std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result = x; }, _receive[0]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result = x; }, _receive[0]); _receive[0].set_ready(); - auto f = async(default_executor, [_sender = _send[0]] { _sender(1); }); + auto f = stlab::async(stlab::default_executor, [_sender = _send[0]] { _sender(1); }); wait_until_done([&] { return result != 0; }); @@ -55,7 +52,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_many_values, ch std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0]); _receive[0].set_ready(); for (auto i = 1; i <= 100; ++i) @@ -74,12 +71,12 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_many_values_asy std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0]); _receive[0].set_ready(); - std::vector> f(100); + std::vector> f(100); for (auto i = 1; i <= 100; ++i) { - f.push_back(async(default_executor, [_sender = _send[0], i] { _sender(i); })); + f.push_back(stlab::async(stlab::default_executor, [_sender = _send[0], i] { _sender(i); })); } auto expected = 100 * (100 + 1) / 2; @@ -88,7 +85,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_many_values_asy BOOST_REQUIRE_EQUAL(expected, result); } -using channel_test_fixture_int_2 = channel_test_fixture; +using channel_test_fixture_int_2 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_one_value, channel_test_fixture_int_2) { @@ -96,7 +93,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_one_v std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]); _receive[0].set_ready(); _receive[1].set_ready(); @@ -114,12 +111,12 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_one_v std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]); _receive[0].set_ready(); _receive[1].set_ready(); auto f = - async(default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference + stlab::async(stlab::default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference _send1(2); _send2(3); }); @@ -135,7 +132,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_many_ std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]); _receive[0].set_ready(); _receive[1].set_ready(); @@ -157,14 +154,14 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_many_ std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]); + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]); _receive[0].set_ready(); _receive[1].set_ready(); - std::vector> f(20); + std::vector> f(20); for (auto i = 0; i < 10; i++) { - f.push_back(async(default_executor, [_send1 = _send[0], i] { _send1(i); })); - f.push_back(async(default_executor, [& _send2 = _send[1], i] { _send2(i + 1); })); + f.push_back(stlab::async(stlab::default_executor, [_send1 = _send[0], i] { _send1(i); })); + f.push_back(stlab::async(stlab::default_executor, [& _send2 = _send[1], i] { _send2(i + 1); })); } const auto expected = @@ -174,13 +171,13 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_many_ BOOST_REQUIRE_EQUAL(expected, result); } -using channel_test_fixture_int_5 = channel_test_fixture; +using channel_test_fixture_int_5 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor, channel_test_fixture_int_5) { BOOST_TEST_MESSAGE("int merge unordered_t channel same type void functor"); std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1], + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]); for (auto& r : _receive) @@ -202,15 +199,15 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_async std::atomic_int result{0}; - auto check = merge_channel(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1], + auto check = stlab::merge_channel(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]); for (auto& r : _receive) r.set_ready(); - std::vector> f(5); + std::vector> f(5); for (auto i = 0; i < 5; i++) { - f.push_back(async(default_executor, [_send = _send[i], i] { _send(i + 2); })); + f.push_back(stlab::async(stlab::default_executor, [_send = _send[i], i] { _send(i + 2); })); } const auto expectation = 2 + 3 + 4 + 5 + 6; diff --git a/test/channel_merge_zip_with_tests.cpp b/test/channel_merge_zip_with_tests.cpp index 699b4ff8a..dcf4bcb0f 100644 --- a/test/channel_merge_zip_with_tests.cpp +++ b/test/channel_merge_zip_with_tests.cpp @@ -15,17 +15,16 @@ #include "channel_test_helper.hpp" -using namespace stlab; -using namespace channel_test_helper; -using channel_test_fixture_int_1 = channel_test_fixture; + +using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_CASE(int_zip_with_channel_void_functor_one_value, channel_test_fixture_int_1) { BOOST_TEST_MESSAGE("int zip_with channel void functor one value one value"); std::atomic_int result{0}; - auto check = zip_with(default_executor, [&](int x) { result = x; }, _receive[0]); + auto check = zip_with(stlab::default_executor, [&](int x) { result = x; }, _receive[0]); _receive[0].set_ready(); _send[0](1); @@ -40,10 +39,10 @@ BOOST_FIXTURE_TEST_CASE(int_zip_with_channel_void_functor_one_value_async, chann std::atomic_int result{0}; - auto check = zip_with(default_executor, [&](int x) { result = x; }, _receive[0]); + auto check = stlab::zip_with(stlab::default_executor, [&](int x) { result = x; }, _receive[0]); _receive[0].set_ready(); - auto f = async(default_executor, [_sender = _send[0]] { _sender(1); }); + auto f = stlab::async(stlab::default_executor, [_sender = _send[0]] { _sender(1); }); wait_until_done([&]() { return result != 0; }); @@ -55,7 +54,7 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_void_functor_many_values, channel_ std::atomic_int result{0}; - auto check = zip_with(default_executor, [&](int x) { result += x; }, _receive[0]); + auto check = stlab::zip_with(stlab::default_executor, [&](int x) { result += x; }, _receive[0]); _receive[0].set_ready(); for (auto i = 1; i <= 100; ++i) @@ -74,12 +73,12 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_void_functor_many_values_async, std::atomic_int result{0}; - auto check = zip_with(default_executor, [&](int x) { result += x; }, _receive[0]); + auto check = stlab::zip_with(stlab::default_executor, [&](int x) { result += x; }, _receive[0]); _receive[0].set_ready(); - std::vector> f(100); + std::vector> f(100); for (auto i = 1; i <= 100; ++i) { - f.push_back(async(default_executor, [_sender = _send[0], _i = i] { _sender(_i); })); + f.push_back(stlab::async(stlab::default_executor, [_sender = _send[0], _i = i] { _sender(_i); })); } auto expected = 100 * (100 + 1) / 2; @@ -88,7 +87,7 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_void_functor_many_values_async, BOOST_REQUIRE_EQUAL(expected, result); } -using channel_test_fixture_int_2 = channel_test_fixture; +using channel_test_fixture_int_2 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_one_value, channel_test_fixture_int_2) { @@ -96,7 +95,7 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_one_value, std::atomic_int result{0}; - auto check = zip_with(default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0], + auto check = stlab::zip_with(stlab::default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0], _receive[1]); _receive[0].set_ready(); @@ -115,13 +114,13 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_one_value_a std::atomic_int result{0}; - auto check = zip_with(default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0], + auto check = stlab::zip_with(stlab::default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0], _receive[1]); _receive[0].set_ready(); _receive[1].set_ready(); auto f = - async(default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference + stlab::async(stlab::default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference _send1(2); _send2(3); }); @@ -137,7 +136,7 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_many_values std::atomic_int result{0}; - auto check = zip_with(default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0], + auto check = stlab::zip_with(stlab::default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0], _receive[1]); _receive[0].set_ready(); @@ -160,15 +159,15 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_many_values std::atomic_int result{0}; - auto check = zip_with(default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0], + auto check = zip_with(stlab::default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0], _receive[1]); _receive[0].set_ready(); _receive[1].set_ready(); - std::vector> f(20); + std::vector> f(20); for (auto i = 0; i < 10; i++) { - f.push_back(async(default_executor, [_send1 = _send[0], _i = i] { _send1(_i); })); - f.push_back(async(default_executor, [& _send2 = _send[1], _i = i] { _send2(_i + 1); })); + f.push_back(stlab::async(stlab::default_executor, [_send1 = _send[0], _i = i] { _send1(_i); })); + f.push_back(stlab::async(stlab::default_executor, [& _send2 = _send[1], _i = i] { _send2(_i + 1); })); } const auto expected = @@ -178,14 +177,14 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_many_values BOOST_REQUIRE_EQUAL(expected, result); } -using channel_test_fixture_int_5 = channel_test_fixture; +using channel_test_fixture_int_5 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor, channel_test_fixture_int_5) { BOOST_TEST_MESSAGE("int zip_with channel same type void functor"); std::atomic_int result{0}; auto check = zip_with( - default_executor, + stlab::default_executor, [&](int v, int w, int x, int y, int z) { result += 2 * v + 3 * w + 4 * x + 5 * y + 6 * z; }, _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]); @@ -207,17 +206,17 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_async, chan std::atomic_int result{0}; - auto check = zip_with( - default_executor, + auto check = stlab::zip_with( + stlab::default_executor, [&](int v, int w, int x, int y, int z) { result += 2 * v + 3 * w + 4 * x + 5 * y + 6 * z; }, _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]); for (auto& r : _receive) r.set_ready(); - std::vector> f(5); + std::vector> f(5); for (auto i = 0; i < 5; i++) { - f.push_back(async(default_executor, [_send = _send[i], _i = i] { _send(_i + 2); })); + f.push_back(stlab::async(stlab::default_executor, [_send = _send[i], _i = i] { _send(_i + 2); })); } wait_until_done([&]() { return result != 0; }); @@ -226,7 +225,7 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_async, chan BOOST_REQUIRE_EQUAL(expected, result); } -using channel_types_test_fixture_int_string = channel_types_test_fixture; +using channel_types_test_fixture_int_string = channel_test_helper::channel_types_test_fixture; BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_different_type_void_functor, channel_types_test_fixture_int_string) { @@ -234,9 +233,9 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_different_type_void_functor, std::atomic_int result{0}; - auto check = zip_with(default_executor, - [&](int, std::string y) { result += 2 + static_cast(y.size()); }, - receive<0>(), receive<1>()); + auto check = stlab::zip_with(stlab::default_executor, + [&](int, std::string y) { result += 2 + static_cast(y.size()); }, + receive<0>(), receive<1>()); receive<0>().set_ready(); receive<1>().set_ready(); @@ -254,14 +253,14 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_2_join_different_type_void_functor std::atomic_int result{0}; - auto check = zip_with(default_executor, + auto check = stlab::zip_with(stlab::default_executor, [&](int x, std::string y) { result += x + static_cast(y.size()); }, receive<0>(), receive<1>()); receive<0>().set_ready(); receive<1>().set_ready(); - auto f1 = async(default_executor, [_send = send<0>()] { _send(2); }); - auto f2 = async(default_executor, [_send = send<1>()] { _send("Foo"); }); + auto f1 = stlab::async(stlab::default_executor, [_send = send<0>()] { _send(2); }); + auto f2 = stlab::async(stlab::default_executor, [_send = send<1>()] { _send("Foo"); }); wait_until_done([&]() { return result != 0; }); @@ -274,15 +273,15 @@ BOOST_FIXTURE_TEST_CASE(int_zip_with_channel_2_different_type_void_functor_async std::atomic_int result{0}; - auto check = zip(default_executor, receive<0>(), receive<1>()) | - [&](std::tuple v) { - result += std::get<0>(v) + static_cast(std::get<1>(v).size()); - }; + auto check = stlab::zip(stlab::default_executor, receive<0>(), receive<1>()) | + [&](std::tuple v) { + result += std::get<0>(v) + static_cast(std::get<1>(v).size()); + }; receive<0>().set_ready(); receive<1>().set_ready(); - auto f1 = async(default_executor, [_send = send<0>()] { _send(2); }); - auto f2 = async(default_executor, [_send = send<1>()] { _send("Foo"); }); + auto f1 = stlab::async(stlab::default_executor, [_send = send<0>()] { _send(2); }); + auto f2 = stlab::async(stlab::default_executor, [_send = send<1>()] { _send("Foo"); }); wait_until_done([&]() { return result != 0; }); diff --git a/test/channel_process_tests.cpp b/test/channel_process_tests.cpp index 1d761b0a1..7f5a6b5bd 100644 --- a/test/channel_process_tests.cpp +++ b/test/channel_process_tests.cpp @@ -17,10 +17,7 @@ #include "channel_test_helper.hpp" -using namespace stlab; -using namespace channel_test_helper; - -using channel_test_fixture_int_1 = channel_test_fixture; +using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_SUITE(int_channel_process_void_functor, channel_test_fixture_int_1) @@ -30,7 +27,7 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_one_step) { std::atomic_int index{0}; std::vector results(10, 0); - auto check = _receive[0] | sum<1>() | [&](int x) { + auto check = _receive[0] | channel_test_helper::sum<1>() | [&](int x) { results[index] = x; ++index; }; @@ -52,15 +49,15 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_one_step_async) { std::atomic_int index{0}; std::vector results(10, 0); - auto check = _receive[0] | sum<1>() | [&](int x) { + auto check = _receive[0] | channel_test_helper::sum<1>() | [&](int x) { results[x] = x; ++index; }; _receive[0].set_ready(); - std::vector> f(10); + std::vector> f(10); for (auto i = 0; i < 10; ++i) { - f.push_back(async(default_executor, [_send = _send[0], i] { _send(i); })); + f.push_back(stlab::async(stlab::default_executor, [_send = _send[0], i] { _send(i); })); } wait_until_done([&] { return index == 10; }); @@ -76,7 +73,7 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_two_steps) { std::atomic_int index{0}; std::vector results(5, 0); - auto check = _receive[0] | sum<2>() | [&](int x) { + auto check = _receive[0] | channel_test_helper::sum<2>() | [&](int x) { results[index] = x; ++index; }; @@ -99,15 +96,15 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_two_steps_async) { std::atomic_int index{0}; std::vector> results; - auto check = _receive[0] | collector<2>() | [&](std::vector x) { + auto check = _receive[0] | channel_test_helper::collector<2>() | [&](std::vector x) { results.push_back(x); ++index; }; _receive[0].set_ready(); - std::vector> f(10); + std::vector> f(10); for (auto i = 0; i < 10; ++i) { - f.push_back(async(default_executor, [_send = _send[0], i] { _send(i); })); + f.push_back(stlab::async(stlab::default_executor, [_send = _send[0], i] { _send(i); })); } wait_until_done([&] { return index == 5; }); @@ -130,7 +127,7 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_many_steps) { std::atomic_int result{0}; - auto check = _receive[0] | sum<10>() | [&](int x) { result = x; }; + auto check = _receive[0] | channel_test_helper::sum<10>() | [&](int x) { result = x; }; _receive[0].set_ready(); for (auto i = 0; i < 10; ++i) @@ -146,12 +143,12 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_many_steps_async) { std::atomic_int result{0}; - auto check = _receive[0] | sum<10>() | [&](int x) { result = x; }; + auto check = _receive[0] | channel_test_helper::sum<10>() | [&](int x) { result = x; }; _receive[0].set_ready(); - std::vector> f(10); + std::vector> f(10); for (auto i = 0; i < 10; ++i) { - f.push_back(async(default_executor, [_send = _send[0], i] { _send(i); })); + f.push_back(stlab::async(stlab::default_executor, [_send = _send[0], i] { _send(i); })); } wait_until_done([&] { return result != 0; }); @@ -167,11 +164,11 @@ BOOST_AUTO_TEST_CASE(int_channel_split_process_one_step) { std::atomic_int index2{0}; std::vector results2(10, 0); - auto check1 = _receive[0] | sum<1>() | [& _index = index1, &_results = results1](int x) { + auto check1 = _receive[0] | channel_test_helper::sum<1>() | [& _index = index1, &_results = results1](int x) { _results[x] = x; ++_index; }; - auto check2 = _receive[0] | sum<1>() | [& _index = index2, &_results = results2](int x) { + auto check2 = _receive[0] | channel_test_helper::sum<1>() | [& _index = index2, &_results = results2](int x) { _results[x] = x; ++_index; }; @@ -196,11 +193,11 @@ BOOST_AUTO_TEST_CASE(int_channel_split_process_two_steps) { std::atomic_int index2{0}; std::vector results2(5); - auto check1 = _receive[0] | sum<2>() | [& _index = index1, &_results = results1](int x) { + auto check1 = _receive[0] | channel_test_helper::sum<2>() | [& _index = index1, &_results = results1](int x) { _results[_index] = x; ++_index; }; - auto check2 = _receive[0] | sum<2>() | [& _index = index2, &_results = results2](int x) { + auto check2 = _receive[0] | channel_test_helper::sum<2>() | [& _index = index2, &_results = results2](int x) { _results[_index] = x; ++_index; }; @@ -224,8 +221,8 @@ BOOST_AUTO_TEST_CASE(int_channel_split_process_many_steps) { std::atomic_int result1{0}; std::atomic_int result2{0}; - auto check1 = _receive[0] | sum<10>() | [& _result = result1](int x) { _result = x; }; - auto check2 = _receive[0] | sum<10>() | [& _result = result2](int x) { _result = x; }; + auto check1 = _receive[0] | channel_test_helper::sum<10>() | [& _result = result1](int x) { _result = x; }; + auto check2 = _receive[0] | channel_test_helper::sum<10>() | [& _result = result2](int x) { _result = x; }; _receive[0].set_ready(); for (auto i = 0; i < 10; ++i) @@ -242,26 +239,26 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_two_steps_timed) { BOOST_TEST_MESSAGE("int channel process with two steps timed"); std::atomic_int result{0}; - sender send; - receiver receive; + stlab::sender send; + stlab::receiver receive; - std::tie(send, receive) = channel(manual_scheduler()); + std::tie(send, receive) = stlab::channel(channel_test_helper::manual_scheduler()); - auto check = receive | timed_sum() | [&](int x) { result = x; }; + auto check = receive | channel_test_helper::timed_sum() | [&](int x) { result = x; }; receive.set_ready(); send(42); - manual_scheduler::run_next_task(); + channel_test_helper::manual_scheduler::run_next_task(); - manual_scheduler::wait_until_queue_size_of(1); - manual_scheduler::run_next_task(); + channel_test_helper::manual_scheduler::wait_until_queue_size_of(1); + channel_test_helper::manual_scheduler::run_next_task(); - manual_scheduler::wait_until_queue_size_of(1); - manual_scheduler::run_next_task(); + channel_test_helper::manual_scheduler::wait_until_queue_size_of(1); + channel_test_helper::manual_scheduler::run_next_task(); - manual_scheduler::wait_until_queue_size_of(1); - manual_scheduler::run_next_task(); + channel_test_helper::manual_scheduler::wait_until_queue_size_of(1); + channel_test_helper::manual_scheduler::run_next_task(); while (result == 0) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); @@ -274,17 +271,17 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_two_steps_timed_wo_timeout) { BOOST_TEST_MESSAGE("int channel process with two steps timed w/o timeout"); std::atomic_int result{0}; - sender send; - receiver receive; + stlab::sender send; + stlab::receiver receive; - std::tie(send, receive) = channel(default_executor); + std::tie(send, receive) = stlab::channel(stlab::default_executor); - auto check = receive | timed_sum(2) | [&](int x) { result = x; }; + auto check = receive | channel_test_helper::timed_sum(2) | [&](int x) { result = x; }; receive.set_ready(); send(42); - while (timed_sum::current_sum() != 42) { + while (channel_test_helper::timed_sum::current_sum() != 42) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } @@ -309,7 +306,7 @@ struct process_with_set_error { int yield() { return 42; } - auto state() const { return await_forever; } + auto state() const { return stlab::await_forever; } }; } // namespace @@ -317,10 +314,10 @@ BOOST_AUTO_TEST_CASE(int_channel_process_set_error_is_called_on_upstream_error) BOOST_TEST_MESSAGE("int channel process set_error is called on upstream error"); std::atomic_bool check{false}; - sender send; - receiver receive; + stlab::sender send; + stlab::receiver receive; - std::tie(send, receive) = channel(default_executor); + std::tie(send, receive) = stlab::channel(stlab::default_executor); auto result = receive | [](auto v) { @@ -351,7 +348,7 @@ struct process_with_close { int yield() { return 42; } - auto state() const { return await_forever; } + auto state() const { return stlab::await_forever; } }; } // namespace @@ -359,10 +356,10 @@ BOOST_AUTO_TEST_CASE(int_channel_process_close_is_called_on_upstream_error) { BOOST_TEST_MESSAGE("int channel process close is called when an upstream eeror happened"); std::atomic_bool check{false}; - sender send; - receiver receive; + stlab::sender send; + stlab::receiver receive; - std::tie(send, receive) = channel(default_executor); + std::tie(send, receive) = stlab::channel(stlab::default_executor); auto result = receive | [](auto v) { diff --git a/test/channel_test_helper.hpp b/test/channel_test_helper.hpp index 295c45ce2..29c8d1450 100644 --- a/test/channel_test_helper.hpp +++ b/test/channel_test_helper.hpp @@ -10,6 +10,7 @@ #define CHANNEL_TEST_HELPER #include + #include #include #include @@ -17,6 +18,7 @@ #include #include + using lock_t = std::unique_lock; namespace channel_test_helper { diff --git a/test/channel_tests.cpp b/test/channel_tests.cpp index 9e2c5075a..09bd0e66d 100755 --- a/test/channel_tests.cpp +++ b/test/channel_tests.cpp @@ -21,14 +21,10 @@ #include "channel_test_helper.hpp" -using namespace stlab; -using namespace std; -using namespace channel_test_helper; - BOOST_AUTO_TEST_CASE(int_sender) { BOOST_TEST_MESSAGE("int sender"); - sender send; + stlab::sender send; BOOST_REQUIRE_NO_THROW(send(42)); } @@ -36,7 +32,7 @@ BOOST_AUTO_TEST_CASE(int_sender) { BOOST_AUTO_TEST_CASE(int_receiver) { BOOST_TEST_MESSAGE("int receiver"); - receiver receive; + stlab::receiver receive; BOOST_REQUIRE_EQUAL(false, receive.ready()); @@ -44,7 +40,7 @@ BOOST_AUTO_TEST_CASE(int_receiver) { BOOST_REQUIRE_EQUAL(true, receive.ready()); } -using channel_test_fixture_int_1 = channel_test_fixture; +using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture; BOOST_FIXTURE_TEST_SUITE(int_channel, channel_test_fixture_int_1) BOOST_AUTO_TEST_CASE(int_channel) { @@ -59,10 +55,10 @@ BOOST_AUTO_TEST_CASE(int_channel) { BOOST_AUTO_TEST_CASE(int_channel_move_ctor_sender) { BOOST_TEST_MESSAGE("int channel move ctor sender"); - atomic_int result{0}; + std::atomic_int result{0}; auto check = _receive[0] | [&](int x) { result = x; }; - auto sut = move(_send[0]); + auto sut = std::move(_send[0]); _receive[0].set_ready(); sut(42); @@ -75,11 +71,11 @@ BOOST_AUTO_TEST_CASE(int_channel_move_ctor_sender) { BOOST_AUTO_TEST_CASE(int_channel_move_assignment_sender) { BOOST_TEST_MESSAGE("int channel move assignment sender"); - sender sut; - atomic_int result{0}; + stlab::sender sut; + std::atomic_int result{0}; auto check = _receive[0] | [&](int x) { result = x; }; - sut = move(_send[0]); + sut = boost::move(_send[0]); _receive[0].set_ready(); sut(42); @@ -92,7 +88,7 @@ BOOST_AUTO_TEST_CASE(int_channel_move_assignment_sender) { BOOST_AUTO_TEST_CASE(int_channel_copy_ctor_sender) { BOOST_TEST_MESSAGE("int channel copy ctor sender"); - atomic_int result{0}; + std::atomic_int result{0}; auto check = _receive[0] | [&](int x) { result = x; }; auto sut(_send[0]); @@ -116,8 +112,8 @@ BOOST_AUTO_TEST_CASE(int_channel_copy_ctor_sender) { BOOST_AUTO_TEST_CASE(int_channel_copy_assignment_sender) { BOOST_TEST_MESSAGE("int channel copy assignment sender"); - sender sut; - atomic_int result{0}; + stlab::sender sut; + std::atomic_int result{0}; auto check = _receive[0] | [&](int x) { result = x; }; sut = _send[0]; @@ -141,9 +137,9 @@ BOOST_AUTO_TEST_CASE(int_channel_copy_assignment_sender) { BOOST_AUTO_TEST_CASE(int_channel_move_ctor_receiver) { BOOST_TEST_MESSAGE("int channel move ctor receiver"); - atomic_int result{0}; + std::atomic_int result{0}; - auto sut = move(_receive[0]); + auto sut = boost::move(_receive[0]); auto check = sut | [&](int x) { result = x; }; sut.set_ready(); @@ -157,10 +153,10 @@ BOOST_AUTO_TEST_CASE(int_channel_move_ctor_receiver) { BOOST_AUTO_TEST_CASE(int_channel_move_assignment_receiver) { BOOST_TEST_MESSAGE("int channel move assignment receiver"); - receiver sut; - atomic_int result{0}; + stlab::receiver sut; + std::atomic_int result{0}; - sut = move(_receive[0]); + sut = boost::move(_receive[0]); auto check = sut | [&](int x) { result = x; }; sut.set_ready(); @@ -174,7 +170,7 @@ BOOST_AUTO_TEST_CASE(int_channel_move_assignment_receiver) { BOOST_AUTO_TEST_CASE(int_channel_copy_ctor_receiver) { BOOST_TEST_MESSAGE("int channel copy ctor receiver"); - atomic_int result{0}; + std::atomic_int result{0}; auto sut(_receive[0]); @@ -192,8 +188,8 @@ BOOST_AUTO_TEST_CASE(int_channel_copy_ctor_receiver) { BOOST_AUTO_TEST_CASE(int_channel_copy_assignment_receiver) { BOOST_TEST_MESSAGE("int channel copy assignment receiver"); - receiver sut; - atomic_int result{0}; + stlab::receiver sut; + std::atomic_int result{0}; sut = _receive[0]; @@ -210,11 +206,11 @@ BOOST_AUTO_TEST_CASE(int_channel_copy_assignment_receiver) { } BOOST_AUTO_TEST_CASE(int_concatenate_two_channels) { - atomic_int result{0}; - sender A, X; - receiver B, Y; - tie(A, B) = channel(default_executor); - tie(X, Y) = channel(default_executor); + std::atomic_int result{0}; + stlab::sender A, X; + stlab::receiver B, Y; + std::tie(A, B) = stlab::channel(stlab::default_executor); + std::tie(X, Y) = stlab::channel(stlab::default_executor); auto b = B | [](int x) { return x * 2; } | X; @@ -232,9 +228,9 @@ BOOST_AUTO_TEST_CASE(int_concatenate_two_channels) { BOOST_AUTO_TEST_CASE(int_concatenate_channels_with_different_executor) { { - atomic_int result{ 0 }; + std::atomic_int result{ 0 }; - auto done = _receive[0] | (executor{ immediate_executor } & [](int x) { return x + 1; }) | [&result](int x) { result = x; }; + auto done = _receive[0] | (stlab::executor{stlab::immediate_executor } & [](int x) { return x + 1; }) | [&result](int x) { result = x; }; _receive[0].set_ready(); @@ -246,9 +242,9 @@ BOOST_AUTO_TEST_CASE(int_concatenate_channels_with_different_executor) { } test_reset(); { - atomic_int result{ 0 }; + std::atomic_int result{ 0 }; - auto done = _receive[0] | ([](int x) { return x + 1; } & executor{ immediate_executor }) | [&result](int x) { result = x; }; + auto done = _receive[0] | ([](int x) { return x + 1; } & stlab::executor{stlab::immediate_executor }) | [&result](int x) { result = x; }; _receive[0].set_ready(); @@ -265,11 +261,11 @@ BOOST_AUTO_TEST_SUITE_END() namespace { class main_queue { - deque> _q; + std::deque> _q; public: auto executor() { - return [this](auto&& task) { _q.emplace_back(forward(task)); }; + return [this](auto&& task) { _q.emplace_back(std::forward(task)); }; } void run() { @@ -288,16 +284,16 @@ class main_queue { }; struct echo { - process_state_scheduled _state = await_forever; + stlab::process_state_scheduled _state = stlab::await_forever; int _result = -1; void await(int x) { _result = x; - _state = yield_immediate; + _state = stlab::yield_immediate; } int yield() { - _state = await_forever; + _state = stlab::await_forever; return _result; } @@ -308,20 +304,20 @@ struct echo { template struct generator { - const process_state_scheduled _state = yield_immediate; + const stlab::process_state_scheduled _state = stlab::yield_immediate; int _value = 0; - tuple _queues; + std::tuple _queues; explicit generator(T&... q) : _queues(q...) {} template - void push_values(int value, index_sequence) { - (void)initializer_list{(get(_queues).push(value), 0)...}; + void push_values(int value, std::index_sequence) { + (void)std::initializer_list{(std::get(_queues).push(value), 0)...}; } int yield() { - push_values(_value, make_index_sequence()); + push_values(_value, std::make_index_sequence()); return _value++; } @@ -340,17 +336,17 @@ void RequireInClosedRange(size_t minValue, size_t test, size_t maxValue) { BOOST_AUTO_TEST_CASE(int_channel_with_2_sized_buffer) { main_queue q; - auto receive = channel(q.executor()); - queue valuesInFlight; + auto receive = stlab::channel(q.executor()); + std::queue valuesInFlight; - generator> myGenerator(valuesInFlight); + generator> myGenerator(valuesInFlight); echo myEcho; - auto r2 = move(receive) | ref(myGenerator) | - (buffer_size{2} & ref(myEcho)) | [&valuesInFlight](auto x) { + auto r2 = boost::move(receive) | ref(myGenerator) | + (stlab::buffer_size{2} & std::ref(myEcho)) | [&valuesInFlight](auto x) { BOOST_REQUIRE_EQUAL(x, valuesInFlight.front()); valuesInFlight.pop(); - cout << x << endl; + std::cout << x << std::endl; }; r2.set_ready(); @@ -392,14 +388,14 @@ BOOST_AUTO_TEST_CASE(int_channel_with_2_sized_buffer) { BOOST_AUTO_TEST_CASE(int_channel_with_3_sized_buffer) { main_queue q; - auto receive = channel(q.executor()); - queue valuesInFlight; + auto receive = stlab::channel(q.executor()); + std::queue valuesInFlight; - generator> myGenerator(valuesInFlight); + generator> myGenerator(valuesInFlight); echo myEcho; - auto r2 = move(receive) | ref(myGenerator) | - (buffer_size{3} & ref(myEcho)) | [&valuesInFlight](auto x) { + auto r2 = std::move(receive) | std::ref(myGenerator) | + (stlab::buffer_size{3} & std::ref(myEcho)) | [&valuesInFlight](auto x) { BOOST_REQUIRE_EQUAL(x, valuesInFlight.front()); valuesInFlight.pop(); }; @@ -445,28 +441,28 @@ BOOST_AUTO_TEST_CASE(int_channel_with_3_sized_buffer) { BOOST_AUTO_TEST_CASE(int_channel_with_split_different_sized_buffer) { // Here the bigger buffer size must not steer the upstream, but the // smaller size - vector> bufferSizes = { + std::vector> bufferSizes = { {1, 2}, {1, 2}, {1, 3}, {3, 1}, {2, 1}}; for (const auto& bs : bufferSizes) { main_queue q; - queue valuesInFlight1; - queue valuesInFlight2; + std::queue valuesInFlight1; + std::queue valuesInFlight2; - generator> myGenerator1(valuesInFlight1); - generator> myGenerator2(valuesInFlight2); + generator> myGenerator1(valuesInFlight1); + generator> myGenerator2(valuesInFlight2); - auto receive = channel(q.executor()); + auto receive = stlab::channel(q.executor()); auto g = - move(receive) | generator, queue>(valuesInFlight1, valuesInFlight2); + std::move(receive) | generator, std::queue>(valuesInFlight1, valuesInFlight2); - auto r1 = g | (buffer_size{ bs.first } &echo()) | [&valuesInFlight1](auto x) { + auto r1 = g | (stlab::buffer_size{ bs.first } &echo()) | [&valuesInFlight1](auto x) { BOOST_REQUIRE_EQUAL(x, valuesInFlight1.front()); valuesInFlight1.pop(); }; - auto r2 = g | (buffer_size{ bs.second } &echo()) | [&valuesInFlight2](auto x) { + auto r2 = g | (stlab::buffer_size{ bs.second } &echo()) | [&valuesInFlight2](auto x) { BOOST_REQUIRE_EQUAL(x, valuesInFlight2.front()); valuesInFlight2.pop(); }; @@ -516,18 +512,18 @@ BOOST_AUTO_TEST_CASE(int_channel_one_value_different_buffer_sizes) { BOOST_TEST_MESSAGE("int channel one value different buffer sizes"); for (auto bs : std::vector{ 0, 1, 2, 10 }) { - sender send; - receiver receive; - tie(send, receive) = channel(default_executor); - atomic_int result{0}; + stlab::sender send; + stlab::receiver receive; + std::tie(send, receive) = stlab::channel(stlab::default_executor); + std::atomic_int result{0}; - auto check = receive | (buffer_size{ bs } &[&](int x) { result += x; }); + auto check = receive | (stlab::buffer_size{ bs } &[&](int x) { result += x; }); receive.set_ready(); send(1); while (result < 1) { - this_thread::sleep_for(chrono::microseconds(1)); + std::this_thread::sleep_for(std::chrono::microseconds(1)); } BOOST_REQUIRE_EQUAL(1, result); @@ -538,19 +534,19 @@ BOOST_AUTO_TEST_CASE(int_channel_two_values_different_buffer_sizes) { BOOST_TEST_MESSAGE("int channel two values different buffer sizes"); for (auto bs : std::vector{ 0, 1, 2, 10 }) { - sender send; - receiver receive; - tie(send, receive) = channel(default_executor); - atomic_int result{0}; + stlab::sender send; + stlab::receiver receive; + std::tie(send, receive) = stlab::channel(stlab::default_executor); + std::atomic_int result{0}; - auto check = receive | (buffer_size{ bs } &[&](int x) { result += x; }); + auto check = receive | (stlab::buffer_size{ bs } &[&](int x) { result += x; }); receive.set_ready(); send(1); send(1); while (result < 2) { - this_thread::sleep_for(chrono::microseconds(1)); + std::this_thread::sleep_for(std::chrono::microseconds(1)); } BOOST_REQUIRE_EQUAL(2, result); @@ -562,19 +558,19 @@ BOOST_AUTO_TEST_CASE(int_channel_many_values_different_buffer_sizes) { { for (auto bs : std::vector{ 0, 1, 2, 10 }) { - sender send; - receiver receive; - tie(send, receive) = channel(default_executor); - atomic_int result{ 0 }; + stlab::sender send; + stlab::receiver receive; + std::tie(send, receive) = stlab::channel(stlab::default_executor); + std::atomic_int result{ 0 }; - auto check = receive | (buffer_size{ bs } &[&](int x) { result += x; }); + auto check = receive | (stlab::buffer_size{ bs } &[&](int x) { result += x; }); receive.set_ready(); for (auto i = 0; i < 10; ++i) send(1); while (result < 10) { - this_thread::sleep_for(chrono::microseconds(1)); + std::this_thread::sleep_for(std::chrono::microseconds(1)); } BOOST_REQUIRE_EQUAL(10, result); @@ -582,19 +578,19 @@ BOOST_AUTO_TEST_CASE(int_channel_many_values_different_buffer_sizes) { } { for (auto bs : std::vector{ 0, 1, 2, 10 }) { - sender send; - receiver receive; - tie(send, receive) = channel(default_executor); - atomic_int result{ 0 }; + stlab::sender send; + stlab::receiver receive; + std::tie(send, receive) = stlab::channel(stlab::default_executor); + std::atomic_int result{ 0 }; - auto check = receive | ([&](int x) { result += x; } &buffer_size{ bs }); + auto check = receive | ([&](int x) { result += x; } & stlab::buffer_size{ bs }); receive.set_ready(); for (auto i = 0; i < 10; ++i) send(1); while (result < 10) { - this_thread::sleep_for(chrono::microseconds(1)); + std::this_thread::sleep_for(std::chrono::microseconds(1)); } BOOST_REQUIRE_EQUAL(10, result); @@ -606,41 +602,41 @@ BOOST_AUTO_TEST_CASE(int_channel_many_values_different_buffer_sizes) { BOOST_AUTO_TEST_CASE(report_channel_broken_when_no_process_is_attached) { BOOST_TEST_MESSAGE("Expect broken channel exception when no process is attached"); - receiver receive; + stlab::receiver receive; BOOST_REQUIRE_EXCEPTION( - (void)(receive | [](int) { return 1; }), channel_error, - ([](const auto& e) { return string("broken channel") == e.what(); })); + (void)(receive | [](int) { return 1; }), stlab::channel_error, + ([](const auto& e) { return std::string("broken channel") == e.what(); })); BOOST_REQUIRE_EXCEPTION( - (void)(receive | (buffer_size{2} & [](int) { return 1; })), channel_error, - ([](const auto& e) { return string("broken channel") == e.what(); })); + (void)(receive | (stlab::buffer_size{2} & [](int) { return 1; })), stlab::channel_error, + ([](const auto& e) { return std::string("broken channel") == e.what(); })); } BOOST_AUTO_TEST_CASE(report_channel_broken_when_process_is_already_running) { BOOST_TEST_MESSAGE( "Expect \"process already running\" exception when process is already running"); - sender send; - receiver receive; - tie(send, receive) = channel(default_executor); + stlab::sender send; + stlab::receiver receive; + std::tie(send, receive) = stlab::channel(stlab::default_executor); receive.set_ready(); BOOST_REQUIRE_EXCEPTION( - (void)(receive | [](int) { return 1; }), channel_error, - ([](const auto& e) { return string("process already running") == e.what(); })); + (void)(receive | [](int) { return 1; }), stlab::channel_error, + ([](const auto& e) { return std::string("process already running") == e.what(); })); BOOST_REQUIRE_EXCEPTION( - (void)(receive | (buffer_size{2} & [](int) { return 1; })), channel_error, - ([](const auto& e) { return string("process already running") == e.what(); })); + (void)(receive | (stlab::buffer_size{2} & [](int) { return 1; })), stlab::channel_error, + ([](const auto& e) { return std::string("process already running") == e.what(); })); } BOOST_AUTO_TEST_CASE(sender_receiver_equality_tests) { BOOST_TEST_MESSAGE("running sender equality tests"); { - sender a, b; - receiver x, y; + stlab::sender a, b; + stlab::receiver x, y; BOOST_REQUIRE(a == b); BOOST_REQUIRE(!(a != b)); @@ -650,8 +646,8 @@ BOOST_AUTO_TEST_CASE(sender_receiver_equality_tests) { } { - sender a, b; - receiver x, y; + stlab::sender a, b; + stlab::receiver x, y; BOOST_REQUIRE(a == b); BOOST_REQUIRE(!(a != b)); @@ -661,9 +657,9 @@ BOOST_AUTO_TEST_CASE(sender_receiver_equality_tests) { } { - sender send; - receiver rec; - tie(send, rec) = channel(immediate_executor); + stlab::sender send; + stlab::receiver rec; + std::tie(send, rec) = stlab::channel(stlab::immediate_executor); auto a = send; auto x = rec; @@ -672,30 +668,30 @@ BOOST_AUTO_TEST_CASE(sender_receiver_equality_tests) { } { - sender a, b; - receiver x, y; - tie(a, x) = channel(immediate_executor); - tie(b, y) = channel(immediate_executor); + stlab::sender a, b; + stlab::receiver x, y; + std::tie(a, x) = stlab::channel(stlab::immediate_executor); + std::tie(b, y) = stlab::channel(stlab::immediate_executor); BOOST_REQUIRE(a != b); BOOST_REQUIRE(x != y); } { - sender send; - receiver rec; - tie(send, rec) = channel(immediate_executor); + stlab::sender send; + stlab::receiver rec; + std::tie(send, rec) = stlab::channel(stlab::immediate_executor); - sender a; + stlab::sender a; BOOST_REQUIRE(a != send); } } BOOST_AUTO_TEST_CASE(sender_receiver_swap_tests) { { - sender a, b; - receiver x, y; - tie(a, x) = channel(immediate_executor); - tie(b, y) = channel(immediate_executor); + stlab::sender a, b; + stlab::receiver x, y; + std::tie(a, x) = stlab::channel(stlab::immediate_executor); + std::tie(b, y) = stlab::channel(stlab::immediate_executor); int result1(0), result2(0); auto v = x | [&result1](int i) { result1 = i; }; @@ -713,10 +709,10 @@ BOOST_AUTO_TEST_CASE(sender_receiver_swap_tests) { BOOST_REQUIRE_EQUAL(2, result1); } { - sender a, b; - receiver x, y; - tie(a, x) = channel(immediate_executor); - tie(b, y) = channel(immediate_executor); + stlab::sender a, b; + stlab::receiver x, y; + std::tie(a, x) = stlab::channel(stlab::immediate_executor); + std::tie(b, y) = stlab::channel(stlab::immediate_executor); int result1(0), result2(0); swap(x, y); @@ -734,14 +730,14 @@ BOOST_AUTO_TEST_CASE(sender_receiver_swap_tests) { BOOST_REQUIRE_EQUAL(2, result1); } { - sender a, b; - receiver x, y; - tie(a, x) = channel(immediate_executor); - tie(b, y) = channel(immediate_executor); + stlab::sender a, b; + stlab::receiver x, y; + std::tie(a, x) = stlab::channel(stlab::immediate_executor); + std::tie(b, y) = stlab::channel(stlab::immediate_executor); int result1(0), result2(0); - auto v = x | [&result1](move_only i) { result1 = i.member(); }; - auto w = y | [&result2](move_only i) { result2 = i.member(); }; + auto v = x | [&result1](stlab::move_only i) { result1 = i.member(); }; + auto w = y | [&result2](stlab::move_only i) { result2 = i.member(); }; x.set_ready(); y.set_ready(); @@ -755,16 +751,16 @@ BOOST_AUTO_TEST_CASE(sender_receiver_swap_tests) { BOOST_REQUIRE_EQUAL(2, result1); } { - sender a, b; - receiver x, y; - tie(a, x) = channel(immediate_executor); - tie(b, y) = channel(immediate_executor); + stlab::sender a, b; + stlab::receiver x, y; + std::tie(a, x) = stlab::channel(stlab::immediate_executor); + std::tie(b, y) = stlab::channel(stlab::immediate_executor); int result1(0), result2(0); - swap(x, y); + std::swap(x, y); - auto v = x | [&result1](move_only i) { result1 = i.member(); }; - auto w = y | [&result2](move_only i) { result2 = i.member(); }; + auto v = x | [&result1](stlab::move_only i) { result1 = i.member(); }; + auto w = y | [&result2](stlab::move_only i) { result2 = i.member(); }; x.set_ready(); y.set_ready(); From 8ef3ca381a8704b868cf6759ac6868c69f9bcea0 Mon Sep 17 00:00:00 2001 From: Sean Parent Date: Mon, 8 Feb 2021 13:31:05 -0800 Subject: [PATCH 03/10] using std::move instead of boost::move in test cases. --- test/channel_tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/channel_tests.cpp b/test/channel_tests.cpp index 09bd0e66d..674787a0e 100755 --- a/test/channel_tests.cpp +++ b/test/channel_tests.cpp @@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(int_channel_move_assignment_sender) { std::atomic_int result{0}; auto check = _receive[0] | [&](int x) { result = x; }; - sut = boost::move(_send[0]); + sut = std::move(_send[0]); _receive[0].set_ready(); sut(42); @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(int_channel_move_ctor_receiver) { std::atomic_int result{0}; - auto sut = boost::move(_receive[0]); + auto sut = std::move(_receive[0]); auto check = sut | [&](int x) { result = x; }; sut.set_ready(); @@ -156,7 +156,7 @@ BOOST_AUTO_TEST_CASE(int_channel_move_assignment_receiver) { stlab::receiver sut; std::atomic_int result{0}; - sut = boost::move(_receive[0]); + sut = std::move(_receive[0]); auto check = sut | [&](int x) { result = x; }; sut.set_ready(); @@ -342,7 +342,7 @@ BOOST_AUTO_TEST_CASE(int_channel_with_2_sized_buffer) { generator> myGenerator(valuesInFlight); echo myEcho; - auto r2 = boost::move(receive) | ref(myGenerator) | + auto r2 = std::move(receive) | ref(myGenerator) | (stlab::buffer_size{2} & std::ref(myEcho)) | [&valuesInFlight](auto x) { BOOST_REQUIRE_EQUAL(x, valuesInFlight.front()); valuesInFlight.pop(); From bb09aba393bf54a91a6d76c3bcfcf3f1a5d9505b Mon Sep 17 00:00:00 2001 From: Sean Parent Date: Mon, 8 Feb 2021 18:24:34 -0800 Subject: [PATCH 04/10] Shot in the dark for missing initializer in future_test_helper atomic. --- stlab/concurrency/future.hpp | 7 ++----- test/future_test_helper.hpp | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/stlab/concurrency/future.hpp b/stlab/concurrency/future.hpp index 16d98abd7..f3f525941 100755 --- a/stlab/concurrency/future.hpp +++ b/stlab/concurrency/future.hpp @@ -628,14 +628,11 @@ template struct shared : shared_base, shared_task { using function_t = task; - std::atomic_size_t _promise_count; + std::atomic_size_t _promise_count{1}; function_t _f; template - shared(executor_t s, F&& f) : shared_base(std::move(s)), _f(std::forward(f)) { - _promise_count = 1; - } - + shared(executor_t s, F&& f) : shared_base(std::move(s)), _f(std::forward(f)) { } void remove_promise() override { if (std::is_same>::value) { diff --git a/test/future_test_helper.hpp b/test/future_test_helper.hpp index df3b649e3..e82100dbf 100644 --- a/test/future_test_helper.hpp +++ b/test/future_test_helper.hpp @@ -150,7 +150,7 @@ struct test_fixture { } } - std::atomic_int _task_counter; + std::atomic_int _task_counter{0}; private: template From aff3cf6687b4a1cdde117008ad8efb984541e2ec Mon Sep 17 00:00:00 2001 From: Felix Petriconi Date: Tue, 9 Feb 2021 09:41:37 +0100 Subject: [PATCH 05/10] Add verbose test output to hunt down test problem --- .appveyor.yml | 3 ++- .travis/build.sh | 3 ++- cmake/RunTests.cmake | 7 ++++++ test/CMakeLists.txt | 56 +++++++++++++++++++++++++++++++++++++------- 4 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 cmake/RunTests.cmake diff --git a/.appveyor.yml b/.appveyor.yml index ef17ba9a7..ac50d1d9b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -54,4 +54,5 @@ build_script: - cd build - cmake -G "%CMAKE_TOOLSET%" -D BOOST_ROOT="%BOOST_ROOT%" -D Boost_USE_STATIC_LIBS=ON .. - cmake --build . --config Release - - ctest -C Release + - set TESTS_ARGUMENTS=--log_level=message + - ctest -C Release --verbose --no-compress-output diff --git a/.travis/build.sh b/.travis/build.sh index 8db63bc8d..a0cfa6063 100755 --- a/.travis/build.sh +++ b/.travis/build.sh @@ -42,7 +42,8 @@ if [ $? -ne 0 ]; then exit 1; fi if $coverage; then lcov -c -i -b .. -d . -o Coverage.baseline; fi -ctest --output-on-failure -j$NPROC +export TESTS_ARGUMENTS=--log_level=message +ctest -C Release -j$NPROC --verbose --no-compress-output if [ $? -ne 0 ]; then exit 1; fi if $coverage; then diff --git a/cmake/RunTests.cmake b/cmake/RunTests.cmake new file mode 100644 index 000000000..8c9892c26 --- /dev/null +++ b/cmake/RunTests.cmake @@ -0,0 +1,7 @@ +if(NOT DEFINED ENV{TESTS_ARGUMENTS}) + set(ENV{TESTS_ARGUMENTS} "--default-arguments") +endif() +execute_process(COMMAND ${TEST_EXECUTABLE} $ENV{TESTS_ARGUMENTS} RESULT_VARIABLE result) +if(NOT "${result}" STREQUAL "0") + message(FATAL_ERROR "Test failed with return value '${result}'") +endif() \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dd0c481da..6a3d348a4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -17,7 +17,12 @@ if( NOT ( ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" endif() target_link_libraries( stlab.test.channel PUBLIC stlab::testing ) -add_test( NAME stlab.test.channel COMMAND stlab.test.channel ) + +add_test( + NAME stlab.test.channel + COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$ -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake +) + ################################################################################ @@ -28,8 +33,11 @@ add_executable( stlab.test.executor target_compile_definitions(stlab.test.executor PRIVATE STLAB_UNIT_TEST) target_link_libraries( stlab.test.executor PUBLIC stlab::testing ) -add_test( NAME stlab.test.executor COMMAND stlab.test.executor ) +add_test( + NAME stlab.test.executor + COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$ -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake +) ################################################################################ @@ -52,7 +60,12 @@ target_sources( stlab.test.future PUBLIC target_compile_definitions(stlab.test.future PRIVATE STLAB_UNIT_TEST) target_link_libraries( stlab.test.future PUBLIC stlab::testing ) -add_test( NAME stlab.test.future COMMAND stlab.test.future ) + +add_test( + NAME stlab.test.future + COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$ -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake +) + ################################################################################ @@ -62,7 +75,11 @@ add_executable( stlab.test.serial_queue target_compile_definitions(stlab.test.serial_queue PRIVATE STLAB_UNIT_TEST) target_link_libraries( stlab.test.serial_queue PUBLIC stlab::testing ) -add_test( NAME stlab.test.serial_queue COMMAND stlab.test.serial_queue ) + +add_test( + NAME stlab.test.serial_queue + COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$ -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake +) ################################################################################ @@ -73,7 +90,12 @@ add_executable( stlab.test.cow target_compile_definitions(stlab.test.cow PRIVATE STLAB_UNIT_TEST) target_link_libraries( stlab.test.cow PUBLIC stlab::testing ) -add_test( NAME stlab.test.cow COMMAND stlab.test.cow ) + +add_test( + NAME stlab.test.cow + COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$ -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake +) + ################################################################################ @@ -84,7 +106,11 @@ add_executable( stlab.test.task target_compile_definitions(stlab.test.task PRIVATE STLAB_UNIT_TEST) target_link_libraries( stlab.test.task PUBLIC stlab::testing ) -add_test( NAME stlab.test.task COMMAND stlab.test.task ) + +add_test( + NAME stlab.test.task + COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$ -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake +) ################################################################################ @@ -95,7 +121,11 @@ add_executable( stlab.test.tuple target_compile_definitions(stlab.test.channel PRIVATE STLAB_UNIT_TEST) target_link_libraries( stlab.test.tuple PUBLIC stlab::testing ) -add_test( NAME stlab.test.tuple COMMAND stlab.test.tuple ) + +add_test( + NAME stlab.test.tuple + COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$ -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake +) ################################################################################ @@ -106,7 +136,11 @@ add_executable( stlab.test.traits target_compile_definitions(stlab.test.channel PRIVATE STLAB_UNIT_TEST) target_link_libraries( stlab.test.traits PUBLIC stlab::testing ) -add_test( NAME stlab.test.traits COMMAND stlab.test.traits ) + +add_test( + NAME stlab.test.traits + COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$ -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake +) ################################################################################ @@ -115,7 +149,11 @@ add_executable( stlab.test.forest main.cpp ) target_link_libraries( stlab.test.forest PUBLIC stlab::testing ) -add_test( NAME stlab.test.forest COMMAND stlab.test.forest ) + +add_test( + NAME stlab.test.forest + COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$ -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake +) ################################################################################ # From 7446df349349af8aa9204e9b3bb33f7bb5eef8f2 Mon Sep 17 00:00:00 2001 From: Felix Petriconi Date: Tue, 9 Feb 2021 10:43:45 +0100 Subject: [PATCH 06/10] Fix default test argument --- cmake/RunTests.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/RunTests.cmake b/cmake/RunTests.cmake index 8c9892c26..97785eddf 100644 --- a/cmake/RunTests.cmake +++ b/cmake/RunTests.cmake @@ -1,5 +1,5 @@ if(NOT DEFINED ENV{TESTS_ARGUMENTS}) - set(ENV{TESTS_ARGUMENTS} "--default-arguments") + set(ENV{TESTS_ARGUMENTS} "") endif() execute_process(COMMAND ${TEST_EXECUTABLE} $ENV{TESTS_ARGUMENTS} RESULT_VARIABLE result) if(NOT "${result}" STREQUAL "0") From 0ab728717913dfeecafa488a1ae00362f5f9fc9d Mon Sep 17 00:00:00 2001 From: Felix Petriconi Date: Tue, 9 Feb 2021 13:53:30 +0100 Subject: [PATCH 07/10] Add more time during polling for the result. --- test/future_test_helper.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/future_test_helper.hpp b/test/future_test_helper.hpp index e82100dbf..4701a1455 100644 --- a/test/future_test_helper.hpp +++ b/test/future_test_helper.hpp @@ -113,6 +113,7 @@ struct test_fixture { auto wait_until_future_r_completed(F& f) { auto result = f.get_try(); while (!result) { + std::this_thread::sleep_for(std::chrono::milliseconds(1))); result = f.get_try(); } return result; From 573d6b8ce98fb5d0b57f92b7b81bf1a3a2ac2ae6 Mon Sep 17 00:00:00 2001 From: Felix Petriconi Date: Tue, 9 Feb 2021 13:58:35 +0100 Subject: [PATCH 08/10] Fix typo --- test/future_test_helper.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/future_test_helper.hpp b/test/future_test_helper.hpp index 4701a1455..656287617 100644 --- a/test/future_test_helper.hpp +++ b/test/future_test_helper.hpp @@ -113,7 +113,7 @@ struct test_fixture { auto wait_until_future_r_completed(F& f) { auto result = f.get_try(); while (!result) { - std::this_thread::sleep_for(std::chrono::milliseconds(1))); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); result = f.get_try(); } return result; From 4b257c81f3b01375e313ed7fb284e3c61eedef4c Mon Sep 17 00:00:00 2001 From: Fernando Pelliccioni Date: Tue, 9 Feb 2021 10:44:56 -0300 Subject: [PATCH 09/10] Adds Task system header selection --- CMakeLists.txt | 7 +++++-- build.py | 6 ++++++ conanfile.py | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53da464b1..bff699d1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ option( stlab.boost_variant "Prefer Boost::variant to std::variant" OFF ) option( stlab.boost_optional "Prefer Boost::optional to std::optional" OFF ) option( stlab.coroutines "Leverage the coroutine TS in stlab" OFF ) -set(stlab.task_system "portable" CACHE STRING "Select the task system (portable|libdispatch|emscripten|pnacl|windows).") +set(stlab.task_system "header" CACHE STRING "Select the task system (header|portable|libdispatch|emscripten|pnacl|windows).") # # On apple we have to force the usage of boost.variant, because Apple's @@ -168,7 +168,10 @@ if (NOT APPLE AND (${stlab.task_system} STREQUAL "libdispatch")) target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE libdispatch::libdispatch) endif() -if (${stlab.task_system} STREQUAL "portable") +if (${stlab.task_system} STREQUAL "header") + # Task System is selected in concurrency/config_task_system.hpp + # Nothing to define. +elseif (${stlab.task_system} STREQUAL "portable") target_compile_definitions( stlab INTERFACE -DSTLAB_FORCE_TASK_SYSTEM_PORTABLE ) elseif (${stlab.task_system} STREQUAL "libdispatch") target_compile_definitions( stlab INTERFACE -DSTLAB_FORCE_TASK_SYSTEM_LIBDISPATCH ) diff --git a/build.py b/build.py index 2dcf9527a..fd3cd9fe7 100644 --- a/build.py +++ b/build.py @@ -9,6 +9,12 @@ filtered_builds = [] for settings, options, env_vars, build_requires, reference in builder.items: + #TODO(fernando): auto and portable Task Systems are disabled until we fix the deadlock + # using portable in Windows. + # opts_auto = copy.deepcopy(options) + # opts_auto["stlab:task_system"] = "auto" + # filtered_builds.append([settings, opts_auto, env_vars, build_requires, reference]) + if settings["compiler"] == "clang": opts_libdispatch = copy.deepcopy(options) opts_libdispatch["stlab:task_system"] = "libdispatch" diff --git a/conanfile.py b/conanfile.py index 113613a93..1bfb72d85 100644 --- a/conanfile.py +++ b/conanfile.py @@ -28,7 +28,7 @@ class StlabLibrariesConan(ConanFile): "boost_optional": [True, False], "boost_variant": [True, False], "coroutines": [True, False], - "task_system": ["portable", "libdispatch", "emscripten", "pnacl", "windows", "auto"], + "task_system": ["header", "portable", "libdispatch", "emscripten", "pnacl", "windows", "auto"], } default_options = { @@ -37,7 +37,7 @@ class StlabLibrariesConan(ConanFile): "boost_optional": False, "boost_variant": False, "coroutines": False, - "task_system": "auto", + "task_system": "header", } def _log(self, str): From 3bb550ecf3c6cfd526af96a0f70e9a4234a21b2d Mon Sep 17 00:00:00 2001 From: Felix Petriconi Date: Tue, 9 Feb 2021 22:41:32 +0100 Subject: [PATCH 10/10] Prepare 1.6.0 release --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 3e3ed1257..08fd4133d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +## v1.6.0 - 2021 - February 9 + - Backport the library to support C++14 and later + - Better auto-configuration - no need for compiler flags. + - Supported for threaded wasm using the portable tasking system (auto-configured). + ## v1.5.6 - 2021 - February 1 - Fixed issues = [#352]:(https://github.com/stlab/libraries/issues/352) Non portable 'warning' preprocessor command