Add <functional> to files that use std::function
[lsnes.git] / include / library / loadlib.hpp
blobf5e11e043aa5bb6e7c99592a40d3583f31c648f4
1 #ifndef _library__loadlib__hpp__included__
2 #define _library__loadlib__hpp__included__
4 #include <functional>
5 #include <string>
6 #include <stdexcept>
7 #include <map>
8 #include <set>
9 #include "threads.hpp"
11 namespace loadlib
13 threads::lock& global_mutex();
15 /**
16 * A loaded library.
18 class library
20 public:
21 /**
22 * Construct a NULL library.
24 library()
26 lib = NULL;
28 /**
29 * Load a new library.
31 * Parameter filename: The name of file.
32 * Throws std::bad_alloc: Not enough memory.
33 * Throws std::runtime_error: Error loading shared library.
35 library(const std::string& filename) throw(std::bad_alloc, std::runtime_error)
37 try {
38 set_loading(this);
39 lib = new internal(filename);
40 set_loading(NULL);
41 } catch(...) {
42 set_loading(NULL);
43 throw;
46 /**
47 * Unload a library.
49 ~library() throw()
51 threads::alock h(global_mutex());
52 if(lib && !--lib->refs)
53 delete lib;
55 /**
56 * Look up a symbol.
58 * Parameter symbol: The symbol to look up.
59 * Returns: The symbol value.
60 * Throws std::bad_alloc: Not enough memory.
61 * Throws std::runtime_error: Error looking up the symbol.
63 void* operator[](const std::string& symbol) const throw(std::bad_alloc, std::runtime_error)
65 threads::alock h(global_mutex());
66 if(!lib) throw std::runtime_error("Symbol '" + symbol + "' not found");
67 return (*lib)[symbol];
69 /**
70 * See what libraries are called on this platform.
72 * Returns: The name of library.
74 static const std::string& name() throw();
75 /**
76 * See what standard library extension is on this platform.
78 * Returns: The extension of library.
80 static const std::string& extension() throw();
81 /**
82 * Copy ctor.
84 library(const library& r)
86 threads::alock h(global_mutex());
87 lib = r.lib;
88 if(lib) ++lib->refs;
90 library& operator=(const library& r)
92 if(lib == r.lib)
93 return *this;
94 threads::alock h(global_mutex());
95 if(lib && !--lib->refs)
96 delete lib;
97 lib = r.lib;
98 if(lib) ++lib->refs;
99 return *this;
101 std::string get_libname() const { return lib->libname; }
102 void mark(const void* obj) const { if(lib) lib->mark(obj); }
103 bool is_marked(const void* obj) const { return lib ? lib->is_marked(obj) : false; }
105 * Get currently loading library, or NULL if nothing is loading.
107 static library* loading() throw();
108 private:
109 void set_loading(library* lib) throw(std::bad_alloc);
110 struct internal
112 internal(const std::string& filename) throw(std::bad_alloc, std::runtime_error);
113 ~internal() throw();
114 void* operator[](const std::string& symbol) const throw(std::bad_alloc, std::runtime_error);
115 internal(const internal&);
116 internal& operator=(const internal&);
117 void* handle;
118 size_t refs;
119 std::string libname;
120 void mark(const void* obj) { marked.insert(obj); }
121 bool is_marked(const void* obj) { return marked.count(obj); }
122 std::set<const void*> marked;
124 mutable internal* lib;
128 * A program module.
130 class module
132 template<typename T, typename... U> struct fntype { typedef T(*t)(U...); };
133 public:
135 * Symbol definition.
137 struct symbol
139 const char* name;
140 void* address;
143 * Construct a module from list of symbols.
145 module(std::initializer_list<symbol> symbols, std::function<void(const module&)> init_fn);
147 * Construct a module from library.
149 module(library lib);
151 * Copy ctor
153 module(const module& mod);
155 * Dtor.
157 ~module();
159 * Symbol lookup.
161 void* operator[](const std::string& symbol) const throw(std::bad_alloc, std::runtime_error);
163 * Variable symbol lookup.
165 template<typename T> T* var(const std::string& symbol) const throw(std::bad_alloc, std::runtime_error)
167 return (T*)(*this)[symbol];
170 * Function symbol lookup.
172 template<typename T, typename... U> typename fntype<T, U...>::t fn(const std::string& symbol) const
173 throw(std::bad_alloc, std::runtime_error)
175 return (typename fntype<T, U...>::t)(*this)[symbol];
178 * Get name.
180 std::string get_libname() const { return libname; }
182 * Run all not ran initialization functions.
184 static void run_initializers();
186 * Mark object (only works for libraries).
188 void mark(const void* obj) const { if(dynamic) lib.mark(obj); }
190 * Is object marked (only works for libraries)?
192 bool is_marked(const void* obj) const { return dynamic ? lib.is_marked(obj) : false; }
193 private:
194 bool dynamic;
195 library lib;
196 std::map<std::string, void*> symbols;
197 std::function<void(const module&)> init;
198 std::string libname;
202 #endif