69#ifndef LIB_HETERO_DATA_H
70#define LIB_HETERO_DATA_H
93 template<
typename...DATA>
104 template<
size_t seg,
typename...DATA>
107 , std::tuple<DATA...>
113 template<
typename SPEC>
115 template<
typename SPEC>
118 template<
size_t slot>
auto&
get() noexcept {
return std::get<slot>(*
this); }
119 template<
typename X>
auto&
get() noexcept {
return std::get<X>(*
this); }
129 template<
size_t seg,
typename...DATA,
class TAIL>
130 class HeteroData<meta::Node<StorageFrame<seg, DATA...>,TAIL>>
138 static constexpr size_t localSiz =
sizeof...(DATA);
140 template<
size_t slot>
141 static constexpr bool isLocal = slot < localSiz;
143 template<
size_t slot>
144 using PickType = std::conditional_t<isLocal<slot>, std::tuple_element<slot,Tuple>
145 ,
typename _Tail::template
PickType<slot-localSiz>>;
150 if (Frame::next ==
nullptr)
152 return *
reinterpret_cast<_Tail*
> (Frame::next);
155 template<
typename...SPEC>
159 return reinterpret_cast<_Self&
> (frontChain);
161 template<
typename...SPEC>
165 return reinterpret_cast<_Self const&
> (frontChain);
169 template<
typename...XX>
178 static constexpr size_t
181 return localSiz + _Tail::size();
185 template<
size_t slot>
190 template<
size_t slot>
194 static_assert (slot < size(),
"HeteroData access index beyond defined data");
195 if constexpr (slot < localSiz)
196 return std::get<slot> (*
this);
198 return accessTail().template get<slot-localSiz>();
201 template<
size_t slot>
205 return const_cast<HeteroData*
>(
this)->get<slot>();
215 template<
size_t slot>
224 auto& fullChain = _Self::recast (frontEnd);
225 return fullChain.template get<slot>();
228 template<
typename HH>
229 Type& operator() (HH& frontEnd)
const {
return Accessor::retrieveData (frontEnd); }
247 template<
typename...VALS>
254 template<
typename...INIT>
258 return {initArgs ...};
260 template<
typename...INIT>
264 return *
new(storage)
NewFrame{initArgs ...};
271 return ChainType::recast (frontChain);
274 template<
typename...XVALS>
277 template<
size_t slot>
292 static size_t constexpr size() {
return 0; }
306 template<
typename...DATA>
308 :
public HeteroData<meta::Node<StorageFrame<0, DATA...>, meta::Nil>>
317 template<
typename...INIT>
321 return {initArgs ...};
344 while (segments and last->next)
349 ASSERT (last->next ==
nullptr and segments == 1
350 ,
"Failure to attach new data segment to HeteroData: "
351 "assumed type structure does not match real connectivity, "
352 "end-of-chain encountered with %d type segment(s) remaining"
368 while (segments and seg->
next)
369 if (segments == 1 and seg->
next == chainBlock)
379 NOTREACHED (
"Failure to detach a data segment from HeteroData: "
380 "assumed type structure does not match real connectivity");
400 template<
size_t seg,
typename...DATA>
401 template<
typename SPEC>
406 StorageLoc*& lastLink = checkedTraversal (seg, firstSeg);
407 ENSURE (lastLink ==
nullptr);
412 template<
size_t seg,
typename...DATA>
413 template<
typename SPEC>
418 checkedDetach (seg, firstSeg,
this);
428 template<
typename...DATA>
429 struct tuple_size<
lib::HeteroData<DATA...> >
430 : integral_constant<size_t, lib::HeteroData<DATA...>::size()>
434 template<
size_t I,
typename...DATA>
435 struct tuple_element<I,
lib::HeteroData<DATA...> >
440 struct tuple_element<I,
lib::HeteroData<lib::meta::Nil> >
442 static_assert (
"accessing element-type of an empty HeteroData block");
451 template<
size_t seg,
typename...DATA>
452 struct tuple_size<
lib::StorageFrame<seg,DATA...> >
453 : tuple_size<typename lib::StorageFrame<seg,DATA...>::Tuple>
457 template<
size_t I,
size_t seg,
typename...DATA>
458 struct tuple_element<I,
lib::StorageFrame<seg,DATA...> >
459 : tuple_element<I, typename lib::StorageFrame<seg,DATA...>::Tuple>
A setup with chained data tuples residing in distributed storage.
_FrontBlock::Frame NewFrame
static HeteroData build(INIT &&...initArgs)
HeteroData< meta::Node< StorageFrame< 0, DATA... >, meta::Nil > > _FrontBlock
Derived specific exceptions within Lumiera's exception hierarchy.
Any copy and copy construction prohibited.
Lumiera error handling (C++ interface).
void checkedDetach(size_t segments, StorageLoc *seg, void *chainBlock)
StorageLoc *& checkedTraversal(size_t segments, StorageLoc *last)
Implementation namespace for support and library code.
lib::HeteroData< DATA... >::template Elm_t< I > type
Mix-Ins to allow or prohibit various degrees of copying and cloning.
individual storage frame in a chain, holding a data tuple
void detachFrom(HeteroData< SPEC > &)
cleanly detach this storage frame from the HeteroData prefix-chain.
std::tuple< DATA... > Tuple
void linkInto(HeteroData< SPEC > &)
Attach a new storage frame at the end of an existing HeteroData-chain.
linked list of StorageFrame elements
Metaprogramming: Helpers for manipulating lists-of-types.
Metaprogramming: simple helpers for working with lists-of-types.
A template metaprogramming technique for manipulating collections of types.
Some basic facilities for manipulating type sequences.