Added cons.
[mozart2.git] / uniques.hh
blob6d518e1f82309c292d4a3f65278c3f5e18c811ff
1 class UniqueBlock{
2 public:
3 UniqueBlock* next;
4 UniqueBlock* gcTo;
5 hash_t hash;
6 const VTable* refVT;
7 virtual bool is(void* extra)=0;
8 virtual void gc(GC& gc)=0;
9 };
10 class UniqueController{
11 VM& vm;
12 size_t capacity;
13 size_t occupancy;
14 UniqueBlock** tab;
15 public:
16 UniqueController(VM& _vm):vm(_vm),capacity(0),occupancy(0),tab(0){}
17 UniqueBlock* get(hash_t hash,const VTable* refVT, void* extra){
18 UniqueBlock* c=tab[hash%capacity];
19 while(c&&!(c->hash==hash&&c->refVT==refVT&&c->is(extra))){
20 c=c->next;
22 return c;
24 void add(UniqueBlock* n){
25 if(capacity>>1<occupancy)grow();
26 n->next=tab[n->hash%capacity];
27 tab[n->hash%capacity]=n;
29 void grow(){
30 size_t ocapacity=capacity;
31 UniqueBlock** otab=tab;
32 capacity=capacity?((capacity<<1)+1):31;
33 tab=(UniqueBlock**)operator new (capacity*sizeof(UniqueBlock*),vm);
34 for(size_t i=0;i<capacity;++i){
35 tab[i]=0;
37 for(size_t i=0;i<ocapacity;++i){
38 UniqueBlock* c=otab[i];
39 while(c){
40 add(c);
41 c=c->next;
45 void gc(){
46 capacity=(occupancy<<1)+1;
47 tab=(UniqueBlock**)operator new (capacity*sizeof(UniqueBlock*),vm);
48 for(size_t i=0;i<capacity;++i){
49 tab[i]=0;
53 void gcIntoUnique(Node& it, GC& gc, Node& dest){
54 UniqueBlock* u=(UniqueBlock*)it.c.ptr;
55 if(u->gcTo){
56 dest.vt=u->refVT;
57 dest.c=u->gcTo;
58 }else{
59 u->gc(gc);
60 dest.vt=u->refVT;
61 dest.c=u->gcTo;
65 m4_define(«PP_VTABLE_UNIQUE»,«PP_VTABLE_SET(«copyable»,«1») PP_VTABLE_SET(«gcInto»,«&gcIntoUnique») PP_VTABLE_SET(«gc»,«&gcDef<&gcIntoUnique>»)»)