Header-only library for lists.

feat: First commit.

stau.space af5572ad

+1
.envrc
··· 1 + use flake
+2
.gitignore
··· 1 + .direnv 2 + .build
+16
LICENSE
··· 1 + MIT No Attribution 2 + 3 + Copyright <year> Sona Tau Estrada Rivera <sona@stau.space> 4 + 5 + Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 + software and associated documentation files (the "Software"), to deal in the Software 7 + without restriction, including without limitation the rights to use, copy, modify, 8 + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 + permit persons to whom the Software is furnished to do so. 10 + 11 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+12
README.md
··· 1 + # C List 2 + 3 + This is a header-only library for singly-linked lists, written in C. 4 + 5 + ## Usage 6 + 7 + Include the header in your project and put: 8 + ```c 9 + #define LIST_IMPLEMENTATION 10 + ``` 11 + When you want the function definitions to be included. 12 +
+25
flake.lock
··· 1 + { 2 + "nodes": { 3 + "nixpkgs": { 4 + "locked": { 5 + "lastModified": 1762111121, 6 + "narHash": "sha256-4vhDuZ7OZaZmKKrnDpxLZZpGIJvAeMtK6FKLJYUtAdw=", 7 + "rev": "b3d51a0365f6695e7dd5cdf3e180604530ed33b4", 8 + "revCount": 888552, 9 + "type": "tarball", 10 + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.888552%2Brev-b3d51a0365f6695e7dd5cdf3e180604530ed33b4/019a4ac5-41ea-7209-b0c4-883187b7dcdd/source.tar.gz" 11 + }, 12 + "original": { 13 + "type": "tarball", 14 + "url": "https://flakehub.com/f/NixOS/nixpkgs/0.1" 15 + } 16 + }, 17 + "root": { 18 + "inputs": { 19 + "nixpkgs": "nixpkgs" 20 + } 21 + } 22 + }, 23 + "root": "root", 24 + "version": 7 25 + }
+42
flake.nix
··· 1 + { 2 + description = "Declarations for the environment that this project will use."; 3 + 4 + # Flake inputs 5 + inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1"; 6 + 7 + # Flake outputs 8 + outputs = inputs: 9 + let 10 + # The systems supported for this flake 11 + supportedSystems = [ 12 + "x86_64-linux" # 64-bit Intel/AMD Linux 13 + "aarch64-linux" # 64-bit ARM Linux 14 + "x86_64-darwin" # 64-bit Intel macOS 15 + "aarch64-darwin" # 64-bit ARM macOS 16 + ]; 17 + 18 + # Helper to provide system-specific attributes 19 + forEachSupportedSystem = f: inputs.nixpkgs.lib.genAttrs supportedSystems (system: f { 20 + pkgs = import inputs.nixpkgs { inherit system; }; 21 + }); 22 + in 23 + { 24 + devShells = forEachSupportedSystem ({ pkgs }: { 25 + default = pkgs.mkShell { 26 + # The Nix packages provided in the environment 27 + # Add any you need here 28 + packages = with pkgs; [ 29 + gcc 30 + gnumake 31 + ]; 32 + 33 + # Set any environment variables for your dev shell 34 + env = { }; 35 + 36 + # Add any shell logic you want executed any time the environment is activated 37 + shellHook = '' 38 + ''; 39 + }; 40 + }); 41 + }; 42 + }
+72
src/list.h
··· 1 + #ifndef LIST_H_ 2 + #define LIST_H_ 3 + /* ----- List definition ----- */ 4 + #ifndef LIST_IMPLEMENTATION 5 + #define DefList(type) \ 6 + struct Node##type { \ 7 + type head; \ 8 + struct Node##type* rest; \ 9 + }; \ 10 + typedef struct Node##type* List##type; \ 11 + void List##type##_deinit(List##type list); \ 12 + type List##type##_car(struct Node##type node); \ 13 + struct Node##type* List##type##_cdr(struct Node##type node); \ 14 + List##type List##type##_cons(type a, List##type list); \ 15 + List##type List##type##_rev(List##type list, List##type a); \ 16 + List##type List##type##_reverse(List##type list); \ 17 + size_t List##type##_length(List##type list); \ 18 + type List##type##_at(List##type list, size_t index); 19 + #else 20 + #define DefList(type) \ 21 + struct Node##type { \ 22 + type head; \ 23 + struct Node##type* rest; \ 24 + }; \ 25 + typedef struct Node##type* List##type; \ 26 + \ 27 + void List##type##_deinit(List##type list) { \ 28 + if (list != NULL) { \ 29 + List##type##_deinit(list->rest); \ 30 + assert(list->rest == NULL); \ 31 + free(list); \ 32 + list = NULL; \ 33 + } \ 34 + } \ 35 + \ 36 + type List##type##_car(struct Node##type node) { \ 37 + List##type##_deinit(node.rest); \ 38 + return node.head; \ 39 + } \ 40 + \ 41 + struct Node##type* List##type##_cdr(struct Node##type node) { \ 42 + return node.rest; \ 43 + } \ 44 + \ 45 + List##type List##type##_cons(type a, List##type list) { \ 46 + struct Node##type* node = (struct Node##type*)calloc(sizeof(struct Node##type), 1); \ 47 + exists(node); \ 48 + *node = (struct Node##type){ .head = a, .rest = list }; \ 49 + return (List##type)node; \ 50 + } \ 51 + \ 52 + List##type List##type##_rev(List##type list, List##type a) { \ 53 + if (list != NULL) return List##type##_rev(list->rest, List##type##_cons(list->head, a)); \ 54 + else return a; \ 55 + } \ 56 + \ 57 + List##type List##type##_reverse(List##type list) { \ 58 + return List##type##_rev(list, NULL); \ 59 + } \ 60 + \ 61 + size_t List##type##_length(List##type list) { \ 62 + if (list != NULL) return List##type##_length(list->rest) + 1; \ 63 + else return 0; \ 64 + } \ 65 + \ 66 + type List##type##_at(List##type list, size_t index) { \ 67 + if (list != NULL) return index == 1 ? list->head : List##type##_at(list->rest, index - 1); \ 68 + else exists(NULL); \ 69 + return (type){0}; \ 70 + } 71 + #endif 72 + #endif // LIST_H_