From a06a35c7d50c4c70511a7506b26d11b94a3bbdf4 Mon Sep 17 00:00:00 2001
From: Scott Snyder <scott.snyder@cern.ch>
Date: Tue, 24 Jan 2017 21:23:52 +0100
Subject: [PATCH] Avoid potential vector overrun in
 AuxContainerBase::insertMove. (xAODCore-00-01-27)

	* Tagging xAODCore-00-01-27.
	* Root/AuxContainerBase.cxx: Avoid potential vector overrun in
	AuxContainerBase::insertMove.

	* Tagging xAODCore-00-01-26.
	* xAODCore/tools/AuxPersVector.h: Rework to use
	SG::AuxTypeVectorHolder.
	* xAODCore/AuxContainerBase.h, Root/AuxContainerBase.cxx:
	Implement insertMove.
	* test/ut_xaodcore_auxcontainerbase_test.cxx,
	share/ut_xaodcore_auxcontainerbase_test.ref: Add unit test for
	insertMove.
	* xAODCore/tools/AuxPersInfo.h: Add insertMove stub.
	* xAODCore/AuxInfoBase.h, Root/AuxInfoBase.cxx: Add insertMove
	stub.
	* xAODCore/ShallowAuxContainer.h, Root/ShallowAuxContainer.cxx:
	Likewise.


Former-commit-id: 1d44f0535fd9595fbb8f91cbfb60a34c0719dc1e
---
 Event/xAOD/xAODCore/CMakeLists.txt            |   6 +-
 Event/xAOD/xAODCore/Root/AuxContainerBase.cxx |  53 +++++-
 Event/xAOD/xAODCore/Root/AuxInfoBase.cxx      |  20 ++-
 .../xAODCore/Root/ShallowAuxContainer.cxx     |  11 +-
 Event/xAOD/xAODCore/cmt/requirements          |   3 +-
 .../ut_xaodcore_auxcontainerbase_test.ref     |   1 +
 .../ut_xaodcore_auxcontainerbase_test.cxx     | 170 ++++++++++++++++++
 .../xAOD/xAODCore/xAODCore/AuxContainerBase.h |  10 +-
 Event/xAOD/xAODCore/xAODCore/AuxInfoBase.h    |  10 +-
 .../xAODCore/xAODCore/ShallowAuxContainer.h   |  12 +-
 .../xAODCore/xAODCore/tools/AuxPersInfo.h     |  11 +-
 .../xAODCore/xAODCore/tools/AuxPersVector.h   |  63 +------
 12 files changed, 295 insertions(+), 75 deletions(-)
 create mode 100644 Event/xAOD/xAODCore/share/ut_xaodcore_auxcontainerbase_test.ref
 create mode 100644 Event/xAOD/xAODCore/test/ut_xaodcore_auxcontainerbase_test.cxx

diff --git a/Event/xAOD/xAODCore/CMakeLists.txt b/Event/xAOD/xAODCore/CMakeLists.txt
index b87feafcb50..f55259014c4 100644
--- a/Event/xAOD/xAODCore/CMakeLists.txt
+++ b/Event/xAOD/xAODCore/CMakeLists.txt
@@ -1,4 +1,4 @@
-# $Id: CMakeLists.txt 789425 2016-12-13 10:50:12Z krasznaa $
+# $Id: CMakeLists.txt 793737 2017-01-24 20:11:10Z ssnyder $
 ################################################################################
 # Package: xAODCore
 ################################################################################
@@ -72,6 +72,10 @@ atlas_add_test( ut_xaodcore_safedeepcopy_test
    SOURCES test/ut_xaodcore_safedeepcopy_test.cxx
    LINK_LIBRARIES AthContainers xAODCore )
 
+atlas_add_test( ut_xaodcore_auxcontainerbase_test
+   SOURCES test/ut_xaodcore_auxcontainerbase_test.cxx
+   LINK_LIBRARIES AthContainers xAODCore )
+
 if( XAOD_STANDALONE )
    atlas_add_test( ut_xaodcore_shallowcopy_test
       SOURCES test/ut_xaodcore_shallowcopy.cxx
diff --git a/Event/xAOD/xAODCore/Root/AuxContainerBase.cxx b/Event/xAOD/xAODCore/Root/AuxContainerBase.cxx
index 12abc0dbd6a..7be0679b21c 100644
--- a/Event/xAOD/xAODCore/Root/AuxContainerBase.cxx
+++ b/Event/xAOD/xAODCore/Root/AuxContainerBase.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: AuxContainerBase.cxx 793264 2017-01-20 18:52:30Z ssnyder $
+// $Id: AuxContainerBase.cxx 793746 2017-01-24 21:23:52Z ssnyder $
 
 // System include(s):
 #include <iostream>
@@ -482,6 +482,57 @@ namespace xAOD {
    }
 
 
+   bool AuxContainerBase::insertMove( size_t pos,
+                                      IAuxStore& other,
+                                      const SG::auxid_set_t& ignore_in ) {
+      // Guard against multi-threaded execution:
+      guard_t guard( m_mutex );
+
+      // This operation is not allowed on a locked container:
+      if( m_locked ) {
+         throw SG::ExcStoreLocked( "insertMove" );
+      }
+
+      const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
+      bool nomove = true;
+      size_t other_size = other.size();
+
+      SG::auxid_set_t ignore = ignore_in;
+      
+      // Do the operation on the static variables:
+      for (SG::auxid_t id : m_auxids) {
+        SG::IAuxTypeVector* v_dst = nullptr;
+        if (id < m_vecs.size())
+          v_dst = m_vecs[id];
+        if (v_dst) {
+          ignore.insert (id);
+          if (other.getData (id)) {
+            void* src_ptr = other.getData (id, other_size, other_size);
+            if (src_ptr) {
+              if (!v_dst->insertMove (pos, src_ptr,
+                                      reinterpret_cast<char*>(src_ptr) + other_size*r.getEltSize(id)))
+                nomove = false;
+            }
+          }
+          else {
+            const void* orig = v_dst->toPtr();
+            v_dst->shift (pos, other_size);
+            if (orig != v_dst->toPtr())
+              nomove = false;
+          }
+        }
+      }
+
+      // Do the operation on the dynamic variables:
+      if( m_store ) {
+        if (!m_store->insertMove( pos, other, ignore ))
+          nomove = false;
+      }
+
+      return nomove;
+   }
+
+
    bool AuxContainerBase::setOption( auxid_t id,
                                      const SG::AuxDataOption& option ) {
 
diff --git a/Event/xAOD/xAODCore/Root/AuxInfoBase.cxx b/Event/xAOD/xAODCore/Root/AuxInfoBase.cxx
index 188fc902067..ee7dd21d7d8 100644
--- a/Event/xAOD/xAODCore/Root/AuxInfoBase.cxx
+++ b/Event/xAOD/xAODCore/Root/AuxInfoBase.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: AuxInfoBase.cxx 793264 2017-01-20 18:52:30Z ssnyder $
+// $Id: AuxInfoBase.cxx 793737 2017-01-24 20:11:10Z ssnyder $
 
 // System include(s):
 #include <iostream>
@@ -483,6 +483,24 @@ namespace xAOD {
    }
 
 
+   bool AuxInfoBase::insertMove( size_t /*pos*/, IAuxStore& /*other*/,
+                                 const SG::auxid_set_t& /*ignore*/ ) {
+
+      // Guard against multi-threaded execution:
+      guard_t guard( m_mutex );
+
+      // Check if the container is locked:
+      if( m_locked ) {
+         throw SG::ExcStoreLocked( "insertMove" );
+      }
+
+      // We are just not allowed to do this...
+      throw std::runtime_error( "Calling insertMove on a non-vector" );
+
+      return false;
+   }
+
+
    bool AuxInfoBase::setOption( auxid_t id, const SG::AuxDataOption& option ) {
 
       if (id < m_vecs.size() && m_vecs[id] != 0)
diff --git a/Event/xAOD/xAODCore/Root/ShallowAuxContainer.cxx b/Event/xAOD/xAODCore/Root/ShallowAuxContainer.cxx
index 448009913fc..dbb29b3717b 100644
--- a/Event/xAOD/xAODCore/Root/ShallowAuxContainer.cxx
+++ b/Event/xAOD/xAODCore/Root/ShallowAuxContainer.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: ShallowAuxContainer.cxx 793264 2017-01-20 18:52:30Z ssnyder $
+// $Id: ShallowAuxContainer.cxx 793737 2017-01-24 20:11:10Z ssnyder $
 
 // System include(s):
 #include <iostream>
@@ -376,6 +376,15 @@ namespace xAOD {
                                 "container" );
    }
 
+   bool ShallowAuxContainer::insertMove( size_t /*pos*/,
+                                         IAuxStore& /*other*/,
+                                         const SG::auxid_set_t& /*ignore*/) {
+
+      // Nope, not allowed...
+      throw std::runtime_error( "Trying to call insertMove on a shallow copy "
+                                "container" );
+   }
+
    //
    /////////////////////////////////////////////////////////////////////////////
 
diff --git a/Event/xAOD/xAODCore/cmt/requirements b/Event/xAOD/xAODCore/cmt/requirements
index f23aecaad2c..4a27b8c719f 100644
--- a/Event/xAOD/xAODCore/cmt/requirements
+++ b/Event/xAOD/xAODCore/cmt/requirements
@@ -1,5 +1,5 @@
 package xAODCore
-# $Id: requirements 767088 2016-08-09 14:55:40Z wlampl $
+# $Id: requirements 793737 2017-01-24 20:11:10Z ssnyder $
 
 author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
 
@@ -49,3 +49,4 @@ apply_pattern have_root_headers root_headers="tools/ReadStats.h \
 use TestTools               TestTools-*               AtlasTest
 apply_pattern UnitTest_run unit_test=ut_xaodcore_auxselection
 apply_pattern UnitTest_run unit_test=ut_xaodcore_printhelpers
+apply_pattern UnitTest_run unit_test=ut_xaodcore_auxcontainerbase
diff --git a/Event/xAOD/xAODCore/share/ut_xaodcore_auxcontainerbase_test.ref b/Event/xAOD/xAODCore/share/ut_xaodcore_auxcontainerbase_test.ref
new file mode 100644
index 00000000000..a5bce3fd256
--- /dev/null
+++ b/Event/xAOD/xAODCore/share/ut_xaodcore_auxcontainerbase_test.ref
@@ -0,0 +1 @@
+test1
diff --git a/Event/xAOD/xAODCore/test/ut_xaodcore_auxcontainerbase_test.cxx b/Event/xAOD/xAODCore/test/ut_xaodcore_auxcontainerbase_test.cxx
new file mode 100644
index 00000000000..b487fd31474
--- /dev/null
+++ b/Event/xAOD/xAODCore/test/ut_xaodcore_auxcontainerbase_test.cxx
@@ -0,0 +1,170 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file xAODCore/test/AuxContainerBase_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Unit tests for AuxContainerBase.  (sadly incomplete)
+ */
+
+
+#undef NDEBUG
+#include "xAODCore/AuxContainerBase.h"
+#include <iostream>
+#include <sstream>
+#include <cassert>
+
+
+struct MoveTest
+{
+  MoveTest(int x=0) : m_v(x) {}
+  MoveTest(const MoveTest& other): m_v (other.m_v) {}
+  MoveTest(MoveTest&& other): m_v (std::move(other.m_v)) {}
+  MoveTest& operator= (const MoveTest& other) {
+    if (this != &other) m_v = other.m_v;
+    return *this;
+  }
+  MoveTest& operator= (MoveTest&& other) {
+    if (this != &other) m_v = std::move(other.m_v);
+    return *this;
+  }
+  std::vector<int> m_v;
+  bool operator== (const MoveTest& other) const { return m_v.size() == other.m_v.size(); }
+};
+
+
+bool wasMoved (const MoveTest& x) { return x.m_v.empty(); }
+
+
+class AuxContainerTest
+  : public xAOD::AuxContainerBase
+{
+public:
+  AuxContainerTest();
+
+  std::vector<int> i1;
+  std::vector<MoveTest> m1;
+};
+
+
+AuxContainerTest::AuxContainerTest()
+{
+  AUX_VARIABLE(i1);
+  AUX_VARIABLE(m1);
+}
+
+
+// Test insertMove.
+void test1()
+{
+  std::cout << "test1\n";
+
+  SG::auxid_t ityp1 = SG::AuxTypeRegistry::instance().getAuxID<int> ("i1");
+  SG::auxid_t ityp2 = SG::AuxTypeRegistry::instance().getAuxID<int> ("i2");
+  SG::auxid_t ityp3 = SG::AuxTypeRegistry::instance().getAuxID<int> ("i3");
+  SG::auxid_t ityp4 = SG::AuxTypeRegistry::instance().getAuxID<int> ("i4");
+  SG::auxid_t mtyp1 = SG::AuxTypeRegistry::instance().getAuxID<MoveTest> ("m1");
+  AuxContainerTest s1;
+  s1.reserve(20);
+  s1.resize(5);
+
+  int* i1 = reinterpret_cast<int*> (s1.getData(ityp1, 5, 20));
+  int* i2 = reinterpret_cast<int*> (s1.getData(ityp2, 5, 20));
+  MoveTest* m1 = reinterpret_cast<MoveTest*> (s1.getData(mtyp1, 5, 20));
+
+  for (int i=0; i<5; i++) {
+    i1[i] = i;
+    i2[i] = i+100;
+    m1[i] = MoveTest(i);
+  }
+
+  AuxContainerTest s2;
+  s2.resize(5);
+
+  int* i1_2 = reinterpret_cast<int*> (s2.getData(ityp1, 5, 5));
+  int* i3_2 = reinterpret_cast<int*> (s2.getData(ityp3, 5, 5));
+  int* i4_2 = reinterpret_cast<int*> (s2.getData(ityp4, 5, 5));
+  MoveTest* m1_2 = reinterpret_cast<MoveTest*> (s2.getData(mtyp1, 5, 5));
+  for (int i=0; i<5; i++) {
+    i1_2[i] = i+10;
+    i3_2[i] = i+110;
+    i4_2[i] = i+210;
+    m1_2[i] = MoveTest(i+10);
+  }
+
+  SG::auxid_set_t ignore { ityp4 };
+  assert (! s1.insertMove (3, s2, ignore)); // false due to added vbl
+  assert (s1.size() == 10);
+  s1.reserve(20);
+  assert (s1.getData(ityp4) == nullptr);
+  const int* i3 = reinterpret_cast<const int*> (s1.getData(ityp3));
+  assert (i3 != 0);
+  for (int i=0; i<3; i++) {
+    assert (i1[i] == i);
+    assert (i2[i] == i+100);
+    assert (i3[i] == 0);
+    assert (m1[i] == MoveTest(i));
+  }
+  for (int i=0; i<5; i++) {
+    assert (i1[3+i] == i+10);
+    assert (i2[3+i] == 0);
+    assert (i3[3+i] == i+110);
+    assert (m1[3+i] == MoveTest(i+10));
+  }
+  for (int i=3; i<5; i++) {
+    assert (i1[5+i] == i);
+    assert (i2[5+i] == i+100);
+    assert (i3[5+i] == 0);
+    assert (m1[5+i] == MoveTest(i));
+  }
+  for (int i=0; i<5; i++) {
+    assert (wasMoved (m1_2[i]));
+  }
+
+  for (int i=0; i<5; i++) {
+    i1_2[i] = i+20;
+    i3_2[i] = i+120;
+    m1_2[i] = MoveTest(i+20);
+  }
+  assert (s1.insertMove (10, s2, ignore));
+  assert (s1.size() == 15);
+  for (int i=0; i<3; i++) {
+    assert (i1[i] == i);
+    assert (i2[i] == i+100);
+    assert (i3[i] == 0);
+    assert (m1[i] == MoveTest(i));
+  }
+  for (int i=0; i<5; i++) {
+    assert (i1[3+i] == i+10);
+    assert (i2[3+i] == 0);
+    assert (i3[3+i] == i+110);
+    assert (m1[3+i] == MoveTest(i+10));
+  }
+  for (int i=3; i<5; i++) {
+    assert (i1[5+i] == i);
+    assert (i2[5+i] == i+100);
+    assert (i3[5+i] == 0);
+    assert (m1[5+i] == MoveTest(i));
+  }
+  for (int i=0; i<5; i++) {
+    assert (i1[10+i] == i+20);
+    assert (i2[10+i] == 0);
+    assert (i3[10+i] == i+120);
+    assert (m1[10+i] == MoveTest(i+20));
+  }
+  for (int i=0; i<5; i++) {
+    assert (wasMoved (m1_2[i]));
+  }
+
+  assert (s1.getStore()->getAuxIDs() == (SG::auxid_set_t {ityp2, ityp3}));
+}
+
+
+int main()
+{
+  test1();
+  return 0;
+}
diff --git a/Event/xAOD/xAODCore/xAODCore/AuxContainerBase.h b/Event/xAOD/xAODCore/xAODCore/AuxContainerBase.h
index e322638f797..23f620bd1e4 100644
--- a/Event/xAOD/xAODCore/xAODCore/AuxContainerBase.h
+++ b/Event/xAOD/xAODCore/xAODCore/AuxContainerBase.h
@@ -4,7 +4,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: AuxContainerBase.h 793264 2017-01-20 18:52:30Z ssnyder $
+// $Id: AuxContainerBase.h 793737 2017-01-24 20:11:10Z ssnyder $
 #ifndef XAODCORE_AUXCONTAINERBASE_H
 #define XAODCORE_AUXCONTAINERBASE_H
 
@@ -42,8 +42,8 @@ namespace xAOD {
    ///
    /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
    ///
-   /// $Revision: 793264 $
-   /// $Date: 2017-01-20 19:52:30 +0100 (Fri, 20 Jan 2017) $
+   /// $Revision: 793737 $
+   /// $Date: 2017-01-24 21:11:10 +0100 (Tue, 24 Jan 2017) $
    ///
    class AuxContainerBase : public SG::IAuxStore,
                             public SG::IAuxStoreIO,
@@ -123,6 +123,10 @@ namespace xAOD {
       virtual void reserve( size_t size );
       /// Shift the contents of the stored arrays
       virtual void shift( size_t pos, ptrdiff_t offs );
+      /// Insert contents of another store via move.
+      virtual bool insertMove (size_t pos,
+                               IAuxStore& other,
+                               const SG::auxid_set_t& ignore);
       /// Make an option setting on an aux variable.
       virtual bool setOption( auxid_t id, const SG::AuxDataOption& option );
 
diff --git a/Event/xAOD/xAODCore/xAODCore/AuxInfoBase.h b/Event/xAOD/xAODCore/xAODCore/AuxInfoBase.h
index 4084bc19390..03bf8b0a761 100644
--- a/Event/xAOD/xAODCore/xAODCore/AuxInfoBase.h
+++ b/Event/xAOD/xAODCore/xAODCore/AuxInfoBase.h
@@ -4,7 +4,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: AuxInfoBase.h 793264 2017-01-20 18:52:30Z ssnyder $
+// $Id: AuxInfoBase.h 793737 2017-01-24 20:11:10Z ssnyder $
 #ifndef XAODCORE_AUXINFOBASE_H
 #define XAODCORE_AUXINFOBASE_H
 
@@ -39,8 +39,8 @@ namespace xAOD {
    ///
    /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
    ///
-   /// $Revision: 793264 $
-   /// $Date: 2017-01-20 19:52:30 +0100 (Fri, 20 Jan 2017) $
+   /// $Revision: 793737 $
+   /// $Date: 2017-01-24 21:11:10 +0100 (Tue, 24 Jan 2017) $
    ///
    class AuxInfoBase : public SG::IAuxStore,
                        public SG::IAuxStoreIO,
@@ -120,6 +120,10 @@ namespace xAOD {
       virtual void reserve( size_t size );
       /// Shift the contents of the stored arrays
       virtual void shift( size_t pos, ptrdiff_t offs );
+      /// Insert contents of another store via move.
+      virtual bool insertMove (size_t pos,
+                               IAuxStore& other,
+                               const SG::auxid_set_t& ignore);
       /// Make an option setting on an aux variable.
       virtual bool setOption( auxid_t id, const SG::AuxDataOption& option );
 
diff --git a/Event/xAOD/xAODCore/xAODCore/ShallowAuxContainer.h b/Event/xAOD/xAODCore/xAODCore/ShallowAuxContainer.h
index 92a146ce8ec..8c24e7312c0 100644
--- a/Event/xAOD/xAODCore/xAODCore/ShallowAuxContainer.h
+++ b/Event/xAOD/xAODCore/xAODCore/ShallowAuxContainer.h
@@ -4,7 +4,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: ShallowAuxContainer.h 793264 2017-01-20 18:52:30Z ssnyder $
+// $Id: ShallowAuxContainer.h 793737 2017-01-24 20:11:10Z ssnyder $
 #ifndef XAODCORE_SHALLOWAUXCONTAINER_H
 #define XAODCORE_SHALLOWAUXCONTAINER_H
 
@@ -41,8 +41,8 @@ namespace xAOD {
    ///
    /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
    ///
-   /// $Revision: 793264 $
-   /// $Date: 2017-01-20 19:52:30 +0100 (Fri, 20 Jan 2017) $
+   /// $Revision: 793737 $
+   /// $Date: 2017-01-24 21:11:10 +0100 (Tue, 24 Jan 2017) $
    ///
    class ShallowAuxContainer : public SG::IAuxStore,
                                public SG::IAuxStoreIO,
@@ -128,7 +128,11 @@ namespace xAOD {
       virtual void reserve( size_t size );
       /// Shift the contents of the stored arrays
       virtual void shift( size_t pos, ptrdiff_t offs );
-
+      /// Insert contents of another store via move.
+      virtual bool insertMove (size_t pos,
+                               IAuxStore& other,
+                               const SG::auxid_set_t& ignore);
+ 
       /// @}
 
       /// @name Functions implementing the SG::IAuxStoreIO interface
diff --git a/Event/xAOD/xAODCore/xAODCore/tools/AuxPersInfo.h b/Event/xAOD/xAODCore/xAODCore/tools/AuxPersInfo.h
index 9fe18ef6454..65618a97ff2 100644
--- a/Event/xAOD/xAODCore/xAODCore/tools/AuxPersInfo.h
+++ b/Event/xAOD/xAODCore/xAODCore/tools/AuxPersInfo.h
@@ -4,7 +4,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: AuxPersInfo.h 793264 2017-01-20 18:52:30Z ssnyder $
+// $Id: AuxPersInfo.h 793737 2017-01-24 20:11:10Z ssnyder $
 #ifndef XAODCORE_TOOLS_AUXPERSINFO_H
 #define XAODCORE_TOOLS_AUXPERSINFO_H
 
@@ -24,8 +24,8 @@ namespace xAOD {
    ///
    /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
    ///
-   /// $Revision: 793264 $
-   /// $Date: 2017-01-20 19:52:30 +0100 (Fri, 20 Jan 2017) $
+   /// $Revision: 793737 $
+   /// $Date: 2017-01-24 21:11:10 +0100 (Tue, 24 Jan 2017) $
    ///
    template< class T >
    class AuxPersInfo : public SG::IAuxTypeVector {
@@ -67,6 +67,11 @@ namespace xAOD {
          throw std::runtime_error( "Calling shift on a non-vector" );
       }
 
+      virtual bool insertMove (size_t /*pos*/, void* /*beg*/, void* /*end*/)
+      {
+        throw std::runtime_error( "Calling insertMove on a non-vector" );
+      }
+     
       virtual const std::type_info* objType() const {
          return &typeid(T);
       }
diff --git a/Event/xAOD/xAODCore/xAODCore/tools/AuxPersVector.h b/Event/xAOD/xAODCore/xAODCore/tools/AuxPersVector.h
index 5adb1315aec..cba85065d1b 100644
--- a/Event/xAOD/xAODCore/xAODCore/tools/AuxPersVector.h
+++ b/Event/xAOD/xAODCore/xAODCore/tools/AuxPersVector.h
@@ -4,7 +4,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: AuxPersVector.h 793264 2017-01-20 18:52:30Z ssnyder $
+// $Id: AuxPersVector.h 793737 2017-01-24 20:11:10Z ssnyder $
 #ifndef XAODCORE_AUXPERSVECTOR_H
 #define XAODCORE_AUXPERSVECTOR_H
 
@@ -23,75 +23,24 @@ namespace xAOD {
    ///
    /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
    ///
-   /// $Revision: 793264 $
-   /// $Date: 2017-01-20 19:52:30 +0100 (Fri, 20 Jan 2017) $
+   /// $Revision: 793737 $
+   /// $Date: 2017-01-24 21:11:10 +0100 (Tue, 24 Jan 2017) $
    ///
    template< class T, class VEC=std::vector< T > >
-   class AuxPersVector : public SG::IAuxTypeVector {
+   class AuxPersVector : public SG::AuxTypeVectorHolder<T, VEC> {
 
    public:
       /// Convenience type definition
       typedef VEC& vector_type;
 
       /// Constructor
-      AuxPersVector( vector_type vec ) : m_vec( vec ) {}
+      AuxPersVector( vector_type vec )
+        : SG::AuxTypeVectorHolder<T, VEC> (&vec, false) {}
 
       virtual SG::IAuxTypeVector* clone() const {
         return new AuxPersVector<T, VEC>(*this);
       }
 
-      virtual void* toPtr() {
-         if (m_vec.empty())
-           return 0;
-         return m_vec.data();
-      }
-      virtual void* toVector() {
-         return &m_vec;
-      }
-      virtual size_t size() const {
-         return m_vec.size();
-      }
-      virtual bool resize( size_t sz ) {
-         const void* orig = toPtr();
-         m_vec.resize( sz );
-         return toPtr() == orig;
-      }
-      virtual void reserve( size_t sz ) {
-         m_vec.reserve( sz );
-      }
-      virtual void shift( size_t pos, ptrdiff_t offs ) {
-         if (offs < 0) {
-            if (-offs > static_cast<off_t>(pos)) offs = -pos;
-            std::copy (m_vec.begin()+pos, m_vec.end(), m_vec.begin()+pos+offs);
-            m_vec.resize (m_vec.size() + offs);
-         }
-         else if (offs > 0) {
-            size_t oldsz = m_vec.size();
-            m_vec.resize (m_vec.size() + offs);
-            std::copy (m_vec.rbegin()+offs, m_vec.rbegin()+offs+oldsz-pos,
-                       m_vec.rbegin());
-            std::fill (m_vec.begin()+pos, m_vec.begin()+pos+offs, T());
-         }
-      }
-
-      virtual bool setOption (const SG::AuxDataOption& option) {
-         // Need to instantiate different functions depending on whether or not
-         // the payload implements @c SG::IAuxSetOption.
-         // From AuxTypeVector.icc
-         return DataModel_detail::setOptionHelper
-            (&m_vec,
-             option,
-             typename std::is_base_of<SG::IAuxSetOption,vector_type>::type());
-      }
-
-     virtual const std::type_info* objType() const {
-        return &typeid( VEC );
-     }
-
-   private:
-      /// Reference to the vector being handled
-      vector_type m_vec;
-
    }; // class AuxPersVector
 
 } // namespace xAOD
-- 
GitLab