@@ -60,8 +60,8 @@ namespace llama
60
60
template <std::size_t Dim, typename DatumDomain>
61
61
LLAMA_FN_HOST_ACC_INLINE auto allocViewStack () -> decltype(auto )
62
62
{
63
+ using Mapping = llama::mapping::One<ArrayDomain<Dim>, DatumDomain>;
63
64
using MadeDatumDomain = mapping::MakeDatumDomain<DatumDomain>; // user might pass struct to reflect
64
- using Mapping = llama::mapping::One<ArrayDomain<Dim>, MadeDatumDomain>;
65
65
return allocView (Mapping{}, llama::allocator::Stack<sizeOf<MadeDatumDomain>>{});
66
66
}
67
67
@@ -342,8 +342,53 @@ namespace llama
342
342
template <typename T, template <typename ...> typename Tuple, typename ... Args>
343
343
constexpr inline auto
344
344
isDirectListInitializableFromTuple<T, Tuple<Args...>> = isDirectListInitializable<T, Args...>;
345
+
346
+ template <typename Tuplish, typename Coord>
347
+ struct GetNestedTuplishType ;
348
+
349
+ template <typename Tuplish, std::size_t Head, std::size_t ... Tail>
350
+ struct GetNestedTuplishType <Tuplish, DatumCoord<Head, Tail...>>
351
+ {
352
+ using type = typename GetNestedTuplishType<
353
+ std::decay_t <decltype(tupleish_get<Head>(std::declval<Tuplish>()))>,
354
+ DatumCoord<Tail...>>::type;
355
+ };
356
+
357
+ template <typename Tuplish>
358
+ struct GetNestedTuplishType <Tuplish, DatumCoord<>>
359
+ {
360
+ using type = Tuplish;
361
+ };
362
+
363
+ template <typename OriginalDatumDomain, typename BoundDatumDomain>
364
+ struct GetValueStructOrVoid
365
+ {
366
+ using type = typename internal::GetNestedTuplishType<OriginalDatumDomain, BoundDatumDomain>::type;
367
+ };
368
+
369
+ template <typename ... Elements, typename BoundDatumDomain>
370
+ struct GetValueStructOrVoid <DatumStruct<Elements...>, BoundDatumDomain>
371
+ {
372
+ using type = void ;
373
+ };
345
374
} // namespace internal
346
375
376
+ template <typename T>
377
+ struct IndirectValue
378
+ {
379
+ T value;
380
+
381
+ auto operator ->() -> T*
382
+ {
383
+ return &value;
384
+ }
385
+
386
+ auto operator ->() const -> const T*
387
+ {
388
+ return &value;
389
+ }
390
+ };
391
+
347
392
// / Virtual data type returned by \ref View after resolving a user domain
348
393
// / coordinate or partially resolving a \ref DatumCoord. A virtual datum
349
394
// / does not hold data itself (thus named "virtual"), it just binds enough
@@ -359,6 +404,8 @@ namespace llama
359
404
private:
360
405
using ArrayDomain = typename View::Mapping::ArrayDomain;
361
406
using DatumDomain = typename View::Mapping::DatumDomain;
407
+ using ValueStruct = typename internal::
408
+ GetValueStructOrVoid<typename View::Mapping::OriginalDatumDomain, BoundDatumDomain>::type;
362
409
363
410
const ArrayDomain userDomainPos;
364
411
std::conditional_t <OwnView, View, View&> view;
@@ -369,10 +416,12 @@ namespace llama
369
416
// / AccessibleDatumDomain is the same as `Mapping::DatumDomain`.
370
417
using AccessibleDatumDomain = GetType<DatumDomain, BoundDatumDomain>;
371
418
419
+ static constexpr auto supportsValueLoad = !std::is_void_v<ValueStruct>;
420
+
372
421
LLAMA_FN_HOST_ACC_INLINE VirtualDatum ()
373
422
/* requires(OwnView) */
374
423
: userDomainPos({})
375
- , view{allocViewStack<1 , DatumDomain>()}
424
+ , view{allocViewStack<1 , std:: conditional_t <supportsValueLoad, ValueStruct, DatumDomain> >()}
376
425
{
377
426
static_assert (OwnView, " The default constructor of VirtualDatum is only available if the " );
378
427
}
@@ -691,6 +740,20 @@ namespace llama
691
740
return {*this };
692
741
}
693
742
743
+ // template <typename = std::enable_if_t<supportsValueLoad>>
744
+ auto operator ->() const -> IndirectValue<ValueStruct>
745
+ {
746
+ static_assert (supportsValueLoad);
747
+ return {loadAs<ValueStruct>()};
748
+ }
749
+
750
+ // template <typename = std::enable_if_t<supportsValueLoad>>
751
+ auto operator *() const -> ValueStruct
752
+ {
753
+ static_assert (supportsValueLoad);
754
+ return loadAs<ValueStruct>();
755
+ }
756
+
694
757
template <typename TupleLike>
695
758
void store (const TupleLike& t)
696
759
{
0 commit comments