{"id":19436429,"url":"https://github.com/beached/function_stream","last_synced_at":"2026-02-19T15:02:26.764Z","repository":{"id":149955335,"uuid":"77659924","full_name":"beached/function_stream","owner":"beached","description":"A parallel library with task, pipeline and algorithmic parallelism.","archived":false,"fork":false,"pushed_at":"2022-05-02T20:45:49.000Z","size":803,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-24T21:51:14.498Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/beached.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-30T04:19:31.000Z","updated_at":"2022-05-03T04:32:26.000Z","dependencies_parsed_at":"2023-05-05T06:20:20.088Z","dependency_job_id":null,"html_url":"https://github.com/beached/function_stream","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/beached/function_stream","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beached%2Ffunction_stream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beached%2Ffunction_stream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beached%2Ffunction_stream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beached%2Ffunction_stream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beached","download_url":"https://codeload.github.com/beached/function_stream/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beached%2Ffunction_stream/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279018785,"owners_count":26086452,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T15:11:07.273Z","updated_at":"2025-10-14T10:40:37.914Z","avatar_url":"https://github.com/beached.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# This is in development and extrememly broken\n# Function Stream\n\nA parallel library with task, pipeline and algorithmic parallelism.  Some examples can be found in the [tests](./tests) folder and some benchmarks are in the [Benchmarks](./benchmarks/) folder.  From the benchmarks you can see the average time per item processed.  In many cases it can be quicker to use the sequential versions as the task is memory bound in the easy case where the supplied function is too quick.  This happens for cases where N is small.  If the work is greater than the per item time in sequential, the parallel should be faster.\n\n## [High Level Parallel Algorithms](./include/algorithms.h)\n\n[Example 1](./tests/algorithms_test.cpp)\n[Example 2](./tests/map_reduce_test.cpp)\n\n### for_each, for_each_n\nApplies the given function object func to the result of dereferencing every iterator in the range [first, last) (not necessarily in order)\n``` C++\ntemplate\u003ctypename RandomIterator, typename Func\u003e \nvoid for_each( RandomIterator const first, RandomIterator const last, Func func, task_scheduler ts );\n\ntemplate\u003ctypename Iterator, typename Func\u003e \nvoid for_each_n( Iterator first, size_t N, Func func, task_scheduler ts );\n```\n\n### fill\nAssigns value to the result of dereferencing every iterator in the range [first, last) (not necessarily in order)\n``` C++\ntemplate\u003ctypename Iterator, typename T\u003e \nvoid fill( Iterator first, Iterator last, T const \u0026value, task_scheduler ts );\n```\n\n### sort\nSorts the elements in the range [first, last) in ascending order. The order of equal elements is not guaranteed to be preserved.  Elements are compared using the given binary comparison function compare.\n``` C++\ntemplate\u003ctypename Iterator, typename LessCompare\u003e \nvoid sort_merge( Iterator first, Iterator last, LessCompare compare, task_scheduler ts );\n```\n\n### stable_sort\nSorts the elements in the range [first, last) in ascending order. The order of equal elements is guaranteed to be preserved.  Elements are compared using the given comparison function compare.\n``` C++\ntemplate\u003ctypename Iterator, typename LessCompare\u003e \nvoid stable_sort_merge( Iterator first, Iterator last, task_scheduler ts, LessCompare compare = LessCompare{} );\n```\n### min/max element\nFinds the smallest(min) or largest(max) element in the range [first, last).  Elements are compared using the given binary comparison function compare.\n``` C++\ntemplate\u003ctypename Iterator, typename LessCompare\u003e \nauto min_element( Iterator first, Iterator last, task_scheduler ts, LessCompare compare = LessCompare{} );\n\ntemplate\u003ctypename Iterator, typename LessCompare\u003e \nauto max_element( Iterator first, Iterator last, task_scheduler ts, LessCompare compare = LessCompare{} );\n```\n\n### reduce      \nReduces the range [first; last), possibly permuted and aggregated in unspecified manner, along with the initial value init over binary_op.\n``` C++\ntemplate\u003ctypename T, typename Iterator, typename BinaryOp\u003e \nT reduce( Iterator first, Iterator last, T init, BinaryOp binary_op, task_scheduler ts );\n\ntemplate\u003ctypename T, typename Iterator\u003e \nauto reduce( Iterator first, Iterator last, T init, task_scheduler ts );\n\ntemplate\u003ctypename Iterator\u003e \nauto reduce( Iterator first, Iterator last, task_scheduler ts );\n```\n\n### transform(map)\nApply the given function unary_op to the result of dereferencing every iterator in the range [first, last) (not necessarily in order).  If supplied the result is stored in range [first2, first2 + std::distance( first, last )), or in place otherwise.\n``` C++\ntemplate\u003ctypename Iterator, typename OutputIterator, typename UnaryOperation\u003e \nvoid transform( Iterator first1, Iterator const last1, OutputIterator first2, UnaryOperation unary_op, task_scheduler ts );\n\ntemplate\u003ctypename Iterator, typename UnaryOperation\u003e \nvoid transform( Iterator first, Iterator last, UnaryOperation unary_op, task_scheduler ts );\n```\n\n### combined map reduce\nApply the given function map_function to the result of dereferencing every iterator in the range [first, last) (not necessarily in order).  The results are passed to the binary_function reduce_function and returned.\n``` C++\ntemplate\u003ctypename Iterator, typename MapFunction, typename ReduceFunction\u003e \nauto map_reduce( Iterator first, Iterator last, MapFunction map_function, ReduceFunction reduce_function, task_scheduler ts );\n\ntemplate\u003ctypename Iterator, typename T, typename MapFunction, typename ReduceFunction\u003e \nauto map_reduce( Iterator first, Iterator last, T const \u0026init, MapFunction map_function, ReduceFunction reduce_function, task_scheduler ts );\n```\n\n### scan(prefix sum)\nComputes the result of binary_op with the elements in the subranges of the range [first, last) and writes them to the range [first_out, last_out).   \n``` C++\ntemplate\u003ctypename Iterator, typename OutputIterator, typename BinaryOp\u003e \nvoid scan( Iterator first, Iterator last, OutputIterator first_out, OutputIterator last_out, BinaryOp binary_op, task_scheduler ts );\n\ntemplate\u003ctypename Iterator, typename OutputIterator, typename BinaryOp\u003e \nvoid scan( Iterator first, Iterator last, BinaryOp binary_op, task_scheduler ts );\n```\n\n### find_if \nReturn an Iterator to the first position where the UnaryPredicate pred returns true.\n``` C++\ntemplate\u003ctypename Iterator, typename UnaryPredicate\u003e\nIterator find_if( Iterator first, Iterator last, UnaryPredicate pred, task_scheduler ts );\n```\n\n### equal\nDetermine if two ranges are equal.\n``` C++\ntemplate\u003ctypename Iterator1, typename Iterator2, typename BinaryPredicate\u003e\nbool equal( Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, BinaryPredicate pred, task_scheduler ts );\n\ntemplate\u003ctypename Iterator1, typename Iterator2, typename BinaryPredicate\u003e\nbool equal( Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, task_scheduler ts );\n```\n\n## [Task Based Parallelism](./include/task_scheduler.h)\n\n[Examples](./tests/task_scheduler_test.cpp)\n\nImplementation of a task stealing work m_queue.  The default is to have 1 thread per core and block on destruction.\n\n### get default task scheduler\n``` C++\ntask_scheduler get_task_scheduler( );\n```\n\n### adding a task to m_queue\nAdd a simple task of the form void( ) to the m_queue.  \n``` C++\ntemplate\u003ctypename Task\u003e\nvoid task_scheduler::add_task( Task task ) noexcept;\n```\n\n### starting task scheduler\n``` C++\nvoid task_scheduler::start( );\n```\n\n### stopping task scheduler\n``` C++\nvoid task_scheduler::request_stop( bool block = true );\n```\n\n### check if task scheduler is started\n``` C++\nbool task_scheduler::started( ) const;\n```\n\n### check how many task queues are processing jobs\n``` C++\nsize_t task_scheduler::size( ) const;\n```\n\n### indicate code sections that will block thread\nUse blocking section to indicate that another thread can start processing the work queues while this one is blocked.  If the current thread is on of the task_scheduler's own, otherwise it will not start a new thread.  Task is of the form of void( ).\nblock_on_waitable requires the object passed to support the wait( ) method.\n``` C++\ntemplate\u003ctypename Task\u003e\nvoid task_scheduler::blocking_task( Task task, taskscheduler ts );\n\ntemplate\u003ctypename Function\u003e\nauto task_scheduler::blocking_function( Function func, taskscheduler ts );\n\ntemplate\u003ctypename Waitable\u003e\nvoid task_scheduler::blocking_on_waiting( Waitable waitable, task_scheduler ts );\n```\n\n### Scheduling tasks\nAdd supplied task to task_scheduler ts and notify supplied semaphore when completed\n``` C++\ntemplate\u003ctypename Task\u003e\nvoid schedule_task( daw::shared_semaphore semaphore, Task task, task_scheduler ts );\n```\n\nAdd supplied task to default task_scheduler and notify supplied semaphore when completed\n``` C++\ntemplate\u003ctypename Task\u003e\nvoid schedule_task( daw::shared_semaphore semaphore, Task task );\n```\n\nAdd supplied task to task_scheduler ts and return a semaphore that will block until it completes\n``` C++\ntemplate\u003ctypename Task\u003e\ndaw::shared_semaphore create_waitable_task( Task task, task_scheduler ts );\n```\n\nAdd supplied tasks to default task_scheduler and return a semaphore that will block until it completes \n``` C++\ntemplate\u003ctypename Task\u003e\ndaw::shared_semaphore create_waitable_task( Task task );\n```\n\nAdd supplied tasks to the default task_scheduler and return a semaphore that will block until all complete\n``` C++\ntemplate\u003ctypename... Tasks\u003e\ndaw::shared_semaphore create_task_group( Tasks \u0026\u0026... tasks );\n```\n\nAdd supplied tasks to the default task_scheduler and return when they all complete\n``` C++\ntemplate\u003ctypename... Tasks\u003e\nvoid invoke_tasks( Tasks \u0026\u0026... tasks );\n```\n## [Future's](./include/future_result.h)\n\n[Examples](./tests/function_stream_test.cpp)\n\nStores the results of parallel operations or exceptions.  Blocks until value is set.  If an exception is set it will throw when value is retrieved.\n``` C++\ntemplate\u003ctypename Result\u003e struct future_result_t;\n```\n\n### Waiting for values to become available\nWait indefinitely until value is avaiable\n``` C++\nvoid future_result_t::wait( ) const override;\n```\n\nWait for a specific time duration.  Returns a future_status that indicates whether the value is available or not.  Takes a std::chrono::duration as argument\n``` C++\ntemplate\u003ctypename Rep, typename Period\u003e\nfuture_status future_result_t::wait_for( std::chrono::duration\u003cRep, Period\u003e const \u0026rel_time ) const;\n```\n\nWait until a specific time.  Returns a future_status that indicates whether the value is available or not.  Takes a std::chrono::time_point as argument\n``` C++\ntemplate\u003ctypename Rep, typename Period\u003e\nfuture_status future_result_t::wait_until( std::chrono::time_point\u003cClock, Duration\u003e const \u0026 timeout_time ) const;\n```\n\nCheck if waiting would block.\n``` C++\n bool future_result_t::try_wait( ) const override\n explicit future_result_t::operator bool( ) const;\n ```\n\n### Setting value in future_result_t\nSets the value and allows threads waiting to proceed.\n``` C++\nvoid future_result_t::set_value( Result value ) noexcept;\n```\n\nDo not return a value but a throw exception\n``` C++\ntemplate\u003ctypename Exception\u003e\nvoid set_exception( Exception const \u0026ex );\n```\n\nReturn current exception that was just thrown\n``` C++\nvoid set_exception( );\n```\n\nSet the value from the result of function and optional arguments args\n``` C++\ntemplate\u003ctypename Function, typename... Args\u003e\nvoid from_code( Function func, Args \u0026\u0026... args );\n```\n### Continuation of future_result_t\nAdd next function in chain and return a new future_result_t that has the result of that function with the argument being the result of the previous\n``` C++\ntemplate\u003ctypename Function\u003e\nauto next( Function next_function );\n```\nSplit the result of future_result_t and pass it to a list of Functions.  The result is a tuple of future_result_t with the result of each function\n``` C++\ntemplate\u003ctypename... Functions\u003e\nauto split( Functions\u0026\u0026... funcs );\n```\n\n### Retreiving the value from future_result_t\nCheck if the future result is an exception\n``` C++\nbool is_exception( ) const;\n```\n\nGet the result, will throw if exception is stored\n``` C++\nResult const \u0026get( ) const;\n```\n\n### Creating future results\n\nThese functions will create a task on the specified task_scheduler or use the default (via get_task_scheduler( )).  An optional semaphore can be supplied for situations where one does not want to return until a group of results is available.  Optional arguments args can be provided to function.\n``` C++\ntemplate\u003ctypename Function, typename... Args\u003e\nauto make_future_result( task_scheduler ts, Function func, Args \u0026\u0026... args );\n\ntemplate\u003ctypename Function, typename... Args\u003e\nauto make_future_result( task_scheduler ts, daw::shared_semaphore semaphore, Function func, Args \u0026\u0026... args );\n\ntemplate\u003ctypename Function, typename... Args\u003e\nauto make_future_result( Function func, Args \u0026\u0026... args );\n```\n\nThese functions will return a tuple of future_results_t for all functions specified.\n\nMake a future result group callable.  The result can be called with arguments to pass to all functions\n``` C++\ntemplate\u003ctypename... Functions\u003e\nauto make_callable_future_result_group( Functions... functions );\n```\n\nMake a default result group with no arguments.\n``` C++\ntemplate\u003ctypename... Functions\u003e\nauto make_future_result_group( Functions... functions );\n```\n\n## [Parallel Stream/Pipeline](./include/function_stream.h)\n\nCreate a pipelined set of functions where the result is passed to each subsequent function.  A future_result_t is returned at the end.  Each function call creates a task in task scheduler for scheduling.  This allows one to add parallelism to serial lists of functions or blocks of code.\n\nA functon stream is callable with the arguments of the first function\n``` C++\ntemplate\u003ctypename... Functions\u003e class function_stream;\n```\n\nCreate a function stream from a list of callables.  The result is a future_result_t with the result type of the last function in the list.\n``` C++\ntemplate\u003ctypename... Functions\u003e\nconstexpr auto make_function_stream( Functions \u0026\u0026... funcs );\n```\n\nWait for a function_stream result to complete\n``` C++\ntemplate\u003ctypename FunctionStream\u003e\nvoid wait_for_function_streams( FunctionStream \u0026 function_stream );\n```\n\nWait for a group of function stream results to complete.  This implements the join pattern\n``` C++\ntemplate\u003ctypename... FunctionStreams\u003e\nvoid wait_for_function_streams( FunctionStreams\u0026... function_streams );\n```\n\n### Parallel/Sequential Function Composition\n\nCompose a stream of functions that may be run as parallel tasks or a sequential flow.\n\nCompose a function that returns a future.  The result of each subsequent function must be the argument of the test.  The future will have a value of the type of the final function.\n``` C++\nconstexpr auto func = daw::compose_future( ) | callable1 | callable2 | callable3;\nauto fut = func( args... );\nfut.wait( );\nauto result = fut.get( );\n```\n\nCompose a sequential function and return the value of the final sub-function.\n``` C++\nconstexpr auto func = daw::compose( ) | callable1 | callable2 | callable3;\nconstexpr auto result = func( args... );\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeached%2Ffunction_stream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeached%2Ffunction_stream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeached%2Ffunction_stream/lists"}