{"id":21379301,"url":"https://github.com/m-peko/booleval","last_synced_at":"2025-07-13T11:32:38.861Z","repository":{"id":43930648,"uuid":"199078025","full_name":"m-peko/booleval","owner":"m-peko","description":"Header-only C++17 library for evaluating logical expressions.","archived":false,"fork":false,"pushed_at":"2022-01-25T09:45:55.000Z","size":475,"stargazers_count":78,"open_issues_count":0,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2023-11-01T16:44:11.317Z","etag":null,"topics":["boolean-algebra","boolean-expression","boolean-logic","boolean-operations","c-plus-plus","cpp","cpp17","evaluation","evaluator","expression","expression-evaluator","expression-tree","filter","header-only","logical-operators","modern-cpp","parser-library","recursive-descent-parser"],"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/m-peko.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":"2019-07-26T20:46:19.000Z","updated_at":"2023-09-07T20:00:33.000Z","dependencies_parsed_at":"2022-08-29T10:10:52.428Z","dependency_job_id":null,"html_url":"https://github.com/m-peko/booleval","commit_stats":null,"previous_names":[],"tags_count":6,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-peko%2Fbooleval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-peko%2Fbooleval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-peko%2Fbooleval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-peko%2Fbooleval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m-peko","download_url":"https://codeload.github.com/m-peko/booleval/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225878194,"owners_count":17538416,"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":["boolean-algebra","boolean-expression","boolean-logic","boolean-operations","c-plus-plus","cpp","cpp17","evaluation","evaluator","expression","expression-evaluator","expression-tree","filter","header-only","logical-operators","modern-cpp","parser-library","recursive-descent-parser"],"created_at":"2024-11-22T10:18:42.321Z","updated_at":"2024-11-22T10:18:42.761Z","avatar_url":"https://github.com/m-peko.png","language":"C++","funding_links":["https://www.buymeacoffee.com/mpeko"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"docs/booleval-title.png\"/\u003e\n\n[![license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/m-peko/booleval/blob/master/LICENSE)\n[![Build Status](https://app.travis-ci.com/m-peko/booleval.svg?branch=master)](https://travis-ci.org/m-peko/booleval)\n[![codecov](https://codecov.io/gh/m-peko/booleval/branch/master/graph/badge.svg)](https://codecov.io/gh/m-peko/booleval)\n[![Standard](https://img.shields.io/badge/C%2B%2B-17-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B17)\n\nHeader-only C++17 library for evaluating logical expressions.\n\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\nThe library is under development and subject to change. Contributions are welcome. You can also log an issue if you have a wish for enhancement or if you spot a bug.\n\n## Quick start\n\n```cpp\n#include \u003cstring\u003e\n#include \u003ciostream\u003e\n#include \u003cbooleval/evaluator.hpp\u003e\n\nclass foo\n{\npublic:\n    foo( std::string value ) noexcept : value_{ std::move( value ) } {}\n\n    std::string const \u0026 value() const noexcept { return value_; }\n\nprivate:\n    std::string value_{};\n};\n\nint main()\n{\n    foo x{ \"foo\" };\n    foo y{ \"bar\" };\n\n    booleval::evaluator evaluator\n    {\n        booleval::make_field( \"field\", \u0026foo::value )\n    };\n\n    if ( !evaluator.expression( \"field eq foo\" ) )\n    {\n        std::cerr \u003c\u003c \"Expression not valid!\" \u003c\u003c std::endl;\n    }\n\n    if ( evaluator.is_activated() )\n    {\n        std::cout \u003c\u003c std::boolalpha \u003c\u003c evaluator.evaluate( x ) \u003c\u003c std::endl; // true\n        std::cout \u003c\u003c std::boolalpha \u003c\u003c evaluator.evaluate( y ) \u003c\u003c std::endl; // false\n    }\n\n    return 0;\n}\n```\n\n## Table of Contents\n\n* [Motivation](#motivation)\n* [Getting Started](#getting-started)\n    * [Zero Copy](#zero-copy)\n    * [EQUAL TO Operator](#equal-to-operator)\n    * [Valid Expressions](#valid-expressions)\n    * [Invalid Expressions](#invalid-expressions)\n    * [Evaluation Result](#evaluation-result)\n    * [Supported Tokens](#supported-tokens)\n* [Benchmark](#benchmark)\n* [Compilation](#compilation)\n* [Tests](#tests)\n* [Compiler Compatibility](#compiler-compatibility)\n* [Contributing](#contributing)\n* [License](#license)\n* [Support](#support)\n\n## Motivation\n\n`booleval` is a header-only C++17 library for evaluating logical expressions. It implements recursive descent parser mechanism for building an expression tree for a user-defined logical expression. After the expression tree is being built, map of fields and values representing a certain object can be passed to the `evaluator` component of this library which will evaluate those values to `true` or `false` according to the user-defined logical expression.\n\n\u003cbr/\u003e\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"docs/booleval-tree.png\"/\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\nIn programming languages like Java and C# accessing arbitrary fields inside a class represents an omnipresent problem. However, it got solved by introducing a **reflections** feature. This feature provides us information about the class to which a certain object belongs to and, also, the methods of that class which we can invoke at runtime.\n\nSince the reflection feature is missing in C++, `booleval` library is implemented. It checks whether the members of a class to which an object belongs to have certain values. Members of a class are specified in a string format and can be used to form a logical expression.\n\nProviding an end-user a functionality of specifying a logical expression is a common way of filtering out a large amounts of objects. E.g. [`tcpdump`](https://www.tcpdump.org/manpages/tcpdump.1.html) and [BPF](https://en.wikipedia.org/wiki/Berkeley_Packet_Filter) (Berkeley Packet Filter), network tools available on most UNIX-like operating systems, have pretty much the same syntax for their filter expression.\n\n## Getting Started\n\n`booleval` is a header-only C++17 library for evaluating logical expressions.\n\n### Zero Copy\n\nIn order to improve performance, `booleval` library does not copy objects that are being evaluated.\n\n### EQUAL TO operator\n\nEQUAL TO operator is an optional operator. Therefore, logical expression that checks whether a field with the name `field_a` has a value of `foo` can be constructed in a two different ways:\n\n- EQUAL TO operator is specified in the expression: `field_a eq foo`\n- EQUAL TO operator is **not** specified in the expression: `field_a foo`\n\nTo conclude, equality operator is a default operator between two fields. Thus, it **does not need** to be specified in the logical expression.\n\n### Valid expressions\n\n- `(field_a foo and field_b bar) or field_a bar`\n- `(field_a eq foo and field_b eq bar) or field_a eq bar`\n\n### Invalid expressions\n\n- `(field_a foo and field_b bar` _Note: Missing closing parentheses_\n- `field_a foo bar` _Note: Two field values in a row_\n\n### Evaluation Result\n\nResult of evaluation process contains two information:\n\n- `success`: `true` if evaluation process is successful; otherwise, `false`\n- `message`: meaningful message if evaluation process is unsuccessful; otherwise, empty message\n\nThis kind of enriched lightweight result is being used instead of exceptions for performance reasons.\n\nExamples of messages:\n\n- `\"Missing operand\"`\n- `\"Unknown field\"`\n- `\"Unknown token type\"`\n\n### Supported tokens\n\n|Name|Keyword|Symbol|\n|:---:|:---:|:---:|\n|AND operator|AND / and|\u0026\u0026|\n|OR operator|OR / or|\\| \\||\n|EQUAL TO operator|EQ / eq|==|\n|NOT EQUAL TO operator|NEQ / neq|!=|\n|GREATER THAN operator|GT / gt|\u003e|\n|LESS THAN operator|LT / lt|\u003c|\n|GREATER THAN OR EQUAL TO operator|GEQ / geq|\u003e=|\n|LESS THAN OR EQUAL TO operator|LEQ / leq|\u003c=|\n|LEFT parentheses|\u0026empty;|(|\n|RIGHT parentheses|\u0026empty;|)|\n\n## Benchmark\n\nFollowing table shows benchmark results:\n\n|Benchmark|Time|Iterations\n|:---:|:---:|:---:|\n|Building expression tree|3817 ns|180904|\n|Evaluation|1285 ns|532522|\n\nIn other words, it is possible to evaluate **2,413,045.84 objects per second**.\n\n## Compilation\n\nIn order to compile the library, run the following commands:\n\n```Shell\n$ # create the build directory\n$ mkdir build\n$ cd build\n\n$ # configure the project\n$ cmake ../\n\n$ # compile\n$ make\n```\n\n## Tests\n\nIn order to run unit tests, run the following commands:\n\n```Shell\n$ # fetch the googletest submodule, needed for tests\n$ git submodule init\n$ git submodule update\n\n$ mkdir build\n$ cd build\n\n$ # configure the project\n$ cmake ..\n\n$ # compile tests\n$ make tests\n\n$ # run tests\n$ make test\n```\n\n## Compiler Compatibility\n\n* Clang/LLVM \u003e= 7\n* MSVC++ \u003e= 19.16\n* GCC \u003e= 8.4\n\nThere are no 3\u003csup\u003erd\u003c/sup\u003e party dependencies.\n\n## Contributing\n\nFeel free to contribute.\n\nIf you find that any of the tests **fail**, please create a ticket in the issue tracker indicating the following information:\n\n* platform\n* architecture\n* library version\n* minimal reproducible example\n\n## License\n\nThe project is available under the [MIT](https://opensource.org/licenses/MIT) license.\n\n## Support\n\nIf you like the work `booleval` library is doing, please consider supporting it:\n\n\u003ca href=\"https://www.buymeacoffee.com/mpeko\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-red.png\" alt=\"Buy Me A Coffee\" style=\"height: 60px !important;width: 217px !important;\" \u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-peko%2Fbooleval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm-peko%2Fbooleval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-peko%2Fbooleval/lists"}