Skip to content

Commit

Permalink
Merge pull request #141 from bernhardmgruber/rectuple
Browse files Browse the repository at this point in the history
Add hierarchical asTuple
  • Loading branch information
bernhardmgruber authored Dec 21, 2020
2 parents 4dfd971 + ca78d46 commit adaff4c
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 7 deletions.
30 changes: 27 additions & 3 deletions include/llama/View.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,16 +211,30 @@ namespace llama
};

template <typename TWithOptionalConst, typename T>
LLAMA_FN_HOST_ACC_INLINE auto asTupleImpl(TWithOptionalConst& leaf, T)
LLAMA_FN_HOST_ACC_INLINE auto asTupleImpl(TWithOptionalConst& leaf, T) -> std::
enable_if_t<!is_VirtualDatum<std::decay_t<TWithOptionalConst>>, std::reference_wrapper<TWithOptionalConst>>
{
return leaf;
}

template <typename VirtualDatum, typename... Elements>
LLAMA_FN_HOST_ACC_INLINE auto asTupleImpl(VirtualDatum&& vd, DatumStruct<Elements...>)
{
return std::make_tuple(asTupleImpl(vd(GetDatumElementTag<Elements>{}), GetDatumElementType<Elements>{})...);
}

template <typename TWithOptionalConst, typename T>
LLAMA_FN_HOST_ACC_INLINE auto asFlatTupleImpl(TWithOptionalConst& leaf, T)
-> std::enable_if_t<!is_VirtualDatum<std::decay_t<TWithOptionalConst>>, std::tuple<TWithOptionalConst&>>
{
return {leaf};
}

template <typename VirtualDatum, typename... Elements>
LLAMA_FN_HOST_ACC_INLINE auto asTupleImpl(VirtualDatum&& vd, DatumStruct<Elements...>)
LLAMA_FN_HOST_ACC_INLINE auto asFlatTupleImpl(VirtualDatum&& vd, DatumStruct<Elements...>)
{
return std::tuple_cat(asTupleImpl(vd(GetDatumElementTag<Elements>{}), GetDatumElementType<Elements>{})...);
return std::tuple_cat(
asFlatTupleImpl(vd(GetDatumElementTag<Elements>{}), GetDatumElementType<Elements>{})...);
}
} // namespace internal

Expand Down Expand Up @@ -492,6 +506,16 @@ namespace llama
{
return internal::asTupleImpl(*this, AccessibleDatumDomain{});
}

auto asFlatTuple()
{
return internal::asFlatTupleImpl(*this, AccessibleDatumDomain{});
}

auto asFlatTuple() const
{
return internal::asFlatTupleImpl(*this, AccessibleDatumDomain{});
}
};

/// Central LLAMA class holding memory for storage and giving access to
Expand Down
105 changes: 101 additions & 4 deletions tests/virtualdatum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,14 +384,15 @@ TEST_CASE("VirtualDatum.asTuple.types")

std::tuple<int&, int&> pos = datum(tag::Pos{}).asTuple();
std::tuple<int&, int&, int&> vel = datum(tag::Vel{}).asTuple();
std::tuple<int&, int&, int&, int&, int&, int&> name = datum.asTuple();
std::tuple<std::tuple<int&, int&>, std::tuple<int&, int&, int&>, int&> name = datum.asTuple();
}
{
const llama::One<Name> datum;

std::tuple<const int&, const int&> pos = datum(tag::Pos{}).asTuple();
std::tuple<const int&, const int&, const int&> vel = datum(tag::Vel{}).asTuple();
std::tuple<const int&, const int&, const int&, const int&, const int&, const int&> name = datum.asTuple();
std::tuple<std::tuple<const int&, const int&>, std::tuple<const int&, const int&, const int&>, const int&> name
= datum.asTuple();
}
}

Expand All @@ -415,7 +416,7 @@ TEST_CASE("VirtualDatum.asTuple.assign")
CHECK(datum(tag::Vel{}, tag::Z{}) == 2);
CHECK(datum(tag::Weight{}) == 0);

datum.asTuple() = std::tuple{3, 3, 3, 3, 3, 3};
datum.asTuple() = std::tuple{std::tuple{3, 3}, std::tuple{3, 3, 3}, 3};
CHECK(datum(tag::Pos{}, tag::A{}) == 3);
CHECK(datum(tag::Pos{}, tag::Y{}) == 3);
CHECK(datum(tag::Vel{}, tag::X{}) == 3);
Expand Down Expand Up @@ -454,7 +455,103 @@ TEST_CASE("VirtualDatum.asTuple.structuredBindings")
}

{
auto [a, y1, x, y2, z, w] = datum.asTuple();
auto [pos, vel, w] = datum.asTuple();
auto [a, y1] = pos;
auto [x, y2, z] = vel;
a = 10;
y1 = 20;
x = 30;
y2 = 40;
z = 50;
w = 60;
CHECK(datum(tag::Pos{}, tag::A{}) == 10);
CHECK(datum(tag::Pos{}, tag::Y{}) == 20);
CHECK(datum(tag::Vel{}, tag::X{}) == 30);
CHECK(datum(tag::Vel{}, tag::Y{}) == 40);
CHECK(datum(tag::Vel{}, tag::Z{}) == 50);
CHECK(datum(tag::Weight{}) == 60);
}
}


TEST_CASE("VirtualDatum.asFlatTuple.types")
{
{
llama::One<Name> datum;

std::tuple<int&, int&> pos = datum(tag::Pos{}).asFlatTuple();
std::tuple<int&, int&, int&> vel = datum(tag::Vel{}).asFlatTuple();
std::tuple<int&, int&, int&, int&, int&, int&> name = datum.asFlatTuple();
}
{
const llama::One<Name> datum;

std::tuple<const int&, const int&> pos = datum(tag::Pos{}).asFlatTuple();
std::tuple<const int&, const int&, const int&> vel = datum(tag::Vel{}).asFlatTuple();
std::tuple<const int&, const int&, const int&, const int&, const int&, const int&> name = datum.asFlatTuple();
}
}

TEST_CASE("VirtualDatum.asFlatTuple.assign")
{
llama::One<Name> datum;

datum(tag::Pos{}).asFlatTuple() = std::tuple{1, 1};
CHECK(datum(tag::Pos{}, tag::A{}) == 1);
CHECK(datum(tag::Pos{}, tag::Y{}) == 1);
CHECK(datum(tag::Vel{}, tag::X{}) == 0);
CHECK(datum(tag::Vel{}, tag::Y{}) == 0);
CHECK(datum(tag::Vel{}, tag::Z{}) == 0);
CHECK(datum(tag::Weight{}) == 0);

datum(tag::Vel{}).asFlatTuple() = std::tuple{2, 2, 2};
CHECK(datum(tag::Pos{}, tag::A{}) == 1);
CHECK(datum(tag::Pos{}, tag::Y{}) == 1);
CHECK(datum(tag::Vel{}, tag::X{}) == 2);
CHECK(datum(tag::Vel{}, tag::Y{}) == 2);
CHECK(datum(tag::Vel{}, tag::Z{}) == 2);
CHECK(datum(tag::Weight{}) == 0);

datum.asFlatTuple() = std::tuple{3, 3, 3, 3, 3, 3};
CHECK(datum(tag::Pos{}, tag::A{}) == 3);
CHECK(datum(tag::Pos{}, tag::Y{}) == 3);
CHECK(datum(tag::Vel{}, tag::X{}) == 3);
CHECK(datum(tag::Vel{}, tag::Y{}) == 3);
CHECK(datum(tag::Vel{}, tag::Z{}) == 3);
CHECK(datum(tag::Weight{}) == 3);
}

TEST_CASE("VirtualDatum.asFlatTuple.structuredBindings")
{
llama::One<Name> datum;

{
auto [a, y] = datum(tag::Pos{}).asFlatTuple();
a = 1;
y = 2;
CHECK(datum(tag::Pos{}, tag::A{}) == 1);
CHECK(datum(tag::Pos{}, tag::Y{}) == 2);
CHECK(datum(tag::Vel{}, tag::X{}) == 0);
CHECK(datum(tag::Vel{}, tag::Y{}) == 0);
CHECK(datum(tag::Vel{}, tag::Z{}) == 0);
CHECK(datum(tag::Weight{}) == 0);
}

{
auto [x, y, z] = datum(tag::Vel{}).asFlatTuple();
x = 3;
y = 4;
z = 5;
CHECK(datum(tag::Pos{}, tag::A{}) == 1);
CHECK(datum(tag::Pos{}, tag::Y{}) == 2);
CHECK(datum(tag::Vel{}, tag::X{}) == 3);
CHECK(datum(tag::Vel{}, tag::Y{}) == 4);
CHECK(datum(tag::Vel{}, tag::Z{}) == 5);
CHECK(datum(tag::Weight{}) == 0);
}

{
auto [a, y1, x, y2, z, w] = datum.asFlatTuple();
a = 10;
y1 = 20;
x = 30;
Expand Down

0 comments on commit adaff4c

Please sign in to comment.