#include #include #include 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 map_ptr_1_t; typedef map map_ptr_2_t; typedef map 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; } }