10 #include <type_traits>
12 #if __has_include(<concepts>)
17 #ifdef __cpp_lib_concepts
20 concept isConstexpr = requires { std::integral_constant<decltype(I), I>{}; };
24 concept Mapping = requires(M m) {
26 typename M::RecordDim;
29 } -> std::same_as<typename M::ArrayExtents>;
32 } -> std::same_as<std::size_t>;
33 requires isConstexpr<M::blobCount>;
35 m.blobSize(
typename M::ArrayExtents::value_type{})
36 } -> std::same_as<typename M::ArrayExtents::value_type>;
40 template<
typename M,
typename RC>
41 concept PhysicalField = requires(M m,
typename M::ArrayExtents::Index ai) {
43 m.blobNrAndOffset(ai, RC{})
44 } -> std::same_as<NrAndOffset<typename M::ArrayExtents::value_type>>;
51 using fn = mp_bool<PhysicalField<M, RC>>;
56 inline constexpr
bool allFieldsArePhysical
57 = mp_all_of<LeafRecordCoords<typename M::RecordDim>, MakeIsPhysical<M>::template fn>::value;
61 concept PhysicalMapping = Mapping<M> && allFieldsArePhysical<M>;
65 concept LValueReference = std::is_lvalue_reference_v<R>;
69 concept AdlTwoStepSwappable = requires(R a, R b) {
swap(a, b); } || requires(R a, R b) {
std::swap(a, b); };
73 concept ProxyReference = std::is_copy_constructible_v<R> && std::is_copy_assignable_v<R> && requires(R r) {
74 typename R::value_type;
76 static_cast<typename R::value_type
>(r)
77 } -> std::same_as<typename R::value_type>;
79 r = std::declval<typename R::value_type>()
80 } -> std::same_as<R&>;
81 } && AdlTwoStepSwappable<R>;
85 concept AnyReference = LValueReference<R> || ProxyReference<R>;
88 template<
typename R,
typename T>
89 concept AnyReferenceTo = (LValueReference<R> && std::is_same_v<std::remove_cvref_t<R>, T>)
90 || (ProxyReference<R> && std::is_same_v<typename R::value_type, T>);
93 template<
typename M,
typename RC>
95 =
M::isComputed(RC{}) && requires(M m,
typename M::ArrayExtents::Index ai, std::byte** blobs) {
97 m.compute(ai, RC{}, blobs)
98 } -> AnyReferenceTo<GetType<typename M::RecordDim, RC>>;
102 struct MakeIsComputed
104 template<
typename RC>
105 using fn = mp_bool<ComputedField<M, RC>>;
110 inline constexpr
bool allFieldsAreComputed
111 = mp_all_of<LeafRecordCoords<typename M::RecordDim>, MakeIsComputed<M>::template fn>::value;
115 concept FullyComputedMapping = Mapping<M> && allFieldsAreComputed<M>;
120 typename LeafCoords = LeafRecordCoords<typename M::RecordDim>,
121 std::size_t PhysicalCount = mp_count_if<LeafCoords, MakeIsPhysical<M>::template fn>::value,
122 std::size_t ComputedCount = mp_count_if<LeafCoords, MakeIsComputed<M>::template fn>::value>
123 inline constexpr
bool allFieldsArePhysicalOrComputed
124 = (PhysicalCount + ComputedCount) >= mp_size<LeafCoords>::value && PhysicalCount > 0
125 && ComputedCount > 0;
131 concept PartiallyComputedMapping = Mapping<M> && allFieldsArePhysicalOrComputed<M>;
136 concept Blob = requires(B b, std::size_t i) {
140 requires std::is_lvalue_reference_v<decltype(b[i])>;
141 requires std::same_as<std::remove_cvref_t<decltype(b[i])>, std::byte>
142 || std::same_as<std::remove_cvref_t<decltype(b[i])>,
unsigned char>;
146 template<
typename BA>
147 concept BlobAllocator = requires(BA ba, std::size_t size) {
149 ba(std::integral_constant<std::size_t, 16>{}, size)
155 concept AnyView = requires(V v,
const V cv) {
157 typename V::BlobType;
160 typename V::RecordDim;
161 typename V::Accessor;
163 typename V::iterator;
164 typename V::const_iterator;
168 } -> std::same_as<typename V::Mapping&>;
172 } -> std::same_as<const typename V::Mapping&>;
176 } -> std::same_as<typename V::Accessor&>;
180 } -> std::same_as<const typename V::Accessor&>;
184 } -> std::same_as<typename V::ArrayExtents>;
188 } -> std::same_as<typename V::iterator>;
192 } -> std::same_as<typename V::const_iterator>;
196 } -> std::same_as<typename V::iterator>;
200 } -> std::same_as<typename V::const_iterator>;
204 } -> std::same_as<Array<typename V::BlobType, V::Mapping::blobCount>&>;
207 } -> std::same_as<const Array<typename V::BlobType, V::Mapping::blobCount>&>;
209 v(std::declval<typename V::ArrayIndex>());
210 cv(std::declval<typename V::ArrayIndex>());
211 v[std::declval<typename V::ArrayIndex>()];
212 cv[std::declval<typename V::ArrayIndex>()];
220 template<
typename R,
typename =
void>
229 typename R::value_type,
230 decltype(static_cast<typename R::value_type>(std::declval<R&>())),
231 decltype(std::declval<R&>() = std::declval<typename R::value_type>())>>
232 : std::bool_constant<std::is_copy_constructible_v<R> && std::is_copy_assignable_v<R>>
239 #ifdef __cpp_lib_concepts
constexpr bool isProxyReference
ArrayIndex(Args...) -> ArrayIndex< typename internal::IndexTypeFromArgs< std::size_t, Args... >::type, sizeof...(Args)>
ArrayExtents(Args...) -> ArrayExtents< typename internal::IndexTypeFromArgs< std::size_t, Args... >::type,(Args{}, dyn)... >
constexpr bool isComputed
Returns true if the field accessed via the given mapping and record coordinate is a computed value.
auto swap(RecordRef< ViewA, BoundRecordDimA, OwnViewA > &a, RecordRef< ViewB, BoundRecordDimB, OwnViewB > &b) noexcept -> std::enable_if_t< std::is_same_v< typename RecordRef< ViewA, BoundRecordDimA, OwnViewA >::AccessibleRecordDim, typename RecordRef< ViewB, BoundRecordDimB, OwnViewB >::AccessibleRecordDim >>