1 module nxt.graph;
2 
3 @safe pure nothrow:
4 
5 import std.array : Appender;
6 
7 extern(C++) class Graph { extern(D):
8 	Appender!(Node[]) nodes;
9 	Appender!(Edge[]) edges;
10 	Appender!(SuperEdge[]) superEdges;
11 }
12 
13 extern(C++) class Entity { extern(D):
14 @safe pure nothrow:
15 	abstract inout(Graph) gr() inout;		   // get up-reference
16 }
17 
18 extern(C++) class Node : Entity { extern(D):
19 @safe pure nothrow:
20 	this(Graph gr) scope @trusted {
21 		_db = gr;
22 		gr.nodes.put(this);
23 	}
24 	pragma(inline, true)
25 	override final inout(Graph) gr() inout => _db;
26 	private Graph _db;			 // up-reference
27 }
28 
29 extern(C++) class Text : Node { extern(D):
30 @safe pure nothrow:
31 	this(Graph gr, string text) scope @trusted {
32 		super(gr);
33 		this.text = text;
34 	}
35 	const string text;
36 }
37 
38 /// Number with numerical type `T`.
39 extern(C++) class Number(T) : Node { extern(D):
40 @safe pure nothrow:
41 	this(Graph gr, T value) scope @trusted {
42 		super(gr);
43 		this.value = value;
44 	}
45 	const T value;
46 }
47 
48 extern(C++) class Edge : Entity { extern(D):
49 @safe pure nothrow:
50 	this(Graph gr) scope @trusted {
51 		_db = gr;
52 		gr.edges.put(this);
53 	}
54 	pragma(inline, true)
55 	override final inout(Graph) gr() inout => _db;
56 	private Graph _db;			 // up-reference
57 }
58 
59 extern(C++) class SuperEdge : Entity { extern(D):
60 @safe pure nothrow:
61 	this(Graph gr) scope @trusted {
62 		_db = gr;
63 		gr.superEdges.put(this);
64 	}
65 	pragma(inline, true)
66 	override final inout(Graph) gr() inout => _db;
67 	private Graph _db;			 // up-reference
68 }
69 
70 extern(C++) class Rela(uint arity) : Edge if (arity >= 2) { extern(D):
71 @safe pure nothrow:
72 	this(Graph gr) scope @trusted {
73 		super(gr);
74 	}
75 	Entity[arity] actors;
76 }
77 
78 extern(C++) class Func(uint arity) : Edge if (arity >= 1) { extern(D):
79 @safe pure nothrow:
80 	this(Graph gr) scope @trusted {
81 		super(gr);
82 	}
83 	Entity[arity] params;
84 }
85 
86 pure nothrow @safe unittest {
87 	auto gr = new Graph();
88 	scope node = new Node(gr);
89 	scope edge = new Edge(gr);
90 	scope rela2 = new Rela!2(gr);
91 	scope func1 = new Func!1(gr);
92 }