{"id":50541771,"url":"https://github.com/notakeith/task-scheduler","last_synced_at":"2026-06-03T20:30:54.383Z","repository":{"id":361597840,"uuid":"1255006214","full_name":"notakeith/task-scheduler","owner":"notakeith","description":"Task scheduler with dependency graph resolution","archived":false,"fork":false,"pushed_at":"2026-05-31T11:15:48.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-31T13:09:36.885Z","etag":null,"topics":["cpp","task-scheduler","template-metaprogramming","type-erasure"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/notakeith.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-31T09:25:00.000Z","updated_at":"2026-05-31T11:15:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/notakeith/task-scheduler","commit_stats":null,"previous_names":["notakeith/task-scheduler"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/notakeith/task-scheduler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notakeith%2Ftask-scheduler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notakeith%2Ftask-scheduler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notakeith%2Ftask-scheduler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notakeith%2Ftask-scheduler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/notakeith","download_url":"https://codeload.github.com/notakeith/task-scheduler/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notakeith%2Ftask-scheduler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33878990,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"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":["cpp","task-scheduler","template-metaprogramming","type-erasure"],"created_at":"2026-06-03T20:30:54.297Z","updated_at":"2026-06-03T20:30:54.370Z","avatar_url":"https://github.com/notakeith.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Task Scheduler\n\n\u003e [Русская версия](README_RU.md)\n\n[![C++17](https://img.shields.io/badge/C%2B%2B-17-blue?logo=cplusplus\u0026logoColor=white)](https://en.cppreference.com/w/cpp/17)\n[![CMake](https://img.shields.io/badge/CMake-3.14%2B-064F8C?logo=cmake\u0026logoColor=white)](https://cmake.org/)\n[![GTest](https://img.shields.io/badge/tested_with-GTest-4285F4?logo=google\u0026logoColor=white)](https://github.com/google/googletest)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\nA header-only C++17 task scheduler that executes a graph of data-dependent computations. Tasks declare their inputs upfront — including results of tasks that haven't run yet — and the scheduler resolves the dependency graph automatically, computing each task at most once.\n\n## How it works\n\nThe central idea is `getFutureResult\u003cT\u003e(id)`: a typed forward reference to the output of a task that will be evaluated later. When `getResult` or `executeAll` is called, the scheduler resolves each `FutureResult` by computing its source task on demand (lazy evaluation with result caching).\n\n**Example — quadratic equation roots:**\n\n```cpp\nfloat a = 1, b = -2, c = 0;\n\nTTaskScheduler scheduler;\n\n// -4ac\nauto id1 = scheduler.add([](float a, float c) { return -4 * a * c; }, a, c);\n\n// b² + (-4ac)\nauto id2 = scheduler.add([](float b, float v) { return b * b + v; },\n                          b, scheduler.getFutureResult\u003cfloat\u003e(id1));\n\n// (-b + sqrt(D)) and (-b - sqrt(D))\nauto id3 = scheduler.add([](float b, float d) { return -b + std::sqrt(d); },\n                          b, scheduler.getFutureResult\u003cfloat\u003e(id2));\nauto id4 = scheduler.add([](float b, float d) { return -b - std::sqrt(d); },\n                          b, scheduler.getFutureResult\u003cfloat\u003e(id2));\n\n// x₁ = id3 / 2a,  x₂ = id4 / 2a\nauto id5 = scheduler.add([](float a, float v) { return v / (2 * a); },\n                          a, scheduler.getFutureResult\u003cfloat\u003e(id3));\nauto id6 = scheduler.add([](float a, float v) { return v / (2 * a); },\n                          a, scheduler.getFutureResult\u003cfloat\u003e(id4));\n\nscheduler.executeAll();\n\nstd::cout \u003c\u003c scheduler.getResult\u003cfloat\u003e(id5) \u003c\u003c \"\\n\"; // x₁\nstd::cout \u003c\u003c scheduler.getResult\u003cfloat\u003e(id6) \u003c\u003c \"\\n\"; // x₂\n```\n\n`sqrt(D)` is computed once even though both `id5` and `id6` depend on it.\n\n## API\n\n```cpp\n// Register a task. Returns a task handle.\nauto id = scheduler.add(callable, arg1, arg2);  // 0–2 arguments\n\n// Get a lazy reference to a task's future result (use as an argument to another task).\nauto future = scheduler.getFutureResult\u003cT\u003e(id);\n\n// Retrieve the result of a task, computing it (and its dependencies) if needed.\nT result = scheduler.getResult\u003cT\u003e(id);\n\n// Execute all registered tasks in dependency order.\nscheduler.executeAll();\n```\n\n**Supported callable types:** lambdas, function pointers, member function pointers.  \n**Maximum arguments per task:** 2 (the instance counts as an argument for member functions).\n\n## Implementation\n\nThe scheduler uses **type erasure** to store heterogeneous callables in a single container. Each task is wrapped behind an `ICallable` interface with three specializations:\n\n| Class | Arguments |\n|-------|-----------|\n| `Derived0\u003cF, R\u003e` | none |\n| `Derived1\u003cF, R, A\u003e` | one (with `FutureResult` unwrapping) |\n| `Derived2\u003cF, R, A, B\u003e` | two (with `FutureResult` unwrapping for either argument) |\n\n`FutureResult\u003cT\u003e` arguments are detected at compile time via `is_future_result_v` and resolved by calling `getResult` on the referenced task before invoking the callable.\n\n## Build\n\n```bash\nmkdir build \u0026\u0026 cd build\ncmake ..\ncmake --build .\n```\n\nRun the quadratic equation example:\n\n```bash\n./bin/main\n```\n\nRun tests:\n\n```bash\nctest --output-on-failure\n```\n\n## Tests\n\nTest suite built with **Google Test**, covering:\n\n- Primitive data types as task arguments/results\n- `FutureResult` forward references and dependency chains\n- Object references (member function pointers)\n- Execution ordering guarantees\n- Container types as task values\n\n## Requirements\n\n- C++17\n- CMake 3.14+\n- Google Test (fetched automatically via CMake FetchContent)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotakeith%2Ftask-scheduler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnotakeith%2Ftask-scheduler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotakeith%2Ftask-scheduler/lists"}