From 9a284db0cbabec695fde878d8246846f81f2e70f Mon Sep 17 00:00:00 2001 From: Bernhard Manfred Gruber Date: Tue, 2 Mar 2021 22:39:11 +0100 Subject: [PATCH] use custom implementation of aligned sizeOf<> and offsetOf<> --- include/llama/Core.hpp | 56 ++++++++++++++++++++++++++++++++---------- tests/core.cpp | 20 ++++++++++----- 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/include/llama/Core.hpp b/include/llama/Core.hpp index 857188f6af..8b352454d4 100644 --- a/include/llama/Core.hpp +++ b/include/llama/Core.hpp @@ -272,14 +272,14 @@ namespace llama namespace internal { template - LLAMA_FN_HOST_ACC_INLINE constexpr void forEachLeaveImpl(T, DatumCoord coord, Functor&& functor) + LLAMA_FN_HOST_ACC_INLINE constexpr void forEachLeaveImpl(T*, DatumCoord coord, Functor&& functor) { functor(coord); }; template LLAMA_FN_HOST_ACC_INLINE constexpr void forEachLeaveImpl( - DatumStruct, + DatumStruct*, DatumCoord, Functor&& functor) { @@ -290,7 +290,7 @@ namespace llama LLAMA_FORCE_INLINE_RECURSIVE forEachLeaveImpl( - GetDatumElementType{}, + static_cast*>(nullptr), llama::DatumCoord{}, std::forward(functor)); }); @@ -308,7 +308,7 @@ namespace llama { LLAMA_FORCE_INLINE_RECURSIVE internal::forEachLeaveImpl( - GetType>{}, + static_cast>*>(nullptr), baseCoord, std::forward(functor)); } @@ -357,17 +357,39 @@ namespace llama } (); + namespace internal + { + constexpr void roundUpToMultiple(std::size_t& value, std::size_t multiple) + { + value = ((value + multiple - 1) / multiple) * multiple; + } + } // namespace internal + template - static constexpr auto sizeOf = sizeof(T); + inline constexpr std::size_t sizeOf = sizeof(T); /// The size a datum domain if it would be a normal struct. template - static constexpr auto sizeOf, Align> = []() constexpr + inline constexpr std::size_t sizeOf, Align> = []() constexpr { if constexpr (Align) - return sizeof(boost::mp11::mp_rename< - boost::mp11::mp_reverse>>, - std::tuple>{}); + { + using namespace boost::mp11; + + std::size_t size; + size = 0; // if we join this assignment with the previous line, MSVC crashes :( + using FlatDD = FlattenDatumDomain>; + mp_for_each>>([&](auto i) constexpr { + using T = mp_at; + internal::roundUpToMultiple(size, alignof(T)); + size += sizeof(T); + }); + + // final padding, so next struct can start right away + using FirstType = mp_first; + internal::roundUpToMultiple(size, alignof(FirstType)); + return size; + } else return (sizeOf, Align> + ...); } @@ -404,11 +426,19 @@ namespace llama { if constexpr (Align) { + using namespace boost::mp11; + constexpr auto i = flatDatumCoord; - using Tuple = boost::mp11::mp_rename>, std::tuple>; - constexpr auto n = boost::mp11::mp_size::value; - Tuple t; - return (std::intptr_t) std::addressof(std::get(t)) - (std::intptr_t) std::addressof(t); + + std::size_t offset = 0; + using FlatDD = FlattenDatumDomain; + mp_for_each>([&](auto i) constexpr { + using T = mp_at; + internal::roundUpToMultiple(offset, alignof(T)); + offset += sizeof(T); + }); + internal::roundUpToMultiple(offset, alignof(boost::mp11::mp_at_c)); + return offset; } else return internal::offsetOfImpl((DatumDomain*) nullptr, DatumCoord{}); diff --git a/tests/core.cpp b/tests/core.cpp index 1a8538b0d6..c907bb1274 100644 --- a/tests/core.cpp +++ b/tests/core.cpp @@ -15,12 +15,13 @@ namespace tag struct Weight {}; } +using XYZ = llama::DS< + llama::DE, + llama::DE, + llama::DE +>; using Particle = llama::DS< - llama::DE, - llama::DE, - llama::DE - >>, + llama::DE, llama::DE, llama::DE, llama::DE == 4); + STATIC_REQUIRE(llama::sizeOf == 24); STATIC_REQUIRE(llama::sizeOf == 52); } TEST_CASE("sizeOf.Align") { + STATIC_REQUIRE(llama::sizeOf == 4); + STATIC_REQUIRE(llama::sizeOf == 24); STATIC_REQUIRE(llama::sizeOf == 56); } @@ -163,6 +168,9 @@ TEST_CASE("offsetOf.Align") STATIC_REQUIRE(llama::offsetOf, true> == 51); } +template +struct S; + TEST_CASE("alignment") { using DD = llama::DS< @@ -183,7 +191,7 @@ TEST_CASE("alignment") STATIC_REQUIRE(llama::offsetOf, true> == 8); // aligned STATIC_REQUIRE(llama::offsetOf, true> == 16); STATIC_REQUIRE(llama::offsetOf, true> == 18); // aligned - STATIC_REQUIRE(llama::sizeOf == 24); + STATIC_REQUIRE(llama::sizeOf == 20); } TEST_CASE("GetCoordFromTags")