JoshDreamland icon

plugin_ptr.hpp

JoshDreamland | PRO | 09/27/14 04:28:53 PM UTC | 0 ⭐ | 377 👁️ | Never ⏰ | []
C++ |

2.7 KB

|

None

|

0 👍

/

0 👎

/* Copyright (c) 2014 Josh Ventura
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
 
#ifndef PLUGIN_PTR_H
#define PLUGIN_PTR_H
#include <memory>
#include <list>
#include <thread>
 
template<class T, class Plugin> class plugin_ptr;
 
namespace plugin_ptr_garbage {
  class collecter {
   public:
    virtual ~collecter() {}
  };
  template<class Plugin> class plugin_ptr_list {
    // If you use this file from more than one source,
    // these must be moved into each Plugin class:
    static size_t global_reference_count;
    static std::list<collecter*> all_pointers;
    
    static void add(collecter *who) {
      all_pointers.push_back(who);
    }
    static void collect() {
      for (std::list<collecter*>::iterator it = all_pointers.begin();
          it != all_pointers.end(); ++it) {
        delete *it;
      }
      all_pointers.clear();
      while (global_reference_count) {
        std::this_thread::yield();
      }
    }
    
    template<class T, class P> friend class plugin_ptr;
    template<class P> friend void collect(P *);
  };
  
  // If you use this file from more than one source, delete these.
  template<class Plugin>
      size_t plugin_ptr_list<Plugin>::global_reference_count;
  template<class Plugin>
      std::list<collecter*> plugin_ptr_list<Plugin>::all_pointers;
  
  // Call this to clean up
  template<class Plugin> void collect(Plugin *) {
    plugin_ptr_list<Plugin>::collect();
  }
}
 
template<class T, class Plugin> class plugin_ptr:
    plugin_ptr_garbage::collecter {
  class deleter {
   public:
    void operator() (T* t) {
      delete t;
      --plugin_ptr_garbage::plugin_ptr_list<Plugin>::global_reference_count;
    }
  };
 
  std::shared_ptr<T> data_share;
 
 public:
 
  plugin_ptr(T* data): data_share(data, deleter()) {
    ++plugin_ptr_garbage::plugin_ptr_list<Plugin>::global_reference_count;
    plugin_ptr_garbage::plugin_ptr_list<Plugin>::add(this);
  }
 
  std::weak_ptr<T> get_pointer() const {
    return std::weak_ptr<T>(data_share);
  }
  
  ~plugin_ptr() {}
};
 
#endif // PLUGIN_PTR_H

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎