11 #include <type_traits>
12 #if __has_include(<boost/describe/members.hpp>)
13 # include <boost/describe/members.hpp>
38 template<
typename Tag,
typename Type>
41 static_assert(isAllowedFieldType<Type>,
"This field's type is not allowed");
49 template<
typename Tag,
typename Type>
50 inline constexpr
bool isField<Field<Tag, Type>> =
true;
54 template<
typename... Fields>
58 requires(mp_all<mp_bool<isField<Fields>>...>::value)
64 #if __cpp_nontype_template_args >= 201911L && !defined(__EDG__)
66 # define LLAMA_HAS_STRING_FIELDS
71 template<std::
size_t N>
74 constexpr FixedString(
const char* str)
82 template<std::
size_t N>
83 FixedString(
const char (&str)[N]) -> FixedString<N>;
85 template<FixedString Name>
91 inline namespace literals
95 template<
internal::FixedString Name>
96 auto operator"" _Name()
98 return internal::StringTag<Name>{};
105 template<
internal::FixedString Tag,
typename Type>
106 using NamedField = Field<internal::StringTag<Tag>, Type>;
108 # if __has_include(<boost/describe/members.hpp>)
110 # define LLAMA_CAN_REFLECT_RECORD_DIM
114 auto reflectToRecordDim();
116 template<
class C,
typename T>
117 auto memberPointerPointeeType(T C::*) -> T;
119 constexpr
auto constexpr_strlen(
const char* s)
127 template<
typename Member>
128 using MakeFieldFromMemberDescriptor = NamedField<
129 FixedString<constexpr_strlen(Member::name) + 1>(Member::name),
130 decltype(reflectToRecordDim<decltype(memberPointerPointeeType(Member::pointer))>())>;
133 auto reflectToRecordDim()
135 if constexpr(boost::describe::has_describe_members<T>::value)
137 using MemberList = boost::describe::describe_members<T, boost::describe::mod_public>;
138 return mp_rename<mp_transform<MakeFieldFromMemberDescriptor, MemberList>,
llama::Record>{};
148 using ReflectToRecordDim = decltype(internal::reflectToRecordDim<T>());
161 return os <<
"NrAndOffset{" << value.nr <<
", " << value.offset <<
"}";
166 template<
typename Int>
170 template<
typename TA,
typename TB>
173 return a.nr == b.nr && a.offset == b.offset;
177 template<
typename TA,
typename TB>
185 template<
typename Field>
190 template<
typename Field>
198 template<
typename... Fields>
203 template<
typename RecordDim,
typename RecordCoord>
206 template<
typename... Fields, std::size_t FirstCoord, std::size_t... Coords>
209 using Field = mp_at_c<mp_list<Fields...>, FirstCoord>;
215 template<
typename ChildType, std::size_t Count, std::size_t FirstCoord, std::size_t... Coords>
232 template<
typename RecordDim,
typename RecordCoord>
237 template<
typename RecordDim,
typename RecordCoord>
240 using type = mp_back<GetTags<RecordDim, RecordCoord>>;
243 template<
typename RecordDim>
252 template<
typename RecordDim,
typename RecordCoord>
263 template<
typename RecordDimA,
typename RecordCoordA,
typename RecordDimB,
typename RecordCoordB>
266 if constexpr(RecordCoordA::size != RecordCoordB::size)
268 else if constexpr(RecordCoordA::size == 0 && RecordCoordB::size == 0)
276 template<
typename FieldList,
typename Tag>
279 template<
typename Field>
280 using HasTag = std::is_same<GetFieldTag<Field>, Tag>;
282 static constexpr
auto value = mp_find_if<FieldList, HasTag>::value;
285 template<
typename RecordDim,
typename RecordCoord,
typename... Tags>
288 static_assert(mp_size<RecordDim>::value != 0,
"Tag combination is not valid");
291 template<
typename... Fields, std::size_t... ResultCoords,
typename FirstTag,
typename... Tags>
294 static constexpr
auto tagIndex =
FindFieldByTag<mp_list<Fields...>, FirstTag>::value;
296 tagIndex <
sizeof...(Fields),
297 "FirstTag was not found inside this Record. Does your record dimension contain the tag you access "
309 std::size_t... ResultCoords,
314 static_assert(isRecordCoord<FirstTag>,
"Please use a RecordCoord<I> to index into static arrays");
315 static_assert(FirstTag::size == 1,
"Expected RecordCoord with 1 coordinate");
316 static_assert(FirstTag::front < Count,
"Index out of bounds");
322 template<
typename RecordDim,
typename RecordCoord>
329 template<
typename... Fields,
typename... Tags>
335 template<
typename ChildType, std::size_t Count,
typename... Tags>
342 template<
typename... Fields, std::size_t... RCs>
352 template<
typename RecordDim,
typename... TagsOrTagList>
357 template<
typename RecordDim,
typename... RecordCoordOrTags>
363 template<
typename... Children, std::size_t HeadCoord, std::size_t... TailCoords>
370 template<
typename ChildType, std::size_t N, std::size_t HeadCoord, std::size_t... TailCoords>
379 static_assert(isAllowedFieldType<T>);
387 template<
typename RecordDim,
typename... RecordCoordOrTags>
392 template<
typename RecordDim,
typename RecordCoord>
395 template<
typename T, std::size_t... RCs>
401 template<
typename... Fields, std::size_t... RCs>
404 template<std::size_t... Is>
405 static auto help(std::index_sequence<Is...>)
410 using type = decltype(help(std::make_index_sequence<
sizeof...(Fields)>{}));
413 template<
typename Child, std::size_t N, std::size_t... RCs>
416 template<std::size_t... Is>
417 static auto help(std::index_sequence<Is...>)
421 using type = decltype(help(std::make_index_sequence<N>{}));
427 template<
typename RecordDim>
436 template<
typename RecordDim,
typename Functor, std::size_t... Coords>
442 { std::forward<Functor>(functor)(
cat(baseCoord, innerCoord)); });
452 template<
typename RecordDim,
typename Functor,
typename... Tags>
466 template<
typename... Fields>
469 using type = mp_append<typename FlattenRecordDimImpl<GetFieldType<Fields>>
::type...>;
471 template<
typename Child, std::
size_t N>
474 using type = mp_repeat_c<typename FlattenRecordDimImpl<Child>::type, N>;
480 template<
typename RecordDim>
485 template<
typename RecordDim>
489 template<
typename... Children>
491 = (flatFieldCount<GetFieldType<Children>> + ... + 0);
494 template<
typename Child, std::
size_t N>
499 template<std::
size_t I,
typename RecordDim>
502 template<
typename... Children>
507 template<std::size_t I,
typename... Children>
516 template<
typename RecordDim,
typename RecordCoord>
521 inline constexpr std::size_t flatRecordCoord<T, RecordCoord<>> = 0;
524 template<
typename... Children, std::size_t I, std::size_t... Is>
530 template<
typename Child, std::size_t N, std::size_t I, std::size_t... Is>
536 template<
typename TypeList>
539 std::size_t maxAlign = 0;
540 mp_for_each_inline<mp_transform<mp_identity, TypeList>>(
541 [&](
auto e) constexpr
543 using T =
typename decltype(e)::type;
544 maxAlign = std::max(maxAlign,
alignof(T));
553 template<
typename TypeList>
554 inline constexpr std::size_t
flatAlignOf = internal::flatAlignOfImpl<TypeList>();
559 inline constexpr std::size_t
alignOf =
alignof(T);
564 template<
typename... Fields>
569 template<
typename Integral>
572 return (a + b - 1) / b;
577 template<
typename Integral>
580 return divCeil(n, mult) * mult;
585 template<
typename TypeList,
bool Align,
bool IncludeTailPadding>
588 std::size_t size = 0;
589 std::size_t maxAlign = 0;
590 mp_for_each_inline<mp_transform<mp_identity, TypeList>>(
591 [&](
auto e) constexpr
593 using T =
typename decltype(e)::type;
597 maxAlign = std::max(maxAlign,
alignof(T));
604 if constexpr(Align && IncludeTailPadding)
611 template<
typename TypeList, std::
size_t I,
bool Align>
617 template<
typename TypeList,
bool Align,
bool IncludeTailPadding = true>
618 inline constexpr std::size_t
flatSizeOf = internal::sizeOfImpl<TypeList, Align, IncludeTailPadding>();
622 template<
typename T,
bool Align = false,
bool IncludeTailPadding = true>
623 inline constexpr std::size_t
sizeOf =
sizeof(T);
627 template<
typename... Fields,
bool Align,
bool IncludeTailPadding>
628 inline constexpr std::size_t
sizeOf<
Record<Fields...>, Align, IncludeTailPadding>
633 template<
typename TypeList, std::
size_t I,
bool Align>
634 inline constexpr std::size_t
flatOffsetOf = internal::offsetOfImplWorkaround<TypeList, I, Align>();
640 template<
typename TypeList, std::
size_t I,
bool Align>
648 =
flatOffsetOf<TypeList, I - 1, Align> +
sizeof(mp_at_c<TypeList, I - 1>);
660 template<
typename RecordDim,
typename RecordCoord,
bool Align = false>
662 = flatOffsetOf<FlatRecordDim<RecordDim>, flatRecordCoord<RecordDim, RecordCoord>, Align>;
689 template<
class T, std::
size_t N>
702 template<
typename Coord,
typename T,
template<
typename,
typename>
typename TypeFunctor>
705 using type = TypeFunctor<Coord, T>;
708 template<std::size_t... Is,
typename... Fields,
template<
typename,
typename>
typename TypeFunctor>
711 template<std::size_t... Js>
712 static auto f(std::index_sequence<Js...>)
720 using type = decltype(f(std::index_sequence_for<Fields...>{}));
722 template<std::size_t... Is,
typename Child, std::size_t N,
template<
typename,
typename>
typename TypeFunctor>
725 template<std::size_t... Js>
726 static void f(std::index_sequence<Js...>)
731 "Leave transformations beneath an array node must return the same type");
733 using dummy = decltype(f(std::make_index_sequence<N>{}));
738 template<
template<
typename>
typename F>
741 template<
typename A,
typename B>
749 template<
typename RecordDim,
template<
typename,
typename>
typename FieldTypeFunctor>
756 template<
typename RecordDim,
template<
typename>
typename FieldTypeFunctor>
765 template<
typename A,
typename B>
768 static_assert(std::is_same_v<A, B>,
"Cannot merge record and non-record or fields with different types");
772 template<
typename A, std::
size_t NA,
typename B, std::
size_t NB>
775 static_assert(std::is_same_v<A, B>,
"Cannot merge arrays of different type");
776 if constexpr(NA < NB)
782 template<
typename... FieldsA>
795 if constexpr(Pos ==
sizeof...(FieldsA))
799 mp_identity<
Record<FieldsB...>>{});
803 using OldFieldA = mp_at_c<
Record<FieldsA...>, Pos>;
804 using NewFieldA =
Field<
808 mp_identity<GetFieldType<FieldB>>{}))::type>;
809 using NewRecordA = mp_replace_at_c<
Record<FieldsA...>, Pos, NewFieldA>;
817 template<
typename RecordDimA,
typename RecordDimB>
823 template<
typename FromT,
typename ToT>
824 using CopyConst = std::conditional_t<std::is_const_v<FromT>,
const ToT, ToT>;
829 using Constant = std::integral_constant<decltype(V), V>;
838 template<
typename T, T V>
839 struct IsConstant<std::integral_constant<T, V>> : std::true_type
853 template<
typename T,
int I = 0>
873 template<auto V,
int I>
903 static const char* unit[] = {
"B ",
"KB",
"MB",
"GB",
"TB",
"PB",
"EB"};
904 unsigned unitIndex = 0;
910 assert(unitIndex < std::size(unit));
911 return {size, unit[unitIndex]};
#define LLAMA_LAMBDA_INLINE_WITH_SPECIFIERS(...)
#define LLAMA_BEGIN_SUPPRESS_HOST_DEVICE_WARNING
#define LLAMA_FN_HOST_ACC_INLINE
#define LLAMA_END_SUPPRESS_HOST_DEVICE_WARNING
constexpr std::size_t flatFieldCountBefore
constexpr auto flatAlignOfImpl()
constexpr auto offsetOfImplWorkaround() -> std::size_t
auto mergeRecordDimsImpl(mp_identity< A > a, mp_identity< B >)
constexpr auto sizeOfImpl() -> std::size_t
std::integral_constant< decltype(V), V > Constant
Used as template argument to specify a constant/compile-time value.
constexpr std::size_t flatFieldCount< Child[N]>
typename internal::FlattenRecordDimImpl< RecordDim >::type FlatRecordDim
Returns a flat type list containing all leaf field types of the given record dimension.
constexpr std::size_t sizeOf
The size of a type T.
NrAndOffset(Int, Int) -> NrAndOffset< Int >
constexpr auto hasSameTags
constexpr auto cat(RecordCoords...)
Concatenate a set of RecordCoords instances.
constexpr auto operator==(ArrayIndex< TA, Dim > a, ArrayIndex< TB, Dim > b) -> bool
typename internal::GetTagsImpl< RecordDim, RecordCoord >::type GetTags
constexpr auto divCeil(Integral a, Integral b) -> Integral
Returns the ceiling of a / b.
typename internal::GetTagImpl< RecordDim, RecordCoord >::type GetTag
Get the tag of the Field at a RecordCoord inside the record dimension tree.
constexpr std::size_t flatRecordCoord
constexpr std::size_t flatAlignOf
constexpr void mp_for_each_inline(F &&f)
Like boost::mp11::mp_for_each, but marked with LLAMA_FN_HOST_ACC_INLINE.
mp_second< Field > GetFieldType
Get the type from a Field.
constexpr std::size_t flatOffsetOf
The byte offset of an element in a type list ifs elements would be in a normal struct.
TransformLeavesWithCoord< RecordDim, internal::MakePassSecond< FieldTypeFunctor >::template fn > TransformLeaves
constexpr auto operator!=(ArrayIndex< TA, Dim > a, ArrayIndex< TB, Dim > b) -> bool
constexpr void forEachLeafCoord(Functor &&functor, RecordCoord< Coords... > baseCoord)
constexpr std::size_t flatFieldCount
The total number of fields in the recursively expanded record dimension.
std::conditional_t< std::is_const_v< FromT >, const ToT, ToT > CopyConst
Alias for ToT, adding const if FromT is const qualified.
constexpr std::size_t offsetOf
typename internal::TransformLeavesWithCoordImpl< RecordCoord<>, RecordDim, FieldTypeFunctor >::type TransformLeavesWithCoord
typename internal::LeafRecordCoordsImpl< RecordDim, RecordCoord<> >::type LeafRecordCoords
Returns a flat type list containing all record coordinates to all leaves of the given record dimensio...
void copy(const View< SrcMapping, SrcBlob > &srcView, View< DstMapping, DstBlob > &dstView, std::size_t threadId=0, std::size_t threadCount=1)
typename decltype(internal::mergeRecordDimsImpl(mp_identity< RecordDimA >{}, mp_identity< RecordDimB >{}))::type MergedRecordDims
Creates a merged record dimension, where duplicated, nested fields are unified.
constexpr bool isRecordDim
True if the T is a record dimension. That is, T is either a llama::Record or a bounded array.
constexpr auto roundUpToMultiple(Integral n, Integral mult) -> Integral
Returns the integral n rounded up to be a multiple of mult.
typename internal::GetCoordFromTagsImpl< RecordDim, RecordCoord<>, TagsOrTagList... >::type GetCoordFromTags
constexpr std::size_t flatSizeOf
The size of a type list if its elements would be in a normal struct.
mp_first< Field > GetFieldTag
Get the tag from a Field.
constexpr bool isAllowedFieldType
Tells whether the given type is allowed as a field type in LLAMA. Such types need to be trivially con...
typename internal::GetTypeImpl< RecordDim, RecordCoordOrTags... >::type GetType
constexpr bool isConstant
constexpr std::size_t alignOf
The alignment of a type T.
auto prettySize(double size) -> PrettySize
Anonymous naming for a Field.
friend auto operator<<(std::ostream &os, const NrAndOffset &value) -> std::ostream &
A type list of Fields which may be used to define a record dimension.
BoxedValue(Constant< V >)
static constexpr auto value()
constexpr auto value() const
std::is_same< GetFieldTag< Field >, Tag > HasTag
static constexpr auto value
mp_repeat_c< typename FlattenRecordDimImpl< Child >::type, N > type
mp_append< typename FlattenRecordDimImpl< GetFieldType< Fields > >::type... > type
mp_back< GetTags< RecordDim, RecordCoord > > type
typename GetTypeImpl< ChildType, RecordCoord< TailCoords... > >::type type
typename GetTypeImpl< ChildType, RecordCoord< TailCoords... > >::type type
GetFieldType< mp_at_c< Record< Children... >, HeadCoord > > ChildType
typename GetTypeImpl< RecordDim, GetCoordFromTags< RecordDim, RecordCoordOrTags... > >::type type
auto operator->() const -> const T *
decltype(help(std::make_index_sequence< N >{})) type
static auto help(std::index_sequence< Is... >)
static auto help(std::index_sequence< Is... >)
decltype(help(std::make_index_sequence< sizeof...(Fields)>{})) type
mp_list< RecordCoord< RCs... > > type