Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-08-23 22:39:53

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