Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make smart library work in C++11 mode #80

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 50 additions & 97 deletions include/boost/dll/import_class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct mem_fn_call_proxy<Class, boost::dll::experimental::detail::mangled_librar
: t(t), mem_fn(mem_fn) {}

template<typename ...Args>
auto operator()(Args&&...args) const
auto operator()(Args&&...args) const -> decltype(mem_fn(t, std::forward<Args>(args)...))
{
return mem_fn(t, std::forward<Args>(args)...);
}
Expand Down Expand Up @@ -120,11 +120,11 @@ import_class(const smart_library& lib, std::size_t size,
template<typename T>
class imported_class
{
smart_library _lib;
std::unique_ptr<T, detail::deleter<T>> _data;
bool _is_allocating;
std::size_t _size;
const std::type_info& _ti;
smart_library lib_;
std::unique_ptr<T, detail::deleter<T>> data_;
bool is_allocating_;
std::size_t size_;
const std::type_info& ti_;

template<typename ... Args>
inline std::unique_ptr<T, detail::deleter<T>> make_data(const smart_library& lib, Args ... args);
Expand Down Expand Up @@ -173,7 +173,7 @@ class imported_class

typedef imported_class<T> base_t;
///Returns a pointer to the underlying class
T* get() {return _data.get();}
T* get() {return data_.get();}
imported_class() = delete;

imported_class(imported_class&) = delete;
Expand All @@ -182,13 +182,13 @@ class imported_class
imported_class& operator=(imported_class&&) = default; ///<Move assignmend

///Check if the imported class is move-constructible
bool is_move_constructible() {return !_lib.symbol_storage().template get_constructor<T(T&&)> ().empty();}
bool is_move_constructible() {return !lib_.symbol_storage().template get_constructor<T(T&&)> ().empty();}
///Check if the imported class is move-assignable
bool is_move_assignable() {return !_lib.symbol_storage().template get_mem_fn<T, T&(T&&)> ("operator=").empty();}
bool is_move_assignable() {return !lib_.symbol_storage().template get_mem_fn<T, T&(T&&)> ("operator=").empty();}
///Check if the imported class is copy-constructible
bool is_copy_constructible() {return !_lib.symbol_storage().template get_constructor<T(const T&)>().empty();}
bool is_copy_constructible() {return !lib_.symbol_storage().template get_constructor<T(const T&)>().empty();}
///Check if the imported class is copy-assignable
bool is_copy_assignable() {return !_lib.symbol_storage().template get_mem_fn<T, T&(const T&)>("operator=").empty();}
bool is_copy_assignable() {return !lib_.symbol_storage().template get_mem_fn<T, T&(const T&)>("operator=").empty();}

imported_class<T> copy() const; ///<Invoke the copy constructor. \attention Undefined behaviour if the imported object is not copy constructible.
imported_class<T> move(); ///<Invoke the move constructor. \attention Undefined behaviour if the imported object is not move constructible.
Expand All @@ -199,10 +199,10 @@ class imported_class
void move_assign( imported_class<T> & lhs);

///Check if the class is loaded.
explicit operator bool() const {return _data;}
explicit operator bool() const {return data_;}

///Get a const reference to the std::type_info.
const std::type_info& get_type_info() {return _ti;};
const std::type_info& get_type_info() {return ti_;};

/*! Call a member function. This returns a proxy to the function.
* The proxy mechanic mechanic is necessary, so the signaute can be passed.
Expand All @@ -216,7 +216,7 @@ class imported_class
template<class Signature>
const detail::mem_fn_call_proxy<T, Signature> call(const std::string& name)
{
return detail::mem_fn_call_proxy<T, Signature>(_data.get(), name, _lib);
return detail::mem_fn_call_proxy<T, Signature>(data_.get(), name, lib_);
}
/*! Call a qualified member function, i.e. const and or volatile.
*
Expand All @@ -229,22 +229,22 @@ class imported_class
template<class Tin, class Signature, class = boost::enable_if<detail::unqalified_is_same<T, Tin>>>
const detail::mem_fn_call_proxy<Tin, Signature> call(const std::string& name)
{
return detail::mem_fn_call_proxy<Tin, Signature>(_data.get(), name, _lib);
return detail::mem_fn_call_proxy<Tin, Signature>(data_.get(), name, lib_);
}
///Overload of ->* for an imported method.
template<class Tin, class T2>
const detail::mem_fn_call_proxy<Tin, boost::dll::experimental::detail::mangled_library_mem_fn<Tin, T2>>
operator->*(detail::mangled_library_mem_fn<Tin, T2>& mn)
{
return detail::mem_fn_call_proxy<Tin, boost::dll::experimental::detail::mangled_library_mem_fn<Tin, T2>>(_data.get(), mn);
return detail::mem_fn_call_proxy<Tin, boost::dll::experimental::detail::mangled_library_mem_fn<Tin, T2>>(data_.get(), mn);
}

///Import a method of the class.
template <class ...Args>
typename boost::dll::experimental::detail::mangled_import_type<boost::dll::experimental::detail::sequence<T, Args...>>::type
import(const std::string & name)
{
return boost::dll::experimental::import_mangled<T, Args...>(_lib, name);
return boost::dll::experimental::import_mangled<T, Args...>(lib_, name);
}
};

Expand Down Expand Up @@ -313,79 +313,79 @@ inline std::unique_ptr<T, detail::deleter<T>> imported_class<T>::make_data(const
template<typename T>
template<typename ...Args>
imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_library & lib, Args...args)
: _lib(lib),
_data(make_data<Args...>(lib, static_cast<Args>(args)...)),
_is_allocating(false),
_size(0),
_ti(lib.get_type_info<T>())
: lib_(lib),
data_(make_data<Args...>(lib_, static_cast<Args>(args)...)),
is_allocating_(false),
size_(0),
ti_(lib.get_type_info<T>())
{

}

template<typename T>
template<typename ...Args>
imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_library & lib, std::size_t size, Args...args)
: _lib(lib),
_data(make_data<Args...>(lib, size, static_cast<Args>(args)...)),
_is_allocating(true),
_size(size),
_ti(lib.get_type_info<T>())
: lib_(lib),
data_(make_data<Args...>(lib_, size, static_cast<Args>(args)...)),
is_allocating_(true),
size_(size),
ti_(lib.get_type_info<T>())
{

}

template<typename T>
template<typename ...Args>
imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library && lib, Args...args)
: _lib(std::move(lib)),
_data(make_data<Args...>(lib, static_cast<Args>(args)...)),
_is_allocating(false),
_size(0),
_ti(lib.get_type_info<T>())
: lib_(std::move(lib)),
data_(make_data<Args...>(lib_, static_cast<Args>(args)...)),
is_allocating_(false),
size_(0),
ti_(lib.get_type_info<T>())
{

}

template<typename T>
template<typename ...Args>
imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library && lib, std::size_t size, Args...args)
: _lib(std::move(lib)),
_data(make_data<Args...>(lib, size, static_cast<Args>(args)...)),
_is_allocating(true),
_size(size),
_ti(lib.get_type_info<T>())
: lib_(std::move(lib)),
data_(make_data<Args...>(lib_, size, static_cast<Args>(args)...)),
is_allocating_(true),
size_(size),
ti_(lib.get_type_info<T>())
{

}

template<typename T>
inline imported_class<T> boost::dll::experimental::imported_class<T>::copy() const
{
if (this->_is_allocating)
return imported_class<T>::template make<const T&>(_lib, *_data);
if (this->is_allocating_)
return imported_class<T>::template make<const T&>(lib_, *data_);
else
return imported_class<T>::template make<const T&>(_lib, _size, *_data);
return imported_class<T>::template make<const T&>(lib_, size_, *data_);
}

template<typename T>
inline imported_class<T> boost::dll::experimental::imported_class<T>::move()
{
if (this->_is_allocating)
return imported_class<T>::template make<T&&>(_lib, *_data);
if (this->is_allocating_)
return imported_class<T>::template make<T&&>(lib_, *data_);
else
return imported_class<T>::template make<T&&>(_lib, _size, *_data);
return imported_class<T>::template make<T&&>(lib_, size_, *data_);
}

template<typename T>
inline void boost::dll::experimental::imported_class<T>::copy_assign(const imported_class<T>& lhs) const
{
this->call<T&(const T&)>("operator=")(*lhs._data);
this->call<T&(const T&)>("operator=")(*lhs.data_);
}

template<typename T>
inline void boost::dll::experimental::imported_class<T>::move_assign(imported_class<T>& lhs)
{
this->call<T&(T&&)>("operator=")(static_cast<T&&>(*lhs._data));
this->call<T&(T&&)>("operator=")(static_cast<T&&>(*lhs.data_));
}


Expand Down Expand Up @@ -420,89 +420,42 @@ inline void boost::dll::experimental::imported_class<T>::move_assign(imported_cl
* Overload that accepts path also throws std::bad_alloc in case of insufficient memory.
*/
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, std::size_t size, Args...args)
import_class(smart_library lib, std::size_t size, Args...args)
{
smart_library lib(lib_);

return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
}

//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, Args...args)
import_class(smart_library lib, Args...args)
{
smart_library lib(lib_);
return imported_class<T>::template make<Args...>(std::move(lib), static_cast<Args>(args)...);
}

//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, const std::string & alias_name, Args...args)
import_class(smart_library lib, const std::string & alias_name, Args...args)
{
smart_library lib(lib_);
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(std::move(lib), static_cast<Args>(args)...);
}

//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, std::size_t size, const std::string & alias_name, Args...args)
import_class(smart_library lib, std::size_t size, const std::string & alias_name, Args...args)
{
smart_library lib(lib_);

lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
}

//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, const std::string & alias_name, std::size_t size, Args...args)
import_class(smart_library lib, const std::string & alias_name, std::size_t size, Args...args)
{
smart_library lib(lib_);

lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
}

//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, Args...args)
{
return imported_class<T>::template make<Args...>(std::move(lib), static_cast<Args>(args)...);
}

//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, const std::string & alias_name, Args...args)
{
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(std::move(lib), static_cast<Args>(args)...);
}

//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, std::size_t size, Args...args)
{
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
}

//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, std::size_t size, const std::string & alias_name, Args...args)
{
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
}

//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, const std::string & alias_name, std::size_t size, Args...args)
{
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
}



/*! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
* \note This function does add the type alias to the \ref boost::dll::experimental::smart_library.
Expand Down
Loading
Loading