Skip to content

Commit

Permalink
Use Standard Library type traits (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
apolukhin authored Dec 17, 2024
1 parent 06bc4c8 commit 0d984c6
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 139 deletions.
3 changes: 0 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@ target_link_libraries(boost_dll
Boost::config
Boost::core
Boost::filesystem
Boost::function
Boost::move
Boost::predef
Boost::smart_ptr
Boost::spirit
Boost::system
Boost::throw_exception
Boost::type_index
Boost::type_traits
Boost::winapi
)

Expand Down
1 change: 0 additions & 1 deletion build.jam
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ constant boost_dependencies :
/boost/system//boost_system
/boost/throw_exception//boost_throw_exception
/boost/type_index//boost_type_index
/boost/type_traits//boost_type_traits
/boost/winapi//boost_winapi ;

project /boost/dll
Expand Down
2 changes: 1 addition & 1 deletion include/boost/dll/alias.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ namespace boost { namespace dll {
#else
// Note: we can not use `aggressive_ptr_cast` here, because in that case GCC applies
// different permissions to the section and it causes Segmentation fault.
// Note: we can not use `boost::addressof()` here, because in that case GCC
// Note: we can not use `std::addressof()` here, because in that case GCC
// may optimize away the FunctionOrVar instance and we'll get a pointer to unexisting symbol.
/*!
* \brief Same as \forcedmacrolink{BOOST_DLL_ALIAS} but puts alias name into the user specified section.
Expand Down
40 changes: 17 additions & 23 deletions include/boost/dll/detail/aggressive_ptr_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,9 @@
# pragma once
#endif

#include <boost/core/addressof.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_pointer.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <cstring> // std::memcpy
#include <memory>
#include <type_traits>

#if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 301)
# pragma GCC system_header
Expand All @@ -32,17 +26,17 @@ namespace boost { namespace dll { namespace detail {
// GCC warns when reinterpret_cast between function pointer and object pointer occur.
// This method suppress the warnings and ensures that such casts are safe.
template <class To, class From>
BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::value || boost::is_reference<To>::value || boost::is_member_pointer<From>::value, To>::type
BOOST_FORCEINLINE typename std::enable_if<!std::is_member_pointer<To>::value && !std::is_reference<To>::value && !std::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From v) noexcept
{
static_assert(
boost::is_pointer<To>::value && boost::is_pointer<From>::value,
std::is_pointer<To>::value && std::is_pointer<From>::value,
"`agressive_ptr_cast` function must be used only for pointer casting."
);

static_assert(
boost::is_void< typename boost::remove_pointer<To>::type >::value
|| boost::is_void< typename boost::remove_pointer<From>::type >::value,
std::is_void< typename std::remove_pointer<To>::type >::value
|| std::is_void< typename std::remove_pointer<From>::type >::value,
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
);

Expand All @@ -60,25 +54,25 @@ BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::val
#endif

template <class To, class From>
BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value || boost::is_member_pointer<From>::value, To>::type
BOOST_FORCEINLINE typename std::enable_if<std::is_reference<To>::value && !std::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From v) noexcept
{
static_assert(
boost::is_pointer<From>::value,
std::is_pointer<From>::value,
"`agressive_ptr_cast` function must be used only for pointer casting."
);

static_assert(
boost::is_void< typename boost::remove_pointer<From>::type >::value,
std::is_void< typename std::remove_pointer<From>::type >::value,
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
);

static_assert(
sizeof(v) == sizeof(typename boost::remove_reference<To>::type*),
sizeof(v) == sizeof(typename std::remove_reference<To>::type*),
"Pointer to function and pointer to object differ in size on your platform."
);
return static_cast<To>(
**reinterpret_cast<typename boost::remove_reference<To>::type**>(
**reinterpret_cast<typename std::remove_reference<To>::type**>(
v
)
);
Expand All @@ -89,16 +83,16 @@ BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value |
#endif

template <class To, class From>
BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::value || boost::is_member_pointer<From>::value, To>::type
BOOST_FORCEINLINE typename std::enable_if<std::is_member_pointer<To>::value && !std::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From v) noexcept
{
static_assert(
boost::is_pointer<From>::value,
std::is_pointer<From>::value,
"`agressive_ptr_cast` function must be used only for pointer casting."
);

static_assert(
boost::is_void< typename boost::remove_pointer<From>::type >::value,
std::is_void< typename std::remove_pointer<From>::type >::value,
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
);

Expand All @@ -108,16 +102,16 @@ BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::va
}

template <class To, class From>
BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::value || !boost::is_member_pointer<From>::value, To>::type
BOOST_FORCEINLINE typename std::enable_if<!std::is_member_pointer<To>::value && std::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From /* v */) noexcept
{
static_assert(
boost::is_pointer<To>::value,
std::is_pointer<To>::value,
"`agressive_ptr_cast` function must be used only for pointer casting."
);

static_assert(
boost::is_void< typename boost::remove_pointer<To>::type >::value,
std::is_void< typename std::remove_pointer<To>::type >::value,
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
);

Expand Down
6 changes: 3 additions & 3 deletions include/boost/dll/detail/ctor_dtor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ template<typename Class, typename Lib>
destructor<Class> load_dtor(Lib & lib, const mangled_storage_impl::dtor_sym & dt) {
typedef typename destructor<Class>::standard_t standard_t;
//@apolukhin That does NOT work this way with MSVC-14 x32 via memcpy. The x64 is different.
//standard_t dtor = &lib.template get< typename boost::remove_pointer<standard_t>::type >(dt);
//standard_t dtor = &lib.template get< typename std::remove_pointer<standard_t>::type >(dt);
void * buf = &lib.template get<unsigned char>(dt);
standard_t dtor;
std::memcpy(&dtor, &buf, sizeof(dtor));
Expand Down Expand Up @@ -175,11 +175,11 @@ destructor<Class> load_dtor(Lib & lib, const mangled_storage_impl::dtor_sym & dt

//see here for the abi http://mentorembedded.github.io/cxx-abi/abi.html#mangling-special-ctor-dtor
if (!dt.D1.empty()) {
s = &lib.template get< typename boost::remove_pointer<stand>::type >(dt.D1);
s = &lib.template get< typename std::remove_pointer<stand>::type >(dt.D1);
}

if (!dt.D0.empty()) {
d = &lib.template get< typename boost::remove_pointer<delet>::type >(dt.D0);
d = &lib.template get< typename std::remove_pointer<delet>::type >(dt.D0);
}

return destructor<Class>(s,d);
Expand Down
30 changes: 13 additions & 17 deletions include/boost/dll/detail/demangling/itanium.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,15 @@
#define BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_

#include <boost/dll/detail/demangling/mangled_storage_base.hpp>
#include <iterator>

#include <algorithm>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/is_rvalue_reference.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <iterator>
#include <type_traits>


namespace boost { namespace dll { namespace detail {



class mangled_storage_impl : public mangled_storage_base
{
template<typename T>
Expand Down Expand Up @@ -185,22 +181,22 @@ namespace parser
}
};

inline std::string const_rule_impl(true_type ) {return " const";}
inline std::string const_rule_impl(false_type) {return "";}
inline std::string const_rule_impl(std::true_type ) {return " const";}
inline std::string const_rule_impl(std::false_type) {return "";}
template<typename T>
std::string const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
std::string const_rule() {using t = std::is_const<typename std::remove_reference<T>::type>; return const_rule_impl(t());}

inline std::string volatile_rule_impl(true_type ) {return " volatile";}
inline std::string volatile_rule_impl(false_type) {return "";}
inline std::string volatile_rule_impl(std::true_type ) {return " volatile";}
inline std::string volatile_rule_impl(std::false_type) {return "";}
template<typename T>
std::string volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
std::string volatile_rule() {using t = std::is_volatile<typename std::remove_reference<T>::type>; return volatile_rule_impl(t());}

inline std::string reference_rule_impl(false_type, false_type) {return "";}
inline std::string reference_rule_impl(true_type, false_type) {return "&" ;}
inline std::string reference_rule_impl(false_type, true_type ) {return "&&";}
inline std::string reference_rule_impl(std::false_type, std::false_type) {return "";}
inline std::string reference_rule_impl(std::true_type, std::false_type) {return "&" ;}
inline std::string reference_rule_impl(std::false_type, std::true_type ) {return "&&";}

template<typename T>
std::string reference_rule() {using t_l = is_lvalue_reference<T>; using t_r = is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
std::string reference_rule() {using t_l = std::is_lvalue_reference<T>; using t_r = std::is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}

//it takes a string, because it may be overloaded.
template<typename Return, typename Arg>
Expand Down
4 changes: 3 additions & 1 deletion include/boost/dll/detail/demangling/mangled_storage_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
#include <vector>
#include <string>
#include <map>
#include <type_traits>

#include <boost/dll/detail/demangling/demangle_symbol.hpp>
#include <boost/dll/library_info.hpp>
#include <boost/type_index/ctti_type_index.hpp>
#include <boost/type_traits/remove_reference.hpp>


namespace boost { namespace dll { namespace detail {

Expand Down
42 changes: 17 additions & 25 deletions include/boost/dll/detail/demangling/msvc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@
#include <boost/dll/detail/demangling/mangled_storage_base.hpp>
#include <iterator>
#include <algorithm>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp>
#include <boost/type_traits/is_rvalue_reference.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <type_traits>

#include <boost/spirit/home/x3.hpp>

Expand Down Expand Up @@ -115,35 +110,35 @@ namespace parser
auto const virtual_ = x3::space >> "virtual";
auto const static_ = x3::space >> x3::lit("static") ;

inline auto const_rule_impl(true_type ) {return x3::space >> "const";};
inline auto const_rule_impl(false_type) {return x3::eps;};
inline auto const_rule_impl(std::true_type ) {return x3::space >> "const";};
inline auto const_rule_impl(std::false_type) {return x3::eps;};
template<typename T>
auto const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
auto const_rule() {using t = std::is_const<typename std::remove_reference<T>::type>; return const_rule_impl(t());}

inline auto volatile_rule_impl(true_type ) {return x3::space >> "volatile";};
inline auto volatile_rule_impl(false_type) {return x3::eps;};
inline auto volatile_rule_impl(std::true_type ) {return x3::space >> "volatile";};
inline auto volatile_rule_impl(std::false_type) {return x3::eps;};
template<typename T>
auto volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
auto volatile_rule() {using t = std::is_volatile<typename std::remove_reference<T>::type>; return volatile_rule_impl(t());}


inline auto inv_const_rule_impl(true_type ) {return "const" >> x3::space ;};
inline auto inv_const_rule_impl(false_type) {return x3::eps;};
inline auto inv_const_rule_impl(std::true_type ) {return "const" >> x3::space ;};
inline auto inv_const_rule_impl(std::false_type) {return x3::eps;};
template<typename T>
auto inv_const_rule() {using t = is_const<typename remove_reference<T>::type>; return inv_const_rule_impl(t());}
auto inv_const_rule() {using t = std::is_const<typename std::remove_reference<T>::type>; return inv_const_rule_impl(t());}

inline auto inv_volatile_rule_impl(true_type ) {return "volatile" >> x3::space;};
inline auto inv_volatile_rule_impl(false_type) {return x3::eps;};
inline auto inv_volatile_rule_impl(std::true_type ) {return "volatile" >> x3::space;};
inline auto inv_volatile_rule_impl(std::false_type) {return x3::eps;};
template<typename T>
auto inv_volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return inv_volatile_rule_impl(t());}
auto inv_volatile_rule() {using t = std::is_volatile<typename std::remove_reference<T>::type>; return inv_volatile_rule_impl(t());}


inline auto reference_rule_impl(false_type, false_type) {return x3::eps;}
inline auto reference_rule_impl(true_type, false_type) {return x3::space >>"&" ;}
inline auto reference_rule_impl(false_type, true_type ) {return x3::space >>"&&" ;}
inline auto reference_rule_impl(std::false_type, std::false_type) {return x3::eps;}
inline auto reference_rule_impl(std::true_type, std::false_type) {return x3::space >>"&" ;}
inline auto reference_rule_impl(std::false_type, std::true_type ) {return x3::space >>"&&" ;}


template<typename T>
auto reference_rule() {using t_l = is_lvalue_reference<T>; using t_r = is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
auto reference_rule() {using t_l = std::is_lvalue_reference<T>; using t_r = std::is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}

auto const class_ = ("class" | x3::lit("struct"));

Expand Down Expand Up @@ -173,15 +168,12 @@ namespace parser
template<typename Return, typename Arg>
auto arg_list(const mangled_storage_impl & ms, Return (*)(Arg))
{
using namespace std;

return type_rule<Arg>(ms.get_name<Arg>());
}

template<typename Return, typename First, typename Second, typename ...Args>
auto arg_list(const mangled_storage_impl & ms, Return (*)(First, Second, Args...))
{

using next_type = Return (*)(Second, Args...);
return type_rule<First>(ms.get_name<First>()) >> x3::char_(',') >> arg_list(ms, next_type());
}
Expand Down
Loading

0 comments on commit 0d984c6

Please sign in to comment.