/******************************************************************************/
/* DYNAMIC LIBRARIES **********************************************************/
/******************************************************************************/

#ifndef _H_EBCL_DYNLIB
#define _H_EBCL_DYNLIB

#include <ebcl/Strings.hh>
#include <ebcl/Utilities.hh>
namespace ebcl {


/*= DYNAMIC LIBRARY SUPPORT ==================================================*/

class T_DynLib : public A_PrivateImplementation
{
    public:
	T_DynLib( ) = delete;
	T_DynLib( T_DynLib const& ) = delete;
	T_DynLib& operator =( T_DynLib const& ) = delete;

	/* Initialise and set the name of the library to load */
	explicit T_DynLib( T_String const& name );
	explicit T_DynLib( char const* const name );

	/* Load/unload the library */
	bool load( );
	void unload( );

	/* Check whether the library has been loaded */
	bool isLoaded( ) const noexcept;
	/* Obtain the last error that was encoutered */
	T_String lastError( ) const noexcept;

	/* Symbol access. The library MUST be loaded. */
	void* getRawSymbol( char const* name ) const noexcept;
	template< typename T >
		T* getPointer( char const* name ) const noexcept;
	template< typename T >
		std::function< T > getFunction(
				char const* name ) const noexcept;
};
M_CLASS_POINTERS( DynLib );


} // namespace lw
#endif // _H_EBCL_DYNLIB
#include <ebcl/inline/DynLib.hh>