CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_4/src/DataFormats/Common/interface/setPtr.h

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