@@ -309,6 +309,21 @@ namespace llama
309
309
template <typename T, template <typename ...> typename Tuple, typename ... Args>
310
310
constexpr inline auto
311
311
isDirectListInitializableFromTuple<T, Tuple<Args...>> = isDirectListInitializable<T, Args...>;
312
+
313
+ template <typename RecordDim, typename RecordCoord>
314
+ constexpr inline auto unboundArraysUntil = []() constexpr
315
+ {
316
+ std::size_t count = 0 ;
317
+ boost::mp11::mp_for_each<boost::mp11::mp_iota_c<RecordCoord::size>>(
318
+ [&](auto i) constexpr
319
+ {
320
+ using RC = RecordCoordFromList<boost::mp11::mp_take_c<typename RecordCoord::List, i>>;
321
+ using TypeAtRC = GetType<RecordDim, RC>;
322
+ count += static_cast <std::size_t >(internal::is_unbounded_array_v<TypeAtRC>);
323
+ });
324
+ return count;
325
+ }
326
+ ();
312
327
} // namespace internal
313
328
314
329
// / Virtual record type returned by \ref View after resolving an array dimensions coordinate or partially resolving
@@ -324,9 +339,11 @@ namespace llama
324
339
private:
325
340
using ArrayDims = typename View::Mapping::ArrayDims;
326
341
using RecordDim = typename View::Mapping::RecordDim;
342
+ using DynamicArrayExtentsArray = Array<std::size_t , internal::unboundArraysUntil<RecordDim, BoundRecordCoord>>;
327
343
328
- [[no_unique_address]] const ArrayDims arrayDimsCoord;
329
344
std::conditional_t <OwnView, View, View&> view;
345
+ [[no_unique_address]] const ArrayDims arrayDimsCoord;
346
+ [[no_unique_address]] const DynamicArrayExtentsArray dynamicArrayExtents;
330
347
331
348
public:
332
349
// / Subtree of the record dimension of View starting at BoundRecordCoord. If BoundRecordCoord is `RecordCoord<>`
@@ -337,15 +354,20 @@ namespace llama
337
354
LLAMA_FN_HOST_ACC_INLINE VirtualRecord ()
338
355
/* requires(OwnView) */
339
356
: arrayDimsCoord({})
357
+ , dynamicArrayExtents({})
340
358
, view{allocViewStack<0 , RecordDim>()}
341
359
{
342
360
static_assert (OwnView, " The default constructor of VirtualRecord is only available if it owns the view." );
343
361
}
344
362
345
363
LLAMA_FN_HOST_ACC_INLINE
346
- VirtualRecord (ArrayDims arrayDimsCoord, std::conditional_t <OwnView, View&&, View&> view)
347
- : arrayDimsCoord(arrayDimsCoord)
348
- , view{static_cast <decltype (view)>(view)}
364
+ VirtualRecord (
365
+ std::conditional_t <OwnView, View&&, View&> view,
366
+ ArrayDims arrayDimsCoord,
367
+ DynamicArrayExtentsArray dynamicArrayExtents = {})
368
+ : view{static_cast <decltype (view)>(view)}
369
+ , arrayDimsCoord(arrayDimsCoord)
370
+ , dynamicArrayExtents{dynamicArrayExtents}
349
371
{
350
372
}
351
373
@@ -388,15 +410,21 @@ namespace llama
388
410
{
389
411
using AbsolutCoord = Cat<BoundRecordCoord, RecordCoord<Coord...>>;
390
412
using AccessedType = GetType<RecordDim, AbsolutCoord>;
391
- if constexpr (isRecord<AccessedType> || internal::is_bounded_array<AccessedType>::value)
413
+ if constexpr (
414
+ isRecord<AccessedType> || internal::is_bounded_array<AccessedType>::value
415
+ || internal::is_unbounded_array_v<AccessedType>)
392
416
{
393
417
LLAMA_FORCE_INLINE_RECURSIVE
394
- return VirtualRecord<const View, AbsolutCoord>{arrayDimsCoord, this ->view };
418
+ return VirtualRecord<const View, AbsolutCoord>{
419
+ this ->view ,
420
+ arrayDimsCoord,
421
+ dynamicArrayExtents,
422
+ };
395
423
}
396
424
else
397
425
{
398
426
LLAMA_FORCE_INLINE_RECURSIVE
399
- return this ->view .accessor (arrayDimsCoord, AbsolutCoord{});
427
+ return this ->view .accessor (arrayDimsCoord, dynamicArrayExtents, AbsolutCoord{});
400
428
}
401
429
}
402
430
@@ -406,22 +434,24 @@ namespace llama
406
434
{
407
435
using AbsolutCoord = Cat<BoundRecordCoord, RecordCoord<Coord...>>;
408
436
using AccessedType = GetType<RecordDim, AbsolutCoord>;
409
- if constexpr (isRecord<AccessedType> || internal::is_bounded_array<AccessedType>::value)
437
+ if constexpr (
438
+ isRecord<AccessedType> || internal::is_bounded_array<AccessedType>::value
439
+ || internal::is_unbounded_array_v<AccessedType>)
410
440
{
411
441
LLAMA_FORCE_INLINE_RECURSIVE
412
- return VirtualRecord<View, AbsolutCoord>{arrayDimsCoord, this ->view };
442
+ return VirtualRecord<View, AbsolutCoord>{this ->view , arrayDimsCoord, dynamicArrayExtents };
413
443
}
414
444
else
415
445
{
416
446
LLAMA_FORCE_INLINE_RECURSIVE
417
- return this ->view .accessor (arrayDimsCoord, AbsolutCoord{});
447
+ return this ->view .accessor (arrayDimsCoord, dynamicArrayExtents, AbsolutCoord{});
418
448
}
419
449
}
420
450
421
451
// / Access a record in the record dimension underneath the current virtual record using a series of tags. If the
422
452
// / access resolves to a leaf, a reference to a variable inside the \ref View storage is returned, otherwise
423
453
// / another virtual record.
424
- template <typename ... Tags>
454
+ template <typename ... Tags, std:: enable_if_t <!std::disjunction_v<std::is_integral<Tags>...>, bool > = true >
425
455
LLAMA_FN_HOST_ACC_INLINE auto operator ()(Tags...) const -> decltype(auto )
426
456
{
427
457
using RecordCoord = GetCoordFromTagsRelative<RecordDim, BoundRecordCoord, Tags...>;
@@ -431,7 +461,7 @@ namespace llama
431
461
}
432
462
433
463
// FIXME(bgruber): remove redundancy
434
- template <typename ... Tags>
464
+ template <typename ... Tags, std:: enable_if_t <!std::disjunction_v<std::is_integral<Tags>...>, bool > = true >
435
465
LLAMA_FN_HOST_ACC_INLINE auto operator ()(Tags...) -> decltype(auto )
436
466
{
437
467
using RecordCoord = GetCoordFromTagsRelative<RecordDim, BoundRecordCoord, Tags...>;
@@ -440,6 +470,47 @@ namespace llama
440
470
return operator ()(RecordCoord{});
441
471
}
442
472
473
+ template <
474
+ typename ADD = AccessibleRecordDim,
475
+ std::enable_if_t <internal::is_unbounded_array_v<ADD>, bool > = true >
476
+ LLAMA_FN_HOST_ACC_INLINE auto operator ()(std::size_t i) const -> decltype(auto )
477
+ {
478
+ using AbsolutCoord = Cat<BoundRecordCoord, RecordCoord<dynamic>>;
479
+ using ResolvedType = GetType<RecordDim, AbsolutCoord>;
480
+ auto newDynamicArrayExtents = push_back (dynamicArrayExtents, i);
481
+ if constexpr (isRecord<ResolvedType> || internal::is_unbounded_array_v<ResolvedType>)
482
+ {
483
+ LLAMA_FORCE_INLINE_RECURSIVE
484
+ return VirtualRecord<const View, AbsolutCoord>{this ->view , arrayDimsCoord, newDynamicArrayExtents};
485
+ }
486
+ else
487
+ {
488
+ LLAMA_FORCE_INLINE_RECURSIVE
489
+ return this ->view .accessor (arrayDimsCoord, newDynamicArrayExtents, AbsolutCoord{});
490
+ }
491
+ }
492
+
493
+ // FIXME(bgruber): remove redundancy
494
+ template <
495
+ typename ADD = AccessibleRecordDim,
496
+ std::enable_if_t <internal::is_unbounded_array_v<ADD>, bool > = true >
497
+ LLAMA_FN_HOST_ACC_INLINE auto operator ()(std::size_t i) -> decltype(auto )
498
+ {
499
+ using AbsolutCoord = Cat<BoundRecordCoord, RecordCoord<dynamic>>;
500
+ using ResolvedType = GetType<RecordDim, AbsolutCoord>;
501
+ auto newDynamicArrayExtents = push_back (dynamicArrayExtents, i);
502
+ if constexpr (isRecord<ResolvedType> || internal::is_unbounded_array_v<ResolvedType>)
503
+ {
504
+ LLAMA_FORCE_INLINE_RECURSIVE
505
+ return VirtualRecord<View, AbsolutCoord>{this ->view , arrayDimsCoord, newDynamicArrayExtents};
506
+ }
507
+ else
508
+ {
509
+ LLAMA_FORCE_INLINE_RECURSIVE
510
+ return this ->view .accessor (arrayDimsCoord, newDynamicArrayExtents, AbsolutCoord{});
511
+ }
512
+ }
513
+
443
514
// we need this one to disable the compiler generated copy assignment
444
515
LLAMA_FN_HOST_ACC_INLINE auto operator =(const VirtualRecord& other) -> VirtualRecord&
445
516
{
0 commit comments