{"id":24481104,"url":"https://github.com/patrickroberts/pr","last_synced_at":"2026-03-03T19:01:29.903Z","repository":{"id":272090851,"uuid":"915502266","full_name":"patrickroberts/pr","owner":"patrickroberts","description":"An assortment of standalone C++ utilities","archived":false,"fork":false,"pushed_at":"2025-04-11T05:17:48.000Z","size":67,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T06:25:19.172Z","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/patrickroberts.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,"zenodo":null}},"created_at":"2025-01-12T02:29:58.000Z","updated_at":"2025-04-11T05:17:52.000Z","dependencies_parsed_at":"2025-01-12T03:25:39.233Z","dependency_job_id":"fa14f65f-ad94-4cde-926c-d423a7d7a9fa","html_url":"https://github.com/patrickroberts/pr","commit_stats":null,"previous_names":["patrickroberts/pr"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickroberts%2Fpr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickroberts%2Fpr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickroberts%2Fpr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickroberts%2Fpr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patrickroberts","download_url":"https://codeload.github.com/patrickroberts/pr/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252873938,"owners_count":21817708,"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":"2025-01-21T11:19:00.202Z","updated_at":"2026-03-03T19:01:29.898Z","avatar_url":"https://github.com/patrickroberts.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `pr`\n\nAn assortment of standalone C++ utilities\n\n## [`include/pr/context.hpp`](include/pr/context.hpp)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 style=\"display:inline-block\"\u003eSynopsis\u003c/h3\u003e\u003c/summary\u003e\n\n```cpp\nnamespace pr {\n\ntemplate \u003cclass T\u003e\nconcept /*storable*/ = std::same_as\u003cT, std::remove_cvref_t\u003cT\u003e\u003e;\n\ntemplate \u003c/*storable*/ T\u003e\ninline thread_local constinit T * /*context*/ = nullptr;\n\ntemplate \u003cclass T\u003e\nconcept /*makeable*/ =\n    /*storable*/\u003cstd::remove_reference_t\u003cT\u003e\u003e and not std::is_rvalue_reference_v\u003cT\u003e;\n\ntemplate \u003cmakeable_ T\u003e\nclass /*provider*/ {\n  using value_type = std::remove_reference_t\u003cT\u003e;\n\n  // `mutable` prevents UB when `make_context` initializes a `const auto`\n  [[no_unique_address]] mutable T inner_; // exposition-only\n  value_type *outer_; // exposition-only\n\npublic:\n  template \u003cclass... ArgsT\u003e\n    requires std::constructible_from\u003cT, ArgsT...\u003e\n  explicit /*provider*/(ArgsT \u0026\u0026...args) noexcept(\n      std::is_nothrow_constructible_v\u003cT, ArgsT...\u003e);\n\n  /*provider*/(const /*provider*/ \u0026) = delete;\n  /*provider*/(/*provider*/ \u0026\u0026) = delete;\n\n  ~/*provider*/() noexcept;\n};\n\ntemplate \u003c/*makeable*/ T, class... ArgsT\u003e\n  requires std::constructible_from\u003cT, ArgsT...\u003e\n[[nodiscard]] auto make_context(ArgsT \u0026\u0026...args) noexcept(\n    std::is_nothrow_constructible_v\u003cT, ArgsT...\u003e) -\u003e /*provider*/\u003cT\u003e;\n\ntemplate \u003cclass T\u003e\nconcept /*gettable*/ = /*storable*/\u003cstd::remove_const_t\u003cT\u003e\u003e;\n\ntemplate \u003c/*gettable*/ T\u003e\n[[nodiscard]] auto get_context() noexcept -\u003e T *;\n\n} // namespace pr\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 style=\"display:inline-block\"\u003e\u003ccode\u003epr::make_context\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\n\n```cpp\ntemplate \u003c/*makeable*/ T, class... ArgsT\u003e\n  requires std::constructible_from\u003cT, ArgsT...\u003e\n[[nodiscard]] auto make_context(ArgsT \u0026\u0026...args) noexcept(\n    std::is_nothrow_constructible_v\u003cT, ArgsT...\u003e) -\u003e /*provider*/\u003cT\u003e;\n```\n\nConstructs and returns `/*provider*/\u003cT\u003e`, whose constructor initializes its members as if by `inner_(std::forward\u003cArgsT\u003e(args)...), outer_(std::exchange(/*context*/\u003cvalue_type\u003e, std::addressof(inner_)))`. Its destructor restores `/*context*/\u003cvalue_type\u003e` to the value of `outer_`. `T` must be a cv-unqualified non-reference or lvalue-reference type, or the instantiation is ill-formed, which can result in substitution failure when the call appears in the immediate context of a template instantiation.\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 style=\"display:inline-block\"\u003e\u003ccode\u003epr::get_context\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\n\n```cpp\ntemplate \u003c/*gettable*/ T\u003e\n[[nodiscard]] auto get_context() noexcept -\u003e T *;\n```\n\nReturns `/*context*/\u003cvalue_type\u003e`, whose value has been initialized by thread-local calls to `pr::make_context\u003cvalue_type\u003e(...)` or `pr::make_context\u003cvalue_type \u0026\u003e(...)`, or `nullptr` otherwise. `T` must be an optionally const-qualified non-reference type, or the instantiation is ill-formed, which can result in substitution failure when the call appears in the immediate context of a template instantiation.\n\n\u003c/details\u003e\n\n## [`include/pr/shared_view.hpp`](include/pr/shared_view.hpp)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 style=\"display:inline-block\"\u003eSynopsis\u003c/h3\u003e\u003c/summary\u003e\n\n```cpp\nnamespace pr {\n  namespace ranges {\n\n    template \u003cclass T\u003e\n    concept copyable_view = /* see description */;\n\n    template \u003cclass T\u003e\n    concept shared_range = /* see description */;\n\n    template \u003cstd::ranges::viewable_range R\u003e\n      requires std::movable\u003cR\u003e\n    class shared_view;\n\n    namespace views {\n      inline constexpr /* unspecified */ shared = /* unspecified */;\n    } // namespace views\n  } // namespace ranges\n\n  namespace views = ranges::views;\n\n} // namespace pr\n\ntemplate \u003cclass T\u003e\ninline constexpr bool\n    std::ranges::enable_borrowed_range\u003cpr::ranges::shared_view\u003cT\u003e\u003e =\n        std::ranges::enable_borrowed_range\u003cT\u003e;\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 style=\"display:inline-block\"\u003e\u003ccode\u003epr::ranges::copyable_view\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\n\n#### Concept\n\n```cpp\nnamespace pr::ranges {\n\n  template \u003cclass T\u003e\n  concept copyable_view = std::ranges::view\u003cT\u003e and std::copyable\u003cT\u003e;\n\n}\n```\n\nThe `pr::ranges::copyable_view` concept is a refinement of `std::ranges::view` for which `std::copyable` is satisfied.\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 style=\"display:inline-block\"\u003e\u003ccode\u003epr::ranges::shared_range\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\n\n#### Concept\n\n```cpp\nnamespace pr::ranges {\n\n  template \u003cclass T\u003e\n  concept shared_range =\n      std::ranges::viewable_range\u003cT\u003e and\n      std::copyable\u003cstd::views::all_t\u003cT\u003e\u003e;\n\n}\n```\n\nThe `pr::ranges::shared_range` concept is a refinement of `std::ranges::viewable_range` for which `std::copyable` is satisfied by `std::views::all_t\u003cT\u003e`.\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 style=\"display:inline-block\"\u003e\u003ccode\u003epr::ranges::views::shared\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\n\n#### Call signature\n\n```cpp\ntemplate \u003cstd::ranges::viewable_range R\u003e\n  requires shared_range\u003cR\u003e or std::movable\u003cR\u003e\n[[nodiscard]] constexpr auto shared(R \u0026\u0026range) -\u003e copyable_view auto;\n```\n\nGiven an expression `e` of type `T`, the expression `pr::views::shared(e)` is expression-equivalent to:\n- `std::views::all(e)`, if it is a well-formed expression and `std::views::all_t\u003cT\u003e` models `std::copyable`;\n- `pr::ranges::shared_view{e}` otherwise.\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 style=\"display:inline-block\"\u003e\u003ccode\u003epr::ranges::shared_view\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\n\n```cpp\ntemplate \u003cstd::ranges::viewable_range R\u003e\n  requires std::movable\u003cR\u003e\nclass shared_view\n    : public std::ranges::view_interface\u003cshared_view\u003cR\u003e\u003e\n```\n\nA view that has shared ownership of a range. It wraps a shared pointer to that range.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch4 style=\"display:inline-block\"\u003eData members\u003c/h4\u003e\u003c/summary\u003e\n\n| Member object                            | Definition                                                                 |\n| ---------------------------------------- | -------------------------------------------------------------------------- |\n| `std::shared_ptr\u003cR\u003e range_ptr` (private) | A shared pointer to the underlying range. (exposition-only member object*) |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch4 style=\"display:inline-block\"\u003eMember functions\u003c/h4\u003e\u003c/summary\u003e\n\n#### `pr::ranges::shared_view\u003cR\u003e::shared_view`\n\n| \u003c!-- --\u003e                                                | \u003c!-- --\u003e |\n| ------------------------------------------------------- | -------- |\n| `shared_view() requires std::default_initializable\u003cR\u003e;` | (1)      |\n| `explicit shared_view(R \u0026\u0026base);`                       | (2)      |\n\nConstructs a `shared_view`.\n\n1) Default constructor. Initializes `range_ptr` as if by `range_ptr(std::make_shared\u003cR\u003e())`.\n2) Initializes the underlying `range_ptr` with `std::make_shared\u003cR\u003e(std::move(base))`.\n\n---\n\n#### `pr::ranges::shared_view\u003cR\u003e::base`\n\n| \u003c!-- --\u003e                                          |\n| ------------------------------------------------- |\n| `[[nodiscard]] auto base() const noexcept -\u003e R \u0026` |\n\nReturns `*range_ptr`.\n\n---\n\n#### `pr::ranges::shared_view\u003cR\u003e::begin`\n\n| \u003c!-- --\u003e                                                          |\n| ----------------------------------------------------------------- |\n| `[[nodiscard]] auto begin() const -\u003e std::ranges::iterator_t\u003cR\u003e;` |\n\nReturns `std::ranges::begin(*range_ptr)`.\n\n---\n\n#### `pr::ranges::shared_view\u003cR\u003e::end`\n\n| \u003c!-- --\u003e                                                        |\n| --------------------------------------------------------------- |\n| `[[nodiscard]] auto end() const -\u003e std::ranges::iterator_t\u003cR\u003e;` |\n\nReturns `std::ranges::end(*range_ptr)`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch4 style=\"display:inline-block\"\u003eHelper templates\u003c/h4\u003e\u003c/summary\u003e\n\n```cpp\ntemplate \u003cclass T\u003e\ninline constexpr bool\n    std::ranges::enable_borrowed_range\u003cpr::ranges::shared_view\u003cT\u003e\u003e =\n        std::ranges::enable_borrowed_range\u003cT\u003e;\n```\n\nThis specialization of `std::ranges::enable_borrowed_range` makes `shared_view` satisfy `borrowed_range` when the underlying range satisfies it. \n\n\u003c/details\u003e\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrickroberts%2Fpr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatrickroberts%2Fpr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrickroberts%2Fpr/lists"}