67 #ifndef LIB_HETERO_DATA_H 68 #define LIB_HETERO_DATA_H 91 template<
typename...DATA>
102 template<
size_t seg,
typename...DATA>
105 , std::tuple<DATA...>
107 using Tuple = std::tuple<DATA...>;
111 template<
typename SPEC>
114 template<
size_t slot>
auto&
get() noexcept {
return std::get<slot>(*this); }
115 template<
typename X>
auto&
get() noexcept {
return std::get<X>(*this); }
125 template<
size_t seg,
typename...DATA,
class TAIL>
126 class HeteroData<meta::Node<StorageFrame<seg, DATA...>,TAIL>>
131 using Tuple = std::tuple<DATA...>;
134 static constexpr
size_t localSiz =
sizeof...(DATA);
136 template<
size_t slot>
137 static constexpr
bool isLocal = slot < localSiz;
139 template<
size_t slot>
140 using PickType = std::conditional_t<isLocal<slot>, std::tuple_element<slot,Tuple>
141 ,
typename _Tail::template PickType<slot-localSiz>>;
146 REQUIRE (Frame::next,
"HeteroData storage logic broken: follow-up extent not yet allocated");
147 return *
reinterpret_cast<_Tail*
> (Frame::next);
150 template<
typename...SPEC>
154 return reinterpret_cast<_Self&
> (frontChain);
156 template<
typename...SPEC>
160 return reinterpret_cast<_Self const&
> (frontChain);
164 template<
typename...XX>
173 static constexpr
size_t 176 return localSiz + _Tail::size();
180 template<
size_t slot>
181 using Elm_t =
typename PickType<slot>::type;
185 template<
size_t slot>
189 static_assert (slot < size(),
"HeteroData access index beyond defined data");
190 if constexpr (slot < localSiz)
191 return std::get<slot> (*this);
193 return accessTail().template
get<slot-localSiz>();
196 template<
size_t slot>
200 return const_cast<HeteroData*
>(
this)->get<slot>();
210 template<
size_t slot>
219 auto& fullChain = _Self::recast (frontEnd);
220 return fullChain.template get<slot>();
223 template<
typename HH>
224 Type& operator() (HH& frontEnd)
const {
return Accessor::get(frontEnd); }
242 template<
typename...VALS>
249 template<
typename...INIT>
251 build (INIT&& ...initArgs)
253 return {initArgs ...};
258 recast (HET& frontChain)
260 return ChainType::recast (frontChain);
263 template<
typename...XVALS>
264 using ChainExtent =
typename ChainType::template Chain<XVALS...>;
266 template<
size_t slot>
267 using Accessor =
typename ChainType::template Accessor<_Self::size()+slot>;
270 using AccessorFor = Accessor<meta::indexOfType<X,VALS...>()>;
281 static size_t constexpr size() {
return 0; }
286 using PickType = void;
295 template<
typename...DATA>
297 :
public HeteroData<meta::Node<StorageFrame<0, DATA...>, meta::NullType>>
302 using NewFrame =
typename _Front::Frame;
303 using ChainType = _Front;
305 template<
typename...INIT>
307 build (INIT&& ...initArgs)
309 return {initArgs ...};
332 while (segments and last->next)
337 ASSERT (last->next ==
nullptr and segments == 1
338 ,
"Failure to attach new data segment to HeteroData: " 339 "assumed type structure does not match real connectivity, " 340 "end-of-chain encountered with %d type segment(s) remaining" 362 template<
size_t seg,
typename...DATA>
363 template<
typename SPEC>
369 ENSURE (lastLink ==
nullptr);
380 template<
typename...DATA>
381 struct tuple_size<
lib::HeteroData<DATA...> >
382 : std::integral_constant<std::size_t, lib::HeteroData<DATA...>::size()>
386 template<
size_t I,
typename...DATA>
387 struct tuple_element<I, lib::HeteroData<DATA...> >
392 struct tuple_element<I, lib::HeteroData<lib::meta::NullType> >
394 static_assert (
"accessing element-type of an empty HeteroData block");
403 template<
size_t seg,
typename...DATA>
404 struct tuple_size<lib::StorageFrame<seg,DATA...> >
405 : std::tuple_size<typename lib::StorageFrame<seg,DATA...>::Tuple>
409 template<
size_t I,
size_t seg,
typename...DATA>
410 struct tuple_element<I, lib::StorageFrame<seg,DATA...> >
411 : std::tuple_element<I, typename lib::StorageFrame<seg,DATA...>::Tuple>
A template metaprogramming technique for manipulating collections of types.
linked list of StorageFrame elements
Any copy and copy construction prohibited.
Metaprogramming: simple helpers for working with lists-of-types.
Some basic facilities for manipulating type sequences.
individual storage frame in a chain, holding a data tuple
Implementation namespace for support and library code.
StorageLoc *& checkedTraversal(size_t segments, StorageLoc *last)
Mix-Ins to allow or prohibit various degrees of copying and cloning.
A setup with chained data tuples residing in distributed storage.
void linkInto(HeteroData< SPEC > &)
Attach a new storage frame at the end of an existing HeteroData-chain.
Lumiera error handling (C++ interface).
Metaprogramming: Helpers for manipulating lists-of-types.