{"id":17263281,"url":"https://github.com/brevzin/span_ext","last_synced_at":"2025-07-20T20:36:02.147Z","repository":{"id":90050997,"uuid":"247561075","full_name":"brevzin/span_ext","owner":"brevzin","description":"Comparison operators for std::span","archived":false,"fork":false,"pushed_at":"2020-03-27T00:30:14.000Z","size":138,"stargazers_count":15,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T21:11:07.605Z","etag":null,"topics":["cpp","cpp20","span"],"latest_commit_sha":null,"homepage":null,"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/brevzin.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":"2020-03-15T22:16:59.000Z","updated_at":"2024-09-04T13:51:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"458725c8-e827-48b9-9ed7-9422165ea5c0","html_url":"https://github.com/brevzin/span_ext","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brevzin%2Fspan_ext","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brevzin%2Fspan_ext/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brevzin%2Fspan_ext/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brevzin%2Fspan_ext/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brevzin","download_url":"https://codeload.github.com/brevzin/span_ext/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248839526,"owners_count":21169826,"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":["cpp","cpp20","span"],"created_at":"2024-10-15T07:56:05.105Z","updated_at":"2025-04-14T07:33:35.577Z","avatar_url":"https://github.com/brevzin.png","language":"C++","readme":"# span_ext\n\nWhen `std::span` was added by [P0122](https://wg21.link/p0122), it had comparison\noperators that performed a deep comparison. Those comparison operators were\nremoved as a result of [P1085](https://wg21.link/p1085).\n\nI disagree with that removal - I do not consider it important that `span`\nbe Regular (and am not even sure that a deep-comparing fail fails to model\n[`std::equality_comparable`](http://eel.is/c++draft/concept.equalitycomparable))\nand I consider comparisons for `std::span` to be quite useful, and that as a\nresult we're missing functionality.\n\nThe goal of this repository is to provide that missing functionality, if you\nchoose to use it, and to gather feedback about the use of these operations.\nIf this repo proves broadly useful, then we should reconsider P1085. If this\nrepo reveals problems with `std::span` having deep comparison, then I will\nreconsider my position.\n\nNote that this repository does provide comparison operators in `namespace std`.\nThis is technically UB, as only the standard library is allowed to put things\nin there (outside of specific exceptions, like providing specializations for\nspecific class templates in `std`), but these operators do not exist today so\nthere is nothing to conflict with.\n\n# Design\n\nGiven the premise that `std::span` should have deep comparisons, the question\nis what comparisons should be allowed? Should `std::span\u003cint\u003e` be comparable\nwith:\n\n1. `std::span\u003cint const\u003e`?\n2. `std::vector\u003cint\u003e`?\n3. `std::list\u003cint\u003e`?\n4. `std::vector\u003clong\u003e`?\n\nMy position is that `span`'s direct comparison operators should behave basically\nlike a `memcmp` - the easy-to-use syntax should only be there when you're\ndirectly comparing blocks of memory. To that end, (1) and (2) should be allowed\n(differing `const`ness is irrelevant and we don't care who owns the block of\nmemory) but comparing against (3) non-contiguous containers or (4) containers\nof a different type are not supported. There is always `std::ranges::equal` for\nthat.\n\nIn other words, in this repo,\n`span\u003cT\u003e` is comparable with any `contiguous_range` with\n`value_type` `U` such that `remove_cvref_t\u003cT\u003e` and `remove_cvref_t\u003cU\u003e` are the\nsame type.\n\nNote that while with this design, you can compare a `span\u003cint\u003e` to a `vector\u003cint\u003e`,\nit will still be the case that `std::equality_comparable_with\u003cspan\u003cint\u003e, vector\u003cint\u003e\u003e`\nfails while `std::equality_comparable_with\u003cspan\u003cint const\u003e, vector\u003cint\u003e\u003e` holds.\nThis is because `span\u003cint\u003e` and `vector\u003cint\u003e` do not share a common reference\n(while `span\u003cint const\u003e` and `vector\u003cint\u003e` do) - because `span\u003cint\u003e` is not\nconstructible from a `vector\u003cint\u003e` rvalue.\n\n# Usage\n\nJust include `\u003cspan_ext/span_ext.h\u003e` and it's as if `std::span` itself had\ncomparison operators already.\n\n# Compiler requirements\n\nThese operators depend on the existence of `std::span`, the Concepts language\nfeature, some of the functionality introduced by Ranges, and `\u003c=\u003e`.\n\nAs a polyfill the standard library concepts and Ranges, this library will\nfall back to using range-v3.\n\nThis library currently works with:\n\n- gcc trunk\n- clang-10 with range-v3\n\n# Building and Testing\n\nTo test with clang-10, you need to also use range-v3. That can be done as follows:\n\n```\n$ mkdir build \u0026\u0026 cd build\n$ CC=$(which clang) CXX=$(which clang-10) cmake -G Ninja -DCMAKE_CXX_FLAGS=\"-std=c++20 -Wall -Wextra\" -DSPAN_EXT_LIBCXX=On -DSPAN_EXT_RANGE_V3_PATH=/path/to/range-v3 -DSPAN_EXT_TESTS=On ..\n$ ninja\n$ ninja test\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrevzin%2Fspan_ext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrevzin%2Fspan_ext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrevzin%2Fspan_ext/lists"}