Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:43

0001 // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
0002 // Copyright Antony Polukhin, 2015-2023.
0003 //
0004 // Distributed under the Boost Software License, Version 1.0.
0005 // (See accompanying file LICENSE_1_0.txt
0006 // or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // GCC warns when reinterpret_cast between function pointer and object pointer occur.
0033 // This method suppress the warnings and ensures that such casts are safe.
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) // "returning address of local variable or temporary" but **v is not local!
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 /* v */) 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 }}} // boost::dll::detail
0133 
0134 #endif // BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP
0135