Commits

Sebastien Binet  committed a5e55fc Merge

sync w/ atlasoff

  • Participants
  • Parent commits 406206d, 68beaf7
  • Branches waffle-repo, mob

Comments (0)

Files changed (19)

 117a4e11368d3aa8ea56c25036d50aa672129e6b StoreGate-02-37-02
 2549af6e39c21a2ec0adc9f178909c27777bc82e StoreGate-02-37-03
 7fd85fd80a29d07f8caad1ebbc60a7b65e4d60ee StoreGate-02-37-04
+73a80a3592b1e9d7645b0e22ccb4e53119134765 StoreGate-02-37-05
+b44f73f62c90f520d768d7aed0819373d6f3bd98 StoreGate-02-38-00
+3c06a40efc49cb3367148f0ed391dbf008b7a85d StoreGate-02-38-01
+a87d9c6e4c760855b28c2cfc25d7fdb3024c1fa0 StoreGate-02-38-02
+2499754995e3fd1da4f4786be07ff97c363ee75c StoreGate-02-38-03
+2012-03-12  scott snyder  <snyder@bnl.gov>
+
+	* Tagging StoreGate-02-38-03.
+	* StoreGate/SGIterator.h: Implement missing methods.
+
+2012-03-02  Sebastien Binet  <sebastien.binet@cern.ch>
+
+	* Tagging StoreGate-02-38-02
+	* remove VarHandle
+	* add RVar, WVar and RWVar handles
+	* add property support for var handles
+	* A StoreGate/RVar.h
+	* A StoreGate/RVar.icc
+	* A StoreGate/RWVar.h
+	* A StoreGate/RWVar.icc
+	* A StoreGate/VarHandleProperty.h
+	* A StoreGate/WVar.h
+	* A StoreGate/WVar.icc
+	* A src/VarHandleProperty.cxx
+	* D StoreGate/VarHandle.h
+	* D StoreGate/VarHandle.icc
+	* M StoreGate/VarHandleBase.h
+	* M src/VarHandleBase.cxx
+
+2011-11-29  scott snyder  <snyder@bnl.gov>
+
+	* Tagging StoreGate-02-38-01.
+	* test/SGtests.cxx (Athena_test): Fix regression test.
+
+2011-11-28  Sebastien Binet  <sebastien.binet@cern.ch>
+
+	* tagging StoreGate-02-38-00
+	* fixing coverity defect 16556 (disambiguate proxy api)
+	* split-up DataHandle into DataHandle and DataHandleBase (reduce
+	  template bloat)
+	* introduce VarHandle and VarHandleBase
+	* A StoreGate/VarHandleBase.h
+	* A StoreGate/VarHandle.h
+	* A StoreGate/VarHandle.icc
+	* A src/VarHandleBase.cxx
+	* M test/DataHandle_test.cxx
+	* M test/SGtests.cxx
+	* M StoreGate/DataHandle.icc
+	* M StoreGate/StoreGateSvc.h
+	* M StoreGate/StoreGateSvc.icc
+	* M StoreGate/DataHandle.h
+
 2011-09-23  scott snyder  <snyder@bnl.gov>
 
 	* tagging StoreGate-02-37-05

File StoreGate/DataHandle.h

 # include "AthenaKernel/IResetable.h"
 #endif
 
+#ifndef ATHENAKERNEL_IPROXYDICT_H
+# include "AthenaKernel/IProxyDict.h"
+#endif
+
 #ifndef SGTOOLS_DATAPROXY_H
 # include "SGTools/DataProxy.h"
 #endif
 
+#ifndef SGTOOLS_DATAHANDLEBASE_H
+# include "SGTools/DataHandleBase.h"
+#endif
+
 #ifndef _CPP_CSTDDEF
  #include <cstddef>  /*ptrdiff_t*/
 #endif
 
 template <class DATA>
 bool operator== (const DataHandle<DATA>& h1,
-		 const DataHandle<DATA>& h2);
+                 const DataHandle<DATA>& h2);
 
 template <class DATA>
 bool operator!= (const DataHandle<DATA>& h1,
-		 const DataHandle<DATA>& h2);
+                 const DataHandle<DATA>& h2);
 
 /** @class DataHandle
  * @brief an iterator over instances of a given type in StoreGateSvc. It d-casts
  **/
 template <typename DATA> 
 class DataHandle :
-  public IResetable,
+  public DataHandleBase,
   public std::iterator<std::forward_iterator_tag, DATA> 
 {
 public:
   typedef typename base_t::reference reference_type;
   typedef const DATA& const_reference_type; 
 
-  typedef std::string ID_type;
+  typedef DataHandleBase::ID_type ID_type;
 
   /// \name structors and assignment
   //@{
   DataHandle();
   DataHandle(const DataHandle& h);
   DataHandle& operator= (const DataHandle& h);
+  DataHandle& operator= (const DATA& d) 
+  { 
+    typename DataHandle<DATA>::pointer_type ptr = this->ptr();
+    if (ptr) {
+      *ptr = d; 
+    } else {
+      std::cerr << "invalid proxy\n";
+    }
+    return *this; 
+  }
 
   virtual ~DataHandle();  ///< unbind from the proxy before we go
    //@}
 
+  /// \name validity checks
+  //@{
+  bool isValid() const; ///<RETRIEVES the DO to check it is valid and unlocked
+  bool isValid();       ///<RETRIEVES the DO to check it is valid
+
+  // FIXME op! is to keep backward compatibility with Gaudi
+  // FIXME similar to checking the SmartDataPtr
+  // FIXME dangerous stuff: remove!
+  ///DEPRECATED for statements like:  if (!DataHandle<XXX>) {...} 
+  bool operator !() const { return !isValid(); }
+
+  //FIXME VERY dangerous stuff: remove!
+  ///DEPRECATED for statements like:  if (DataHandle<XXX>) {...} 
+  operator int() const  { return isValid(); }
+  //@}
+
   /// \name iterator interface
   //@{
   const DataHandle& operator++ () const;        ///<prefix
   reference_type operator*()                { return *ptr();  }
   //@}
 
-  /// \name validity checks
-  //@{
-  bool isConst() const;
-
-  bool isValid() const; ///<RETRIEVES the DO to check it is valid and unlocked
-  bool isValid();       ///<RETRIEVES the DO to check it is valid
-  bool isInitialized() const;    ///<weaker test but it does not touch the disk!
-  bool isSet() const { return isInitialized(); }
-
-  // FIXME op! is to keep backward compatibility with Gaudi
-  // FIXME similar to checking the SmartDataPtr
-  // FIXME dangerous stuff: remove!
-  ///DEPRECATED for statements like:  if (!DataHandle<XXX>) {...} 
-  bool operator !() const { return !isValid(); }
-
-  //FIXME VERY dangerous stuff: remove!
-  ///DEPRECATED for statements like:  if (DataHandle<XXX>) {...} 
-  operator int() const  { return isValid(); }
-  //@}
-
   /// \name access to the underlying ptr
   //@{
   operator pointer_type()             { return ptr(); }  ///< often ambiguos
   const_pointer_type cptr() const;   ///< safer explicit ptr accessor 
   pointer_type ptr();                ///< safer explicit ptr accessor 
 
-  /// Get the key string with which the current object was stored.
-  const std::string& key() const;
-
   void reset() { m_ptr = 0; }        ///< reset pointer
   //@}
 
   DataHandle(SG::DataProxy* proxy); ///< 
   DataHandle(const SG::ConstProxyIterator& itr1,
              const SG::ConstProxyIterator& itr2);
-  StatusCode setState(StoreGateSvc*, SG::DataProxy* proxy);
-  StatusCode setState(StoreGateSvc*, SG::DataProxy* proxy) const;
 
-  // Note: itr1 may be modified!
-  StatusCode setState(StoreGateSvc*, SG::ConstProxyIterator& itr1,
-		      const SG::ConstProxyIterator& itr2) const;
   //@}
 
-  ///get the data object key (ID)
-  ID_type ID() const { return isInitialized() ? m_proxy->name() : "NONE"; }
+  /// the CLID of the object we are bound to
+  virtual CLID clid() const { return ClassID_traits<DATA>::ID(); }
 
   friend
   bool operator==<>(const DataHandle<DATA>& h1,
-		    const DataHandle<DATA>& h2); 
+                    const DataHandle<DATA>& h2); 
   friend
   bool operator!=<>(const DataHandle<DATA>& h1,
-		    const DataHandle<DATA>& h2); 
+                    const DataHandle<DATA>& h2); 
 private:
 
-  mutable SG::ConstProxyIterator m_itr, m_itrEnd;
   mutable pointer_type m_ptr;
-  mutable SG::DataProxy* m_proxy;
-  mutable bool m_useItr;
-
   pointer_type dataPointer() const;
 
 

File StoreGate/DataHandle.icc

   
 template <class DATA> 
 DataHandle<DATA>::DataHandle() : 
-  IResetable(),
-  m_itr(), m_itrEnd(), m_ptr(0), m_proxy(0), m_useItr(false)
+  DataHandleBase(),
+  m_ptr(0)
 { }
 
 //....................................................................
   
 template <class DATA> 
 DataHandle<DATA>::DataHandle(const DataHandle& h):
-  IResetable(),
-  m_itr(h.m_itr), m_itrEnd(h.m_itrEnd), m_ptr(h.m_ptr), 
-  m_proxy(h.m_proxy), m_useItr(h.m_useItr)
-
-{
-  if (m_proxy) m_proxy->addRef();
-}
+  DataHandleBase(h),
+  m_ptr(h.m_ptr)
+{}
 
 //....................................................................
 
 template <class DATA>
-DataHandle<DATA>& DataHandle<DATA>::DataHandle::operator= (const DataHandle& h)
+DataHandle<DATA>& 
+DataHandle<DATA>::DataHandle::operator= (const DataHandle& h)
 {
-  if (m_proxy) m_proxy->release();
-
-  m_itr = h.m_itr;
-  m_ptr = h.m_ptr;
-  m_itrEnd = h.m_itrEnd;
-  m_useItr = h.m_useItr;
-  m_proxy = h.m_proxy;
-
-  if (m_proxy) m_proxy->addRef();
-
+  if (this != &h) {
+    this->DataHandleBase::operator=(h);
+    m_ptr = h.m_ptr;
+  }
   return *this;
 }
 
   
 template <class DATA> 
 DataHandle<DATA>::DataHandle(SG::DataProxy* proxy) : 
-  IResetable(),
-  m_itr(), m_itrEnd(), m_ptr(0), m_proxy(proxy), m_useItr(false)
-{
-  if (m_proxy) m_proxy->addRef();
-}
-
+  DataHandleBase(proxy),
+  m_ptr(0)
+{}
 
 //....................................................................
 
 template <class DATA> 
 DataHandle<DATA>::DataHandle(const SG::ConstProxyIterator &itr, 
-			     const SG::ConstProxyIterator &itrEnd) : 
-  IResetable(),
-  m_itr(itr), m_itrEnd(itrEnd),
-  m_ptr(0), m_proxy(0), m_useItr(true)
-{
-  if (m_itr != m_itrEnd) m_proxy = m_itr->second;
-  if (m_proxy) m_proxy->addRef();
-}
+                             const SG::ConstProxyIterator &itrEnd) : 
+  DataHandleBase(itr, itrEnd),
+  m_ptr(0)
+{}
 
 
 // DESTRUCTOR
 template <class DATA> 
 DataHandle<DATA>::~DataHandle()
 { 
-  if (m_proxy != 0) {
-    m_proxy->unbindHandle(this);
-    m_proxy->release();
-  }
 } 
 
 
 ///////////////////////////////////////////////////////////////////////////////
 
 template <class DATA> 
-const DataHandle<DATA>& DataHandle<DATA>::operator++() const //prefix
+const DataHandle<DATA>& 
+DataHandle<DATA>::operator++() const //prefix
 {	
   if (m_proxy) m_proxy->release();
   m_proxy = 0;
 
 ///////////////////////////////////////////////////////////////////////////////
 template <class DATA> 
-DataHandle<DATA> DataHandle<DATA>::operator++ (int) const //postfix
+DataHandle<DATA> 
+DataHandle<DATA>::operator++ (int) const //postfix
 {	
   DataHandle<DATA> ret(*this);
   if (m_proxy) m_proxy->release();
 // ACCESSOR METHODS:
 ///////////////////////////////////////////////////////////////////////////////
 
-template <class DATA>
-StatusCode DataHandle<DATA>::setState(StoreGateSvc* , 
-     SG::ConstProxyIterator &itr, const SG::ConstProxyIterator &itrEnd) const 
-{
-  if (m_proxy) m_proxy->release();
 
-  m_itr = itr;
-  m_itrEnd = itrEnd;
-  m_useItr = true;
-  m_ptr = 0;
-
-// scan from itr to itrEnd and set m_itr to the first valid iterator:
-
-  for (; itr != itrEnd; itr++) {
-    if (itr->second->isValid()) {
-      m_itr = itr;
-      m_proxy = m_itr->second;
-      if (m_proxy) m_proxy->addRef();
-      return StatusCode::SUCCESS;
-    }
-  }
-
-  m_itr = itrEnd;
-  m_proxy = 0;
-  
-  return StatusCode::FAILURE; 
-
-}
-
-//.....................................................................
-
-template <class DATA>
-StatusCode DataHandle<DATA>::setState(StoreGateSvc*, SG::DataProxy* proxy)
-{
-  if (0 == proxy || !proxy->isValid() || proxy->isConst()) return StatusCode::FAILURE;
-
-  if (m_proxy != proxy) {
-    if (m_proxy) m_proxy->release();
-    m_proxy = proxy;
-    m_proxy->addRef();
-  }
-
-  m_useItr = false;
-  m_ptr = 0;
-  return StatusCode::SUCCESS;
-}
-///////////////////////////////////////////////////////////////////////////////
-
-template <class DATA>
-StatusCode DataHandle<DATA>::setState(StoreGateSvc*, SG::DataProxy* proxy) const {
-  if (0 == proxy || !proxy->isValid()) return StatusCode::FAILURE;
-
-  if (m_proxy != proxy) {
-    if (m_proxy) m_proxy->release();
-    m_proxy = proxy;
-    m_proxy->addRef();
-  }
-
-  m_useItr = false;
-  m_ptr = 0;
-  return StatusCode::SUCCESS;
-}
 ///////////////////////////////////////////////////////////////////////////////
 
 template <class DATA> 
   return 0 != p && !isConst() ? p : 0;
 }
 
-//////////////////////////////////////////////////////////////////////////////
- 
-template <class DATA> 
-const std::string& DataHandle<DATA>::key() const
-{
-  if (m_itr == m_itrEnd) {
-    return m_proxy->name();
-  } else {
-    return m_itr->first;
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-template <class DATA>
-bool DataHandle<DATA>::isConst() const
-{
-  return 0 != m_proxy ? m_proxy->isConst() : false;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 // The const version checks if the pointer is a valid pointer. 
 // Retrieves the GaudiObject to check validity if not already done
 
 template <class DATA>
-bool DataHandle<DATA>::isValid() const
+bool
+DataHandle<DATA>::isValid() const
 {
   // dataPointer() prints a warning if the proxy is null,
   // so also test isInitialized().
 // Retrieves the GaudiObject to check validity if not already done
 
 template <class DATA>
-bool DataHandle<DATA>::isValid()
+bool
+DataHandle<DATA>::isValid()
 {
   // ptr() prints a warning if the proxy is null, so also test isInitialized().
   return (isInitialized() && 0 != ptr());
 }
 
 //////////////////////////////////////////////////////////////////////////////
-
-// A weaker test that
-// *does not* retrieve the GaudiObject to check validity if not already done
-
 template <class DATA>
-bool DataHandle<DATA>::isInitialized() const
-{
-  return (0 != m_proxy);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-template <class DATA>
-typename DataHandle<DATA>::pointer_type DataHandle<DATA>::dataPointer() const {
+typename DataHandle<DATA>::pointer_type
+DataHandle<DATA>::dataPointer() const {
   if (0 == m_ptr) {
     m_ptr = SG::DataProxy_cast<DATA>(m_proxy);
   }

File StoreGate/RVar.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// RVar.h 
+// Header file for class SG::RVar<T>
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef STOREGATE_SG_RVAR_H
+#define STOREGATE_SG_RVAR_H 1
+
+// STL includes
+#include <string>
+
+// fwk includes
+#include "GaudiKernel/IInterface.h"
+#include "AthenaKernel/IProxyDict.h"
+#include "AthenaKernel/IResetable.h"
+
+// SGTools includes
+#include "SGTools/ClassID_traits.h"
+
+// StoreGate includes
+#include "StoreGate/VarHandleBase.h"
+
+// Forward declaration
+
+
+namespace SG {
+/**
+ * @class SG::RVar<T>
+ * @brief a smart pointer to an object of a given type in an @c IProxyDict (such
+ * as StoreGateSvc). It d-casts and caches locally the pointed-at object, to 
+ * speed-up subsequent accesses.
+ * It can be reset by the store for asynchronous updates (IOVSvc)
+ *
+ * @c SG::RVar<T> can access const and non-const proxies in StoreGate but
+ * cannot modify them (ie: it is actually a const T*).
+ * A valid proxy must already exist in StoreGate.
+ *
+ * Usage example:
+ * @code
+ *   class MyAlg : public AthAlgorithm
+ *   {
+ *     SG::RVar<int> m_int;
+ *   };
+ *
+ *   MyAlg::MyAlg(...) : ..., m_int("MyIntSgKey") {
+ *      declareProperty("IntHandle",
+ *                      m_int = SG::RVar<int>("MyIntSgKey"),
+ *                      "a handle to an int in StoreGate");
+ *   }
+ *
+ *   StatusCode MyAlg::execute()
+ *   {
+ *     ATH_MSG_INFO("int value @[" << m_int.name() << "]="
+ *                  << *m_int);
+ *     return StatusCode::SUCCESS;
+ *   }
+ * @endcode
+ *
+ * For more informations have a look under the package
+ *     Control/AthenaExamples/AthExHelloWorld
+ *
+ */
+template <class T>
+class RVar : public SG::VarHandleBase
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public typedefs: 
+  /////////////////////////////////////////////////////////////////// 
+public: 
+  typedef T*               pointer_type; // FIXME: better handling of
+  typedef const T*   const_pointer_type; //        qualified T type ?
+  typedef T&             reference_type;
+  typedef const T& const_reference_type;
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+public: 
+
+  /// Default constructor: 
+  RVar();
+
+  /// Copy constructor: 
+  RVar( const RVar& rhs );
+
+  /// Assignment operator: 
+  RVar& operator=( const RVar& rhs ); 
+
+  /// Constructor with parameters: 
+
+  //RVar(SG::DataProxy* proxy); ///< 
+
+  /// retrieve a proxy of name `name` from evtStore (via component `component`)
+  RVar(const IInterface* component,
+       const std::string& name);
+
+  /// retrieve a proxy of name `name` from store `store`
+  RVar(const IInterface* component,
+       const std::string& name, 
+       const std::string& store);
+
+  /// retrieve a proxy of name `name` from evtStore
+  RVar(const std::string& name);
+
+  /// retrieve a proxy of name `name` from store `store`
+  RVar(const std::string& name, 
+       const std::string& store);
+
+  /// retrieve a proxy of name `name` from store `store`
+  //RVar(const std::string& name, IProxyDict* store);
+
+  /// Destructor: 
+  virtual ~RVar(); 
+
+  /// \name access to the underlying ptr
+  //@{
+  const_pointer_type  operator->() const   { return  cptr(); }
+  const_reference_type operator*() const   { return *cptr(); }   
+
+   ///< safer explicit ptr accessor 
+  const_pointer_type cptr() const
+  { return reinterpret_cast<const_pointer_type>(this->typeless_cptr()); }
+
+  ///< safer explicit ptr accessor 
+  const_pointer_type ptr() 
+  { return cptr(); }
+
+  //@}
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /// the CLID of the object we are bound to
+  virtual CLID clid() const { return ClassID_traits<T>::ID(); }
+
+  /// the mode of the underlying handle (reader|writer|updater)
+  virtual Mode mode() const { return SG::VarHandleBase::Reader; }
+
+}; 
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+//std::ostream& operator<<( std::ostream& out, const RVar& o );
+
+
+} /* namespace SG */
+
+#ifndef STOREGATE_SG_RVAR_ICC
+ #include "StoreGate/RVar.icc"
+#endif
+
+#endif //> !STOREGATE_SG_RVAR_H

File StoreGate/RVar.icc

+///////////////////////// -*- C++ -*- /////////////////////////////
+// RVar.icc
+// Implementation file for class SG::RVar<T>
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef STOREGATE_SG_RVAR_ICC
+#define STOREGATE_SG_RVAR_ICC 1
+
+// stl includes
+#include <stdexcept>
+
+// fwk includes
+#include "AthenaKernel/IProxyDict.h"
+#include "AthenaKernel/IResetable.h"
+
+// SGTools includes
+#include "SGTools/ClassID_traits.h"
+#include "SGTools/DataBucketBase.h"
+
+// StoreGate includes
+#include "StoreGate/VarHandleBase.h"
+
+namespace SG {
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+
+/// Default constructor: 
+template <class T> 
+RVar<T>::RVar() : 
+  VarHandleBase()
+{ }
+
+/// Copy constructor: 
+template <class T> 
+RVar<T>::RVar(const RVar& h):
+  VarHandleBase(h)
+{}
+
+/// Assignment operator: 
+template <class T>
+RVar<T>& 
+RVar<T>::RVar::operator= (const RVar& h)
+{
+  if (this != &h) {
+    this->VarHandleBase::operator=(h);
+  }
+  return *this;
+}
+
+/// retrieve a proxy of name `name` from evtStore
+template <class T>
+RVar<T>::RVar(const IInterface* /*iface*/,
+              const std::string& name) :
+  VarHandleBase( name )
+{}
+
+/// retrieve a proxy of name `name` from evtStore
+template <class T>
+RVar<T>::RVar(const IInterface* /*iface*/,
+              const std::string& name,
+              const std::string& store) :
+  VarHandleBase( name, store )
+{}
+
+
+/// retrieve a proxy of name `name` from evtStore
+template <class T>
+RVar<T>::RVar(const std::string& name) :
+  VarHandleBase( name )
+{}
+
+/// retrieve a proxy of name `name` from store `store`
+template <class T>
+RVar<T>::RVar(const std::string& name,
+              const std::string& store) :
+  VarHandleBase( name, store )
+{}
+
+/// Destructor: 
+template <class T> 
+RVar<T>::~RVar()
+{ 
+} 
+
+} /* namespace SG */
+
+#endif //> !STOREGATE_SG_RVAR_ICC

File StoreGate/RWVar.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// RWVar.h 
+// Header file for class SG::RWVar<T>
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef STOREGATE_SG_RWVAR_H
+#define STOREGATE_SG_RWVAR_H 1
+
+// STL includes
+#include <string>
+
+// fwk includes
+#include "GaudiKernel/IInterface.h"
+#include "AthenaKernel/IProxyDict.h"
+#include "AthenaKernel/IResetable.h"
+
+// SGTools includes
+#include "SGTools/ClassID_traits.h"
+
+// StoreGate includes
+#include "StoreGate/VarHandleBase.h"
+
+// Forward declaration
+
+
+namespace SG {
+/**
+ * @class SG::RWVar<T>
+ * @brief a smart pointer to an object of a given type in an @c IProxyDict (such
+ * as StoreGateSvc). It d-casts and caches locally the pointed-at object, to 
+ * speed-up subsequent accesses.
+ * It can be reset by the store for asynchronous updates (IOVSvc)
+ *
+ * @c SG::RWVar<T> can only access non-const proxies in StoreGate, a valid
+ * proxy must already exist in StoreGate.
+ *
+ * Usage example:
+ * @code
+ *   class MyAlg : public AthAlgorithm
+ *   {
+ *     SG::RWVar<int> m_int;
+ *   };
+ *
+ *   MyAlg::MyAlg(...) : ..., m_int("MyIntSgKey") {
+ *      declareProperty("IntHandle",
+ *                      m_int = SG::RWVar<int>("MyIntSgKey"),
+ *                      "a handle to an int in StoreGate");
+ *   }
+ *
+ *   StatusCode MyAlg::execute()
+ *   {
+ *     ATH_MSG_INFO("int value @[" << m_int.name() << "]="
+ *                  << *m_int);
+ *     m_int = 10;
+ *     ATH_MSG_INFO("int value @[" << m_int.name() << "]="
+ *                  << *m_int);
+ *     return StatusCode::SUCCESS;
+ *   }
+ * @endcode
+ *
+ * For more informations have a look under the package
+ *     Control/AthenaExamples/AthExHelloWorld
+ *
+ */
+template <class T>
+class RWVar : public SG::VarHandleBase
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public typedefs: 
+  /////////////////////////////////////////////////////////////////// 
+public: 
+  typedef T*               pointer_type; // FIXME: better handling of
+  typedef const T*   const_pointer_type; //        qualified T type ?
+  typedef T&             reference_type;
+  typedef const T& const_reference_type;
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+public: 
+
+  /// Default constructor: 
+  RWVar();
+
+  /// Copy constructor: 
+  RWVar( const RWVar& rhs );
+
+  /// Assignment operator: 
+  RWVar& operator=( const RWVar& rhs ); 
+  RWVar& operator=( const T& data );
+  //RWVar& operator=(       T* data );
+
+  /// Constructor with parameters: 
+
+  //RWVar(SG::DataProxy* proxy); ///< 
+
+  /// retrieve a proxy of name `name` from evtStore
+  RWVar(const IInterface* component,
+            const std::string& name);
+
+  /// retrieve a proxy of name `name` from store `store`
+  RWVar(const IInterface* component,
+        const std::string& name, 
+        const std::string& store);
+
+  /// retrieve a proxy of name `name` from evtStore
+  RWVar(const std::string& name);
+
+  /// retrieve a proxy of name `name` from store `store`
+  RWVar(const std::string& name, 
+        const std::string& store);
+
+  /// retrieve a proxy of name `name` from store `store`
+  //RWVar(const std::string& name, IProxyDict* store);
+
+  /// Destructor: 
+  virtual ~RWVar(); 
+
+  /// \name access to the underlying ptr
+  //@{
+  const_pointer_type operator->() const   { return cptr(); }
+  pointer_type operator->()               { return ptr();  }
+
+  const_reference_type operator*() const    { return *cptr(); }   
+  reference_type operator*()                { return *ptr();  }
+
+   ///< safer explicit ptr accessor 
+  const_pointer_type cptr() const
+  { return reinterpret_cast<const_pointer_type>(this->typeless_cptr()); }
+
+  ///< safer explicit ptr accessor 
+  pointer_type ptr()
+  { return reinterpret_cast<pointer_type>(this->typeless_ptr()); }
+
+  //@}
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /// the CLID of the object we are bound to
+  virtual CLID clid() const { return ClassID_traits<T>::ID(); }
+
+  /// the mode of the underlying handle (reader|writer|updater)
+  virtual Mode mode() const { return SG::VarHandleBase::Updater; }
+
+}; 
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+//std::ostream& operator<<( std::ostream& out, const RWVar& o );
+
+
+} /* namespace SG */
+
+#ifndef STOREGATE_SG_RWVAR_ICC
+ #include "StoreGate/RWVar.icc"
+#endif
+
+#endif //> !STOREGATE_SG_RWVAR_H

File StoreGate/RWVar.icc

+///////////////////////// -*- C++ -*- /////////////////////////////
+// RWVar.icc
+// Implementation file for class SG::RWVar<T>
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef STOREGATE_SG_RWVAR_ICC
+#define STOREGATE_SG_RWVAR_ICC 1
+
+// stl includes
+#include <stdexcept>
+
+// fwk includes
+#include "AthenaKernel/IProxyDict.h"
+#include "AthenaKernel/IResetable.h"
+
+// SGTools includes
+#include "SGTools/ClassID_traits.h"
+#include "SGTools/DataBucketBase.h"
+
+// StoreGate includes
+#include "StoreGate/VarHandleBase.h"
+
+namespace SG {
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+
+/// Default constructor: 
+template <class T> 
+RWVar<T>::RWVar() : 
+  VarHandleBase()
+{ }
+
+/// Copy constructor: 
+template <class T> 
+RWVar<T>::RWVar(const RWVar& h):
+  VarHandleBase(h)
+{}
+
+/// Assignment operator: 
+template <class T>
+RWVar<T>& 
+RWVar<T>::RWVar::operator= (const RWVar& h)
+{
+  if (this != &h) {
+    this->VarHandleBase::operator=(h);
+  }
+  return *this;
+}
+
+template <class T>
+RWVar<T>& 
+RWVar<T>::RWVar::operator= (const T& data)
+{
+  if (!isInitialized()) {
+    throw std::logic_error
+      ("RWVar<T>::operator=(const T& data) called while un-initialized");
+  }
+  if (!isConst()) {
+    this->reset();
+  }
+  T*val = this->ptr();
+  *val = data;
+
+  return *this;
+}
+
+/// retrieve a proxy of name `name` from evtStore
+template <class T>
+RWVar<T>::RWVar(const IInterface* /*iface*/,
+                const std::string& name) :
+  VarHandleBase( name )
+{}
+
+/// retrieve a proxy of name `name` from evtStore
+template <class T>
+RWVar<T>::RWVar(const IInterface* /*iface*/,
+                const std::string& name,
+                const std::string& store) :
+  VarHandleBase( name, store )
+{}
+
+
+/// retrieve a proxy of name `name` from evtStore
+template <class T>
+RWVar<T>::RWVar(const std::string& name) :
+  VarHandleBase( name )
+{}
+
+/// retrieve a proxy of name `name` from store `store`
+template <class T>
+RWVar<T>::RWVar(const std::string& name,
+                const std::string& store) :
+  VarHandleBase( name, store )
+{}
+
+/// Destructor: 
+template <class T> 
+RWVar<T>::~RWVar()
+{ 
+} 
+} /* namespace SG */
+
+#endif //> !STOREGATE_SG_RWVAR_ICC

File StoreGate/SGIterator.h

     /// @name SG-specific accessors
     //@{
     /// Get the key string with which the current object was stored.
-    const std::string& key() const;
+    const std::string& key() const
+    { return m_dh.key(); }
     /// RETRIEVES the data object to check it is valid and unlocked
-    bool isValid() const; 
+    bool isValid() const
+    {
+      const DataHandle<DATA>& dh = m_dh;
+      return dh.isValid();
+    }
     /// RETRIEVES the data object to check it is valid
-    bool isValid();       
+    //bool isValid()
+    //{ return m_dh.isValid(); }
     /// weaker test but it does not touch the disk!
-    bool isInitialized() const;    
+    bool isInitialized() const
+    { return m_dh.isInitialized(); }
     //@}
   private:
     mutable DataHandle<DATA> m_dh;
   
 namespace SG {
 /** @class ConstIterator 
- *  a const_iterator facase to DataHandle. Behaves like a forward iterator
+ *  a const_iterator facade to DataHandle. Behaves like a forward iterator
  */
   template <class DATA>
   class ConstIterator : 

File StoreGate/StoreGateSvc.h

 class MemoryMonitorSvc;
 class SGDeleteAlg;
 class ThinningSvc;
+namespace SG { class VarHandleBase; }
 namespace PerfMon { class StorePayloadMon; }
 
 /** @class StoreGateSvc 
 
   /// get proxy with given id and key. Returns 0 to flag failure
   virtual SG::DataProxy* proxy(const CLID& id, const std::string& key) const;
+  /// get proxy with given id and key. Returns 0 to flag failure
+  /// (overload to prevent a char* to be interpreted as a bool.)
+  virtual SG::DataProxy* proxy(const CLID& id, const char* key) const
+  { return this->proxy(id, std::string(key)); }
+
   //@}
 
   /// \name more proxy dictionary functionality
   /// get proxy with given id and key, optionally checking validity.
   ///  @returns 0 to flag failure
   virtual SG::DataProxy* proxy(const CLID& id, const std::string& key, bool checkValid) const;
+  /// get proxy with given id and key, optionally checking validity.
+  ///  @returns 0 to flag failure
+  /// (overload to prevent a char* to be interpreted as a bool.)
+  virtual SG::DataProxy* proxy(const CLID& id, const char* key, bool checkValid) const
+  { return this->proxy(id, std::string(key), checkValid); }
 
   /// return the list of all current proxies in store
   std::vector<const SG::DataProxy*> proxies() const;
   friend void testHLTAutoKeyReset(StoreGateSvc&, IProxyProviderSvc&);
   ///access typeless_record
   friend class ThinningSvc;
+  friend class SG::VarHandleBase;
   friend 
   PyObject* 
   AthenaInternal::recordObjectToStore(PyObject*,PyObject*,PyObject*);

File StoreGate/StoreGateSvc.icc

 template <typename T> 
 StatusCode StoreGateSvc::retrieve(const DataHandle<T>& handle)
 {
-  StatusCode sc = handle.setState(this, proxy(ClassID_traits<T>::ID()));
+  StatusCode sc = handle.setState(proxy(ClassID_traits<T>::ID()));
 
   if (sc.isFailure()) {
     msg() << MSG::WARNING 
 StatusCode StoreGateSvc::retrieve(DataHandle<T>& handle)
 {
 
-  StatusCode sc = handle.setState(this, proxy(ClassID_traits<T>::ID()));
+  StatusCode sc = handle.setState(proxy(ClassID_traits<T>::ID()));
 
   if (sc.isFailure()) {
     msg() << MSG::WARNING 
 {
   boost::function_requires< KeyConcept<TKEY> > ();
  
-  StatusCode sc = handle.setState(this, proxy(ClassID_traits<T>::ID(), (std::string)key, false));
+  StatusCode sc = handle.setState(proxy(ClassID_traits<T>::ID(), 
+                                        (std::string)key, 
+                                        false));
 
   if (sc.isFailure()) {
     msg() << MSG::WARNING 
   boost::function_requires< KeyConcept<TKEY> > ();
 
   StatusCode sc = 
-    handle.setState(this, proxy(ClassID_traits<T>::ID(), key, false));
+    handle.setState(proxy(ClassID_traits<T>::ID(), key, false));
 
   if (sc.isFailure()) {
     msg() << MSG::WARNING 
 #endif
   }
 
-  (chend.setState(this, end, end)).ignore();
+  (chend.setState(end, end)).ignore();
   
-  if (!(chbegin.setState(this, first, end)).isSuccess()) {
+  if (!(chbegin.setState(first, end)).isSuccess()) {
 #ifndef NDEBUG
     SG_MSG_DEBUG("retrieve(range): Can't set DataHandle for object range " 
 		  << " of type "  << ClassID_traits<T>::typeName() 
     return StatusCode::FAILURE;
   } else 
   {
-    return (handle.setState(this,dp)); // FIXME - should be retrieve?
+    return (handle.setState(dp)); // FIXME - should be retrieve?
   }
 }
 

File StoreGate/VarHandleBase.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// VarHandleBase.h 
+// Header file for class SG::VarHandleBase
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef STOREGATE_SG_VARHANDLEBASE_H
+#define STOREGATE_SG_VARHANDLEBASE_H 1
+
+// STL includes
+#include <string>
+
+// fwk includes
+#include "AthenaKernel/IProxyDict.h"
+#include "AthenaKernel/IResetable.h"
+
+// SGTools includes
+#include "SGTools/DataProxy.h"
+#include "SGTools/ProxyMap.h"
+#include "SGTools/StorableConversions.h"
+#include "SGTools/BuiltinsClids.h"
+#include "SGTools/StlVectorClids.h"
+#include "SGTools/StlMapClids.h"
+
+// StoreGate includes
+#include "StoreGate/StoreGateSvc.h"
+
+// Forward declaration
+//namespace AthenaInternal { class AthAlgorithmAccessor; }
+class VarHandleProperty;
+namespace SG { class VarHandleBase; }
+namespace Gaudi { namespace Parsers {
+    StatusCode parse(SG::VarHandleBase&, const std::string&);
+  }
+}
+namespace SG {
+/**
+ * @class SG::VarHandleBase
+ * @brief a smart pointer to an object of a given type in an @c IProxyDict (such
+ * as StoreGateSvc). It d-casts and caches locally the pointed-at object, to 
+ * speed-up subsequent accesses.
+ * It can be reset by the store for asynchronous updates (IOVSvc)
+ */
+class VarHandleBase : public IResetable
+{ 
+  //friend class AthenaInternal::AthAlgorithmAccessor;
+  friend class VarHandleProperty;
+  friend StatusCode Gaudi::Parsers::parse(SG::VarHandleBase&, 
+                                          const std::string&);
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public enums: 
+  /////////////////////////////////////////////////////////////////// 
+public: 
+
+  /** VarHandle type: Reader|Writer
+   */
+  enum Mode {
+    Reader = 1<<2,
+    Writer = 1<<4,
+    Updater = Reader | Writer
+  };
+ 
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+public: 
+
+  /// Default constructor: 
+  VarHandleBase();
+
+  /// Copy constructor: 
+  VarHandleBase( const VarHandleBase& rhs );
+
+  /// Assignment operator: 
+  VarHandleBase& operator=( const VarHandleBase& rhs ); 
+
+  /// Constructor with parameters: 
+
+  //VarHandleBase(SG::DataProxy* proxy); ///< 
+
+  VarHandleBase(const std::string& sgkey,
+                const std::string& storename = "StoreGateSvc");
+
+  /// Destructor: 
+  virtual ~VarHandleBase(); 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /// \name validity checks
+  //@{
+  bool isConst() const;
+  bool isInitialized() const;    ///<weaker test but it does not touch the disk!
+  bool isSet() const { return isInitialized(); }
+  //@}
+
+  /// \name validity checks
+  //@{
+  /// retrieves the @c DataObject to check it is valid and locked
+  bool isValid() const 
+  { 
+    // typeless_dataPointer() prints a warning if the proxy is null,
+    // so also test isInitialized().
+    return isInitialized() && 0 != typeless_dataPointer(); 
+  }
+
+  /// retrieves the @c DataObject to check it is valid and unlocked
+  bool isValid()
+  {
+    // typeless_ptr() prints a warning if the proxy is null,
+    // so also test isInitialized().
+    return (isInitialized() && 0 != typeless_ptr());
+  }
+
+#ifdef ATHENA_USE_CXX11
+  explicit operator bool() const  { return isValid(); }
+  explicit operator bool()        { return isValid(); }
+#else
+#endif
+  //@}
+
+  StatusCode setState() const;
+
+  /// the CLID of the object we are bound to
+  /// it is extracted from the templated derived class instead of
+  /// from the datamember proxy because we use this clid() method to
+  /// know which proxy to retrieve from the IProxyDict store.
+  virtual CLID clid() const =0;
+
+  /// the mode of the underlying handle (reader|writer|updater)
+  virtual Mode mode() const =0;
+
+  /// name of the store holding the object we are proxying
+  const std::string& store() const { return m_store; }
+
+  ///get the data object key (proxy name) - IResetable iface
+  const std::string& key() const { return this->name(); }
+
+  ///get the data object key (proxy name)
+  const std::string& name() const 
+  { 
+    return m_sgkey;
+  }
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  void reset() { m_ptr = 0; }        ///< reset pointer
+
+  StatusCode setState();
+
+  /// set the 'const' bit for the bound proxy in the store
+  void setConst() { m_proxy->setConst(); }
+
+  /////////////////////////////////////////////////////////////////// 
+  // Protected methods: 
+  /////////////////////////////////////////////////////////////////// 
+protected: 
+
+  StatusCode setState(SG::DataProxy* proxy) const;
+  StatusCode setState(IProxyDict* store, const std::string& name) const;
+
+  StatusCode setState(SG::DataProxy* proxy);
+  StatusCode setState(IProxyDict* store, const std::string& name);
+
+  /// helper functions to bind ourselves to a DataProxy
+  static bool bindToProxy(      SG::VarHandleBase* v);
+  static bool bindToProxy(const SG::VarHandleBase* v)
+  { 
+    return SG::VarHandleBase::bindToProxy(const_cast<SG::VarHandleBase*>(v));
+  }
+
+  /////////////////////////////////////////////////////////////////// 
+  // Protected data: 
+  /////////////////////////////////////////////////////////////////// 
+protected: 
+
+  /// the object we are bound to
+  mutable void* m_ptr;
+
+  /// the proxy holding the object we are bound to
+  mutable SG::DataProxy* m_proxy;
+
+  /// storegate key we will be bound to
+  std::string m_sgkey;
+  
+  /// name of the store which holds the object
+  std::string m_store;
+
+  void* typeless_dataPointer() const
+  {
+    if (m_ptr) { return m_ptr; }
+    return typeless_dataPointer_impl();
+  }
+
+  void* typeless_dataPointer_impl() const;
+  const void* typeless_cptr() const { return typeless_dataPointer(); }
+  void* typeless_ptr()
+  {
+    void* p = typeless_dataPointer();
+    return 0 != p && !isConst() ? p : 0;
+  }
+
+  // /// helper function to retrieve a `SG::DataProxy` from a store
+  // /// given its name and clid
+  // static 
+  // SG::DataProxy* retrieveProxyFromStore(CLID clid,
+  //                                       const std::string& name,
+  //                                       const std::string& store);
+}; 
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+//std::ostream& operator<<( std::ostream& out, const VarHandleBase& o );
+
+
+} /* namespace SG */
+
+#endif //> !STOREGATE_SG_VARHANDLEBASE_H

File StoreGate/VarHandleProperty.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// VarHandleProperty.h 
+// Header file for class VarHandleProperty
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef STOREGATE_VARHANDLEPROPERTY_H
+#define STOREGATE_VARHANDLEPROPERTY_H 1
+
+// stl
+#include <iostream>
+
+// framework includes
+#include "GaudiKernel/StatusCode.h"
+#include "GaudiKernel/Parsers.h"
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/PropertyMgr.h"
+#include "GaudiKernel/ToStream.h"
+
+#include "StoreGate/RVar.h"
+#include "StoreGate/WVar.h"
+#include "StoreGate/RWVar.h"
+
+namespace Gaudi { 
+namespace Parsers {
+
+GAUDI_API
+StatusCode
+parse(SG::VarHandleBase&, const std::string&);
+
+} //> ns Parsers
+
+namespace Utils {
+
+GAUDI_API
+std::ostream& 
+toStream(const SG::VarHandleBase& v, std::ostream& o);
+
+} //> ns Utils
+} //> ns Gaudi
+
+
+
+/** @brief VarHandleProperty is the class which wraps a @c SG::VarHandleBase
+ *
+ *  VarHandleProperty allows any SG::VarHandleBase instance (ie SG::RVar<T>,
+ *  SG::WVar<T> and SG::RWVar<T>) to be modified at the job option level.
+ */
+class GAUDI_API VarHandleProperty : 
+    public ::Property 
+{
+ public:
+
+  /// Constructor with parameters: 
+  VarHandleProperty( const std::string& name, SG::VarHandleBase& ref );
+
+  /// Assignment operator: 
+  VarHandleProperty& operator=( const SG::VarHandleBase& value );
+
+  /// Destructor: 
+  virtual ~VarHandleProperty();
+
+  virtual VarHandleProperty* clone() const;
+    
+  virtual bool load( Property& destination ) const;
+
+  virtual bool assign( const Property& source );
+
+  virtual std::string toString() const;
+
+  virtual void toStream(std::ostream& out) const;
+
+  virtual StatusCode fromString(const std::string& s);
+
+  const SG::VarHandleBase& value() const;
+
+  bool setValue( const SG::VarHandleBase& value );
+
+ private:
+  /** Pointer to the real property. Reference would be better, 
+   *  but Reflex does not support references yet
+   */
+  SG::VarHandleBase* m_pValue;
+};
+
+/** @brief Specialization for SG::RVar<T>
+ *
+ *  Needed drudgery for the @c PropertyMgr and @c Property classes so
+ *  @c ::VarHandleBase (and derived) classes are known to the property handling
+ *  infrastructure of Gaudi
+ */
+template<typename T>
+class SimplePropertyRef< SG::RVar<T> > :
+  public ::VarHandleProperty
+{
+public:
+
+  /// Constructor from the name and the handle
+  SimplePropertyRef(const std::string& name, SG::RVar<T>& value) :
+    ::VarHandleProperty(name, value)
+  {}
+
+  /// virtual Destructor
+  virtual ~SimplePropertyRef() {}
+};
+
+
+/** @brief Specialization for SG::RWVar<T>
+ *
+ *  Needed drudgery for the @c PropertyMgr and @c Property classes so
+ *  @c ::VarHandleBase (and derived) classes are known to the property handling
+ *  infrastructure of Gaudi
+ */
+template<typename T>
+class SimplePropertyRef< SG::RWVar<T> > :
+  public ::VarHandleProperty
+{
+public:
+
+  /// Constructor from the name and the handle
+  SimplePropertyRef( const std::string& name, SG::RWVar<T>& value ) :
+    ::VarHandleProperty(name, value)
+  {}
+
+  /// virtual Destructor
+  virtual ~SimplePropertyRef() {}
+};
+
+/** @brief Specialization for SG::WVar<T>
+ *
+ *  Needed drudgery for the @c PropertyMgr and @c Property classes so
+ *  @c ::VarHandleBase (and derived) classes are known to the property handling
+ *  infrastructure of Gaudi
+ */
+template<typename T>
+class SimplePropertyRef< SG::WVar<T> > :
+  public ::VarHandleProperty
+{
+public:
+
+  /// Constructor from the name and the handle
+  SimplePropertyRef( const std::string& name, SG::WVar<T>& value ) :
+    ::VarHandleProperty(name, value)
+  {}
+
+  /// virtual Destructor
+  virtual ~SimplePropertyRef() {}
+};
+
+
+inline
+VarHandleProperty& 
+VarHandleProperty::operator=( const SG::VarHandleBase& value ) 
+{
+  setValue( value );
+  return *this;
+}
+
+inline
+VarHandleProperty* 
+VarHandleProperty::clone() const 
+{
+  return new VarHandleProperty( *this );
+}
+
+inline
+bool
+VarHandleProperty::load( Property& destination ) const 
+{
+  return destination.assign( *this );
+}
+
+inline
+bool
+VarHandleProperty::assign( const Property& source ) 
+{
+  return fromString( source.toString() ).isSuccess();
+}
+
+inline
+const SG::VarHandleBase& 
+VarHandleProperty::value() const 
+{
+  useReadHandler();
+  return *m_pValue;
+}
+
+#endif /* !STOREGATE_VARHANDLEPROPERTY_H */
+

File StoreGate/WVar.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// WVar.h 
+// Header file for class SG::WVar<T>
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef STOREGATE_SG_WVAR_H
+#define STOREGATE_SG_WVAR_H 1
+
+// STL includes
+#include <string>
+
+// fwk includes
+#include "GaudiKernel/IInterface.h"
+#include "AthenaKernel/IProxyDict.h"
+#include "AthenaKernel/IResetable.h"
+
+// SGTools includes
+#include "SGTools/ClassID_traits.h"
+
+// StoreGate includes
+#include "StoreGate/VarHandleBase.h"
+
+// Forward declaration
+
+
+namespace SG {
+/**
+ * @class SG::WVar<T>
+ * @brief a smart pointer to an object of a given type in an @c IProxyDict (such
+ * as StoreGateSvc). It d-casts and caches locally the pointed-at object, to 
+ * speed-up subsequent accesses.
+ * It can be reset by the store for asynchronous updates (IOVSvc)
+ *
+ * @c SG::WVar<T> can only access non-const proxies in StoreGate, no proxy
+ * should already exist in StoreGate as SG::WVar<T> will create it.
+ *
+ * Usage example:
+ * @code
+ *   class MyAlg : public AthAlgorithm
+ *   {
+ *     SG::WVar<int> m_int;
+ *   };
+ *
+ *   MyAlg::MyAlg(...) : ..., m_int("MyIntSgKey") {
+ *      declareProperty("IntHandle",
+ *                      m_int = SG::WVar<int>("MyIntSgKey"),
+ *                      "a handle to an int in StoreGate");
+ *   }
+ *
+ *   StatusCode MyAlg::execute()
+ *   {
+ *     m_int = new int(42);
+ *     ATH_MSG_INFO("int value @[" << m_int.name() << "]="
+ *                  << *m_int);
+ *     *m_int += 10;
+ *     ATH_MSG_INFO("int value @[" << m_int.name() << "]="
+ *                  << *m_int);
+ *     return StatusCode::SUCCESS;
+ *   }
+ * @endcode
+ *
+ * For more informations have a look under the package
+ *     Control/AthenaExamples/AthExHelloWorld
+ *
+ */
+template <class T>
+class WVar : public SG::VarHandleBase
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public typedefs: 
+  /////////////////////////////////////////////////////////////////// 
+public: 
+  typedef T*               pointer_type; // FIXME: better handling of
+  typedef const T*   const_pointer_type; //        qualified T type ?
+  typedef T&             reference_type;
+  typedef const T& const_reference_type;
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+public: 
+
+  /// Default constructor: 
+  WVar();
+
+  /// Copy constructor: 
+  WVar( const WVar& rhs );
+
+  /// Assignment operator: 
+  WVar& operator=( const WVar& rhs ); 
+  WVar& operator=( const T& data );
+  // owns the pointer
+  WVar& operator=( T* data );
+
+  /// Constructor with parameters: 
+
+  //WVar(SG::DataProxy* proxy); ///< 
+
+  /// retrieve a proxy of name `name` from evtStore
+  WVar(const IInterface* component,
+            const std::string& name);
+
+  /// retrieve a proxy of name `name` from store `store`
+  WVar(const IInterface* component,
+        const std::string& name, 
+        const std::string& store);
+
+  /// retrieve a proxy of name `name` from evtStore
+  WVar(const std::string& name);
+
+  /// retrieve a proxy of name `name` from store `store`
+  WVar(const std::string& name, 
+        const std::string& store);
+
+  /// retrieve a proxy of name `name` from store `store`
+  //WVar(const std::string& name, IProxyDict* store);
+
+  /// Destructor: 
+  virtual ~WVar(); 
+
+  /// \name access to the underlying ptr
+  //@{
+  const_pointer_type operator->() const   { return cptr(); }
+  pointer_type operator->()               { return ptr();  }
+
+  const_reference_type operator*() const    { return *cptr(); }   
+  reference_type operator*()                { return *ptr();  }
+
+   ///< safer explicit ptr accessor 
+  const_pointer_type cptr() const
+  { return reinterpret_cast<const_pointer_type>(this->typeless_cptr()); }
+
+  ///< safer explicit ptr accessor 
+  pointer_type ptr()
+  { return reinterpret_cast<pointer_type>(this->typeless_ptr()); }
+
+  //@}
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /// the CLID of the object we are bound to
+  virtual CLID clid() const { return ClassID_traits<T>::ID(); }
+
+  /// the mode of the underlying handle (reader|writer|updater)
+  virtual Mode mode() const { return SG::VarHandleBase::Writer; }
+
+}; 
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+//std::ostream& operator<<( std::ostream& out, const WVar& o );
+
+
+} /* namespace SG */
+
+#ifndef STOREGATE_SG_WVAR_ICC
+ #include "StoreGate/WVar.icc"
+#endif
+
+#endif //> !STOREGATE_SG_WVAR_H

File StoreGate/WVar.icc

+///////////////////////// -*- C++ -*- /////////////////////////////
+// WVar.icc
+// Implementation file for class SG::WVar<T>
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef STOREGATE_SG_WVAR_ICC
+#define STOREGATE_SG_WVAR_ICC 1
+
+// stl includes
+#include <stdexcept>
+
+// fwk includes
+#include "AthenaKernel/IProxyDict.h"
+#include "AthenaKernel/IResetable.h"
+
+// SGTools includes
+#include "SGTools/ClassID_traits.h"
+#include "SGTools/DataBucketBase.h"
+
+// StoreGate includes
+#include "StoreGate/VarHandleBase.h"
+
+namespace SG {
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+
+/// Default constructor: 
+template <class T> 
+WVar<T>::WVar() : 
+  VarHandleBase()
+{ }
+
+/// Copy constructor: 
+template <class T> 
+WVar<T>::WVar(const WVar& h):
+  VarHandleBase(h)
+{}
+
+/// Assignment operator: 
+template <class T>
+WVar<T>& 
+WVar<T>::WVar::operator= (const WVar& h)
+{
+  if (this != &h) {
+    this->VarHandleBase::operator=(h);
+  }
+  return *this;
+}
+
+template <class T>
+WVar<T>& 
+WVar<T>::WVar::operator= (const T& data)
+{
+  if (!isInitialized()) {
+    throw std::logic_error
+      ("WVar<T>::operator=(const T& data) called while un-initialized");
+  }
+  T*val = this->ptr();
+  *val = data;
+  return *this;
+}
+
+template <class T>
+WVar<T>& 
+WVar<T>::WVar::operator= (T* data)
+{
+  if (!isInitialized()) {
+    // record into storegate
+    ServiceHandle<StoreGateSvc> svc(this->store(), "SG::WVar<T>");
+    svc->record<T>(data, this->name()).ignore();
+    setState().ignore();
+    return *this;
+  }
+  reset();
+
+  this->m_proxy->setObject(SG::asStorable<T>(data));
+  return *this;
+}
+
+/// retrieve a proxy of name `name` from evtStore
+template <class T>
+WVar<T>::WVar(const IInterface* /*iface*/,
+                        const std::string& name) :
+  VarHandleBase( name )
+{}
+
+/// retrieve a proxy of name `name` from evtStore
+template <class T>
+WVar<T>::WVar(const IInterface* /*iface*/,
+                        const std::string& name,
+                        const std::string& store) :
+  VarHandleBase( name, store )
+{}
+
+
+/// retrieve a proxy of name `name` from evtStore
+template <class T>
+WVar<T>::WVar(const std::string& name) :
+  VarHandleBase( name )
+{}
+
+/// retrieve a proxy of name `name` from store `store`
+template <class T>
+WVar<T>::WVar(const std::string& name,
+                        const std::string& store) :
+  VarHandleBase( name, store )
+{}
+
+/// Destructor: 
+template <class T> 
+WVar<T>::~WVar()
+{ 
+} 
+
+} /* namespace SG */
+
+#endif //> !STOREGATE_SG_WVAR_ICC

File src/VarHandleBase.cxx

+///////////////////////// -*- C++ -*- /////////////////////////////
+// VarHandleBase.cxx 
+// Implementation file for class VarHandleBase
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// StoreGate includes
+#include "StoreGate/VarHandleBase.h"
+#include "StoreGate/StoreGateSvc.h"
+
+// SGTools includes
+#include "SGTools/DataBucketBase.h"
+#include "SGTools/StorableConversions.h"
+
+// STL includes
+#include <algorithm> //> for std::swap
+
+// fwk includes
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "AthenaKernel/getMessageSvc.h"
+
+// #ifdef NDEBUG
+// #undef NDEBUG
+// #endif
+
+namespace SG {
+
+/// helper functions to bind ourselves to a DataProxy
+bool 
+VarHandleBase::bindToProxy(SG::VarHandleBase* v)
+{
+  // we need to set v's proxy to null in order for the 
+  // DataProxy::bindHandle call to succeed: it checks if the to-be-bound
+  // object is already set/bound...
+  if (v->m_proxy) {
+    SG::DataProxy *p = NULL;
+    std::swap(v->m_proxy, p);
+    bool o = p->bindHandle(v);
+    std::swap(v->m_proxy, p);
+    return o;
+  }
+  return false;
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+
+/// Default constructor: 
+VarHandleBase::VarHandleBase() :
+  IResetable(),
+  m_ptr(NULL),
+  m_proxy(NULL),
+  m_sgkey(""),
+  m_store("")
+{}
+
+/// Copy constructor: 
+VarHandleBase::VarHandleBase( const VarHandleBase& rhs ) :
+  IResetable(),
+  m_ptr(rhs.m_ptr),
+  m_proxy(rhs.m_proxy),
+  m_sgkey(rhs.m_sgkey),
+  m_store(rhs.m_store)
+{
+  if (m_proxy) {
+    m_proxy->addRef();
+  }
+  bindToProxy(this);
+}
+
+
+/// Assignment operator: 
+VarHandleBase& 
+VarHandleBase::operator=( const VarHandleBase& rhs )
+{
+  if (m_proxy) {
+    m_proxy->release();
+  }
+
+  m_ptr =    rhs.m_ptr;
+  m_proxy =  rhs.m_proxy;
+  m_sgkey =  rhs.m_sgkey;
+  m_store =  rhs.m_store;
+
+  if (m_proxy) {
+    m_proxy->addRef();
+  }
+
+  bindToProxy(this);
+  return *this;
+}
+
+VarHandleBase::VarHandleBase(const std::string& sgkey,
+                             const std::string& storename) :
+  IResetable(),
+  m_ptr(NULL),
+  m_proxy(NULL),
+  m_sgkey(sgkey),
+  m_store(storename)
+{}
+
+/// Destructor: 
+VarHandleBase::~VarHandleBase()
+{
+  if (m_proxy != 0) {
+    m_proxy->unbindHandle(this);
+    m_proxy->release();
+  }
+  m_proxy = 0;
+  m_ptr = 0;
+}
+
+// Destructor
+///////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+StatusCode 
+VarHandleBase::setState() const
+{
+  //std::cerr << "::VHB::setState() const...\n"; 
+  if (m_sgkey.empty() || m_store.empty()) {
+    return StatusCode::FAILURE;
+  }
+
+  typedef ServiceHandle<StoreGateSvc> Store_t;
+  Store_t store(m_store, "VarHandle");
+  if (!store.retrieve().isSuccess()) {
+    return StatusCode::FAILURE;
+  }
+
+  SG::DataProxy * proxy = store->proxy(this->clid(), m_sgkey);
+  return this->setState(proxy);
+}
+
+StatusCode 
+VarHandleBase::setState(SG::DataProxy* proxy) const
+{
+  // std::cerr << "::VHB::setState(" 
+  //           << proxy 
+  //           << " -- isValid: " << proxy->isValid()
+  //           << " -- isConst: " << proxy->isConst()
+  //           << ") const\n";
+  if (0 == proxy || !proxy->isValid()) {
+    return StatusCode::FAILURE;
+  }
+
+  SG::VarHandleBase *self = const_cast<SG::VarHandleBase*>(this);
+
+  if (m_proxy != proxy) {
+    if (m_proxy) m_proxy->release();
+    m_proxy = proxy;
+    m_proxy->addRef();
+    bindToProxy(self);
+  }
+
+  self->reset();
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode 
+VarHandleBase::setState(IProxyDict* store, const std::string& key) const 
+{
+  if (0 == store) {
+    return StatusCode::FAILURE;
+  }
+  // std::cerr << "::VHB::setState(" 
+  //           << store->name() << ", "
+  //           << key
+  //           << ") const\n";
+
+  CLID cid = this->clid();
+  SG::DataProxy* proxy = store->proxy(cid, key);
+  // std::cerr << "::VHB:: -- clid=[" << cid << "] proxy=[" << proxy << "]\n";
+  return this->setState(proxy);
+}
+
+bool 
+VarHandleBase::isConst() const
+{
+  return 0 != m_proxy 
+    ? m_proxy->isConst() 
+    : false;
+}
+
+
+// A weaker test that
+// *does not* retrieve the GaudiObject to check validity if not already done
+bool 
+VarHandleBase::isInitialized() const
+{
+  return (0 != m_proxy);
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+StatusCode 
+VarHandleBase::setState()
+{
+  // std::cerr << "::VHB::setState()...\n"; 
+  if (m_sgkey.empty() || m_store.empty()) {
+    return StatusCode::FAILURE;
+  }
+
+  typedef ServiceHandle<StoreGateSvc> Store_t;
+  Store_t store(m_store, "VarHandle");
+  if (!store.retrieve().isSuccess()) {
+    return StatusCode::FAILURE;
+  }
+
+  SG::DataProxy * proxy = store->proxy(this->clid(), m_sgkey);
+  return this->setState(proxy);
+}
+
+StatusCode 
+VarHandleBase::setState(SG::DataProxy* proxy)
+{
+  // std::cerr << "::VHB::setState(" 
+  //           << proxy 
+  //           << " -- isValid: " << proxy->isValid()
+  //           << " -- isConst: " << proxy->isConst()
+  //           << ")\n";
+  if (0 == proxy || !proxy->isValid() || proxy->isConst()) {
+    return StatusCode::FAILURE;
+  }
+
+  if (m_proxy != proxy) {
+    if (m_proxy) m_proxy->release();
+    m_proxy = NULL;
+    m_proxy = proxy;
+    m_proxy->addRef();
+    bindToProxy(this);
+  }
+  this->reset();
+  return StatusCode::SUCCESS;
+}
+
+StatusCode 
+VarHandleBase::setState(IProxyDict* store, const std::string& key)
+{
+  if (0 == store) {
+    return StatusCode::FAILURE;
+  }
+  // std::cerr << "::VHB::setState(" 
+  //           << store->name() << ", "
+  //           << key
+  //           << ")\n";
+  CLID cid = this->clid();
+  SG::DataProxy* proxy = store->proxy(cid, key);
+  // std::cerr << "::VHB:: -- clid=[" << cid << "] proxy=[" << proxy << "]\n";
+  return this->setState(proxy);
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Protected methods: 
+/////////////////////////////////////////////////////////////////// 
+
+#define SG_VARHANDLE_NAME "SG::VarHandleBase::typeless_dataPointer"
+void* 
+VarHandleBase::typeless_dataPointer_impl() const
+{
+  // std::cerr << "::VHB::typeless_dataPointer("
+  //           << "ptr=" << this->m_ptr << ", "
+  //           << "proxy=" << this->m_proxy << ", "
+  //           << "key=" <<this->m_sgkey
+  //           << ")...\n";
+  if (m_ptr) {
+    return m_ptr;
+  }
+
+  m_ptr = NULL;
+  if (NULL == m_proxy) {
+    setState().ignore();
+  }
+  if (!m_proxy || !m_proxy->isValid()) {
+    // invalid proxy
+#ifndef NDEBUG
+    MsgStream msg(Athena::getMessageSvc(), SG_VARHANDLE_NAME);
+    if (msg.level() <= MSG::WARNING) {
+      msg << MSG::WARNING