1 /**
2 * This module defines the notion of a $(RULE). A $(RULE) is the part of
3 * a $(I cellular automaton) responsible for changing the $(I ca)'s $(I cells) state.
4 * Each generation the $(RULE) is applied to the $(I cellular automaton) in order to
5 * get it's $(I cells) new state.
6 *
7 * It provides templates for testing whether a given object is a $(RULE), and
8 * what kind of $(RULE) it is.
9 *
10 * $(CALIB_ABSTRACT_DESC)
11 */
12 
13 module caLib_abstract.rule;
14 
15 /**
16 * Tests if something is a $(B Rule), defined as having a primitive `applyRule`
17 *
18 * returns `true` if `T` is a $(B Rule). A $(B Rule) is the most
19 * basic form of a $(CU rule). It must define the primitive
20 * `void applyRule()`.
21 *
22 * params: T = the type to be tested
23 *
24 * returns: true if T is a $(B Rule), false if not
25 */
26 enum isRule(T) =
27     is(typeof(T.init.applyRule()) : void);
28 
29 ///
30 unittest
31 {
32     struct A { void applyRule() {} }
33     struct B { int applyRule(int b) { return int.init; } }
34     
35     static assert( isRule!A );
36     static assert(!isRule!B );
37     static assert(!isRule!string );
38 }
39 
40 /**
41 * Tests if something is a $(B ReversibleRule), defined as being a $(B Rule) with
42 * the additional primitive `applyRuleReverse` 
43 *
44 * returns `true` if `T` is a $(B ReversibleRule). A $(B ReversibleRule) can "reverse"
45 * the state of a $(I ca) to its previours state. It must define the primitive
46 * `void applyRuleReverse()`, in addition to the primitives defined in $(B Rule)
47 *
48 * params: T = the type to be tested
49 *
50 * returns: true if T is a $(B ReversibleRule), false if not
51 */
52 enum isReversibleRule(T) =
53     isRule!T &&
54     is(typeof(T.init.applyRuleReverse()) : void);
55 
56 ///
57 unittest
58 {
59     struct A
60     {
61         void applyRule() {}
62         void applyRuleReverse() {}
63     }
64     
65     static assert( isRule!A );
66     static assert(!isRule!string );
67 }