Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:31:11

0001 // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
0002 // Copyright Antony Polukhin, 2015-2025.
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 <cstring>              // std::memcpy
0017 #include <memory>
0018 #include <type_traits>
0019 
0020 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 301)
0021 #   pragma GCC system_header
0022 #endif
0023 
0024 namespace boost { namespace dll { namespace detail {
0025 
0026 // GCC warns when reinterpret_cast between function pointer and object pointer occur.
0027 // This method suppress the warnings and ensures that such casts are safe.
0028 template <class To, class From>
0029 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
0030     aggressive_ptr_cast(From v) noexcept
0031 {
0032     static_assert(
0033         std::is_pointer<To>::value && std::is_pointer<From>::value,
0034         "`agressive_ptr_cast` function must be used only for pointer casting."
0035     );
0036 
0037     static_assert(
0038         std::is_void< typename std::remove_pointer<To>::type >::value
0039         || std::is_void< typename std::remove_pointer<From>::type >::value,
0040         "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
0041     );
0042 
0043     static_assert(
0044         sizeof(v) == sizeof(To),
0045         "Pointer to function and pointer to object differ in size on your platform."
0046     );
0047 
0048     return reinterpret_cast<To>(v);
0049 }
0050 
0051 #ifdef BOOST_MSVC
0052 #   pragma warning(push)
0053 #   pragma warning(disable: 4172) // "returning address of local variable or temporary" but **v is not local!
0054 #endif
0055 
0056 template <class To, class From>
0057 BOOST_FORCEINLINE typename std::enable_if<std::is_reference<To>::value && !std::is_member_pointer<From>::value, To>::type
0058     aggressive_ptr_cast(From v) noexcept
0059 {
0060     static_assert(
0061         std::is_pointer<From>::value,
0062         "`agressive_ptr_cast` function must be used only for pointer casting."
0063     );
0064 
0065     static_assert(
0066         std::is_void< typename std::remove_pointer<From>::type >::value,
0067         "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
0068     );
0069 
0070     static_assert(
0071         sizeof(v) == sizeof(typename std::remove_reference<To>::type*),
0072         "Pointer to function and pointer to object differ in size on your platform."
0073     );
0074     return static_cast<To>(
0075         **reinterpret_cast<typename std::remove_reference<To>::type**>(
0076             v
0077         )
0078     );
0079 }
0080 
0081 #ifdef BOOST_MSVC
0082 #   pragma warning(pop)
0083 #endif
0084 
0085 template <class To, class From>
0086 BOOST_FORCEINLINE typename std::enable_if<std::is_member_pointer<To>::value && !std::is_member_pointer<From>::value, To>::type
0087     aggressive_ptr_cast(From v) noexcept
0088 {
0089     static_assert(
0090         std::is_pointer<From>::value,
0091         "`agressive_ptr_cast` function must be used only for pointer casting."
0092     );
0093 
0094     static_assert(
0095         std::is_void< typename std::remove_pointer<From>::type >::value,
0096         "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
0097     );
0098 
0099     To res = 0;
0100     std::memcpy(&res, &v, sizeof(From));
0101     return res;
0102 }
0103 
0104 template <class To, class From>
0105 BOOST_FORCEINLINE typename std::enable_if<!std::is_member_pointer<To>::value && std::is_member_pointer<From>::value, To>::type
0106     aggressive_ptr_cast(From /* v */) noexcept
0107 {
0108     static_assert(
0109         std::is_pointer<To>::value,
0110         "`agressive_ptr_cast` function must be used only for pointer casting."
0111     );
0112 
0113     static_assert(
0114         std::is_void< typename std::remove_pointer<To>::type >::value,
0115         "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
0116     );
0117 
0118     static_assert(
0119         !sizeof(From),
0120         "Casting from member pointers to void pointer is not implemnted in `agressive_ptr_cast`."
0121     );
0122 
0123     return 0;
0124 }
0125 
0126 }}} // boost::dll::detail
0127 
0128 #endif // BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP
0129