Skip to content

Commit

Permalink
Make smart library work in C++11 mode (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
apolukhin authored Dec 19, 2024
1 parent 3a903d2 commit e6304f4
Show file tree
Hide file tree
Showing 14 changed files with 103 additions and 204 deletions.
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

0 comments on commit e6304f4

Please sign in to comment.