summaryrefslogtreecommitdiffabout
path: root/lib/pointer_map.cc
Unidiff
Diffstat (limited to 'lib/pointer_map.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/pointer_map.cc74
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/pointer_map.cc b/lib/pointer_map.cc
new file mode 100644
index 0000000..44f7ebc
--- a/dev/null
+++ b/lib/pointer_map.cc
@@ -0,0 +1,74 @@
1#include <cassert>
2#include <map>
3#include <string>
4using namespace std;
5#include "konforka/exception.h"
6#include "konforka/pointer_map.h"
7
8namespace konforka {
9
10 /*
11 * to_t->from_t->from->to
12 */
13 class mpointer_t {
14 public:
15 void *ptr;
16 int ref;
17
18 mpointer_t() : ptr(0), ref(0) { }
19
20 void _ref() { ref++; }
21 void _unref() { ref--; }
22 };
23 typedef map<void*,mpointer_t> map_ptr_1_t;
24 typedef map<string,map_ptr_1_t> map_ptr_2_t;
25 typedef map<string,map_ptr_2_t> map_ptr_t;
26
27 static map_ptr_t pointer_map;
28
29 void _map_pointer(const type_info& tf,void *pf,const type_info& tt,void *pt) {
30 mpointer_t& mpt = pointer_map[tf.name()][tt.name()][pf];
31 if(mpt.ref) {
32 if(mpt.ptr != pt)
33 throw exception(CODEPOINT,"trying to remap existing pointer with different value");
34 }else{
35 mpt.ptr = pt;
36 }
37 mpt.ref++;
38 }
39 void _unmap_pointer(const type_info& tf,void *pf,const type_info& tt,void *pt) {
40 map_ptr_t::iterator i1 = pointer_map.find(tf.name());
41 if(i1==pointer_map.end())
42 throw exception(CODEPOINT,"no pointer of such type has ever been mapped");
43 map_ptr_2_t::iterator i2 = i1->second.find(tt.name());
44 if(i2==i1->second.end())
45 throw exception(CODEPOINT,"no pointer has ever been mapped to the object of this type");
46 map_ptr_1_t::iterator i3 = i2->second.find(pf);
47 if(i3==i2->second.end())
48 throw exception(CODEPOINT,"this pointer has never been mapped");
49 assert(i3->second.ref>0);
50 if(--(i3->second.ref))
51 return;
52 i2->second.erase(i3);
53 if(!i2->second.empty())
54 return;
55 i1->second.erase(i2);
56 if(!i1->second.empty())
57 return;
58 pointer_map.erase(i1);
59 }
60 void *_mapped_pointer(const type_info& tf,void *pf,const type_info& tt) {
61 map_ptr_t::iterator i1 = pointer_map.find(tf.name());
62 if(i1==pointer_map.end())
63 throw exception(CODEPOINT,"no pointer of such type has ever been mapped");
64 map_ptr_2_t::iterator i2 = i1->second.find(tt.name());
65 if(i2==i1->second.end())
66 throw exception(CODEPOINT,"no pointer has ever been mapped to the object of this type");
67 map_ptr_1_t::iterator i3 = i2->second.find(pf);
68 if(i3==i2->second.end())
69 throw exception(CODEPOINT,"this pointer has never been mapped");
70 assert(i3->second.ref>0);
71 return i3->second.ptr;
72 }
73
74}