CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/DataFormats/Common/interface/fillPtrVector.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_fillPtrVector_h
00002 #define DataFormats_Common_fillPtrVector_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     Common
00006 // Class  :     fillPtrVector
00007 // 
00016 //
00017 // Original Author:  Chris Jones
00018 //         Created:  Sat Oct 20 11:45:38 CEST 2007
00019 //
00020 
00021 // system include files
00022 
00023 // user include files
00024 #include "DataFormats/Common/interface/FillView.h"
00025 #include "FWCore/Utilities/interface/EDMException.h"
00026 #include "Reflex/Object.h"
00027 #include "Reflex/Type.h"
00028 
00029 // forward declarations
00030 namespace edm {
00031   namespace detail {
00032     
00033     
00034     template <class COLLECTION>
00035     void
00036     reallyfillPtrVector(COLLECTION const& coll,
00037                         const std::type_info& iToType,
00038                         const std::vector<unsigned long>& iIndicies,
00039                         std::vector<void const*>& oPtr)
00040     {
00041       typedef COLLECTION                            product_type;
00042       typedef typename GetProduct<product_type>::element_type     element_type;
00043       typedef typename product_type::const_iterator iter;
00044       typedef typename product_type::size_type      size_type;
00045       
00046       oPtr.reserve(iIndicies.size());
00047       if(iToType == typeid(element_type)) {
00048         for(std::vector<unsigned long>::const_iterator itIndex=iIndicies.begin(),
00049             itEnd = iIndicies.end();
00050             itIndex != itEnd;
00051             ++itIndex) {
00052           iter it = coll.begin();
00053           std::advance(it,*itIndex);          
00054           element_type const* address = GetProduct<product_type>::address( it );
00055           oPtr.push_back(address);
00056         }
00057       } else {
00058         using Reflex::Type;
00059         using Reflex::Object;
00060         static const Type s_type(Type::ByTypeInfo(typeid(element_type)));
00061         Type toType=Type::ByTypeInfo(iToType);
00062         
00063         for(std::vector<unsigned long>::const_iterator itIndex=iIndicies.begin(),
00064             itEnd = iIndicies.end();
00065             itIndex != itEnd;
00066             ++itIndex) {
00067           iter it = coll.begin();
00068           std::advance(it,*itIndex);          
00069           element_type const* address = GetProduct<product_type>::address( it );
00070           // The const_cast below is needed because
00071           // Object's constructor requires a pointer to
00072           // non-const void, although the implementation does not, of
00073           // course, modify the object to which the pointer points.
00074           Object obj(s_type, const_cast<void*>(static_cast<const void*>(address)));
00075           Object cast = obj.CastObject(toType);
00076           if(0 != cast.Address()) {
00077             oPtr.push_back(cast.Address());// returns void*, after pointer adjustment
00078           } else {
00079             Exception::throwThis(errors::LogicError,
00080             "TypeConversionError "
00081             "edm::PtrVector<> : unable to convert type ",
00082             typeid(element_type).name(),
00083             " to ",
00084             iToType.name(),
00085             "\n");
00086           }
00087           
00088         }
00089       }
00090     }
00091   }
00092   
00093   template <class T, class A>
00094   void
00095   fillPtrVector(std::vector<T,A> const& obj,
00096                 const std::type_info& iToType,
00097                 const std::vector<unsigned long>& iIndicies,
00098                 std::vector<void const*>& oPtr) {
00099     detail::reallyfillPtrVector(obj, iToType, iIndicies, oPtr);
00100   }
00101   
00102   template <class T, class A>
00103   void
00104   fillPtrVector(std::list<T,A> const& obj,
00105                 const std::type_info& iToType,
00106                 const std::vector<unsigned long>& iIndicies,
00107                 std::vector<void const*>& oPtr) {
00108     detail::reallyfillPtrVector(obj, iToType, iIndicies, oPtr);
00109   }
00110   
00111   template <class T, class A>
00112   void
00113   fillPtrVector(std::deque<T,A> const& obj,
00114                 const std::type_info& iToType,
00115                 const std::vector<unsigned long>& iIndicies,
00116                 std::vector<void const*>& oPtr) {
00117     detail::reallyfillPtrVector(obj, iToType, iIndicies, oPtr);
00118   }
00119   
00120   template <class T, class A, class Comp>
00121   void
00122   fillPtrVector(std::set<T,A,Comp> const& obj,
00123                 const std::type_info& iToType,
00124                 const std::vector<unsigned long>& iIndicies,
00125                 std::vector<void const*>& oPtr) {
00126     detail::reallyfillPtrVector(obj, iToType, iIndicies, oPtr);
00127   }
00128 
00129 }
00130 
00131 #endif