# Difference between revisions of "Creating a subtype using struct template"

 Level: Novice Cookbook Type: Recipe Cookbook Status: Draft Approximate reading time: 5 min0.083 hr D Version: D2

This recipe shows how to create a subtype for an integral / floating point range using a struct template. Run the code

## Program Code

```import std.traits : isIntegral, isFloatingPoint;

struct SubType(Type, Type Min, Type Max, Type Init = Min, alias Ex = Exception,
alias Tolerance = 0.001f)
if( isIntegral!(Type) || isFloatingPoint!(Type) )
{
private
{
Type value = Init;
}
//static const Type min = Min;
//static const Type max = Max;

@property Type access()
{
return value;
}

@property void access(Type new_val)
{
static if (isIntegral!(Type))
{
if ( !((new_val >= Min) && (new_val <= Max)) )
throw new Ex("Value not in range [min,max]");
}
else static if (isFloatingPoint!(Type))
{
Type amin = new_val - Min;
amin = (amin < 0.0)? -amin : amin;

Type amax = new_val - Max;
amax = (amax < 0.0)? -amax : amax;

if ( !( ((new_val > Min) || (amin < Tolerance)) &&
((new_val < Max) || (amax < Tolerance))    ) )
throw new Ex("Value not in range [min,max]");
}
else
static assert(false, "Not Implemented!");

value = new_val;
}

alias access this;
}

class MyException : Exception
{
this(string msg, string f = __FILE__, size_t l = __LINE__)
{
super( "MyException: " ~ msg, f, l);
}
}

//pragma(msg, SubType!(int, 0, 123).max );

unittest
{
import std.conv      : to;
import std.exception : assertThrown;

alias SubType!(int, 0, 123, 100, MyException) MyInt1;
alias SubType!(int, 0, 123) MyInt2;

MyInt1 m1;
MyInt2 m2;

assert(m1 == 100);
assert(m2 == 0);

m1 = 123;
assert(m1 == 123);

m2 = to!(uint)("123");
assert(m2 == 123);

assertThrown!(MyException)(m1 = -1);
assertThrown!(MyException)(m1 = 124);
m1 = 99;
assert(m1 == 99);

assertThrown(m2 = -1);
assertThrown(m2 = 124);
m2 = 99;
assert(m2 == 99);

SubType!(float, 0.0, 1.0) f1;

const float tol = 0.001f;

float diff;

diff = f1 - 0.0f;
diff = (diff < 0.0f)? -diff : diff;
assert(diff < tol);

f1 = 1.0f;
diff = f1 - 1.0f;
diff = (diff < 0.0f)? -diff : diff;
assert(diff < tol);

assertThrown(f1 = -0.01f);
assertThrown(f1 =  1.01f);

SubType!(double, 0.000_1, 0.000_9, 0.000_1, MyException, 0.000_001) d1;

const double dtol = 0.000_001;

double ddiff;

ddiff = d1 - 0.000_1;
ddiff = (ddiff < 0)? -ddiff : ddiff;
assert(ddiff < dtol);

d1 = 0.000_9;

ddiff = d1 - 0.000_9;
ddiff = (ddiff < 0)? -ddiff : ddiff;
assert(ddiff < dtol);

assertThrown!(MyException)(d1 = 0.000_09);
assertThrown!(MyException)(d1 = 0.000_099);
assertThrown!(MyException)(d1 = 0.000_91);
assertThrown!(MyException)(d1 = 0.000_901);

d1 = 0.000_0999;

ddiff = d1 - 0.000_0999;
ddiff = (ddiff < 0)? -ddiff : ddiff;
assert(ddiff < dtol);

d1 = 0.000_9001;

ddiff = d1 - 0.000_9001;
ddiff = (ddiff < 0)? -ddiff : ddiff;
assert(ddiff < dtol);

}

void main() { }
```