Expand Up
@@ -8,153 +8,6 @@ Authors: $(WEB erdani.com, Andrei Alexandrescu), Timon Gehr (`Ternary`)
module std.experimental.allocator.common ;
import std.algorithm , std.traits ;
/**
Ternary type with three thruth values.
*/
struct Ternary
{
@safe @nogc nothrow pure :
package ubyte value = 6 ;
package static Ternary make(ubyte b)
{
Ternary r = void ;
r.value = b;
return r;
}
/**
In addition to `false` and `true`, `Ternary` offers `unknown`.
*/
enum no = make(0 );
// / ditto
enum yes = make(2 );
// / ditto
enum unknown = make(6 );
/**
Construct and assign from a `bool`, receiving `no` for `false` and `yes`
for `true`.
*/
this (bool b) { value = b << 1 ; }
// / ditto
void opAssign (bool b) { value = b << 1 ; }
/**
Construct a ternary value from another ternary value
*/
this (const Ternary b) { value = b.value; }
/**
$(TABLE Truth table for logical operations,
$(TR $(TH `a`) $(TH `b`) $(TH `$(TILDE)a`) $(TH `a | b`) $(TH `a & b`) $(TH `a ^ b`))
$(TR $(TD `no`) $(TD `no`) $(TD `yes`) $(TD `no`) $(TD `no`) $(TD `no`))
$(TR $(TD `no`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `no`) $(TD `yes`))
$(TR $(TD `no`) $(TD `unknown`) $(TD) $(TD `unknown`) $(TD `no`) $(TD `unknown`))
$(TR $(TD `yes`) $(TD `no`) $(TD `no`) $(TD `yes`) $(TD `no`) $(TD `yes`))
$(TR $(TD `yes`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `yes`) $(TD `no`))
$(TR $(TD `yes`) $(TD `unknown`) $(TD) $(TD `yes`) $(TD `unknown`) $(TD `unknown`))
$(TR $(TD `unknown`) $(TD `no`) $(TD `unknown`) $(TD `unknown`) $(TD `no`) $(TD `unknown`))
$(TR $(TD `unknown`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `unknown`) $(TD `unknown`))
$(TR $(TD `unknown`) $(TD `unknown`) $(TD) $(TD `unknown`) $(TD `unknown`) $(TD `unknown`))
)
*/
Ternary opUnary (string s)() if (s == " ~" )
{
return make (386 >> value & 6 );
}
// / ditto
Ternary opBinary (string s)(Ternary rhs) if (s == " |" )
{
return make (25_512 >> value + rhs.value & 6 );
}
// / ditto
Ternary opBinary (string s)(Ternary rhs) if (s == " &" )
{
return make (26_144 >> value + rhs.value & 6 );
}
// / ditto
Ternary opBinary (string s)(Ternary rhs) if (s == " ^" )
{
return make (26_504 >> value + rhs.value & 6 );
}
}
@safe @nogc nothrow pure
unittest
{
alias f = Ternary.no, t = Ternary.yes, u = Ternary.unknown;
Ternary[27 ] truthTableAnd =
[
t, t, t,
t, u, u,
t, f, f,
u, t, u,
u, u, u,
u, f, f,
f, t, f,
f, u, f,
f, f, f,
];
Ternary[27 ] truthTableOr =
[
t, t, t,
t, u, t,
t, f, t,
u, t, t,
u, u, u,
u, f, u,
f, t, t,
f, u, u,
f, f, f,
];
Ternary[27 ] truthTableXor =
[
t, t, f,
t, u, u,
t, f, t,
u, t, u,
u, u, u,
u, f, u,
f, t, t,
f, u, u,
f, f, f,
];
for (auto i = 0 ; i != truthTableAnd.length; i += 3 )
{
assert ((truthTableAnd[i] & truthTableAnd[i + 1 ])
== truthTableAnd[i + 2 ]);
assert ((truthTableOr[i] | truthTableOr[i + 1 ])
== truthTableOr[i + 2 ]);
assert ((truthTableXor[i] ^ truthTableXor[i + 1 ])
== truthTableXor[i + 2 ]);
}
Ternary a;
assert (a == Ternary.unknown);
static assert (! is (typeof ({ if (a) {} })));
assert (! is (typeof ({ auto b = Ternary(3 ); })));
a = true ;
assert (a == Ternary.yes);
a = false ;
assert (a == Ternary.no);
a = Ternary.unknown;
assert (a == Ternary.unknown);
Ternary b;
b = a;
assert (b == a);
assert (~ Ternary.yes == Ternary.no);
assert (~ Ternary.no == Ternary.yes);
assert (~ Ternary.unknown == Ternary.unknown);
}
/**
Returns the size in bytes of the state that needs to be allocated to hold an
object of type $(D T). $(D stateSize!T) is zero for $(D struct)s that are not
Expand Down
Expand Up
@@ -605,6 +458,7 @@ package void testAllocator(alias make)()
{
import std.conv : text;
import std.stdio : writeln, stderr;
import std.typecons : Ternary;
alias A = typeof (make());
scope (failure) stderr.writeln(" testAllocator failed for " , A.stringof);
Expand Down