Skip to content

Commit 6cbddf1

Browse files
committed
resource manager variants handling
1 parent ffccf14 commit 6cbddf1

File tree

4 files changed

+295
-75
lines changed

4 files changed

+295
-75
lines changed

src/amr/resources_manager/resources_manager.hpp

Lines changed: 37 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <map>
2121
#include <optional>
22+
#include <tuple>
2223

2324

2425
namespace PHARE
@@ -127,6 +128,36 @@ namespace amr
127128
* we ask for them in a tuple, and recursively call registerResources() for all of the
128129
* unpacked elements
129130
*/
131+
132+
void static handle_sub_resources(auto fn, auto& obj, auto&&... args)
133+
{
134+
using ResourcesView = decltype(obj);
135+
136+
if constexpr (has_runtime_subresourceview_list<ResourcesView>::value)
137+
{
138+
for (auto& runtimeResource : obj.getRunTimeResourcesViewList())
139+
{
140+
using RuntimeResource = decltype(runtimeResource);
141+
if constexpr (has_sub_resources_v<RuntimeResource>)
142+
{
143+
fn(runtimeResource, args...);
144+
}
145+
else
146+
{
147+
std::visit([&](auto&& val) { fn(val, args...); }, runtimeResource);
148+
}
149+
}
150+
}
151+
152+
if constexpr (has_compiletime_subresourcesview_list<ResourcesView>::value)
153+
{
154+
// unpack the tuple subResources and apply for each element registerResources()
155+
// (recursively)
156+
std::apply([&](auto&... subResource) { (fn(subResource, args...), ...); },
157+
obj.getCompileTimeResourcesViewList());
158+
}
159+
}
160+
130161
template<typename ResourcesView>
131162
void registerResources(ResourcesView& obj)
132163
{
@@ -138,24 +169,8 @@ namespace amr
138169
{
139170
static_assert(has_sub_resources_v<ResourcesView>);
140171

141-
if constexpr (has_runtime_subresourceview_list<ResourcesView>::value)
142-
{
143-
for (auto& resourcesUser : obj.getRunTimeResourcesViewList())
144-
{
145-
this->registerResources(resourcesUser);
146-
}
147-
}
148-
149-
if constexpr (has_compiletime_subresourcesview_list<ResourcesView>::value)
150-
{
151-
// unpack the tuple subResources and apply for each element registerResources()
152-
// (recursively)
153-
std::apply(
154-
[this](auto&... subResource) {
155-
(this->registerResources(subResource), ...);
156-
},
157-
obj.getCompileTimeResourcesViewList());
158-
}
172+
handle_sub_resources( //
173+
[&](auto&&... args) { this->registerResources(args...); }, obj);
159174
}
160175
}
161176

@@ -180,21 +195,8 @@ namespace amr
180195
{
181196
static_assert(has_sub_resources_v<ResourcesView>);
182197

183-
if constexpr (has_runtime_subresourceview_list<ResourcesView>::value)
184-
{
185-
for (auto& resourcesUser : obj.getRunTimeResourcesViewList())
186-
{
187-
this->allocate(resourcesUser, patch, allocateTime);
188-
}
189-
}
190-
191-
if constexpr (has_compiletime_subresourcesview_list<ResourcesView>::value)
192-
{
193-
// unpack the tuple subResources and apply for each element registerResources()
194-
std::apply([this, &patch, allocateTime](auto&... subResource) //
195-
{ (this->allocate(subResource, patch, allocateTime), ...); },
196-
obj.getCompileTimeResourcesViewList());
197-
}
198+
handle_sub_resources( //
199+
[&](auto&&... args) { this->allocate(args...); }, obj, patch, allocateTime);
198200
}
199201
}
200202

@@ -403,24 +405,9 @@ namespace amr
403405
}
404406
else
405407
{
406-
if constexpr (has_runtime_subresourceview_list<ResourcesView>::value)
407-
{
408-
for (auto& resourcesUser : obj.getRunTimeResourcesViewList())
409-
{
410-
//
411-
this->getIDs_(resourcesUser, IDs);
412-
}
413-
}
408+
static_assert(has_sub_resources_v<ResourcesView>);
414409

415-
if constexpr (has_compiletime_subresourcesview_list<ResourcesView>::value)
416-
{
417-
// unpack the tuple subResources and apply for each element registerResources()
418-
std::apply(
419-
[this, &IDs](auto&... subResource) {
420-
(this->getIDs_(subResource, IDs), ...);
421-
},
422-
obj.getCompileTimeResourcesViewList());
423-
}
410+
handle_sub_resources([&](auto&&... args) { this->getIDs_(args...); }, obj, IDs);
424411
}
425412
}
426413

@@ -456,21 +443,6 @@ namespace amr
456443

457444

458445

459-
void static handle_sub_resources(auto fn, auto& obj, auto&&... args)
460-
{
461-
using ResourcesView = decltype(obj);
462-
463-
if constexpr (has_runtime_subresourceview_list<ResourcesView>::value)
464-
for (auto& runtimeResource : obj.getRunTimeResourcesViewList())
465-
fn(runtimeResource, args...);
466-
467-
// unpack the tuple subResources and apply for each element registerResources()
468-
// (recursively)
469-
if constexpr (has_compiletime_subresourcesview_list<ResourcesView>::value)
470-
std::apply([&](auto&... subResource) { (fn(subResource, args...), ...); },
471-
obj.getCompileTimeResourcesViewList());
472-
}
473-
474446

475447
template<typename ResourcesView>
476448
void setResources_(ResourcesView& obj, SAMRAI::hier::Patch const& patch) const

src/core/data/tensorfield/tensorfield.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
#ifndef PHARE_TENSORFIELD_HPP
22
#define PHARE_TENSORFIELD_HPP
33

4-
#include <cstddef>
5-
#include <string>
6-
#include <array>
7-
#include <vector>
8-
#include <unordered_map>
94

105
#include "core/def.hpp"
116
#include "core/utilities/types.hpp"
127
#include "core/data/vecfield/vecfield_component.hpp"
138

9+
10+
#include <array>
11+
#include <string>
12+
#include <vector>
13+
#include <cstddef>
14+
#include <unordered_map>
15+
1416
namespace PHARE::core::detail
1517
{
1618
template<std::size_t rank>

src/core/utilities/variants.hpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#ifndef PHARE_CORE_UTILITIES_RESOURCES_VARIANTS_HPP
2+
#define PHARE_CORE_UTILITIES_RESOURCES_VARIANTS_HPP
3+
4+
#include "core/utilities/types.hpp"
5+
6+
#include <core/logger.hpp>
7+
#include <tuple>
8+
#include <variant>
9+
#include <stdexcept>
10+
11+
namespace PHARE::core
12+
{
13+
template<typename T>
14+
auto decay_to_ptr()
15+
{
16+
return [](T& arg) mutable -> void* { return const_cast<std::decay_t<T>*>(&arg); };
17+
}
18+
19+
template<typename... Ts>
20+
struct varient_visitor_overloads : Ts...
21+
{
22+
using Ts::operator()...;
23+
};
24+
25+
template<typename... Ts>
26+
varient_visitor_overloads(Ts&&...) -> varient_visitor_overloads<std::decay_t<Ts>...>;
27+
28+
29+
template<typename... Args>
30+
auto constexpr _visit_ptr_overloads(std::tuple<Args...>*)
31+
{
32+
return varient_visitor_overloads{decay_to_ptr<Args>()...,
33+
[](auto&) mutable -> void* { return nullptr; }};
34+
}
35+
36+
37+
template<typename T, typename... Ts>
38+
struct unique : std::type_identity<T>
39+
{
40+
};
41+
42+
template<typename... Ts, typename U, typename... Us>
43+
struct unique<std::tuple<Ts...>, U, Us...>
44+
: std::conditional_t<(std::is_same_v<U, Ts> || ...), unique<std::tuple<Ts...>, Us...>,
45+
unique<std::tuple<Ts..., U>, Us...>>
46+
{
47+
};
48+
49+
template<typename... Ts>
50+
using unique_tuple = typename unique<std::tuple<>, Ts...>::type;
51+
52+
53+
54+
template<typename... Args>
55+
auto constexpr visit_ptr_overloads()
56+
{
57+
return _visit_ptr_overloads(static_cast<unique_tuple<Args...>*>(nullptr));
58+
}
59+
60+
61+
62+
template<typename Type, typename Variants>
63+
auto& get_as_ref_or_throw(Variants& variants, std::size_t const start = 0)
64+
{
65+
for (std::size_t idx = start; idx < variants.size(); ++idx)
66+
if (auto type = std::visit(visit_ptr_overloads<Type>(), variants[idx]))
67+
return *reinterpret_cast<Type*>(type);
68+
69+
throw std::runtime_error("No element in variant for type");
70+
}
71+
72+
73+
// ARGS MUST BE IN THE SAME ORDER AS VARIANT LIST TYPES!!!!!
74+
template<typename... Args, typename Variants>
75+
auto get_as_tuple_or_throw(Variants& variants, std::size_t start = 0)
76+
{
77+
using Tuple = std::tuple<Args...>;
78+
auto constexpr tuple_size = std::tuple_size_v<Tuple>;
79+
80+
auto ptr_or_null = visit_ptr_overloads<Args...>();
81+
82+
auto pointer_tuple = for_N<tuple_size>([&](auto i) mutable {
83+
using Type = std::tuple_element_t<i, Tuple>;
84+
85+
for (std::size_t idx = start; idx < variants.size(); ++idx)
86+
if (auto ptr = std::visit(ptr_or_null, variants[idx]))
87+
{
88+
++start;
89+
return reinterpret_cast<Type*>(ptr);
90+
}
91+
return static_cast<Type*>(nullptr);
92+
});
93+
94+
for_N<tuple_size>([&](auto i) {
95+
if (std::get<i>(pointer_tuple) == nullptr)
96+
throw std::runtime_error("No element in variant for type");
97+
});
98+
99+
return for_N<tuple_size, for_N_R_mode::forward_tuple>(
100+
[&](auto i) -> auto& { return *std::get<i>(pointer_tuple); });
101+
}
102+
103+
template<typename Type>
104+
auto& get_from_variants(auto& variants, Type& arg)
105+
{
106+
std::size_t start = 0;
107+
108+
while (start < variants.size())
109+
{
110+
if (auto& res = get_as_ref_or_throw<Type>(variants, start); res.name() == arg.name())
111+
return res;
112+
++start;
113+
}
114+
115+
if (start == variants.size())
116+
std::runtime_error("Required name not found in variants: " + arg.name());
117+
}
118+
119+
120+
template<typename... Args>
121+
auto get_from_variants(auto& variants, Args&... args)
122+
requires(sizeof...(Args) > 1)
123+
{
124+
return std::forward_as_tuple(get_from_variants(variants, args)...);
125+
}
126+
127+
128+
129+
130+
} // namespace PHARE::core
131+
132+
133+
#endif /*PHARE_CORE_UTILITIES_RESOURCES_VARIANTS_HPP*/

0 commit comments

Comments
 (0)