{"id":23110605,"url":"https://github.com/elandaofficial/venum","last_synced_at":"2025-06-24T09:34:29.351Z","repository":{"id":56078248,"uuid":"265884481","full_name":"ElandaOfficial/venum","owner":"ElandaOfficial","description":"A simulated java-like associative-enum implementation.","archived":false,"fork":false,"pushed_at":"2021-05-16T18:42:13.000Z","size":238,"stargazers_count":18,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-04T16:07:05.846Z","etag":null,"topics":["associative","cpp","enum","java","macros","map","set","venum"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ElandaOfficial.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}},"created_at":"2020-05-21T15:29:40.000Z","updated_at":"2024-05-03T22:59:33.000Z","dependencies_parsed_at":"2022-08-15T12:40:57.896Z","dependency_job_id":null,"html_url":"https://github.com/ElandaOfficial/venum","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ElandaOfficial/venum","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElandaOfficial%2Fvenum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElandaOfficial%2Fvenum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElandaOfficial%2Fvenum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElandaOfficial%2Fvenum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ElandaOfficial","download_url":"https://codeload.github.com/ElandaOfficial/venum/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElandaOfficial%2Fvenum/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259909623,"owners_count":22930663,"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":["associative","cpp","enum","java","macros","map","set","venum"],"created_at":"2024-12-17T01:49:28.627Z","updated_at":"2025-06-15T01:35:06.517Z","avatar_url":"https://github.com/ElandaOfficial.png","language":"C++","readme":"![venum.logo](https://i.imgur.com/raM6O1h.png)\n\nvenum is an attempt to make enums more meaningful.\nThe purpose of this library is not to polish up the existing concept of C/C++ enums,\nbut instead to create a new type of enums: venums\n\nShort for virtual-enum, venums try to give constants more data to play with.\nEvery constant has its own name and ordinal. If you are a Java fanatic you may notice similarities\nas this library is inspired by Java enums.\n\nAs a little sidenote, the Virtual in venum does not stand for polymorphism but\nrather the fact that venums simulate enums and are not real enums.\n\nWarning: This library defines a massive amount of macros that begin with VENUM_\n         so be sure that you don't use any of these besides the below mentioned ones.\n\n\n# Table of contents\n\u003cdetails\u003e\u003csummary\u003eClick to expand\u003c/summary\u003e\n         \n1. [Installation](#installation)\n2. [Getting Started](#getting-started)\n    * [Tools](#tools)\n    * [Venum](#venum)\n    * [Constants](#constants)\n3. [Creation of venums](#creation-of-venums)\n    * [Defining a simple venum](#defining-a-simple-venum)\n    * [Defining an associative venum](#defining-an-associative-venum)\n        1. [ID and Values](#id-and-values)\n        2. [Body](#body)\n        3. [Attributes](#attributes)\n4. [Making use of venums](#making-use-of-venums)\n    * [Get constant data](#get-constant-data)\n    * [Get all constants](#get-all-constants)\n    * [Get constant from name](#get-constant-from-name)\n5. [Known Issues](#known-issues)\n\u003c/details\u003e\n\n# Installation\nInstallation is pretty darn easy. Nothing more than including the venum core header and that's it.\nThe cmake file included is for running the test included in this repo, which you can find in\nthe folder denoted as \"test\"\n\nIf your project utilises CMake, you can just add this folder as subfolder and put `venum` in your target links:\n```cmake\n# Add as a subfolder\nadd_subdirectory(venum)\n\n# Link against venum\ntarget_link_libraries(Target PRIVATE venum)\n```\nAnd that's it, you can now use it as part of your CMake project.\n\nTo run the test, run the included CMakeLists.txt with one of the available\nexporters and build your project:\n\n```bash\nmkdir build\ncd build\ncmake -DCOMPILE_TESTS=ON ..\n```\n\n# Getting Started\n## Tools\nThe venum library tries to make enum creation as simple as possible. Since venum classes are huge\nthis is done via macros.\n\nBelow are the 3 macros that should be used for creating venums:\n\n| Macro                | Description                                                              |\n| -------------------- | ------------------------------------------------------------------------ |\n| VENUM_CREATE         | Creates a simple venum with fixed constants.                             |\n| VENUM_CREATE_ASSOC   | Creates an associative venum with associated values.                     |\n| VENUM_BASE           | An utility macro used for overriding constructors in associative venums. |\n\nBesides these macros there are also classes that allow to use venums for special situations:\n\n| Class    | Description                                             |\n| -------- | ------------------------------------------------------- |\n| VenumMap | An array that maps venum constants to a set of values.  |\n| VenumSet | A set that contains a fixed amount of constants.        |\n\n## Venum\nA venum is, similar to a trivial enum, collection of constants. Other than enums, though,\nthey cannot hold values that are not defined in them (optimally) and store additional data that trivial enums do not.\nA venum can hold up to 100 constants.\n\n## Constants\nConstants are the heart of every venum.\nConstants are a compound of data that are unique to their instance.  \nEvery constant gets an unique name and an ordinal number which denotes their position in the venum's constant storage.  \nConstants also have the ability to contain user defined data and functions that do not change their internal state.\n\n\n# Creation of venums\n## Defining a simple venum\nTo define a simple venum which doesn't associate any special values to its constants we can do the following:\n```C++\n// Create an venum called CarType and specify constants\nVENUM_CREATE(CarType\n    Mercedes,\n    Volkswagen,\n    RollsRoyce\n)\n```\n\nIt's as simple as that, nothing more has to be done.\nYou now have access to the CarType venum and its constants. (more below)\n\n## Defining an associative venum\n### ID and VALUES\nCreating an associative venum is slightly more work than creating a simple venum,\ndifficulty is the same however.\n```C++\n// Create an venum called PhoneType and specify constants\nVENUM_CREATE_ASSOC\n(\n    ID(PhoneType),\n    VALUES\n    (\n        (Samsumg)(),\n        (IPhone)(),\n        (Nokia)(),\n        (Huaweii)()\n    )\n)\n```\n\nAs we can see, this time we had to write a little more than before.\n\nWhile we specified the name as first argument in the first example, we had\nto encapsulate it with the **ID** keyword. (keyword here refers to the venum macro name **ID**, **VALUES**, **BODY** and **ATTRIB**)  \nThe **VALUES** keyword is, in turn, responsible for declaring the constants we want to have.\n\nI think you already noticed the difference, didn't you?  \nExactly, the constants are parenthesised. \nWhile the first group describes the constant's name, the second group is responsible for\ndefining the constant's associated values.\n\nBut unfortunately, just putting values in there would do more harm than good, as the compiler doesn't know\nwhere to put them to interpret them correctly.  \nFor exactly this reason we introduce another important keyword: **BODY**\n\n### BODY\nThe body keyword is there for giving constants additional information about data it\nhas and can hold.\n\nSo, let's say we want our constants to hold the vendor and price of any model.\n\n```C++\nVALUES\n(\n    (Samsumg)(\"Samsung\", 400),\n    (IPhone) (\"Apple\",   10000),\n    (Nokia)  (\"Nokia\",   200),\n    (Huaweii)(\"Huaweii\", 10)\n)\n```\nTo stop this piece of code to show us errors we now need to give our constants their custom body.\n\n```C++\nBODY\n(\nprivate:\n    constexpr PhoneTypeConstant(const char *name, int ordinal, const char *vendor, int price)\n        : VENUM_BASE(name, ordinal)\n    {}\n)\n```\n\nWhat we did here is introducing a new constructor that takes our two arguments we specified above.\nIt is important that the constructor is a constant expression or it won't work.  \nUnfortunately, this doesn't let us create constants with types that are not valid constant expressions,\nbut we do have a solution for this to which we will get later on.\n\nYou will need to also add accessors so you get access to these variables.\nAnd it is important to know that all the constants have to have the same constructor which will be\ndetermined by the first constant.\n\nAs you probably already noticed, we also added two other parameters to the constructor *name* and *ordinal*, these\nare important to be written as the first two arguments, as they are responsible for\npassing the constant's name and ordinal to the constant.  \nThe VENUM_BASE(name, ordinal) is just a convenience define so that you don't need to\nassign the first two parameters yourself.\n\nAnother thing to note is that the constructor is private, this is intentional because\nvenums have an internal checking mechanism whether constructors are private or public.  \nThis is a safety mechanism so the user can't create any new constants and use them which\ncould result in undefined behaviour if not used correctly.\n\n### Attributes\nOne last thing we didn't discuss now is *attributes*!  \nAttributes are a refined way of changing the behaviour of venum creation.\n\nFor the time beeing, there are only 4 attributes that are available:\n\n| Attribute    | Description                                                                         | Values        |\n| ------------ | ----------------------------------------------------------------------------------- | ------------- |\n| CTOR_UNIFORM | Allows to toggle the ability of having diverse constant constructors.               | true/false    |\n| CTOR_PRIVATE | Allows to toggle whether constant constructors have to be private or can be public. | true/false    |\n| NULL_CONST   | Allows the venum to have a null constant.                                            | true/false    |\n| RETENTION    | Specifies the validation time of the venum.                                          | RUNTIME/CLASS |\n\nAs we addressed before, you cannot have non-constexpr variables to be contained by constants.  \nThis is due to the fact that constants are constant expression by default, however, if this is\na problem you will need to turn this off.  \nThis disadvantage of this is that you will lose all constant expression benefits of your venum.\n\nTo disable constexpr qualification we need to specify the corresponding attribute and change it to\n**RUNTIME**:\n```\nATTRIB(RETENTION(RUNTIME))\n```\n\nThis is what our venum looks like now:\n```C++\nVENUM_CREATE_ASSOC\n(\n    ID(PhoneType),\n    VALUES\n    (\n        (Samsumg)(\"Samsung\", 400),\n        (IPhone)(\"Apple\",   10000),\n        (Nokia)(\"Nokia\",   200),\n        (Huaweii)(\"Huaweii\", 10)\n    ),\n    BODY\n    (\n    private:\n        const char *const vendor {};\n        const int price {};\n\n        constexpr PhoneTypeConstant(const char *name, int ordinal, const char *vendor, int price)\n            : venum_BASE(name, ordinal),\n              vendor(vendor), price(price)\n        {}\n\n    public:\n        constexpr const char* getVendor() { return vendor; }\n        constexpr int getPrice() { return price; }\n    ),\n    ATTRIB\n    (\n        RETENTION(RUNTIME)\n    )\n)\n```\n\n## Making use of venums\nNow that we sorted out how to create our venums, we also need to know what we can do with them. \nAfter all, we also want to have a use for them and don't just let them stay there doing nothing.\n\n### Get constant data\nTo gain access to the data of a constant, we can either directly access the constant,\nor through the venum instance and the dereference operator.\n```C++\n// Access vendor directly through constant\nPhoneType::Samsung.getVendor()\n\n// or through instance\nPhoneType type = PhoneType::Samsung;\ntype-\u003egetVendor();\n```\n\nNote that the instance \"type\" may point to a null-constant,\nwhich can lead to undefined behaviour if not checked beforehand.\n\n### Get all constants\nThe \"values()\" function of any venum will return a reference to an internal array that contains all the constants.\n\n### Get constant from name\nSince constants can be refered to by name, we can also resolve them by their name.  \nFor this to work, every venum contains a function called \"valueOf\" which accepts a string and returns the constant\nor a nullptr that is found to be equivalent to this string.\n\nNote that if a venum doesn't accept null-constants,\nthis will throw an exception if no constant with the specified name was found.\n\n# Known Issues\n- The MSVC-Compiler does not have any support for optional preceding commas in variadic macro expansions, due to this the library will most likely not work on Windows with the MSVC compiler with any standard below C++20. (C++20 standard proposes \\_\\_VA_OPT\\_\\_ as a fix for this)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felandaofficial%2Fvenum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felandaofficial%2Fvenum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felandaofficial%2Fvenum/lists"}