/* 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
0 B
|👍
/👎