{"id":13521374,"url":"https://github.com/lamarrr/STX","last_synced_at":"2025-03-31T20:31:21.843Z","repository":{"id":45097570,"uuid":"250762873","full_name":"lamarrr/STX","owner":"lamarrr","description":"C++17 \u0026 C++ 20 error-handling and utility extensions. ","archived":false,"fork":false,"pushed_at":"2023-12-26T22:43:32.000Z","size":5117,"stargazers_count":631,"open_issues_count":0,"forks_count":20,"subscribers_count":16,"default_branch":"main","last_synced_at":"2024-11-02T05:32:52.335Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://lamarrr.github.io/STX","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/lamarrr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"lamarrr","patreon":"lamarrr","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-03-28T10:08:03.000Z","updated_at":"2024-10-20T06:29:13.000Z","dependencies_parsed_at":"2023-10-05T04:02:27.350Z","dependency_job_id":"8955f7cd-3477-41dc-87b7-55878058c855","html_url":"https://github.com/lamarrr/STX","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamarrr%2FSTX","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamarrr%2FSTX/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamarrr%2FSTX/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamarrr%2FSTX/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lamarrr","download_url":"https://codeload.github.com/lamarrr/STX/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246535896,"owners_count":20793346,"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","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-08-01T06:00:33.525Z","updated_at":"2025-03-31T20:31:21.385Z","avatar_url":"https://github.com/lamarrr.png","language":"C++","funding_links":["https://github.com/sponsors/lamarrr","https://patreon.com/lamarrr"],"categories":["C++","未分类","Libraries \u0026 Frameworks:"],"sub_categories":["Other"],"readme":"\u003cimg src=\"https://github.com/lamarrr/STX/workflows/cpp-17:clang-14:macos-12/badge.svg\"\u003e \u003cimg src=\"https://github.com/lamarrr/STX/workflows/cpp-17:clang-14:ubuntu-22.04/badge.svg\"\u003e \u003cimg src=\"https://github.com/lamarrr/STX/workflows/cpp-17:gcc-12:ubuntu-22.04/badge.svg\"\u003e \u003cimg src=\"https://github.com/lamarrr/STX/workflows/cpp-17:msvc-2019:windows/badge.svg\"\u003e\n\u003cimg src=\"https://github.com/lamarrr/STX/workflows/cpp-17:clang-15:ubuntu-22.04-qemu-arm/badge.svg\"\u003e\n\n\u003cbr/\u003e\n\u003cdiv align=\"center\"\u003e\u003cimg src=\"assets/stx.png\"/\u003e \u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\u003ci\u003e C++ 17 \u0026 C++ 20 error-handling and utility extensions.\u003c/i\u003e\n\u003c/div\u003e\n\n## Overview\n\nSTX is a collection of libraries and utilities designed to make working with C++ easier and less error-prone.\n\n\u003cdiv align=\"center\"\u003e\n\u003ch3\u003e\n\u003ca href=\"http://lamarrr.github.io/STX\"\u003e READ THE DOCUMENTATION \u003c/a\u003e\n\u003c/h3\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\u003ch3\u003e\n\u003ca href=\"https://github.com/lamarrr/STX/tree/master/examples\"\u003e SEE THE EXAMPLES \u003c/a\u003e\n\u003c/h3\u003e\n\u003c/div\u003e\n\n## Features\n\n* Experimental async library, runtime, and scheduler\n* C-API-compatible functor object `Fn\u003cReturn(Args...)\u003e`\n* Memory allocators\n* Resource reference-counting `Rc\u003cHandle\u003e`\n* `Span\u003cT\u003e` with helper methods that eliminates use of iterator-pairs\n* `Vec\u003cT\u003e` with trivial relocation (faster than `std::vector\u003cT\u003e`)\n* Efficient `Result\u003cT, Err\u003e` (error-handling) and with monadic methods\n* Efficient `Option\u003cT\u003e` (optional-value handling) with monadic methods\n* UTF-8 string iterator method\n* Fail-fast (Abandonment/ Fatal failure) via `panic` s\n* Runtime panic hooks\n* Backtrace library\n* Source Location\n* Panic with backtraces\n* Portable, suitable, and easily-adoptable for embedded systems, real-time systems, safety-critical systems, and operating systems\n* Easy debugging\n* Easy to use and hard to misuse API\n* Exception-free, RTTI-free, and memory allocation free ( `no-std` )\n* Space and time deterministic error-handling\n* Deterministic value lifetimes\n* Eliminates repetitive code and abstractable error-handling logic code via monadic extensions\n* Fast success and error return paths\n* Modern and clean API\n* Well-documented\n* Extensively tested\n\n## Basic Examples\n\n### Option\n\n``` cpp\n\n#include \u003ciostream\u003e\n\n#include \"stx/option.h\"\n\nusing stx::Option, stx::Some, stx::None;\n\nauto safe_divide(double numerator, double denominator) -\u003e Option\u003cdouble\u003e {\n  if (denominator == 0.0) return None;\n  return Some(numerator / denominator);\n}\n\nint main() {\n  safe_divide(5.0, 2.0).match(\n      [](auto value) { std::cout \u003c\u003c \"Result: \" \u003c\u003c value \u003c\u003c std::endl; },\n      []() { std::cout \u003c\u003c \"Cannot divide by zero\" \u003c\u003c std::endl; });\n}\n\n```\n\n### Result\n\n``` cpp\n\n#include \u003carray\u003e\n#include \u003ccinttypes\u003e\n#include \u003ciostream\u003e\n\n#include \"stx/result.h\"\n\nusing std::array, std::string_view;\nusing namespace std::literals;\n\nusing stx::Result, stx::Ok, stx::Err;\n\nenum class Version { V1 = 1, V2 = 2 };\n\nauto parse_version(array\u003cuint8_t, 6\u003e const\u0026 header) -\u003e Result\u003cVersion, string_view\u003e {\n  switch (header.at(0)) {\n    case 1:\n      return Ok(Version::V1);\n    case 2:\n      return Ok(Version::V2);\n    default:\n      return Err(\"Unknown Version\"sv);\n  }\n}\n\nint main() {\n  parse_version({2, 3, 4, 5, 6, 7}).match([](auto version){\n    std::cout \u003c\u003c \"Version: \" \u003c\u003c static_cast\u003cint\u003e(version) \u003c\u003c std::endl;\n  }, [](auto error){\n    std::cout \u003c\u003c error  \u003c\u003c std::endl;\n  });\n\n}\n\n```\n\n### Propagating Errors with `TRY_OK`\n\n`TRY_OK` assigns the successful value to its first parameter `version` if `parse_version` returned an `Ok` , else propagates the error value.\n\n``` cpp\n\n// As in the example above\nauto parse_version(array\u003cuint8_t, 6\u003e const\u0026 header) -\u003e Result\u003cVersion, string_view\u003e;\n\nauto parse_data(array\u003cuint8_t, 6\u003e const\u0026 header) -\u003e Result\u003cuint8_t, string_view\u003e {\n  TRY_OK(version, parse_version(header));\n  return Ok(version + header[1] + header[2]);\n}\n\nint main() {\n  auto parsed = parse_data({2, 3, 4, 5, 6, 7}).unwrap();\n\n  std::cout \u003c\u003c parsed \u003c\u003c std::endl;\n}\n\n```\n\nYou can also add const/volatile attributes to `TRY_OK` 's assigned value, i.e:\n\n``` cpp\n\nauto parse_data(array\u003cuint8_t, 6\u003e const\u0026 header) -\u003e Result\u003cuint8_t, string_view\u003e {\n  TRY_OK(const version, parse_version(header));\n  return Ok(version + header[1] + header[2]);\n}\n\n```\n\n## Guidelines\n\n* Result and Option will only work in `constexpr` context (compile-time error-handling) in C++ 20, to check if you can use it as `constexpr` check if the macros `STX_RESULT_IS_CONSTEXPR` and `STX_OPTION_IS_CONSTEXPR` are set to `1`, for an example see [`constexpr_test`](tests/constexpr_test.cc) .\n* To ensure you never forget to use the returned errors/results, raise the warning levels for your project ( `-Wall`  `-Wextra`  `-Wpedantic` on GNUC-based compilers, and `/W4` on MSVC)\n* Some methods like `map` , `unwrap`, `or_else`, and most of `Result` and `Option`'s monadic methods **consume** the stored value and thus the `Result` or `Option` has to be destroyed as its lifetime has ended. For example:\n\n  Say we define a function named `safe_divide` as in the example above, with the following prototype:\n\n``` cpp\nauto safe_divide(float n, float d) -\u003e Option\u003cfloat\u003e;\n```\n\nAnd we call:\n\n``` cpp\nfloat result = safe_divide(n, d).unwrap(); // compiles, because 'safe_divide' returns a temporary\n```\n\n``` cpp\nOption option = safe_divide(n, d);\nfloat result = option.unwrap();  // will not compile, because 'unwrap' consumes the value and is only usable with temporaries (as above) or r-value references (as below)\n```\n\nAlternatively, suppose the `Option` or `Result` is no longer needed, we can obtain an r-value reference:\n\n``` cpp\n\nOption option = safe_divide(n, d);\nfloat result  = std::move(option).unwrap(); // will compile, the value is moved out of 'option' , 'option' should not be used any more\n\n```\n\n\u003cb\u003eNOTE\u003c/b\u003e: Just as any moved-from object, `Option` and `Result` are not to be used after a `std::move` ! (as the objects will be left in an unspecified state).\n\n* `Result` and `Option` do not make any implicit copies of the contained object as they are designed as purely forwarding types, this is especially due to their primary purpose as return channels in which we do not want duplication nor implicit copies of the returned values.\n\nTo make explicit copies:\n\n``` cpp\n\nOption option = safe_divide(n, d);\nfloat result = option.clone().unwrap(); // note that 'clone()' explicitly makes a copy of the 'Option'\n\n```\n\nWe can also obtain an l-value reference to copy the value:\n\n``` cpp\n\nOption option = safe_divide(n, d);\nfloat result = option.value(); // note that 'value()' returns an l-value reference and 'result' is copied from 'option''s value in the process\n\n```\n\n``` cpp\n\nfloat result = safe_divide(n, d).value(); // this won't compile as 'value' always returns an l-value reference, use 'unwrap()' instead\n\n```\n\n* All methods of `Result` and `Option` pass r-value/l-value references to their invocable parameters.\n\n## Build Requirements\n\n* CMake\n* Make or Ninja Build\n* C++ 17 or C++ 20 Compiler\n* Git\n* Doxygen and Graphviz (for documentation)\n\n## License\n\n[**MIT License**](LICENSE)\n\n## FAQ\n\n### Is STX's ABI stable?\n\nNO\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flamarrr%2FSTX","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flamarrr%2FSTX","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flamarrr%2FSTX/lists"}