{"sha":"8bec44964e6d477237d230d826b73cb54860068e","node_id":"MDY6Q29tbWl0MzU2ODEzNzY6OGJlYzQ0OTY0ZTZkNDc3MjM3ZDIzMGQ4MjZiNzNjYjU0ODYwMDY4ZQ==","commit":{"author":{"name":"Felix Petriconi","email":"FelixPetriconi@users.noreply.github.com","date":"2021-02-09T22:08:30Z"},"committer":{"name":"GitHub","email":"noreply@github.com","date":"2021-02-09T22:08:30Z"},"message":"Merge pull request #362 from stlab/develop\n\n1.6.0 release","tree":{"sha":"7e59bb8312c73cfa0e1cd26222c78bfdbe18577e","url":"https://api.github.com/repos/stlab/stlab/git/trees/7e59bb8312c73cfa0e1cd26222c78bfdbe18577e"},"url":"https://api.github.com/repos/stlab/stlab/git/commits/8bec44964e6d477237d230d826b73cb54860068e","comment_count":0,"verification":{"verified":true,"reason":"valid","signature":"-----BEGIN PGP SIGNATURE-----\n\nwsBcBAABCAAQBQJgIwfeCRBK7hj4Ov3rIwAAdHIIAAIc7nrJi5RaiPEreRyILCkn\nP45HY6gu4V0dBgs8IFPZdWA9wcykjsANuy0zxUT7AhxwphxJNJ2V3R183tTFmohD\n3stKVoCbV8SMtP8WucbgRetw+dtVJC31XlbQb2ySXU6WTPJRlWhH3Eik/jG8fJxs\n/Pvs9nhFjsiLE19YFOXVW4BfC7sOoiBIOoPwJYnIe8XDDyBth7JYAxesTJtIw5El\n+xQw/pBu70rW6xiqOJk6/+jDelNo/6VUvq/aTF7JYRjnYEvaFpK3+Mq0Ddp7z3dK\nq6gJp7CZXigBhNiSezNSewtF7gFHb3//OoFr4OMkSRgwAQNuQ5iRLx7nfUfTCI8=\n=E2eg\n-----END PGP SIGNATURE-----\n","payload":"tree 7e59bb8312c73cfa0e1cd26222c78bfdbe18577e\nparent c9d5de0b2ab5ef6b16bfee1d9e7e83a28246ae1f\nparent 314193c4b22bdfc6e1acf8ad7e348d1fa8b649e5\nauthor Felix Petriconi <FelixPetriconi@users.noreply.github.com> 1612908510 +0100\ncommitter GitHub <noreply@github.com> 1612908510 +0100\n\nMerge pull request #362 from stlab/develop\n\n1.6.0 release","verified_at":"2024-01-16T19:59:59Z"}},"url":"https://api.github.com/repos/stlab/stlab/commits/8bec44964e6d477237d230d826b73cb54860068e","html_url":"https://github.com/stlab/stlab/commit/8bec44964e6d477237d230d826b73cb54860068e","comments_url":"https://api.github.com/repos/stlab/stlab/commits/8bec44964e6d477237d230d826b73cb54860068e/comments","author":{"login":"FelixPetriconi","id":612377,"node_id":"MDQ6VXNlcjYxMjM3Nw==","avatar_url":"https://avatars.githubusercontent.com/u/612377?v=4","gravatar_id":"","url":"https://api.github.com/users/FelixPetriconi","html_url":"https://github.com/FelixPetriconi","followers_url":"https://api.github.com/users/FelixPetriconi/followers","following_url":"https://api.github.com/users/FelixPetriconi/following{/other_user}","gists_url":"https://api.github.com/users/FelixPetriconi/gists{/gist_id}","starred_url":"https://api.github.com/users/FelixPetriconi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FelixPetriconi/subscriptions","organizations_url":"https://api.github.com/users/FelixPetriconi/orgs","repos_url":"https://api.github.com/users/FelixPetriconi/repos","events_url":"https://api.github.com/users/FelixPetriconi/events{/privacy}","received_events_url":"https://api.github.com/users/FelixPetriconi/received_events","type":"User","user_view_type":"public","site_admin":false},"committer":{"login":"web-flow","id":19864447,"node_id":"MDQ6VXNlcjE5ODY0NDQ3","avatar_url":"https://avatars.githubusercontent.com/u/19864447?v=4","gravatar_id":"","url":"https://api.github.com/users/web-flow","html_url":"https://github.com/web-flow","followers_url":"https://api.github.com/users/web-flow/followers","following_url":"https://api.github.com/users/web-flow/following{/other_user}","gists_url":"https://api.github.com/users/web-flow/gists{/gist_id}","starred_url":"https://api.github.com/users/web-flow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/web-flow/subscriptions","organizations_url":"https://api.github.com/users/web-flow/orgs","repos_url":"https://api.github.com/users/web-flow/repos","events_url":"https://api.github.com/users/web-flow/events{/privacy}","received_events_url":"https://api.github.com/users/web-flow/received_events","type":"User","user_view_type":"public","site_admin":false},"parents":[{"sha":"c9d5de0b2ab5ef6b16bfee1d9e7e83a28246ae1f","url":"https://api.github.com/repos/stlab/stlab/commits/c9d5de0b2ab5ef6b16bfee1d9e7e83a28246ae1f","html_url":"https://github.com/stlab/stlab/commit/c9d5de0b2ab5ef6b16bfee1d9e7e83a28246ae1f"},{"sha":"314193c4b22bdfc6e1acf8ad7e348d1fa8b649e5","url":"https://api.github.com/repos/stlab/stlab/commits/314193c4b22bdfc6e1acf8ad7e348d1fa8b649e5","html_url":"https://github.com/stlab/stlab/commit/314193c4b22bdfc6e1acf8ad7e348d1fa8b649e5"}],"stats":{"total":1087,"additions":649,"deletions":438},"files":[{"sha":"ac50d1d9b1561e1ddfe0f8aaa7f23b5d78eeedf1","filename":".appveyor.yml","status":"modified","additions":2,"deletions":1,"changes":3,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/.appveyor.yml","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/.appveyor.yml","contents_url":"https://api.github.com/repos/stlab/stlab/contents/.appveyor.yml?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -54,4 +54,5 @@ build_script:\n   - cd build\n   - cmake -G \"%CMAKE_TOOLSET%\" -D BOOST_ROOT=\"%BOOST_ROOT%\" -D Boost_USE_STATIC_LIBS=ON ..\n   - cmake --build . --config Release\n-  - ctest -C Release\n+  - set TESTS_ARGUMENTS=--log_level=message\n+  - ctest -C Release --verbose --no-compress-output"},{"sha":"a0cfa60635f94d829bc4c0dc557eb9d258d261ba","filename":".travis/build.sh","status":"modified","additions":2,"deletions":1,"changes":3,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/.travis%2Fbuild.sh","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/.travis%2Fbuild.sh","contents_url":"https://api.github.com/repos/stlab/stlab/contents/.travis%2Fbuild.sh?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -42,7 +42,8 @@ if [ $? -ne 0 ]; then exit 1; fi\n \n if $coverage; then lcov -c -i -b .. -d . -o Coverage.baseline; fi\n \n-ctest --output-on-failure -j$NPROC\n+export TESTS_ARGUMENTS=--log_level=message \n+ctest -C Release -j$NPROC --verbose --no-compress-output\n if [ $? -ne 0 ]; then exit 1; fi\n \n if $coverage; then"},{"sha":"08fd4133dd06da10074d6a0443aae23844f3c522","filename":"CHANGES.md","status":"modified","additions":5,"deletions":0,"changes":5,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/CHANGES.md","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/CHANGES.md","contents_url":"https://api.github.com/repos/stlab/stlab/contents/CHANGES.md?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -1,3 +1,8 @@\n+## v1.6.0 - 2021 - February 9\n+ - Backport the library to support C++14 and later\n+ - Better auto-configuration - no need for compiler flags.\n+ - Supported for threaded wasm using the portable tasking system (auto-configured).\n+\n ## v1.5.6 - 2021 - February 1\n  - Fixed issues\n    = [#352]:(https://github.com/stlab/libraries/issues/352) Non portable 'warning' preprocessor command"},{"sha":"78601f1da1ebbcc824a25d13572020ed815f1145","filename":"CMakeLists.txt","status":"modified","additions":11,"deletions":4,"changes":15,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/CMakeLists.txt","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/CMakeLists.txt","contents_url":"https://api.github.com/repos/stlab/stlab/contents/CMakeLists.txt?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -16,7 +16,8 @@ endif()\n \n project( stlab VERSION 1.5.6 LANGUAGES CXX )\n \n-set(CMAKE_CXX_STANDARD 17)\n+# Overriden from Conan?\n+# set(CMAKE_CXX_STANDARD 17)\n set(CMAKE_CXX_STANDARD_REQUIRED ON)\n \n include( CTest )\n@@ -40,7 +41,7 @@ option( stlab.boost_variant \"Prefer Boost::variant to std::variant\" OFF )\n option( stlab.boost_optional \"Prefer Boost::optional to std::optional\" OFF )\n option( stlab.coroutines \"Leverage the coroutine TS in stlab\" OFF )\n \n-set(stlab.task_system \"portable\" CACHE STRING \"Select the task system (portable|libdispatch|emscripten|pnacl|windows).\")\n+set(stlab.task_system \"header\" CACHE STRING \"Select the task system (header|portable|libdispatch|emscripten|pnacl|windows).\")\n \n #\n # On apple we have to force the usage of boost.variant, because Apple's\n@@ -67,7 +68,7 @@ add_library( stlab::stlab ALIAS stlab )\n # features ensures that the corresponding C++ standard flag is populated in\n # targets linking to stlab.\n #\n-target_compile_features( stlab INTERFACE cxx_std_17 )\n+# target_compile_features( stlab INTERFACE cxx_std_14)\n \n #\n # The include directory for stlab can be expected to vary between build\n@@ -106,6 +107,9 @@ if( EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)\n   # conanfile.txt\n   #\n   conan_basic_setup( TARGETS KEEP_RPATHS )\n+\n+  # REVISIT (sparent) : This should not be necessary but appears to be\n+  set(CMAKE_CXX_STANDARD ${CONAN_SETTINGS_COMPILER_CPPSTD})\n endif()\n \n if ( stlab.testing OR stlab.boost_variant OR stlab.boost_optional )\n@@ -168,7 +172,10 @@ if (NOT APPLE AND (${stlab.task_system} STREQUAL \"libdispatch\"))\n   target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE libdispatch::libdispatch)\n endif()\n \n-if (${stlab.task_system} STREQUAL \"portable\")\n+if (${stlab.task_system} STREQUAL \"header\")\n+  # Task System is selected in concurrency/config_task_system.hpp\n+  # Nothing to define.\n+elseif (${stlab.task_system} STREQUAL \"portable\")\n   target_compile_definitions( stlab INTERFACE -DSTLAB_FORCE_TASK_SYSTEM_PORTABLE )\n elseif (${stlab.task_system} STREQUAL \"libdispatch\")\n   target_compile_definitions( stlab INTERFACE -DSTLAB_FORCE_TASK_SYSTEM_LIBDISPATCH )"},{"sha":"fd3cd9fe773cebbb7627dabe498d31b7c1036ef8","filename":"build.py","status":"modified","additions":6,"deletions":0,"changes":6,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/build.py","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/build.py","contents_url":"https://api.github.com/repos/stlab/stlab/contents/build.py?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -9,6 +9,12 @@\n     filtered_builds = []\n     for settings, options, env_vars, build_requires, reference in builder.items:\n     \n+        #TODO(fernando): auto and portable Task Systems are disabled until we fix the deadlock \n+        #                using portable in Windows.\n+        # opts_auto = copy.deepcopy(options)\n+        # opts_auto[\"stlab:task_system\"] = \"auto\"\n+        # filtered_builds.append([settings, opts_auto, env_vars, build_requires, reference])\n+\n         if settings[\"compiler\"] == \"clang\":\n             opts_libdispatch = copy.deepcopy(options)\n             opts_libdispatch[\"stlab:task_system\"] = \"libdispatch\""},{"sha":"97785eddf1607813ab0388fb3af1d1f6b374cf64","filename":"cmake/RunTests.cmake","status":"added","additions":7,"deletions":0,"changes":7,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/cmake%2FRunTests.cmake","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/cmake%2FRunTests.cmake","contents_url":"https://api.github.com/repos/stlab/stlab/contents/cmake%2FRunTests.cmake?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -0,0 +1,7 @@\n+if(NOT DEFINED ENV{TESTS_ARGUMENTS})\n+    set(ENV{TESTS_ARGUMENTS} \"\")\n+endif()\n+execute_process(COMMAND ${TEST_EXECUTABLE} $ENV{TESTS_ARGUMENTS} RESULT_VARIABLE result)\n+if(NOT \"${result}\" STREQUAL \"0\")\n+    message(FATAL_ERROR \"Test failed with return value '${result}'\")\n+endif()\n\\ No newline at end of file"},{"sha":"f4c26390b5cfd9d590c7290231986a1379a171b3","filename":"conanfile.py","status":"modified","additions":7,"deletions":5,"changes":12,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/conanfile.py","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/conanfile.py","contents_url":"https://api.github.com/repos/stlab/stlab/contents/conanfile.py?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -28,7 +28,7 @@ class StlabLibrariesConan(ConanFile):\n         \"boost_optional\": [True, False],\n         \"boost_variant\": [True, False],\n         \"coroutines\": [True, False],\n-        \"task_system\": [\"portable\", \"libdispatch\", \"emscripten\", \"pnacl\", \"windows\", \"auto\"],\n+        \"task_system\": [\"header\", \"portable\", \"libdispatch\", \"emscripten\", \"pnacl\", \"windows\", \"auto\"],\n     }\n \n     default_options = {\n@@ -37,7 +37,7 @@ class StlabLibrariesConan(ConanFile):\n         \"boost_optional\": False,\n         \"boost_variant\": False,\n         \"coroutines\": False,\n-        \"task_system\": \"auto\",\n+        \"task_system\": \"header\",\n     }\n \n     def _log(self, str):\n@@ -109,7 +109,8 @@ def _configure_boost(self):\n     def _fix_boost_components(self):\n         if self.settings.os != \"Macos\": return\n         if self.settings.compiler != \"apple-clang\": return\n-        if float(str(self.settings.compiler.version)) >= 12: return\n+\n+        if (float(str(self.settings.compiler.version)) >= 12) and not ((self.settings.compiler.cppstd == \"14\") or (self.settings.compiler.cppstd == \"gnu14\")): return\n \n         #\n         # On Apple we have to force the usage of boost.variant, because Apple's implementation of C++17 is not complete.\n@@ -171,6 +172,8 @@ def _configure_task_system(self):\n     def configure(self):\n         ConanFile.configure(self)\n \n+        tools.check_min_cppstd(self, \"14\")\n+\n         self._fix_boost_components()\n \n         if self._use_boost():\n@@ -195,11 +198,10 @@ def build(self):\n             cmake.configure()\n             cmake.build()\n             cmake.test(output_on_failure=True)\n-\n+ \n     def package(self):\n         self.copy(\"*.hpp\")\n \n     def imports(self):\n         self.copy(\"*.dll\", \"./bin\", \"bin\")\n         self.copy(\"*.dylib\", \"./bin\", \"lib\")\n-"},{"sha":"0336aad9f0015f556277be510f2f1276a44b25e8","filename":"setup_xcode_cpp14.sh","status":"renamed","additions":1,"deletions":1,"changes":2,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/setup_xcode_cpp14.sh","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/setup_xcode_cpp14.sh","contents_url":"https://api.github.com/repos/stlab/stlab/contents/setup_xcode_cpp14.sh?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -3,7 +3,7 @@\n mkdir -p build\n pushd build\n \n-conan install .. --build=missing -s build_type=Debug\n+conan install .. --build=missing -s build_type=Debug -o testing=True -s compiler.cppstd=14\n \n cmake -GXcode -D CMAKE_BUILD_TYPE=debug -D stlab_testing=ON ..\n ","previous_filename":"setup_xcode.sh"},{"sha":"90ffe88acdc459fe0c3a0155fb9dce7281527b7f","filename":"setup_xcode_cpp17.sh","status":"added","additions":10,"deletions":0,"changes":10,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/setup_xcode_cpp17.sh","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/setup_xcode_cpp17.sh","contents_url":"https://api.github.com/repos/stlab/stlab/contents/setup_xcode_cpp17.sh?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -0,0 +1,10 @@\n+#!/bin/bash\n+\n+mkdir -p build\n+pushd build\n+\n+conan install .. --build=missing -s build_type=Debug -o testing=True -s compiler.cppstd=17\n+\n+cmake -GXcode -D CMAKE_BUILD_TYPE=debug -D stlab_testing=ON ..\n+\n+popd"},{"sha":"2e7ce9d497071567f855b5c4e03df4bc9974240e","filename":"stlab/concurrency/channel.hpp","status":"modified","additions":115,"deletions":21,"changes":136,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Fchannel.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Fchannel.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/stlab%2Fconcurrency%2Fchannel.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -229,15 +229,21 @@ struct invoke_variant_dispatcher {\n template <>\n struct invoke_variant_dispatcher<1> {\n     template <typename F, typename T, typename Arg>\n-    static auto invoke_(F&& f, T& t) {\n-        if constexpr (std::is_same<Arg, void>::value) {\n-            return;\n-        } else if constexpr (std::is_same<Arg, detail::avoid_>::value) {\n-            return std::forward<F>(f)();\n-        } else {\n-            return std::forward<F>(f)(std::move(stlab::get<Arg>(std::get<0>(t))));\n-        }\n+    static auto invoke_(F&&, T&) -> std::enable_if_t<std::is_same<Arg, void>::value, void> {\n+        return;\n     }\n+    template <typename F, typename T, typename Arg>\n+    static auto invoke_(F&& f, T&) -> std::enable_if_t<std::is_same<Arg, detail::avoid_>::value,\n+                                                       decltype(std::forward<F>(f)())> {\n+        return std::forward<F>(f)();\n+    }\n+    template <typename F, typename T, typename Arg>\n+    static auto invoke_(F&& f, T& t) -> std::enable_if_t<\n+        !(std::is_same<Arg, detail::avoid_>::value || std::is_same<Arg, detail::avoid_>::value),\n+        decltype(std::forward<F>(f)(std::move(stlab::get<Arg>(std::get<0>(t)))))> {\n+        return std::forward<F>(f)(std::move(stlab::get<Arg>(std::get<0>(t))));\n+    }\n+\n     template <typename F, typename T, typename... Args>\n     static auto invoke(F&& f, T& t) {\n         return invoke_<F, T, first_t<Args...>>(std::forward<F>(f), t);\n@@ -699,7 +705,7 @@ struct downstream<\n         _data = std::forward<F>(f);\n     }\n \n-    void clear() { _data = nullopt; }\n+    void clear() { _data = stlab::nullopt; }\n \n     std::size_t size() const { return 1; }\n \n@@ -828,7 +834,7 @@ struct shared_process\n         if (do_final) {\n             std::unique_lock<std::mutex> lock(_downstream_mutex);\n             _downstream.clear(); // This will propagate the close to anything downstream\n-            _process = nullopt;\n+            _process = stlab::nullopt;\n         }\n     }\n \n@@ -910,8 +916,14 @@ struct shared_process\n         return bool(message);\n     }\n \n+    /*\n+        REVISIT (sparent) : Next two cases are nearly identical, complicated by the need to\n+        remove constexpr if to support C++14.\n+    */\n+\n     template <typename U>\n-    auto step() -> std::enable_if_t<has_process_yield_v<unwrap_reference_t<U>>> {\n+    auto step() -> std::enable_if_t<has_process_yield_v<unwrap_reference_t<U>> &&\n+                                    !has_process_await_v<unwrap_reference_t<T>, Args...>> {\n         // in case that the timeout function is just been executed then we have to re-schedule\n         // the current run\n         lock_t lock(_timeout_function_control, std::try_to_lock);\n@@ -926,12 +938,90 @@ struct shared_process\n             is done on yield()\n         */\n         try {\n-            if constexpr (has_process_await_v<unwrap_reference_t<T>, Args...>) {\n-                while (get_process_state(_process).first == process_state::await) {\n-                    if (!dequeue()) break;\n-                }\n+            if (get_process_state(_process).first == process_state::await) return;\n+\n+            // Workaround until we can use structured bindings\n+            auto tmp = get_process_state(_process);\n+            const auto& state = tmp.first;\n+            const auto& duration = tmp.second;\n+\n+            /*\n+                Once we hit yield, go ahead and call it. If the yield is delayed then schedule it.\n+               This process will be considered running until it executes.\n+            */\n+            if (state == process_state::yield) {\n+                if (std::chrono::duration_cast<std::chrono::nanoseconds>(duration) <=\n+                    std::chrono::nanoseconds::min())\n+                    broadcast(unwrap(*_process).yield());\n+                else\n+                    execute_at(duration,\n+                               _executor)([_weak_this = make_weak_ptr(this->shared_from_this())] {\n+                        auto _this = _weak_this.lock();\n+                        if (!_this) return;\n+                        _this->try_broadcast();\n+                    });\n+            }\n+\n+            /*\n+                We are in an await state and the queue is empty.\n+\n+                If we await forever then task_done() leaving us in an await state.\n+                else if we await with an expired timeout then go ahead and yield now.\n+                else schedule a timeout when we will yield if not canceled by intervening await.\n+            */\n+            else if (std::chrono::duration_cast<std::chrono::nanoseconds>(duration) ==\n+                     std::chrono::nanoseconds::max()) {\n+                task_done();\n+            } else if (std::chrono::duration_cast<std::chrono::nanoseconds>(duration) <=\n+                       std::chrono::nanoseconds::min()) {\n+                broadcast(unwrap(*_process).yield());\n             } else {\n-                if (get_process_state(_process).first == process_state::await) return;\n+                /* Schedule a timeout. */\n+                _timeout_function_active = true;\n+                execute_at(duration,\n+                           _executor)([_weak_this = make_weak_ptr(this->shared_from_this())] {\n+                    auto _this = _weak_this.lock();\n+                    // It may be that the complete channel is gone in the meanwhile\n+                    if (!_this) return;\n+\n+                    // try_lock can fail spuriously\n+                    while (true) {\n+                        lock_t lock(_this->_timeout_function_control, std::try_to_lock);\n+                        if (!lock) continue;\n+\n+                        // we were cancelled\n+                        if (get_process_state(_this->_process).first != process_state::yield) {\n+                            _this->try_broadcast();\n+                            _this->_timeout_function_active = false;\n+                        }\n+                        return;\n+                    }\n+                });\n+            }\n+        } catch (...) { // this catches exceptions during _process.await() and _process.yield()\n+            broadcast(std::move(std::current_exception()));\n+        }\n+    }\n+\n+    template <typename U>\n+    auto step() -> std::enable_if_t<has_process_yield_v<unwrap_reference_t<U>> &&\n+                                    has_process_await_v<unwrap_reference_t<T>, Args...>> {\n+        // in case that the timeout function is just been executed then we have to re-schedule\n+        // the current run\n+        lock_t lock(_timeout_function_control, std::try_to_lock);\n+        if (!lock) {\n+            run();\n+            return;\n+        }\n+        _timeout_function_active = false;\n+\n+        /*\n+            While we are waiting we will flush the queue. The assumption here is that work\n+            is done on yield()\n+        */\n+        try {\n+            while (get_process_state(_process).first == process_state::await) {\n+                if (!dequeue()) break;\n             }\n \n             // Workaround until we can use structured bindings\n@@ -944,7 +1034,8 @@ struct shared_process\n                This process will be considered running until it executes.\n             */\n             if (state == process_state::yield) {\n-                if (std::chrono::duration_cast<std::chrono::nanoseconds>(duration) <= std::chrono::nanoseconds::min())\n+                if (std::chrono::duration_cast<std::chrono::nanoseconds>(duration) <=\n+                    std::chrono::nanoseconds::min())\n                     broadcast(unwrap(*_process).yield());\n                 else\n                     execute_at(duration,\n@@ -962,14 +1053,17 @@ struct shared_process\n                 else if we await with an expired timeout then go ahead and yield now.\n                 else schedule a timeout when we will yield if not canceled by intervening await.\n             */\n-            else if (std::chrono::duration_cast<std::chrono::nanoseconds>(duration) == std::chrono::nanoseconds::max()) {\n+            else if (std::chrono::duration_cast<std::chrono::nanoseconds>(duration) ==\n+                     std::chrono::nanoseconds::max()) {\n                 task_done();\n-            } else if (std::chrono::duration_cast<std::chrono::nanoseconds>(duration) <= std::chrono::nanoseconds::min()) {\n+            } else if (std::chrono::duration_cast<std::chrono::nanoseconds>(duration) <=\n+                       std::chrono::nanoseconds::min()) {\n                 broadcast(unwrap(*_process).yield());\n             } else {\n                 /* Schedule a timeout. */\n                 _timeout_function_active = true;\n-                execute_at(duration, _executor)([_weak_this = make_weak_ptr(this->shared_from_this())] {\n+                execute_at(duration,\n+                           _executor)([_weak_this = make_weak_ptr(this->shared_from_this())] {\n                     auto _this = _weak_this.lock();\n                     // It may be that the complete channel is gone in the meanwhile\n                     if (!_this) return;\n@@ -1367,7 +1461,7 @@ detail::annotated_process<F> operator&(detail::annotated_process<F>&& a, buffer_\n /**************************************************************************************************/\n \n template <typename T>\n-class [[nodiscard]] receiver {\n+class STLAB_NODISCARD() receiver {\n     using ptr_t = std::shared_ptr<detail::shared_process_receiver<T>>;\n \n     ptr_t _p;"},{"sha":"1cecd5baa68020d44a6777d4ca57fc86c20c5bea","filename":"stlab/concurrency/config.hpp","status":"modified","additions":9,"deletions":0,"changes":9,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Fconfig.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Fconfig.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/stlab%2Fconcurrency%2Fconfig.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -61,6 +61,15 @@\n     #endif\n #endif\n \n+/**************************************************************************************************/\n+\n+#if __cplusplus < 201703L\n+#define STLAB_NODISCARD()\n+#else\n+#define STLAB_NODISCARD() [[nodiscard]]\n+#endif\n+\n+\n /**************************************************************************************************/\n \n #endif // STLAB_CONCURRENCY_CONFIG_HPP"},{"sha":"42e10061ce139f62f453b556f80bae318fca9b49","filename":"stlab/concurrency/config_task_system.hpp","status":"modified","additions":27,"deletions":10,"changes":37,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Fconfig_task_system.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Fconfig_task_system.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/stlab%2Fconcurrency%2Fconfig_task_system.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -46,31 +46,48 @@\n \n #else\n \n-    #if __APPLE__\n+    #if defined(__APPLE__)\n \n         #undef STLAB_TASK_SYSTEM_PRIVATE_LIBDISPATCH\n         #define STLAB_TASK_SYSTEM_PRIVATE_LIBDISPATCH() 1\n \n-    #elif __EMSCRIPTEN__\n+    #elif defined(__EMSCRIPTEN__)\n \n-        #undef STLAB_TASK_SYSTEM_PRIVATE_EMSCRIPTEN\n-        #define STLAB_TASK_SYSTEM_PRIVATE_EMSCRIPTEN() 1\n+        #if defined(__EMSCRIPTEN_PTHREADS__)\n \n-    #elif __pnacl__\n+            #undef STLAB_TASK_SYSTEM_PRIVATE_PORTABLE\n+            #define STLAB_TASK_SYSTEM_PRIVATE_PORTABLE() 1\n+\n+        #else\n+\n+            #undef STLAB_TASK_SYSTEM_PRIVATE_EMSCRIPTEN\n+            #define STLAB_TASK_SYSTEM_PRIVATE_EMSCRIPTEN() 1\n+\n+        #endif\n+\n+    #elif defined(__pnacl__)\n \n         #undef STLAB_TASK_SYSTEM_PRIVATE_PNACL\n         #define STLAB_TASK_SYSTEM_PRIVATE_PNACL() 1\n \n-    #elif _MSC_VER\n+    #elif defined(_MSC_VER)\n \n         #undef STLAB_TASK_SYSTEM_PRIVATE_WINDOWS\n         #define STLAB_TASK_SYSTEM_PRIVATE_WINDOWS() 1\n \n     #else\n-\n-        #undef STLAB_TASK_SYSTEM_PRIVATE_PORTABLE\n-        #define STLAB_TASK_SYSTEM_PRIVATE_PORTABLE() 1\n-\n+        #if defined(__has_include)\n+            #if __has_include(<dispatch/dispatch.h>)\n+                #undef STLAB_TASK_SYSTEM_PRIVATE_LIBDISPATCH\n+                #define STLAB_TASK_SYSTEM_PRIVATE_LIBDISPATCH() 1\n+            #else\n+                #undef STLAB_TASK_SYSTEM_PRIVATE_PORTABLE\n+                #define STLAB_TASK_SYSTEM_PRIVATE_PORTABLE() 1\n+            #endif\n+        #else\n+            #undef STLAB_TASK_SYSTEM_PRIVATE_PORTABLE\n+            #define STLAB_TASK_SYSTEM_PRIVATE_PORTABLE() 1\n+        #endif\n     #endif\n \n #endif"},{"sha":"f3f5259419be66686a61a92c534f8390470cfb19","filename":"stlab/concurrency/future.hpp","status":"modified","additions":44,"deletions":36,"changes":80,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Ffuture.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Ffuture.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/stlab%2Fconcurrency%2Ffuture.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -80,6 +80,17 @@ inline const char* Future_error_map(\n \n /**************************************************************************************************/\n \n+// This could be lifted into a common header if needed in other places\n+#if __cplusplus < 201703L\n+template <class F, class...Args>\n+using result_t = std::result_of_t<F(Args...)>;\n+#else\n+template <class F, class... Args>\n+using result_t = std::invoke_result_t<F, Args...>;\n+#endif\n+\n+/**************************************************************************************************/\n+\n } // namespace detail\n \n /**************************************************************************************************/\n@@ -131,25 +142,25 @@ struct result_of_when_all_t;\n \n template <typename F>\n struct result_of_when_all_t<F, void> {\n-    using result_type = std::invoke_result_t<F>;\n+    using result_type = detail::result_t<F>;\n };\n \n template <typename F, typename T>\n struct result_of_when_all_t {\n-    using result_type = std::invoke_result_t<F, const std::vector<T>&>;\n+    using result_type = detail::result_t<F, const std::vector<T>&>;\n };\n \n template <typename F, typename T>\n struct result_of_when_any_t;\n \n template <typename F>\n struct result_of_when_any_t<F, void> {\n-    using result_type = std::invoke_result_t<F, size_t>;\n+    using result_type = detail::result_t<F, size_t>;\n };\n \n template <typename F, typename R>\n struct result_of_when_any_t {\n-    using result_type = std::invoke_result_t<F, R, size_t>;\n+    using result_type = detail::result_t<F, R, size_t>;\n };\n \n template <typename T>\n@@ -292,7 +303,7 @@ struct shared_base<T, enable_if_copyable<T>> : std::enable_shared_from_this<shar\n \n     template <typename E, typename F>\n     auto recover(E executor, F&& f) {\n-        auto p = package<std::invoke_result_t<F, future<T>>()>(\n+        auto p = package<detail::result_t<F, future<T>>()>(\n             executor, [_f = std::forward<F>(f), _p = future<T>(this->shared_from_this())]() mutable {\n                 return std::move(_f)(std::move(_p));\n             });\n@@ -329,7 +340,7 @@ struct shared_base<T, enable_if_copyable<T>> : std::enable_shared_from_this<shar\n     auto recover_r(bool unique, E&& executor, F&& f) {\n         if (!unique) return recover(std::forward<E>(executor), std::forward<F>(f));\n \n-        auto p = package<std::invoke_result_t<F, future<T>>()>(\n+        auto p = package<detail::result_t<F, future<T>>()>(\n             executor, [_f = std::forward<F>(f), _p = future<T>(this->shared_from_this())]() mutable {\n                 return _f(std::move(_p));\n             });\n@@ -453,7 +464,7 @@ struct shared_base<T, enable_if_not_copyable<T>> : std::enable_shared_from_this<\n     template <typename E, typename F>\n     auto recover_r(bool, E executor, F&& f) {\n         // rvalue case unique is assumed.\n-        auto p = package<std::invoke_result_t<F, future<T>>()>(\n+        auto p = package<detail::result_t<F, future<T>>()>(\n             executor, [_f = std::forward<F>(f), _p = future<T>(this->shared_from_this())]() {\n                 return _f(std::move(_p));\n             });\n@@ -556,7 +567,7 @@ struct shared_base<void> : std::enable_shared_from_this<shared_base<void>> {\n     }\n \n     template <typename E, typename F>\n-    auto recover(E&& executor, F&& f) -> future<reduced_t<std::invoke_result_t<F, future<void>>>>;\n+    auto recover(E&& executor, F&& f) -> future<reduced_t<detail::result_t<F, future<void>>>>;\n \n     template <typename F>\n     auto recover_r(bool, F&& f) {\n@@ -617,14 +628,11 @@ template <typename R, typename... Args>\n struct shared<R(Args...)> : shared_base<R>, shared_task<Args...> {\n     using function_t = task<R(Args...)>;\n \n-    std::atomic_size_t _promise_count;\n+    std::atomic_size_t _promise_count{1};\n     function_t _f;\n \n     template <typename F>\n-    shared(executor_t s, F&& f) : shared_base<R>(std::move(s)), _f(std::forward<F>(f)) {\n-        _promise_count = 1;\n-    }\n-\n+    shared(executor_t s, F&& f) : shared_base<R>(std::move(s)), _f(std::forward<F>(f)) { }\n \n     void remove_promise() override {\n         if (std::is_same<R, reduced_t<R>>::value) {\n@@ -710,7 +718,7 @@ class packaged_task {\n /**************************************************************************************************/\n \n template <typename T>\n-class [[nodiscard]] future<T, enable_if_copyable<T>> {\n+class STLAB_NODISCARD() future<T, enable_if_copyable<T>> {\n     using ptr_t = std::shared_ptr<detail::shared_base<T>>;\n     ptr_t _p;\n \n@@ -846,7 +854,7 @@ class [[nodiscard]] future<T, enable_if_copyable<T>> {\n /**************************************************************************************************/\n \n template <>\n-class [[nodiscard]] future<void, void> {\n+class STLAB_NODISCARD() future<void, void> {\n     using ptr_t = std::shared_ptr<detail::shared_base<void>>;\n     ptr_t _p;\n \n@@ -980,7 +988,7 @@ class [[nodiscard]] future<void, void> {\n /**************************************************************************************************/\n \n template <typename T>\n-class [[nodiscard]] future<T, enable_if_not_copyable<T>> {\n+class STLAB_NODISCARD() future<T, enable_if_not_copyable<T>> {\n     using ptr_t = std::shared_ptr<detail::shared_base<T>>;\n     ptr_t _p;\n \n@@ -1131,7 +1139,7 @@ struct when_all_shared {\n     void done(FF&& f) {\n         auto run{ false };\n         {\n-            std::unique_lock lock{ _guard };\n+            std::unique_lock<std::mutex> lock{ _guard };\n             if (!_exception) {\n                 assign_ready_future<FF>::assign(std::get<index>(_args), std::forward<FF>(f));\n                 if (--_remaining == 0) run = true;\n@@ -1143,7 +1151,7 @@ struct when_all_shared {\n     void failure(std::exception_ptr error) {\n         auto run{ false };\n         {\n-            std::unique_lock lock{ _guard };\n+            std::unique_lock<std::mutex> lock{ _guard };\n             if (!_exception) {\n                 for (auto& h : _holds)\n                     h.reset();\n@@ -1170,7 +1178,7 @@ struct when_any_shared {\n     void failure(std::exception_ptr error) {\n         auto run{ false };\n         {\n-            std::unique_lock lock{ _guard };\n+            std::unique_lock<std::mutex> lock{ _guard };\n             if (--_remaining == 0) {\n                 _exception = std::move(error);\n                 run = true;\n@@ -1183,7 +1191,7 @@ struct when_any_shared {\n     void done(FF&& f) {\n         auto run{ false };\n         {\n-            std::unique_lock lock{ _guard };\n+            std::unique_lock<std::mutex> lock{ _guard };\n             if (_index == std::numeric_limits<std::size_t>::max()) {\n                 _arg = std::move(*std::forward<FF>(f).get_try());\n                 _index = index;\n@@ -1212,7 +1220,7 @@ struct when_any_shared<S, void> {\n \n     void failure(std::exception_ptr error) {\n         auto run{ false };\n-        std::unique_lock lock{ _guard };\n+        std::unique_lock<std::mutex> lock{ _guard };\n         {\n             if (--_remaining == 0) {\n                 _exception = std::move(error);\n@@ -1226,7 +1234,7 @@ struct when_any_shared<S, void> {\n     void done(FF&&) {\n         auto run{ false };\n         {\n-            std::unique_lock lock{ _guard };\n+            std::unique_lock<std::mutex> lock{ _guard };\n             if (_index == std::numeric_limits<std::size_t>::max()) {\n                 _index = index;\n                 run = true;\n@@ -1275,13 +1283,13 @@ void attach_when_arg_(E&& executor, std::shared_ptr<P>& p, T a) {\n         auto p = _w.lock();\n         if (!p) return;\n \n-        if (auto ex = x.exception(); ex) {\n+        if (auto ex = x.exception()) {\n             p->failure(ex);\n         } else {\n             p->template done<i>(std::move(x));\n         }\n     });\n-    std::unique_lock lock{ p->_guard };\n+    std::unique_lock<std::mutex> lock{ p->_guard };\n     p->_holds[i] = std::move(holds);\n }\n \n@@ -1322,7 +1330,7 @@ template <typename T>\n struct make_when_any {\n     template <typename E, typename F, typename... Ts>\n     static auto make(E executor, F f, future<T> arg, future<Ts>... args) {\n-        using result_t = std::invoke_result_t<F, T, size_t>;\n+        using result_t = detail::result_t<F, T, size_t>;\n \n         auto shared = std::make_shared<detail::when_any_shared<sizeof...(Ts) + 1, T>>();\n         auto p = package<result_t()>(executor, [_f = std::move(f), _p = shared] {\n@@ -1342,7 +1350,7 @@ template <>\n struct make_when_any<void> {\n     template <typename E, typename F, typename... Ts>\n     static auto make(E executor, F&& f, future<Ts>... args) {\n-        using result_t = std::invoke_result_t<F, size_t>;\n+        using result_t = detail::result_t<F, size_t>;\n \n         auto shared = std::make_shared<detail::when_any_shared<sizeof...(Ts), void>>();\n         auto p = package<result_t()>(executor, [_f = std::forward<F>(f), _p = shared] {\n@@ -1479,7 +1487,7 @@ struct single_trigger {\n     static bool go(C& context, F&& f, size_t index) {\n         auto run{ false };\n         {\n-            std::unique_lock lock{ context._guard };\n+            std::unique_lock<std::mutex> lock{ context._guard };\n             if (!context._single_event) {\n                 for (auto i = 0u; i < context._holds.size(); ++i) {\n                     if (i != index) context._holds[i].reset();\n@@ -1504,7 +1512,7 @@ struct all_trigger {\n     static bool go(C& context, F&& f, size_t index) {\n         auto run{ false };\n         {\n-            std::unique_lock lock{ context._guard };\n+            std::unique_lock<std::mutex> lock{ context._guard };\n             context.apply(std::forward<F>(f), index);\n             if (--context._remaining == 0) run = true;\n         }\n@@ -1515,7 +1523,7 @@ struct all_trigger {\n     static bool go(C& context, std::exception_ptr error, size_t index) {\n         auto run{ false };\n         {\n-            std::unique_lock lock{ context._guard };\n+            std::unique_lock<std::mutex> lock{ context._guard };\n             if (--context._remaining == 0) {\n                 context.apply(std::move(error), index);\n                 run = true;\n@@ -1559,14 +1567,14 @@ void attach_tasks(size_t index, E executor, const std::shared_ptr<C>& context, T\n     auto&& hold = std::forward<T>(a).recover(std::move(executor), [_context = make_weak_ptr(context), _i = index](auto x) {\n             auto p = _context.lock();\n             if (!p) return;\n-            if (auto ex = x.exception(); ex) {\n+            if (auto ex = x.exception()) {\n                 p->failure(ex, _i);\n             } else {\n                 p->done(std::move(x), _i);\n             }\n         });\n \n-    std::unique_lock guard(context->_guard);\n+    std::unique_lock<std::mutex> guard(context->_guard);\n     context->_holds[index] = std::move(hold);\n }\n \n@@ -1672,8 +1680,8 @@ auto when_any(E executor, F&& f, std::pair<I, I> range) {\n \n template <typename E, typename F, typename... Args>\n auto async(E executor, F&& f, Args&&... args)\n-    -> future<std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>> {\n-    using result_type = std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>;\n+    -> future<detail::result_t<std::decay_t<F>, std::decay_t<Args>...>> {\n+    using result_type = detail::result_t<std::decay_t<F>, std::decay_t<Args>...>;\n \n     auto p = package<result_type()>(\n         executor, std::bind<result_type>(\n@@ -1785,7 +1793,7 @@ struct value_<T, enable_if_not_copyable<T>> {\n         sb._reduction_helper.value =\n             std::move(*sb._result)\n                 .recover([_p = sb.shared_from_this()](future<R> f) {\n-                    if (auto ex = std::move(f).exception(); ex) {\n+                    if (auto ex = std::move(f).exception()) {\n                         _p->_exception = ex;\n                         proceed(*_p);\n                         throw future_error(future_error_codes::reduction_failed);\n@@ -1840,8 +1848,8 @@ void shared_base<void>::set_value(F& f, Args&&... args) {\n \n template <typename E, typename F>\n auto shared_base<void>::recover(E&& executor, F&& f)\n-    -> future<reduced_t<std::invoke_result_t<F, future<void>>>> {\n-    auto p = package<std::invoke_result_t<F, future<void>>()>(\n+    -> future<reduced_t<detail::result_t<F, future<void>>>> {\n+    auto p = package<detail::result_t<F, future<void>>()>(\n         executor, [_f = std::forward<F>(f), _p = future<void>(this->shared_from_this())]() mutable {\n             return _f(_p);\n         });"},{"sha":"eb087f96ca7dbb6054ad601bef8a091885c82a77","filename":"stlab/concurrency/optional.hpp","status":"modified","additions":7,"deletions":1,"changes":8,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Foptional.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Foptional.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/stlab%2Fconcurrency%2Foptional.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -27,7 +27,13 @@\n         #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_STD()\n     #elif __has_include(<experimental/optional>)\n         #include <experimental/optional>\n-        #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_STD_EXPERIMENTAL()\n+        #if defined(__cpp_lib_experimental_optional)\n+            #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_STD_EXPERIMENTAL()\n+        #else\n+            #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_BOOST()\n+        #endif\n+    #else\n+        #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_BOOST()\n     #endif\n #else\n     #define STLAB_OPTIONAL_PRIVATE_SELECTION() STLAB_OPTIONAL_PRIVATE_BOOST()"},{"sha":"6e478f1f714600192f237c4dffecf5386478170f","filename":"stlab/concurrency/task.hpp","status":"modified","additions":12,"deletions":11,"changes":23,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Ftask.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Ftask.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/stlab%2Fconcurrency%2Ftask.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -37,18 +37,19 @@ class task;\n template <class R, class... Args>\n class task<R(Args...)> {\n \n-    template <typename F>\n-    constexpr static auto is_empty(const F& f){\n-        if constexpr (std::is_pointer<std::decay_t<F>>::value ||\n+    template <class F>\n+    constexpr static bool maybe_empty = std::is_pointer<std::decay_t<F>>::value ||\n                       std::is_member_pointer<std::decay_t<F>>::value ||\n-                      std::is_same<std::function<R(Args...)>, std::decay_t<F>>::value)\n-        {\n-            return !f;\n-        }\n-        else\n-        {\n-            return false;\n-        }\n+                      std::is_same<std::function<R(Args...)>, std::decay_t<F>>::value;\n+\n+    template <class F>\n+    constexpr static auto is_empty(const F& f) -> std::enable_if_t<maybe_empty<F>, bool> {\n+        return !f;\n+    }\n+\n+    template <class F>\n+    constexpr static auto is_empty(const F&) -> std::enable_if_t<!maybe_empty<F>, bool> {\n+        return false;\n     }\n \n     struct concept_t {"},{"sha":"97a74a009bef39e0508ab4e61bc1e9eaf99d76ef","filename":"stlab/concurrency/utility.hpp","status":"modified","additions":2,"deletions":2,"changes":4,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Futility.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Futility.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/stlab%2Fconcurrency%2Futility.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -165,7 +165,7 @@ inline void blocking_get(future<void> x) {\n     std::condition_variable condition;\n     std::mutex m;\n     auto hold = std::move(x).recover(immediate_executor, [&](auto&& r) {\n-        if (auto ex = std::forward<decltype(r)>(r).exception(); ex) error = ex;\n+        if (auto ex = std::forward<decltype(r)>(r).exception()) error = ex;\n         {\n             std::unique_lock<std::mutex> lock(m);\n             flag = true;\n@@ -190,7 +190,7 @@ inline bool blocking_get(future<void> x, const std::chrono::nanoseconds& timeout\n             if (!state) {\n                 return;\n             }\n-            if (auto ex = r.exception(); ex) state->error = ex;\n+            if (auto ex = r.exception()) state->error = ex;\n             {\n                 std::unique_lock<std::mutex> lock(state->m);\n                 state->flag = true;"},{"sha":"4730af5c2ac55f71e1002ecbab2a03434128199d","filename":"stlab/concurrency/variant.hpp","status":"modified","additions":2,"deletions":0,"changes":2,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Fvariant.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fconcurrency%2Fvariant.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/stlab%2Fconcurrency%2Fvariant.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -24,6 +24,8 @@\n     #if __has_include(<variant>) && STLAB_CPP_VERSION_AT_LEAST(17)\n         #include <variant>\n         #define STLAB_VARIANT_PRIVATE_SELECTION() STLAB_VARIANT_PRIVATE_STD()\n+    #else\n+        #define STLAB_VARIANT_PRIVATE_SELECTION() STLAB_VARIANT_PRIVATE_BOOST()\n     #endif\n #else\n     #define STLAB_VARIANT_PRIVATE_SELECTION() STLAB_VARIANT_PRIVATE_BOOST()"},{"sha":"e463d50287aaa288231201c222dfb930ade4aab2","filename":"stlab/forest_algorithms.hpp","status":"modified","additions":2,"deletions":2,"changes":4,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fforest_algorithms.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/stlab%2Fforest_algorithms.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/stlab%2Fforest_algorithms.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -72,7 +72,7 @@ struct transcribe_iterator {\n \n template <class Container>\n auto transcriber(Container& c) {\n-    return transcribe_iterator(c, c.begin());\n+    return transcribe_iterator<Container>(c, c.begin());\n }\n \n /**************************************************************************************************/\n@@ -115,7 +115,7 @@ auto flatten(I first, I last, O out) {\n         if (is_leading(first)) {\n             *out++ = *first;\n         } else {\n-            *out++ = std::nullopt;\n+            *out++ = nullopt;\n         }\n     }\n     return out;"},{"sha":"6a3d348a4ec13fbb246e1302ad86a2ac0bb73a4e","filename":"test/CMakeLists.txt","status":"modified","additions":47,"deletions":9,"changes":56,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2FCMakeLists.txt","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2FCMakeLists.txt","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2FCMakeLists.txt?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -17,7 +17,12 @@ if( NOT ( ${CMAKE_CXX_COMPILER_ID} STREQUAL \"MSVC\"\n endif()\n \n target_link_libraries( stlab.test.channel PUBLIC stlab::testing )\n-add_test( NAME stlab.test.channel COMMAND stlab.test.channel )\n+\n+add_test(\n+    NAME stlab.test.channel\n+    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:stlab.test.channel> -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake\n+)\n+\n \n ################################################################################\n \n@@ -28,8 +33,11 @@ add_executable( stlab.test.executor\n target_compile_definitions(stlab.test.executor PRIVATE STLAB_UNIT_TEST)\n \n target_link_libraries( stlab.test.executor PUBLIC stlab::testing )\n-add_test( NAME stlab.test.executor COMMAND stlab.test.executor )\n \n+add_test(\n+    NAME stlab.test.executor\n+    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:stlab.test.executor> -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake\n+)\n \n ################################################################################\n \n@@ -52,7 +60,12 @@ target_sources( stlab.test.future PUBLIC\n target_compile_definitions(stlab.test.future PRIVATE STLAB_UNIT_TEST)\n \n target_link_libraries( stlab.test.future PUBLIC stlab::testing )\n-add_test( NAME stlab.test.future COMMAND stlab.test.future )\n+\n+add_test(\n+    NAME stlab.test.future\n+    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:stlab.test.future> -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake\n+)\n+\n \n ################################################################################\n \n@@ -62,7 +75,11 @@ add_executable( stlab.test.serial_queue\n target_compile_definitions(stlab.test.serial_queue PRIVATE STLAB_UNIT_TEST)\n \n target_link_libraries( stlab.test.serial_queue PUBLIC stlab::testing )\n-add_test( NAME stlab.test.serial_queue COMMAND stlab.test.serial_queue )\n+\n+add_test(\n+    NAME stlab.test.serial_queue\n+    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:stlab.test.serial_queue> -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake\n+)\n \n ################################################################################\n \n@@ -73,7 +90,12 @@ add_executable( stlab.test.cow\n target_compile_definitions(stlab.test.cow PRIVATE STLAB_UNIT_TEST)\n \n target_link_libraries( stlab.test.cow PUBLIC stlab::testing )\n-add_test( NAME stlab.test.cow COMMAND stlab.test.cow )\n+\n+add_test(\n+    NAME stlab.test.cow\n+    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:stlab.test.cow> -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake\n+)\n+\n \n ################################################################################\n \n@@ -84,7 +106,11 @@ add_executable( stlab.test.task\n target_compile_definitions(stlab.test.task PRIVATE STLAB_UNIT_TEST)\n \n target_link_libraries( stlab.test.task PUBLIC stlab::testing )\n-add_test( NAME stlab.test.task COMMAND stlab.test.task )\n+\n+add_test(\n+    NAME stlab.test.task\n+    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:stlab.test.task> -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake\n+)\n \n ################################################################################\n \n@@ -95,7 +121,11 @@ add_executable( stlab.test.tuple\n target_compile_definitions(stlab.test.channel PRIVATE STLAB_UNIT_TEST)\n \n target_link_libraries( stlab.test.tuple PUBLIC stlab::testing )\n-add_test( NAME stlab.test.tuple COMMAND stlab.test.tuple )\n+\n+add_test(\n+    NAME stlab.test.tuple\n+    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:stlab.test.tuple> -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake\n+)\n \n ################################################################################\n \n@@ -106,7 +136,11 @@ add_executable( stlab.test.traits\n target_compile_definitions(stlab.test.channel PRIVATE STLAB_UNIT_TEST)\n \n target_link_libraries( stlab.test.traits PUBLIC stlab::testing )\n-add_test( NAME stlab.test.traits COMMAND stlab.test.traits )\n+\n+add_test(\n+    NAME stlab.test.traits\n+    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:stlab.test.traits> -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake\n+)\n \n ################################################################################\n \n@@ -115,7 +149,11 @@ add_executable( stlab.test.forest\n         main.cpp )\n \n target_link_libraries( stlab.test.forest PUBLIC stlab::testing )\n-add_test( NAME stlab.test.forest COMMAND stlab.test.forest )\n+\n+add_test(\n+    NAME stlab.test.forest\n+    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:stlab.test.forest> -P ${CMAKE_SOURCE_DIR}/cmake/RunTests.cmake\n+)\n \n ################################################################################\n #"},{"sha":"c454428acc6b9b8847283e97ec2fe3754888bd6b","filename":"test/channel_functor_tests.cpp","status":"modified","additions":20,"deletions":17,"changes":37,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_functor_tests.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_functor_tests.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Fchannel_functor_tests.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -17,10 +17,9 @@\n \n #include \"channel_test_helper.hpp\"\n \n-using namespace stlab;\n-using namespace channel_test_helper;\n \n-using channel_test_fixture_int_1 = channel_test_fixture<int, 1>;\n+\n+using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture<int, 1>;\n \n BOOST_FIXTURE_TEST_SUITE(int_channel_void_functor, channel_test_fixture_int_1)\n \n@@ -148,20 +147,22 @@ BOOST_AUTO_TEST_CASE(int_channel_split_int_functor_async) {\n \n BOOST_AUTO_TEST_SUITE_END()\n \n-using channel_test_fixture_move_only_1 = channel_test_fixture<stlab::move_only, 1>;\n+\n+using channel_test_fixture_move_only_1 = channel_test_helper::channel_test_fixture<stlab::move_only, 1>;\n \n BOOST_FIXTURE_TEST_SUITE(move_only_channel_void_functor, channel_test_fixture_move_only_1)\n \n+\n BOOST_AUTO_TEST_CASE(move_only_int_channel_void_functor) {\n     BOOST_TEST_MESSAGE(\"move only int channel void functor\");\n \n     std::atomic_int result{0};\n \n-    auto check = _receive[0] | [&](move_only x) { result += x.member(); };\n+    auto check = _receive[0] | [&](stlab::move_only x) { result += x.member(); };\n \n     _receive[0].set_ready();\n     for (int i = 0; i < 10; ++i) {\n-        _send[0](move_only(1));\n+        _send[0](stlab::move_only(1));\n     }\n \n     wait_until_done([&]() { return result == 10; });\n@@ -173,13 +174,13 @@ BOOST_AUTO_TEST_CASE(move_only_int_channel_void_functor_async) {\n \n     std::atomic_int result{0};\n \n-    auto check = _receive[0] | [&](move_only x) { result += x.member(); };\n+    auto check = _receive[0] | [&](stlab::move_only x) { result += x.member(); };\n \n     _receive[0].set_ready();\n-    std::vector<future<void>> f;\n+    std::vector<stlab::future<void>> f;\n     f.reserve(10);\n     for (int i = 0; i < 10; ++i) {\n-        f.push_back(async(default_executor, [& _send = _send[0]] { _send(move_only(1)); }));\n+        f.push_back(stlab::async(stlab::default_executor, [& _send = _send[0]] { _send(stlab::move_only(1)); }));\n     }\n \n     wait_until_done([&]() { return result == 10; });\n@@ -191,37 +192,39 @@ BOOST_AUTO_TEST_CASE(move_only_int_channel_int_functor) {\n \n     std::atomic_int result{0};\n \n-    auto check = _receive[0] | [](move_only x) { return move_only(2 * x.member()); } |\n-                 [&](move_only x) { result += x.member(); };\n+    auto check = _receive[0] | [](stlab::move_only x) { return stlab::move_only(2 * x.member()); } |\n+                 [&](stlab::move_only x) { result += x.member(); };\n \n     _receive[0].set_ready();\n     for (int i = 0; i < 10; ++i) {\n-        _send[0](move_only(1));\n+        _send[0](stlab::move_only(1));\n     }\n \n     wait_until_done([&]() { return result >= 20; });\n \n     BOOST_REQUIRE_EQUAL(20, result);\n }\n \n+\n BOOST_AUTO_TEST_CASE(move_only_int_channel_int_functor_async) {\n     BOOST_TEST_MESSAGE(\"move only int channel int functor asynchronously\");\n \n     std::atomic_int result{0};\n \n-    auto check = _receive[0] | [](move_only x) { return move_only(2 * x.member()); } |\n-                 [&](move_only x) { result += x.member(); };\n+    auto check = _receive[0] | [](stlab::move_only x) { return stlab::move_only(2 * x.member()); } |\n+                 [&](stlab::move_only x) { result += x.member(); };\n \n     _receive[0].set_ready();\n-    std::vector<future<void>> f;\n+    std::vector<stlab::future<void>> f;\n     f.reserve(10);\n     for (int i = 0; i < 10; ++i) {\n-        f.push_back(async(default_executor, [& _send = _send[0]] { _send(move_only(1)); }));\n+        f.push_back(stlab::async(stlab::default_executor, [& _send = _send[0]] { _send(stlab::move_only(1)); }));\n     }\n \n     wait_until_done([&]() { return result >= 20; });\n \n     BOOST_REQUIRE_EQUAL(20, result);\n }\n \n-BOOST_AUTO_TEST_SUITE_END()\n+\n+BOOST_AUTO_TEST_SUITE_END()\n\\ No newline at end of file"},{"sha":"08e2a2245b5a3a7f249e8a13c60a7f8f46d792ac","filename":"test/channel_merge_round_robin_tests.cpp","status":"modified","additions":28,"deletions":31,"changes":59,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_merge_round_robin_tests.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_merge_round_robin_tests.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Fchannel_merge_round_robin_tests.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -16,17 +16,14 @@\n \n #include \"channel_test_helper.hpp\"\n \n-using namespace stlab;\n-using namespace channel_test_helper;\n-\n-using channel_test_fixture_int_1 = channel_test_fixture<int, 1>;\n+using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture<int, 1>;\n \n BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_one_value, channel_test_fixture_int_1) {\n     BOOST_TEST_MESSAGE(\"int merge round robin channel void functor one value one value\");\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<round_robin_t>(default_executor, [&](int x) { result = x; }, _receive[0]);\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor, [&](int x) { result = x; }, _receive[0]);\n \n     _receive[0].set_ready();\n     _send[0](1);\n@@ -41,10 +38,10 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_one_value_asy\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<round_robin_t>(default_executor, [&](int x) { result = x; }, _receive[0]);\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor, [&](int x) { result = x; }, _receive[0]);\n \n     _receive[0].set_ready();\n-    auto f = async(default_executor, [_sender = _send[0]] { _sender(1); });\n+    auto f = stlab::async(stlab::default_executor, [_sender = _send[0]] { _sender(1); });\n \n     wait_until_done([&]() { return result != 0; });\n \n@@ -56,7 +53,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_many_values,\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<round_robin_t>(default_executor, [&](int x) { result += x; }, _receive[0]);\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0]);\n \n     _receive[0].set_ready();\n     for (auto i = 1; i <= 100; ++i)\n@@ -75,12 +72,12 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_many_values_a\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<round_robin_t>(default_executor, [&](int x) { result += x; }, _receive[0]);\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0]);\n \n     _receive[0].set_ready();\n-    std::vector<future<void>> f(100);\n+    std::vector<stlab::future<void>> f(100);\n     for (auto i = 1; i <= 100; ++i) {\n-        f.push_back(async(default_executor, [_sender = _send[0], i] { _sender(i); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_sender = _send[0], i] { _sender(i); }));\n     }\n \n     auto expected = 100 * (100 + 1) / 2;\n@@ -89,15 +86,15 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_void_functor_many_values_a\n     BOOST_REQUIRE_EQUAL(expected, result);\n }\n \n-using channel_test_fixture_int_2 = channel_test_fixture<int, 2>;\n+using channel_test_fixture_int_2 = channel_test_helper::channel_test_fixture<int, 2>;\n \n BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_one_value,\n                         channel_test_fixture_int_2) {\n     BOOST_TEST_MESSAGE(\"int merge round robin channel same type void functor oane value\");\n \n     std::atomic_int result{0};\n     int incrementer{1};\n-    auto check = merge_channel<round_robin_t>(default_executor,\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor,\n                      [&](int x) {\n                          result += incrementer * x;\n                          ++incrementer;\n@@ -121,7 +118,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_one\n \n     std::atomic_int result{0};\n     int incrementer{1};\n-    auto check = merge_channel<round_robin_t>(default_executor,\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor,\n                      [&](int x) {\n                          result += incrementer * x;\n                          ++incrementer;\n@@ -131,7 +128,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_one\n     _receive[0].set_ready();\n     _receive[1].set_ready();\n     auto f =\n-        async(default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference\n+      stlab::async(stlab::default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference\n             _send1(2);\n             _send2(3);\n         });\n@@ -148,7 +145,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man\n \n     std::atomic_int result{0};\n     int incrementer{1};\n-    auto check = merge_channel<round_robin_t>(default_executor,\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor,\n                      [&](int x) {\n                          result += incrementer * x;\n                          ++incrementer;\n@@ -170,7 +167,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man\n     BOOST_REQUIRE_EQUAL(expectation, result);\n }\n \n-using channel_test_fixture_pair_2 = channel_test_fixture<std::pair<int, std::size_t>, 5>;\n+using channel_test_fixture_pair_2 = channel_test_helper::channel_test_fixture<std::pair<int, std::size_t>, 5>;\n \n BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_many_values_async,\n                         channel_test_fixture_pair_2) {\n@@ -180,7 +177,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man\n     std::atomic_bool zipped_ok{true};\n     std::size_t expected_input{0};\n \n-    auto check = merge_channel<round_robin_t>(default_executor,\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor,\n                      [&](std::pair<int, std::size_t> x) {\n                          result += x.first;\n                          zipped_ok = zipped_ok && (x.second == expected_input);\n@@ -190,12 +187,12 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man\n \n     _receive[0].set_ready();\n     _receive[1].set_ready();\n-    std::vector<future<void>> f(200);\n+    std::vector<stlab::future<void>> f(200);\n     for (auto i = 1; i <= 200; i += 2) {\n-        f.push_back(async(default_executor, [& _send1 = _send[0], _i = i] {\n+        f.push_back(stlab::async(stlab::default_executor, [& _send1 = _send[0], _i = i] {\n             _send1(std::make_pair(_i, std::size_t(0)));\n         }));\n-        f.push_back(async(default_executor, [& _send2 = _send[1], _i = i] {\n+        f.push_back(stlab::async(stlab::default_executor, [& _send2 = _send[1], _i = i] {\n             _send2(std::make_pair(_i + 1, std::size_t(1)));\n         }));\n     }\n@@ -208,20 +205,20 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_man\n     BOOST_REQUIRE_EQUAL(expectation, result);\n }\n \n-using channel_test_fixture_int_5 = channel_test_fixture<int, 5>;\n+using channel_test_fixture_int_5 = channel_test_helper::channel_test_fixture<int, 5>;\n \n BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor, channel_test_fixture_int_5) {\n     BOOST_TEST_MESSAGE(\"int merge round robin channel same type void functor\");\n \n     std::atomic_int result{0};\n     std::atomic_int incrementer{1};\n \n-    auto check = merge_channel<round_robin_t>(default_executor,\n-                     [&](int x) {\n-                         result += incrementer * x;\n-                         ++incrementer;\n-                     },\n-                     _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]);\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor,\n+                                                     [&](int x) {\n+                                                         result += incrementer * x;\n+                                                         ++incrementer;\n+                                                     },\n+                                                     _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]);\n \n     for (auto& r : _receive)\n         r.set_ready();\n@@ -242,7 +239,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_asy\n     std::atomic_int result{0};\n     std::atomic_int incrementer{1};\n \n-    auto check = merge_channel<round_robin_t>(default_executor,\n+    auto check = stlab::merge_channel<stlab::round_robin_t>(stlab::default_executor,\n                      [&](int x) {\n                          result += incrementer * x;\n                          ++incrementer;\n@@ -252,9 +249,9 @@ BOOST_FIXTURE_TEST_CASE(int_merge_round_robin_channel_same_type_void_functor_asy\n     for (auto& r : _receive)\n         r.set_ready();\n \n-    std::vector<future<void>> f(5);\n+    std::vector<stlab::future<void>> f(5);\n     for (auto i = 0; i < 5; i++) {\n-        f.push_back(async(default_executor, [_send = _send[i], _i = i] { _send(_i + 2); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_send = _send[i], _i = i] { _send(_i + 2); }));\n     }\n \n     const auto expected = 2 * 1 + 3 * 2 + 4 * 3 + 5 * 4 + 6 * 5;"},{"sha":"aad8ef7bc1abd205459c06732162e25ba66e472a","filename":"test/channel_merge_unordered_tests.cpp","status":"modified","additions":22,"deletions":25,"changes":47,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_merge_unordered_tests.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_merge_unordered_tests.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Fchannel_merge_unordered_tests.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -14,17 +14,14 @@\n \n #include \"channel_test_helper.hpp\"\n \n-using namespace stlab;\n-using namespace channel_test_helper;\n-\n-using channel_test_fixture_int_1 = channel_test_fixture<int, 1>;\n+using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture<int, 1>;\n \n BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_one_value, channel_test_fixture_int_1) {\n     BOOST_TEST_MESSAGE(\"int merge unordered_t channel void functor one value one value\");\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result = x; }, _receive[0]);\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result = x; }, _receive[0]);\n \n     _receive[0].set_ready();\n     _send[0](1);\n@@ -40,10 +37,10 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_one_value_async\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result = x; }, _receive[0]);\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result = x; }, _receive[0]);\n \n     _receive[0].set_ready();\n-    auto f = async(default_executor, [_sender = _send[0]] { _sender(1); });\n+    auto f = stlab::async(stlab::default_executor, [_sender = _send[0]] { _sender(1); });\n \n     wait_until_done([&] { return result != 0; });\n \n@@ -55,7 +52,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_many_values, ch\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result += x; }, _receive[0]);\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0]);\n \n     _receive[0].set_ready();\n     for (auto i = 1; i <= 100; ++i)\n@@ -74,12 +71,12 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_many_values_asy\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result += x; }, _receive[0]);\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0]);\n \n     _receive[0].set_ready();\n-    std::vector<future<void>> f(100);\n+    std::vector<stlab::future<void>> f(100);\n     for (auto i = 1; i <= 100; ++i) {\n-        f.push_back(async(default_executor, [_sender = _send[0], i] { _sender(i); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_sender = _send[0], i] { _sender(i); }));\n     }\n \n     auto expected = 100 * (100 + 1) / 2;\n@@ -88,15 +85,15 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_void_functor_many_values_asy\n     BOOST_REQUIRE_EQUAL(expected, result);\n }\n \n-using channel_test_fixture_int_2 = channel_test_fixture<int, 2>;\n+using channel_test_fixture_int_2 = channel_test_helper::channel_test_fixture<int, 2>;\n \n BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_one_value,\n                         channel_test_fixture_int_2) {\n     BOOST_TEST_MESSAGE(\"int merge unordered_t channel same type void functor oane value\");\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]);\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]);\n \n     _receive[0].set_ready();\n     _receive[1].set_ready();\n@@ -114,12 +111,12 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_one_v\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]);\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]);\n \n     _receive[0].set_ready();\n     _receive[1].set_ready();\n     auto f =\n-        async(default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference\n+      stlab::async(stlab::default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference\n             _send1(2);\n             _send2(3);\n         });\n@@ -135,7 +132,7 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_many_\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]);\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]);\n \n     _receive[0].set_ready();\n     _receive[1].set_ready();\n@@ -157,14 +154,14 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_many_\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]);\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1]);\n \n     _receive[0].set_ready();\n     _receive[1].set_ready();\n-    std::vector<future<void>> f(20);\n+    std::vector<stlab::future<void>> f(20);\n     for (auto i = 0; i < 10; i++) {\n-        f.push_back(async(default_executor, [_send1 = _send[0], i] { _send1(i); }));\n-        f.push_back(async(default_executor, [& _send2 = _send[1], i] { _send2(i + 1); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_send1 = _send[0], i] { _send1(i); }));\n+        f.push_back(stlab::async(stlab::default_executor, [& _send2 = _send[1], i] { _send2(i + 1); }));\n     }\n \n     const auto expected =\n@@ -174,13 +171,13 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_many_\n     BOOST_REQUIRE_EQUAL(expected, result);\n }\n \n-using channel_test_fixture_int_5 = channel_test_fixture<int, 5>;\n+using channel_test_fixture_int_5 = channel_test_helper::channel_test_fixture<int, 5>;\n BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor, channel_test_fixture_int_5) {\n     BOOST_TEST_MESSAGE(\"int merge unordered_t channel same type void functor\");\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1],\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1],\n                        _receive[2], _receive[3], _receive[4]);\n \n     for (auto& r : _receive)\n@@ -202,15 +199,15 @@ BOOST_FIXTURE_TEST_CASE(int_merge_unordered_channel_same_type_void_functor_async\n \n     std::atomic_int result{0};\n \n-    auto check = merge_channel<unordered_t>(default_executor, [&](int x) { result += x; }, _receive[0], _receive[1],\n+    auto check = stlab::merge_channel<stlab::unordered_t>(stlab::default_executor, [&](int x) { result += x; }, _receive[0], _receive[1],\n                        _receive[2], _receive[3], _receive[4]);\n \n     for (auto& r : _receive)\n         r.set_ready();\n \n-    std::vector<future<void>> f(5);\n+    std::vector<stlab::future<void>> f(5);\n     for (auto i = 0; i < 5; i++) {\n-        f.push_back(async(default_executor, [_send = _send[i], i] { _send(i + 2); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_send = _send[i], i] { _send(i + 2); }));\n     }\n \n     const auto expectation = 2 + 3 + 4 + 5 + 6;"},{"sha":"dcf4bcb0f1c7c2a016d89668fd1f9613dc7b0d33","filename":"test/channel_merge_zip_with_tests.cpp","status":"modified","additions":37,"deletions":38,"changes":75,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_merge_zip_with_tests.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_merge_zip_with_tests.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Fchannel_merge_zip_with_tests.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -15,17 +15,16 @@\n \n #include \"channel_test_helper.hpp\"\n \n-using namespace stlab;\n-using namespace channel_test_helper;\n \n-using channel_test_fixture_int_1 = channel_test_fixture<int, 1>;\n+\n+using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture<int, 1>;\n \n BOOST_FIXTURE_TEST_CASE(int_zip_with_channel_void_functor_one_value, channel_test_fixture_int_1) {\n     BOOST_TEST_MESSAGE(\"int zip_with channel void functor one value one value\");\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor, [&](int x) { result = x; }, _receive[0]);\n+    auto check = zip_with(stlab::default_executor, [&](int x) { result = x; }, _receive[0]);\n \n     _receive[0].set_ready();\n     _send[0](1);\n@@ -40,10 +39,10 @@ BOOST_FIXTURE_TEST_CASE(int_zip_with_channel_void_functor_one_value_async, chann\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor, [&](int x) { result = x; }, _receive[0]);\n+    auto check = stlab::zip_with(stlab::default_executor, [&](int x) { result = x; }, _receive[0]);\n \n     _receive[0].set_ready();\n-    auto f = async(default_executor, [_sender = _send[0]] { _sender(1); });\n+    auto f = stlab::async(stlab::default_executor, [_sender = _send[0]] { _sender(1); });\n \n     wait_until_done([&]() { return result != 0; });\n \n@@ -55,7 +54,7 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_void_functor_many_values, channel_\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor, [&](int x) { result += x; }, _receive[0]);\n+    auto check = stlab::zip_with(stlab::default_executor, [&](int x) { result += x; }, _receive[0]);\n \n     _receive[0].set_ready();\n     for (auto i = 1; i <= 100; ++i)\n@@ -74,12 +73,12 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_void_functor_many_values_async,\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor, [&](int x) { result += x; }, _receive[0]);\n+    auto check = stlab::zip_with(stlab::default_executor, [&](int x) { result += x; }, _receive[0]);\n \n     _receive[0].set_ready();\n-    std::vector<future<void>> f(100);\n+    std::vector<stlab::future<void>> f(100);\n     for (auto i = 1; i <= 100; ++i) {\n-        f.push_back(async(default_executor, [_sender = _send[0], _i = i] { _sender(_i); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_sender = _send[0], _i = i] { _sender(_i); }));\n     }\n \n     auto expected = 100 * (100 + 1) / 2;\n@@ -88,15 +87,15 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_void_functor_many_values_async,\n     BOOST_REQUIRE_EQUAL(expected, result);\n }\n \n-using channel_test_fixture_int_2 = channel_test_fixture<int, 2>;\n+using channel_test_fixture_int_2 = channel_test_helper::channel_test_fixture<int, 2>;\n \n BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_one_value,\n                         channel_test_fixture_int_2) {\n     BOOST_TEST_MESSAGE(\"int zip_with channel same type void functor oane value\");\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0],\n+    auto check = stlab::zip_with(stlab::default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0],\n                       _receive[1]);\n \n     _receive[0].set_ready();\n@@ -115,13 +114,13 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_one_value_a\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0],\n+    auto check = stlab::zip_with(stlab::default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0],\n                       _receive[1]);\n \n     _receive[0].set_ready();\n     _receive[1].set_ready();\n     auto f =\n-        async(default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference\n+      stlab::async(stlab::default_executor, [_send1 = _send[0], &_send2 = _send[1]] { // one copy,one reference\n             _send1(2);\n             _send2(3);\n         });\n@@ -137,7 +136,7 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_many_values\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0],\n+    auto check = stlab::zip_with(stlab::default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0],\n                       _receive[1]);\n \n     _receive[0].set_ready();\n@@ -160,15 +159,15 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_many_values\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0],\n+    auto check = zip_with(stlab::default_executor, [&](int x, int y) { result += 2 * x + 3 * y; }, _receive[0],\n                       _receive[1]);\n \n     _receive[0].set_ready();\n     _receive[1].set_ready();\n-    std::vector<future<void>> f(20);\n+    std::vector<stlab::future<void>> f(20);\n     for (auto i = 0; i < 10; i++) {\n-        f.push_back(async(default_executor, [_send1 = _send[0], _i = i] { _send1(_i); }));\n-        f.push_back(async(default_executor, [& _send2 = _send[1], _i = i] { _send2(_i + 1); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_send1 = _send[0], _i = i] { _send1(_i); }));\n+        f.push_back(stlab::async(stlab::default_executor, [& _send2 = _send[1], _i = i] { _send2(_i + 1); }));\n     }\n \n     const auto expected =\n@@ -178,14 +177,14 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_many_values\n     BOOST_REQUIRE_EQUAL(expected, result);\n }\n \n-using channel_test_fixture_int_5 = channel_test_fixture<int, 5>;\n+using channel_test_fixture_int_5 = channel_test_helper::channel_test_fixture<int, 5>;\n BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor, channel_test_fixture_int_5) {\n     BOOST_TEST_MESSAGE(\"int zip_with channel same type void functor\");\n \n     std::atomic_int result{0};\n \n     auto check = zip_with(\n-        default_executor,\n+        stlab::default_executor,\n         [&](int v, int w, int x, int y, int z) { result += 2 * v + 3 * w + 4 * x + 5 * y + 6 * z; },\n         _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]);\n \n@@ -207,17 +206,17 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_async, chan\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(\n-        default_executor,\n+    auto check = stlab::zip_with(\n+        stlab::default_executor,\n         [&](int v, int w, int x, int y, int z) { result += 2 * v + 3 * w + 4 * x + 5 * y + 6 * z; },\n         _receive[0], _receive[1], _receive[2], _receive[3], _receive[4]);\n \n     for (auto& r : _receive)\n         r.set_ready();\n \n-    std::vector<future<void>> f(5);\n+    std::vector<stlab::future<void>> f(5);\n     for (auto i = 0; i < 5; i++) {\n-        f.push_back(async(default_executor, [_send = _send[i], _i = i] { _send(_i + 2); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_send = _send[i], _i = i] { _send(_i + 2); }));\n     }\n \n     wait_until_done([&]() { return result != 0; });\n@@ -226,17 +225,17 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_same_type_void_functor_async, chan\n     BOOST_REQUIRE_EQUAL(expected, result);\n }\n \n-using channel_types_test_fixture_int_string = channel_types_test_fixture<int, std::string>;\n+using channel_types_test_fixture_int_string = channel_test_helper::channel_types_test_fixture<int, std::string>;\n \n BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_different_type_void_functor,\n                         channel_types_test_fixture_int_string) {\n     BOOST_TEST_MESSAGE(\"int zip_with channel different type void functor\");\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor,\n-                      [&](int, std::string y) { result += 2 + static_cast<int>(y.size()); },\n-                      receive<0>(), receive<1>());\n+    auto check = stlab::zip_with(stlab::default_executor,\n+                          [&](int, std::string y) { result += 2 + static_cast<int>(y.size()); },\n+                          receive<0>(), receive<1>());\n \n     receive<0>().set_ready();\n     receive<1>().set_ready();\n@@ -254,14 +253,14 @@ BOOST_FIXTURE_TEST_CASE(int_zip_width_channel_2_join_different_type_void_functor\n \n     std::atomic_int result{0};\n \n-    auto check = zip_with(default_executor,\n+    auto check = stlab::zip_with(stlab::default_executor,\n                       [&](int x, std::string y) { result += x + static_cast<int>(y.size()); },\n                       receive<0>(), receive<1>());\n \n     receive<0>().set_ready();\n     receive<1>().set_ready();\n-    auto f1 = async(default_executor, [_send = send<0>()] { _send(2); });\n-    auto f2 = async(default_executor, [_send = send<1>()] { _send(\"Foo\"); });\n+    auto f1 = stlab::async(stlab::default_executor, [_send = send<0>()] { _send(2); });\n+    auto f2 = stlab::async(stlab::default_executor, [_send = send<1>()] { _send(\"Foo\"); });\n \n     wait_until_done([&]() { return result != 0; });\n \n@@ -274,15 +273,15 @@ BOOST_FIXTURE_TEST_CASE(int_zip_with_channel_2_different_type_void_functor_async\n \n     std::atomic_int result{0};\n \n-\t\tauto check = zip(default_executor, receive<0>(), receive<1>()) | \n-\t\t\t\t[&](std::tuple<int, std::string> v) { \n-\t\t\t\t\t\tresult += std::get<0>(v) + static_cast<int>(std::get<1>(v).size()); \n-\t\t\t\t};\n+    auto check = stlab::zip(stlab::default_executor, receive<0>(), receive<1>()) |\n+        [&](std::tuple<int, std::string> v) { \n+            result += std::get<0>(v) + static_cast<int>(std::get<1>(v).size()); \n+        };\n \n     receive<0>().set_ready();\n     receive<1>().set_ready();\n-    auto f1 = async(default_executor, [_send = send<0>()] { _send(2); });\n-    auto f2 = async(default_executor, [_send = send<1>()] { _send(\"Foo\"); });\n+    auto f1 = stlab::async(stlab::default_executor, [_send = send<0>()] { _send(2); });\n+    auto f2 = stlab::async(stlab::default_executor, [_send = send<1>()] { _send(\"Foo\"); });\n \n     wait_until_done([&]() { return result != 0; });\n "},{"sha":"7f5a6b5bdeaa8b933f9b7b4c05e18576c21ecdf5","filename":"test/channel_process_tests.cpp","status":"modified","additions":43,"deletions":46,"changes":89,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_process_tests.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_process_tests.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Fchannel_process_tests.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -17,10 +17,7 @@\n \n #include \"channel_test_helper.hpp\"\n \n-using namespace stlab;\n-using namespace channel_test_helper;\n-\n-using channel_test_fixture_int_1 = channel_test_fixture<int, 1>;\n+using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture<int, 1>;\n \n BOOST_FIXTURE_TEST_SUITE(int_channel_process_void_functor, channel_test_fixture_int_1)\n \n@@ -30,7 +27,7 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_one_step) {\n     std::atomic_int index{0};\n     std::vector<int> results(10, 0);\n \n-    auto check = _receive[0] | sum<1>() | [&](int x) {\n+    auto check = _receive[0] | channel_test_helper::sum<1>() | [&](int x) {\n         results[index] = x;\n         ++index;\n     };\n@@ -52,15 +49,15 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_one_step_async) {\n     std::atomic_int index{0};\n     std::vector<int> results(10, 0);\n \n-    auto check = _receive[0] | sum<1>() | [&](int x) {\n+    auto check = _receive[0] | channel_test_helper::sum<1>() | [&](int x) {\n         results[x] = x;\n         ++index;\n     };\n \n     _receive[0].set_ready();\n-    std::vector<future<void>> f(10);\n+    std::vector<stlab::future<void>> f(10);\n     for (auto i = 0; i < 10; ++i) {\n-        f.push_back(async(default_executor, [_send = _send[0], i] { _send(i); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_send = _send[0], i] { _send(i); }));\n     }\n \n     wait_until_done([&] { return index == 10; });\n@@ -76,7 +73,7 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_two_steps) {\n     std::atomic_int index{0};\n     std::vector<int> results(5, 0);\n \n-    auto check = _receive[0] | sum<2>() | [&](int x) {\n+    auto check = _receive[0] | channel_test_helper::sum<2>() | [&](int x) {\n         results[index] = x;\n         ++index;\n     };\n@@ -99,15 +96,15 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_two_steps_async) {\n     std::atomic_int index{0};\n     std::vector<std::vector<int>> results;\n \n-    auto check = _receive[0] | collector<2>() | [&](std::vector<int> x) {\n+    auto check = _receive[0] | channel_test_helper::collector<2>() | [&](std::vector<int> x) {\n         results.push_back(x);\n         ++index;\n     };\n \n     _receive[0].set_ready();\n-    std::vector<future<void>> f(10);\n+    std::vector<stlab::future<void>> f(10);\n     for (auto i = 0; i < 10; ++i) {\n-        f.push_back(async(default_executor, [_send = _send[0], i] { _send(i); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_send = _send[0], i] { _send(i); }));\n     }\n \n     wait_until_done([&] { return index == 5; });\n@@ -130,7 +127,7 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_many_steps) {\n \n     std::atomic_int result{0};\n \n-    auto check = _receive[0] | sum<10>() | [&](int x) { result = x; };\n+    auto check = _receive[0] | channel_test_helper::sum<10>() | [&](int x) { result = x; };\n \n     _receive[0].set_ready();\n     for (auto i = 0; i < 10; ++i)\n@@ -146,12 +143,12 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_many_steps_async) {\n \n     std::atomic_int result{0};\n \n-    auto check = _receive[0] | sum<10>() | [&](int x) { result = x; };\n+    auto check = _receive[0] | channel_test_helper::sum<10>() | [&](int x) { result = x; };\n \n     _receive[0].set_ready();\n-    std::vector<future<void>> f(10);\n+    std::vector<stlab::future<void>> f(10);\n     for (auto i = 0; i < 10; ++i) {\n-        f.push_back(async(default_executor, [_send = _send[0], i] { _send(i); }));\n+        f.push_back(stlab::async(stlab::default_executor, [_send = _send[0], i] { _send(i); }));\n     }\n \n     wait_until_done([&] { return result != 0; });\n@@ -167,11 +164,11 @@ BOOST_AUTO_TEST_CASE(int_channel_split_process_one_step) {\n     std::atomic_int index2{0};\n     std::vector<int> results2(10, 0);\n \n-    auto check1 = _receive[0] | sum<1>() | [& _index = index1, &_results = results1](int x) {\n+    auto check1 = _receive[0] | channel_test_helper::sum<1>() | [& _index = index1, &_results = results1](int x) {\n         _results[x] = x;\n         ++_index;\n     };\n-    auto check2 = _receive[0] | sum<1>() | [& _index = index2, &_results = results2](int x) {\n+    auto check2 = _receive[0] | channel_test_helper::sum<1>() | [& _index = index2, &_results = results2](int x) {\n         _results[x] = x;\n         ++_index;\n     };\n@@ -196,11 +193,11 @@ BOOST_AUTO_TEST_CASE(int_channel_split_process_two_steps) {\n     std::atomic_int index2{0};\n     std::vector<int> results2(5);\n \n-    auto check1 = _receive[0] | sum<2>() | [& _index = index1, &_results = results1](int x) {\n+    auto check1 = _receive[0] | channel_test_helper::sum<2>() | [& _index = index1, &_results = results1](int x) {\n         _results[_index] = x;\n         ++_index;\n     };\n-    auto check2 = _receive[0] | sum<2>() | [& _index = index2, &_results = results2](int x) {\n+    auto check2 = _receive[0] | channel_test_helper::sum<2>() | [& _index = index2, &_results = results2](int x) {\n         _results[_index] = x;\n         ++_index;\n     };\n@@ -224,8 +221,8 @@ BOOST_AUTO_TEST_CASE(int_channel_split_process_many_steps) {\n     std::atomic_int result1{0};\n     std::atomic_int result2{0};\n \n-    auto check1 = _receive[0] | sum<10>() | [& _result = result1](int x) { _result = x; };\n-    auto check2 = _receive[0] | sum<10>() | [& _result = result2](int x) { _result = x; };\n+    auto check1 = _receive[0] | channel_test_helper::sum<10>() | [& _result = result1](int x) { _result = x; };\n+    auto check2 = _receive[0] | channel_test_helper::sum<10>() | [& _result = result2](int x) { _result = x; };\n \n     _receive[0].set_ready();\n     for (auto i = 0; i < 10; ++i)\n@@ -242,26 +239,26 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_two_steps_timed) {\n     BOOST_TEST_MESSAGE(\"int channel process with two steps timed\");\n \n     std::atomic_int result{0};\n-    sender<int> send;\n-    receiver<int> receive;\n+    stlab::sender<int> send;\n+    stlab::receiver<int> receive;\n \n-    std::tie(send, receive) = channel<int>(manual_scheduler());\n+    std::tie(send, receive) = stlab::channel<int>(channel_test_helper::manual_scheduler());\n \n-    auto check = receive | timed_sum() | [&](int x) { result = x; };\n+    auto check = receive | channel_test_helper::timed_sum() | [&](int x) { result = x; };\n \n     receive.set_ready();\n     send(42);\n \n-    manual_scheduler::run_next_task();\n+    channel_test_helper::manual_scheduler::run_next_task();\n \n-    manual_scheduler::wait_until_queue_size_of(1);\n-    manual_scheduler::run_next_task();\n+    channel_test_helper::manual_scheduler::wait_until_queue_size_of(1);\n+    channel_test_helper::manual_scheduler::run_next_task();\n \n-    manual_scheduler::wait_until_queue_size_of(1);\n-    manual_scheduler::run_next_task();\n+    channel_test_helper::manual_scheduler::wait_until_queue_size_of(1);\n+    channel_test_helper::manual_scheduler::run_next_task();\n \n-    manual_scheduler::wait_until_queue_size_of(1);\n-    manual_scheduler::run_next_task();\n+    channel_test_helper::manual_scheduler::wait_until_queue_size_of(1);\n+    channel_test_helper::manual_scheduler::run_next_task();\n \n     while (result == 0) {\n         std::this_thread::sleep_for(std::chrono::milliseconds(10));\n@@ -274,17 +271,17 @@ BOOST_AUTO_TEST_CASE(int_channel_process_with_two_steps_timed_wo_timeout) {\n     BOOST_TEST_MESSAGE(\"int channel process with two steps timed w/o timeout\");\n \n     std::atomic_int result{0};\n-    sender<int> send;\n-    receiver<int> receive;\n+    stlab::sender<int> send;\n+    stlab::receiver<int> receive;\n \n-    std::tie(send, receive) = channel<int>(default_executor);\n+    std::tie(send, receive) = stlab::channel<int>(stlab::default_executor);\n \n-    auto check = receive | timed_sum(2) | [&](int x) { result = x; };\n+    auto check = receive | channel_test_helper::timed_sum(2) | [&](int x) { result = x; };\n \n     receive.set_ready();\n     send(42);\n \n-    while (timed_sum::current_sum() != 42) {\n+    while (channel_test_helper::timed_sum::current_sum() != 42) {\n         std::this_thread::sleep_for(std::chrono::milliseconds(10));\n     }\n \n@@ -309,18 +306,18 @@ struct process_with_set_error {\n \n     int yield() { return 42; }\n \n-    auto state() const { return await_forever; }\n+    auto state() const { return stlab::await_forever; }\n };\n } // namespace\n \n BOOST_AUTO_TEST_CASE(int_channel_process_set_error_is_called_on_upstream_error) {\n     BOOST_TEST_MESSAGE(\"int channel process set_error is called on upstream error\");\n \n     std::atomic_bool check{false};\n-    sender<int> send;\n-    receiver<int> receive;\n+    stlab::sender<int> send;\n+    stlab::receiver<int> receive;\n \n-    std::tie(send, receive) = channel<int>(default_executor);\n+    std::tie(send, receive) = stlab::channel<int>(stlab::default_executor);\n \n     auto result = receive |\n                   [](auto v) {\n@@ -351,18 +348,18 @@ struct process_with_close {\n \n     int yield() { return 42; }\n \n-    auto state() const { return await_forever; }\n+    auto state() const { return stlab::await_forever; }\n };\n } // namespace\n \n BOOST_AUTO_TEST_CASE(int_channel_process_close_is_called_on_upstream_error) {\n     BOOST_TEST_MESSAGE(\"int channel process close is called when an upstream eeror happened\");\n \n     std::atomic_bool check{false};\n-    sender<int> send;\n-    receiver<int> receive;\n+    stlab::sender<int> send;\n+    stlab::receiver<int> receive;\n \n-    std::tie(send, receive) = channel<int>(default_executor);\n+    std::tie(send, receive) = stlab::channel<int>(stlab::default_executor);\n \n     auto result = receive |\n                   [](auto v) {"},{"sha":"29c8d1450965c1704a765fd8ab468915ca96865e","filename":"test/channel_test_helper.hpp","status":"modified","additions":2,"deletions":0,"changes":2,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_test_helper.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_test_helper.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Fchannel_test_helper.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -10,13 +10,15 @@\n #define CHANNEL_TEST_HELPER\n \n #include <stlab/concurrency/channel.hpp>\n+\n #include <stlab/concurrency/default_executor.hpp>\n #include <stlab/concurrency/task.hpp>\n #include <stlab/scope.hpp>\n \n #include <queue>\n #include <thread>\n \n+\n using lock_t = std::unique_lock<std::mutex>;\n \n namespace channel_test_helper {"},{"sha":"674787a0eba21fa5f884888d643849648f643591","filename":"test/channel_tests.cpp","status":"modified","additions":131,"deletions":134,"changes":265,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_tests.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Fchannel_tests.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Fchannel_tests.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -21,30 +21,26 @@\n \n #include \"channel_test_helper.hpp\"\n \n-using namespace stlab;\n-using namespace std;\n-using namespace channel_test_helper;\n-\n BOOST_AUTO_TEST_CASE(int_sender) {\n     BOOST_TEST_MESSAGE(\"int sender\");\n \n-    sender<int> send;\n+    stlab::sender<int> send;\n \n     BOOST_REQUIRE_NO_THROW(send(42));\n }\n \n BOOST_AUTO_TEST_CASE(int_receiver) {\n     BOOST_TEST_MESSAGE(\"int receiver\");\n \n-    receiver<int> receive;\n+    stlab::receiver<int> receive;\n \n     BOOST_REQUIRE_EQUAL(false, receive.ready());\n \n     receive.set_ready();\n     BOOST_REQUIRE_EQUAL(true, receive.ready());\n }\n \n-using channel_test_fixture_int_1 = channel_test_fixture<int, 1>;\n+using channel_test_fixture_int_1 = channel_test_helper::channel_test_fixture<int, 1>;\n \n BOOST_FIXTURE_TEST_SUITE(int_channel, channel_test_fixture_int_1)\n BOOST_AUTO_TEST_CASE(int_channel) {\n@@ -59,10 +55,10 @@ BOOST_AUTO_TEST_CASE(int_channel) {\n BOOST_AUTO_TEST_CASE(int_channel_move_ctor_sender) {\n     BOOST_TEST_MESSAGE(\"int channel move ctor sender\");\n \n-    atomic_int result{0};\n+    std::atomic_int result{0};\n \n     auto check = _receive[0] | [&](int x) { result = x; };\n-    auto sut = move(_send[0]);\n+    auto sut = std::move(_send[0]);\n \n     _receive[0].set_ready();\n     sut(42);\n@@ -75,11 +71,11 @@ BOOST_AUTO_TEST_CASE(int_channel_move_ctor_sender) {\n BOOST_AUTO_TEST_CASE(int_channel_move_assignment_sender) {\n     BOOST_TEST_MESSAGE(\"int channel move assignment sender\");\n \n-    sender<int> sut;\n-    atomic_int result{0};\n+    stlab::sender<int> sut;\n+    std::atomic_int result{0};\n \n     auto check = _receive[0] | [&](int x) { result = x; };\n-    sut = move(_send[0]);\n+    sut = std::move(_send[0]);\n \n     _receive[0].set_ready();\n     sut(42);\n@@ -92,7 +88,7 @@ BOOST_AUTO_TEST_CASE(int_channel_move_assignment_sender) {\n BOOST_AUTO_TEST_CASE(int_channel_copy_ctor_sender) {\n     BOOST_TEST_MESSAGE(\"int channel copy ctor sender\");\n \n-    atomic_int result{0};\n+    std::atomic_int result{0};\n \n     auto check = _receive[0] | [&](int x) { result = x; };\n     auto sut(_send[0]);\n@@ -116,8 +112,8 @@ BOOST_AUTO_TEST_CASE(int_channel_copy_ctor_sender) {\n BOOST_AUTO_TEST_CASE(int_channel_copy_assignment_sender) {\n     BOOST_TEST_MESSAGE(\"int channel copy assignment sender\");\n \n-    sender<int> sut;\n-    atomic_int result{0};\n+    stlab::sender<int> sut;\n+    std::atomic_int result{0};\n \n     auto check = _receive[0] | [&](int x) { result = x; };\n     sut = _send[0];\n@@ -141,9 +137,9 @@ BOOST_AUTO_TEST_CASE(int_channel_copy_assignment_sender) {\n BOOST_AUTO_TEST_CASE(int_channel_move_ctor_receiver) {\n     BOOST_TEST_MESSAGE(\"int channel move ctor receiver\");\n \n-    atomic_int result{0};\n+    std::atomic_int result{0};\n \n-    auto sut = move(_receive[0]);\n+    auto sut = std::move(_receive[0]);\n \n     auto check = sut | [&](int x) { result = x; };\n     sut.set_ready();\n@@ -157,10 +153,10 @@ BOOST_AUTO_TEST_CASE(int_channel_move_ctor_receiver) {\n BOOST_AUTO_TEST_CASE(int_channel_move_assignment_receiver) {\n     BOOST_TEST_MESSAGE(\"int channel move assignment receiver\");\n \n-    receiver<int> sut;\n-    atomic_int result{0};\n+    stlab::receiver<int> sut;\n+    std::atomic_int result{0};\n \n-    sut = move(_receive[0]);\n+    sut = std::move(_receive[0]);\n     auto check = sut | [&](int x) { result = x; };\n \n     sut.set_ready();\n@@ -174,7 +170,7 @@ BOOST_AUTO_TEST_CASE(int_channel_move_assignment_receiver) {\n BOOST_AUTO_TEST_CASE(int_channel_copy_ctor_receiver) {\n     BOOST_TEST_MESSAGE(\"int channel copy ctor receiver\");\n \n-    atomic_int result{0};\n+    std::atomic_int result{0};\n \n     auto sut(_receive[0]);\n \n@@ -192,8 +188,8 @@ BOOST_AUTO_TEST_CASE(int_channel_copy_ctor_receiver) {\n BOOST_AUTO_TEST_CASE(int_channel_copy_assignment_receiver) {\n     BOOST_TEST_MESSAGE(\"int channel copy assignment receiver\");\n \n-    receiver<int> sut;\n-    atomic_int result{0};\n+    stlab::receiver<int> sut;\n+    std::atomic_int result{0};\n \n     sut = _receive[0];\n \n@@ -210,11 +206,11 @@ BOOST_AUTO_TEST_CASE(int_channel_copy_assignment_receiver) {\n }\n \n BOOST_AUTO_TEST_CASE(int_concatenate_two_channels) {\n-    atomic_int result{0};\n-    sender<int> A, X;\n-    receiver<int> B, Y;\n-    tie(A, B) = channel<int>(default_executor);\n-    tie(X, Y) = channel<int>(default_executor);\n+    std::atomic_int result{0};\n+    stlab::sender<int> A, X;\n+    stlab::receiver<int> B, Y;\n+    std::tie(A, B) = stlab::channel<int>(stlab::default_executor);\n+    std::tie(X, Y) = stlab::channel<int>(stlab::default_executor);\n \n     auto b = B | [](int x) { return x * 2; } | X;\n \n@@ -232,9 +228,9 @@ BOOST_AUTO_TEST_CASE(int_concatenate_two_channels) {\n \n BOOST_AUTO_TEST_CASE(int_concatenate_channels_with_different_executor) {\n     {\n-        atomic_int result{ 0 };\n+        std::atomic_int result{ 0 };\n \n-        auto done = _receive[0] | (executor{ immediate_executor } & [](int x) { return x + 1; }) | [&result](int x) { result = x; };\n+        auto done = _receive[0] | (stlab::executor{stlab::immediate_executor } & [](int x) { return x + 1; }) | [&result](int x) { result = x; };\n \n         _receive[0].set_ready();\n \n@@ -246,9 +242,9 @@ BOOST_AUTO_TEST_CASE(int_concatenate_channels_with_different_executor) {\n     }\n     test_reset();\n     {\n-        atomic_int result{ 0 };\n+        std::atomic_int result{ 0 };\n \n-        auto done = _receive[0] | ([](int x) { return x + 1; } & executor{ immediate_executor }) | [&result](int x) { result = x; };\n+        auto done = _receive[0] | ([](int x) { return x + 1; } & stlab::executor{stlab::immediate_executor }) | [&result](int x) { result = x; };\n \n         _receive[0].set_ready();\n \n@@ -265,11 +261,11 @@ BOOST_AUTO_TEST_SUITE_END()\n namespace {\n \n class main_queue {\n-    deque<task<void()>> _q;\n+    std::deque<stlab::task<void()>> _q;\n \n public:\n     auto executor() {\n-        return [this](auto&& task) { _q.emplace_back(forward<decltype(task)>(task)); };\n+        return [this](auto&& task) { _q.emplace_back(std::forward<decltype(task)>(task)); };\n     }\n \n     void run() {\n@@ -288,16 +284,16 @@ class main_queue {\n };\n \n struct echo {\n-    process_state_scheduled _state = await_forever;\n+    stlab::process_state_scheduled _state = stlab::await_forever;\n     int _result = -1;\n \n     void await(int x) {\n         _result = x;\n-        _state = yield_immediate;\n+        _state = stlab::yield_immediate;\n     }\n \n     int yield() {\n-        _state = await_forever;\n+        _state = stlab::await_forever;\n         return _result;\n     }\n \n@@ -308,20 +304,20 @@ struct echo {\n \n template <typename... T>\n struct generator {\n-    const process_state_scheduled _state = yield_immediate;\n+    const stlab::process_state_scheduled _state = stlab::yield_immediate;\n \n     int _value = 0;\n-    tuple<T&...> _queues;\n+    std::tuple<T&...> _queues;\n \n     explicit generator(T&... q) : _queues(q...) {}\n \n     template <size_t... I>\n-    void push_values(int value, index_sequence<I...>) {\n-        (void)initializer_list<int>{(get<I>(_queues).push(value), 0)...};\n+    void push_values(int value, std::index_sequence<I...>) {\n+        (void)std::initializer_list<int>{(std::get<I>(_queues).push(value), 0)...};\n     }\n \n     int yield() {\n-        push_values(_value, make_index_sequence<sizeof...(T)>());\n+        push_values(_value, std::make_index_sequence<sizeof...(T)>());\n         return _value++;\n     }\n \n@@ -340,17 +336,17 @@ void RequireInClosedRange(size_t minValue, size_t test, size_t maxValue) {\n BOOST_AUTO_TEST_CASE(int_channel_with_2_sized_buffer) {\n     main_queue q;\n \n-    auto receive = channel<void>(q.executor());\n-    queue<int> valuesInFlight;\n+    auto receive = stlab::channel<void>(q.executor());\n+    std::queue<int> valuesInFlight;\n \n-    generator myGenerator(valuesInFlight);\n+    generator<std::queue<int>> myGenerator(valuesInFlight);\n     echo myEcho;\n \n-    auto r2 = move(receive) | ref(myGenerator) |\n-              (buffer_size{2} & ref(myEcho)) | [&valuesInFlight](auto x) {\n+    auto r2 = std::move(receive) | ref(myGenerator) |\n+              (stlab::buffer_size{2} & std::ref(myEcho)) | [&valuesInFlight](auto x) {\n                   BOOST_REQUIRE_EQUAL(x, valuesInFlight.front());\n                   valuesInFlight.pop();\n-                  cout << x << endl;\n+                  std::cout << x << std::endl;\n               };\n \n     r2.set_ready();\n@@ -392,14 +388,14 @@ BOOST_AUTO_TEST_CASE(int_channel_with_2_sized_buffer) {\n BOOST_AUTO_TEST_CASE(int_channel_with_3_sized_buffer) {\n     main_queue q;\n \n-    auto receive = channel<void>(q.executor());\n-    queue<int> valuesInFlight;\n+    auto receive = stlab::channel<void>(q.executor());\n+    std::queue<int> valuesInFlight;\n \n-    generator myGenerator(valuesInFlight);\n+    generator<std::queue<int>> myGenerator(valuesInFlight);\n     echo myEcho;\n \n-    auto r2 = move(receive) | ref(myGenerator) |\n-              (buffer_size{3} & ref(myEcho)) | [&valuesInFlight](auto x) {\n+    auto r2 = std::move(receive) | std::ref(myGenerator) |\n+              (stlab::buffer_size{3} & std::ref(myEcho)) | [&valuesInFlight](auto x) {\n                   BOOST_REQUIRE_EQUAL(x, valuesInFlight.front());\n                   valuesInFlight.pop();\n               };\n@@ -445,27 +441,28 @@ BOOST_AUTO_TEST_CASE(int_channel_with_3_sized_buffer) {\n BOOST_AUTO_TEST_CASE(int_channel_with_split_different_sized_buffer) {\n     // Here the bigger buffer size must not steer the upstream, but the\n     // smaller size\n-    vector<pair<size_t, size_t>> bufferSizes = {\n+    std::vector<std::pair<size_t, size_t>> bufferSizes = {\n         {1, 2}, {1, 2}, {1, 3}, {3, 1}, {2, 1}};\n \n     for (const auto& bs : bufferSizes) {\n         main_queue q;\n \n-        queue<int> valuesInFlight1;\n-        queue<int> valuesInFlight2;\n+        std::queue<int> valuesInFlight1;\n+        std::queue<int> valuesInFlight2;\n \n-        generator myGenerator1(valuesInFlight1);\n-        generator myGenerator2(valuesInFlight2);\n+        generator<std::queue<int>> myGenerator1(valuesInFlight1);\n+        generator<std::queue<int>> myGenerator2(valuesInFlight2);\n \n-        auto receive = channel<void>(q.executor());\n+        auto receive = stlab::channel<void>(q.executor());\n \n-        auto g = move(receive) | generator(valuesInFlight1, valuesInFlight2);\n+        auto g =\n+            std::move(receive) | generator<std::queue<int>, std::queue<int>>(valuesInFlight1, valuesInFlight2);\n \n-        auto r1 = g | (buffer_size{ bs.first } &echo()) | [&valuesInFlight1](auto x) {\n+        auto r1 = g | (stlab::buffer_size{ bs.first } &echo()) | [&valuesInFlight1](auto x) {\n             BOOST_REQUIRE_EQUAL(x, valuesInFlight1.front());\n             valuesInFlight1.pop();\n         };\n-        auto r2 = g | (buffer_size{ bs.second } &echo()) | [&valuesInFlight2](auto x) {\n+        auto r2 = g | (stlab::buffer_size{ bs.second } &echo()) | [&valuesInFlight2](auto x) {\n             BOOST_REQUIRE_EQUAL(x, valuesInFlight2.front());\n             valuesInFlight2.pop();\n         };\n@@ -515,18 +512,18 @@ BOOST_AUTO_TEST_CASE(int_channel_one_value_different_buffer_sizes) {\n     BOOST_TEST_MESSAGE(\"int channel one value different buffer sizes\");\n \n     for (auto bs : std::vector<std::size_t>{ 0, 1, 2, 10 }) {\n-        sender<int> send;\n-        receiver<int> receive;\n-        tie(send, receive) = channel<int>(default_executor);\n-        atomic_int result{0};\n+      stlab::sender<int> send;\n+      stlab::receiver<int> receive;\n+      std::tie(send, receive) = stlab::channel<int>(stlab::default_executor);\n+      std::atomic_int result{0};\n \n-        auto check = receive | (buffer_size{ bs } &[&](int x) { result += x; });\n+        auto check = receive | (stlab::buffer_size{ bs } &[&](int x) { result += x; });\n \n         receive.set_ready();\n         send(1);\n \n         while (result < 1) {\n-            this_thread::sleep_for(chrono::microseconds(1));\n+            std::this_thread::sleep_for(std::chrono::microseconds(1));\n         }\n \n         BOOST_REQUIRE_EQUAL(1, result);\n@@ -537,19 +534,19 @@ BOOST_AUTO_TEST_CASE(int_channel_two_values_different_buffer_sizes) {\n     BOOST_TEST_MESSAGE(\"int channel two values different buffer sizes\");\n \n     for (auto bs : std::vector<std::size_t>{ 0, 1, 2, 10 }) {\n-        sender<int> send;\n-        receiver<int> receive;\n-        tie(send, receive) = channel<int>(default_executor);\n-        atomic_int result{0};\n+        stlab::sender<int> send;\n+        stlab::receiver<int> receive;\n+        std::tie(send, receive) = stlab::channel<int>(stlab::default_executor);\n+        std::atomic_int result{0};\n \n-        auto check = receive | (buffer_size{ bs } &[&](int x) { result += x; });\n+        auto check = receive | (stlab::buffer_size{ bs } &[&](int x) { result += x; });\n \n         receive.set_ready();\n         send(1);\n         send(1);\n \n         while (result < 2) {\n-            this_thread::sleep_for(chrono::microseconds(1));\n+            std::this_thread::sleep_for(std::chrono::microseconds(1));\n         }\n \n         BOOST_REQUIRE_EQUAL(2, result);\n@@ -561,39 +558,39 @@ BOOST_AUTO_TEST_CASE(int_channel_many_values_different_buffer_sizes) {\n \n     {\n         for (auto bs : std::vector<std::size_t>{ 0, 1, 2, 10 }) {\n-            sender<int> send;\n-            receiver<int> receive;\n-            tie(send, receive) = channel<int>(default_executor);\n-            atomic_int result{ 0 };\n+            stlab::sender<int> send;\n+            stlab::receiver<int> receive;\n+            std::tie(send, receive) = stlab::channel<int>(stlab::default_executor);\n+            std::atomic_int result{ 0 };\n \n-            auto check = receive | (buffer_size{ bs } &[&](int x) { result += x; });\n+            auto check = receive | (stlab::buffer_size{ bs } &[&](int x) { result += x; });\n \n             receive.set_ready();\n             for (auto i = 0; i < 10; ++i)\n                 send(1);\n \n             while (result < 10) {\n-                this_thread::sleep_for(chrono::microseconds(1));\n+                std::this_thread::sleep_for(std::chrono::microseconds(1));\n             }\n \n             BOOST_REQUIRE_EQUAL(10, result);\n         }\n     }\n     {\n         for (auto bs : std::vector<std::size_t>{ 0, 1, 2, 10 }) {\n-            sender<int> send;\n-            receiver<int> receive;\n-            tie(send, receive) = channel<int>(default_executor);\n-            atomic_int result{ 0 };\n+            stlab::sender<int> send;\n+            stlab::receiver<int> receive;\n+            std::tie(send, receive) = stlab::channel<int>(stlab::default_executor);\n+            std::atomic_int result{ 0 };\n \n-            auto check = receive | ([&](int x) { result += x; } &buffer_size{ bs });\n+            auto check = receive | ([&](int x) { result += x; } & stlab::buffer_size{ bs });\n \n             receive.set_ready();\n             for (auto i = 0; i < 10; ++i)\n                 send(1);\n \n             while (result < 10) {\n-                this_thread::sleep_for(chrono::microseconds(1));\n+                std::this_thread::sleep_for(std::chrono::microseconds(1));\n             }\n \n             BOOST_REQUIRE_EQUAL(10, result);\n@@ -605,41 +602,41 @@ BOOST_AUTO_TEST_CASE(int_channel_many_values_different_buffer_sizes) {\n BOOST_AUTO_TEST_CASE(report_channel_broken_when_no_process_is_attached) {\n     BOOST_TEST_MESSAGE(\"Expect broken channel exception when no process is attached\");\n \n-    receiver<int> receive;\n+    stlab::receiver<int> receive;\n \n     BOOST_REQUIRE_EXCEPTION(\n-        (void)(receive | [](int) { return 1; }), channel_error,\n-        ([](const auto& e) { return string(\"broken channel\") == e.what(); }));\n+        (void)(receive | [](int) { return 1; }), stlab::channel_error,\n+        ([](const auto& e) { return std::string(\"broken channel\") == e.what(); }));\n \n     BOOST_REQUIRE_EXCEPTION(\n-        (void)(receive | (buffer_size{2} & [](int) { return 1; })), channel_error,\n-        ([](const auto& e) { return string(\"broken channel\") == e.what(); }));\n+        (void)(receive | (stlab::buffer_size{2} & [](int) { return 1; })), stlab::channel_error,\n+        ([](const auto& e) { return std::string(\"broken channel\") == e.what(); }));\n }\n \n BOOST_AUTO_TEST_CASE(report_channel_broken_when_process_is_already_running) {\n     BOOST_TEST_MESSAGE(\n         \"Expect \\\"process already running\\\" exception when process is already running\");\n \n-    sender<int> send;\n-    receiver<int> receive;\n-    tie(send, receive) = channel<int>(default_executor);\n+    stlab::sender<int> send;\n+    stlab::receiver<int> receive;\n+    std::tie(send, receive) = stlab::channel<int>(stlab::default_executor);\n \n     receive.set_ready();\n \n     BOOST_REQUIRE_EXCEPTION(\n-        (void)(receive | [](int) { return 1; }), channel_error,\n-        ([](const auto& e) { return string(\"process already running\") == e.what(); }));\n+        (void)(receive | [](int) { return 1; }), stlab::channel_error,\n+        ([](const auto& e) { return std::string(\"process already running\") == e.what(); }));\n \n     BOOST_REQUIRE_EXCEPTION(\n-        (void)(receive | (buffer_size{2} & [](int) { return 1; })), channel_error,\n-        ([](const auto& e) { return string(\"process already running\") == e.what(); }));\n+        (void)(receive | (stlab::buffer_size{2} & [](int) { return 1; })), stlab::channel_error,\n+        ([](const auto& e) { return std::string(\"process already running\") == e.what(); }));\n }\n \n BOOST_AUTO_TEST_CASE(sender_receiver_equality_tests) {\n     BOOST_TEST_MESSAGE(\"running sender equality tests\");\n     {\n-        sender<int> a, b;\n-        receiver<int> x, y;\n+        stlab::sender<int> a, b;\n+        stlab::receiver<int> x, y;\n \n         BOOST_REQUIRE(a == b);\n         BOOST_REQUIRE(!(a != b));\n@@ -649,8 +646,8 @@ BOOST_AUTO_TEST_CASE(sender_receiver_equality_tests) {\n     }\n \n     {\n-        sender<move_only> a, b;\n-        receiver<move_only> x, y;\n+        stlab::sender<stlab::move_only> a, b;\n+        stlab::receiver<stlab::move_only> x, y;\n \n         BOOST_REQUIRE(a == b);\n         BOOST_REQUIRE(!(a != b));\n@@ -660,9 +657,9 @@ BOOST_AUTO_TEST_CASE(sender_receiver_equality_tests) {\n     }\n \n     {\n-        sender<int> send;\n-        receiver<int> rec;\n-        tie(send, rec) = channel<int>(immediate_executor);\n+        stlab::sender<int> send;\n+        stlab::receiver<int> rec;\n+        std::tie(send, rec) = stlab::channel<int>(stlab::immediate_executor);\n \n         auto a = send;\n         auto x = rec;\n@@ -671,30 +668,30 @@ BOOST_AUTO_TEST_CASE(sender_receiver_equality_tests) {\n     }\n \n     {\n-        sender<int> a, b;\n-        receiver<int> x, y;\n-        tie(a, x) = channel<int>(immediate_executor);\n-        tie(b, y) = channel<int>(immediate_executor);\n+        stlab::sender<int> a, b;\n+        stlab::receiver<int> x, y;\n+        std::tie(a, x) = stlab::channel<int>(stlab::immediate_executor);\n+        std::tie(b, y) = stlab::channel<int>(stlab::immediate_executor);\n \n         BOOST_REQUIRE(a != b);\n         BOOST_REQUIRE(x != y);\n     }\n     {\n-        sender<move_only> send;\n-        receiver<move_only> rec;\n-        tie(send, rec) = channel<move_only>(immediate_executor);\n+        stlab::sender<stlab::move_only> send;\n+        stlab::receiver<stlab::move_only> rec;\n+        std::tie(send, rec) = stlab::channel<stlab::move_only>(stlab::immediate_executor);\n \n-        sender<move_only> a;\n+        stlab::sender<stlab::move_only> a;\n         BOOST_REQUIRE(a != send);\n     }\n }\n \n BOOST_AUTO_TEST_CASE(sender_receiver_swap_tests) {\n     {\n-        sender<int> a, b;\n-        receiver<int> x, y;\n-        tie(a, x) = channel<int>(immediate_executor);\n-        tie(b, y) = channel<int>(immediate_executor);\n+        stlab::sender<int> a, b;\n+        stlab::receiver<int> x, y;\n+        std::tie(a, x) = stlab::channel<int>(stlab::immediate_executor);\n+        std::tie(b, y) = stlab::channel<int>(stlab::immediate_executor);\n         int result1(0), result2(0);\n \n         auto v = x | [&result1](int i) { result1 = i; };\n@@ -712,10 +709,10 @@ BOOST_AUTO_TEST_CASE(sender_receiver_swap_tests) {\n         BOOST_REQUIRE_EQUAL(2, result1);\n     }\n     {\n-        sender<int> a, b;\n-        receiver<int> x, y;\n-        tie(a, x) = channel<int>(immediate_executor);\n-        tie(b, y) = channel<int>(immediate_executor);\n+        stlab::sender<int> a, b;\n+        stlab::receiver<int> x, y;\n+        std::tie(a, x) = stlab::channel<int>(stlab::immediate_executor);\n+        std::tie(b, y) = stlab::channel<int>(stlab::immediate_executor);\n         int result1(0), result2(0);\n \n         swap(x, y);\n@@ -733,14 +730,14 @@ BOOST_AUTO_TEST_CASE(sender_receiver_swap_tests) {\n         BOOST_REQUIRE_EQUAL(2, result1);\n     }\n     {\n-        sender<move_only> a, b;\n-        receiver<move_only> x, y;\n-        tie(a, x) = channel<move_only>(immediate_executor);\n-        tie(b, y) = channel<move_only>(immediate_executor);\n+        stlab::sender<stlab::move_only> a, b;\n+        stlab::receiver<stlab::move_only> x, y;\n+        std::tie(a, x) = stlab::channel<stlab::move_only>(stlab::immediate_executor);\n+        std::tie(b, y) = stlab::channel<stlab::move_only>(stlab::immediate_executor);\n         int result1(0), result2(0);\n \n-        auto v = x | [&result1](move_only i) { result1 = i.member(); };\n-        auto w = y | [&result2](move_only i) { result2 = i.member(); };\n+        auto v = x | [&result1](stlab::move_only i) { result1 = i.member(); };\n+        auto w = y | [&result2](stlab::move_only i) { result2 = i.member(); };\n \n         x.set_ready();\n         y.set_ready();\n@@ -754,16 +751,16 @@ BOOST_AUTO_TEST_CASE(sender_receiver_swap_tests) {\n         BOOST_REQUIRE_EQUAL(2, result1);\n     }\n     {\n-        sender<move_only> a, b;\n-        receiver<move_only> x, y;\n-        tie(a, x) = channel<move_only>(immediate_executor);\n-        tie(b, y) = channel<move_only>(immediate_executor);\n+        stlab::sender<stlab::move_only> a, b;\n+        stlab::receiver<stlab::move_only> x, y;\n+        std::tie(a, x) = stlab::channel<stlab::move_only>(stlab::immediate_executor);\n+        std::tie(b, y) = stlab::channel<stlab::move_only>(stlab::immediate_executor);\n         int result1(0), result2(0);\n \n-        swap(x, y);\n+        std::swap(x, y);\n \n-        auto v = x | [&result1](move_only i) { result1 = i.member(); };\n-        auto w = y | [&result2](move_only i) { result2 = i.member(); };\n+        auto v = x | [&result1](stlab::move_only i) { result1 = i.member(); };\n+        auto w = y | [&result2](stlab::move_only i) { result2 = i.member(); };\n \n         x.set_ready();\n         y.set_ready();"},{"sha":"79d19a899983f16beb8b5e033f2e5f03d61d763f","filename":"test/executor_test.cpp","status":"modified","additions":27,"deletions":17,"changes":44,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Fexecutor_test.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Fexecutor_test.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Fexecutor_test.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(all_low_prio_tasks_are_executed) {\n \n     for (auto i = 0; i < 10; ++i) {\n         queue.executor()([_i = i, &m, &results] {\n-            unique_lock block{m};\n+            unique_lock<mutex> block{m};\n             results.push_back(_i);\n         });\n     }\n@@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE(all_default_prio_tasks_get_executed) {\n \n     for (auto i = 0; i < 10; ++i) {\n         queue.executor()([_i = i, &m, &results] {\n-            unique_lock block{m};\n+            unique_lock<mutex> block{m};\n             results.push_back(_i);\n         });\n     }\n@@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(all_high_prio_tasks_get_executed) {\n \n     for (auto i = 0; i < 10; ++i) {\n         queue.executor()([_i = i, &m, &results] {\n-            unique_lock block{m};\n+            unique_lock<mutex> block{m};\n             results.push_back(_i);\n         });\n     }\n@@ -153,15 +153,15 @@ BOOST_AUTO_TEST_CASE(task_system_restarts_after_it_went_pending) {\n     default_executor([&]{\n         rest();\n         {\n-            unique_lock block{m};\n+            unique_lock<mutex> block{m};\n             done = true;\n         }\n         cv.notify_one();\n     });\n \n \n     {\n-        unique_lock block{m};\n+        unique_lock<mutex> block{m};\n         while (!done) {\n             cv.wait(block);\n         }\n@@ -170,14 +170,14 @@ BOOST_AUTO_TEST_CASE(task_system_restarts_after_it_went_pending) {\n     default_executor([&] {\n         rest();\n         {\n-            unique_lock block{m};\n+            unique_lock<mutex> block{m};\n             done = false;\n             cv.notify_one();\n         }\n     });\n \n     {\n-        unique_lock block{m};\n+        unique_lock<mutex> block{m};\n         while (done) {\n             cv.wait(block);\n         }\n@@ -191,7 +191,7 @@ namespace\n     auto fiboN{ 1000 };\n     const auto iterations = 100'000;\n     const auto startCount = 100;\n-    atomic_int workToDo = (iterations - startCount) * 3;\n+    atomic_int workToDo{(iterations - startCount) * 3};\n     const auto expectedWork = startCount * 3 + workToDo;\n     atomic_int highCount{0};\n     atomic_int defaultCount{0};\n@@ -218,17 +218,27 @@ namespace\n             ++_currentPrioCount;\n         }\n \n+        template <stlab::detail::executor_priority Q>\n+        auto schedule_increment() -> std::enable_if_t<Q == stlab::detail::executor_priority::low, int> {\n+            return static_cast<int>(highCount <= taskRunning && defaultCount <= taskRunning);\n+        }\n+\n+        template <stlab::detail::executor_priority Q>\n+        auto schedule_increment() -> std::enable_if_t<Q == stlab::detail::executor_priority::medium, int> {\n+            return static_cast<int>(highCount <= taskRunning);\n+        }\n+\n+        template <stlab::detail::executor_priority Q>\n+        auto schedule_increment() -> std::enable_if_t<Q == stlab::detail::executor_priority::high, int> {\n+            return 0;\n+        }\n+\n         void operator()() {\n             --_currentPrioCount;\n \n             ++taskRunning;\n \n-            if constexpr (P == stlab::detail::executor_priority::low)\n-                _correctScheduleCount += static_cast<int>(highCount <= taskRunning && defaultCount <= taskRunning);\n-\n-            if constexpr (P == stlab::detail::executor_priority::medium) {\n-                _correctScheduleCount += static_cast<int>(highCount <= taskRunning);\n-            }\n+            _correctScheduleCount += schedule_increment<P>();\n \n             fibonacci<mp::cpp_int>(fiboN);\n \n@@ -279,7 +289,7 @@ BOOST_AUTO_TEST_CASE(MeasureTiming) {\n     std::vector<int> results;\n     const auto iterations = 300'000;\n     results.resize(iterations * 3);\n-    atomic_bool done = false;\n+    atomic_bool done{false};\n     condition_variable ready;\n     atomic_int counter{0};\n \n@@ -306,15 +316,15 @@ BOOST_AUTO_TEST_CASE(MeasureTiming) {\n     mutex block;\n     low_executor([&] {\n         {\n-            unique_lock lock{block};\n+            unique_lock<mutex> lock{block};\n             done = true;\n \n             ready.notify_one();\n         }\n     });\n \n \n-    unique_lock lock{block};\n+    unique_lock<mutex> lock{block};\n     while (!done) ready.wait(lock);\n \n     auto stop = std::chrono::high_resolution_clock::now();"},{"sha":"cb3f5a12f9ed8c730331a8253d84e6dfd532e433","filename":"test/forest_test.cpp","status":"modified","additions":5,"deletions":4,"changes":9,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Fforest_test.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Fforest_test.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Fforest_test.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -129,7 +129,7 @@ auto to_string(const std::string& x) {\n }\n \n template <>\n-auto to_string(const std::optional<std::string>& x) {\n+auto to_string(const stlab::optional<std::string>& x) {\n     return x ? to_string(*x) : \"?\";\n }\n \n@@ -285,12 +285,13 @@ BOOST_AUTO_TEST_CASE(child_traversal) {\n \n     BOOST_CHECK(to_string(child_range(parent)) == expected);\n \n-    if constexpr (false) { // I'm not sure reverse_child_iterator ever worked.\n+    #if 0\n+        // I'm not sure reverse_child_iterator ever worked.\n         forest<std::string>::reverse_child_iterator first{child_begin(parent)};\n         forest<std::string>::reverse_child_iterator last{child_end(parent)};\n         std::string result{to_string(first, last)};\n         BOOST_CHECK(result == expected);\n-    }\n+    #endif\n }\n \n /**************************************************************************************************/\n@@ -460,7 +461,7 @@ BOOST_AUTO_TEST_CASE(test_transcribe_forest) {\n \n BOOST_AUTO_TEST_CASE(test_flatten) {\n     auto f1{big_test_forest()};\n-    std::vector<std::optional<std::string>> flat;\n+    std::vector<stlab::optional<std::string>> flat;\n \n     forests::flatten(f1.begin(), f1.end(), std::back_inserter(flat));\n "},{"sha":"20c3e77f8a45a59f72c09d8292d59addc53e3639","filename":"test/future_recover_tests.cpp","status":"modified","additions":8,"deletions":12,"changes":20,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Ffuture_recover_tests.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Ffuture_recover_tests.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Ffuture_recover_tests.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -899,9 +899,8 @@ BOOST_AUTO_TEST_CASE(future_recover_int_with_broken_promise) {\n     {\n         auto check{false};\n         sut = [&check]() {\n-            auto [promise, future]{package<int(int)>(immediate_executor, [](int x) { return x; })};\n-            (void)promise;\n-            return future.recover([&check](const auto& f) {\n+            auto p{package<int(int)>(immediate_executor, [](int x) { return x; })};\n+            return p.second.recover([&check](const auto& f) {\n                 check = true;\n                 try {\n                     return *f.get_try();\n@@ -917,9 +916,8 @@ BOOST_AUTO_TEST_CASE(future_recover_int_with_broken_promise) {\n     {\n         auto check{false};\n         sut = [&check]() {\n-            auto [promise, future]{package<int(int)>(immediate_executor, [](int x) { return x; })};\n-            (void)promise;\n-            return future ^ [&check](const auto& f) {\n+            auto p{package<int(int)>(immediate_executor, [](int x) { return x; })};\n+            return p.second ^ [&check](const auto& f) {\n                 check = true;\n                 try {\n                     return *f.get_try();\n@@ -1158,10 +1156,9 @@ BOOST_AUTO_TEST_CASE(future_recover_move_only_with_broken_promise) {\n     {\n         auto check{false};\n         sut = [&check]() {\n-            auto [promise, future]{\n+            auto p{\n                 package<move_only(move_only)>(immediate_executor, [](move_only x) { return x; })};\n-            (void)promise;\n-            return std::move(future).recover([&check](auto f) {\n+            return std::move(p.second).recover([&check](auto f) {\n                 check = true;\n                 try {\n                     return *std::move(f.get_try());\n@@ -1177,10 +1174,9 @@ BOOST_AUTO_TEST_CASE(future_recover_move_only_with_broken_promise) {\n     {\n         auto check{false};\n         sut = [&check]() {\n-            auto [promise, future]{\n+            auto p{\n                 package<move_only(move_only)>(immediate_executor, [](move_only x) { return x; })};\n-            (void)promise;\n-            return std::move(future) ^ [&check](auto f) {\n+            return std::move(p.second) ^ [&check](auto f) {\n                 check = true;\n                 try {\n                     return *std::move(f.get_try());"},{"sha":"65628761703f48522e0b09a652fb4b732c28ead9","filename":"test/future_test_helper.hpp","status":"modified","additions":2,"deletions":1,"changes":3,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Ffuture_test_helper.hpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Ffuture_test_helper.hpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Ffuture_test_helper.hpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -113,6 +113,7 @@ struct test_fixture {\n     auto wait_until_future_r_completed(F& f) {\n         auto result = f.get_try();\n         while (!result) {\n+            std::this_thread::sleep_for(std::chrono::milliseconds(1));\n             result = f.get_try();\n         }\n         return result;\n@@ -150,7 +151,7 @@ struct test_fixture {\n         }\n     }\n \n-    std::atomic_int _task_counter;\n+    std::atomic_int _task_counter{0};\n \n private:\n     template <typename F>"},{"sha":"a9951c23d7b6be8e7fe691b910911512440f8d55","filename":"test/future_tests.cpp","status":"modified","additions":6,"deletions":9,"changes":15,"blob_url":"https://github.com/stlab/stlab/blob/8bec44964e6d477237d230d826b73cb54860068e/test%2Ffuture_tests.cpp","raw_url":"https://github.com/stlab/stlab/raw/8bec44964e6d477237d230d826b73cb54860068e/test%2Ffuture_tests.cpp","contents_url":"https://api.github.com/repos/stlab/stlab/contents/test%2Ffuture_tests.cpp?ref=8bec44964e6d477237d230d826b73cb54860068e","patch":"@@ -537,9 +537,8 @@ BOOST_AUTO_TEST_CASE(future_int_detach_without_execution) {\n     annotate_counters counter;\n     bool check = true;\n     {\n-        auto [promise, future] = package<int()>(immediate_executor, [] { return 42; });\n-        future.then([a = annotate(counter), &_check = check](int) { _check = false; }).detach();\n-        (void)promise;\n+        auto p = package<int()>(immediate_executor, [] { return 42; });\n+        p.second.then([a = annotate(counter), &_check = check](int) { _check = false; }).detach();\n     }\n     std::cout << counter;\n \n@@ -552,10 +551,9 @@ BOOST_AUTO_TEST_CASE(future_move_only_detach_without_execution) {\n     annotate_counters counter;\n     bool check = true;\n     {\n-        auto [promise, future] = package<move_only()>(immediate_executor, [] { return move_only{42}; });\n-        auto r = std::move(future).then([a = annotate(counter), &_check = check](auto&&) { _check = false; });\n+        auto p = package<move_only()>(immediate_executor, [] { return move_only{42}; });\n+        auto r = std::move(p.second).then([a = annotate(counter), &_check = check](auto&&) { _check = false; });\n         r.detach();\n-        (void)promise;\n     }\n     std::cout << counter;\n \n@@ -568,9 +566,8 @@ BOOST_AUTO_TEST_CASE(future_void_detach_without_execution) {\n     annotate_counters counter;\n     bool check = true;\n     {\n-        auto [promise, future] = package<void()>(immediate_executor, [] {});\n-        future.then([a = annotate(counter), &_check = check]() { _check = false; }).detach();\n-        (void)promise;\n+        auto p = package<void()>(immediate_executor, [] {});\n+        p.second.then([a = annotate(counter), &_check = check]() { _check = false; }).detach();\n     }\n     std::cout << counter;\n "}]}