{"id":30051973,"url":"https://github.com/evgeniums/cpp-validator","last_synced_at":"2025-08-07T16:34:32.218Z","repository":{"id":139171666,"uuid":"285886484","full_name":"evgeniums/cpp-validator","owner":"evgeniums","description":"C++ header-only library for generic data validation.","archived":false,"fork":false,"pushed_at":"2025-04-18T17:04:27.000Z","size":1512,"stargazers_count":61,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-06-04T17:11:34.209Z","etag":null,"topics":["boost","cpp","cpp-validator","cpp14","cpp17","hana","validation","validation-framework","validation-library","validator"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/evgeniums.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","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,"zenodo":null}},"created_at":"2020-08-07T17:34:59.000Z","updated_at":"2025-05-31T16:24:07.000Z","dependencies_parsed_at":"2024-01-06T14:50:48.978Z","dependency_job_id":"e80257d8-bece-4eb2-9b42-6e3a3b548d7d","html_url":"https://github.com/evgeniums/cpp-validator","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/evgeniums/cpp-validator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evgeniums%2Fcpp-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evgeniums%2Fcpp-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evgeniums%2Fcpp-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evgeniums%2Fcpp-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/evgeniums","download_url":"https://codeload.github.com/evgeniums/cpp-validator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evgeniums%2Fcpp-validator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269291033,"owners_count":24392372,"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","status":"online","status_checked_at":"2025-08-07T02:00:09.698Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["boost","cpp","cpp-validator","cpp14","cpp17","hana","validation","validation-framework","validation-library","validator"],"created_at":"2025-08-07T16:32:57.607Z","updated_at":"2025-08-07T16:34:32.207Z","avatar_url":"https://github.com/evgeniums.png","language":"C++","readme":"# *cpp-validator* (C++ Data Validation Library)\n\n## Motivation\n\nChecking data constraints or verifying data integrity is a very common task in programming. A typical approach for complex data validation is writing nested *if-conditions* or chained invocations of partial validation methods. Declarations of the constraints could become intermixed with their implementations, thus, spreading the validation routines over the code. Requirements to construct and show error messages could make everything even more complicated.\n\n`cpp-validator` library allows one to declare data constraints with clean statements in certain points of code and apply them in other parts of code on demand. If needed, the validation error messages are automatically constructed by taking into account the user's locale.\n\nMinimal generic example:\n\n```cpp\n// define a validator \nauto v1=validator(\n        _[key1][key1_1][key1_1_1](gt,100),\n        _[key2][key2_1](value(ne,\"UNKNOWN\") \u0026\u0026 size(lte,32))\n    );\n\n.....\n\n// validate some objects with the validator \n// throwing exception if validation fails\nvalidate(obj1,v1);\nvalidate(obj2,v1);\n```\n\n## Introduction\n\n*cpp-validator* is a modern C++ header-only library for validation of variables, objects and containers. \n\nThe library can be used to validate:\n- plain variables;\n- properties of objects, where a property can be accessed either as object's variable or object's method;\n- contents and properties of containers;\n- nested containers and objects;\n- heterogeneous containers such as pairs and tuples;\n- trees;\n- results of evaluations or value transformations.\n\nBasic usage of the library includes two steps:\n\n- first, define a validator using almost declarative syntax;\n- then, apply the validator to data that must be validated and check the results.\n\nThe library is suitable for both *post-validation* and *pre-validation*. *Post-validation* stands for validating the object that is already populated with the data. *Pre-validation* stands for validating the data before updating the object. The same validator declaration can be used in both cases.\n\nThere are a lot of options for `cpp-validator` extension and customization. During validation a text report describing an error can be constructed. Reports can be widely customised and translated to desired languages.\n\nThe library is tested with *Clang*, *GCC* and *MSVC* compilers that support *C\\++14* or *C\\++17* standards. Tested operating systems include *Linux*, *Windows*, *macOS*, *iOS* and *Android* platforms.\n\nFor more details see [Documentation](docs/index.md).\n\n## Some examples of basic usage\n\n### Check nested container elements and print report\n\n```cpp\n// define compound validator of nested container elements\nauto v=validator(\n                _[\"field1\"][0](lt,100),\n                _[\"field1\"][1](in,range({10,20,30,40,50})),\n                _[\"field2\"](exists,false),\n                _[\"field3\"](empty(flag,true))\n            );\n                \nerror_report err;\n\n// apply validator to container and construct error message\n\nstd::map\u003cstd::string,std::map\u003csize_t,size_t\u003e\u003e nested_map={\n            {\"field1\",{{1,5},{2,50}}},\n            {\"field3\",{}}\n        };\nvalidate(nested_map,v,err);\nif (err)\n{\n    std::cerr \u003c\u003c err.message() \u003c\u003c std::endl;\n    /* prints:\n    \n    \"element #1 of field1 must be in range [10, 20, 30, 40, 50]\"\n    \n    */\n}\n```\n\n### Check if value is greater than constant\n\nError as an argument.\n\n```cpp\n// define validator\nauto v=validator(gt,100);\n\n// validate variables\nerror err;\n\nvalidate(90,v,err);\nif (err)\n{\n  // validation failed\n}\n\nvalidate(200,v,err))\nif (!err)\n{\n  // validation succeeded\n}\n```\n\nError as an exception.\n\n```cpp\n// define validator\nauto v=validator(gt,100);\n\n// validate variables\n\ntry\n{\n    validate(200,v); // succeed\n    validate(90,v); // throw\n}\ncatch (const validation_error\u0026 err)\n{\n    std::cerr \u003c\u003c err.what() \u003c\u003c std::endl;\n    /* prints:\n    \n    \"must be greater than 100\"\n    \n    */\n}\n\n```\n\nExplicit applying of a validator.\n\n```cpp\n// define validator\nauto v=validator(gt,100);\n\n// apply validator to variables\n\nint value1=90;\nif (!v.apply(value1))\n{\n  // validation failed\n}\n\nint value2=200;\nif (v.apply(value2))\n{\n  // validation succeeded\n}\n```\n\n### Check if string is greater than or equal to other string and size of the string is less than constant\n\n```cpp\n// define validator\nauto v=validator(\n  value(gte,\"sample string\"),\n  size(lt,15)\n);\n\n// apply validator to variables\n\nstd::string str1=\"sample\";\nif (!v.apply(str1))\n{\n  // validation failed, string is less than sample string\n}\n\nstd::string str2=\"sample string+\";\nif (v.apply(str2))\n{\n  // validation succeeded\n}\n\nstd::string str3=\"too long sample string\";\nif (!v.apply(str3))\n{\n  // validation failed, string is too long\n}\n\n```\n### Check if value is in interval and print report\n\n```cpp\n// define validator\nauto v=validator(in,interval(95,100));\n\n// apply validator to variable and construct validation error message\n\nerror_report err;\n\nsize_t val=90;\nvalidate(val,v,err);\nif (err)\n{\n    std::cerr \u003c\u003c err.mesage() \u003c\u003c std::endl; \n    /* prints:\n    \n    \"must be in interval [95,100]\"\n    \n    */\n}\n\n```\n### Check container element and print report\n\n```cpp\n// define compound validator of container elements\nauto v=validator(\n                _[\"field1\"](gte,\"xxxxxx\")\n                 ^OR^\n                _[\"field1\"](size(gte,100) ^OR^ value(gte,\"zzzzzzzzzzzz\"))\n            );\n\n// apply validator to container and construct validation error message\n\nerror_report err;\nstd::map\u003cstd::string,std::string\u003e test_map={{\"field1\",\"value1\"}};\nvalidate(test_map,v,err);\nif (err)\n{\n    std::cerr \u003c\u003c err.message() \u003c\u003c std::endl;\n    /* prints:\n    \n    \"field1 must be greater than or equal to xxxxxx OR size of field1 must be greater than or equal to 100 OR field1 must be greater than or equal to zzzzzzzzzzzz\"\n    \n    */\n}\n```\n\n### Check custom object property and print report\n\n```cpp\n// define structure with getter method\nstruct Foo\n{\n    bool red_color() const\n    {\n        return true;\n    }\n};\n\n// define custom property\nHATN_VALIDATOR_PROPERTY_FLAG(red_color,\"Must be red\",\"Must be not red\");\n\n// define validator of custom property\nauto v=validator(\n    _[red_color](flag,false)\n);\n\n// apply validator to object with custom property and construct validation error message\n\nerror_report err;\nFoo foo_instance;\nvalidate(foo_instance,v,err);\nif (err)\n{\n    std::cerr \u003c\u003c err.message() \u003c\u003c std::endl;\n    /* prints:\n    \n    \"Must be not red\"\n    \n    */\n}\n\n```\n\n### Pre-validate data before updating object's member\n\n```cpp\n// define structure with member variables and member setter method\nstruct Foo\n{\n    std::string bar_value;\n    \n    uint32_t other_value;\n    size_t some_size;\n    \n    void set_bar_value(std::string val)\n    {\n        bar_value=std::move(val);\n    }\n};\n\n// define custom properties\nHATN_VALIDATOR_PROPERTY(bar_value);\nHATN_VALIDATOR_PROPERTY(other_value);\n\n// template specialization for setting bar_value member of Foo\nHATN_VALIDATOR_NAMESPACE_BEGIN\n\ntemplate \u003c\u003e\nstruct set_member_t\u003cFoo,HATN_VALIDATOR_PROPERTY_TYPE(bar_value)\u003e\n{\n    template \u003ctypename ObjectT, typename MemberT, typename ValueT\u003e\n    void operator() (\n            ObjectT\u0026 obj,\n            MemberT\u0026\u0026,\n            ValueT\u0026\u0026 val\n        ) const\n    {\n        obj.set_bar_value(std::forward\u003cValueT\u003e(val));\n    }\n};\n\nHATN_VALIDATOR_NAMESPACE_END\n\nusing namespace HATN_VALIDATOR_NAMESPACE;\n\n// define validator of custom properties\nauto v=validator(\n    _[bar_value](ilex_ne,\"UNKNOWN\"), // case insensitive lexicographical not equal\n    _[other_value](gte,1000)\n);\n\nFoo foo_instance;\n\nerror_report err;\n\n// call setter with valid data\nset_validated(foo_instance,bar_value,\"Hello world\",v,err);\nif (!err)\n{\n    // object's member is set\n}\n\n// call setter with invalid data\nset_validated(foo_instance,bar_value,\"unknown\",v,err);\nif (err)\n{\n    // object's member is not set\n    std::cerr \u003c\u003c err.message() \u003c\u003c std::endl;\n    /* prints:\n     \n     \"bar_value must be not equal to UNKNOWN\"\n     \n     */\n}\n```\n","funding_links":[],"categories":["Validation","C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevgeniums%2Fcpp-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevgeniums%2Fcpp-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevgeniums%2Fcpp-validator/lists"}