00001 #ifndef CLASSLIB_AUTO_LOAD_H
00002 # define CLASSLIB_AUTO_LOAD_H
00003
00004
00005
00006 # include "classlib/utils/SharedLibrary.h"
00007 # include "classlib/utils/Error.h"
00008
00009 namespace lat {
00010
00011
00012
00013
00014
00015
00016
00018 class AutoLoadLib
00019 {
00020 public:
00021 AutoLoadLib (const char *libname);
00022
00023
00024
00025
00026 bool exists (void);
00027 SharedLibrary *library (void);
00028 SharedLibrary::Function function (const char *symname);
00029 SharedLibrary::Data data (const char *symname);
00030
00031 private:
00032 const char *m_libname;
00033 SharedLibrary *m_library;
00034 };
00035
00037 class AutoLoadError : public Error
00038 {
00039 public:
00040 AutoLoadError (const char *lib, const char *sym, Error *next = 0);
00041
00042 virtual std::string explainSelf (void) const;
00043 virtual Error * clone (void) const;
00044 virtual void rethrow (void);
00045
00046 private:
00047 const char *m_libname;
00048 const char *m_symname;
00049 };
00050
00063 template <class Type>
00064 class AutoLoad
00065 {
00066 public:
00067 AutoLoad (AutoLoadLib &library, const char *symname);
00068
00069
00070
00071
00072 bool exists (void);
00073 Type & operator* (void);
00074 Type * operator-> (void);
00075
00076 private:
00077 void loadme (void);
00078
00079 AutoLoadLib & m_library;
00080 const char *m_symname;
00081 Type *m_symbol;
00082 };
00083
00084
00085
00086
00087
00088
00089
00090
00091 template <class Type>
00092 inline Type *
00093 AutoLoadLookup (AutoLoadLib &lib, const char *symbol, void *)
00094 { return (Type *) lib.data (symbol); }
00095
00096 template <class Type>
00097 inline Type *
00098 AutoLoadLookup (AutoLoadLib &lib, const char *symbol, ...)
00099 { return (Type *) lib.function (symbol); }
00100
00101
00102
00105 template <class Type>
00106 inline
00107 AutoLoad<Type>::AutoLoad (AutoLoadLib &library, const char *funcname)
00108 : m_library (library),
00109 m_symname (funcname),
00110 m_symbol (0)
00111 {}
00112
00116 template <class Type>
00117 inline void
00118 AutoLoad<Type>::loadme (void)
00119 { if (! m_symbol) m_symbol = AutoLoadLookup<Type> (m_library, m_symname, (Type *) 0); }
00120
00123 template <class Type>
00124 inline bool
00125 AutoLoad<Type>::exists (void)
00126 { try { loadme (); } catch (AutoLoadError &) {} return m_symbol; }
00127
00131 template <class Type>
00132 inline Type &
00133 AutoLoad<Type>::operator* (void)
00134 { loadme (); return *m_symbol; }
00135
00139 template <class Type>
00140 inline Type *
00141 AutoLoad<Type>::operator-> (void)
00142 { loadme (); return m_symbol; }
00143
00144 }
00145 #endif // CLASSLIB_AUTO_LOAD_H