]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/dll/include/boost/dll/detail/aggressive_ptr_cast.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / dll / include / boost / dll / detail / aggressive_ptr_cast.hpp
CommitLineData
7c673cae
FG
1// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
2// Copyright 2015-2016 Antony Polukhin.
3//
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt
6// or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8#ifndef BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP
9#define BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP
10
11#include <boost/config.hpp>
12#ifdef BOOST_HAS_PRAGMA_ONCE
13# pragma once
14#endif
15
16#include <boost/static_assert.hpp>
17#include <boost/type_traits/is_pointer.hpp>
18#include <boost/type_traits/is_member_pointer.hpp>
19#include <boost/type_traits/is_void.hpp>
20#include <boost/type_traits/is_reference.hpp>
21#include <boost/type_traits/remove_pointer.hpp>
22#include <boost/type_traits/remove_reference.hpp>
23#include <boost/utility/enable_if.hpp>
24#include <boost/cstdint.hpp> // boost::uintptr_t
25#include <cstring> // std::memcpy
26
27namespace boost { namespace dll { namespace detail {
28
29// GCC warns when reinterpret_cast between function pointer and object pointer occur.
30// This method suppress the warnings and ensures that such casts are safe.
31template <class To, class From>
32BOOST_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
33 aggressive_ptr_cast(From v) BOOST_NOEXCEPT
34{
35 BOOST_STATIC_ASSERT_MSG(
36 boost::is_pointer<To>::value && boost::is_pointer<From>::value,
37 "`agressive_ptr_cast` function must be used only for pointer casting."
38 );
39
40 BOOST_STATIC_ASSERT_MSG(
41 boost::is_void< typename boost::remove_pointer<To>::type >::value
42 || boost::is_void< typename boost::remove_pointer<From>::type >::value,
43 "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
44 );
45
46 BOOST_STATIC_ASSERT_MSG(
47 sizeof(v) == sizeof(To),
48 "Pointer to function and pointer to object differ in size on your platform."
49 );
50
51 return reinterpret_cast<To>(
52 reinterpret_cast<boost::uintptr_t>(v)
53 );
54}
55
56template <class To, class From>
57BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value || boost::is_member_pointer<From>::value, To>::type
58 aggressive_ptr_cast(From v) BOOST_NOEXCEPT
59{
60 BOOST_STATIC_ASSERT_MSG(
61 boost::is_pointer<From>::value,
62 "`agressive_ptr_cast` function must be used only for pointer casting."
63 );
64
65 BOOST_STATIC_ASSERT_MSG(
66 boost::is_void< typename boost::remove_pointer<From>::type >::value,
67 "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
68 );
69
70 BOOST_STATIC_ASSERT_MSG(
71 sizeof(v) == sizeof(typename boost::remove_reference<To>::type*),
72 "Pointer to function and pointer to object differ in size on your platform."
73 );
74
75 return static_cast<To>(
76 *reinterpret_cast<typename boost::remove_reference<To>::type*>(
77 *reinterpret_cast<boost::uintptr_t*>(
78 reinterpret_cast<unsigned char*>(
79 v
80 )
81 )
82 )
83 );
84}
85
86template <class To, class From>
87BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::value || boost::is_member_pointer<From>::value, To>::type
88 aggressive_ptr_cast(From v) BOOST_NOEXCEPT
89{
90 BOOST_STATIC_ASSERT_MSG(
91 boost::is_pointer<From>::value,
92 "`agressive_ptr_cast` function must be used only for pointer casting."
93 );
94
95 BOOST_STATIC_ASSERT_MSG(
96 boost::is_void< typename boost::remove_pointer<From>::type >::value,
97 "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
98 );
99
100 To res = 0;
101 std::memcpy(&res, &v, sizeof(To));
102 return res;
103}
104
105template <class To, class From>
106BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::value || !boost::is_member_pointer<From>::value, To>::type
107 aggressive_ptr_cast(From /* v */) BOOST_NOEXCEPT
108{
109 BOOST_STATIC_ASSERT_MSG(
110 boost::is_pointer<To>::value,
111 "`agressive_ptr_cast` function must be used only for pointer casting."
112 );
113
114 BOOST_STATIC_ASSERT_MSG(
115 boost::is_void< typename boost::remove_pointer<To>::type >::value,
116 "`agressive_ptr_cast` function must be used only for casting to or from void pointers."
117 );
118
119 BOOST_STATIC_ASSERT_MSG(
120 !sizeof(From),
121 "Casting from member pointers to void pointer is not implemnted in `agressive_ptr_cast`."
122 );
123
124 return 0;
125}
126
127}}} // boost::dll::detail
128
129#endif // BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP
130