Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <boost/utility.hpp>
- #include <set>
- #include <map>
- //! A map of types to values.
- //!
- //! Associative container which allows mapping of types to values of that
- //! type.
- class TypeMap : boost::noncopyable {
- typedef void (*destruct_func)(void*);
- class TypeMapStaticInstance : boost::noncopyable {
- destruct_func destroy_;
- std::map<TypeMap const*, void*> map_;
- public:
- TypeMapStaticInstance(destruct_func f)
- : destroy_(f) {}
- void*& get(TypeMap const* tm) {
- return map_[tm];
- }
- void const* cget(TypeMap const* tm) const {
- auto element = map_.find(tm);
- if (element != map_.end())
- return element->second;
- return nullptr;
- }
- void remove(TypeMap const* tm) {
- auto element = map_.find(tm);
- destroy_(element->second);
- map_.erase(element);
- }
- };
- template<typename T>
- class TypeMapDetail {
- TypeMapDetail() = delete;
- static void destroy_impl(void* p) {
- delete static_cast<T*>(p);
- }
- public:
- static TypeMapStaticInstance map_;
- static T& get(TypeMap const* p) {
- auto& element = map_.get(p);
- if (!element)
- element = new T();
- return *static_cast<T*>(element);
- }
- static T const* cget(TypeMap const* p) {
- return static_cast<T const*>(map_.cget(p));
- }
- };
- std::set<TypeMapStaticInstance*> members_;
- public:
- //! Retrieve the data associated with the given type.
- template<typename T>
- T& get() {
- members_.insert(&TypeMapDetail<T>::map_);
- return TypeMapDetail<T>::get(this);
- }
- template<typename T>
- T const* cget() const {
- return TypeMapDetail<T>::cget(this);
- }
- ~TypeMap() {
- for (auto m : members_) {
- m->remove(this);
- }
- }
- };
- template<typename T>
- TypeMap::TypeMapStaticInstance TypeMap::TypeMapDetail<T>::map_(TypeMap::TypeMapDetail<T>::destroy_impl);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement