{"id":20494344,"url":"https://github.com/voltra/linq","last_synced_at":"2025-10-25T12:06:08.157Z","repository":{"id":133010438,"uuid":"121118988","full_name":"Voltra/linq","owner":"Voltra","description":"A LINQ alike library for C++11","archived":false,"fork":false,"pushed_at":"2020-07-25T12:58:21.000Z","size":376,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-02T01:34:40.713Z","etag":null,"topics":["c-plus-plus","c-plus-plus-11","c-plus-plus-library","linq"],"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/Voltra.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-02-11T11:58:38.000Z","updated_at":"2022-01-03T06:12:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"d130c302-9bef-4c8b-a569-d51b5e560cf8","html_url":"https://github.com/Voltra/linq","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voltra%2Flinq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voltra%2Flinq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voltra%2Flinq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voltra%2Flinq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Voltra","download_url":"https://codeload.github.com/Voltra/linq/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242075965,"owners_count":20068231,"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":["c-plus-plus","c-plus-plus-11","c-plus-plus-library","linq"],"created_at":"2024-11-15T17:39:10.001Z","updated_at":"2025-10-25T12:06:03.101Z","avatar_url":"https://github.com/Voltra.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"resources/logo.png\" alt=\"LINQ++ logo\" width=\"300\"\u003e\u003c/p\u003e\n\n## Quick introduction\n\nLINQ++ is a (headers only) C++11 library that aims to emulate the behavior of LINQ in other languages such as C#.\n\nCollection manipulation in C++ is often painful, LINQ++ makes it way easier.\n\n## Features\n\nThese are the features that are currently supported :\n\n\n\n### Types declarations\n\n* `linq::Linqable\u003cT\u003e::value_type` : The type of the elements of this `Linqable`\n\n* `linq::Linqable\u003cT\u003e::reference` : Equivalent to `T\u0026`\n\n* `linq::Linqable\u003cT\u003e::ref` : Alias for the above\n\n* `linq::Linqable\u003cT\u003e::const_reference` : Equivalent to `const T\u0026`\n\n* `linq::Linqable\u003cT\u003e::const_ref` : Equivalent to the above\n\n* `linq::Linqable\u003cT\u003e::pointer` : Equivalent to `T*`\n\n* `linq::Linqable\u003cT\u003e::ptr` : An alias for `linq::Linqable\u003cT\u003e::pointer`\n\n* `linq::Linqable\u003cT\u003e::const_pointr` : Equivalent to `const T*`\n\n* `linq::Linqable\u003cT\u003e::const_ptr` : An alias for `linq::Linqable\u003cT\u003e::const_ptr`\n\n  ​\n\n* `linq::Linqable\u003cT\u003e::container` : The type of container used by the `Linqable`\n\n* `linq::Linqable\u003cT\u003e::iterator` : The type of iterators to a `Linqable`\n\n* `linq::Linqable\u003cT\u003e::const_iterator` : The type of iterators (const-aware) to a `Linqable`\n\n  ​\n\n* `linq::Linqable\u003cT\u003e::Predicate` : A predicate that takes a `T` as argument\n\n* `linq::Linqable\u003cT\u003e::WhereBuilder` : A function that takes a `linq::Linqable\u003cT\u003e` and returns a `linq::Linqable\u003cT\u003e`\n\n* `linq::Linqable\u003cT\u003e::SelfMapper` : A function that takes a `T` and returns a `T`\n\n\n\n### Construction (FROM operations)\n\n- `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::from(It begin, It end)`  : A static method of the class `Linqable` that uses two iterators in order to build the `Linqable` object\n- `linq::Linqable\u003cT\u003e linq::from\u003cT\u003e(It begin, It end)` : A utilitary function that calls the above, it is basically syntactic sugar\n\n\n\n### Selection/Filtering (WHERE operations)\n\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::where(Predicate p)` : The method usually used to start the selection sequence (chaining WHERE operations), only the elements that match the predicate `p` (`T =\u003e bool`) will be kept\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::orWhere(linq::Linqable\u003cT\u003e::Predicate p)` : Adds elements from the previous selection that match the given predicate\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::andWhere(Predicate p)` : An alias to `where` usually used after the first (and supposedly only) `where` in order to add an additionnal filter to the current selection\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::andComplexWhere(WhereBuilder wb)` : Used to make selection sub-operations (for instance, in `WHERE a AND (b OR C)`, `(b OR C)` would usually require a sub-operation). `wb` is a function that is `Linqable\u003cT\u003e =\u003e Linqable\u003cT\u003e`\n\n\n\n### \"Special\" operations\n\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::limit(unsigned int n)` : Restricts the current selection to a maximal amount of `n` elements (selects them in their order)\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::unique()` : Removes duplicates from the current selection (packs to set and goes back to `Linqable`)\n\n\n\n### Ordering (ORDER BY operations)\n\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::orderDesc()` : Sorts the currently selected elements in descending order using the `operator\u003e`\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::orderAsc()` : Sorts the currently selected elements in ascending order using the `operator\u003c`\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::orderDescBy(Transformer f)` : Sorts the currently selected elements in ascending order using the transformed elements's (via `f`, `T =\u003e E`) `operator\u003e`\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::orderAscBy(Transformer f)` : Sorts the currently selected elements in ascending order using the transformed elements's (via `f`, `T =\u003e E`) `operator\u003c`\n\n### Projection (SELECT operations)\n\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::select()` : Returns `*this`, only used for semantic coherence purposes\n* `linq::Linqable\u003cReturnType\u003e linq::Linqable\u003cT\u003e::select(Mapper mapper)` : Maps the currently selected elements using the given mapper function `mapper` (`T =\u003e ReturnType`) and render them available as the current selection\n* `linq::Linqable\u003cT\u003e linq::Linqable\u003cT\u003e::selet(Mapper mapper)` : Maps the currently selected elements to elements of the same type and render them available as the current selection\n* `ReturnType linq::Linqable\u003cT\u003e::selectReduced(Reducer red, ReturnType acc)` : Reduces the currently selected elements to a single value of the type `ReturnType` based upon the reducer function `red` (`(ReturnType, T) =\u003e ReturnType`) and the inital value of the accumulator `acc`\n\n### Packing\n\nI would describe the *packing* operation as the operation of getting to a usual C++ Container (or pointer) from a `Linqable` object : `Linqable` serving only as a way to manipulate your base Container easily.\n\n* `T* linq::Linqable\u003cT\u003e::packToPointer()` : Allocates a pointer of `T` elements from a `Linqable\u003cT\u003e`\n* `std::vector\u003cT\u003e linq::Linqable\u003cT\u003e::packToVector()` : Creates a `std::vector\u003cT\u003e` from the currently selected elements of the `Linqable\u003cT\u003e` object\n* `std::list\u003cT\u003e linq::Linqable\u003cT\u003e::packToList()` : Creates a `std::list\u003cT\u003e` from the currently selected elements of the `Linqable\u003cT\u003e` object\n* `std::set\u003cT\u003e linq::Linqable\u003cT\u003e::packToSet()` : Creates a `std::set\u003cT\u003e` from the currently selected elements of the `Linqable\u003cT\u003e` object\n* `std::deque\u003cT\u003e linq::Linqable\u003cT\u003e::packToDeque()` : Creates a `std::deque\u003cT\u003e` from the currently selected elements of the `Linqable\u003cT\u003e` object\n* `std::forward_list\u003cT\u003e linq::Linqable\u003cT\u003e::packToForwardList()` : Creates a `std::forward_list\u003cT\u003e` from the currently selected elements of the `Linqable\u003cT\u003e` object. Note that this operation has a bit more overhead than the others due to the fact that insertion in `std::forward_list` is done to the front, so we have to reverse the list to keep the original order\n\n\n\n### Utilitaries\n\nLINQ++ comes with a bit of utilitaries function that makes it easier to use (even though some may only be used for the development of this library, eg. `TransformerGreaterThanComparator`).\n\nThe base namespace for those is `linq::utils`.\n\n#### Basics\n\n* `Identity\u003cT\u003e` : A struct that is used as a functor for the identity function (`(T a) =\u003e a`)\n* `identityOf\u003cT\u003e()` : A function that returns the identity function of the given type `T`\n\n\n\n#### Helper Functions\n\nMost of those functions are meant to ease the use of WHERE operations by giving support to recurrent operations (With x being the element : `x==n`,`x\u003cn`, `n\u003cx\u003cm`, `x%2==0`, etc...).\n\nThe base namespace for those is `linq::utils::helperFunctions`.\n\nLet's have `PREDICATE` designate a function `T =\u003e bool` and let's have `T` be the type of the elements in the `Linqable\u003cT\u003e` object.\n\n\n\n##### Comparison\n\n* `PREDICATE is(T ref)` : Returns a predicate that is true only when a given `T x` is equal to `ref` using `operator==`\n* `PREDICATE isNot(T ref)` : Returns a predicate that is true only when a given `T x` is not equal to `ref` using `operator!=`\n* `PREDICATE isGreaterThan(T ref)` : Returns a predicate that is true only when a given `T x` is greater than `ref` using `operator\u003e`\n* `PREDICATE isLessThan(T ref)` : Returns a predicate that is true only when a given `T x` is less than `ref` using `operator\u003c`\n* `PREDICATE isGreaterThanOrEqualTo(T ref)` : Returns a predicate that is true only when a given `T x` is greater than or equal to `ref` using `operator\u003e=`\n* `PREDICATE isLessThanOrEqualTo(T ref)` : Returns a predicate that is true only when a given `T x` is less than or equal to `ref` using `operator\u003c=`\n\n\n\n##### Comparison (for maximum compatibility, `operator==` and `operator\u003c` only)\n\n* `PREDICATE e(T ref)` : Alias of `is` (added solely for consistency)\n* `PREDICATE ne(T ref)` : Equivalent to `isNot` but using `operator==`\n* `PREDICATE lt(T ref)` : Alias of `isLessThan` (added solely for consistency)\n* `PREDICATE gt(T ref)` : Equivalent to `isGreaterThan` but using `operator\u003c`\n* `PREDICATE le(T ref)` : Equivalent to `isLessThanOrEqualTo` but using `operator\u003c`\n* `PREDICATE ge(T ref)` : Equivalent to `isGreaterThanOrEqualTo` but using `operator\u003c`\n\n\n\n##### Ranges\n\n* `PREDICATE isBetween(T lhs, T rhs)` : Equivalent to $elem \\in [lhs ; rhs]$\n* `PREDICATE isInRange(T lhs, T rhs)` : Equivalent to $elem \\in [lhs ; rhs[ $\n* `PREDICATE isWithin(T lhs, T rhs)` : Equivalent to $elem \\in \\space]lhs;rhs[ $\n* `PREDICATE isInExclusiveRange(T lhs, T rhs)` : Equivalent to $elem \\in \\space]lhs ; rhs] $\n\n\n\n##### Number specifics\n\n* `bool isOdd(T elem)`\n* `bool isEven(T elem)`\n\n\n\n\n\n## General use cases\n\nAs we already know, collection manipulation in C++ is not exactly as smooth as it can be in other languages.\n\nLINQ++ tends to simplify collection manipulation operation by offering various ways to operate on a [container](http://www.cplusplus.com/reference/stl/).\n\n\n\nThe way you would usually process is to pass the `begin` and `end` iterator of your C++ Container as the parameters of `linq::from` (do not forget to specify the type of elements, eg. `linq::from\u003cint\u003e(arr.begin(), arr.end())`) and then chain operations until you are willing to `pack ` them back to a C++ Container.\n\n\n\nLet's have an example, shall we ?\n\n```c++\n#include \"linq/linq.hpp\"\n#include \u003cset\u003e\n#include \u003cforward_list\u003e\n\nusing namespace std;\nusing namespace linq::utils::helperFunctions;\n\nset\u003cint\u003e arr = {0,1,2,3,4,5,6,7,8,9};\nforward_list\u003cint\u003e linqed = linq::from\u003cint\u003e(arr.begin(), arr.end())\n-\u003ewhere(isEven\u003cint\u003e) //I want even numbers only\n-\u003eorWhere(is(1)) //But if there are any 1s, keep them\n-\u003eandWhere([](const int\u0026 elem)-\u003ebool{ return true; }) //Then keep everything from that\n-\u003eorderDesc() //Order them in descending order\n-\u003eselect() //Optional\n-\u003epackToForwardList(); //Pack them into a forward_list\n\nfor(int elem : linqed)\n    cout \u003c\u003c elem \u003c\u003c \" \";\n//prints: 8 6 4 2 1 0\n```\n\nIn SQL, that would roughly be equivalent to (if we have a table `arr` that has `elem` as a column) :\n\n```sql\nSELECT elem\nFROM arr\nWHERE ((MOD(elem, 2)=0 OR elem=1) AND TRUE)\nORDER BY elem DESC\n```\n\nOr in C# :\n\n```c#\nfrom elem in arr\nwhere (elem%2==0 || elem==1) \u0026\u0026 true\norderby elem descending\nselect elem\n```\n\n\n\n\n\nAs of v1.0.2, you can use member functions in order to ease your job at manipulating collections of objects :\n\n```c++\n#include \u003cstring\u003e\n\nusing namespace std;\nusing namespace linq::utils::helperFunctions;\n\nclass RandomPelo{\n\tprotected:\n\t\tstring name;\n\t\tbool lives;\n\n\tpublic:\n\t\tEmploye(string name, bool lives = true) : name{name}, lives{lives}{}\n\n\t\tbool isAlive(){ return this-\u003elives; }\n\t\tstring getName(){ return this-\u003ename; }\n};\n\nvector\u003cRandomPelo\u003e vect = {};\nbool isAlive = true;\nfor(char c='a' ; c \u003c= 'z' ; c+=1) {\n    vect.push_back( RandomPelo{string{c}, isAlive} );\n    isAlive = !isAlive;\n}\n\nstring names = linq::from\u003cRandomPelo\u003e(vect.begin(), vect.end())\n-\u003ewhere(\u0026RandomPelo::isAlive) //I only want to keep those who are alive\n-\u003eselect\u003cstring\u003e(\u0026RandomPelo::getName) //I want to retrieve their name\n-\u003eselect\u003cstring\u003e([](string s){ return s + \" \"; }) //I want to add a blank space after their name\n-\u003eselectReduced\u003cstring\u003e(reducers::strings::concat, string{}); //I want to concatenate their name\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoltra%2Flinq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoltra%2Flinq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoltra%2Flinq/lists"}