Skip to content

suggestive constexpr tuple validNbrParticles #972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions res/cmake/test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ if (test AND ${PHARE_EXEC_LEVEL_MIN} GREATER 0) # 0 = no tests
add_subdirectory(tests/core/utilities/range)
add_subdirectory(tests/core/utilities/index)
add_subdirectory(tests/core/utilities/indexer)
add_subdirectory(tests/core/utilities/meta)
add_subdirectory(tests/core/utilities/cellmap)
#add_subdirectory(tests/core/numerics/boundary_condition)
add_subdirectory(tests/core/numerics/interpolator)
Expand Down
43 changes: 41 additions & 2 deletions src/core/utilities/meta/meta_utilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define PHARE_CORE_UTILITIES_META_META_UTILITIES_HPP

#include <iterator>
#include <tuple>
#include <type_traits>

#include "core/utilities/types.hpp"
Expand All @@ -17,7 +18,7 @@ namespace core
struct dummy
{
using type = int;
static const type value = 0;
static type const value = 0;
};


Expand Down Expand Up @@ -69,6 +70,7 @@ namespace core
using SimulatorOption = std::tuple<DimConstant, InterpConstant,
std::integral_constant<std::size_t, ValidNbrParticles>...>;


constexpr decltype(auto) possibleSimulators()
{
// inner tuple = dim, interp, list[possible nbrParticles for dim/interp]
Expand All @@ -81,6 +83,43 @@ namespace core
SimulatorOption<DimConst<2>, InterpConst<3>, 4, 5, 8, 9, 25>>{};
}

constexpr static auto n_possibleSimulators()
{
return std::tuple_size_v<decltype(possibleSimulators())>;
}

template<typename Dimension, typename InterpOrder, typename... NbRefinedParts>
auto static constexpr validNbrParticlesFor(
std::tuple<Dimension, InterpOrder, NbRefinedParts...> const&)
{
return std::tuple<NbRefinedParts...>{};
}

template<std::size_t dim, std::size_t interp /*, etc*/>
auto static constexpr simulatorTupleIndex()
{
std::int64_t idx = -1;
auto constexpr simulators_list = possibleSimulators();
auto constexpr predicate = [](auto i, auto& idx) constexpr -> void {
using SimuType = std::decay_t<decltype(std::get<i>(simulators_list))>;
constexpr std::tuple_element_t<0, SimuType> _dim{};
constexpr std::tuple_element_t<1, SimuType> _interp{};
if constexpr (dim == _dim() and interp == _interp())
idx = i;
};

for_N<n_possibleSimulators()>(predicate, idx);

assert(idx >= 0);
return static_cast<std::size_t>(idx);
}

template<std::size_t dim, std::size_t interp>
auto static constexpr validNbrParticlesFor()
{
return validNbrParticlesFor(
std::get<simulatorTupleIndex<dim, interp>()>(possibleSimulators()));
}

template<typename Maker> // used from PHARE::amr::Hierarchy
auto makeAtRuntime(std::size_t dim, Maker&& maker)
Expand All @@ -90,7 +129,7 @@ namespace core

core::apply(possibleSimulators(), [&](auto const& simType) {
using SimuType = std::decay_t<decltype(simType)>;
using _dim = typename std::tuple_element<0, SimuType>::type;
using _dim = std::tuple_element_t<0, SimuType>;

if (!p)
p = maker(dim, _dim{});
Expand Down
24 changes: 12 additions & 12 deletions src/core/utilities/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@

NO_DISCARD inline std::optional<std::string> get_env(std::string const& key)
{
if (const char* val = std::getenv(key.c_str()))
if (char const* val = std::getenv(key.c_str()))
return std::string{val};
return std::nullopt;
}
Expand Down Expand Up @@ -424,8 +424,8 @@
forward_tuple,
};

template<std::uint16_t N, auto M = for_N_R_mode::make_tuple, typename Fn>
constexpr auto for_N(Fn& fn)
template<std::uint16_t N, auto M = for_N_R_mode::make_tuple, typename Fn, typename... Args>
constexpr auto for_N(Fn& fn, Args&&... args)
{
/* // how to use
for_N<2>([](auto ic) {
Expand All @@ -435,33 +435,33 @@
*/

static_assert(std::is_same_v<decltype(M), for_N_R_mode>);
using return_type
= std::decay_t<std::invoke_result_t<Fn, std::integral_constant<std::uint16_t, 0>>>;
using return_type = std::decay_t<
std::invoke_result_t<Fn, std::integral_constant<std::uint16_t, 0>, Args&...>>;
constexpr bool returns = !std::is_same_v<return_type, void>;

if constexpr (returns)
{
return std::apply(
[&](auto... ics) {
if constexpr (M == for_N_R_mode::make_tuple)
return std::make_tuple(fn(ics)...);
return std::make_tuple(fn(ics, args...)...);
else if constexpr (M == for_N_R_mode::make_array)
return std::array{fn(ics)...};
return std::array{fn(ics, args...)...};
else if constexpr (M == for_N_R_mode::forward_tuple)
return std::forward_as_tuple(fn(ics)...);
return std::forward_as_tuple(fn(ics, args...)...);
else
throw std::runtime_error("unknown return mode");
},
apply_N<N>(Apply{}));
}
else
std::apply([&](auto... ics) { (fn(ics), ...); }, apply_N<N>(Apply{}));
std::apply([&](auto... ics) { (fn(ics, args...), ...); }, apply_N<N>(Apply{}));
}

template<std::uint16_t N, auto M = for_N_R_mode::make_tuple, typename Fn>
constexpr auto for_N(Fn&& fn)
template<std::uint16_t N, auto M = for_N_R_mode::make_tuple, typename Fn, typename... Args>
constexpr auto for_N(Fn&& fn, Args&&... args)
{
return for_N<N, M>(fn);
return for_N<N, M>(fn, args...);
}

template<std::uint16_t N, typename Fn>
Expand Down
20 changes: 20 additions & 0 deletions tests/core/utilities/meta/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

cmake_minimum_required (VERSION 3.20.1)

project(test-meta-utilities)

set(SOURCES test_meta_utilities.cpp)

add_executable(${PROJECT_NAME} ${SOURCES})

target_include_directories(${PROJECT_NAME} PRIVATE
${GTEST_INCLUDE_DIRS}
)

target_link_libraries(${PROJECT_NAME} PRIVATE
phare_core
${GTEST_LIBS})

add_no_mpi_phare_test(${PROJECT_NAME} ${CMAKE_CURRENT_BINARY_DIR})


30 changes: 30 additions & 0 deletions tests/core/utilities/meta/test_meta_utilities.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <string>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

torm (copy paste)

#include <vector>
#include <random>

#include "core/utilities/meta/meta_utilities.hpp"

#include "gtest/gtest.h"

using namespace PHARE::core;

struct MetaUtilitiesTest : public ::testing::Test
{
};

TEST(MetaUtilitiesTest, testvalidNbrParticlesFor)
{
std::size_t constexpr static dim = 2;
std::size_t constexpr static interp = 2;

auto constexpr validNbrParticlesTuple = validNbrParticlesFor<dim, interp>();
auto constexpr n_validNbrParticles = std::tuple_size_v<decltype(validNbrParticlesTuple)>;
EXPECT_EQ(n_validNbrParticles, 5);
}

int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);

return RUN_ALL_TESTS();
}
Loading