From c26c647f5b5e824210acaf6b6e2092b88c598e3d Mon Sep 17 00:00:00 2001
From: Scott Snyder <scott.snyder@cern.ch>
Date: Mon, 13 May 2024 10:32:09 +0200
Subject: [PATCH] StoreGate: Add ReadDecorHandle::withDefault.

StoreGate: Add ReadDecorHandle::withDefault.

Add withDefault() method to ReadDecorHandle.  This works like operator(),
except that one specifies a default value to return if the variable
is not available.  This allows removing some instances of isAvailable().
---
 Control/StoreGate/StoreGate/ReadDecorHandle.h | 24 +++++++++++-
 .../StoreGate/StoreGate/ReadDecorHandle.icc   | 39 ++++++++++++++++++-
 .../StoreGate/test/ReadDecorHandle_test.cxx   |  6 ++-
 3 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/Control/StoreGate/StoreGate/ReadDecorHandle.h b/Control/StoreGate/StoreGate/ReadDecorHandle.h
index 3824790832cc..9377996c2c7a 100644
--- a/Control/StoreGate/StoreGate/ReadDecorHandle.h
+++ b/Control/StoreGate/StoreGate/ReadDecorHandle.h
@@ -1,6 +1,6 @@
 // This file's extension implies that it's C, but it's really -*- C++ -*-.
 /*
- * Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration.
+ * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
  */
 /**
  * @file StoreGate/ReadDecorHandle.h
@@ -176,6 +176,28 @@ public:
   const_reference_type operator() (const AuxElement& e) const;
 
 
+  /**
+   * @brief Fetch the variable for one element, as a const reference.
+   * @param index The index of the desired element.
+   * @param deflt Default value.
+   *
+   * This looks up the variable in the object referenced by this handle.
+   * For a standalone object, pass an index of 0.
+   * If this variable is not available, then return @c deflt instead.
+   */
+  const_reference_type withDefault (size_t index, const D& deflt);
+
+
+  /**
+   * @brief Fetch the variable for one element, as a const reference.
+   * @param e The element for which to fetch the variable.
+   * @param deflt Default value.
+   *
+   * If this variable is not available, then return @c deflt instead.
+   */
+  const_reference_type withDefault (const AuxElement& e, const D& deflt) const;
+
+
   /**
    * @brief Fetch the variable for one element, as a const reference.
    * @param index The index of the desired element.
diff --git a/Control/StoreGate/StoreGate/ReadDecorHandle.icc b/Control/StoreGate/StoreGate/ReadDecorHandle.icc
index 9981320e5aa2..934858a939d0 100644
--- a/Control/StoreGate/StoreGate/ReadDecorHandle.icc
+++ b/Control/StoreGate/StoreGate/ReadDecorHandle.icc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration.
+ * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
  */
 /**
  * @file StoreGate/ReadDecorHandle.icc
@@ -151,6 +151,43 @@ ReadDecorHandle<T, D>::operator() (size_t i)
 }
 
 
+/**
+ * @brief Fetch the variable for one element, as a const reference.
+ * @param e The element for which to fetch the variable.
+ * @param deflt Default value.
+ *
+ * If this variable is not available, then return @c deflt instead.
+ */
+template <class T, class D>
+inline
+typename ReadDecorHandle<T, D>::const_reference_type
+ReadDecorHandle<T, D>::withDefault (const AuxElement& e, const D& deflt) const
+{
+  // FIXME?  In principle, should check here that E is actually an element
+  // of our declared container.  But that would force a SG lookup here
+  // which we otherwise wouldn't need to do.
+  return m_acc.withDefault (e, deflt);
+}
+
+
+/**
+ * @brief Fetch the variable for one element, as a const reference.
+ * @param index The index of the desired element.
+ * @param deflt Default value.
+ *
+ * This looks up the variable in the object referenced by this handle.
+ * For a standalone object, pass an index of 0.
+ * If this variable is not available, then return @c deflt instead.
+ */
+template <class T, class D>
+inline
+typename ReadDecorHandle<T, D>::const_reference_type
+ReadDecorHandle<T, D>::withDefault (size_t i, const D& deflt)
+{
+  return m_acc.withDefault (*this->vectorData(), i, deflt);
+}
+
+
 /**
  * @brief Get a pointer to the start of the auxiliary data array.
  *        for the referenced object.
diff --git a/Control/StoreGate/test/ReadDecorHandle_test.cxx b/Control/StoreGate/test/ReadDecorHandle_test.cxx
index dd3ff9e6478a..0cf919032001 100644
--- a/Control/StoreGate/test/ReadDecorHandle_test.cxx
+++ b/Control/StoreGate/test/ReadDecorHandle_test.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 /**
  * @file StoreGate/test/ReadDecorHandle_test.cxx
@@ -218,6 +218,8 @@ void test3()
   assert (h1.auxid() == ityp);
   assert (h1.isPresent());
   assert (!h1.isAvailable());
+  assert (h1.withDefault(1, -1) == -1);
+  assert (h1.withDefault(*(*pcont)[0], -1) == -1);
 
   MyObj::Decorator<int> adec ("aaa");
   adec (*(*pcont)[0]) = 10;
@@ -229,6 +231,8 @@ void test3()
   assert (h1 (2) == 12);
   assert (h1.getDataArray()[0] == 10);
   assert (h1.getDataSpan()[0] == 10);
+  assert (h1.withDefault(1, -1) == 11);
+  assert (h1.withDefault(*(*pcont)[0], -1) == 10);
 
   // Test case of no alias.
   SG::ReadDecorHandleKey<MyObjCont> k2 ("foo.bbb");
-- 
GitLab