5
5
#pragma once
6
6
7
7
#include " generated/functions.hpp"
8
+ #include " emplacer.hpp"
9
+ #include " tuples.hpp"
8
10
#include " header_start.hpp"
9
11
10
- #define soagen_storage_ptr (...) soagen::assume_aligned<alignof(storage_type)>(__VA_ARGS__)
12
+ #ifndef SOAGEN_LAUNDER
13
+ #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
14
+ #define SOAGEN_LAUNDER (...) std::launder(__VA_ARGS__)
15
+ #elif SOAGEN_CLANG >= 8 || SOAGEN_GCC >= 7 || SOAGEN_ICC >= 1910 || SOAGEN_MSVC >= 1914 \
16
+ || SOAGEN_HAS_BUILTIN(__builtin_launder)
17
+ #define SOAGEN_LAUNDER (...) __builtin_launder(__VA_ARGS__)
18
+ #else
19
+ #define SOAGEN_LAUNDER (...) __VA_ARGS__
20
+ #endif
21
+ #endif
22
+
23
+ #ifndef SOAGEN_COLUMN
24
+ #define SOAGEN_COLUMN (I ) \
25
+ SOAGEN_PURE_INLINE_GETTER \
26
+ SOAGEN_ATTR (returns_nonnull)
27
+ #endif
28
+
29
+ #ifndef SOAGEN_ALIGNED_COLUMN
30
+ #define SOAGEN_ALIGNED_COLUMN (I ) \
31
+ SOAGEN_COLUMN (I) \
32
+ SOAGEN_ATTR(assume_aligned( \
33
+ soagen::detail::actual_column_alignment<table_traits, allocator_type, static_cast <std::size_t >(I)>))
34
+ #endif
35
+
36
+ #define soagen_aligned_storage (...) soagen::assume_aligned<alignof(storage_type)>(__VA_ARGS__)
11
37
12
38
// / @cond
13
39
namespace soagen ::detail
@@ -22,24 +48,48 @@ namespace soagen::detail
22
48
static_assert (!std::is_void_v<storage_type>, " column storage_type may not be void" );
23
49
static_assert (std::is_destructible_v<storage_type>, " column storage_type must be destructible" );
24
50
25
- // --- dereferencing --------------------------------------------------------------------------------------------
51
+ // --- pointers ----- --------------------------------------------------------------------------------------------
26
52
27
53
SOAGEN_PURE_GETTER
28
54
SOAGEN_ATTR (nonnull)
29
- static constexpr storage_type& get (std::byte* ptr ) noexcept
55
+ static constexpr storage_type* ptr (std::byte* p ) noexcept
30
56
{
31
- SOAGEN_ASSUME (ptr != nullptr );
57
+ SOAGEN_ASSUME (p != nullptr );
32
58
33
- return *SOAGEN_LAUNDER (reinterpret_cast <storage_type*>(soagen_storage_ptr (ptr)));
59
+ if constexpr (std::is_same_v<storage_type, std::byte>)
60
+ return p;
61
+ else
62
+ return SOAGEN_LAUNDER (reinterpret_cast <storage_type*>(p));
34
63
}
35
64
36
65
SOAGEN_PURE_GETTER
37
66
SOAGEN_ATTR (nonnull)
38
- static constexpr const storage_type& get (const std::byte* ptr) noexcept
67
+ static constexpr const storage_type* ptr (const std::byte* p) noexcept
68
+ {
69
+ SOAGEN_ASSUME (p != nullptr );
70
+
71
+ if constexpr (std::is_same_v<storage_type, std::byte>)
72
+ return p;
73
+ else
74
+ return SOAGEN_LAUNDER (reinterpret_cast <const storage_type*>(p));
75
+ }
76
+
77
+ // --- dereferencing --------------------------------------------------------------------------------------------
78
+
79
+ SOAGEN_PURE_INLINE_GETTER
80
+ SOAGEN_ATTR (nonnull)
81
+ static constexpr storage_type& get (std::byte* p) noexcept
82
+ {
83
+ return *ptr (p);
84
+ }
85
+
86
+ SOAGEN_PURE_INLINE_GETTER
87
+ SOAGEN_ATTR (nonnull)
88
+ static constexpr const storage_type& get (const std::byte* p) noexcept
39
89
{
40
- SOAGEN_ASSUME (ptr != nullptr );
90
+ SOAGEN_ASSUME (p != nullptr );
41
91
42
- return *SOAGEN_LAUNDER ( reinterpret_cast < const storage_type*>( soagen_storage_ptr ( ptr)) );
92
+ return *ptr (p );
43
93
}
44
94
45
95
// --- default construction -------------------------------------------------------------------------------------
@@ -54,12 +104,12 @@ namespace soagen::detail
54
104
#if defined(__cpp_lib_start_lifetime_as) && __cpp_lib_start_lifetime_as >= 202207
55
105
if constexpr (is_implicit_lifetime_type<storage_type>)
56
106
{
57
- return *(std::start_lifetime_as<storage_type>(soagen_storage_ptr ( destination) ));
107
+ return *(std::start_lifetime_as<storage_type>(destination));
58
108
}
59
109
else
60
110
{
61
111
#endif
62
- return *(::new (static_cast <void *>(soagen_storage_ptr ( destination) )) storage_type);
112
+ return *(::new (static_cast <void *>(destination)) storage_type);
63
113
64
114
#if defined(__cpp_lib_start_lifetime_as) && __cpp_lib_start_lifetime_as >= 202207
65
115
}
@@ -88,7 +138,7 @@ namespace soagen::detail
88
138
#if defined(__cpp_lib_start_lifetime_as) && __cpp_lib_start_lifetime_as >= 2022071
89
139
if constexpr (is_implicit_lifetime_type<storage_type>)
90
140
{
91
- std::start_lifetime_as_array<storage_type>(soagen_storage_ptr ( destination) , count);
141
+ std::start_lifetime_as_array<storage_type>(destination, count);
92
142
}
93
143
else
94
144
#endif
@@ -269,7 +319,7 @@ namespace soagen::detail
269
319
{
270
320
SOAGEN_ASSUME (destination != nullptr );
271
321
272
- return construct (destination, get_from_tuple_like <Indices>(static_cast <Tuple&&>(tuple))...);
322
+ return construct (destination, get_from_tuple <Indices>(static_cast <Tuple&&>(tuple))...);
273
323
}
274
324
275
325
public:
@@ -295,21 +345,19 @@ namespace soagen::detail
295
345
}
296
346
else if constexpr (sizeof ...(Args) == 1 && (is_constructible_with_memcpy<Args&&> && ...))
297
347
{
298
- std::memcpy (soagen_storage_ptr (destination), soagen_storage_ptr ( &args) ..., sizeof (storage_type));
348
+ std::memcpy (soagen_aligned_storage (destination), &args..., sizeof (storage_type));
299
349
300
350
return get (destination);
301
351
}
302
352
else if constexpr (std::is_constructible_v<storage_type, Args&&...>)
303
353
{
304
354
if constexpr (std::is_aggregate_v<storage_type>)
305
355
{
306
- return *(::new (static_cast <void *>(soagen_storage_ptr (destination)))
307
- storage_type{ static_cast <Args&&>(args)... });
356
+ return *(::new (static_cast <void *>(destination)) storage_type{ static_cast <Args&&>(args)... });
308
357
}
309
358
else
310
359
{
311
- return *(::new (static_cast <void *>(soagen_storage_ptr (destination)))
312
- storage_type (static_cast <Args&&>(args)...));
360
+ return *(::new (static_cast <void *>(destination)) storage_type (static_cast <Args&&>(args)...));
313
361
}
314
362
}
315
363
else if constexpr (sizeof ...(Args) == 1 && (is_constructible_by_unpacking_tuple<Args&&> && ...))
@@ -538,8 +586,8 @@ namespace soagen::detail
538
586
539
587
if constexpr (is_constructible_with_memcpy<storage_type&&>)
540
588
{
541
- std::memcpy (soagen_storage_ptr (destination),
542
- soagen_storage_ptr (static_cast <std::byte*>(source)),
589
+ std::memcpy (soagen_aligned_storage (destination),
590
+ soagen_aligned_storage (static_cast <std::byte*>(source)),
543
591
sizeof (storage_type));
544
592
545
593
return get (destination);
@@ -605,8 +653,8 @@ namespace soagen::detail
605
653
606
654
if constexpr (is_constructible_with_memcpy<storage_type&&>)
607
655
{
608
- std::memcpy (soagen_storage_ptr (destination),
609
- soagen_storage_ptr (static_cast <const std::byte*>(source)),
656
+ std::memcpy (soagen_aligned_storage (destination),
657
+ soagen_aligned_storage (static_cast <const std::byte*>(source)),
610
658
sizeof (storage_type));
611
659
612
660
return get (destination);
@@ -673,9 +721,9 @@ namespace soagen::detail
673
721
if constexpr (is_trivially_swappable)
674
722
{
675
723
alignas (storage_type) std::byte buf[sizeof (storage_type)];
676
- std::memcpy (soagen_storage_ptr (buf), soagen_storage_ptr (lhs), sizeof (storage_type));
677
- std::memcpy (soagen_storage_ptr (lhs), soagen_storage_ptr (rhs), sizeof (storage_type));
678
- std::memcpy (soagen_storage_ptr (rhs), soagen_storage_ptr (buf), sizeof (storage_type));
724
+ std::memcpy (soagen_aligned_storage (buf), soagen_aligned_storage (lhs), sizeof (storage_type));
725
+ std::memcpy (soagen_aligned_storage (lhs), soagen_aligned_storage (rhs), sizeof (storage_type));
726
+ std::memcpy (soagen_aligned_storage (rhs), soagen_aligned_storage (buf), sizeof (storage_type));
679
727
}
680
728
else if constexpr (std::is_swappable_v<storage_type>)
681
729
{
@@ -708,8 +756,8 @@ namespace soagen::detail
708
756
if SOAGEN_UNLIKELY (!count)
709
757
return ;
710
758
711
- lhs_buffer = soagen_storage_ptr (lhs_buffer + lhs_index * sizeof (storage_type));
712
- rhs_buffer = soagen_storage_ptr (rhs_buffer + rhs_index * sizeof (storage_type));
759
+ lhs_buffer = soagen_aligned_storage (lhs_buffer + lhs_index * sizeof (storage_type));
760
+ rhs_buffer = soagen_aligned_storage (rhs_buffer + rhs_index * sizeof (storage_type));
713
761
714
762
[[maybe_unused]] SOAGEN_CPP23_STATIC_CONSTEXPR size_t trivial_buf_size = 2048u / sizeof (storage_type);
715
763
@@ -724,8 +772,8 @@ namespace soagen::detail
724
772
std::memcpy (lhs_buffer, rhs_buffer, sizeof (storage_type) * num);
725
773
std::memcpy (rhs_buffer, buf, sizeof (storage_type) * num);
726
774
727
- lhs_buffer = soagen_storage_ptr (lhs_buffer + trivial_buf_size * sizeof (storage_type));
728
- rhs_buffer = soagen_storage_ptr (rhs_buffer + trivial_buf_size * sizeof (storage_type));
775
+ lhs_buffer = soagen_aligned_storage (lhs_buffer + trivial_buf_size * sizeof (storage_type));
776
+ rhs_buffer = soagen_aligned_storage (rhs_buffer + trivial_buf_size * sizeof (storage_type));
729
777
}
730
778
}
731
779
else
@@ -750,8 +798,8 @@ namespace soagen::detail
750
798
SOAGEN_ASSUME (dest_buffer != nullptr );
751
799
SOAGEN_ASSUME (source_buffer != nullptr );
752
800
753
- std::memmove (soagen_storage_ptr (dest_buffer + dest_index * sizeof (storage_type)),
754
- soagen_storage_ptr (source_buffer + source_index * sizeof (storage_type)),
801
+ std::memmove (soagen_aligned_storage (dest_buffer + dest_index * sizeof (storage_type)),
802
+ soagen_aligned_storage (source_buffer + source_index * sizeof (storage_type)),
755
803
count * sizeof (storage_type));
756
804
}
757
805
@@ -934,6 +982,6 @@ namespace soagen::detail
934
982
}
935
983
// / @endcond
936
984
937
- #undef soagen_storage_ptr
985
+ #undef soagen_aligned_storage
938
986
939
987
#include " header_end.hpp"
0 commit comments