proxsuite 0.6.7
The Advanced Proximal Optimization Toolbox
Loading...
Searching...
No Matches
placement.hpp
Go to the documentation of this file.
1#ifndef VEG_PLACEMENT_HPP_LP0HMLTPS
2#define VEG_PLACEMENT_HPP_LP0HMLTPS
3
9#include <new>
10
11#if defined(VEG_WITH_CXX20_SUPPORT) && !VEG_HAS_BUILTIN(__builtin_bit_cast)
12#include <bit>
13#define VEG_HAS_BITCAST 1
14#define VEG_BITCAST(T, x) ::std::bit_cast<T>(x)
15#define VEG_BITCAST_CONSTEXPR constexpr
16#elif VEG_HAS_BUILTIN(__builtin_bit_cast)
17#define VEG_HAS_BITCAST 1
18#define VEG_BITCAST(T, x) __builtin_bit_cast(T, x)
19#define VEG_BITCAST_CONSTEXPR constexpr
20#else
21#include <cstring>
22#define VEG_HAS_BITCAST 0
23#define VEG_BITCAST_CONSTEXPR
24#endif
25
26// construct_at
27#if defined(VEG_WITH_CXX20_SUPPORT)
28
29// std::construct_at
30#if __VEG_HAS_INCLUDE(<bits / stl_construct.h>) && \
31 __VEG_HAS_INCLUDE(<bits / stl_iterator_base_types.h>) && \
32 __VEG_HAS_INCLUDE(<bits / stl_iterator_base_funcs.h>)
33#include <bits/stl_iterator_base_types.h>
34#include <bits/stl_iterator_base_funcs.h>
35#include <bits/stl_construct.h>
36#else
37#include <memory>
38#endif
39
40#endif
41
42#if VEG_HAS_BUILTIN(__builtin_launder) || __GNUC__ >= 7
43#define VEG_LAUNDER(p) (__builtin_launder(p))
44#elif defined(VEG_WITH_CXX17_SUPPORT) && __GNUC__ >= 6
45#include <new>
46#define VEG_LAUNDER(p) (::std::launder(p))
47#else
48#define VEG_LAUNDER(p) (+p)
49#endif
50
51namespace proxsuite {
52namespace linalg {
53namespace veg {
54namespace mem {
55namespace nb {
56struct launder
57{
58 VEG_TEMPLATE(typename T,
59 requires(VEG_CONCEPT(complete<T>)),
60 VEG_INLINE constexpr auto
61 operator(),
62 (mem, T*))
63 const VEG_NOEXCEPT->T* { return VEG_LAUNDER(mem); }
64};
65#undef VEG_LAUNDER
66
68{
69 VEG_TEMPLATE((typename T, typename... Args),
70 requires(!VEG_CONCEPT(const_type<T>) &&
72 VEG_INLINE VEG_CPP20(constexpr) auto
73 operator(),
74 (mem, T*),
75 (... args, Args&&))
77 ->T*
78 {
79#if defined(VEG_WITH_CXX20_SUPPORT)
80 return ::std::construct_at(mem, VEG_FWD(args)...);
81#else
82 return ::new (mem) T(VEG_FWD(args)...);
83#endif
84 }
85};
86
88{
89 VEG_TEMPLATE((typename T, typename Fn),
90 requires(!VEG_CONCEPT(const_type<T>) &&
92 VEG_INLINE VEG_CPP20(constexpr) auto
93 operator(),
94 (mem, T*),
95 (fn, Fn&&))
97 {
98#if defined(VEG_WITH_CXX20_SUPPORT)
99 struct Convertor
100 {
101 Fn&& fn;
102 VEG_INLINE constexpr operator T() const&& VEG_NOEXCEPT_IF(
104 {
105 return VEG_FWD(fn)();
106 }
107 };
108
109 return ::std::construct_at(mem, Convertor{ VEG_FWD(fn) });
110#else
111 return ::new (mem) T(VEG_FWD(fn)());
112#endif
113 }
114};
115
117{
118 VEG_TEMPLATE((typename T),
119 requires(VEG_CONCEPT(complete<T>)),
120 VEG_INLINE VEG_CPP14(constexpr) void
121 operator(),
122 (mem, T*))
124};
126{
127 auto operator()(usize alignment, void* ptr) const VEG_NOEXCEPT->void*
128 {
129 using byte_ptr = unsigned char*;
130 std::uintptr_t lo_mask = alignment - 1U;
131 std::uintptr_t hi_mask = ~lo_mask;
132 auto const intptr = reinterpret_cast<std::uintptr_t>(ptr);
133 auto* const byteptr = static_cast<byte_ptr>(ptr);
134 auto offset = ((intptr + alignment - 1U) & hi_mask) - intptr;
135
136 return byteptr + offset;
137 }
138 auto operator()(usize alignment,
139 void const* ptr) const VEG_NOEXCEPT->void const*
140 {
141 return this->operator()(alignment, const_cast<void*>(ptr));
142 }
143};
145{
146 auto operator()(usize alignment, void* ptr) const VEG_NOEXCEPT->void*
147 {
148 using byte_ptr = unsigned char*;
149 std::uintptr_t lo_mask = alignment - 1U;
150 std::uintptr_t hi_mask = ~lo_mask;
151 auto const intptr = reinterpret_cast<std::uintptr_t>(ptr);
152 auto* const byteptr = static_cast<byte_ptr>(ptr);
153 auto offset = ((intptr)&hi_mask) - intptr;
154
155 return byteptr + offset;
156 }
157 auto operator()(usize alignment,
158 void const* ptr) const VEG_NOEXCEPT->void const*
159 {
160 return this->operator()(alignment, const_cast<void*>(ptr));
161 }
162};
163} // namespace nb
164VEG_NIEBLOID(align_next);
165VEG_NIEBLOID(align_prev);
167VEG_NIEBLOID(construct_at);
168VEG_NIEBLOID(construct_with);
169VEG_NIEBLOID(destroy_at);
170
171namespace nb {
172template<typename To>
174{
178 (sizeof(From) == sizeof(To)))),
180 operator(),
181 (from, From const&))
182 const VEG_NOEXCEPT->To
183 {
184#if VEG_HAS_BITCAST
185 return VEG_BITCAST(To, from);
186#else
187 alignas(To) unsigned char buf[sizeof(To)];
188 To* ptr = reinterpret_cast<To*>(static_cast<unsigned char*>(buf));
189 ::std::memcpy(ptr, nb::addressof{}(from), sizeof(To));
190 return To(static_cast<To&&>(*nb::launder{}(ptr)));
191#endif
192 }
193};
194} // namespace nb
195VEG_NIEBLOID_TEMPLATE(typename To, bit_cast, To);
196} // namespace mem
197} // namespace veg
198} // namespace linalg
199} // namespace proxsuite
200
202#endif /* end of include guard VEG_PLACEMENT_HPP_LP0HMLTPS */
#define VEG_CONCEPT(...)
Definition macros.hpp:1243
#define VEG_NIEBLOID_TEMPLATE(Tpl, Name,...)
Definition macros.hpp:547
#define VEG_NIEBLOID(Name)
Definition macros.hpp:545
#define VEG_INLINE
Definition macros.hpp:118
#define VEG_FWD(X)
Definition macros.hpp:569
#define VEG_BITCAST_CONSTEXPR
Definition placement.hpp:23
#define VEG_LAUNDER(p)
Definition placement.hpp:48
#define VEG_CPP20(...)
Definition prologue.hpp:83
#define VEG_NOEXCEPT
Definition prologue.hpp:30
#define VEG_CPP14(...)
Definition prologue.hpp:71
#define VEG_NOEXCEPT_IF(...)
Definition prologue.hpp:31
auto operator()(usize alignment, void *ptr) const VEG_NOEXCEPT -> void *
auto operator()(usize alignment, void const *ptr) const VEG_NOEXCEPT -> void const *
auto operator()(usize alignment, void *ptr) const VEG_NOEXCEPT -> void *
auto operator()(usize alignment, void const *ptr) const VEG_NOEXCEPT -> void const *
VEG_TEMPLATE(typename From, requires((VEG_CONCEPT(trivially_copyable< From >) &&VEG_CONCEPT(trivially_copyable< To >) &&(sizeof(From)==sizeof(To)))), VEG_INLINE VEG_BITCAST_CONSTEXPR auto operator(),(from, From const &)) const VEG_NOEXCEPT -> To
VEG_TEMPLATE((typename T, typename... Args), requires(!VEG_CONCEPT(const_type< T >) &&VEG_CONCEPT(inplace_constructible< T, Args... >)), VEG_INLINE VEG_CPP20(constexpr) auto operator(),(mem, T *),(... args, Args &&)) const VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_inplace_constructible< T
VEG_TEMPLATE((typename T, typename Fn), requires(!VEG_CONCEPT(const_type< T >) &&VEG_CONCEPT(fn_once< Fn, T >)), VEG_INLINE VEG_CPP20(constexpr) auto operator(),(mem, T *),(fn, Fn &&)) const VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_fn_once< Fn
VEG_TEMPLATE((typename T), requires(VEG_CONCEPT(complete< T >)), VEG_INLINE VEG_CPP14(constexpr) void operator(),(mem, T *)) const VEG_NOEXCEPT_IF(VEG_CONCEPT(nothrow_destructible< T >))
VEG_TEMPLATE(typename T, requires(VEG_CONCEPT(complete< T >)), VEG_INLINE constexpr auto operator(),(mem, T *)) const VEG_NOEXCEPT -> T *
Definition placement.hpp:58