Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:13:09

0001 #ifndef FWCore_SOA_ColumnFillers_h
0002 #define FWCore_SOA_ColumnFillers_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     FWCore/SOA
0006 // Class  :     ColumnFillers
0007 //
0008 /**\class ColumnFillers ColumnFillers.h "ColumnFillers.h"
0009 
0010  Description: Controls how edm::soa::Table columns can be filled from C++ objects
0011 
0012  Usage:
0013     An edm::soa::Table<> can be filled from a container of objects if the appropriate overloaded
0014  functions are defined.
0015  
0016  The overloaded function must be called `value_for_column`. The function takes two arguments. The
0017  first argument is a const reference to the class in question, or its base class. The second argument
0018  is a pointer to the edm::soa::Column<> type. E.g.
0019  
0020  \code
0021      namespace reco {
0022         double value_for_column(Candidate const& iCand, edm::soa::Energy*) {
0023            return iCand.energy();
0024         }
0025      }
0026  \endcode
0027 
0028 */
0029 //
0030 // Original Author:  Chris Jones
0031 //         Created:  Thu, 24 Aug 2017 22:22:42 GMT
0032 //
0033 
0034 // system include files
0035 
0036 // user include files
0037 
0038 // forward declarations
0039 #include <tuple>
0040 
0041 namespace edm {
0042   namespace soa {
0043 
0044     template <typename... Args>
0045     class ColumnFillers {
0046       using Layout = std::tuple<Args...>;
0047       Layout m_fillers;
0048 
0049       template <int I, typename ELEMENT>
0050       decltype(auto) callFiller(ELEMENT&& iEl) {
0051         return std::get<I>(m_fillers).m_f(iEl);
0052       }
0053 
0054       template <int I, typename COLUMN, typename ELEMENT>
0055       typename COLUMN::type tryValue(ELEMENT&& iEl) {
0056         if constexpr (I < sizeof...(Args)) {
0057           using Pair = typename std::tuple_element<I, Layout>::type;
0058           using COL = typename Pair::Column_type;
0059           if constexpr (std::is_same<COL, COLUMN>::value) {
0060             return callFiller<I>(iEl);
0061           } else {
0062             //try another filler to see if it matches
0063             return tryValue<I + 1, COLUMN>(iEl);
0064           }
0065         } else {
0066           //no matches so call overload function
0067           return value_for_column(iEl, static_cast<COLUMN*>(nullptr));
0068         }
0069       }
0070 
0071     public:
0072       ColumnFillers(Args... iArgs) : m_fillers(std::forward<Args>(iArgs)...) {}
0073 
0074       template <typename ELEMENT, typename COLUMN>
0075       typename COLUMN::type value(ELEMENT&& iEl, COLUMN*) {
0076         return tryValue<0, COLUMN>(iEl);
0077       }
0078     };
0079 
0080     template <typename... Args>
0081     ColumnFillers<Args...> column_fillers(Args... iArgs) {
0082       return ColumnFillers<Args...>(std::forward<Args>(iArgs)...);
0083     }
0084 
0085   }  // namespace soa
0086 }  // namespace edm
0087 
0088 #endif