Commits

Anonymous committed 93a096f

remove VarHandle + add RVar, WVar and RWVar handles + add property support for var handles

  • Participants
  • Parent commits 62b7e45

Comments (0)

Files changed (13)

+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.
+///////////////////////// -*- 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

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

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

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

StoreGate/VarHandle.h

-///////////////////////// -*- C++ -*- /////////////////////////////
-// VarHandle.h 
-// Header file for class SG::VarHandle<T>
-// Author: S.Binet<binet@cern.ch>
-/////////////////////////////////////////////////////////////////// 
-#ifndef STOREGATE_SG_VARHANDLE_H
-#define STOREGATE_SG_VARHANDLE_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::VarHandle<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)
- */
-template <class T>
-class VarHandle : 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: 
-  VarHandle();
-
-  /// Copy constructor: 
-  VarHandle( const VarHandle& rhs );
-
-  /// Assignment operator: 
-  VarHandle& operator=( const VarHandle& rhs ); 
-  VarHandle& operator=( const T& data );
-
-  /// Constructor with parameters: 
-
-  //VarHandle(SG::DataProxy* proxy); ///< 
-
-  /// retrieve a proxy of name `name` from evtStore
-  VarHandle(const IInterface* component,
-            const std::string& name);
-
-  /// retrieve a proxy of name `name` from store `store`
-  VarHandle(const IInterface* component,
-            const std::string& name, 
-            const std::string& store);
-
-  /// retrieve a proxy of name `name` from evtStore
-  VarHandle(const std::string& name);
-
-  /// retrieve a proxy of name `name` from store `store`
-  VarHandle(const std::string& name, 
-            const std::string& store);
-
-  /// retrieve a proxy of name `name` from store `store`
-  //VarHandle(const std::string& name, IProxyDict* store);
-
-  /// Destructor: 
-  virtual ~VarHandle(); 
-
-  /// \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(); }
-
-private:
-  /// put a default-constructed object into store `store`
-  virtual StatusCode 
-  pre_record_object(const std::string& name,
-                    const std::string& store);
-
-}; 
-
-/////////////////////////////////////////////////////////////////// 
-// Inline methods: 
-/////////////////////////////////////////////////////////////////// 
-//std::ostream& operator<<( std::ostream& out, const VarHandle& o );
-
-
-} /* namespace SG */
-
-#ifndef STOREGATE_SG_VARHANDLE_ICC
- #include "StoreGate/VarHandle.icc"
-#endif
-
-#endif //> !STOREGATE_SG_VARHANDLE_H

StoreGate/VarHandle.icc

-///////////////////////// -*- C++ -*- /////////////////////////////
-// VarHandle.icc
-// Implementation file for class SG::VarHandle<T>
-// Author: S.Binet<binet@cern.ch>
-/////////////////////////////////////////////////////////////////// 
-#ifndef STOREGATE_SG_VARHANDLE_ICC
-#define STOREGATE_SG_VARHANDLE_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> 
-VarHandle<T>::VarHandle() : 
-  VarHandleBase()
-{ }
-
-/// Copy constructor: 
-template <class T> 
-VarHandle<T>::VarHandle(const VarHandle& h):
-  VarHandleBase(h)
-{}
-
-/// Assignment operator: 
-template <class T>
-VarHandle<T>& 
-VarHandle<T>::VarHandle::operator= (const VarHandle& h)
-{
-  if (this != &h) {
-    this->VarHandleBase::operator=(h);
-  }
-  return *this;
-}
-
-template <class T>
-VarHandle<T>& 
-VarHandle<T>::VarHandle::operator= (const T& data)
-{
-  if (!isInitialized()) {
-    throw std::logic_error
-      ("VarHandle<T>::operator=(const T& data) called while un-initialized");
-  }
-  //std::cerr << "--- op= ---...\n";
-  T*val = this->ptr();
-  //std::cerr << "  val: " << *val << " -- addr: " << this->m_ptr << "\n";
-  if (!isConst()) {
-    //delete this->m_ptr;
-    this->reset();
-  }
-  //new(this->m_ptr) T(data);
-  this->m_ptr = new T(data);
-  this->m_proxy->setObject(SG::asStorable<T>(this->ptr()));
-  val = this->ptr();
-  // std::cerr << "  val: " << *val << " -- addr: " << this->m_ptr << "\n";
-  // std::cerr << "  reset-only: " << this->m_proxy->isResetOnly() << "\n";
-  // std::cerr << "--- op= ---... [done]\n";
-  return *this;
-}
-
-
-/// Constructor with parameters: 
-// template <class T> 
-// VarHandle<T>::VarHandle(SG::DataProxy* proxy) : 
-//   VarHandleBase(proxy)
-// {}
-
-/// retrieve a proxy of name `name` from evtStore
-template <class T>
-VarHandle<T>::VarHandle(const IInterface* /*iface*/,
-                        const std::string& name) :
-  VarHandleBase( name )
-{}
-
-/// retrieve a proxy of name `name` from evtStore
-template <class T>
-VarHandle<T>::VarHandle(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>
-VarHandle<T>::VarHandle(const std::string& name) :
-  VarHandleBase( name )
-{}
-
-/// retrieve a proxy of name `name` from store `store`
-template <class T>
-VarHandle<T>::VarHandle(const std::string& name,
-                        const std::string& store) :
-  VarHandleBase( name, store )
-{}
-
-/// retrieve a proxy of name `name` from store `store`
-// template <class T>
-// VarHandle<T>::VarHandle(const std::string& name, IProxyDict* store) :
-//   VarHandleBase( store != 0 
-//                  ? store->proxy(ClassID_traits<T>::ID(), name)
-//                  : 0)
-// {}
-
-/// Destructor: 
-template <class T> 
-VarHandle<T>::~VarHandle()
-{ 
-} 
-
-template <class T>
-StatusCode 
-VarHandle<T>::pre_record_object(const std::string& name,
-                                const std::string& store)
-{
-  T *ptr = new T;
-  std::cerr << "--pre-record: " << ptr << "...\n";
-  DataObject* dobj = SG::asStorable<T>(ptr);
-  ServiceHandle<StoreGateSvc> svc(store, "SG::VarHandle<T>");
-  // default taken from StoreGateSvc::record<T>(T* data, key name);
-  const bool allowMods = true;
-  const bool resetOnly = true;
-  const bool noHist = false;
-  return typeless_record(svc, dobj, name, ptr, allowMods, resetOnly, noHist);
-  //return svc->typeless_record(dobj, name, ptr, allowMods, resetOnly, noHist);
-}
-
-} /* namespace SG */
-
-#endif //> !STOREGATE_SG_VARHANDLE_ICC

StoreGate/VarHandleBase.h

 #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; }
-
+//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
  */
 class VarHandleBase : public IResetable
 { 
-  friend class AthenaInternal::AthAlgorithmAccessor;
+  //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: 
   /// 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; }
 
 
   StatusCode setState();
 
+  /// set the 'const' bit for the bound proxy in the store
+  void setConst() { m_proxy->setConst(); }
+
   /////////////////////////////////////////////////////////////////// 
   // Protected methods: 
   /////////////////////////////////////////////////////////////////// 
   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: 
   /////////////////////////////////////////////////////////////////// 
   /// name of the store which holds the object
   std::string m_store;
 
-  void* typeless_dataPointer() const;
+  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()
   {
     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);
-
-  /// put a default-constructed object into store `store`
-  virtual StatusCode 
-  pre_record_object(const std::string& name,
-                    const std::string& store = "StoreGateSvc") =0;
-
-  
-  template<class SVC>
-  StatusCode 
-  typeless_record(SVC& svc, 
-                  DataObject* obj, const std::string& key,
-			      const void* const raw_ptr,
-			      bool allowMods, bool resetOnly,
-			      bool noHist)
-  {
-    return svc->typeless_record(obj, key, raw_ptr, 
-                                allowMods, resetOnly, noHist);
-  }
+  // /// 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);
 }; 
 
 /////////////////////////////////////////////////////////////////// 

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 */
+
+///////////////////////// -*- 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

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

src/VarHandleBase.cxx

 #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: 
 /////////////////////////////////////////////////////////////////// 
   if (m_proxy) {
     m_proxy->addRef();
   }
+  bindToProxy(this);
 }
 
 
     m_proxy->addRef();
   }
 
+  bindToProxy(this);
   return *this;
 }
 
-/// Constructor with parameters: 
-/*
-VarHandleBase::VarHandleBase(SG::DataProxy* proxy) :
-  IResetable(),
-  m_ptr(NULL),
-  m_proxy(proxy),
-  m_sgkey(proxy ? proxy->name() :: "")
-  m_store("") // FIXME: how to retrieve that information from DataProxy?
-{
-  if (m_proxy) {
-    m_proxy->addRef();
-  }
-}
-*/
-
 VarHandleBase::VarHandleBase(const std::string& sgkey,
                              const std::string& storename) :
   IResetable(),
   m_proxy(NULL),
   m_sgkey(sgkey),
   m_store(storename)
-{
-  if (m_proxy) {
-    m_proxy->addRef();
-  }
-}
+{}
 
 /// Destructor: 
 VarHandleBase::~VarHandleBase()
 StatusCode 
 VarHandleBase::setState() const
 {
+  //std::cerr << "::VHB::setState() const...\n"; 
   if (m_sgkey.empty() || m_store.empty()) {
     return StatusCode::FAILURE;
   }
 StatusCode 
 VarHandleBase::setState(SG::DataProxy* proxy) const
 {
-  std::cerr << "::VHB::setState(" 
-            << proxy 
-            << " -- isValid: " << proxy->isValid()
-            << " -- isConst: " << proxy->isConst()
-            << ") const\n";
+  // 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);
   }
 
-  const_cast<SG::VarHandleBase*>(this)->reset();
+  self->reset();
 
   return StatusCode::SUCCESS;
 }
   if (0 == store) {
     return StatusCode::FAILURE;
   }
-  std::cerr << "::VHB::setState(" 
-            << store->name() << ", "
-            << key
-            << ") const\n";
+  // 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";
+  // std::cerr << "::VHB:: -- clid=[" << cid << "] proxy=[" << proxy << "]\n";
   return this->setState(proxy);
 }
 
 StatusCode 
 VarHandleBase::setState()
 {
+  // std::cerr << "::VHB::setState()...\n"; 
   if (m_sgkey.empty() || m_store.empty()) {
     return StatusCode::FAILURE;
   }
 StatusCode 
 VarHandleBase::setState(SG::DataProxy* proxy)
 {
-  std::cerr << "::VHB::setState(" 
-            << proxy 
-            << " -- isValid: " << proxy->isValid()
-            << " -- isConst: " << proxy->isConst()
-            << ")\n";
+  // 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;
 }
   if (0 == store) {
     return StatusCode::FAILURE;
   }
-  std::cerr << "::VHB::setState(" 
-            << store->name() << ", "
-            << key
-            << ")\n";
+  // 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";
+  // std::cerr << "::VHB:: -- clid=[" << cid << "] proxy=[" << proxy << "]\n";
   return this->setState(proxy);
 }
 
 
 #define SG_VARHANDLE_NAME "SG::VarHandleBase::typeless_dataPointer"
 void* 
-VarHandleBase::typeless_dataPointer() const
+VarHandleBase::typeless_dataPointer_impl() const
 {
-  if (0 == m_ptr) {
-    void *ptr = 0;
-    if (0 != m_proxy && m_proxy->isValid()) {
-      DataObject* dobj = m_proxy->accessData();
-      if (0 != dobj) {
-        const CLID clid = this->clid();
-        ptr = SG::Storable_cast(dobj, clid, m_proxy);
-        
-        if (0 == ptr) {
-          // if ptr is null, probably the clid we gave wasn't the clid
-          // the object was stored with, nor it inherits from it.
-          // before giving up, let's check its transient CLIDs
-          DataBucketBase *dbb = 0;
-          if (m_proxy->transientAddress()->transientID(clid) &&
-              0 != (dbb = dynamic_cast<DataBucketBase*>(dobj))) {
-            // it is a symlink after all.
-            // Let's hard cast (and keep our fingers Xed)
-            ptr = static_cast<void*>(dbb->object());
-          } else {
+  // 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 
-                  << "Request for an invalid object; requested CLID = " 
-                  << clid 
-                  << ", proxy primary ID is " << m_proxy->clID() 
-                  << endreq;
-            }
+    MsgStream msg(Athena::getMessageSvc(), SG_VARHANDLE_NAME);
+    if (msg.level() <= MSG::WARNING) {
+      msg << MSG::WARNING 
+          << "this proxy " << MSG::hex << m_proxy
+          << MSG::dec 
+          << " [" << (m_proxy != 0 ? m_proxy->clID() : 0)
+          << "/" << (m_proxy != 0 
+                     ? m_proxy->name() 
+                     : std::string("<N/A>"))
+          << "] is in an invalid state" << endreq;
+    }
 #endif
-          } // try symlink -- endif
-        } // ptr != 0 -- endif
-      } else { 
-        // invalid dobj
+    return m_ptr;
+  }
+
+  DataObject* dobj = m_proxy->accessData();
+  if (!dobj) {
+    // invalid dobj
 #ifndef NDEBUG
-            MsgStream msg(Athena::getMessageSvc(), SG_VARHANDLE_NAME);
-            if (msg.level() <= MSG::WARNING) {
-              msg << MSG::WARNING 
-                  << "this proxy " << MSG::hex << m_proxy
-                  << MSG::dec << " has a NULL data object ptr" 
-                  << endreq;
-            }
+    MsgStream msg(Athena::getMessageSvc(), SG_VARHANDLE_NAME);
+    if (msg.level() <= MSG::WARNING) {
+      msg << MSG::WARNING 
+          << "this proxy " << MSG::hex << m_proxy
+          << MSG::dec << " has a NULL data object ptr" 
+          << endreq;
+    }
 #endif
-      }
-    } else { 
-      // invalid proxy
+    return m_ptr;
+  }
+
+  const CLID clid = this->clid();
+  m_ptr = SG::Storable_cast(dobj, clid, m_proxy);
+  if (m_ptr) {
+    return m_ptr;
+  }
+
+  // if m_ptr is null, probably the clid we gave wasn't the clid
+  // the object was stored with, nor it inherits from it.
+  // before giving up, let's check its transient CLIDs
+  DataBucketBase *dbb = 0;
+  if (m_proxy->transientAddress()->transientID(clid) &&
+      0 != (dbb = dynamic_cast<DataBucketBase*>(dobj))) {
+    // it is a symlink after all.
+    // Let's hard cast (and keep our fingers Xed)
+    m_ptr = static_cast<void*>(dbb->object());
+  } else {
 #ifndef NDEBUG
-            MsgStream msg(Athena::getMessageSvc(), SG_VARHANDLE_NAME);
-            if (msg.level() <= MSG::WARNING) {
-              msg << MSG::WARNING 
-                  << "this proxy " << MSG::hex << m_proxy
-                  << MSG::dec 
-                  << " [" << (m_proxy != 0 ? m_proxy->clID() : 0)
-                  << "/" << (m_proxy != 0 
-                             ? m_proxy->name() 
-                             : std::string("<N/A>"))
-                  << "] is in an invalid state" << endreq;
-            }
+    MsgStream msg(Athena::getMessageSvc(), SG_VARHANDLE_NAME);
+    if (msg.level() <= MSG::WARNING) {
+      msg << MSG::WARNING 
+          << "Request for an invalid object; requested CLID = " 
+          << clid 
+          << ", proxy primary ID is " << m_proxy->clID() 
+          << endreq;
+    }
 #endif
-    }
-    m_ptr = ptr;
-  }
+  } // try symlink -- endif
   return m_ptr;
 }
 #undef SG_VARHANDLE_NAME
 
-SG::DataProxy*
-VarHandleBase::retrieveProxyFromStore(CLID clid,
-                                      const std::string& name,
-                                      const std::string& store_name)
-{
-  ServiceHandle<IProxyDict> store(store_name, "SG::VarHandleBase");
-  return store->proxy(clid, name);
-}
+// SG::DataProxy*
+// VarHandleBase::retrieveProxyFromStore(CLID clid,
+//                                       const std::string& name,
+//                                       const std::string& store_name)
+// {
+//   ServiceHandle<IProxyDict> store(store_name, "SG::VarHandleBase");
+//   return store->proxy(clid, name);
+// }
 
 } /* namespace SG */

src/VarHandleProperty.cxx

+///////////////////////// -*- C++ -*- /////////////////////////////
+// VarHandleProperty.cxx 
+// Implementation file for class VarHandleProperty
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// stl includes
+#include <sstream>
+#include <map>
+
+// StoreGate includes
+#include "StoreGate/VarHandleProperty.h"
+
+namespace Gaudi { 
+namespace Parsers {
+
+StatusCode 
+parse(SG::VarHandleBase& v, const std::string& s)
+{
+  std::map<std::string, std::string> vs;
+  // default values
+  vs["store"] = "StoreGateSvc";
+
+  if (Gaudi::Parsers::parse(vs, s).isSuccess()) {
+    v.m_sgkey = vs["key"];
+    v.m_store = vs["store"];
+    if (!vs["mode"].empty()) {
+      int mode = -1;
+      if (!Gaudi::Parsers::parse(mode, vs["mode"])) {
+        return StatusCode::FAILURE;
+      }
+      if (v.mode() != mode) {
+        return StatusCode::FAILURE;
+      }
+    }
+    return StatusCode::SUCCESS;
+  }
+
+  // try as a simple string, then.
+  if (!Gaudi::Parsers::parse(v.m_sgkey, s).isSuccess()) {
+    return StatusCode::FAILURE;
+  }
+  v.m_store = "StoreGateSvc";
+
+  return StatusCode::SUCCESS;
+}
+
+} //> ns Parsers
+
+namespace Utils {
+
+std::ostream& 
+toStream(const SG::VarHandleBase& v, std::ostream& o)
+{
+  o << "{"
+    << "\"key\": \"" << v.name() << "\", "
+    << "\"store\": \"" << v.store() << "\", "
+    << "\"mode\": \"" << v.mode() << "\", "
+    << "\"clid\": \"" << v.clid() << "\", "
+    << "}";
+  return o;
+}
+    
+} //> ns Utils
+
+} //> ns Gaudi
+
+
+VarHandleProperty::VarHandleProperty( const std::string& name, 
+                                      SG::VarHandleBase& ref )
+  : Property( name, typeid( SG::VarHandleBase ) ), 
+    m_pValue( &ref ) 
+{}
+
+VarHandleProperty::~VarHandleProperty()
+{}
+
+StatusCode 
+VarHandleProperty::fromString(const std::string& s)
+{
+  if (!Gaudi::Parsers::parse(*m_pValue, s).isSuccess()) {
+    return StatusCode::FAILURE;
+  }
+  return useUpdateHandler()
+    ? StatusCode::SUCCESS
+    : StatusCode::FAILURE;
+}
+
+bool
+VarHandleProperty::setValue( const SG::VarHandleBase& value ) 
+{
+  m_pValue->operator=(value);
+  return useUpdateHandler();
+}
+
+std::string
+VarHandleProperty::toString( ) const 
+{
+  useReadHandler();
+  std::ostringstream o;
+  Gaudi::Utils::toStream(*m_pValue, o);
+  return o.str();
+}
+
+void
+VarHandleProperty::toStream(std::ostream& out) const
+{
+  useReadHandler();
+  out << this->toString();
+}
+