Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-06 04:26:43

0001 #ifndef DataFormats_SoATemplate_interface_SoAView_h
0002 #define DataFormats_SoATemplate_interface_SoAView_h
0003 
0004 /*
0005  * Structure-of-Arrays templates allowing access to a selection of scalars and columns from one
0006  * or multiple SoA layouts or views.
0007  * This template generator will allow handling subsets of columns from one or multiple SoA views or layouts.
0008  */
0009 
0010 #include "SoACommon.h"
0011 
0012 #define SOA_VIEW_LAYOUT(TYPE, NAME) (TYPE, NAME)
0013 
0014 #define SOA_VIEW_LAYOUT_LIST(...) __VA_ARGS__
0015 
0016 #define SOA_VIEW_VALUE(LAYOUT_NAME, LAYOUT_MEMBER) (LAYOUT_NAME, LAYOUT_MEMBER, LAYOUT_MEMBER)
0017 
0018 #define SOA_VIEW_VALUE_RENAME(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME) (LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME)
0019 
0020 #define SOA_VIEW_VALUE_LIST(...) __VA_ARGS__
0021 
0022 /*
0023  * A macro defining a SoA view (collection of columns from multiple layouts or views.)
0024  *
0025  * Usage:
0026  * GENERATE_SOA_VIEW(PixelXYConstView, PixelXYView,
0027  *   SOA_VIEW_LAYOUT_LIST(
0028  *     SOA_VIEW_LAYOUT(PixelDigis,         pixelDigis),
0029  *     SOA_VIEW_LAYOUT(PixelRecHitsLayout, pixelsRecHit)
0030  *   ),
0031  *   SOA_VIEW_VALUE_LIST(
0032  *     SOA_VIEW_VALUE_RENAME(pixelDigis,   x,   digisX),
0033  *     SOA_VIEW_VALUE_RENAME(pixelDigis,   y,   digisY),
0034  *     SOA_VIEW_VALUE_RENAME(pixelsRecHit, x, recHitsX),
0035  *     SOA_VIEW_VALUE_RENAME(pixelsRecHit, y, recHitsY)
0036  *   )
0037  * );
0038  *
0039  */
0040 
0041 namespace cms::soa {
0042 
0043   /* Traits for the different column type scenarios */
0044   /* Value traits passes the class as is in the case of column type and return
0045    * an empty class with functions returning non-scalar as accessors. */
0046   template <class C, SoAColumnType COLUMN_TYPE>
0047   struct ConstValueTraits : public C {
0048     using C::C;
0049   };
0050 
0051   template <class C>
0052   struct ConstValueTraits<C, SoAColumnType::scalar> {
0053     // Just take to SoAValue type to generate the right constructor.
0054     SOA_HOST_DEVICE SOA_INLINE ConstValueTraits(size_type, const typename C::valueType*) {}
0055     SOA_HOST_DEVICE SOA_INLINE ConstValueTraits(size_type, const typename C::Params&) {}
0056     SOA_HOST_DEVICE SOA_INLINE ConstValueTraits(size_type, const typename C::ConstParams&) {}
0057     // Any attempt to do anything with the "scalar" value a const element will fail.
0058   };
0059 
0060 }  // namespace cms::soa
0061 
0062 /*
0063  * Members definitions macros for views
0064  */
0065 
0066 /**
0067  * Layout templates parametrization
0068  */
0069 #define _DECLARE_VIEW_LAYOUT_PARAMETRIZED_TEMPLATE_IMPL(TYPE, NAME)                            \
0070   (using BOOST_PP_CAT(TYPE, _default) = BOOST_PP_CAT(TYPE, _StagedTemplates) < VIEW_ALIGNMENT, \
0071    VIEW_ALIGNMENT_ENFORCEMENT > ;)
0072 
0073 #define _DECLARE_VIEW_LAYOUT_PARAMETRIZED_TEMPLATE(R, DATA, TYPE_NAME) \
0074   BOOST_PP_EXPAND(_DECLARE_VIEW_LAYOUT_PARAMETRIZED_TEMPLATE_IMPL TYPE_NAME)
0075 
0076 /**
0077  * Layout types aliasing for referencing by name
0078  */
0079 #define _DECLARE_VIEW_LAYOUT_TYPE_ALIAS_IMPL(TYPE, NAME) using BOOST_PP_CAT(TypeOf_, NAME) = TYPE;
0080 
0081 #define _DECLARE_VIEW_LAYOUT_TYPE_ALIAS(R, DATA, TYPE_NAME) \
0082   BOOST_PP_EXPAND(_DECLARE_VIEW_LAYOUT_TYPE_ALIAS_IMPL TYPE_NAME)
0083 
0084 /**
0085  * Member types aliasing for referencing by name
0086  */
0087 // clang-format off
0088 #define _DECLARE_VIEW_MEMBER_TYPE_ALIAS_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME, CAST)                             \
0089   using BOOST_PP_CAT(TypeOf_, LOCAL_NAME) =                                                                            \
0090       typename BOOST_PP_CAT(TypeOf_, LAYOUT_NAME)::Metadata::BOOST_PP_CAT(TypeOf_, LAYOUT_MEMBER);                     \
0091   using BOOST_PP_CAT(ParametersTypeOf_, LOCAL_NAME) =                                                                  \
0092       typename BOOST_PP_CAT(TypeOf_, LAYOUT_NAME)::Metadata::BOOST_PP_CAT(ParametersTypeOf_, LAYOUT_MEMBER);           \
0093   constexpr static cms::soa::SoAColumnType BOOST_PP_CAT(ColumnTypeOf_, LOCAL_NAME) =                                   \
0094       BOOST_PP_CAT(TypeOf_, LAYOUT_NAME)::Metadata::BOOST_PP_CAT(ColumnTypeOf_, LAYOUT_MEMBER);                        \
0095   using BOOST_PP_CAT(ConstAccessorOf_, LOCAL_NAME) =                                                                   \
0096     typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                            \
0097         template ColumnType<BOOST_PP_CAT(ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                             \
0098             cms::soa::SoAAccessType::constAccess>::template Alignment<conditionalAlignment>::                          \
0099                 template RestrictQualifier<restrictQualify> ;                                                          \
0100   using BOOST_PP_CAT(MutableAccessorOf_, LOCAL_NAME) =                                                                 \
0101     typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                            \
0102         template ColumnType<BOOST_PP_CAT(ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                             \
0103             cms::soa::SoAAccessType::mutableAccess>::template Alignment<conditionalAlignment>::                        \
0104                 template RestrictQualifier<restrictQualify> ;                                                          \
0105   SOA_HOST_DEVICE SOA_INLINE                                                                                           \
0106   const auto BOOST_PP_CAT(parametersOf_, LOCAL_NAME)() const {                                                         \
0107     return CAST(parent_.BOOST_PP_CAT(LOCAL_NAME, Parameters_));                                                        \
0108   };
0109 // clang-format on
0110 
0111 // DATA should be a function used to convert
0112 //   parent_.LOCAL_NAME ## Parameters_
0113 // to
0114 //   ParametersTypeOf_ ## LOCAL_NAME                (for a View)
0115 // or
0116 //   ParametersTypeOf_ ## LOCAL_NAME :: ConstType   (for a ConstView)
0117 // or empty, if no conversion is necessary.
0118 #define _DECLARE_VIEW_MEMBER_TYPE_ALIAS(R, DATA, LAYOUT_MEMBER_NAME) \
0119   BOOST_PP_EXPAND(_DECLARE_VIEW_MEMBER_TYPE_ALIAS_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA))
0120 
0121 /**
0122  * Member type pointers for referencing by name
0123  */
0124 // clang-format off
0125 #define _DECLARE_VIEW_MEMBER_POINTERS_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME)                                     \
0126   SOA_HOST_DEVICE SOA_INLINE auto* BOOST_PP_CAT(addressOf_, LOCAL_NAME)() {                                            \
0127     return BOOST_PP_CAT(parametersOf_, LOCAL_NAME)().addr_;                                                            \
0128   };
0129 // clang-format on
0130 
0131 #define _DECLARE_VIEW_MEMBER_POINTERS(R, DATA, LAYOUT_MEMBER_NAME) \
0132   BOOST_PP_EXPAND(_DECLARE_VIEW_MEMBER_POINTERS_IMPL LAYOUT_MEMBER_NAME)
0133 
0134 /**
0135  * Member type const pointers for referencing by name
0136  */
0137 // clang-format off
0138 #define _DECLARE_VIEW_MEMBER_CONST_POINTERS_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME)                               \
0139   SOA_HOST_DEVICE SOA_INLINE auto const* BOOST_PP_CAT(addressOf_, LOCAL_NAME)() const {                                \
0140     return BOOST_PP_CAT(parametersOf_, LOCAL_NAME)().addr_;                                                            \
0141   };
0142 // clang-format on
0143 
0144 #define _DECLARE_VIEW_MEMBER_CONST_POINTERS(R, DATA, LAYOUT_MEMBER_NAME) \
0145   BOOST_PP_EXPAND(_DECLARE_VIEW_MEMBER_CONST_POINTERS_IMPL LAYOUT_MEMBER_NAME)
0146 
0147 /**
0148  * Generator of parameters (layouts/views) for constructor by layouts/views.
0149  */
0150 #define _DECLARE_VIEW_CONSTRUCTION_PARAMETERS_IMPL(LAYOUT_TYPE, LAYOUT_NAME, DATA) (DATA LAYOUT_TYPE & LAYOUT_NAME)
0151 
0152 #define _DECLARE_VIEW_CONSTRUCTION_PARAMETERS(R, DATA, TYPE_NAME) \
0153   BOOST_PP_EXPAND(_DECLARE_VIEW_CONSTRUCTION_PARAMETERS_IMPL BOOST_PP_TUPLE_PUSH_BACK(TYPE_NAME, DATA))
0154 
0155 /**
0156  * Generator of parameters for constructor by column.
0157  */
0158 #define _DECLARE_VIEW_CONSTRUCTION_BYCOLUMN_PARAMETERS_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME, DATA) \
0159   (DATA typename BOOST_PP_CAT(Metadata::ParametersTypeOf_, LOCAL_NAME)::TupleOrPointerType LOCAL_NAME)
0160 
0161 #define _DECLARE_VIEW_CONSTRUCTION_BYCOLUMN_PARAMETERS(R, DATA, LAYOUT_MEMBER_NAME) \
0162   BOOST_PP_EXPAND(                                                                  \
0163       _DECLARE_VIEW_CONSTRUCTION_BYCOLUMN_PARAMETERS_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA))
0164 
0165 /**
0166  * Generator of member initialization from constructor.
0167  * We use a lambda with auto return type to handle multiple possible return types.
0168  */
0169 // clang-format off
0170 #define _DECLARE_VIEW_MEMBER_INITIALIZERS_IMPL(LAYOUT, MEMBER, NAME)                                                   \
0171   (BOOST_PP_CAT(NAME, Parameters_)([&]() -> auto {                                                                     \
0172     auto params = LAYOUT.metadata().BOOST_PP_CAT(parametersOf_, MEMBER)();                                             \
0173     if constexpr (alignmentEnforcement == AlignmentEnforcement::enforced)                                              \
0174       if (reinterpret_cast<intptr_t>(params.addr_) % alignment)                                                        \
0175         throw std::runtime_error("In constructor by layout: misaligned column: " #NAME);                               \
0176     return params;                                                                                                     \
0177   }()))
0178 // clang-format on
0179 
0180 #define _DECLARE_VIEW_MEMBER_INITIALIZERS(R, DATA, LAYOUT_MEMBER_NAME) \
0181   BOOST_PP_EXPAND(_DECLARE_VIEW_MEMBER_INITIALIZERS_IMPL LAYOUT_MEMBER_NAME)
0182 
0183 /**
0184  * Generator of size computation for constructor.
0185  * This is the per-layout part of the lambda checking they all have the same size.
0186  */
0187 // clang-format off
0188 #define _UPDATE_SIZE_OF_VIEW_IMPL(LAYOUT_TYPE, LAYOUT_NAME)                                                            \
0189   if (set) {                                                                                                           \
0190     if (ret != LAYOUT_NAME.metadata().size())                                                                          \
0191       throw std::runtime_error("In constructor by layout: different sizes from layouts.");                             \
0192   } else {                                                                                                             \
0193     ret = LAYOUT_NAME.metadata().size();                                                                               \
0194     set = true;                                                                                                        \
0195   }
0196 // clang-format on
0197 
0198 #define _UPDATE_SIZE_OF_VIEW(R, DATA, TYPE_NAME) BOOST_PP_EXPAND(_UPDATE_SIZE_OF_VIEW_IMPL TYPE_NAME)
0199 
0200 /**
0201  * Generator of member initialization from constructor.
0202  * We use a lambda with auto return type to handle multiple possible return types.
0203  */
0204 // clang-format off
0205 #define _DECLARE_VIEW_MEMBER_INITIALIZERS_BYCOLUMN_IMPL(LAYOUT, MEMBER, NAME)                                          \
0206   (                                                                                                                    \
0207     BOOST_PP_CAT(NAME, Parameters_)([&]() -> auto {                                                                    \
0208       if constexpr (alignmentEnforcement == AlignmentEnforcement::enforced)                                            \
0209         if (Metadata:: BOOST_PP_CAT(ParametersTypeOf_, NAME)::checkAlignment(NAME, alignment))                         \
0210           throw std::runtime_error("In constructor by column: misaligned column: " #NAME);                             \
0211       return NAME;                                                                                                     \
0212     }())                                                                                                               \
0213   )
0214 // clang-format on
0215 
0216 #define _DECLARE_VIEW_MEMBER_INITIALIZERS_BYCOLUMN(R, DATA, LAYOUT_MEMBER_NAME) \
0217   BOOST_PP_EXPAND(_DECLARE_VIEW_MEMBER_INITIALIZERS_BYCOLUMN_IMPL LAYOUT_MEMBER_NAME)
0218 
0219 /**
0220  * Generator of layout list.
0221  */
0222 #define _DECLARE_LAYOUT_LIST_IMPL(LAYOUT, NAME) (NAME)
0223 
0224 #define _DECLARE_LAYOUT_LIST(R, DATA, LAYOUT_MEMBER_NAME) BOOST_PP_EXPAND(_DECLARE_LAYOUT_LIST_IMPL LAYOUT_MEMBER_NAME)
0225 
0226 /**
0227  * Generator of view member list.
0228  */
0229 #define _DECLARE_VIEW_MEMBER_LIST_IMPL(LAYOUT, MEMBER, NAME) (NAME)
0230 
0231 #define _DECLARE_VIEW_MEMBER_LIST(R, DATA, LAYOUT_MEMBER_NAME) \
0232   BOOST_PP_EXPAND(_DECLARE_VIEW_MEMBER_LIST_IMPL LAYOUT_MEMBER_NAME)
0233 
0234 /**
0235  * Generator of view member list.
0236  */
0237 #define _DECLARE_VIEW_OTHER_MEMBER_LIST_IMPL(LAYOUT, MEMBER, NAME) \
0238   (const_cast_SoAParametersImpl(other.BOOST_PP_CAT(NAME, Parameters_)).tupleOrPointer())
0239 
0240 #define _DECLARE_VIEW_OTHER_MEMBER_LIST(R, DATA, LAYOUT_MEMBER_NAME) \
0241   BOOST_PP_EXPAND(_DECLARE_VIEW_OTHER_MEMBER_LIST_IMPL LAYOUT_MEMBER_NAME)
0242 
0243 /**
0244  * Generator of member initializer for copy constructor.
0245  */
0246 #define _DECLARE_VIEW_MEMBER_INITIALIZERS_FROM_OTHER_IMPL(LAYOUT, MEMBER, LOCAL_NAME, DATA) \
0247   (BOOST_PP_CAT(MEMBER, Parameters_){DATA.BOOST_PP_CAT(MEMBER, Parameters_)})
0248 
0249 #define _DECLARE_VIEW_MEMBER_INITIALIZERS_FROM_OTHER(R, DATA, LAYOUT_MEMBER_NAME) \
0250   BOOST_PP_EXPAND(_DECLARE_VIEW_MEMBER_INITIALIZERS_FROM_OTHER_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA))
0251 
0252 /**
0253  * Generator of member assignment for assignment operator.
0254  */
0255 #define _DECLARE_VIEW_MEMBER_ASSIGNMENT_FROM_OTHER_IMPL(LAYOUT, MEMBER, LOCAL_NAME, DATA) \
0256   BOOST_PP_CAT(MEMBER, Parameters_) = DATA.BOOST_PP_CAT(MEMBER, Parameters_);
0257 
0258 #define _DECLARE_VIEW_MEMBER_ASSIGNMENT_FROM_OTHER(R, DATA, LAYOUT_MEMBER_NAME) \
0259   BOOST_PP_EXPAND(_DECLARE_VIEW_MEMBER_ASSIGNMENT_FROM_OTHER_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA))
0260 
0261 /**
0262  * Generator of element members initializer.
0263  */
0264 #define _DECLARE_VIEW_ELEM_MEMBER_INIT_IMPL(LAYOUT, MEMBER, LOCAL_NAME, DATA) (LOCAL_NAME(DATA, LOCAL_NAME))
0265 
0266 #define _DECLARE_VIEW_ELEM_MEMBER_INIT(R, DATA, LAYOUT_MEMBER_NAME) \
0267   BOOST_PP_EXPAND(_DECLARE_VIEW_ELEM_MEMBER_INIT_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA))
0268 
0269 /**
0270  * Helper macro extracting the data type from metadata of a layout or view
0271  */
0272 #define _COLUMN_TYPE(LAYOUT_NAME, LAYOUT_MEMBER) \
0273   typename std::remove_pointer<decltype(BOOST_PP_CAT(LAYOUT_NAME, Type)()::LAYOUT_MEMBER())>::type
0274 
0275 /**
0276  * Generator of parameters for (non-const) element subclass (expanded comma separated).
0277  */
0278 #define _DECLARE_VIEW_ELEMENT_VALUE_ARG_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME, DATA) \
0279   (DATA typename BOOST_PP_CAT(Metadata::ParametersTypeOf_, LOCAL_NAME) LOCAL_NAME)
0280 
0281 #define _DECLARE_VIEW_ELEMENT_VALUE_ARG(R, DATA, LAYOUT_MEMBER_NAME) \
0282   _DECLARE_VIEW_ELEMENT_VALUE_ARG_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA)
0283 
0284 /**
0285  * Generator of parameters for (const) element subclass (expanded comma separated).
0286  */
0287 #define _DECLARE_CONST_VIEW_ELEMENT_VALUE_ARG_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME, DATA) \
0288   (DATA typename BOOST_PP_CAT(Metadata::ParametersTypeOf_, LOCAL_NAME)::ConstType LOCAL_NAME)
0289 
0290 #define _DECLARE_CONST_VIEW_ELEMENT_VALUE_ARG(R, DATA, LAYOUT_MEMBER_NAME) \
0291   _DECLARE_CONST_VIEW_ELEMENT_VALUE_ARG_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA)
0292 
0293 /**
0294  * Generator of member initialization for constructor of element subclass
0295  */
0296 #define _DECLARE_VIEW_CONST_ELEM_MEMBER_INIT_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME, DATA) \
0297   (BOOST_PP_CAT(LOCAL_NAME, _)(DATA, LOCAL_NAME))
0298 
0299 /* declare AoS-like element value args for contructor; these should expand,for columns only */
0300 #define _DECLARE_VIEW_CONST_ELEM_MEMBER_INIT(R, DATA, LAYOUT_MEMBER_NAME) \
0301   BOOST_PP_EXPAND(_DECLARE_VIEW_CONST_ELEM_MEMBER_INIT_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA))
0302 
0303 /**
0304  * Declaration of the members accessors of the const element subclass
0305  */
0306 // clang-format off
0307 #define _DECLARE_VIEW_CONST_ELEMENT_ACCESSOR_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME)                              \
0308   SOA_HOST_DEVICE SOA_INLINE                                                                                           \
0309       const typename SoAConstValueWithConf<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME),                          \
0310       const typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::RefToConst                                          \
0311       LOCAL_NAME() const {                                                                                             \
0312     return BOOST_PP_CAT(LOCAL_NAME, _)();                                                                              \
0313   }
0314 // clang-format on
0315 
0316 #define _DECLARE_VIEW_CONST_ELEMENT_ACCESSOR(R, DATA, LAYOUT_MEMBER_NAME) \
0317   _DECLARE_VIEW_CONST_ELEMENT_ACCESSOR_IMPL LAYOUT_MEMBER_NAME
0318 
0319 /**
0320  * Declaration of the private members of the const element subclass
0321  */
0322 // clang-format off
0323 #define _DECLARE_VIEW_CONST_ELEMENT_VALUE_MEMBER_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME)                          \
0324   const cms::soa::ConstValueTraits<SoAConstValueWithConf<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME),            \
0325                                                          typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>,        \
0326                                    BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME)>                                  \
0327       BOOST_PP_CAT(LOCAL_NAME, _);
0328 // clang-format on
0329 
0330 #define _DECLARE_VIEW_CONST_ELEMENT_VALUE_MEMBER(R, DATA, LAYOUT_MEMBER_NAME) \
0331   _DECLARE_VIEW_CONST_ELEMENT_VALUE_MEMBER_IMPL LAYOUT_MEMBER_NAME
0332 
0333 /**
0334  * Generator of the member-by-member copy operator of the element subclass.
0335  */
0336 #define _DECLARE_VIEW_ELEMENT_VALUE_COPY_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME)                 \
0337   if constexpr (Metadata::BOOST_PP_CAT(ColumnTypeOf_, LOCAL_NAME) != cms::soa::SoAColumnType::scalar) \
0338     LOCAL_NAME() = _soa_impl_other.LOCAL_NAME();
0339 
0340 #define _DECLARE_VIEW_ELEMENT_VALUE_COPY(R, DATA, LAYOUT_MEMBER_NAME) \
0341   BOOST_PP_EXPAND(_DECLARE_VIEW_ELEMENT_VALUE_COPY_IMPL LAYOUT_MEMBER_NAME)
0342 
0343 /**
0344  * Declaration of the private members of the const element subclass
0345  */
0346 // clang-format off
0347 #define _DECLARE_VIEW_ELEMENT_VALUE_MEMBER_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME)                                \
0348   SoAValueWithConf<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME),                                                  \
0349                    typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>                                               \
0350       LOCAL_NAME;
0351 // clang-format on
0352 
0353 #define _DECLARE_VIEW_ELEMENT_VALUE_MEMBER(R, DATA, LAYOUT_MEMBER_NAME) \
0354   _DECLARE_VIEW_ELEMENT_VALUE_MEMBER_IMPL LAYOUT_MEMBER_NAME
0355 
0356 /**
0357  * Parameters passed to const element subclass constructor in operator[]
0358  */
0359 #define _DECLARE_VIEW_CONST_ELEMENT_CONSTR_CALL_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME) \
0360   (BOOST_PP_CAT(LOCAL_NAME, Parameters_))
0361 
0362 #define _DECLARE_VIEW_CONST_ELEMENT_CONSTR_CALL(R, DATA, LAYOUT_MEMBER_NAME) \
0363   BOOST_PP_EXPAND(_DECLARE_VIEW_CONST_ELEMENT_CONSTR_CALL_IMPL LAYOUT_MEMBER_NAME)
0364 
0365 /**
0366  * Parameters passed to element subclass constructor in operator[]
0367  *
0368  * The use of const_cast (inside const_cast_SoAParametersImpl) is safe because the constructor of a View binds only to
0369  * non-const arguments.
0370  */
0371 #define _DECLARE_VIEW_ELEMENT_CONSTR_CALL_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME) \
0372   (const_cast_SoAParametersImpl(base_type::BOOST_PP_CAT(LOCAL_NAME, Parameters_)))
0373 
0374 #define _DECLARE_VIEW_ELEMENT_CONSTR_CALL(R, DATA, LAYOUT_MEMBER_NAME) \
0375   BOOST_PP_EXPAND(_DECLARE_VIEW_ELEMENT_CONSTR_CALL_IMPL LAYOUT_MEMBER_NAME)
0376 
0377 /**
0378  * Direct access to column pointer and indexed access
0379  */
0380 // clang-format off
0381 #define _DECLARE_VIEW_SOA_ACCESSOR_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME)                                        \
0382   /* Column or scalar */                                                                                               \
0383   SOA_HOST_DEVICE SOA_INLINE                                                                                           \
0384   typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                              \
0385         template ColumnType<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                   \
0386             cms::soa::SoAAccessType::mutableAccess>::template Alignment<conditionalAlignment>::                        \
0387                  template RestrictQualifier<restrictQualify>::NoParamReturnType                                        \
0388   LOCAL_NAME() {                                                                                                       \
0389     return typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                     \
0390         template ColumnType<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                   \
0391             cms::soa::SoAAccessType::mutableAccess>::template Alignment<conditionalAlignment>::                        \
0392                 template RestrictQualifier<restrictQualify>(const_cast_SoAParametersImpl(                              \
0393                     base_type:: BOOST_PP_CAT(LOCAL_NAME, Parameters_)))();                                             \
0394   }                                                                                                                    \
0395   SOA_HOST_DEVICE SOA_INLINE                                                                                           \
0396   typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                              \
0397         template ColumnType<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                   \
0398             cms::soa::SoAAccessType::mutableAccess>::template Alignment<conditionalAlignment>::                        \
0399                  template RestrictQualifier<restrictQualify>::ParamReturnType                                          \
0400   LOCAL_NAME(size_type _soa_impl_index) {                                                                              \
0401     if constexpr (rangeChecking == cms::soa::RangeChecking::enabled) {                                                 \
0402       if (_soa_impl_index >= base_type::elements_ or _soa_impl_index < 0)                                              \
0403         SOA_THROW_OUT_OF_RANGE("Out of range index in mutable " #LOCAL_NAME "(size_type index)")                       \
0404     }                                                                                                                  \
0405     return typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                     \
0406         template ColumnType<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                   \
0407             cms::soa::SoAAccessType::mutableAccess>::template Alignment<conditionalAlignment>::                        \
0408                 template RestrictQualifier<restrictQualify>(const_cast_SoAParametersImpl(                              \
0409                     base_type:: BOOST_PP_CAT(LOCAL_NAME, Parameters_)))(_soa_impl_index);                              \
0410   }
0411 // clang-format on
0412 
0413 #define _DECLARE_VIEW_SOA_ACCESSOR(R, DATA, LAYOUT_MEMBER_NAME) \
0414   BOOST_PP_EXPAND(_DECLARE_VIEW_SOA_ACCESSOR_IMPL LAYOUT_MEMBER_NAME)
0415 
0416 /**
0417  * Direct access to column pointer (const) and indexed access.
0418  */
0419 // clang-format off
0420 #define _DECLARE_VIEW_SOA_CONST_ACCESSOR_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME)                                  \
0421   /* Column or scalar */                                                                                               \
0422   SOA_HOST_DEVICE SOA_INLINE                                                                                           \
0423   typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                              \
0424         template ColumnType<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                   \
0425             cms::soa::SoAAccessType::constAccess>::template Alignment<conditionalAlignment>::                          \
0426                 template RestrictQualifier<restrictQualify>::NoParamReturnType                                         \
0427   LOCAL_NAME() const {                                                                                                 \
0428     return typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                     \
0429         template ColumnType<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                   \
0430             cms::soa::SoAAccessType::constAccess>::template Alignment<conditionalAlignment>::                          \
0431                 template RestrictQualifier<restrictQualify>(BOOST_PP_CAT(LOCAL_NAME, Parameters_))();                  \
0432   }                                                                                                                    \
0433   SOA_HOST_DEVICE SOA_INLINE                                                                                           \
0434   typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                              \
0435         template ColumnType<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                   \
0436             cms::soa::SoAAccessType::constAccess>::template Alignment<conditionalAlignment>::                          \
0437                 template RestrictQualifier<restrictQualify>::ParamReturnType                                           \
0438   LOCAL_NAME(size_type _soa_impl_index) const {                                                                        \
0439     if constexpr (rangeChecking == cms::soa::RangeChecking::enabled) {                                                 \
0440       if (_soa_impl_index >= elements_ or _soa_impl_index < 0)                                                         \
0441         SOA_THROW_OUT_OF_RANGE("Out of range index in const " #LOCAL_NAME "(size_type index)")                         \
0442     }                                                                                                                  \
0443     return typename cms::soa::SoAAccessors<typename BOOST_PP_CAT(Metadata::TypeOf_, LOCAL_NAME)>::                     \
0444         template ColumnType<BOOST_PP_CAT(Metadata::ColumnTypeOf_, LOCAL_NAME)>::template AccessType<                   \
0445             cms::soa::SoAAccessType::constAccess>::template Alignment<conditionalAlignment>::                          \
0446                 template RestrictQualifier<restrictQualify>(BOOST_PP_CAT(LOCAL_NAME, Parameters_))(_soa_impl_index);   \
0447   }
0448 // clang-format on
0449 
0450 #define _DECLARE_VIEW_SOA_CONST_ACCESSOR(R, DATA, LAYOUT_MEMBER_NAME) \
0451   BOOST_PP_EXPAND(_DECLARE_VIEW_SOA_CONST_ACCESSOR_IMPL LAYOUT_MEMBER_NAME)
0452 
0453 /**
0454  * SoA class member declaration (column pointers and parameters).
0455  */
0456 #define _DECLARE_VIEW_SOA_MEMBER_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME, DATA) \
0457   typename BOOST_PP_CAT(Metadata::ParametersTypeOf_, LOCAL_NAME) BOOST_PP_CAT(LOCAL_NAME, Parameters_);
0458 
0459 #define _DECLARE_VIEW_SOA_MEMBER(R, DATA, LAYOUT_MEMBER_NAME) \
0460   BOOST_PP_EXPAND(_DECLARE_VIEW_SOA_MEMBER_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA))
0461 
0462 /**
0463  * Const SoA class member declaration (column pointers and parameters).
0464  */
0465 #define _DECLARE_CONST_VIEW_SOA_MEMBER_IMPL(LAYOUT_NAME, LAYOUT_MEMBER, LOCAL_NAME, DATA) \
0466   typename BOOST_PP_CAT(Metadata::ParametersTypeOf_, LOCAL_NAME)::ConstType BOOST_PP_CAT(LOCAL_NAME, Parameters_);
0467 
0468 #define _DECLARE_CONST_VIEW_SOA_MEMBER(R, DATA, LAYOUT_MEMBER_NAME) \
0469   BOOST_PP_EXPAND(_DECLARE_CONST_VIEW_SOA_MEMBER_IMPL BOOST_PP_TUPLE_PUSH_BACK(LAYOUT_MEMBER_NAME, DATA))
0470 
0471 /**
0472  * Assign the value of the view from the values in the value_element.
0473  */
0474 
0475 // clang-format off
0476 #define _TRIVIAL_VIEW_ASSIGN_VALUE_ELEMENT_IMPL(VALUE_TYPE, CPP_TYPE, NAME)                                            \
0477   _SWITCH_ON_TYPE(VALUE_TYPE,                                                                                          \
0478       /* Scalar (empty) */                                                                                             \
0479       ,                                                                                                                \
0480       /* Column */                                                                                                     \
0481       NAME() = _soa_impl_value.NAME;                                                                                   \
0482       ,                                                                                                                \
0483       /* Eigen column */                                                                                               \
0484       NAME() = _soa_impl_value.NAME;                                                                                   \
0485 )
0486 // clang-format on
0487 
0488 #define _TRIVIAL_VIEW_ASSIGN_VALUE_ELEMENT(R, DATA, TYPE_NAME) _TRIVIAL_VIEW_ASSIGN_VALUE_ELEMENT_IMPL TYPE_NAME
0489 
0490 /* ---- MUTABLE VIEW ------------------------------------------------------------------------------------------------ */
0491 // clang-format off
0492 #define _GENERATE_SOA_VIEW_PART_0(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                                          \
0493   template <CMS_SOA_BYTE_SIZE_TYPE VIEW_ALIGNMENT = cms::soa::CacheLineSize::defaultSize,                              \
0494             bool VIEW_ALIGNMENT_ENFORCEMENT = cms::soa::AlignmentEnforcement::relaxed,                                 \
0495             bool RESTRICT_QUALIFY = cms::soa::RestrictQualify::Default,                                                \
0496             bool RANGE_CHECKING = cms::soa::RangeChecking::Default>                                                    \
0497   struct VIEW : public CONST_VIEW<VIEW_ALIGNMENT, VIEW_ALIGNMENT_ENFORCEMENT, RESTRICT_QUALIFY, RANGE_CHECKING> {      \
0498     /* Declare the parametrized layouts as the default */                                                              \
0499     /*BOOST_PP_SEQ_CAT(_ITERATE_ON_ALL(_DECLARE_VIEW_LAYOUT_PARAMETRIZED_TEMPLATE, ~, LAYOUTS_LIST))   */              \
0500     /* these could be moved to an external type trait to free up the symbol names */                                   \
0501     using self_type = VIEW;                                                                                            \
0502     using base_type = CONST_VIEW<VIEW_ALIGNMENT, VIEW_ALIGNMENT_ENFORCEMENT, RESTRICT_QUALIFY, RANGE_CHECKING>;
0503 // clang-format on
0504 
0505 // clang-format off
0506 #define _GENERATE_SOA_VIEW_PART_0_NO_DEFAULTS(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                              \
0507   template <CMS_SOA_BYTE_SIZE_TYPE VIEW_ALIGNMENT,                                                                     \
0508             bool VIEW_ALIGNMENT_ENFORCEMENT,                                                                           \
0509             bool RESTRICT_QUALIFY,                                                                                     \
0510             bool RANGE_CHECKING>                                                                                       \
0511   struct VIEW : public CONST_VIEW<VIEW_ALIGNMENT, VIEW_ALIGNMENT_ENFORCEMENT, RESTRICT_QUALIFY, RANGE_CHECKING> {      \
0512     /* Declare the parametrized layouts as the default */                                                              \
0513     /*BOOST_PP_SEQ_CAT(_ITERATE_ON_ALL(_DECLARE_VIEW_LAYOUT_PARAMETRIZED_TEMPLATE, ~, LAYOUTS_LIST))   */              \
0514     /* these could be moved to an external type trait to free up the symbol names */                                   \
0515     using self_type = VIEW;                                                                                            \
0516     using base_type = CONST_VIEW<VIEW_ALIGNMENT, VIEW_ALIGNMENT_ENFORCEMENT, RESTRICT_QUALIFY, RANGE_CHECKING>;
0517 // clang-format on
0518 
0519 /**
0520  * Split of the const view definition where the parametrized template alias for the layout is defined for layout trivial view.
0521  */
0522 
0523 // clang-format off
0524 #define _GENERATE_SOA_VIEW_PART_1(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                                          \
0525     using size_type = cms::soa::size_type;                                                                             \
0526     using byte_size_type = cms::soa::byte_size_type;                                                                   \
0527     using AlignmentEnforcement = cms::soa::AlignmentEnforcement;                                                       \
0528                                                                                                                        \
0529     /* For CUDA applications, we align to the 128 bytes of the cache lines.                                            \
0530      * See https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#global-memory-3-0 this is still valid      \
0531      * up to compute capability 8.X.                                                                                   \
0532      */                                                                                                                \
0533     constexpr static byte_size_type defaultAlignment = cms::soa::CacheLineSize::defaultSize;                           \
0534     constexpr static byte_size_type alignment = VIEW_ALIGNMENT;                                                        \
0535     constexpr static bool alignmentEnforcement = VIEW_ALIGNMENT_ENFORCEMENT;                                           \
0536     constexpr static byte_size_type conditionalAlignment =                                                             \
0537         alignmentEnforcement == AlignmentEnforcement::enforced ? alignment : 0;                                        \
0538     constexpr static bool restrictQualify = RESTRICT_QUALIFY;                                                          \
0539     constexpr static bool rangeChecking = RANGE_CHECKING;                                                              \
0540     /* Those typedefs avoid having commas in macros (which is problematic) */                                          \
0541     template <cms::soa::SoAColumnType COLUMN_TYPE, class C>                                                            \
0542     using SoAValueWithConf = cms::soa::SoAValue<COLUMN_TYPE, C, conditionalAlignment, restrictQualify>;                \
0543                                                                                                                        \
0544     template <cms::soa::SoAColumnType COLUMN_TYPE, class C>                                                            \
0545     using SoAConstValueWithConf = cms::soa::SoAConstValue<COLUMN_TYPE, C, conditionalAlignment, restrictQualify>;      \
0546                                                                                                                        \
0547     template <CMS_SOA_BYTE_SIZE_TYPE, bool, bool, bool>                                                                \
0548     friend struct VIEW;                                                                                                \
0549                                                                                                                        \
0550     /**                                                                                                                \
0551      * Helper/friend class allowing SoA introspection.                                                                 \
0552      */                                                                                                                \
0553     struct Metadata {                                                                                                  \
0554       friend VIEW;                                                                                                     \
0555       SOA_HOST_DEVICE SOA_INLINE size_type size() const { return parent_.elements_; }                                  \
0556       /* Alias layout or view types to name-derived identifyer to allow simpler definitions */                         \
0557       _ITERATE_ON_ALL(_DECLARE_VIEW_LAYOUT_TYPE_ALIAS, ~, LAYOUTS_LIST)                                                \
0558                                                                                                                        \
0559       /* Alias member types to name-derived identifyer to allow simpler definitions */                                 \
0560       _ITERATE_ON_ALL(_DECLARE_VIEW_MEMBER_TYPE_ALIAS, const_cast_SoAParametersImpl, VALUE_LIST)                       \
0561       _ITERATE_ON_ALL(_DECLARE_VIEW_MEMBER_POINTERS, ~, VALUE_LIST)                                                    \
0562       _ITERATE_ON_ALL(_DECLARE_VIEW_MEMBER_CONST_POINTERS, ~, VALUE_LIST)                                              \
0563                                                                                                                        \
0564       /* Forbid copying to avoid const correctness evasion */                                                          \
0565       Metadata& operator=(const Metadata&) = delete;                                                                   \
0566       Metadata(const Metadata&) = delete;                                                                              \
0567                                                                                                                        \
0568     private:                                                                                                           \
0569       SOA_HOST_DEVICE SOA_INLINE Metadata(const VIEW& _soa_impl_parent) : parent_(_soa_impl_parent) {}                 \
0570       const VIEW& parent_;                                                                                             \
0571     };                                                                                                                 \
0572                                                                                                                        \
0573     friend Metadata;                                                                                                   \
0574     SOA_HOST_DEVICE SOA_INLINE const Metadata metadata() const { return Metadata(*this); }                             \
0575     SOA_HOST_DEVICE SOA_INLINE Metadata metadata() { return Metadata(*this); }                                         \
0576                                                                                                                        \
0577     /* Trivial constuctor */                                                                                           \
0578     VIEW() = default;                                                                                                  \
0579                                                                                                                        \
0580     /* Constructor relying on user provided layouts or views */                                                        \
0581     SOA_HOST_ONLY VIEW(_ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_CONSTRUCTION_PARAMETERS, BOOST_PP_EMPTY(), LAYOUTS_LIST))   \
0582         : base_type{_ITERATE_ON_ALL_COMMA(_DECLARE_LAYOUT_LIST, BOOST_PP_EMPTY(), LAYOUTS_LIST)} {}                    \
0583                                                                                                                        \
0584     /* Constructor relying on individually provided column addresses */                                                \
0585     SOA_HOST_ONLY VIEW(size_type _soa_impl_elements,                                                                   \
0586                         _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_CONSTRUCTION_BYCOLUMN_PARAMETERS,                          \
0587                                               BOOST_PP_EMPTY(),                                                        \
0588                                               VALUE_LIST))                                                             \
0589         : base_type{_soa_impl_elements,                                                                                \
0590                     _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_MEMBER_LIST, BOOST_PP_EMPTY(), VALUE_LIST)                     \
0591           } {}                                                                                                         \
0592                                                                                                                        \
0593     /* Copiable */                                                                                                     \
0594     VIEW(VIEW const&) = default;                                                                                       \
0595     VIEW& operator=(VIEW const&) = default;                                                                            \
0596                                                                                                                        \
0597     /* Copy constructor for other parameters */                                                                        \
0598     template <CMS_SOA_BYTE_SIZE_TYPE OTHER_VIEW_ALIGNMENT,                                                             \
0599               bool OTHER_VIEW_ALIGNMENT_ENFORCEMENT,                                                                   \
0600               bool OTHER_RESTRICT_QUALIFY,                                                                             \
0601               bool OTHER_RANGE_CHECKING>                                                                               \
0602     VIEW(VIEW<OTHER_VIEW_ALIGNMENT, OTHER_VIEW_ALIGNMENT_ENFORCEMENT, OTHER_RESTRICT_QUALIFY,                          \
0603               OTHER_RANGE_CHECKING> const& other): base_type{other.elements_,                                          \
0604                 _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_OTHER_MEMBER_LIST, BOOST_PP_EMPTY(), VALUE_LIST)                   \
0605               } {}                                                                                                     \
0606     /* Copy operator for other parameters */                                                                           \
0607     template <CMS_SOA_BYTE_SIZE_TYPE OTHER_VIEW_ALIGNMENT,                                                             \
0608               bool OTHER_VIEW_ALIGNMENT_ENFORCEMENT,                                                                   \
0609               bool OTHER_RESTRICT_QUALIFY,                                                                             \
0610               bool OTHER_RANGE_CHECKING>                                                                               \
0611     VIEW& operator=(VIEW<OTHER_VIEW_ALIGNMENT, OTHER_VIEW_ALIGNMENT_ENFORCEMENT, OTHER_RESTRICT_QUALIFY,               \
0612               OTHER_RANGE_CHECKING> const& other) { static_cast<base_type>(*this) = static_cast<base_type>(other); }   \
0613                                                                                                                        \
0614     /* Movable */                                                                                                      \
0615     VIEW(VIEW &&) = default;                                                                                           \
0616     VIEW& operator=(VIEW &&) = default;                                                                                \
0617                                                                                                                        \
0618     /* Trivial destuctor */                                                                                            \
0619     ~VIEW() = default;                                                                                                 \
0620                                                                                                                        \
0621     /* AoS-like accessor (const) */                                                                                    \
0622     using const_element = typename base_type::const_element;                                                           \
0623                                                                                                                        \
0624     using base_type::operator[];                                                                                       \
0625                                                                                                                        \
0626     /* AoS-like accessor (mutable) */                                                                                  \
0627     struct element {                                                                                                   \
0628       SOA_HOST_DEVICE SOA_INLINE                                                                                       \
0629       element(size_type _soa_impl_index, /* Declare parameters */                                                      \
0630               _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_ELEMENT_VALUE_ARG, BOOST_PP_EMPTY(), VALUE_LIST))                    \
0631           : _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_ELEM_MEMBER_INIT, _soa_impl_index, VALUE_LIST) {}                      \
0632       SOA_HOST_DEVICE SOA_INLINE                                                                                       \
0633       element& operator=(const element& _soa_impl_other) {                                                             \
0634         _ITERATE_ON_ALL(_DECLARE_VIEW_ELEMENT_VALUE_COPY, ~, VALUE_LIST)                                               \
0635         return *this;                                                                                                  \
0636       }                                                                                                                \
0637       SOA_HOST_DEVICE SOA_INLINE                                                                                       \
0638       element& operator=(const const_element& _soa_impl_other) {                                                       \
0639         _ITERATE_ON_ALL(_DECLARE_VIEW_ELEMENT_VALUE_COPY, ~, VALUE_LIST)                                               \
0640         return *this;                                                                                                  \
0641       }
0642 // clang-format on
0643 
0644 // clang-format off
0645 #define _GENERATE_SOA_VIEW_PART_2(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                                          \
0646       _ITERATE_ON_ALL(_DECLARE_VIEW_ELEMENT_VALUE_MEMBER, ~, VALUE_LIST)                                               \
0647     };                                                                                                                 \
0648                                                                                                                        \
0649     SOA_HOST_DEVICE SOA_INLINE                                                                                         \
0650     element operator[](size_type _soa_impl_index) {                                                                    \
0651       if constexpr (rangeChecking == cms::soa::RangeChecking::enabled) {                                               \
0652         if (_soa_impl_index >= base_type::elements_ or _soa_impl_index < 0)                                            \
0653           SOA_THROW_OUT_OF_RANGE("Out of range index in " #VIEW "::operator[]")                                        \
0654       }                                                                                                                \
0655       return element{_soa_impl_index, _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_ELEMENT_CONSTR_CALL, ~, VALUE_LIST)};        \
0656     }                                                                                                                  \
0657                                                                                                                        \
0658     /* inherit const accessors from ConstView */                                                                       \
0659                                                                                                                        \
0660     /* non-const accessors */                                                                                          \
0661     _ITERATE_ON_ALL(_DECLARE_VIEW_SOA_ACCESSOR, ~, VALUE_LIST)                                                         \
0662                                                                                                                        \
0663     /* dump the SoA internal structure */                                                                              \
0664     template <typename T>                                                                                              \
0665     SOA_HOST_ONLY friend void dump();                                                                                  \
0666   };
0667 // clang-format on
0668 
0669 /* ---- CONST VIEW -------------------------------------------------------------------------------------------------- */
0670 // clang-format off
0671 #define _GENERATE_SOA_CONST_VIEW_PART_0(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                                    \
0672   template <CMS_SOA_BYTE_SIZE_TYPE VIEW_ALIGNMENT = cms::soa::CacheLineSize::defaultSize,                              \
0673             bool VIEW_ALIGNMENT_ENFORCEMENT = cms::soa::AlignmentEnforcement::relaxed,                                 \
0674             bool RESTRICT_QUALIFY = cms::soa::RestrictQualify::Default,                                                \
0675             bool RANGE_CHECKING = cms::soa::RangeChecking::Default>                                                    \
0676   struct CONST_VIEW {                                                                                                  \
0677     /* these could be moved to an external type trait to free up the symbol names */                                   \
0678     using self_type = CONST_VIEW;
0679 // clang-format on
0680 
0681 // clang-format off
0682 #define _GENERATE_SOA_CONST_VIEW_PART_0_NO_DEFAULTS(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                        \
0683   template <CMS_SOA_BYTE_SIZE_TYPE VIEW_ALIGNMENT,                                                                     \
0684             bool VIEW_ALIGNMENT_ENFORCEMENT,                                                                           \
0685             bool RESTRICT_QUALIFY,                                                                                     \
0686             bool RANGE_CHECKING>                                                                                       \
0687   struct CONST_VIEW {                                                                                                  \
0688     /* these could be moved to an external type trait to free up the symbol names */                                   \
0689     using self_type = CONST_VIEW;
0690 // clang-format on
0691 
0692 /**
0693  * Split of the const view definition where the parametrized template alias for the layout is defined for layout trivial view.
0694  */
0695 
0696 // clang-format off
0697 #define _GENERATE_SOA_CONST_VIEW_PART_1(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                                    \
0698     using size_type = cms::soa::size_type;                                                                             \
0699     using byte_size_type = cms::soa::byte_size_type;                                                                   \
0700     using AlignmentEnforcement = cms::soa::AlignmentEnforcement;                                                       \
0701                                                                                                                        \
0702     template <CMS_SOA_BYTE_SIZE_TYPE, bool, bool, bool>                                                                \
0703     friend struct VIEW;                                                                                                \
0704                                                                                                                        \
0705     template <CMS_SOA_BYTE_SIZE_TYPE, bool, bool, bool>                                                                \
0706     friend struct CONST_VIEW;                                                                                          \
0707                                                                                                                        \
0708     /* For CUDA applications, we align to the 128 bytes of the cache lines.                                            \
0709      * See https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#global-memory-3-0 this is still valid      \
0710      * up to compute capability 8.X.                                                                                   \
0711      */                                                                                                                \
0712     constexpr static byte_size_type defaultAlignment = cms::soa::CacheLineSize::defaultSize;                           \
0713     constexpr static byte_size_type alignment = VIEW_ALIGNMENT;                                                        \
0714     constexpr static bool alignmentEnforcement = VIEW_ALIGNMENT_ENFORCEMENT;                                           \
0715     constexpr static byte_size_type conditionalAlignment =                                                             \
0716         alignmentEnforcement == AlignmentEnforcement::enforced ? alignment : 0;                                        \
0717     constexpr static bool restrictQualify = RESTRICT_QUALIFY;                                                          \
0718     constexpr static bool rangeChecking = RANGE_CHECKING;                                                              \
0719     /* Those typedefs avoid having commas in macros (which is problematic) */                                          \
0720     template <cms::soa::SoAColumnType COLUMN_TYPE, class C>                                                            \
0721     using SoAValueWithConf = cms::soa::SoAValue<COLUMN_TYPE, C, conditionalAlignment, restrictQualify>;                \
0722                                                                                                                        \
0723     template <cms::soa::SoAColumnType COLUMN_TYPE, class C>                                                            \
0724     using SoAConstValueWithConf = cms::soa::SoAConstValue<COLUMN_TYPE, C, conditionalAlignment, restrictQualify>;      \
0725                                                                                                                        \
0726     /**                                                                                                                \
0727      * Helper/friend class allowing SoA introspection.                                                                 \
0728      */                                                                                                                \
0729     struct Metadata {                                                                                                  \
0730       friend CONST_VIEW;                                                                                               \
0731       SOA_HOST_DEVICE SOA_INLINE size_type size() const { return parent_.elements_; }                                  \
0732       /* Alias layout or view types to name-derived identifyer to allow simpler definitions */                         \
0733       _ITERATE_ON_ALL(_DECLARE_VIEW_LAYOUT_TYPE_ALIAS, ~, LAYOUTS_LIST)                                                \
0734                                                                                                                        \
0735       /* Alias member types to name-derived identifyer to allow simpler definitions */                                 \
0736       _ITERATE_ON_ALL(_DECLARE_VIEW_MEMBER_TYPE_ALIAS, BOOST_PP_EMPTY(), VALUE_LIST)                                   \
0737       _ITERATE_ON_ALL(_DECLARE_VIEW_MEMBER_CONST_POINTERS, ~, VALUE_LIST)                                              \
0738                                                                                                                        \
0739       /* Forbid copying to avoid const correctness evasion */                                                          \
0740       Metadata& operator=(const Metadata&) = delete;                                                                   \
0741       Metadata(const Metadata&) = delete;                                                                              \
0742                                                                                                                        \
0743     private:                                                                                                           \
0744       SOA_HOST_DEVICE SOA_INLINE Metadata(const CONST_VIEW& _soa_impl_parent) : parent_(_soa_impl_parent) {}           \
0745       const CONST_VIEW& parent_;                                                                                       \
0746     };                                                                                                                 \
0747                                                                                                                        \
0748     friend Metadata;                                                                                                   \
0749     SOA_HOST_DEVICE SOA_INLINE const Metadata metadata() const { return Metadata(*this); }                             \
0750                                                                                                                        \
0751     /* Trivial constuctor */                                                                                           \
0752     CONST_VIEW() = default;                                                                                            \
0753                                                                                                                        \
0754     /* Constructor relying on user provided layouts or views */                                                        \
0755     SOA_HOST_ONLY CONST_VIEW(_ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_CONSTRUCTION_PARAMETERS, const, LAYOUTS_LIST))        \
0756         : elements_([&]() -> size_type {                                                                               \
0757             bool set = false;                                                                                          \
0758             size_type ret = 0;                                                                                         \
0759             _ITERATE_ON_ALL(_UPDATE_SIZE_OF_VIEW, BOOST_PP_EMPTY(), LAYOUTS_LIST)                                      \
0760             return ret;                                                                                                \
0761           }()),                                                                                                        \
0762           _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_MEMBER_INITIALIZERS, ~, VALUE_LIST) {}                                   \
0763                                                                                                                        \
0764     /* Constructor relying on individually provided column addresses */                                                \
0765     SOA_HOST_ONLY CONST_VIEW(size_type _soa_impl_elements,                                                             \
0766                         _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_CONSTRUCTION_BYCOLUMN_PARAMETERS, const, VALUE_LIST))      \
0767         : elements_(_soa_impl_elements),                                                                               \
0768           _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_MEMBER_INITIALIZERS_BYCOLUMN, ~, VALUE_LIST) {}                          \
0769                                                                                                                        \
0770     /* Copiable */                                                                                                     \
0771     CONST_VIEW(CONST_VIEW const&) = default;                                                                           \
0772     CONST_VIEW& operator=(CONST_VIEW const&) = default;                                                                \
0773                                                                                                                        \
0774     /* Copy constructor for other parameters */                                                                        \
0775     template <CMS_SOA_BYTE_SIZE_TYPE OTHER_VIEW_ALIGNMENT,                                                             \
0776               bool OTHER_VIEW_ALIGNMENT_ENFORCEMENT,                                                                   \
0777               bool OTHER_RESTRICT_QUALIFY,                                                                             \
0778               bool OTHER_RANGE_CHECKING>                                                                               \
0779     CONST_VIEW(CONST_VIEW<OTHER_VIEW_ALIGNMENT, OTHER_VIEW_ALIGNMENT_ENFORCEMENT, OTHER_RESTRICT_QUALIFY,              \
0780               OTHER_RANGE_CHECKING> const& other): CONST_VIEW{other.elements_,                                         \
0781                 _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_OTHER_MEMBER_LIST, BOOST_PP_EMPTY(), VALUE_LIST)                   \
0782               } {}                                                                                                     \
0783     /* Copy operator for other parameters */                                                                           \
0784     template <CMS_SOA_BYTE_SIZE_TYPE OTHER_VIEW_ALIGNMENT,                                                             \
0785               bool OTHER_VIEW_ALIGNMENT_ENFORCEMENT,                                                                   \
0786               bool OTHER_RESTRICT_QUALIFY,                                                                             \
0787               bool OTHER_RANGE_CHECKING>                                                                               \
0788     CONST_VIEW& operator=(CONST_VIEW<OTHER_VIEW_ALIGNMENT, OTHER_VIEW_ALIGNMENT_ENFORCEMENT, OTHER_RESTRICT_QUALIFY,   \
0789               OTHER_RANGE_CHECKING> const& other) { *this = other; }                                                   \
0790                                                                                                                        \
0791     /* Movable */                                                                                                      \
0792     CONST_VIEW(CONST_VIEW &&) = default;                                                                               \
0793     CONST_VIEW& operator=(CONST_VIEW &&) = default;                                                                    \
0794                                                                                                                        \
0795     /* Trivial destuctor */                                                                                            \
0796     ~CONST_VIEW() = default;                                                                                           \
0797                                                                                                                        \
0798     /* AoS-like accessor (const) */                                                                                    \
0799     struct const_element {                                                                                             \
0800       SOA_HOST_DEVICE SOA_INLINE                                                                                       \
0801       const_element(size_type _soa_impl_index, /* Declare parameters */                                                \
0802                     _ITERATE_ON_ALL_COMMA(_DECLARE_CONST_VIEW_ELEMENT_VALUE_ARG, const, VALUE_LIST))                   \
0803           : _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_CONST_ELEM_MEMBER_INIT, _soa_impl_index, VALUE_LIST) {}                \
0804       _ITERATE_ON_ALL(_DECLARE_VIEW_CONST_ELEMENT_ACCESSOR, ~, VALUE_LIST)                                             \
0805                                                                                                                        \
0806     private:                                                                                                           \
0807       _ITERATE_ON_ALL(_DECLARE_VIEW_CONST_ELEMENT_VALUE_MEMBER, ~, VALUE_LIST)                                         \
0808     };                                                                                                                 \
0809                                                                                                                        \
0810     SOA_HOST_DEVICE SOA_INLINE                                                                                         \
0811     const_element operator[](size_type _soa_impl_index) const {                                                        \
0812       if constexpr (rangeChecking == cms::soa::RangeChecking::enabled) {                                               \
0813         if (_soa_impl_index >= elements_ or _soa_impl_index < 0)                                                       \
0814           SOA_THROW_OUT_OF_RANGE("Out of range index in " #CONST_VIEW "::operator[]")                                  \
0815       }                                                                                                                \
0816       return const_element{                                                                                            \
0817         _soa_impl_index, _ITERATE_ON_ALL_COMMA(_DECLARE_VIEW_CONST_ELEMENT_CONSTR_CALL, ~, VALUE_LIST)                 \
0818       };                                                                                                               \
0819     }                                                                                                                  \
0820                                                                                                                        \
0821     /* const accessors */                                                                                              \
0822     _ITERATE_ON_ALL(_DECLARE_VIEW_SOA_CONST_ACCESSOR, ~, VALUE_LIST)                                                   \
0823                                                                                                                        \
0824     /* dump the SoA internal structure */                                                                              \
0825     template <typename T>                                                                                              \
0826     SOA_HOST_ONLY friend void dump();                                                                                  \
0827                                                                                                                        \
0828   private:                                                                                                             \
0829     size_type elements_ = 0;                                                                                           \
0830     _ITERATE_ON_ALL(_DECLARE_CONST_VIEW_SOA_MEMBER, const, VALUE_LIST)                                                 \
0831 };
0832 // clang-format on
0833 
0834 // clang-format off
0835 // MAJOR caveat: in order to propagate the LAYOUTS_LIST and VALUE_LIST
0836 #define _GENERATE_SOA_CONST_VIEW(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                                           \
0837    _GENERATE_SOA_CONST_VIEW_PART_0(CONST_VIEW, VIEW,                                                                   \
0838      SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))                                              \
0839    _GENERATE_SOA_CONST_VIEW_PART_1(CONST_VIEW, VIEW,                                                                   \
0840      SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))
0841 
0842 #define GENERATE_SOA_CONST_VIEW(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                                            \
0843    _GENERATE_SOA_CONST_VIEW(CONST_VIEW, BOOST_PP_CAT(CONST_VIEW, Unused_),                                             \
0844      SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))
0845 
0846 #define _GENERATE_SOA_TRIVIAL_CONST_VIEW(CLASS, LAYOUTS_LIST, VALUE_LIST)                                              \
0847    _GENERATE_SOA_CONST_VIEW_PART_0_NO_DEFAULTS(ConstViewTemplateFreeParams, ViewTemplateFreeParams,                    \
0848      SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))                                              \
0849    using BOOST_PP_CAT(CLASS, _parametrized) = CLASS<VIEW_ALIGNMENT, VIEW_ALIGNMENT_ENFORCEMENT>;                       \
0850    _GENERATE_SOA_CONST_VIEW_PART_1(ConstViewTemplateFreeParams, ViewTemplateFreeParams,                                \
0851      SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))
0852 
0853 #define _GENERATE_SOA_VIEW(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                                                 \
0854    _GENERATE_SOA_VIEW_PART_0(CONST_VIEW, VIEW, SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))    \
0855    _GENERATE_SOA_VIEW_PART_1(CONST_VIEW, VIEW, SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))    \
0856    _GENERATE_SOA_VIEW_PART_2(CONST_VIEW, VIEW, SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))
0857 
0858 #define GENERATE_SOA_VIEW(CONST_VIEW, VIEW, LAYOUTS_LIST, VALUE_LIST)                                                  \
0859    _GENERATE_SOA_CONST_VIEW(CONST_VIEW, VIEW, SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))     \
0860    _GENERATE_SOA_VIEW(CONST_VIEW, VIEW, SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))
0861 
0862 #define _GENERATE_SOA_TRIVIAL_VIEW(CLASS, LAYOUTS_LIST, VALUE_LIST, ...)                                               \
0863    _GENERATE_SOA_VIEW_PART_0_NO_DEFAULTS(ConstViewTemplateFreeParams, ViewTemplateFreeParams,                          \
0864      SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))                                              \
0865    using BOOST_PP_CAT(CLASS, _parametrized) = CLASS<VIEW_ALIGNMENT, VIEW_ALIGNMENT_ENFORCEMENT>;                       \
0866    _GENERATE_SOA_VIEW_PART_1(ConstViewTemplateFreeParams, ViewTemplateFreeParams,                                      \
0867      SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))                                              \
0868                                                                                                                        \
0869    /* Extra operator=() for mutable element to emulate the aggregate initialisation syntax */                          \
0870    SOA_HOST_DEVICE SOA_INLINE constexpr element & operator=(const typename                                             \
0871        BOOST_PP_CAT(CLASS, _parametrized)::Metadata::value_element _soa_impl_value) {                                  \
0872      _ITERATE_ON_ALL(_TRIVIAL_VIEW_ASSIGN_VALUE_ELEMENT, ~, __VA_ARGS__)                                               \
0873      return *this;                                                                                                     \
0874    }                                                                                                                   \
0875                                                                                                                        \
0876    _GENERATE_SOA_VIEW_PART_2(ConstViewTemplateFreeParams, ViewTemplateFreeParams,                                      \
0877      SOA_VIEW_LAYOUT_LIST(LAYOUTS_LIST), SOA_VIEW_VALUE_LIST(VALUE_LIST))
0878 // clang-format on
0879 
0880 /**
0881  * Helper macro turning layout field declaration into view field declaration.
0882  */
0883 #define _VIEW_FIELD_FROM_LAYOUT_IMPL(VALUE_TYPE, CPP_TYPE, NAME, DATA) (DATA, NAME, NAME)
0884 
0885 #define _VIEW_FIELD_FROM_LAYOUT(R, DATA, VALUE_TYPE_NAME) \
0886   BOOST_PP_EXPAND((_VIEW_FIELD_FROM_LAYOUT_IMPL BOOST_PP_TUPLE_PUSH_BACK(VALUE_TYPE_NAME, DATA)))
0887 
0888 #endif  // DataFormats_SoATemplate_interface_SoAView_h