Skip to content

Commit

Permalink
make constructing VirtualRecords from types other than VirtualRecord …
Browse files Browse the repository at this point in the history
…is explicit

This fixes bugs where VirtualRecord's operator overloads were accidentally selected due to an implicit converting constructor given by VirtualRecord(const T&).
  • Loading branch information
bernhardmgruber committed Jun 4, 2021
1 parent 76e92f8 commit c60373b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
2 changes: 1 addition & 1 deletion examples/alpaka/asyncblur/asyncblur.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ struct BlurKernel
LLAMA_INDEPENDENT_DATA
for (auto x = start[1]; x < end[1]; ++x)
{
llama::One<PixelOnAcc> sum = 0;
llama::One<PixelOnAcc> sum{0};

using ItType = std::int64_t;
const ItType iBStart = SHARED ? ItType(y) - ItType(bi[0] * ElemsPerBlock) : y;
Expand Down
24 changes: 19 additions & 5 deletions include/llama/VirtualRecord.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,18 +329,32 @@ namespace llama
VirtualRecord(const VirtualRecord&) = default;
VirtualRecord(VirtualRecord&&) = default;

/// Create a VirtuaRecord from a single value or a different VirtualRecord. Only available for if the view is
/// owned. Used by llama::One.
template <typename T>
LLAMA_FN_HOST_ACC_INLINE VirtualRecord(const T& other)
/// Create a VirtuaRecord from a different VirtualRecord. Only available for if the view is owned. Used by
/// llama::One.
template <typename OtherView, typename OtherBoundRecordCoord, bool OtherOwnView>
LLAMA_FN_HOST_ACC_INLINE VirtualRecord(
const VirtualRecord<OtherView, OtherBoundRecordCoord, OtherOwnView>& virtualRecord)
/* requires(OwnView) */
: VirtualRecord()
{
static_assert(
OwnView,
"The copy constructor of VirtualRecord from a different VirtualRecord is only available if it owns the "
"view.");
*this = other;
*this = virtualRecord;
}

// TODO: unify with previous in C++20 and use explicit(cond)
/// Create a VirtuaRecord from a scalar. Only available for if the view is owned. Used by llama::One.
template <typename T, typename = std::enable_if_t<!is_VirtualRecord<T>>>
LLAMA_FN_HOST_ACC_INLINE explicit VirtualRecord(const T& scalar)
/* requires(OwnView) */
: VirtualRecord()
{
static_assert(
OwnView,
"The copy constructor of VirtualRecord from a scalar is only available if it owns the view.");
*this = scalar;
}

/// Access a record in the record dimension underneath the current virtual
Expand Down
11 changes: 11 additions & 0 deletions tests/virtualrecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,17 @@ TEST_CASE("VirtualRecord.One_inside_std::vector")
CHECK(v[2](tag::Weight{}) == 30);
}

TEST_CASE("VirtualRecord.One_from_scalar")
{
llama::One<Particle> p{42};
CHECK(p(tag::Pos{}, tag::A{}) == 42);
CHECK(p(tag::Pos{}, tag::Y{}) == 42);
CHECK(p(tag::Vel{}, tag::X{}) == 42);
CHECK(p(tag::Vel{}, tag::Y{}) == 42);
CHECK(p(tag::Vel{}, tag::Z{}) == 42);
CHECK(p(tag::Weight{}) == 42);
}

TEST_CASE("VirtualRecord.operator<<")
{
auto p = oneParticle();
Expand Down

0 comments on commit c60373b

Please sign in to comment.