{"id":13730541,"url":"https://github.com/tacticalmelonfarmer/cxl","last_synced_at":"2025-05-08T03:30:49.912Z","repository":{"id":216133665,"uuid":"154008828","full_name":"tacticalmelonfarmer/cxl","owner":"tacticalmelonfarmer","description":"A C++17 metaprogramming library. Strings, Parsing, Typelists, Aggregate to Tuple conversions and Constant integral literals","archived":false,"fork":false,"pushed_at":"2019-01-25T03:11:20.000Z","size":163,"stargazers_count":50,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-14T21:38:06.600Z","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/tacticalmelonfarmer.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":"2018-10-21T13:02:04.000Z","updated_at":"2024-04-16T09:14:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"368237e5-1d26-42f8-8e50-b91caceb00f4","html_url":"https://github.com/tacticalmelonfarmer/cxl","commit_stats":null,"previous_names":["tacticalmelonfarmer/cxl"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacticalmelonfarmer%2Fcxl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacticalmelonfarmer%2Fcxl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacticalmelonfarmer%2Fcxl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacticalmelonfarmer%2Fcxl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tacticalmelonfarmer","download_url":"https://codeload.github.com/tacticalmelonfarmer/cxl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252992883,"owners_count":21837187,"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-03T02:01:16.294Z","updated_at":"2025-05-08T03:30:49.900Z","avatar_url":"https://github.com/tacticalmelonfarmer.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# Constant eXpression Library (abbreviated **cxl**)\n\n## Fundamental Utilities\n**include/cxl/utility.hpp** contains basic template types and functions\nthat are used across the whole library, such as `cxl::index_t` which is used in \nplace of `size_t` and as indices, it should be a signed integer type capable \nof holding relatively large values, it is signed to allow negative indices. \nanything that requires a huge unsigned integer as an index value should probably not be done at \ncompile-time. `cxl::select_t\u003cN, Types...\u003e` selects the `N`th type in `Types...`. \n`cxl::index_range\u003cIndices...\u003e` holds a parameter pack of `cxl::index_t`, and provides some methods:\n* `.size()`\n  * returns a `std::integral_constant\u003cindex_t, sizeof...(Indices)\u003e`\n* `operator[]`\n  * takes a `std::integral_constant\u003cindex_t, N\u003e` and returns the `N`th value in `Indices...`\n\ntemplate function `cxl::make_index_range\u003cindex_t First, index_t Last\u003e()` returns:\n* `First` \u003c `Last`?\n  * a `cxl::index_range\u003cIndices...\u003e` where `Indices...` starts at First **ascending** to Last\n* `First` \u003e `Last`?\n  * a `cxl::index_range\u003cIndices...\u003e` where `Indices...` starts at First **descending** to Last\n\ntemplate function `cxl::pow\u003cauto N, auto E\u003e()` is a compile time power/exponent function:\n  * `N` is the base\n  * `E` is the exponent\n\n## Aggregate\n**include/cxl/aggregate.hpp** contains the aggregate sublibrary. this sublibrary allows converting arbitrary \naggregate class type objects into tuples of their member variables, or converting a sequence of variables into a struct.\nto convert a struct to tuple pass it into `cxl::destructure(...)`, if it is an lvalue the tuple contains references to the members, \notherwise it contains copied values. to make a `struct` out of a sequence of variables pass them into `cxl::make_struct(...)`.\n\n## Integral\n**include/cxl/integral.hpp** contains templated user-defined \nliteral operators that allow you to easily convert literals \nto `std::integral_constant\u003c...\u003e`s.\n* literal operator `_i` returns an `index_t` integral constant\n* literal operator `_i8` returns an `int8_t` integral constant\n* literal operator `_i16` returns an `int16_t` integral constant\n* literal operator `_i32` returns an `int32_t` integral constant\n* literal operator `_i64` returns an `int64_t` integral constant\n* literal operator `_u8` returns an `uint8_t` integral constant\n* literal operator `_u16` returns an `uint16_t` integral constant\n* literal operator `_u32` returns an `uint32_t` integral constant\n* literal operator `_u64` returns an `uint64_t` integral constant\n\n## Iterator\n**include/cxl/iterator.hpp** contains an adaptable constexpr iterator class\n`cxl::iterator\u003c...\u003e` which can support any constexpr class that implements the following methods properly:\n* `constexpr auto begin() const`\n* `constexpr auto end() const`\n* `template\u003ctypename T, T value\u003e`  \n`constexpr auto operator[](std::integral_constant\u003cT,value\u003e) const`\n\n## String\n**include/cxl/string.hpp** contains a string class `cxl::string\u003c...\u003e` with \na completely constexpr compatible interface. It also supports the\n`cxl::iterator\u003c...\u003e`s. Elements can be accesed through \nan iterator, operator[] or converting to const char*. String can \nbe created through a macro `STR(\"string\")`, because C++17 \ndoes not support templated user-defined string literals. The long way would \nbe `cxl::string\u003c's','t','r','i','n','g'\u003e{}`\n\n## Typelist\n**include/cxl/typelist.hpp** contains the typelist sublibrary \nwhich has a few transform functions and different \nways to apply/expand a typelist into a user template. \nIt is compatible with the iterator sublibrary.\n\nmethods for empty typelists include:\n* `.append(Typelist)`\n  * expands a typelist into this, the only valid operation for an empty typelist\n\nmethods for non-empty typelists include:\n* `.subrange(Begin, End)`\n  * returns a range of types indicated by two inclusive compile-time indices\n* `.insert(Typelist)`\n  * expands another typelist into this typelist at given index\n* `.append(Typelist)`\n  * expands a typelist into the end of this typelist\n* `.prepend(Typelist)`\n  * expands a typelist into the beginning of this typelist\n* `.erase(Index)`\n  * returns a typelist, with type at given index removed\n* `.erase(Begin, End)`\n  * returns a typelist, with types between given indices removed\n* `.erase(BeginIter, EndIter)`\n  * returns a typelist, with types between given iterators removed\n* `.applied_emplacer()`\n  * applies types to a templated class and returns an emplacer for that class\n* `.template index_of\u003cT\u003e()`\n  * for a given type, returns index of first occurence\n* `.type_emplacer(Index)`\n  * returns a proxy constructor for a type at given index\n* `.operator[](Index)`\n  * equivalent to `type_emplacer`, enables `cxl::iterator` compatibility\n* `.front()`\n  * returns a proxy constructor for the first type\n* `.back()`\n  * returns a proxy constructor for the last type\n\n## Parse\n**include/cxl/parse\\*.hpp** headers contain the parsing sublibrary in `cxl::parse` namespace. \nThere are a handful of predefined fundamental parsers, which operate on `cxl::string\u003c...\u003e`s. \nThese parsers can be combined in many different ways to create more complex parsers.\nWhen a parse operation is performed using the parser, it will return a \n`cxl::parse::parsed\u003c...\u003e` that can tell you if the parse was a success, how far \nthe parser matched, what remains to be parsed and a generated typelist.\nsubparsers can generate custom types, however if they do not, the generated type \nwill be a `cxl::string\u003c...\u003e` filled with what the subparser matched. \ncustom generated types are just a templated class taking a parameter pack.\nsee example csv parser-generator in **example/csv**\n\nFor example, here is a default generating parser:\n```c++\nusing namespace cxl::parse;\nconstexpr auto parser = one_string(STR(\"abc\"));\nconstexpr auto result = parser.parse(STR(\"abc\"));\n\n```\nin this case `result.tree()` would return a `typelist\u003cstring\u003c'a','b','c'\u003e\u003e`\n\nBut if we have a custom generated type:\n```c++\ntemplate\u003ctypename... T\u003e\nstruct synth{};\n\nusing namespace cxl::parse;\nconstexpr auto parser = one_string(STR(\"abc\")).generate(synth\u003c\u003e{});\nconstexpr auto result = parser.parse(STR(\"abc\"));\n\n```\n\nnow `result.tree()` will return a `typelist\u003csynth\u003cstring\u003c'a','b','c'\u003e\u003e\u003e`. \n\nBuilt-in parser classes include:\n* `one_string`\n  * `(constructor)(TargetString)`: takes a string as target\n  * `.parse(StringToParse)`: parses a string and matches target; consumes on success\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `one_char`\n  * `(constructor)(TargetString)`: takes a string as target\n  * `.parse(StringToParse)`: parses first character in a string and matches any character in target; consumes on success\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `before`\n  * `(constructor)(TargetParser)`: takes another parser as target\n  * `.parse(StringToParse)`: parses a string and matches target; does **not** consume on success\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `filter`\n  * `(constructor)(TargetParser)`: takes another parser as target\n  * `.parse(StringToParse)`: parses a string and matches anything but target; consumes one character on success\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `optional`\n  * `(constructor)(TargetParser)`: takes another parser as target\n  * `.parse(StringToParse)`: parses a string and always returns success; consumes if the target succeeds\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `one_or_more`\n  * `(constructor)(TargetParser)`: takes another parser as target\n  * `.parse(StringToParse)`: parses a string and matches the target aleast one time; consumes on success\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `zero_or_more`\n  * `(constructor)(TargetParser)`: takes another parser as target\n  * `.parse(StringToParse)`: parses a string and matches the target aleast zero times; consumes on success\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `repeat`, `repeat_minimum`, `repeat_maximum`, `repeat_range`: four types of repeat parsers are implemented\n  * `(constructor)(TargetParser, Index, [OptionalIndex])`: takes another parser as target, and some constraints\n  * `.parse(StringToParse)`: parses a string and matches the target the specified allowed amount of times; consumes on success\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `sequence`\n  * `(constructor)(TargetParsers...)`: takes an ordered sequence of parsers as targets\n  * `.parse(StringToParse)`: parses a string and matches all the targets in the order they were specifed; consumes on success\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `one_of`\n  * `(constructor)(TargetParsers...)`: takes an ordered sequence of parsers as targets\n  * `.parse(StringToParse)`: parses a string and only matches one of the targets, trying in the order they were specifed; consumes on success\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n* `anything`\n  * `.parse(StringToParse)`: parses a string and always matches one single character; always consumes\n  * `.generate(GeneratorTemplate)`: returns a new parser matching this one in behaviour, but producing user defined types into the parse tree on success\n\n### Parser Generator\n* `generator`\n  * `(constructor)(TargetParsers)`: takes a parser as target and an output template to generate\n  * `.parse(StringToParse)`: parses a string using the targets output to generate an synthesized type; consumes if target consumes","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftacticalmelonfarmer%2Fcxl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftacticalmelonfarmer%2Fcxl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftacticalmelonfarmer%2Fcxl/lists"}