Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
482 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* This software is distributed under BSD 3-clause license (see LICENSE file). | ||
* | ||
* Authors: Sergey Lisitsyn, Sanuj Sharma | ||
*/ | ||
|
||
#include <shogun/base/library.h> | ||
#include <shogun/lib/common.h> | ||
|
||
namespace shogun | ||
{ | ||
class LibraryHandle : public CSGObject | ||
{ | ||
public: | ||
LibraryHandle(const std::string& filename) | ||
{ | ||
dlerror(); | ||
handle = dlopen(filename.c_str(), RTLD_NOW | RTLD_LOCAL); | ||
if (handle) | ||
{ | ||
SG_INFO("Loaded.\n"); | ||
} | ||
else | ||
{ | ||
SG_ERROR("Failed: %s.\n", dlerror()); | ||
} | ||
} | ||
|
||
~LibraryHandle() | ||
{ | ||
if (handle) | ||
{ | ||
SG_INFO("Closing library.\n"); | ||
dlclose(handle); | ||
} | ||
} | ||
|
||
template <typename T> | ||
T call(const std::string& name) | ||
{ | ||
dlerror(); | ||
T (*fm)(); | ||
*(void**)(&fm) = dlsym(handle, name.c_str()); | ||
char* potential_error = dlerror(); | ||
if (potential_error) | ||
SG_ERROR("Failed: %s.\n", potential_error); | ||
return fm(); | ||
} | ||
|
||
const char* get_name() const | ||
{ | ||
return "LibraryHandle"; | ||
} | ||
|
||
private: | ||
void* handle; | ||
|
||
}; | ||
|
||
Library::Library(const std::string& filename) : | ||
m_handle(some<LibraryHandle>(filename)) | ||
{ | ||
} | ||
|
||
Library::Library(const Library& other) : | ||
m_handle(Some<LibraryHandle>(other.m_handle)) | ||
{ | ||
} | ||
|
||
Library& Library::operator=(const Library& other) | ||
{ | ||
m_handle = other.m_handle; | ||
return *this; | ||
} | ||
|
||
bool operator==(const Library& first, const Library& second) | ||
{ | ||
Some<LibraryHandle> first_handle = first.m_handle; | ||
Some<LibraryHandle> second_handle = second.m_handle; | ||
return first_handle == second_handle; | ||
} | ||
|
||
bool operator!=(const Library& first, const Library& second) | ||
{ | ||
return !(first == second); | ||
} | ||
|
||
Library::~Library() | ||
{ | ||
} | ||
|
||
Manifest Library::manifest() | ||
{ | ||
return m_handle->call<Manifest>(manifest_accessor_name); | ||
} | ||
|
||
Library load_library(const std::string& filename) | ||
{ | ||
return Library(filename); | ||
} | ||
|
||
const char* Library::manifest_accessor_name = "shogunManifest"; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* This software is distributed under BSD 3-clause license (see LICENSE file). | ||
* | ||
* Authors: Sergey Lisitsyn, Sanuj Sharma | ||
*/ | ||
|
||
#ifndef _LIBRARY_H_ | ||
#define _LIBRARY_H_ | ||
|
||
#include <shogun/base/manifest.h> | ||
#include <shogun/base/SGObject.h> | ||
#include <string> | ||
#include <dlfcn.h> | ||
|
||
namespace shogun | ||
{ | ||
|
||
/** @brief | ||
* Handles loading, calling and closing of plugins from shared object files. | ||
*/ | ||
class LibraryHandle; | ||
|
||
/** @brief | ||
* Provides an API for loading plugins as objects of this class | ||
* and accessing Manifest of the loaded plugins. | ||
* Uses LibraryHandle under the hood. | ||
*/ | ||
class Library | ||
{ | ||
public: | ||
/** Constructor to initialize library | ||
* @param filename name of shared object file | ||
*/ | ||
Library(const std::string& filename); | ||
|
||
/** Copy constructor | ||
* @param other library object to be copied | ||
*/ | ||
Library(const Library& other); | ||
|
||
/** Class Assignment operator | ||
* @param other library object to be assigned | ||
*/ | ||
Library& operator=(const Library& other); | ||
|
||
/** Equality operator | ||
* @param first first Library | ||
* @param second second Library | ||
*/ | ||
friend bool operator==(const Library& first, const Library& second); | ||
|
||
/** Inequality operator | ||
* @param first first Library | ||
* @param second second Library | ||
*/ | ||
friend bool operator!=(const Library& first, const Library& second); | ||
|
||
/** Destructor */ | ||
~Library(); | ||
|
||
/** @return manifest of loaded library */ | ||
Manifest manifest(); | ||
|
||
/** @return name of function that accesses Manifest | ||
* of loaded library. | ||
*/ | ||
static const char* get_manifest_accessor_name() | ||
{ | ||
return manifest_accessor_name; | ||
} | ||
|
||
private: | ||
static const char* manifest_accessor_name; | ||
Some<LibraryHandle> m_handle; | ||
|
||
}; | ||
|
||
/** Loads a plugin into a library object. | ||
* @param filename name of shared object file | ||
* @return library object of loaded plugin | ||
*/ | ||
Library load_library(const std::string& filename); | ||
|
||
} | ||
|
||
#endif //_LIBRARY_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* This software is distributed under BSD 3-clause license (see LICENSE file). | ||
* | ||
* Authors: Sergey Lisitsyn, Sanuj Sharma | ||
*/ | ||
|
||
#include <shogun/base/manifest.h> | ||
#include <shogun/io/SGIO.h> | ||
|
||
#include <unordered_map> | ||
|
||
namespace shogun | ||
{ | ||
|
||
class Manifest::Self | ||
{ | ||
public: | ||
std::string description; | ||
std::unordered_map<std::string, Any> classes; | ||
}; | ||
|
||
Manifest::Manifest(const std::string& description, | ||
const std::initializer_list<std::pair<std::string,Any>> classes) : | ||
self() | ||
{ | ||
self->description = description; | ||
for (const auto& m : classes) | ||
add_class(m.first, m.second); | ||
} | ||
|
||
Manifest::Manifest(const Manifest& other) : | ||
self() | ||
{ | ||
self->description = other.self->description; | ||
self->classes = other.self->classes; | ||
} | ||
|
||
Manifest& Manifest::operator=(const Manifest& other) | ||
{ | ||
self->description = other.self->description; | ||
self->classes = other.self->classes; | ||
return *this; | ||
} | ||
|
||
bool operator==(const Manifest& first, const Manifest& second) | ||
{ | ||
return (first.self->description == second.self->description) | ||
and (first.self->classes == second.self->classes); | ||
} | ||
|
||
bool operator!=(const Manifest& first, const Manifest& second) | ||
{ | ||
return !(first == second); | ||
} | ||
|
||
Manifest::~Manifest() | ||
{ | ||
} | ||
|
||
std::string Manifest::description() const | ||
{ | ||
return self->description; | ||
} | ||
|
||
void Manifest::add_class(const std::string& name, Any clazz) | ||
{ | ||
self->classes[name] = clazz; | ||
} | ||
|
||
Any Manifest::find_class(const std::string& name) const | ||
{ | ||
if (!self->classes.count(name)) | ||
SG_SERROR("MetaClass corresponding to the name '%s' couldn't be found.\n", name.c_str()); | ||
return self->classes.at(name); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* | ||
* This software is distributed under BSD 3-clause license (see LICENSE file). | ||
* | ||
* Authors: Sergey Lisitsyn, Sanuj Sharma | ||
*/ | ||
|
||
#ifndef _MANIFEST_H_ | ||
#define _MANIFEST_H_ | ||
|
||
#include <shogun/base/metaclass.h> | ||
#include <shogun/base/unique.h> | ||
#include <shogun/base/some.h> | ||
|
||
namespace shogun | ||
{ | ||
|
||
class Library; | ||
|
||
/** @brief Manifest stores meta-data of Library. | ||
* Each manifest has description and a set of meta-classes | ||
* (see @ref MetaClass) which are responsible for | ||
* creating instances of exported classes. | ||
*/ | ||
class Manifest | ||
{ | ||
public: | ||
/** Constructor to initialize hash from name | ||
* @param description description for the Library | ||
* @param metaclasses list of meta-classes for exported classes | ||
*/ | ||
Manifest(const std::string& description, | ||
const std::initializer_list<std::pair<std::string,Any>> metaclasses); | ||
|
||
/** Copy constructor | ||
* @param other Manifest object to be copied | ||
*/ | ||
Manifest(const Manifest& other); | ||
|
||
/** Class Assignment operator | ||
* @param other manifest object to be assigned | ||
*/ | ||
Manifest& operator=(const Manifest& other); | ||
|
||
/** Equality operator | ||
* @param first first Manifest | ||
* @param second second Manifest | ||
*/ | ||
friend bool operator==(const Manifest& first, const Manifest& second); | ||
|
||
/** Inequality operator | ||
* @param first first Manifest | ||
* @param second second Manifest | ||
*/ | ||
friend bool operator!=(const Manifest& first, const Manifest& second); | ||
|
||
/** Destructor */ | ||
~Manifest(); | ||
|
||
/** Returns meta-class by its name. | ||
* | ||
* @param name name of meta-class to obtain | ||
* @return object of meta-class | ||
*/ | ||
template <typename T> | ||
MetaClass<T> class_by_name(const std::string& name) const | ||
{ | ||
Any clazz = find_class(name); | ||
return any_cast<MetaClass<T>>(clazz); | ||
} | ||
|
||
/** @return description stored in the manifest. */ | ||
std::string description() const; | ||
|
||
protected: | ||
/** Adds mapping from class name to MetaClass object of | ||
* class (stored as Any object) corresponding to the name. | ||
* The map is stored in Self. | ||
* @param name name for class | ||
* @param clazz class | ||
*/ | ||
void add_class(const std::string& name, Any clazz); | ||
|
||
/** Finds MetaClass object (stored as Any object) of class | ||
* corresponding to the input name. | ||
* @param name name for class | ||
* @return | ||
*/ | ||
Any find_class(const std::string& name) const; | ||
|
||
private: | ||
class Self; | ||
Unique<Self> self; | ||
}; | ||
|
||
/** Starts manifest declaration with its description. | ||
* Always immediately follow this macro with | ||
* @ref EXPORT or @ref END_MANIFEST. | ||
*/ | ||
#define BEGIN_MANIFEST(DESCRIPTION) \ | ||
extern "C" Manifest shogunManifest() \ | ||
{ \ | ||
static Manifest manifest(DESCRIPTION,{ \ | ||
|
||
/** Declares class to be exported. | ||
* Always use this macro between @ref BEGIN_MANIFEST and | ||
* @ref END_MANIFEST | ||
*/ | ||
#define EXPORT(CLASSNAME, BASE_CLASSNAME, IDENTIFIER) \ | ||
std::make_pair(IDENTIFIER, erase_type( \ | ||
MetaClass<BASE_CLASSNAME>(erase_type( \ | ||
std::function<Some<BASE_CLASSNAME>()>( \ | ||
[]() -> Some<BASE_CLASSNAME> \ | ||
{ \ | ||
return Some<BASE_CLASSNAME>(new CLASSNAME); \ | ||
} \ | ||
))))), \ | ||
|
||
/** Ends manifest declaration. | ||
* Always use this macro after @ref BEGIN_MANIFEST | ||
*/ | ||
#define END_MANIFEST() \ | ||
}); \ | ||
return manifest; \ | ||
} | ||
|
||
} | ||
|
||
#endif //_MANIFEST_H_ |
Oops, something went wrong.