access_byid.h
上传用户:kx_jwh
上传日期:2021-09-03
资源大小:76k
文件大小:5k
源码类别:

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #ifndef __febird_io_id_generator_h__
  3. #define __febird_io_id_generator_h__
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. #include "../config.h"
  8. #include <assert.h>
  9. #include <vector>
  10. #include <map>
  11. #if defined(__GNUC__)
  12. # include <stdint.h>
  13. #endif
  14. #if defined(linux) || defined(__linux) || defined(__linux__)
  15. # include <linux/types.h>
  16. #else
  17. # include <sys/types.h>
  18. #endif
  19. #include <boost/current_function.hpp>
  20. #include <boost/intrusive_ptr.hpp>
  21. namespace febird {
  22. class FEBIRD_DLL_EXPORT id_generator
  23. {
  24. // use free-list structure, same as memory management
  25. // id may not be 0
  26. std::vector<uintptr_t> id_list; // id_list[0] is linked list head
  27. long m_nUsed;
  28. void chain(long newHead);
  29. public:
  30. void clear() { id_list.clear(); }
  31. explicit id_generator(long maxID);
  32. virtual ~id_generator();
  33. long alloc_id();
  34. void free_id(long id);
  35. uintptr_t get_val(long id) const
  36. {
  37. assert(id >= 1);
  38. assert(id <= long(id_list.size()-1));
  39. return id_list[id];
  40. }
  41. long add_val(uintptr_t val);
  42. bool is_valid(long id) const
  43. {
  44. return id >= 1 && id <= long(id_list.size()-1);
  45. }
  46. long maxid() const { return id_list.size()-1; }
  47. long size() const { return m_nUsed; }
  48. void get_used_id(std::vector<uintptr_t>& used_id) const;
  49. };
  50. // do not allow T to be non-pointer type
  51. template<class T> class access_byid;
  52. template<> class FEBIRD_DLL_EXPORT access_byid<void*> : public id_generator
  53. {
  54. protected:
  55. virtual void on_destroy(void* vp);
  56. void* get_ptr_imp(long id, const char* func) const;
  57. using id_generator::add_val; // hide it
  58. public:
  59. access_byid(long maxID = 3) : id_generator(maxID) { }
  60. //! delete all object in list, and clear self
  61. void destroy();
  62. void* get_ptr(long id) const { return access_byid<void*>::get_ptr_imp(id, BOOST_CURRENT_FUNCTION); }
  63. long  add_ptr(void* x) { return this->add_val((uintptr_t)(x)); }
  64. };
  65. template<class T> class access_byid<T*> : public access_byid<void*>
  66. {
  67. virtual void on_destroy(void* vp) { delete (T*)vp; }
  68. public:
  69. access_byid(long maxID = 3) : access_byid<void*>(maxID) { }
  70. T* get_ptr(long id) const { return access_byid<void*>::get_ptr_imp(id, BOOST_CURRENT_FUNCTION); }
  71. long add_ptr(T* x) { return this->add_val((uintptr_t)(x)); }
  72. };
  73. template<class T> class AccessByNameID;
  74. template<> class FEBIRD_DLL_EXPORT AccessByNameID<void*>
  75. {
  76. protected:
  77. access_byid<void*> m_byid;
  78. std::map<std::string, void*> m_byname;
  79. virtual void on_destroy(void* vp);
  80. public:
  81. long add_ptr(void* x, const std::string& name, void** existed);
  82. long add_ptr(void* x) { return m_byid.add_ptr(x); }
  83. void* get_byid(long id) const { return m_byid.get_ptr(id); }
  84. void* get_byname(const std::string& name) const;
  85. bool is_valid(long id) const { return m_byid.is_valid(id); }
  86. void destroy();
  87. void remove(long id, const std::string& name);
  88. void remove(long id);
  89. long size() const { return m_byid.size(); }
  90. bool check_id(long id, const char* szClassName, std::string& err) const;
  91. };
  92. template<class T> class AccessByNameID<T*> : public AccessByNameID<void*>
  93. {
  94. virtual void on_destroy(void* vp)
  95. {
  96. delete (T*)vp;
  97. }
  98. public:
  99. long add_ptr(T* x, const std::string& name, T** existed)
  100. {
  101. return AccessByNameID<void*>::add_ptr(x, name, (void**)existed);
  102. }
  103. long add_ptr(T* x) // add without name
  104. {
  105. assert(0 != x);
  106. return m_byid.add_ptr(x);
  107. }
  108. T* get_byid(long id) const { return (T*) m_byid.get_ptr(id); }
  109. T* get_byname(const std::string& name) const
  110. {
  111. return (T*)AccessByNameID<void*>::get_byname(name);
  112. }
  113. };
  114. template<class T>
  115. class AccessByNameID<boost::intrusive_ptr<T> > : public AccessByNameID<void*>
  116. {
  117. virtual void on_destroy(void* vp)
  118. {
  119. intrusive_ptr_release((T*)vp);
  120. }
  121. public:
  122. long add_ptr(boost::intrusive_ptr<T> x, const std::string& name, boost::intrusive_ptr<T>* existed)
  123. {
  124. assert(0 != x.get());
  125. T* vpExisted;
  126. long id = AccessByNameID<void*>::add_ptr(x.get(), name, (void**)&vpExisted);
  127. if (0 == vpExisted)
  128. {
  129. intrusive_ptr_add_ref(x.get());
  130. *existed = vpExisted;
  131. }
  132. return id;
  133. }
  134. long add_ptr(boost::intrusive_ptr<T> x) // add without name
  135. {
  136. assert(0 != x.get());
  137. intrusive_ptr_add_ref(x.get());
  138. return m_byid.add_ptr(x.get());
  139. }
  140. long add_ptr(T* x, const std::string& name, T** existed)
  141. {
  142. assert(0 != x);
  143. assert(0 != existed);
  144. long id = AccessByNameID<void*>::add_ptr(x, name, (void**)existed);
  145. if (0 == *existed)
  146. intrusive_ptr_add_ref(x);
  147. return id;
  148. }
  149. long add_ptr(T* x) // add without name
  150. {
  151. assert(0 != x);
  152. intrusive_ptr_add_ref(x);
  153. return m_byid.add_ptr(x);
  154. }
  155. boost::intrusive_ptr<T> get_byid(long id) const { return (T*)m_byid.get_ptr(id); }
  156. boost::intrusive_ptr<T> get_byname(const std::string& name) const
  157. {
  158. return (T*)AccessByNameID<void*>::get_byname(name);
  159. }
  160. T* get_rawptr_byid(long id) const
  161. {
  162. return (T*)m_byid.get_ptr(id);
  163. }
  164. T* get_rawptr_byname(const std::string& name) const
  165. {
  166. return (T*)AccessByNameID<void*>::get_byname(name);
  167. }
  168. ~AccessByNameID() { destroy(); }
  169. };
  170. } // namespace febird
  171. #endif // __febird_io_id_generator_h__