diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 9a05fbe91885f..a467e99f4b47a 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2803,281 +2803,281 @@ consteval auto getIndexTargets() /// NORMAL #define DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ - struct _Name_##Id : o2::soa::PersistentColumn<_Type_, _Name_##Id> { \ - static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ - static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ - static constexpr const char* mLabel = "fIndex" _Label_ _Suffix_; \ - using base = o2::soa::PersistentColumn<_Type_, _Name_##Id>; \ - using type = _Type_; \ - using column_t = _Name_##Id; \ - using binding_t = _Table_; \ - static constexpr auto index_targets = getIndexTargets<_Table_>(); \ - _Name_##Id(arrow::ChunkedArray const* column) \ - : o2::soa::PersistentColumn<_Type_, _Name_##Id>(o2::soa::ColumnIterator(column)) \ - { \ - } \ - \ - _Name_##Id() = default; \ - _Name_##Id(_Name_##Id const& other) = default; \ - _Name_##Id& operator=(_Name_##Id const& other) = default; \ - type inline getId() const \ - { \ - return _Getter_##Id(); \ - } \ - \ - type _Getter_##Id() const \ - { \ - return *mColumnIterator; \ - } \ - \ - bool has_##_Getter_() const \ - { \ - return *mColumnIterator >= 0; \ - } \ - \ - template \ - auto _Getter_##_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \ - o2::soa::accessingInvalidIndexFor(#_Getter_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ - } \ - return t->rawIteratorAt(*mColumnIterator); \ - } \ - \ - auto _Getter_() const \ - { \ - return _Getter_##_as(); \ - } \ - \ - template \ - bool setCurrent(T* current) \ - { \ - if constexpr (o2::soa::is_binding_compatible_v()) { \ - assert(current != nullptr); \ - this->mBinding.bind(current); \ - return true; \ - } \ - return false; \ - } \ - \ - bool setCurrentRaw(o2::soa::Binding current) \ - { \ - this->mBinding = current; \ - return true; \ - } \ - binding_t const* getCurrent() const { return mBinding.get(); } \ - o2::soa::Binding getCurrentRaw() const { return mBinding; } \ - o2::soa::Binding mBinding; \ - }; \ - [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" #_Table_ _Suffix_, o2::framework::TypeIdHelpers::uniqueId<_Name_##Id>(), \ - o2::framework::expressions::selectArrowType<_Type_>() } + struct _Name_##Id : o2::soa::PersistentColumn<_Type_, _Name_##Id> { \ + static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ + static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ + static constexpr const char* mLabel = "fIndex" _Label_ _Suffix_; \ + using base = o2::soa::PersistentColumn<_Type_, _Name_##Id>; \ + using type = _Type_; \ + using column_t = _Name_##Id; \ + using binding_t = _Table_; \ + static constexpr auto index_targets = getIndexTargets<_Table_>(); \ + _Name_##Id(arrow::ChunkedArray const* column) \ + : o2::soa::PersistentColumn<_Type_, _Name_##Id>(o2::soa::ColumnIterator(column)) \ + { \ + } \ + \ + _Name_##Id() = default; \ + _Name_##Id(_Name_##Id const& other) = default; \ + _Name_##Id& operator=(_Name_##Id const& other) = default; \ + type inline getId() const \ + { \ + return _Getter_##Id(); \ + } \ + \ + type _Getter_##Id() const \ + { \ + return *mColumnIterator; \ + } \ + \ + bool has_##_Getter_() const \ + { \ + return *mColumnIterator >= 0; \ + } \ + \ + template \ + auto _Getter_##_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \ + o2::soa::accessingInvalidIndexFor(#_Getter_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ + } \ + return t->rawIteratorAt(*mColumnIterator); \ + } \ + \ + auto _Getter_() const \ + { \ + return _Getter_##_as(); \ + } \ + \ + template \ + bool setCurrent(T* current) \ + { \ + if constexpr (o2::soa::is_binding_compatible_v()) { \ + assert(current != nullptr); \ + this->mBinding.bind(current); \ + return true; \ + } \ + return false; \ + } \ + \ + bool setCurrentRaw(o2::soa::Binding current) \ + { \ + this->mBinding = current; \ + return true; \ + } \ + binding_t const* getCurrent() const { return mBinding.get(); } \ + o2::soa::Binding getCurrentRaw() const { return mBinding; } \ + o2::soa::Binding mBinding; \ + }; \ + [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" #_Table_ _Suffix_, o2::framework::TypeIdHelpers::uniqueId<_Name_##Id>(), \ + o2::framework::expressions::selectArrowType<_Type_>() } #define DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_) #define DECLARE_SOA_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "") #define DECLARE_SOA_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "") -/// SELF + /// SELF #define DECLARE_SOA_SELF_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ - struct _Name_##Id : o2::soa::PersistentColumn<_Type_, _Name_##Id> { \ - static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ - static constexpr const char* mLabel = "fIndex" _Label_; \ - using base = o2::soa::PersistentColumn<_Type_, _Name_##Id>; \ - using type = _Type_; \ - using column_t = _Name_##Id; \ - using self_index_t = std::true_type; \ - using compatible_signature = std::conditional, _IndexTarget_, void>; \ - _Name_##Id(arrow::ChunkedArray const* column) \ - : o2::soa::PersistentColumn<_Type_, _Name_##Id>(o2::soa::ColumnIterator(column)) \ - { \ - } \ - \ - _Name_##Id() = default; \ - _Name_##Id(_Name_##Id const& other) = default; \ - _Name_##Id& operator=(_Name_##Id const& other) = default; \ - type inline getId() const \ - { \ - return _Getter_##Id(); \ - } \ - \ - type _Getter_##Id() const \ - { \ - return *mColumnIterator; \ - } \ - \ - bool has_##_Getter_() const \ - { \ - return *mColumnIterator >= 0; \ - } \ - \ - template \ - auto _Getter_##_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \ - o2::soa::accessingInvalidIndexFor(#_Getter_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ - } \ - return t->rawIteratorAt(*mColumnIterator); \ - } \ - \ - bool setCurrentRaw(o2::soa::Binding current) \ - { \ - this->mBinding = current; \ - return true; \ - } \ - o2::soa::Binding getCurrentRaw() const { return mBinding; } \ - o2::soa::Binding mBinding; \ - }; \ - [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" _Label_, o2::framework::TypeIdHelpers::uniqueId<_Name_##Id>(), \ - o2::framework::expressions::selectArrowType<_Type_>() } + struct _Name_##Id : o2::soa::PersistentColumn<_Type_, _Name_##Id> { \ + static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ + static constexpr const char* mLabel = "fIndex" _Label_; \ + using base = o2::soa::PersistentColumn<_Type_, _Name_##Id>; \ + using type = _Type_; \ + using column_t = _Name_##Id; \ + using self_index_t = std::true_type; \ + using compatible_signature = std::conditional, _IndexTarget_, void>; \ + _Name_##Id(arrow::ChunkedArray const* column) \ + : o2::soa::PersistentColumn<_Type_, _Name_##Id>(o2::soa::ColumnIterator(column)) \ + { \ + } \ + \ + _Name_##Id() = default; \ + _Name_##Id(_Name_##Id const& other) = default; \ + _Name_##Id& operator=(_Name_##Id const& other) = default; \ + type inline getId() const \ + { \ + return _Getter_##Id(); \ + } \ + \ + type _Getter_##Id() const \ + { \ + return *mColumnIterator; \ + } \ + \ + bool has_##_Getter_() const \ + { \ + return *mColumnIterator >= 0; \ + } \ + \ + template \ + auto _Getter_##_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \ + o2::soa::accessingInvalidIndexFor(#_Getter_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ + } \ + return t->rawIteratorAt(*mColumnIterator); \ + } \ + \ + bool setCurrentRaw(o2::soa::Binding current) \ + { \ + this->mBinding = current; \ + return true; \ + } \ + o2::soa::Binding getCurrentRaw() const { return mBinding; } \ + o2::soa::Binding mBinding; \ + }; \ + [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" _Label_, o2::framework::TypeIdHelpers::uniqueId<_Name_##Id>(), \ + o2::framework::expressions::selectArrowType<_Type_>() } #define DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void) #define DECLARE_SOA_SELF_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, #_Name_) -/// SELF SLICE + /// SELF SLICE #define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ - struct _Name_##IdSlice : o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice> { \ - static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ - static constexpr const char* mLabel = "fIndexSlice" _Label_; \ - using base = o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice>; \ - using type = _Type_[2]; \ - using column_t = _Name_##IdSlice; \ - using self_index_t = std::true_type; \ - using compatible_signature = std::conditional, _IndexTarget_, void>; \ - _Name_##IdSlice(arrow::ChunkedArray const* column) \ - : o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator(column)) \ - { \ - } \ - \ - _Name_##IdSlice() = default; \ - _Name_##IdSlice(_Name_##IdSlice const& other) = default; \ - _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \ - std::array<_Type_, 2> inline getIds() const \ - { \ - return _Getter_##Ids(); \ - } \ - \ - bool has_##_Getter_() const \ - { \ - auto a = *mColumnIterator; \ - return a[0] >= 0 && a[1] >= 0; \ - } \ - \ - std::array<_Type_, 2> _Getter_##Ids() const \ - { \ - auto a = *mColumnIterator; \ - return std::array{a[0], a[1]}; \ - } \ - \ - template \ - auto _Getter_##_as() const \ - { \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ - } \ - if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \ - return t->emptySlice(); \ - } \ - auto a = *mColumnIterator; \ - auto r = t->rawSlice(a[0], a[1]); \ - t->copyIndexBindings(r); \ - r.bindInternalIndicesTo(t); \ - return r; \ - } \ - \ - bool setCurrentRaw(o2::soa::Binding current) \ - { \ - this->mBinding = current; \ - return true; \ - } \ - o2::soa::Binding getCurrentRaw() const { return mBinding; } \ - o2::soa::Binding mBinding; \ - }; + struct _Name_##IdSlice : o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice> { \ + static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ + static constexpr const char* mLabel = "fIndexSlice" _Label_; \ + using base = o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice>; \ + using type = _Type_[2]; \ + using column_t = _Name_##IdSlice; \ + using self_index_t = std::true_type; \ + using compatible_signature = std::conditional, _IndexTarget_, void>; \ + _Name_##IdSlice(arrow::ChunkedArray const* column) \ + : o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator(column)) \ + { \ + } \ + \ + _Name_##IdSlice() = default; \ + _Name_##IdSlice(_Name_##IdSlice const& other) = default; \ + _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \ + std::array<_Type_, 2> inline getIds() const \ + { \ + return _Getter_##Ids(); \ + } \ + \ + bool has_##_Getter_() const \ + { \ + auto a = *mColumnIterator; \ + return a[0] >= 0 && a[1] >= 0; \ + } \ + \ + std::array<_Type_, 2> _Getter_##Ids() const \ + { \ + auto a = *mColumnIterator; \ + return std::array{a[0], a[1]}; \ + } \ + \ + template \ + auto _Getter_##_as() const \ + { \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ + } \ + if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \ + return t->emptySlice(); \ + } \ + auto a = *mColumnIterator; \ + auto r = t->rawSlice(a[0], a[1]); \ + t->copyIndexBindings(r); \ + r.bindInternalIndicesTo(t); \ + return r; \ + } \ + \ + bool setCurrentRaw(o2::soa::Binding current) \ + { \ + this->mBinding = current; \ + return true; \ + } \ + o2::soa::Binding getCurrentRaw() const { return mBinding; } \ + o2::soa::Binding mBinding; \ + }; #define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void) #define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_) /// SELF ARRAY -#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ - struct _Name_##Ids : o2::soa::PersistentColumn, _Name_##Ids> { \ - static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ - static constexpr const char* mLabel = "fIndexArray" _Label_; \ - using base = o2::soa::PersistentColumn, _Name_##Ids>; \ - using type = std::vector<_Type_>; \ - using column_t = _Name_##Ids; \ - using self_index_t = std::true_type; \ - using compatible_signature = std::conditional, _IndexTarget_, void>; \ - _Name_##Ids(arrow::ChunkedArray const* column) \ - : o2::soa::PersistentColumn, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ - { \ - } \ - \ - _Name_##Ids() = default; \ - _Name_##Ids(_Name_##Ids const& other) = default; \ - _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ - gsl::span inline getIds() const \ - { \ - return _Getter_##Ids(); \ - } \ - \ - gsl::span _Getter_##Ids() const \ - { \ - return *mColumnIterator; \ - } \ - \ - bool has_##_Getter_() const \ - { \ - return !(*mColumnIterator).empty(); \ - } \ - \ - template \ - auto _Getter_##_as() const \ - { \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ - } \ - return getIterators(); \ - } \ - \ - template \ - auto getIterators() const \ - { \ - auto result = std::vector(); \ - for (auto& i : *mColumnIterator) { \ - result.push_back(mBinding.get()->rawIteratorAt(i)); \ - } \ - return result; \ - } \ - \ - template \ - auto _Getter_##_first_as() const \ - { \ - return mBinding.get()->rawIteratorAt((*mColumnIterator)[0]); \ - } \ - \ - template \ - auto _Getter_##_last_as() const \ - { \ - return mBinding.get()->rawIteratorAt((*mColumnIterator).back()); \ - } \ - \ - bool setCurrentRaw(o2::soa::Binding current) \ - { \ - this->mBinding = current; \ - return true; \ - } \ - o2::soa::Binding getCurrentRaw() const { return mBinding; } \ - o2::soa::Binding mBinding; \ - }; +#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ + struct _Name_##Ids : o2::soa::PersistentColumn, _Name_##Ids> { \ + static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ + static constexpr const char* mLabel = "fIndexArray" _Label_; \ + using base = o2::soa::PersistentColumn, _Name_##Ids>; \ + using type = std::vector<_Type_>; \ + using column_t = _Name_##Ids; \ + using self_index_t = std::true_type; \ + using compatible_signature = std::conditional, _IndexTarget_, void>; \ + _Name_##Ids(arrow::ChunkedArray const* column) \ + : o2::soa::PersistentColumn, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ + { \ + } \ + \ + _Name_##Ids() = default; \ + _Name_##Ids(_Name_##Ids const& other) = default; \ + _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ + gsl::span inline getIds() const \ + { \ + return _Getter_##Ids(); \ + } \ + \ + gsl::span _Getter_##Ids() const \ + { \ + return *mColumnIterator; \ + } \ + \ + bool has_##_Getter_() const \ + { \ + return !(*mColumnIterator).empty(); \ + } \ + \ + template \ + auto _Getter_##_as() const \ + { \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ + } \ + return getIterators(); \ + } \ + \ + template \ + auto getIterators() const \ + { \ + auto result = std::vector(); \ + for (auto& i : *mColumnIterator) { \ + result.push_back(mBinding.get()->rawIteratorAt(i)); \ + } \ + return result; \ + } \ + \ + template \ + auto _Getter_##_first_as() const \ + { \ + return mBinding.get()->rawIteratorAt((*mColumnIterator)[0]); \ + } \ + \ + template \ + auto _Getter_##_last_as() const \ + { \ + return mBinding.get()->rawIteratorAt((*mColumnIterator).back()); \ + } \ + \ + bool setCurrentRaw(o2::soa::Binding current) \ + { \ + this->mBinding = current; \ + return true; \ + } \ + o2::soa::Binding getCurrentRaw() const { return mBinding; } \ + o2::soa::Binding mBinding; \ + }; #define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void) #define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_) @@ -3111,56 +3111,56 @@ consteval auto getIndexTargets() /// \endcode /// #define DECLARE_SOA_DYNAMIC_COLUMN(_Name_, _Getter_, ...) \ - struct _Name_##Callback { \ - static inline constexpr auto getLambda() { return __VA_ARGS__; } \ - }; \ - \ - struct _Name_##Helper { \ - using callable_t = decltype(o2::framework::FunctionMetadata(std::declval())); \ - using return_type = typename callable_t::return_type; \ - }; \ - template \ - struct _Name_ : o2::soa::TransientColumn> { \ - using base = o2::soa::TransientColumn>; \ - using helper = _Name_##Helper; \ - using callback_holder_t = _Name_##Callback; \ - using callable_t = helper::callable_t; \ - using callback_t = callable_t::type; \ - \ - _Name_(arrow::ChunkedArray const*) \ - { \ - } \ - _Name_() = default; \ - _Name_(_Name_ const& other) = default; \ - _Name_& operator=(_Name_ const& other) = default; \ - static constexpr const char* mLabel = #_Name_; \ - using type = typename callable_t::return_type; \ - \ - template \ - type _Getter_(FreeArgs... freeArgs) const \ - { \ - return boundGetter(std::make_index_sequence>{}, freeArgs...); \ - } \ - template \ - type getDynamicValue(FreeArgs... freeArgs) const \ - { \ - return boundGetter(std::make_index_sequence>{}, freeArgs...); \ - } \ - \ - type get() const \ - { \ - return _Getter_(); \ - } \ - \ - template \ - type boundGetter(std::integer_sequence&&, FreeArgs... freeArgs) const \ - { \ - return __VA_ARGS__((**std::get(boundIterators))..., freeArgs...); \ - } \ - \ - using bindings_t = typename o2::framework::pack; \ - std::tuple const*...> boundIterators; \ - } + struct _Name_##Callback { \ + static inline constexpr auto getLambda() { return __VA_ARGS__; } \ + }; \ + \ + struct _Name_##Helper { \ + using callable_t = decltype(o2::framework::FunctionMetadata(std::declval())); \ + using return_type = typename callable_t::return_type; \ + }; \ + template \ + struct _Name_ : o2::soa::TransientColumn> { \ + using base = o2::soa::TransientColumn>; \ + using helper = _Name_##Helper; \ + using callback_holder_t = _Name_##Callback; \ + using callable_t = helper::callable_t; \ + using callback_t = callable_t::type; \ + \ + _Name_(arrow::ChunkedArray const*) \ + { \ + } \ + _Name_() = default; \ + _Name_(_Name_ const& other) = default; \ + _Name_& operator=(_Name_ const& other) = default; \ + static constexpr const char* mLabel = #_Name_; \ + using type = typename callable_t::return_type; \ + \ + template \ + type _Getter_(FreeArgs... freeArgs) const \ + { \ + return boundGetter(std::make_index_sequence>{}, freeArgs...); \ + } \ + template \ + type getDynamicValue(FreeArgs... freeArgs) const \ + { \ + return boundGetter(std::make_index_sequence>{}, freeArgs...); \ + } \ + \ + type get() const \ + { \ + return _Getter_(); \ + } \ + \ + template \ + type boundGetter(std::integer_sequence&&, FreeArgs... freeArgs) const \ + { \ + return __VA_ARGS__((**std::get(boundIterators))..., freeArgs...); \ + } \ + \ + using bindings_t = typename o2::framework::pack; \ + std::tuple const*...> boundIterators; \ + } #define DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, ...) \ using _Name_##Metadata = TableMetadata, __VA_ARGS__>;