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