Skip to content

Commit

Permalink
Revert "Merge pull request #690 from klickverbot/template-predicates"
Browse files Browse the repository at this point in the history
This reverts commit 87e9a4e, reversing
changes made to 7326c53.
  • Loading branch information
andralex committed Sep 8, 2012
1 parent 87e9a4e commit 043633d
Showing 1 changed file with 3 additions and 228 deletions.
231 changes: 3 additions & 228 deletions std/typetuple.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
* type tuple. TL[$(I lwr) .. $(I upr)] returns a new type
* list that is a slice of the old one.
*
* Several templates in this module use or operate on eponymous templates that
* take a single argument and evaluate to a boolean constant. Such templates
* are referred to as $(I template predicates).
*
* References:
* Based on ideas in Table 3.1 from
* $(LINK2 http://amazon.com/exec/obidos/ASIN/0201704315/ref=ase_classicempire/102-2957199-2585768,
Expand All @@ -22,9 +18,7 @@
*
* Copyright: Copyright Digital Mars 2005 - 2009.
* License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
* Authors:
* $(WEB digitalmars.com, Walter Bright),
* $(WEB klickverbot.at, David Nadlinger)
* Authors: $(WEB digitalmars.com, Walter Bright)
* Source: $(PHOBOSSRC std/_typetuple.d)
*/
/* Copyright Digital Mars 2005 - 2009.
Expand Down Expand Up @@ -559,11 +553,7 @@ unittest
}

/**
Tests whether all given items satisfy a template predicate, i.e. evaluates to
$(D F!(T[0]) && F!(T[1]) && ... && F!(T[$ - 1])).
Evaluation is $(I not) short-circuited if a false result is encountered; the
template predicate must be instantiable with all the given items.
Evaluates to $(D F!(T[0]) && F!(T[1]) && ... && F!(T[$ - 1])).
Example:
----
Expand Down Expand Up @@ -594,11 +584,7 @@ unittest
}

/**
Tests whether all given items satisfy a template predicate, i.e. evaluates to
$(D F!(T[0]) || F!(T[1]) || ... || F!(T[$ - 1])).
Evaluation is $(I not) short-circuited if a true result is encountered; the
template predicate must be instantiable with all the given items.
Evaluates to $(D F!(T[0]) || F!(T[1]) || ... || F!(T[$ - 1])).
Example:
----
Expand Down Expand Up @@ -819,214 +805,3 @@ unittest
static assert(is(Filter!(isPointer, int, void*, char[], int*) == TypeTuple!(void*, int*)));
static assert(is(Filter!isPointer == TypeTuple!()));
}


/*
* Instantiates the given template with the given list of parameters.
*
* Used to work around syntactic limitations of D with regard to instantiating
* a template from a type tuple (e.g. T[0]!(...) is not valid) or a template
* returning another template (e.g. Foo!(Bar)!(Baz) is not allowed).
*/
// TODO: Consider publicly exposing this, maybe even if only for better
// understandability of error messages.
template Instantiate(alias Template, Params...)
{
alias Template!Params Instantiate;
}


// Used in template predicate unit tests below.
version (unittest)
{
template always(T...)
{
enum always = true;
}

template never(T...)
{
enum never = false;
}

template error(T...)
{
static assert(false, "Should never be instantiated.");
}
}


/**
* Negates the passed template predicate.
*
* Examples:
* ---
* alias templateNot!isPointer isNoPointer;
* static assert(!isNoPointer!(int*));
* static assert(allSatisfy!(isNoPointer, string, char, float));
* ---
*/
template templateNot(alias pred)
{
template templateNot(T...)
{
enum templateNot = !pred!T;
}
}

// Verify examples.
unittest
{
import std.traits;

alias templateNot!isPointer isNoPointer;
static assert(!isNoPointer!(int*));
static assert(allSatisfy!(isNoPointer, string, char, float));
}

unittest
{
foreach (T; TypeTuple!(int, staticMap, 42))
{
static assert(!Instantiate!(templateNot!always, T));
static assert(Instantiate!(templateNot!never, T));
}
}


/**
* Combines several template predicates using logical AND, i.e. constructs a new
* predicate which evaluates to true for a given input T if and only if all of
* the passed predicates are true for T.
*
* The predicates are evaluated from left to right, aborting evaluation in a
* short-cut manner if a false result is encountered, in which case the latter
* instantiations do not need to compile.
*
* Examples:
* ---
* alias templateAnd!(isNumeric, templateNot!isUnsigned) storesNegativeNumbers;
* static assert(storesNegativeNumbers!int);
* static assert(!storesNegativeNumbers!string && !storesNegativeNumbers!uint);
*
* // An empty list of predicates always yields true.
* alias templateAnd!() alwaysTrue;
* static assert(alwaysTrue!int);
* ---
*/
template templateAnd(Preds...)
{
template templateAnd(T...)
{
static if (Preds.length == 0)
{
enum templateAnd = true;
}
else
{
static if (Instantiate!(Preds[0], T))
alias Instantiate!(.templateAnd!(Preds[1 .. $]), T) templateAnd;
else
enum templateAnd = false;
}
}
}

// Verify examples.
unittest
{
alias templateAnd!(isNumeric, templateNot!isUnsigned) storesNegativeNumbers;
static assert(storesNegativeNumbers!int);
static assert(!storesNegativeNumbers!string && !storesNegativeNumbers!uint);

// An empty list of predicates always yields true.
alias templateAnd!() alwaysTrue;
static assert(alwaysTrue!int);
}

unittest
{
foreach (T; TypeTuple!(int, staticMap, 42))
{
static assert(Instantiate!(templateAnd!(), T));
static assert(Instantiate!(templateAnd!(always), T));
static assert(Instantiate!(templateAnd!(always, always), T));
static assert(!Instantiate!(templateAnd!(never), T));
static assert(!Instantiate!(templateAnd!(always, never), T));
static assert(!Instantiate!(templateAnd!(never, always), T));

static assert(!Instantiate!(templateAnd!(never, error), T));
static assert(!is(typeof(Instantiate!(templateAnd!(always, error), T))));
}
}


/**
* Combines several template predicates using logical OR, i.e. constructs a new
* predicate which evaluates to true for a given input T if and only at least
* one of the passed predicates is true for T.
*
* The predicates are evaluated from left to right, aborting evaluation in a
* short-cut manner if a true result is encountered, in which case the latter
* instantiations do not need to compile.
*
* Examples:
* ---
* alias templateOr!(isPointer, isUnsigned) isPtrOrUnsigned;
* static assert(isPtrOrUnsigned!uint && isPtrOrUnsigned!(short*));
* static assert(!isPtrOrUnsigned!int && !isPtrOrUnsigned!string);
*
* // An empty list of predicates never yields true.
* alias templateOr!() alwaysFalse;
* static assert(!alwaysFalse!int);
* ---
*/
template templateOr(Preds...)
{
template templateOr(T...)
{
static if (Preds.length == 0)
{
enum templateOr = false;
}
else
{
static if (Instantiate!(Preds[0], T))
enum templateOr = true;
else
alias Instantiate!(.templateOr!(Preds[1 .. $]), T) templateOr;
}
}
}

// Verify examples.
unittest
{
alias templateOr!(isPointer, isUnsigned) isPtrOrUnsigned;
static assert(isPtrOrUnsigned!uint && isPtrOrUnsigned!(short*));
static assert(!isPtrOrUnsigned!int && !isPtrOrUnsigned!string);

// An empty list of predicates never yields true.
alias templateOr!() alwaysFalse;
static assert(!alwaysFalse!int);
}

unittest
{
foreach (T; TypeTuple!(int, staticMap, 42))
{
static assert(Instantiate!(templateOr!(always), T));
static assert(Instantiate!(templateOr!(always, always), T));
static assert(Instantiate!(templateOr!(always, never), T));
static assert(Instantiate!(templateOr!(never, always), T));
static assert(!Instantiate!(templateOr!(), T));
static assert(!Instantiate!(templateOr!(never), T));

static assert(Instantiate!(templateOr!(always, error), T));
static assert(Instantiate!(templateOr!(never, always, error), T));
// DMD @@BUG@@: Assertion fails for int, seems like a error gagging
// problem. The bug goes away when removing some of the other template
// instantiations in the module.
// static assert(!is(typeof(Instantiate!(templateOr!(never, error), T))));
}
}

0 comments on commit 043633d

Please sign in to comment.