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
|
#include <cassert>
#include <map>
#include <string>
using namespace std;
#include "konforka/exception.h"
#include "konforka/pointer_map.h"
namespace konforka {
/*
* to_t->from_t->from->to
*/
class mpointer_t {
public:
void *ptr;
int ref;
mpointer_t() : ptr(0), ref(0) { }
void _ref() { ref++; }
void _unref() { ref--; }
};
typedef map<void*,mpointer_t> map_ptr_1_t;
typedef map<string,map_ptr_1_t> map_ptr_2_t;
typedef map<string,map_ptr_2_t> map_ptr_t;
static map_ptr_t pointer_map;
void _map_pointer(const type_info& tf,void *pf,const type_info& tt,void *pt) {
mpointer_t& mpt = pointer_map[tf.name()][tt.name()][pf];
if(mpt.ref) {
if(mpt.ptr != pt)
throw exception(CODEPOINT,"trying to remap existing pointer with different value");
}else{
mpt.ptr = pt;
}
mpt.ref++;
}
void _unmap_pointer(const type_info& tf,void *pf,const type_info& tt,void *pt) {
map_ptr_t::iterator i1 = pointer_map.find(tf.name());
if(i1==pointer_map.end())
throw exception(CODEPOINT,"no pointer of such type has ever been mapped");
map_ptr_2_t::iterator i2 = i1->second.find(tt.name());
if(i2==i1->second.end())
throw exception(CODEPOINT,"no pointer has ever been mapped to the object of this type");
map_ptr_1_t::iterator i3 = i2->second.find(pf);
if(i3==i2->second.end())
throw exception(CODEPOINT,"this pointer has never been mapped");
assert(i3->second.ref>0);
if(--(i3->second.ref))
return;
i2->second.erase(i3);
if(!i2->second.empty())
return;
i1->second.erase(i2);
if(!i1->second.empty())
return;
pointer_map.erase(i1);
}
void *_mapped_pointer(const type_info& tf,void *pf,const type_info& tt) {
map_ptr_t::iterator i1 = pointer_map.find(tf.name());
if(i1==pointer_map.end())
throw exception(CODEPOINT,"no pointer of such type has ever been mapped");
map_ptr_2_t::iterator i2 = i1->second.find(tt.name());
if(i2==i1->second.end())
throw exception(CODEPOINT,"no pointer has ever been mapped to the object of this type");
map_ptr_1_t::iterator i3 = i2->second.find(pf);
if(i3==i2->second.end())
throw exception(CODEPOINT,"this pointer has never been mapped");
assert(i3->second.ref>0);
return i3->second.ptr;
}
}
|