CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/DataFormats/Common/interface/Ref.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_Ref_h
00002 #define DataFormats_Common_Ref_h
00003 
00004 /*----------------------------------------------------------------------
00005   
00006 Ref: A template for a interproduct reference to a member of a product_.
00007 
00008 ----------------------------------------------------------------------*/
00074 /*----------------------------------------------------------------------
00075 //  This defines the public interface to the class Ref<C, T, F>.
00076 //  C                         is the collection type.
00077 //  T (default C::value_type) is the type of an element in the collection.
00078 //
00079 //  ProductID productID       is the product ID of the collection.
00080 //  key_type itemKey          is the key of the element in the collection.
00081 //  C::value_type *itemPtr    is a C++ pointer to the element 
00082 //  Ref<C, T, F> const& ref   is another Ref<C, T, F>
00083 
00084 //  Constructors
00085     Ref(); // Default constructor
00086     Ref(Ref<C, T> const& ref);  // Copy constructor  (default, not explicitly specified)
00087 
00088     Ref(Handle<C> const& handle, key_type itemKey);
00089     Ref(ProductID pid, key_type itemKey, EDProductGetter const* prodGetter);
00090 
00091 //  Destructor
00092     virtual ~Ref() {}
00093 
00094     // Operators and methods
00095     Ref<C, T>& operator=(Ref<C, T> const&);             // assignment (default, not explicitly specified)
00096     T const& operator*() const;                 // dereference
00097     T const* const operator->() const;          // member dereference
00098     bool operator==(Ref<C, T> const& ref) const; // equality
00099     bool operator!=(Ref<C, T> const& ref) const; // inequality
00100     bool operator<(Ref<C, T> const& ref) const; // ordering
00101     bool isNonnull() const;                     // true if an object is referenced
00102     bool isNull() const;                        // equivalent to !isNonnull()
00103     bool operator!() const;                     // equivalent to !isNonnull()
00104     ----------------------------------------------------------------------*/ 
00105 
00106 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00107 #include "DataFormats/Common/interface/ConstPtrCache.h"
00108 #include "DataFormats/Common/interface/EDProductfwd.h"
00109 #include "DataFormats/Common/interface/EDProductGetter.h"
00110 #include "DataFormats/Common/interface/Handle.h"
00111 #include "DataFormats/Common/interface/OrphanHandle.h"
00112 #include "DataFormats/Common/interface/RefCore.h"
00113 #include "DataFormats/Common/interface/RefCoreWithIndex.h"
00114 #include "DataFormats/Common/interface/TestHandle.h"
00115 #include "DataFormats/Common/interface/traits.h"
00116 #include "DataFormats/Provenance/interface/ProductID.h"
00117 
00118 #include "boost/functional.hpp"
00119 #include "boost/call_traits.hpp"
00120 #include "boost/type_traits.hpp"
00121 #include "boost/mpl/has_xxx.hpp"
00122 #include "boost/utility/enable_if.hpp"
00123 
00124 BOOST_MPL_HAS_XXX_TRAIT_DEF(key_compare)
00125 
00126   template <typename C, typename K>
00127   typename boost::enable_if<has_key_compare<C>, bool>::type
00128   compare_key(K const& lhs, K const& rhs) {
00129     typedef typename C::key_compare comparison_functor;
00130     return comparison_functor()(lhs, rhs);
00131   }
00132 
00133   template <typename C, typename K>
00134   typename boost::disable_if<has_key_compare<C>, bool>::type
00135   compare_key(K const& lhs, K const& rhs) {
00136     return lhs < rhs;
00137   }
00138 
00139 #include "DataFormats/Common/interface/RefTraits.h"
00140 
00141 namespace edm {
00142   template<typename C, typename T, typename F>
00143   class RefVector;
00144 
00145   template<typename T>
00146   class RefToBaseVector;
00147 
00148   template <typename C, 
00149             typename T = typename refhelper::ValueTrait<C>::value, 
00150             typename F = typename refhelper::FindTrait<C, T>::value>
00151   class Ref {
00152   private:
00153     typedef refhelper::FindRefVectorUsingAdvance<RefVector<C, T, F> > VF;
00154     typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T> > VBF;
00155     friend class RefVectorIterator<C, T, F>;
00156     friend class RefVector<C, T, F>;
00157     friend class RefVector<RefVector<C, T, F>, T, VF>;
00158     friend class RefVector<RefVector<RefVector<C, T, F>, T, VF>, T, VF>;
00159     friend class RefVector<RefVector<C, T, F>, T, VBF>;
00160     friend class RefVector<RefVector<RefVector<C, T, F>, T, VBF>, T, VBF>;
00162 
00163   public:
00165     typedef C product_type;
00166     typedef T value_type; 
00167     typedef T const element_type; //used for generic programming
00168     typedef F finder_type;
00169     typedef typename boost::binary_traits<F>::second_argument_type argument_type;
00170     typedef typename boost::remove_cv<typename boost::remove_reference<argument_type>::type>::type key_type;   
00173 
00175     Ref() : product_(), index_(key_traits<key_type>::value) {}
00176 
00178     Ref(Handle<C> const& handle, key_type itemKey, bool setNow=true);
00179 
00181     Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow=true);
00182 
00184     //  Note. refvector[index] returns a Ref where index is the index into
00185     //  the RefVector. This index argument is the index into the COLLECTION,
00186     //  not the index into the RefVector.
00187     Ref(RefVector<C, T, F> const& refvector, key_type itemKey, bool setNow=true);
00188 
00190     //  An exception will be thrown if an attempt is made to persistify
00191     //  any object containing this Ref.  Also, in the future work will
00192     //  be done to throw an exception if an attempt is made to put any object
00193     //  containing this Ref into an event(or run or lumi).
00194     Ref(C const* product, key_type itemKey, bool setNow=true);
00195 
00197     //  An exception will be thrown if an attempt is made to persistify
00198     //  any object containing this Ref.  Also, in the future work will
00199     Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow=true);
00200 
00204     Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
00205       product_(productID, 0, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {
00206     }
00207 
00209     //  It is an error (not diagnosable at compile- or run-time) to call
00210     //  this constructor with a pointer to a T unless the pointed-to T
00211     //  object is already in a collection of type C stored in the
00212     //  Event. The given ProductID must be the id of the collection in
00213     //  the Event.
00214     
00215     Ref(ProductID const& iProductID, T const* /*item*/, key_type iItemKey, C const* iProduct) :
00216       product_(iProductID, iProduct, 0, false), index_(iItemKey)
00217     { }
00218 
00222 
00223     explicit Ref(ProductID const& iId) :
00224       product_(iId, 0, 0, false), index_(key_traits<key_type>::value)
00225     { }
00226 
00228     Ref(RefProd<C> const& refProd, key_type itemKey);
00229 
00231     ~Ref() {}
00232 
00234     T const&
00235     operator*() const;
00236 
00238     T const*
00239     operator->() const;
00240 
00242     T const* get() const {
00243       return isNull() ? 0 : this->operator->();
00244     }
00245 
00247     bool isNull() const {return !isNonnull(); }
00248 
00250     bool isNonnull() const { return index_!=edm::key_traits<key_type>::value; }
00251 
00253     bool operator!() const {return isNull();}
00254 
00256     ProductID id() const {return product_.id();}
00257 
00259     EDProductGetter const* productGetter() const {return product_.productGetter();}
00260 
00262     // Accessor must get the product if necessary
00263     C const* product() const;
00264 
00266     key_type key() const {return index_;}
00267 
00268     // This one just for backward compatibility.  Will be removed soon.
00269     key_type index() const {return index_;}
00270 
00272     bool hasProductCache() const {return product_.productPtr() != 0;}
00273 
00276     bool isAvailable() const {return product_.isAvailable();}
00277 
00279     bool isTransient() const {return product_.isTransient();}
00280 
00281     RefCore const& refCore() const {return product_;}
00282     
00283     //Used by ROOT storage
00284     CMS_CLASS_VERSION(10)
00285     //  private:
00286     // Constructor from member of RefVector
00287     Ref(RefCore const& iRefCore, key_type const& iKey) : 
00288       product_(iRefCore), index_(iKey) {
00289     }
00290 
00291   private:
00292     // Compile time check that the argument is a C* or C const*
00293     // or derived from it.
00294     void checkTypeAtCompileTime(C const*) {}
00295 
00296     mutable RefCore product_;
00297     key_type index_;
00298 
00299   };
00300 
00301   //***************************
00302   //Specialization for a vector
00303   //***************************
00304 #define REF_FOR_VECTOR_ARGS std::vector<E>,typename refhelper::ValueTrait<std::vector<E> >::value,typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E> >::value>::value
00305 
00306   template <typename E>
00307   class Ref<REF_FOR_VECTOR_ARGS> {
00308   private:
00309     typedef typename refhelper::ValueTrait<std::vector<E> >::value T;
00310     typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E> >::value>::value F;
00311     typedef refhelper::FindRefVectorUsingAdvance<RefVector<std::vector<E>, T, F> > VF;
00312     typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T> > VBF;
00313     friend class RefVectorIterator<std::vector<E>, T, F>;
00314     friend class RefVector<std::vector<E>, T, F>;
00315     friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
00316     friend class RefVector<RefVector<RefVector<std::vector<E>, T, F>, T, VF>, T, VF>;
00317     friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
00318     friend class RefVector<RefVector<RefVector<std::vector<E>, T, F>, T, VBF>, T, VBF>;
00320     
00321   public:
00323     typedef std::vector<E> product_type;
00324     typedef typename refhelper::ValueTrait<std::vector<E> >::value value_type; 
00325     typedef value_type const element_type; //used for generic programming
00326     typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E> >::value>::value finder_type;
00327     typedef typename boost::binary_traits<F>::second_argument_type argument_type;
00328     typedef unsigned int key_type;   
00331     
00333     Ref() : product_() {}
00334     
00336     Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow=true);
00337     
00339     Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow=true);
00340     
00342     //  Note. refvector[index] returns a Ref where index is the index into
00343     //  the RefVector. This index argument is the index into the COLLECTION,
00344     //  not the index into the RefVector.
00345     Ref(RefVector<product_type, T, F> const& refvector, key_type itemKey, bool setNow=true);
00346     
00348     //  An exception will be thrown if an attempt is made to persistify
00349     //  any object containing this Ref.  Also, in the future work will
00350     //  be done to throw an exception if an attempt is made to put any object
00351     //  containing this Ref into an event(or run or lumi).
00352     Ref(product_type const* product, key_type itemKey, bool setNow=true);
00353     
00355     //  An exception will be thrown if an attempt is made to persistify
00356     //  any object containing this Ref.  Also, in the future work will
00357     Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow=true);
00358     
00362     Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
00363     product_(productID, 0, mustBeNonZero(prodGetter, "Ref", productID), false,itemKey) {
00364     }
00365     
00367     //  It is an error (not diagnosable at compile- or run-time) to call
00368     //  this constructor with a pointer to a T unless the pointed-to T
00369     //  object is already in a collection of type C stored in the
00370     //  Event. The given ProductID must be the id of the collection in
00371     //  the Event.
00372     
00373     Ref(ProductID const& iProductID, T const* /*item*/, key_type iItemKey, product_type const* iProduct) :
00374     product_(iProductID, iProduct, 0, false,iItemKey)
00375     { }
00376     
00380     
00381     explicit Ref(ProductID const& iId) :
00382     product_(iId, 0, 0, false,key_traits<key_type>::value)
00383     { }
00384     
00386     Ref(RefProd<product_type> const& refProd, key_type itemKey);
00387     
00389     ~Ref() {}
00390     
00392     T const&
00393     operator*() const;
00394     
00396     T const*
00397     operator->() const;
00398     
00400     T const* get() const {
00401       return isNull() ? 0 : this->operator->();
00402     }
00403     
00405     bool isNull() const {return !isNonnull(); }
00406     
00408     bool isNonnull() const { return key()!=edm::key_traits<key_type>::value; }
00409     
00411     bool operator!() const {return isNull();}
00412     
00414     ProductID id() const {return product_.id();}
00415     
00417     EDProductGetter const* productGetter() const {return product_.productGetter();}
00418     
00420     // Accessor must get the product if necessary
00421     product_type const* product() const;
00422     
00424     key_type key() const {return product_.index();}
00425     
00426     // This one just for backward compatibility.  Will be removed soon.
00427     key_type index() const {return product_.index();}
00428     
00430     bool hasProductCache() const {return product_.productPtr() != 0;}
00431     
00434     bool isAvailable() const {return product_.isAvailable();}
00435     
00437     bool isTransient() const {return product_.isTransient();}
00438     
00439     RefCore const& refCore() const {return product_.toRefCore();}
00440     
00441     //Used by ROOT storage
00442     CMS_CLASS_VERSION(11)
00443     //  private:
00444     // Constructor from member of RefVector
00445     Ref(RefCore const& iRefCore, key_type const& iKey) : 
00446     product_(iRefCore,iKey) {
00447     }
00448     
00449   private:
00450     // Compile time check that the argument is a C* or C const*
00451     // or derived from it.
00452     void checkTypeAtCompileTime(product_type const*) {}
00453     
00454     mutable RefCoreWithIndex product_;
00455     
00456   };
00457 
00458 }
00459 
00460 #include "DataFormats/Common/interface/RefProd.h"
00461 #include "DataFormats/Common/interface/RefCoreGet.h"
00462 #include "DataFormats/Common/interface/RefItemGet.h"
00463 
00464 namespace edm {
00466   template <typename C, typename T, typename F>
00467   inline
00468   Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool setNow) :
00469       product_(handle.id(), handle.product(), 0, false), index_(itemKey){
00470     checkTypeAtCompileTime(handle.product());
00471     assert(key() == itemKey);
00472         
00473     if (setNow) {getPtr_<C, T, F>(product_, index_);}
00474   }
00475 
00477   template <typename E>
00478   inline
00479   Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E> > const& handle, key_type itemKey, bool setNow) :
00480   product_(handle.id(), handle.product(), 0, false,itemKey){
00481     checkTypeAtCompileTime(handle.product());
00482     assert(key() == itemKey);
00483     
00484     if (setNow) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), index());}
00485   }
00486 
00488   template <typename C, typename T, typename F>
00489   inline
00490   Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow) :
00491   product_(handle.id(), handle.product(), 0, false), index_(itemKey) {
00492     checkTypeAtCompileTime(handle.product());
00493     assert(key() == itemKey);
00494         
00495     if (setNow) {getPtr_<C, T, F>(product_, index_);}
00496   }
00497 
00499   template <typename E>
00500   inline
00501   Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E> > const& handle, key_type itemKey, bool setNow) :
00502   product_(handle.id(), handle.product(), 0, false,itemKey) {
00503     checkTypeAtCompileTime(handle.product());
00504     assert(key() == itemKey);
00505     
00506     if (setNow) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());}
00507   }
00508   
00510   template <typename C, typename T, typename F>
00511   inline
00512   Ref<C, T, F>::Ref(RefVector<C, T, F> const& refvector, key_type itemKey, bool setNow) :
00513       product_(refvector.id(), refvector.product(), 0, refvector.isTransient()), index_(itemKey) {
00514     checkTypeAtCompileTime(refvector.product());
00515     assert(key() == itemKey);
00516         
00517     if (setNow) {getPtr_<C, T, F>(product_, index_);}
00518   }
00519 
00521   template <typename E>
00522   inline
00523   Ref<REF_FOR_VECTOR_ARGS>::Ref(RefVector<REF_FOR_VECTOR_ARGS> const& refvector, key_type itemKey, bool setNow) :
00524   product_(refvector.id(), refvector.product(), 0, refvector.isTransient(),itemKey) {
00525     checkTypeAtCompileTime(refvector.product());
00526     assert(key() == itemKey);
00527     
00528     if (setNow) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());}
00529   }
00530   
00532   //  An exception will be thrown if an attempt is made to persistify
00533   //  any object containing this Ref.  Also, in the future work will
00534   //  be done to throw an exception if an attempt is made to put any object
00535   //  containing this Ref into an event(or run or lumi).
00536   //  Note:  It is legal for the referenced object to be put into the event
00537   //  and persistified.  It is this Ref itself that cannot be persistified.
00538   template <typename C, typename T, typename F>
00539   inline
00540   Ref<C, T, F>::Ref(C const* iProduct, key_type iItemKey, bool iSetNow) :
00541     product_(ProductID(), iProduct, 0, true), index_(iProduct != 0 ? iItemKey : key_traits<key_type>::value) {
00542     checkTypeAtCompileTime(iProduct);
00543     assert(key() == (iProduct != 0 ? iItemKey : key_traits<key_type>::value));
00544         
00545     if (iSetNow && iProduct != 0) {getPtr_<C, T, F>(product_, index_);}
00546   }
00547 
00548   template <typename E>
00549   inline
00550   Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type iItemKey, bool iSetNow) :
00551   product_(ProductID(), iProduct, 0, true,(iProduct != 0 ? iItemKey : key_traits<key_type>::value)) {
00552     checkTypeAtCompileTime(iProduct);
00553     assert(key() == (iProduct != 0 ? iItemKey : key_traits<key_type>::value));
00554     
00555     if (iSetNow && iProduct != 0) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());}
00556   }
00557 
00559   //  An exception will be thrown if an attempt is made to persistify any object containing this Ref.
00560   template <typename C, typename T, typename F>
00561   inline
00562   Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow) :
00563       product_(handle.id(), handle.product(), 0, true), index_(itemKey) {
00564     checkTypeAtCompileTime(handle.product());
00565     assert(key() == itemKey);
00566         
00567     if (setNow) {getPtr_<C, T, F>(product_, index_);}
00568   }
00569 
00570   template <typename E>
00571   inline
00572   Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E> > const& handle, key_type itemKey, bool setNow) :
00573   product_(handle.id(), handle.product(), 0, true,itemKey) {
00574     checkTypeAtCompileTime(handle.product());
00575     assert(key() == itemKey);
00576     
00577     if (setNow) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());}
00578   }
00579 
00581   template <typename C, typename T, typename F>
00582   inline
00583   Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey) :
00584       product_(refProd.id(), refProd.refCore().productPtr(), refProd.refCore().productGetter(), refProd.refCore().isTransient()), index_(itemKey) {
00585     assert(index() == itemKey);
00586   }
00587 
00588   template <typename E>
00589   inline
00590   Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E> > const& refProd, key_type itemKey) :
00591   product_(refProd.id(), refProd.refCore().productPtr(), refProd.refCore().productGetter(), refProd.refCore().isTransient(),itemKey) {
00592     assert(index() == itemKey);
00593   }
00594   
00595   
00597   // Accessor must get the product if necessary
00598   template <typename C, typename T, typename F>
00599   inline
00600   C const*
00601   Ref<C, T, F>::product() const {
00602       return isNull() ? 0 : edm::template getProduct<C>(product_);
00603   }
00604   template <typename E>
00605   inline
00606   std::vector<E> const*
00607   Ref<REF_FOR_VECTOR_ARGS>::product() const {
00608     return isNull() ? 0 : edm::template getProduct<std::vector<E> >(product_.toRefCore());
00609   }
00610 
00612   template <typename C, typename T, typename F>
00613   inline
00614   T const&
00615   Ref<C, T, F>::operator*() const {
00616     return *getPtr<C, T, F>(product_, index_);
00617   }
00618   template <typename E>
00619   inline
00620   typename refhelper::ValueTrait<std::vector<E> >::value const&
00621   Ref<REF_FOR_VECTOR_ARGS>::operator*() const {
00622     return *getPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
00623   }
00624 
00626   template <typename C, typename T, typename F>
00627   inline
00628   T const*
00629   Ref<C, T, F>::operator->() const {
00630     return getPtr<C, T, F>(product_, index_);
00631   }
00632   template <typename E>
00633   inline
00634   typename refhelper::ValueTrait<std::vector<E> >::value const*
00635   Ref<REF_FOR_VECTOR_ARGS>::operator->() const {
00636     return getPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
00637   }
00638 
00639   template <typename C, typename T, typename F>
00640   inline
00641   bool
00642   operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00643     return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore() ;
00644   }
00645 
00646   template <typename C, typename T, typename F>
00647   inline
00648   bool
00649   operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00650     return !(lhs == rhs);
00651   }
00652 
00653   template <typename C, typename T, typename F>
00654   inline
00655   bool
00656   operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00659       return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
00660   }
00661 
00662 }
00663 
00664 #include "DataFormats/Common/interface/HolderToVectorTrait.h"
00665 #include "DataFormats/Common/interface/Holder.h"
00666 #include "DataFormats/Common/interface/VectorHolder.h"
00667 #include "DataFormats/Common/interface/RefVector.h"
00668 
00669 namespace edm {
00670   namespace reftobase {
00671 
00672     template <typename T, typename REF>
00673     struct RefHolderToVector {
00674       static  std::auto_ptr<BaseVectorHolder<T> > makeVectorHolder() {
00675         typedef RefVector<typename REF::product_type,
00676                           typename REF::value_type, 
00677                           typename REF::finder_type> REFV;
00678         return std::auto_ptr<BaseVectorHolder<T> >(new VectorHolder<T, REFV>);
00679       }
00680       static  std::auto_ptr<RefVectorHolderBase> makeVectorBaseHolder() {
00681         typedef RefVector<typename REF::product_type,
00682                           typename REF::value_type, 
00683                           typename REF::finder_type> REFV;
00684         return std::auto_ptr<RefVectorHolderBase>(new RefVectorHolder<REFV>);
00685       }
00686     };
00687 
00688     template<typename T1, typename C, typename T, typename F>
00689     struct HolderToVectorTrait<T1, Ref<C, T, F> > {
00690       typedef RefHolderToVector<T1, Ref<C, T, F> > type;
00691     };
00692 
00693     template <typename REF>
00694     struct RefRefHolderToRefVector {
00695       static std::auto_ptr<RefVectorHolderBase> makeVectorHolder() {
00696         typedef RefVector<typename REF::product_type,
00697                           typename REF::value_type, 
00698                                 typename REF::finder_type> REFV;
00699         return std::auto_ptr<RefVectorHolderBase>(new RefVectorHolder<REFV>);
00700       }
00701     };
00702 
00703     template<typename C, typename T, typename F>
00704     struct RefHolderToRefVectorTrait<Ref<C, T, F> > {
00705       typedef RefRefHolderToRefVector<Ref<C, T, F> > type;
00706     };
00707 
00708   }
00709 }
00710   
00711 #endif