Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:34

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIALG_TUPLEPUT_H
0012 #define GAUDIALG_TUPLEPUT_H 1
0013 #include "GaudiAlg/TupleObj.h"
0014 #include "GaudiKernel/System.h"
0015 #include "TClass.h"
0016 #include <memory>
0017 // =============================================================================
0018 /** @file
0019  *  Implementation file for Tuple::TupleObj::put method
0020  *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0021  *  @date 2007-04-08
0022  */
0023 // =============================================================================
0024 namespace Tuples {
0025   /** @class ItemStore TuplePut.h GaudiAlg/TuplePut.h
0026    *
0027    *  Simple class, which represents the local storage of N-tuple items
0028    *  of the given type. Essentially it is a restricted
0029    *  std::unordered_map with ownership of the newly created entries
0030    *
0031    *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0032    *  @date   2007-04-08
0033    */
0034   template <class VALUE>
0035   class ItemStore final {
0036     friend class TupleObj;
0037 
0038   public:
0039     /// constructor : create empty map
0040     ItemStore() = default;
0041 
0042   private:
0043     /// the only one method:
0044     NTuple::Item<VALUE>* getItem( std::string_view key, Tuples::TupleObj* tuple ) {
0045       // find the item by name
0046       auto ifound = m_map.find( key );
0047       // existing item?
0048       if ( m_map.end() != ifound ) return &ifound->second.first; // RETURN
0049 
0050       // check the tuple for booking:
0051       if ( !tuple ) return nullptr;
0052       // check the existence of the name
0053       if ( !tuple->goodItem( key ) ) {
0054         tuple->Error( fmt::format( "ItemStore::getItem('{}') item name is not unique", key ) ).ignore();
0055         return nullptr; // RETURN
0056       }
0057       // get the underlying object
0058       NTuple::Tuple* tup = tuple->tuple();
0059       if ( !tup ) {
0060         tuple->Error( fmt::format( "ItemStore::getItem('{}') invalid NTuple::Tuple*", key ) ).ignore();
0061         return nullptr; // RETURN
0062       }
0063       // create new item:
0064       // add the newly created item into the store -- and point the key view into the mapped value...
0065       auto [iter, ok] = m_map.try_emplace( key, NTuple::Item<VALUE>{}, std::string{ key } );
0066       if ( ok ) {
0067         auto nh  = m_map.extract( iter );
0068         nh.key() = nh.mapped().second; // "re-point" key to the string contained value_type
0069         // std::tie( iter,ok,std::ignore)  = m_map.insert( std::move( nh ) );
0070         auto r = m_map.insert( std::move( nh ) );
0071         iter   = r.position;
0072         ok     = r.inserted;
0073       }
0074       if ( !ok ) {
0075         tuple->Warning( fmt::format( "ItemStore::getItem('{}') item already exists, new one not inserted!", key ) )
0076             .ignore();
0077         return nullptr;
0078       }
0079       auto& item = iter->second.first;
0080       // add it into N-tuple
0081       StatusCode sc = tup->addItem( iter->second.second, item ); // ATTENTION!
0082       if ( sc.isFailure() ) {
0083         tuple->Error( fmt::format( "ItemStore::getItem('{}') cannot addItem", key ), sc ).ignore();
0084         m_map.erase( iter );
0085         return nullptr; // RETURN
0086       }
0087       // check the name again
0088       if ( !tuple->addItem( iter->second.second, System::typeinfoName( typeid( VALUE ) ) ) ) {
0089         tuple->Warning( fmt::format( "ItemStore::getItem('{}') the item not unique ", key ) ).ignore();
0090         m_map.erase( iter );
0091         return nullptr;
0092       }
0093       //
0094       return &item; // RETURN
0095     }
0096 
0097     // delete copy constructor and assignment
0098     ItemStore( const ItemStore& )            = delete;
0099     ItemStore& operator=( const ItemStore& ) = delete;
0100 
0101   private:
0102     std::unordered_map<std::string_view, std::pair<NTuple::Item<VALUE>, std::string>> m_map; ///< the underlying map
0103   };
0104 } // end of namespace Tuples
0105 // =============================================================================
0106 /** The function allows to add almost arbitrary object into N-tuple
0107  *  @attention it requires POOL persistency
0108  *
0109  *  @param name column name
0110  *  @param obj  pointer to the object
0111  *
0112  *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0113  *  @date 2007-04-08
0114  */
0115 // =============================================================================
0116 template <class TYPE>
0117 StatusCode Tuples::TupleObj::put( std::string_view name, const TYPE* obj ) {
0118   if ( invalid() ) { return ErrorCodes::InvalidTuple; }         // RETURN
0119   if ( !evtColType() ) { return ErrorCodes::InvalidOperation; } // RETURN
0120 
0121   // static block: The type description & the flag
0122   static bool    s_fail = false;   // STATIC
0123   static TClass* s_type = nullptr; // STATIC
0124   // check the status
0125   if ( s_fail ) {
0126     return ErrorCodes::InvalidItem;
0127   } // RETURN
0128   else if ( !s_type ) {
0129     s_type = TClass::GetClass( typeid( TYPE ) );
0130     if ( !s_type ) {
0131       s_fail = true;
0132       return Error( fmt::format( " put('{}',{}) :Invalid ROOT Type", name, System::typeinfoName( typeid( TYPE ) ) ),
0133                     ErrorCodes::InvalidItem ); // RETURN
0134     }
0135   }
0136   // the local storage of items
0137   static Tuples::ItemStore<TYPE*> s_map;
0138   // get the variable by name:
0139   auto item = s_map.getItem( name, this );
0140   if ( !item ) { return Error( fmt::format( " put('{}'): invalid item detected", name ), ErrorCodes::InvalidItem ); }
0141   // assign the item!
0142   *item = const_cast<TYPE*>( obj ); // THATS ALL!!
0143   //
0144   return StatusCode::SUCCESS; // RETURN
0145 }
0146 // ============================================================================
0147 
0148 // ============================================================================
0149 // The END
0150 // ============================================================================
0151 #endif // GAUDIALG_TUPLEPUT_H