/* 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 . */ #ifndef PLUGIN_PTR_H #define PLUGIN_PTR_H #include #include #include template class plugin_ptr; namespace plugin_ptr_garbage { class collecter { public: virtual ~collecter() {} }; template 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 all_pointers; static void add(collecter *who) { all_pointers.push_back(who); } static void collect() { for (std::list::iterator it = all_pointers.begin(); it != all_pointers.end(); ++it) { delete *it; } all_pointers.clear(); while (global_reference_count) { std::this_thread::yield(); } } template friend class plugin_ptr; template friend void collect(P *); }; // If you use this file from more than one source, delete these. template size_t plugin_ptr_list::global_reference_count; template std::list plugin_ptr_list::all_pointers; // Call this to clean up template void collect(Plugin *) { plugin_ptr_list::collect(); } } template class plugin_ptr: plugin_ptr_garbage::collecter { class deleter { public: void operator() (T* t) { delete t; --plugin_ptr_garbage::plugin_ptr_list::global_reference_count; } }; std::shared_ptr data_share; public: plugin_ptr(T* data): data_share(data, deleter()) { ++plugin_ptr_garbage::plugin_ptr_list::global_reference_count; plugin_ptr_garbage::plugin_ptr_list::add(this); } std::weak_ptr get_pointer() const { return std::weak_ptr(data_share); } ~plugin_ptr() {} }; #endif // PLUGIN_PTR_H