A need that I met one day was to make sure some values are being properly controlled no matter who changes them.
struct Input { int a; int b; };
-
a
must be maximum50
– if a greater value is assigned,50
must be setb
must be minimum50
– if a lower value is assigned,50
must be set- if
b
is greater than100
, the flow cannot continue, the execution must be stopped
The fields in the struct can be changed by multiple layers of the application, so their values must be checked after each change. Possible solutions:
-
- an API that assigns and verifies the values: each layer must use the API
- an API that only verifies the values: after each layer updates the values, the API must be used by the caller
- setters defined on the struct:
SetA(int)
,SetB(int)
The API solutions require extra work; someone must use the API and not forget about it otherwise bugs could be introduced. The setters solution forces the usage of those methods, but I don’t want to rely on OOP here; instead, I want to go for a data-oriented approach and keep my struct as simple as possible.
I would like for a property of the struct to be configured in such a way that every time it’s being assigned a value, that value is verified against some requirements. In larger projects with layers that need to mutate some data passed around, it might be safer to go this way instead of relying on people to remember to explicitly do something.
How it looks
Someone told me they would like to see something like this:
struct Input { wrapped_value<int> a; wrapped_value<int> b; };
wrapped_value
is a wrapper that receives any value assigned to the property it wraps and makes sure it’s valid. The type of the property is passed as a template argument to the wrapper.
a
and b
should behave like their original types. Wrapping them, they are no longer integers, but wrapped_value
s. Continue reading Another type of data validation in C++