1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#include "memorystore.hpp"
#include "concept.hpp"
#include "errors.hpp"
#include "ref.hpp"
#include <unordered_set>
namespace intellect {
namespace level0 {
static auto & index()
{
static std::unordered_set<ref, std::hash<concept*>> index;
return index;
}
namespace concepts {
ref allocator() { static ref ret = new concept(); return ret; };
ref allocates() { static ref ret = new concept(); return ret; };
ref allocations() { static ref ret = new concept(); return ret; };
ref level0allocations() { static ref ret = new concept(); return ret; };
}
struct init { init()
{
concepts::allocator().link(concepts::allocator(), concepts::level0allocations());
concepts::level0allocations().link(concepts::allocates(), concepts::allocator());
index().insert(concepts::allocator());
concepts::allocates().link(concepts::allocator(), concepts::level0allocations());
concepts::level0allocations().link(concepts::allocates(), concepts::allocates());
index().insert(concepts::allocates());
concepts::allocations().link(concepts::allocator(), concepts::level0allocations());
concepts::level0allocations().link(concepts::allocates(), concepts::allocations());
index().insert(concepts::allocations());
concepts::level0allocations().link(concepts::allocator(), concepts::level0allocations());
concepts::level0allocations().link(concepts::allocates(), concepts::level0allocations());
index().insert(concepts::level0allocations());
} } _init;
ref alloc(ref source, std::any data)
{
concept * r = new concept();
r->data = data;
alloc((ref)r, source);
index().insert(r);
return r;
}
void alloc(ref r, ref source)
{
r.link(concepts::allocator(), source);
source.link(concepts::allocates(), r);
}
void realloc(ref r, ref newsource)
{
ref oldsource = r.get(concepts::allocator());
alloc(r, newsource);
dealloc(r, oldsource);
}
static concept* referenced(ref r, ref source) {
for (ref r2 : index()) {
if (r2 == source) {
continue;
}
if (r2 == r) {
continue;
}
for (auto & l : r2.links()) {
if (ref(l.first) == r) {
return r2;
}
if (ref(l.second) == r) {
return r2;
}
}
}
return 0;
}
void dealloc(ref r, ref source) {
auto it = index().find(r);
if (it == index().end()) { throw no_such_concept(r); }
source.unlink(concepts::allocates(), r);
r.unlink(concepts::allocator(), source);
if (r.linked(concepts::allocator())) { return; }
index().erase(it);
auto ours = r.getAll(concepts::allocates());
for (auto allocation : ours) {
dealloc(allocation, r);
}
for (auto ghost : ours) {
concept * referenced = intellect::level0::referenced(ghost, source);
if (referenced) {
throw still_referenced_by(ghost, referenced);
}
}
delete (concept*)r;
}
std::size_t allocated()
{
return index().size();
}
}
}
|