Advertisement
Guest User

Untitled

a guest
Sep 26th, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.06 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <boost/utility.hpp>
  4. #include <set>
  5. #include <map>
  6.  
  7. //! A map of types to values.
  8. //!
  9. //! Associative container which allows mapping of types to values of that
  10. //! type.
  11. class TypeMap : boost::noncopyable {
  12. typedef void (*destruct_func)(void*);
  13. class TypeMapStaticInstance : boost::noncopyable {
  14. destruct_func destroy_;
  15. std::map<TypeMap const*, void*> map_;
  16.  
  17. public:
  18. TypeMapStaticInstance(destruct_func f)
  19. : destroy_(f) {}
  20.  
  21. void*& get(TypeMap const* tm) {
  22. return map_[tm];
  23. }
  24.  
  25. void const* cget(TypeMap const* tm) const {
  26. auto element = map_.find(tm);
  27. if (element != map_.end())
  28. return element->second;
  29. return nullptr;
  30. }
  31.  
  32. void remove(TypeMap const* tm) {
  33. auto element = map_.find(tm);
  34. destroy_(element->second);
  35. map_.erase(element);
  36. }
  37. };
  38.  
  39. template<typename T>
  40. class TypeMapDetail {
  41. TypeMapDetail() = delete;
  42.  
  43. static void destroy_impl(void* p) {
  44. delete static_cast<T*>(p);
  45. }
  46.  
  47. public:
  48. static TypeMapStaticInstance map_;
  49.  
  50. static T& get(TypeMap const* p) {
  51. auto& element = map_.get(p);
  52. if (!element)
  53. element = new T();
  54. return *static_cast<T*>(element);
  55. }
  56.  
  57. static T const* cget(TypeMap const* p) {
  58. return static_cast<T const*>(map_.cget(p));
  59. }
  60. };
  61.  
  62. std::set<TypeMapStaticInstance*> members_;
  63. public:
  64. //! Retrieve the data associated with the given type.
  65. template<typename T>
  66. T& get() {
  67. members_.insert(&TypeMapDetail<T>::map_);
  68. return TypeMapDetail<T>::get(this);
  69. }
  70.  
  71. template<typename T>
  72. T const* cget() const {
  73. return TypeMapDetail<T>::cget(this);
  74. }
  75.  
  76. ~TypeMap() {
  77. for (auto m : members_) {
  78. m->remove(this);
  79. }
  80. }
  81. };
  82.  
  83. template<typename T>
  84. TypeMap::TypeMapStaticInstance TypeMap::TypeMapDetail<T>::map_(TypeMap::TypeMapDetail<T>::destroy_impl);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement