constrained-variable

A C++23 header-only library for type-safe variable constraints with support for validation, transformation, and clear error reporting.(使用C++23开发的头文件库,支持类型安全的变量约束,包括校验、转换和清晰的错误报告。)

https://github.com/zhuagenborn/constrained-variable

Science Score: 44.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (9.0%) to scientific vocabulary

Keywords

configuration constraints validation
Last synced: 6 months ago · JSON representation ·

Repository

A C++23 header-only library for type-safe variable constraints with support for validation, transformation, and clear error reporting.(使用C++23开发的头文件库,支持类型安全的变量约束,包括校验、转换和清晰的错误报告。)

Basic Info
  • Host: GitHub
  • Owner: Zhuagenborn
  • License: mit
  • Language: C++
  • Default Branch: main
  • Homepage:
  • Size: 17.6 KB
Statistics
  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • Open Issues: 0
  • Releases: 0
Topics
configuration constraints validation
Created 8 months ago · Last pushed 7 months ago
Metadata Files
Readme License Citation

README.md

Constrained Variable

C++ CMake GitHub Actions License

Introduction

A header-only library written in C++23 for applying composable validation and transformation constraints to variables in a flexible and type-safe way, supporting:

  • Range checks.
  • Null and emptiness checks.
  • Enumeration restrictions.
  • Value transformation.
  • Custom predicate validation.

Constraints are applied in a user-defined order and ensure the values are within the expected bounds or rules. Helpful error messages are generated when constraints are violated.

Unit Tests

Prerequisites

  • Install GoogleTest.
  • Install CMake.

Building

Go to the project folder and run:

bash mkdir -p build cd build cmake -DCVAR_BUILD_TESTS=ON .. cmake --build .

Running

Go to the build folder and run:

bash ctest -VV

Examples

See more examples in tests/constrained_var_tests.cpp.

```c++ // Create a constraint. constexpr InRangestd::size_t speed_range {{10, 80}};

// Create a constrained variable. InRangeVariablestd::size_t speed {speed_range};

// Try to set a new value. speed.Set(input).transform_error( noexcept { std::println("Failed to set the speed: {}", err.second); return false; }); ```

Constraints

Min

Min ensures the value is not less than a specified minimum.

```c++ constexpr Min minopt {10}; MinVariable var {minopt};

EXPECTFALSE(var.Set(5).hasvalue()); EXPECTEQ(var.Set(15).valueor(0), 15); ```

Max

Max ensures the value does not exceed a specified maximum.

```c++ constexpr Max maxopt {100}; MaxVariable var {maxopt};

EXPECTFALSE(var.Set(120).hasvalue()); EXPECTEQ(var.Set(80).valueor(0), 80); ```

InRange

InRange ensures the value lies within a specified range.

```c++ constexpr InRange inrangeopt {{10, 100}}; InRangeVariable var {inrangeopt};

EXPECTFALSE(var.Set(5).hasvalue()); EXPECTEQ(var.Set(50).valueor(0), 50); ```

NotInRange

NotInRange ensures the value is not within a specified range.

```c++ constexpr NotInRange notinrangeopt {{10, 100}}; NotInRangeVariable var {notinrangeopt};

EXPECTFALSE(var.Set(50).hasvalue()); EXPECTEQ(var.Set(5).valueor(0), 5); ```

InSet

InSet ensures the value is in a specified set.

```c++ const InSet insetopt {1, 2}; InSetVariable var {insetopt};

EXPECTEQ(var.Set(1).valueor(0), 1); EXPECTEQ(var.Set(2).valueor(0), 2); EXPECTFALSE(var.Set(3).hasvalue()); ```

NotInSet

NotInSet ensures the value is not in a specified set.

```c++ const NotInSet notinsetopt {1, 2}; NotInSetVariable var {notinsetopt};

EXPECTFALSE(var.Set(1).hasvalue()); EXPECTFALSE(var.Set(2).hasvalue()); EXPECTEQ(var.Set(3).valueor(0), 3); ```

Clamp

Clamp clamps the value into a specified range (std::clamp).

```c++ constexpr Clamp clampopt {{10, 100}}; ClampVariable var {clampopt};

EXPECTEQ(var.Set(5).valueor(0), 10); EXPECTEQ(var.Set(120).valueor(0), 100); ```

Enum

Enum ensures the enumeration lies within an inclusive range.

```c++ enum class Color { White, Red, Green, Black, Invalid };

template <> struct EnumValues { static constexpr std::array values {Color::White, Color::Red, Color::Green, Color::Black}; };

EnumVariable var;

EXPECTFALSE(var.Set(Color::Invalid).hasvalue()); EXPECTEQ(var.Set(Color::Red).valueor(Color::Invalid), Color::Red); ```

NotNull

NotNull ensures the value is not null or false.

```c++ NotNullVariable var;

EXPECTFALSE(var.Set(0).hasvalue()); EXPECTEQ(var.Set(42).valueor(0), 42); ```

NotEmpty

NotEmpty ensures the container like std::vector is not empty.

```c++ NotEmptyVariablestd::vector<int> var;

EXPECTFALSE(var.Set(std::vector {}).hasvalue()); EXPECTEQ(var.Set(std::vector {1}).valueor(std::vector {}), std::vector {1}); ```

Predicate

Predicate ensures the value satisfies a predicate.

```c++ const Predicate pred { noexcept { return x % 2 == 0; }};

PredicateVariable var {pred};

EXPECTFALSE(var.Set(3).hasvalue()); EXPECTEQ(var.Set(4).valueor(0), 4); ```

Transformer

Transformer transforms the value before validation or storage, supporting chaining with other constraints.

```c++ const Transformer func { noexcept { return static_cast(v); }};

TransformerVariable var {func};

EXPECTEQ(var.Set(5).valueor(0.0), 5.0); ```

Constraint Chains

This example transforms an integer to a vector as its size and then check if it is empty using a chain of Transformer and NotEmpty.

```c++ ChainTypestd::vector<int> SizeToVector(const std::size_t& size) noexcept { return std::vector(size); }

constexpr NotEmptystd::vector<int> notemptyopt; const Transformer> transformeropt {SizeToVector}; ConstrainedVariablestd::vector<int, decltype(transformeropt), decltype(notemptyopt)> var {transformeropt, notempty_opt};

EXPECTFALSE(var.Set(0).hasvalue()); EXPECTEQ(var.Set(1).valueor(std::vector {}), std::vector(1)); ```

This example defines a boolean variable that is true only when the input value is 1 or 2 using a chain of InSet and Transformer.

```c++ const InSet insetopt {1, 2}; const Transformer, bool> transformeropt { noexcept { return val.hasvalue(); } };

ConstrainedVariable var {insetopt, transformer_opt};

EXPECTTRUE(var.Set(1).hasvalue()); EXPECT_TRUE(var.Get());

EXPECTTRUE(var.Set(3).hasvalue()); EXPECT_FALSE(var.Get()); ```

In most cases, the parameter type of Apply is exactly the same as the return type of the previous constraint in the chain. For example, the return type of Set<int>::Apply and the parameter type of Transformer<int, bool>::Apply are both ChainType<int>. In this case, if the previous constraint returns an std::unexpected, the user-provided transformation function will not be called.

But currently we want the transformation function to return the validity of the previous constraint's return value. The constraint chain of Set<int> and Transformer<int, bool> does not work because the when the number is not in the set, the transformer will be skipped. Instead, we should use Transformer<ChainType<int>, bool>. The parameter type of its Apply is ChainType<ChainType<int>>. Regardless of whether Set<int> returns a number or an std::unexpected, the result will always be forwarded to the user-provided function.

Validated Boolean Variables

You can directly use ValidatedBoolVariable if you need a boolean variable validated against a set of constraints.

```c++ const InSet insetopt {1, 2}; ValidatedBoolVariable var {insetopt};

EXPECTTRUE(var.Set(1)); EXPECTTRUE(var.Set(2)); EXPECT_FALSE(var.Set(3)); ```

Validation

If you only need to validate values without storing them, you can directly ConstraintChain and ValidationChain.

```c++ const InSet insetopt {1, 2}; ValidationChain var {insetopt};

EXPECTTRUE(var.Apply(1)); EXPECTTRUE(var.Apply(2)); EXPECT_FALSE(var.Apply(3)); ```

License

Distributed under the MIT License. See LICENSE for more information.

Owner

  • Name: Zhuagenborn
  • Login: Zhuagenborn
  • Kind: organization
  • Location: Ireland

Software Development | Artificial Intelligence | Reverse Engineering.

Citation (CITATION.cff)

cff-version: 1.2.0
authors:
- family-names: Chen
  given-names: Zhenshuo
  orcid: https://orcid.org/0000-0003-2091-4160
title: Constrained Variable
date-released: 2025-06-10
url: https://github.com/Zhuagenborn/Constrained-Variable

GitHub Events

Total
  • Public event: 1
  • Push event: 11
Last Year
  • Public event: 1
  • Push event: 11

Committers

Last synced: 7 months ago

All Time
  • Total Commits: 6
  • Total Committers: 1
  • Avg Commits per committer: 6.0
  • Development Distribution Score (DDS): 0.0
Past Year
  • Commits: 6
  • Committers: 1
  • Avg Commits per committer: 6.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Chenzs108 c****8@o****m 6

Issues and Pull Requests

Last synced: 7 months ago

All Time
  • Total issues: 0
  • Total pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Total issue authors: 0
  • Total pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels

Dependencies

.github/workflows/cmake-gtest.yaml actions
  • actions/checkout main composite
  • actions/download-artifact main composite
  • actions/upload-artifact main composite