From 2f4037b5454a53f3cfb9c201d8cac8edf7b33655 Mon Sep 17 00:00:00 2001 From: Sean Parent Date: Thu, 14 Mar 2024 17:12:55 -0700 Subject: [PATCH] namespace version bump (#541) Bumping the inline namespace version to v2 to avoid ODR violations. The pre_exit code remains at v1 (it must be bumped more carefully). The portable default executor is moving to v2 - which may lead to more than one thread pool for the portable instance. Pinning the version here is more difficult. Removed dead reset() operations in future shared_base Documented (and assert) precondition that future::exception() is only invoked on a ready exception. Made more of the tuple meta-facilities public to avoid detail:: namespace usage in unit tests. Restructured unit tests to avoid sleep-wait-loops. --- README.md | 1 + stlab/concurrency/await.hpp | 15 +- stlab/concurrency/channel.hpp | 26 +- stlab/concurrency/default_executor.hpp | 10 +- stlab/concurrency/executor_base.hpp | 11 +- stlab/concurrency/future.hpp | 36 +-- stlab/concurrency/immediate_executor.hpp | 11 +- stlab/concurrency/main_executor.hpp | 10 +- stlab/concurrency/ready_future.hpp | 12 +- stlab/concurrency/serial_queue.hpp | 6 +- stlab/concurrency/system_timer.hpp | 20 +- stlab/concurrency/task.hpp | 10 +- stlab/concurrency/traits.hpp | 12 +- stlab/concurrency/tuple_algorithm.hpp | 71 +++--- stlab/config.hpp.in | 64 ++--- stlab/functional.hpp | 11 +- stlab/memory.hpp | 10 +- stlab/pre_exit.hpp | 6 + stlab/scope.hpp | 11 +- stlab/test/model.hpp | 6 +- stlab/utility.hpp | 11 +- test/executor_test.cpp | 61 +++-- test/future_recover_tests.cpp | 32 +-- test/future_test_helper.hpp | 49 +--- test/future_tests.cpp | 7 +- test/future_then_tests.cpp | 305 +++++++++++------------ test/future_when_all_arguments_tests.cpp | 8 +- test/future_when_all_range_tests.cpp | 4 +- test/future_when_any_arguments_tests.cpp | 4 +- test/future_when_any_range_tests.cpp | 5 +- test/tuple_test.cpp | 22 +- 31 files changed, 405 insertions(+), 462 deletions(-) diff --git a/README.md b/README.md index d513ea0ce..ba070de97 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ cmake -S . -B ../BUILD -GNinja -DCMAKE_CXX_STANDARD=17 -DCMAKE_BUILD_TYPE=Releas If you organize the build directory into subdirectories you can support multiple configurations. ``` +rm -rf ../builds/portable cmake -S . -B ../builds/portable -GXcode -DCMAKE_CXX_STANDARD=17 -DBUILD_TESTING=ON -DSTLAB_TASK_SYSTEM=portable -DCMAKE_OSX_DEPLOYMENT_TARGET=14.4 -DCMAKE_OSX_DEPLOYMENT_TARGET=macosx14.4 ``` diff --git a/stlab/concurrency/await.hpp b/stlab/concurrency/await.hpp index 97bb58f6e..0d2885e6a 100644 --- a/stlab/concurrency/await.hpp +++ b/stlab/concurrency/await.hpp @@ -31,10 +31,7 @@ /**************************************************************************************************/ namespace stlab { - -/**************************************************************************************************/ - -inline namespace v1 { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ @@ -203,18 +200,16 @@ template } template -[[deprecated("Use await_for instead.")]] auto blocking_get(future x, - const std::chrono::nanoseconds& timeout) - -> decltype(x.get_try()) { +[[deprecated("Use await_for instead.")]] auto blocking_get( + future x, const std::chrono::nanoseconds& timeout) -> decltype(x.get_try()) { return blocking_get_for(std::move(x), timeout).get_try(); } /**************************************************************************************************/ -} // namespace v1 +} // namespace STLAB_VERSION_NAMESPACE() +} // namespace stlab /**************************************************************************************************/ -} // namespace stlab - #endif // STLAB_CONCURRENCY_AWAIT_HPP diff --git a/stlab/concurrency/channel.hpp b/stlab/concurrency/channel.hpp index ab778bbbe..d7d07ceae 100755 --- a/stlab/concurrency/channel.hpp +++ b/stlab/concurrency/channel.hpp @@ -9,6 +9,8 @@ #ifndef STLAB_CONCURRENCY_CHANNEL_HPP #define STLAB_CONCURRENCY_CHANNEL_HPP +#include + #include #include #include @@ -33,10 +35,7 @@ /**************************************************************************************************/ namespace stlab { - -/**************************************************************************************************/ - -inline namespace v1 { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ @@ -192,7 +191,9 @@ using avoid = std::conditional_t::value, avoid_, T>; /**************************************************************************************************/ template -auto invoke_(F&& f, std::tuple...>& t, std::index_sequence) { +auto invoke_(F&& f, + std::tuple...>& t, + std::index_sequence) { return std::forward(f)(std::move(std::get(t))...); } @@ -484,14 +485,12 @@ struct round_robin_queue_strategy { queue_t _queue; bool empty() const { - return get_i( - _queue, _index, [](const auto& c) { return c.empty(); }, true); + return get_i(_queue, _index, [](const auto& c) { return c.empty(); }, true); } auto front() { assert(!empty() && "front on an empty container is a very bad idea!"); - return std::make_tuple(get_i( - _queue, _index, [](auto& c) { return c.front(); }, item_t{})); + return std::make_tuple(get_i(_queue, _index, [](auto& c) { return c.front(); }, item_t{})); } void pop_front() { @@ -546,8 +545,8 @@ struct unordered_queue_strategy { auto front() { assert(!empty() && "front on an empty container is a very bad idea!"); _index = tuple_find(_queue, [](const auto& c) { return !c.empty(); }); - return std::make_tuple(get_i( - _queue, _index, [](auto& c) { return std::move(c.front()); }, item_t{})); + return std::make_tuple( + get_i(_queue, _index, [](auto& c) { return std::move(c.front()); }, item_t{})); } void pop_front() { @@ -1705,10 +1704,7 @@ struct function_process { /**************************************************************************************************/ -} // namespace v1 - -/**************************************************************************************************/ - +} // namespace STLAB_VERSION_NAMESPACE() } // namespace stlab /**************************************************************************************************/ diff --git a/stlab/concurrency/default_executor.hpp b/stlab/concurrency/default_executor.hpp index be370f0cf..eb26673db 100644 --- a/stlab/concurrency/default_executor.hpp +++ b/stlab/concurrency/default_executor.hpp @@ -40,10 +40,7 @@ /**************************************************************************************************/ namespace stlab { - -/**************************************************************************************************/ - -inline namespace v1 { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ @@ -500,10 +497,7 @@ constexpr auto high_executor = detail::executor_type + #include #include @@ -18,12 +20,10 @@ /**************************************************************************************************/ namespace stlab { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ -inline namespace v1 { -/**************************************************************************************************/ - using executor_t = std::function)>; /* @@ -82,10 +82,7 @@ executor_task_pair operator&(F&& f, executor e) { /**************************************************************************************************/ -} // namespace v1 - -/**************************************************************************************************/ - +} // namespace STLAB_VERSION_NAMESPACE() } // namespace stlab /**************************************************************************************************/ diff --git a/stlab/concurrency/future.hpp b/stlab/concurrency/future.hpp index 9a2911136..e4aac893a 100644 --- a/stlab/concurrency/future.hpp +++ b/stlab/concurrency/future.hpp @@ -38,10 +38,7 @@ /**************************************************************************************************/ namespace stlab { - -/**************************************************************************************************/ - -inline namespace v1 { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ @@ -274,8 +271,6 @@ struct shared_base> : std::enable_shared_from_this auto recover(future&& p, F&& f) { return recover(std::move(p), _executor, std::forward(f)); @@ -389,8 +384,6 @@ struct shared_base> : std::enable_shared_from_this< explicit shared_base(executor_t s) : _executor(std::move(s)) {} - void reset() { _then.second = task{}; } - template auto recover(future&& p, F&& f) { return recover(std::move(p), _executor, std::forward(f)); @@ -474,8 +467,6 @@ struct shared_base : std::enable_shared_from_this> { explicit shared_base(executor_t s) : _executor(std::move(s)) {} - void reset() { _then.clear(); } - template auto recover(future&& p, F&& f) { return recover(std::move(p), _executor, std::forward(f)); @@ -750,7 +741,11 @@ class STLAB_NODISCARD() future> { return _p->_exception ? std::optional{_p->_exception} : std::nullopt; } - std::exception_ptr exception() const& { return _p->_exception; } + // Precondition: is_ready() + std::exception_ptr exception() const& { + assert(is_ready()); + return _p->_exception; + } }; /**************************************************************************************************/ @@ -897,7 +892,11 @@ class STLAB_NODISCARD() future { return _p->_exception ? std::optional{_p->_exception} : std::nullopt; } - std::exception_ptr exception() const& { return _p->_exception; } + // Precondition: is_ready() + std::exception_ptr exception() const& { + assert(is_ready()); + return _p->_exception; + } }; /**************************************************************************************************/ @@ -1001,7 +1000,11 @@ class STLAB_NODISCARD() future> { return _p->_exception ? std::optional{_p->_exception} : std::nullopt; } - std::exception_ptr exception() const& { return _p->_exception; } + // Precondition: is_ready() + std::exception_ptr exception() const& { + assert(is_ready()); + return _p->_exception; + } }; template @@ -1233,7 +1236,7 @@ template auto when_all(E executor, F f, future... args) { using vt_t = voidless_tuple; using opt_t = optional_placeholder_tuple; - using result_t = decltype(detail::apply_tuple(std::declval(), std::declval())); + using result_t = decltype(apply_ignore_placeholders(std::declval(), std::declval())); auto shared = std::make_shared>(); auto p = package( @@ -1816,10 +1819,7 @@ auto shared_base::recover(future&& p, E executor, F&& f) { /**************************************************************************************************/ -} // namespace v1 - -/**************************************************************************************************/ - +} // namespace STLAB_VERSION_NAMESPACE() } // namespace stlab /**************************************************************************************************/ diff --git a/stlab/concurrency/immediate_executor.hpp b/stlab/concurrency/immediate_executor.hpp index 7c733dcc9..015b2d435 100644 --- a/stlab/concurrency/immediate_executor.hpp +++ b/stlab/concurrency/immediate_executor.hpp @@ -9,17 +9,17 @@ #ifndef STLAB_CONCURRENCY_IMMEDIATE_EXECUTOR_HPP #define STLAB_CONCURRENCY_IMMEDIATE_EXECUTOR_HPP +#include + #include /**************************************************************************************************/ namespace stlab { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ -inline namespace v1 { -/**************************************************************************************************/ - namespace detail { /**************************************************************************************************/ @@ -41,10 +41,7 @@ constexpr auto immediate_executor = detail::immediate_executor_type{}; /**************************************************************************************************/ -} // namespace v1 - -/**************************************************************************************************/ - +} // namespace STLAB_VERSION_NAMESPACE() } // namespace stlab /**************************************************************************************************/ diff --git a/stlab/concurrency/main_executor.hpp b/stlab/concurrency/main_executor.hpp index adc0b7bef..c7ad8d3d8 100644 --- a/stlab/concurrency/main_executor.hpp +++ b/stlab/concurrency/main_executor.hpp @@ -35,10 +35,7 @@ /**************************************************************************************************/ namespace stlab { - -/**************************************************************************************************/ - -inline namespace v1 { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ @@ -170,8 +167,11 @@ struct main_executor_type { constexpr auto main_executor = detail::main_executor_type{}; -} // namespace v1 +/**************************************************************************************************/ +} // namespace STLAB_VERSION_NAMESPACE() } // namespace stlab +/**************************************************************************************************/ + #endif // STLAB_CONCURRENCY_MAIN_EXECUTOR_HPP diff --git a/stlab/concurrency/ready_future.hpp b/stlab/concurrency/ready_future.hpp index 4e637c1cb..f68a619ef 100644 --- a/stlab/concurrency/ready_future.hpp +++ b/stlab/concurrency/ready_future.hpp @@ -9,6 +9,8 @@ #ifndef STLAB_CONCURRENCY_READY_FUTURE_HPP #define STLAB_CONCURRENCY_READY_FUTURE_HPP +#include + #include #include #include @@ -18,10 +20,7 @@ /**************************************************************************************************/ namespace stlab { - -/**************************************************************************************************/ - -inline namespace v1 { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ @@ -72,10 +71,9 @@ future make_exceptional_future(std::exception_ptr error, E executor) { /**************************************************************************************************/ -} // namespace v1 +} // namespace STLAB_VERSION_NAMESPACE() +} // namespace stlab /**************************************************************************************************/ -} // namespace stlab - #endif // STLAB_CONCURRENCY_READY_FUTURE_HPP diff --git a/stlab/concurrency/serial_queue.hpp b/stlab/concurrency/serial_queue.hpp index 97ed65775..21d80cbaa 100644 --- a/stlab/concurrency/serial_queue.hpp +++ b/stlab/concurrency/serial_queue.hpp @@ -11,6 +11,8 @@ /**************************************************************************************************/ +#include + #include #include #include @@ -29,7 +31,7 @@ /**************************************************************************************************/ namespace stlab { -inline namespace v1 { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ @@ -164,7 +166,7 @@ class serial_queue_t { /**************************************************************************************************/ -} // namespace v1 +} // namespace STLAB_VERSION_NAMESPACE() } // namespace stlab /**************************************************************************************************/ diff --git a/stlab/concurrency/system_timer.hpp b/stlab/concurrency/system_timer.hpp index 467114695..60cf71f53 100755 --- a/stlab/concurrency/system_timer.hpp +++ b/stlab/concurrency/system_timer.hpp @@ -34,10 +34,7 @@ /**************************************************************************************************/ namespace stlab { - -/**************************************************************************************************/ - -inline namespace v1 { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ @@ -58,8 +55,8 @@ struct system_timer_type { } template > - auto operator()(std::chrono::duration duration, F f) const - -> std::enable_if_t> { + auto operator()(std::chrono::duration duration, + F f) const -> std::enable_if_t> { using namespace std::chrono; using f_t = decltype(f); @@ -110,8 +107,8 @@ class system_timer { } template > - auto operator()(std::chrono::duration duration, F&& f) - -> std::enable_if_t> { + auto operator()(std::chrono::duration duration, + F&& f) -> std::enable_if_t> { using namespace std::chrono; auto timer = CreateThreadpoolTimer(&timer_callback_impl, new F(std::forward(f)), &_callBackEnvironment); @@ -228,8 +225,8 @@ class system_timer { } template > - auto operator()(std::chrono::duration duration, F&& f) - -> std::enable_if_t> { + auto operator()(std::chrono::duration duration, + F&& f) -> std::enable_if_t> { lock_t lock(_timed_queue_mutex); _timed_queue.emplace_back(std::chrono::steady_clock::now() + duration, std::forward(f)); std::push_heap(std::begin(_timed_queue), std::end(_timed_queue), greater_first()); @@ -272,10 +269,9 @@ struct system_timer_type { constexpr auto system_timer = detail::system_timer_type{}; -} // namespace v1 - /**************************************************************************************************/ +} // namespace STLAB_VERSION_NAMESPACE() } // namespace stlab /**************************************************************************************************/ diff --git a/stlab/concurrency/task.hpp b/stlab/concurrency/task.hpp index 93fafa0de..9cfff2ae7 100644 --- a/stlab/concurrency/task.hpp +++ b/stlab/concurrency/task.hpp @@ -23,10 +23,7 @@ /**************************************************************************************************/ namespace stlab { - -/**************************************************************************************************/ - -inline namespace v1 { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ @@ -285,10 +282,7 @@ using task = typename noexcept_deducer::type; /**************************************************************************************************/ -} // namespace v1 - -/**************************************************************************************************/ - +} // namespace STLAB_VERSION_NAMESPACE() } // namespace stlab /**************************************************************************************************/ diff --git a/stlab/concurrency/traits.hpp b/stlab/concurrency/traits.hpp index 67159e701..1aed3d71a 100644 --- a/stlab/concurrency/traits.hpp +++ b/stlab/concurrency/traits.hpp @@ -9,17 +9,17 @@ #ifndef STLAB_CONCURRENCY_TRAITS_HPP #define STLAB_CONCURRENCY_TRAITS_HPP +#include + #include /**************************************************************************************************/ namespace stlab { +inline namespace STLAB_VERSION_NAMESPACE() { /**************************************************************************************************/ -inline namespace v1 { -/**************************************************************************************************/ - template struct bool_pack; template @@ -27,10 +27,10 @@ using all_true = std::is_same, bool_pack>; /**************************************************************************************************/ -template class test, typename T> +template