Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: alpaka-group/llama
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1e46ed5e33bcfa3e5ff45aa1a94d57c78ed3ae4b
Choose a base ref
..
head repository: alpaka-group/llama
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f1bb7fc2cba1eb5a77a8c0a7ec7a8680e5300311
Choose a head ref
Showing with 30 additions and 20 deletions.
  1. +12 −20 include/llama/Core.hpp
  2. +18 −0 tests/core.cpp
32 changes: 12 additions & 20 deletions include/llama/Core.hpp
Original file line number Diff line number Diff line change
@@ -333,34 +333,30 @@ namespace llama
{
using type = boost::mp11::mp_append<typename FlattenRecordDimImpl<GetFieldType<Fields>>::type...>;
};

template <typename T>
constexpr auto fieldCountImpl(T*) -> std::size_t
{
return 1;
}

template <typename... Children>
constexpr auto fieldCountImpl(Record<Children...>*) -> std::size_t
{
return (fieldCountImpl(static_cast<GetFieldType<Children>*>(nullptr)) + ... + 0);
}
} // namespace internal

/// Returns a flat type list containing all leaf field types of the given record dimension.
template <typename RecordDim>
using FlatRecordDim = typename internal::FlattenRecordDimImpl<RecordDim>::type;

/// The total number of fields in the recursively expanded record dimension.
template <typename RecordDim>
inline constexpr std::size_t fieldCount = internal::fieldCountImpl(static_cast<RecordDim*>(nullptr));
inline constexpr std::size_t fieldCount = 1;

template <typename... Children>
inline constexpr std::size_t fieldCount<Record<Children...>> = (fieldCount<GetFieldType<Children>> + ... + 0);

namespace internal
{
// recursive formulation to benefit from template instantiation memoization
template <std::size_t I, typename... Children>
constexpr auto fieldCountUpTo(Record<Children...> r) -> std::size_t
constexpr auto fieldCountBefore(Record<Children...> r) -> std::size_t
{
if constexpr (I == 0)
return 0;
else
return fieldCountUpTo<I - 1>(r) + fieldCount<boost::mp11::mp_at_c<Record<Children...>, I - 1>>;
return fieldCountBefore<I - 1>(r)
+ fieldCount<GetFieldType<boost::mp11::mp_at_c<Record<Children...>, I - 1>>>;
}

template <typename T>
@@ -372,17 +368,13 @@ namespace llama
template <typename... Children, std::size_t I, std::size_t... Is>
constexpr auto flatRecordCoordImpl(Record<Children...>*, RecordCoord<I, Is...>) -> std::size_t
{
return fieldCountUpTo<I>(Record<Children...>{})
return fieldCountBefore<I>(Record<Children...>{})
+ flatRecordCoordImpl(
static_cast<GetFieldType<boost::mp11::mp_at_c<Record<Children...>, I>>*>(nullptr),
RecordCoord<Is...>{});
}
} // namespace internal

/// Returns a flat type list containing all leaf field types of the given record dimension.
template <typename RecordDim>
using FlatRecordDim = typename internal::FlattenRecordDimImpl<RecordDim>::type;

/// The equivalent zero based index into a flat record dimension (\ref FlatRecordDim) of the given hierarchical
/// record coordinate.
template <typename RecordDim, typename RecordCoord>
18 changes: 18 additions & 0 deletions tests/core.cpp
Original file line number Diff line number Diff line change
@@ -144,6 +144,24 @@ TEST_CASE("offsetOf.Align")
STATIC_REQUIRE(llama::offsetOf<Particle, llama::RecordCoord<4, 3>, true> == 51);
}

TEST_CASE("fieldCount")
{
STATIC_REQUIRE(llama::fieldCount<int> == 1);
STATIC_REQUIRE(llama::fieldCount<XYZ> == 3);
STATIC_REQUIRE(llama::fieldCount<Particle> == 11);
STATIC_REQUIRE(llama::fieldCount<Other> == 2);
}

TEST_CASE("fieldCountBefore")
{
STATIC_REQUIRE(llama::internal::fieldCountBefore<0>(Particle{}) == 0);
STATIC_REQUIRE(llama::internal::fieldCountBefore<1>(Particle{}) == 3);
STATIC_REQUIRE(llama::internal::fieldCountBefore<2>(Particle{}) == 4);
STATIC_REQUIRE(llama::internal::fieldCountBefore<3>(Particle{}) == 5);
STATIC_REQUIRE(llama::internal::fieldCountBefore<4>(Particle{}) == 7);
STATIC_REQUIRE(llama::internal::fieldCountBefore<5>(Particle{}) == 11);
}

template <int i>
struct S;