10
10
#include " macros.hpp"
11
11
#include " mapping/One.hpp"
12
12
13
+ #include < boost/pfr.hpp>
13
14
#include < boost/preprocessor/cat.hpp>
14
15
#include < type_traits>
15
16
@@ -259,18 +260,50 @@ namespace llama
259
260
template <typename ... Ts>
260
261
constexpr inline auto dependentFalse = false ;
261
262
263
+ template <typename T>
264
+ constexpr inline auto tupleish_size = []() constexpr
265
+ {
266
+ if constexpr (isTupleLike<T>)
267
+ return std::tuple_size_v<T>;
268
+ else if constexpr (std::is_aggregate_v<T>) // TODO
269
+ return boost::pfr::tuple_size_v<T>;
270
+ else
271
+ static_assert (
272
+ dependentFalse<T>,
273
+ " T is not a tuple like type or an aggregate to reflect with boost.pfr" );
274
+ }
275
+ ();
276
+
277
+ template <std::size_t I, typename T>
278
+ decltype (auto ) tupleish_get(T&& t)
279
+ {
280
+ using DT = std::decay_t <T>;
281
+ if constexpr (isTupleLike<DT>)
282
+ {
283
+ using std::get;
284
+ return get<I>(std::forward<T>(t));
285
+ }
286
+ else if constexpr (std::is_aggregate_v<DT>) // TODO
287
+ return boost::pfr::get<I>(std::forward<T>(t));
288
+ else
289
+ static_assert (
290
+ dependentFalse<T>,
291
+ " T is not a tuple like type or an aggregate to reflect with boost.pfr" );
292
+ }
293
+
262
294
template <typename Tuple1, typename Tuple2, std::size_t ... Is>
263
295
LLAMA_FN_HOST_ACC_INLINE void assignTuples (Tuple1&& dst, Tuple2&& src, std::index_sequence<Is...>);
264
296
265
297
template <typename T1, typename T2>
266
298
LLAMA_FN_HOST_ACC_INLINE void assignTupleElement (T1&& dst, T2&& src)
267
299
{
268
- if constexpr (isTupleLike<std::decay_t <T1>> && isTupleLike<std::decay_t <T2>>)
269
- {
270
- static_assert (std::tuple_size_v<std::decay_t <T1>> == std::tuple_size_v<std::decay_t <T2>>);
271
- assignTuples (dst, src, std::make_index_sequence<std::tuple_size_v<std::decay_t <T1>>>{});
272
- }
273
- else if constexpr (!isTupleLike<std::decay_t <T1>> && !isTupleLike<std::decay_t <T2>>)
300
+ using DT1 = std::decay_t <T1>;
301
+ using DT2 = std::decay_t <T2>;
302
+ constexpr auto isTupleish1 = isTupleLike<DT1> || std::is_aggregate_v<DT1>;
303
+ constexpr auto isTupleish2 = isTupleLike<DT2> || std::is_aggregate_v<DT2>;
304
+ if constexpr (isTupleish1 && isTupleish2)
305
+ assignTuples (dst, src, std::make_index_sequence<tupleish_size<DT1>>{});
306
+ else if constexpr (!isTupleish1 && !isTupleish2)
274
307
std::forward<T1>(dst) = std::forward<T2>(src);
275
308
else
276
309
static_assert (dependentFalse<T1, T2>, " Elements to assign are not tuple/tuple or non-tuple/non-tuple." );
@@ -279,9 +312,11 @@ namespace llama
279
312
template <typename Tuple1, typename Tuple2, std::size_t ... Is>
280
313
LLAMA_FN_HOST_ACC_INLINE void assignTuples (Tuple1&& dst, Tuple2&& src, std::index_sequence<Is...>)
281
314
{
282
- static_assert (std::tuple_size_v<std::decay_t <Tuple1>> == std::tuple_size_v<std::decay_t <Tuple2>>);
283
- using std::get;
284
- (assignTupleElement (get<Is>(std::forward<Tuple1>(dst)), get<Is>(std::forward<Tuple2>(src))), ...);
315
+ static_assert (tupleish_size<std::decay_t <Tuple1>> == tupleish_size<std::decay_t <Tuple2>>);
316
+ (assignTupleElement (
317
+ tupleish_get<Is>(std::forward<Tuple1>(dst)),
318
+ tupleish_get<Is>(std::forward<Tuple2>(src))),
319
+ ...);
285
320
}
286
321
287
322
template <typename T, typename Tuple, std::size_t ... Is>
@@ -659,7 +694,7 @@ namespace llama
659
694
template <typename TupleLike>
660
695
void store (const TupleLike& t)
661
696
{
662
- internal::assignTuples (asTuple (), t, std::make_index_sequence<std::tuple_size_v<TupleLike >>{});
697
+ internal::assignTuples (asTuple (), t, std::make_index_sequence<std::tuple_size_v<decltype ( asTuple ()) >>{});
663
698
}
664
699
};
665
700
} // namespace llama
0 commit comments