1 module nxt.graph;
2 
3 @safe pure nothrow:
4 
5 import std.array : Appender;
6 
7 import nxt.languages;
8 
9 class Db
10 {
11     Appender!(Node[]) nodes;
12     Appender!(Edge[]) edges;
13     Appender!(SuperEdge[]) superEdges;
14 }
15 
16 extern(C++) class Entity
17 {
18 extern(D):
19     @safe pure nothrow:
20     abstract inout(Db) db() inout;           // get up-reference
21 }
22 
23 extern(C++) class Node : Entity
24 {
25 extern(D):
26     @safe pure nothrow:
27 
28     this(Db db)
29     {
30         _db = db;
31         db.nodes.put(this);
32     }
33 
34     pragma(inline, true)
35     override final inout(Db) db() inout { return _db; }
36     private Db _db;             // up-reference
37 }
38 
39 extern(C++) class Text : Node
40 {
41 extern(D):
42     @safe pure nothrow:
43     this(Db db, string text, Lang lang)
44     {
45         super(db);
46         this.text = text;
47     }
48     const string text;
49     Lang lang;
50 }
51 
52 /// Number with numerical type `T`.
53 extern(C++) class Number(T) : Node
54 {
55 extern(D):
56     @safe pure nothrow:
57     this(Db db, T value)
58     {
59         super(db);
60         this.value = value;
61     }
62     const T value;
63 }
64 
65 extern(C++) class Edge : Entity
66 {
67 extern(D):
68     @safe pure nothrow:
69 
70     this(Db db)
71     {
72         _db = db;
73         db.edges.put(this);
74     }
75 
76     pragma(inline, true)
77     override final inout(Db) db() inout { return _db; }
78     private Db _db;             // up-reference
79 }
80 
81 extern(C++) class SuperEdge : Entity
82 {
83 extern(D):
84     @safe pure nothrow:
85 
86     this(Db db)
87     {
88         _db = db;
89         db.superEdges.put(this);
90     }
91 
92     pragma(inline, true)
93     override final inout(Db) db() inout { return _db; }
94     private Db _db;             // up-reference
95 }
96 
97 extern(C++) class Rela(uint arity) : Edge
98     if (arity >= 2)
99 {
100 extern(D):
101     @safe pure nothrow:
102 
103     this(Db db)
104     {
105         super(db);
106     }
107 
108     Entity[arity] actors;
109 }
110 
111 extern(C++) class Func(uint arity) : Edge
112     if (arity >= 1)
113 {
114 extern(D):
115     @safe pure nothrow:
116 
117     this(Db db)
118     {
119         super(db);
120     }
121 
122     Entity[arity] params;
123 }
124 
125 @safe pure nothrow unittest
126 {
127     auto db = new Db();
128     scope node = new Node(db);
129     scope edge = new Edge(db);
130     scope rela2 = new Rela!2(db);
131     scope func1 = new Func!1(db);
132 }