File indexing completed on 2025-01-18 09:30:43
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP
0009 #define BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP
0010
0011 #include <boost/dll/config.hpp>
0012 #ifdef BOOST_HAS_PRAGMA_ONCE
0013 # pragma once
0014 #endif
0015
0016 #include <boost/core/addressof.hpp>
0017 #include <boost/core/enable_if.hpp>
0018 #include <boost/type_traits/is_pointer.hpp>
0019 #include <boost/type_traits/is_member_pointer.hpp>
0020 #include <boost/type_traits/is_void.hpp>
0021 #include <boost/type_traits/is_reference.hpp>
0022 #include <boost/type_traits/remove_pointer.hpp>
0023 #include <boost/type_traits/remove_reference.hpp>
0024 #include <cstring> // std::memcpy
0025
0026 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 301)
0027 # pragma GCC system_header
0028 #endif
0029
0030 namespace boost { namespace dll { namespace detail {
0031
0032
0033
0034 template <class To, class From>
0035 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
0036 aggressive_ptr_cast(From v) BOOST_NOEXCEPT
0037 {
0038 static_assert(
0039 boost::is_pointer<To>::value && boost::is_pointer<From>::value,
0040 "`agressive_ptr_cast` function must be used only for pointer casting."
0041 );
0042
0043 static_assert(
0044 boost::is_void< typename boost::remove_pointer<To>::type >::value
0045 || boost::is_void< typename boost::remove_pointer<From>::type >::value,
0046 "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
0047 );
0048
0049 static_assert(
0050 sizeof(v) == sizeof(To),
0051 "Pointer to function and pointer to object differ in size on your platform."
0052 );
0053
0054 return reinterpret_cast<To>(v);
0055 }
0056
0057 #ifdef BOOST_MSVC
0058 # pragma warning(push)
0059 # pragma warning(disable: 4172)
0060 #endif
0061
0062 template <class To, class From>
0063 BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value || boost::is_member_pointer<From>::value, To>::type
0064 aggressive_ptr_cast(From v) BOOST_NOEXCEPT
0065 {
0066 static_assert(
0067 boost::is_pointer<From>::value,
0068 "`agressive_ptr_cast` function must be used only for pointer casting."
0069 );
0070
0071 static_assert(
0072 boost::is_void< typename boost::remove_pointer<From>::type >::value,
0073 "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
0074 );
0075
0076 static_assert(
0077 sizeof(v) == sizeof(typename boost::remove_reference<To>::type*),
0078 "Pointer to function and pointer to object differ in size on your platform."
0079 );
0080 return static_cast<To>(
0081 **reinterpret_cast<typename boost::remove_reference<To>::type**>(
0082 v
0083 )
0084 );
0085 }
0086
0087 #ifdef BOOST_MSVC
0088 # pragma warning(pop)
0089 #endif
0090
0091 template <class To, class From>
0092 BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::value || boost::is_member_pointer<From>::value, To>::type
0093 aggressive_ptr_cast(From v) BOOST_NOEXCEPT
0094 {
0095 static_assert(
0096 boost::is_pointer<From>::value,
0097 "`agressive_ptr_cast` function must be used only for pointer casting."
0098 );
0099
0100 static_assert(
0101 boost::is_void< typename boost::remove_pointer<From>::type >::value,
0102 "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
0103 );
0104
0105 To res = 0;
0106 std::memcpy(&res, &v, sizeof(From));
0107 return res;
0108 }
0109
0110 template <class To, class From>
0111 BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::value || !boost::is_member_pointer<From>::value, To>::type
0112 aggressive_ptr_cast(From ) BOOST_NOEXCEPT
0113 {
0114 static_assert(
0115 boost::is_pointer<To>::value,
0116 "`agressive_ptr_cast` function must be used only for pointer casting."
0117 );
0118
0119 static_assert(
0120 boost::is_void< typename boost::remove_pointer<To>::type >::value,
0121 "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
0122 );
0123
0124 static_assert(
0125 !sizeof(From),
0126 "Casting from member pointers to void pointer is not implemnted in `agressive_ptr_cast`."
0127 );
0128
0129 return 0;
0130 }
0131
0132 }}}
0133
0134 #endif
0135