{"id":19708804,"url":"https://github.com/willkill07/concepts-lighter","last_synced_at":"2025-02-27T14:47:15.112Z","repository":{"id":78761858,"uuid":"95613151","full_name":"willkill07/concepts-lighter","owner":"willkill07","description":"Concepts (with and without SFINAE) in C++11","archived":false,"fork":false,"pushed_at":"2017-07-03T17:14:52.000Z","size":32,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-24T04:13:16.447Z","etag":null,"topics":["concepts","cplusplus","portability","raja"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willkill07.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2017-06-28T00:46:42.000Z","updated_at":"2020-02-17T08:01:56.000Z","dependencies_parsed_at":"2023-02-25T05:00:37.959Z","dependency_job_id":null,"html_url":"https://github.com/willkill07/concepts-lighter","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/willkill07%2Fconcepts-lighter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willkill07%2Fconcepts-lighter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willkill07%2Fconcepts-lighter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willkill07%2Fconcepts-lighter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willkill07","download_url":"https://codeload.github.com/willkill07/concepts-lighter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241025806,"owners_count":19896513,"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":["concepts","cplusplus","portability","raja"],"created_at":"2024-11-11T21:44:59.871Z","updated_at":"2025-02-27T14:47:15.107Z","avatar_url":"https://github.com/willkill07.png","language":"C++","readme":"# Concepts Lighter\n\nBasic concept-like functionality in C++11\n\nSee `example.cpp` for potential usage\n\n*NOTE:* Most of this work is accomplished through original work done by Eric Niebler with `range-v3` and his concepts implementation. I enhanced and simplified the dependence on `meta` to only include relevant metafunctions. This work also leverages the `detector` idiom proposed in N4502.\n\n## Goals\n\n* Provide a concepts facility in C++11 without any third-party libraries\n* Emulate the interface reasonably close\n* Aim for high-throughput by prefering aliases to new struct definitions\n\n## Non-Goals\n\n* Provide a complete concepts replacement for use until Concepts are added to the C++ language\n* Implement the entire Concepts TS and Ranges TS concept list\n\n## Design\n\n### A concept:\n\n* is a type alias which when fully evaluated *can* produce a compiler error\n* provides a protected evaluation context of arbitrary code\n* only detects if operations exist and emit the correct type\n\n### What can a concept do?\n\n* checks if it models another concept (`models\u003cT\u003e()`)\n* checks if an expression is valid (`val\u003cT\u003e() == val\u003cT\u003e()`)\n* checks if an expression has some result type (`has_type\u003cT\u003e(expr)`)\n* checks if an expression has some result type convertible to another (`convertible_to\u003cT\u003e(expr)`)\n\n### What can go in a concept expression?\n\n* type helpers for creating instances of types which may not always be default constructible (`val\u003cT\u003e`, `cval\u003cT\u003e`, `ref\u003cT\u003e`, `cref\u003cT\u003e`\n* any aribitrary code not dependent on any code out of the scope of the concept definition (can only use types)\n\n### What is the syntax for a concept?\n\nA concept first starts with defining the types of which the concept depends on. For example, if we are writing a concept that depends on an aribitrary value type, perhaps `typename Type` might be enough. If we are writing a concept to see if a type models an Iterator of some type, we may want to use `typename Iter`. If we need to check the relations between two types, we will need to define two types as template parameters: `typename T, typename U`\n\n```cpp\ntemplate \u003ctypename Iter\u003e\nusing Iterator = // ...\n```\n\nSo far that's our concept definition. We specified our template arguments and the name of our concept. Next we will look at defining some number of expressions required by `Iterator`. First we need to indicate we are writing a concept instead of a type alias.\n\n```cpp\ntemplate \u003ctypename Iter\u003e\nusing Iterator = DefineConcept( ... );\n\n// OR\n\ntemplate \u003ctypename Iter\u003e\nusing Iterator = decltype(concepts::valid_expr( ... ));\n```\n\nEither syntax is acceptable (`DefineConcept` is a macro). Now we need to determine what are valid expressions in the concept of an `Iterator`. According to the Ranges TS, an `Iterator` requires the functionality of pre-incrementing (`operator++`) and dereferencing (`operator*`).\n\nLet us first look at normal usages:\n\n```cpp\nIter i; // we have an instance of Iter\n++i; // preincrement -- return type should be Iter\u0026\n*i;  // dereference -- unspecified return type\n```\n\nSince we are not able to declare any variables in a type definition, we will leverage the `ref\u003cT\u003e()` component provided in this concepts framework:\n\n```cpp\nconcepts::has_type\u003cIter\u0026\u003e(++concepts::ref\u003cIter\u003e());\n*concepts::ref\u003cIter\u003e();\n```\n\nWe no longer have any variable definitions, and can easily replace the semicolons of separate statements to be comma-separated for our expression list:\n\n```cpp\ntemplate \u003ctypename Iter\u003e\nusing Iterator = DefineConcept(\n  concepts::has_type\u003cIter\u0026\u003e(++concepts::ref\u003cIter\u003e()),\n  *concepts::ref\u003cIter\u003e()\n);\n```\n\nThis is a complete concept definition! Look further up at `ForwardIterator` to see extended implementations using `ref\u003cT\u003e()`, `has_type\u003cT\u003e(expr)`, and `models\u003cConcept\u003e()`.\n\n## Usage\n\nA very simple usage pattern is illustrated below\n\n```cpp\ntemplate \u003ctypename T\u003e\nusing LessThanComparable =\n  DefineConcept(\n    concepts::convertible_to\u003cbool\u003e(\n      concepts::val\u003cT\u003e() \u003c concepts::val\u003cT\u003e())));\n```\n\nPlease note that there are a few key components (and everything lives under `namespace concepts`:\n\n* `concepts::valid_expr(...)` -- a function accepting a list of expressions to evaluate -- consider using the wrapper macro `DefineConcept(...)` instead\n* `concepts::has_type\u003cT\u003e(x)` -- a function accepting an expression that checks the return type and ensures it matches the passed type\n* `concepts::convertible_to\u003cT\u003e(x)` -- a function accepting an expression that checks the return type to a passed type for conversion\n* `concepts::models\u003cConceptType\u003e()` -- a function accepting a fully-qualified concept name of which a new concept should model\n* `concepts::val\u003cT\u003e()` -- a function accepting a type that returns a `declval` instance of `T`\n* `concepts::ref\u003cT\u003e()` -- a function accepting a type that returns a `declval` instance of `T\u0026`\n* `concepts::cref\u003cT\u003e()` -- a function accepting a type that returns a `declval` instance of `T const \u0026`\n* `concepts::cval\u003cT\u003e()` -- a function accepting a type that returns a `declval` instance of `T const`\n\nWe are also able to easily check for total comparisons between any two types:\n\n```cpp\ntemplate \u003ctypename T, typename U\u003e\nusing ComparableTo = DefineConcept(\n    convertible_to\u003cbool\u003e(val\u003cU\u003e() \u003c  val\u003cT\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cT\u003e() \u003c  val\u003cU\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cU\u003e() \u003c= val\u003cT\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cT\u003e() \u003c= val\u003cU\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cU\u003e() \u003e  val\u003cT\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cT\u003e() \u003e  val\u003cU\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cU\u003e() \u003e= val\u003cT\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cT\u003e() \u003e= val\u003cU\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cU\u003e() == val\u003cT\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cT\u003e() == val\u003cU\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cU\u003e() != val\u003cT\u003e()),\n    convertible_to\u003cbool\u003e(val\u003cT\u003e() != val\u003cU\u003e())));\n\ntemplate \u003ctypename T\u003e using Comparable = ComparableTo\u003cT, T\u003e;\n```\n\nBelow is an example of Iterator concepts using the convenience macro (and assuming `using namespace concepts`)\n```cpp\n\ntemplate \u003ctypename T\u003e\nusing Iterator = DefineConcept(\n  *ref\u003cT\u003e(),                // checks dereference\n  has_type\u003cT \u0026\u003e(++ref\u003cT\u003e()) // checks return type from preincrement\n);\n\ntemplate \u003ctypename T\u003e\nusing ForwardIterator = DefineConcept(\n  models\u003cIterator\u003cT\u003e\u003e(), // ForwardIterator models Iterator\n  ref\u003cT\u003e()++,            // and provides post-increment\n  *ref\u003cT\u003e()++            // and dereferencing a post-increment expression\n);\n\ntemplate \u003ctypename T\u003e\nusing BidirectionalIterator = DefineConcept(\n  models\u003cForwardIterator\u003cT\u003e\u003e(),          // BidirectionalIterator models ForwardIterator\n  has_type\u003cT \u0026\u003e(--ref\u003cT\u003e()),             // and provides pre-decrement\n  convertible_to\u003cT const \u0026\u003e(ref\u003cT\u003e()--), // and post-decrement\n  *ref\u003cT\u003e()--                            // and dereferencing a post-decrement\n);\n\ntemplate \u003ctypename T\u003e\nusing diff_t = decltype(val\u003cT\u003e() - val\u003cT\u003e()); // alias for difference_type\n\ntemplate \u003ctypename T\u003e\nusing RandomAccessIterator = DefineConcept(\n  models\u003cBidirectionalIterator\u003cT\u003e\u003e(),          // RandomAccessIterator models BidirectionalIterator\n  has_type\u003cT \u0026\u003e(ref\u003cT\u003e() += val\u003cdiff_t\u003cT\u003e\u003e()), // allows for arbitrary advancement\n  has_type\u003cT\u003e(val\u003cT\u003e() + val\u003cdiff_t\u003cT\u003e\u003e()),    // addition to difference_type\n  has_type\u003cT\u003e(val\u003cdiff_t\u003cT\u003e\u003e() + val\u003cT\u003e()),    // --- where order does not matter\n  has_type\u003cT \u0026\u003e(ref\u003cT\u003e() -= val\u003cdiff_t\u003cT\u003e\u003e()), // arbitrary decrement modifying\n  has_type\u003cT\u003e(val\u003cT\u003e() - val\u003cdiff_t\u003cT\u003e\u003e()),    // and by unmodified with expression\n  val\u003cT\u003e()[val\u003cdiff_t\u003cT\u003e\u003e()]                   // and allows indexing with operator[]\n);\n```\n\nFurther examples and usage patterns will be described in the future\n\n## License\n\nThis software is provided under a dual-license scheme (Boost License + BSD 3-clause).\n\nThe Boost License is use for relevant code from `ericneibler/range-v3` while the BSD 3-clause further specifies additional constraints on distribution, private use, and sublicensing.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillkill07%2Fconcepts-lighter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillkill07%2Fconcepts-lighter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillkill07%2Fconcepts-lighter/lists"}