13,139,132 members (82,459 online)
Add your own
alternative version

#### Stats

17.5K views
27 bookmarked
Posted 15 Apr 2014

# Trusted Variables

, 29 Apr 2014
 Rate this:
Please Sign up or sign in to vote.
An easy and an elegeant way to create "trusted" data variables.

## Introduction

"Trusted Variables" are intended to simplify three very common coding approaches:

1. Set variable default value.
2. Define range of valid values that may be assigned to the variable.
3. Validate assignment (assigned value is in the range) for any assignment.

Usually, these three approaches are implemented in different places: default values are set on declaration or initialization, range definition is semantic only, and assignment validation is implemented for any particular assignment.

"Trusted variables" are trying to bring all three approaches together to the single place - declaration. Once "Trusted variable" is declared, default value is set, and any trial to assign "not in range" value will fail.

## Example

Let's assume we have some application, that uses calendar day, as a variable..

Ideally, we would like to define some "trusted" `day`, that may be used without any further verification.

```// variable "day" declaration, type set as uint8_t, range 1-31, and default value 15
TRUSTED_VAR( uint8_t, day, MIN(1), MAX(31), DEFAULT(15) ); ```

Then, when we use, we may refer to variable `day`, as a native `uint8_t`.

```// May be used as a native type ( uint8_t in this case ) Lvalue in any expression
day = 10; // ok, value in range

uint8_t wrong_day = 32;

day = wrong_day; // out of range, error generated, "day" was not changed

// May be used as a native type ( uint8_t in this case ) Rvalue in any expression
uint8_t temp_day = day;```

## The Idea

The idea of trusted variable is pretty simple:

For assignment verification, Copy Constructor and Assignment Operator, should involve verification, and for using "like" a native type, Cast Operator to the native type should be implemented.

## Implementation

Please NOTE, the following code contains "extra" information like a variable name, and other "`string`" related conversions, that may be omitted.

```#ifndef __TRUSTED_VAR__
#define __TRUSTED_VAR__

#include <string>
// Following constexpr functions are for decorations purposes only
template < typename T > static constexpr T MIN(T min) { return min; }
template < typename T > static constexpr T MAX(T max) { return max; }
template < typename T > static constexpr T DEFAULT(T default) { return default; }

#define TRUSTED_VAR( _type, _name, _min, _max, _default ) \
TrustedVar< _type,_min, _max, _default > _name{#_name};

template
< typename VAR_TYPE, VAR_TYPE MIN_VAL, VAR_TYPE MAX_VAL, VAR_TYPE DEFAULT_VAL >
class TrustedVar
{
public:
static_assert((MAX_VAL >= MIN_VAL), "Invalid Range");

explicit TrustedVar(const char* _val_name):val_name{_val_name}, value{DEFAULT_VAL}
{}

TrustedVar(const TrustedVar& _var)
{
value = _var.value;
}

TrustedVar& operator = (const VAR_TYPE& _value)
{
if ( IsInRange(_value) ) value = _value;

else NotInRange( val_name,
std::to_string(MIN_VAL),
std::to_string(MAX_VAL),
std::to_string(_value)
);

return *this;
}

operator VAR_TYPE()
{
return value;
}

private:
bool IsInRange(const VAR_TYPE& _value)
{
return ((MIN_VAL <= _value) && (MAX_VAL >= _value));
}
private:
const std::string val_name;
VAR_TYPE value;
};

#endif //__TRUSTED_VAR__```

I did use MACRO definition for `TRUSTED_VAR `for this particular example I wanted to pass variable name for logging purposes `(_name{#_name}) `

If that is not required - that single MACRO may be omitted.

## Error Handling

As we saw, on invalid (out of range) assignment will generate an error. The question is how this error will be handled? That really depends on the application, that uses Trusted Variable. As an option, "Out of Range" assignment may generate an exception, may trigger "assert", may generate error log, may set last error, etc.

So ideally, we want to make Error Handling customizable.

Another interesting thing about Trusted Variables, is that usually they are not coming in "singles". In our example with a variable `day`, most likely we will have Trusted Variable `month`, Trusted Variable `year`, and may be `hour`, `minute `and `second`. All of them, I assume, will have the same Error Handling Method.

Providing Error Handling method, as a virtual method on definition of every Trusted Variable, will add another parameter, and more important, will add Memory Complexity (Virtual Table will be created for any single variable) and Performance Complexity (Error handling method will be resolved in Run time).

Instead of this, I suggest to use kind of Compile Time "Namespace Polymorphism".

Let's define Error Handling method, scoped by specific namespace.

```namespace DEFAULT_ERROR_HANDLING_NAMESPACE
{
void NotInRange(const std::string& _var_name,
const std::string& range_min,
const std::string& range_max,
const std::string& val)
{
std::cout << "ERROR: Variable \""
+ std::string(_var_name)
+ "\":"
+ " value "
+ val
+ " is out of "
+ range_min
+ '-'
+ range_max
+ " range " << std::endl;
}
}```

Now, before using of Trusted Variable, we just need to declare using of the specific namespace, that contains "desired" Error handling implementation. Now all Trusted Variables, while we are "using" this specific namespace, will be handled by the same method (remember, Trusted Variables are not coming "alone" to the "party").

```using namespace DEFAULT_ERROR_HANDLING_NAMESPACE;

int main()
{
// variable "day" declaration, type set as uint8_t, range 1-31, and default value 15
TRUSTED_VAR( uint8_t, day, MIN(1), MAX(31), DEFAULT(15) );

// May be used as a native type ( uint8_t in this case ) Lvalue in any expression
day = 10; // ok, value in range

uint8_t wrong_day = 32;

day = wrong_day; // out of range, error generated, "day" was not changed

// May be used as a native type ( uint8_t in this case ) Rvalue in any expression
uint8_t temp_day = day;

return 0;
}```

As a result, on Out Of Range assignment,

`ERROR: Variable "day": value 32 is out of 1-31 range `

will be generated.

## Customization

Please see Trusted Variable implementation as a concept. The code may be easily customized, by omitting unnecessary information, like a variable name, removing `string `related operations, and/or change of `NotInRange `Error Handling signature.

I preferred to avoid run-time polymorphism.

## Revisions

• April 27, 2014 - `constexpr `functions instead of decoration macros were added (thanks to Stefan_Lang for the idea)

## Compatibility

• Tested on VS2013 + Visual C++ Compiler November 2013 CTP (for constexpr support)

Use them ! :)

## License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

## About the Author

 Software Developer Box United States
No Biography provided

## Comments and Discussions

 First Prev Next
 Better than enums? Member 969253030-Apr-14 21:36 Member 9692530 30-Apr-14 21:36
 Re: Better than enums? Evgeny Zavalkovsky1-May-14 5:21 Evgeny Zavalkovsky 1-May-14 5:21
 We Think Along Similar Lines Enigmatic Texan27-Apr-14 18:52 Enigmatic Texan 27-Apr-14 18:52
 Re: We Think Along Similar Lines Evgeny Zavalkovsky1-May-14 13:07 Evgeny Zavalkovsky 1-May-14 13:07
 Please eliminate the #define statements! Stefan_Lang24-Apr-14 20:15 Stefan_Lang 24-Apr-14 20:15
 Re: Please eliminate the #define statements! Evgeny Zavalkovsky25-Apr-14 7:33 Evgeny Zavalkovsky 25-Apr-14 7:33
 Re: Please eliminate the #define statements! Stefan_Lang27-Apr-14 20:13 Stefan_Lang 27-Apr-14 20:13
 Re: Please eliminate the #define statements! Evgeny Zavalkovsky27-Apr-14 20:29 Evgeny Zavalkovsky 27-Apr-14 20:29
 Re: Please eliminate the #define statements! Bill_Hallahan1-May-14 18:15 Bill_Hallahan 1-May-14 18:15
 Re: Please eliminate the #define statements! Evgeny Zavalkovsky2-May-14 4:59 Evgeny Zavalkovsky 2-May-14 4:59
 Re: Please eliminate the #define statements! Bill_Hallahan2-May-14 15:56 Bill_Hallahan 2-May-14 15:56
 Re: Please eliminate the #define statements! Evgeny Zavalkovsky2-May-14 17:40 Evgeny Zavalkovsky 2-May-14 17:40
 more safer defination jacky_zz21-Apr-14 16:50 jacky_zz 21-Apr-14 16:50
 Re: more safer defination Evgeny Zavalkovsky21-Apr-14 20:06 Evgeny Zavalkovsky 21-Apr-14 20:06
 Re: more safer defination Prakash Nadar29-Apr-14 7:18 Prakash Nadar 29-Apr-14 7:18
 Re: more safer defination Evgeny Zavalkovsky1-May-14 13:07 Evgeny Zavalkovsky 1-May-14 13:07
 My 5 kwanti20-Apr-14 7:10 kwanti 20-Apr-14 7:10
 My vote of 5 David Days17-Apr-14 7:37 David Days 17-Apr-14 7:37
 Last Visit: 31-Dec-99 18:00     Last Update: 19-Sep-17 7:22 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.170915.1 | Last Updated 29 Apr 2014
Article Copyright 2014 by Evgeny Zavalkovsky
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid