diff --git a/Control/StoreGate/CMakeLists.txt b/Control/StoreGate/CMakeLists.txt index 62c77bf918c765255f5981ce25b7e09b9f1077e2..3178d246b37ec339c1a718b42b5ec0d7ecc943d7 100644 --- a/Control/StoreGate/CMakeLists.txt +++ b/Control/StoreGate/CMakeLists.txt @@ -168,6 +168,12 @@ atlas_add_test( WriteDecorHandle_test LINK_LIBRARIES StoreGateLib AthContainers TestTools ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) +atlas_add_test( CondHandleKeyArray_test + SOURCES test/CondHandleKeyArray_test.cxx + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} + LINK_LIBRARIES StoreGateLib AthContainers TestTools + ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) + # Install files from the package: atlas_install_python_modules( python/*.py ) atlas_install_joboptions( share/StoreGate_jobOptions.txt diff --git a/Control/StoreGate/StoreGate/CondHandleKeyArray.h b/Control/StoreGate/StoreGate/CondHandleKeyArray.h new file mode 100644 index 0000000000000000000000000000000000000000..e19bca9db63e7b4ed9079f919ad53a4c8069638b --- /dev/null +++ b/Control/StoreGate/StoreGate/CondHandleKeyArray.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef STOREGATE_CONDHANDLEKEYARRAY_H +#define STOREGATE_CONDHANDLEKEYARRAY_H 1 + +#include "StoreGate/HandleKeyArray.h" + +#include "StoreGate/ReadCondHandleKey.h" +#include "StoreGate/ReadCondHandle.h" +#include "StoreGate/WriteCondHandleKey.h" +#include "StoreGate/WriteCondHandle.h" + +namespace SG { + + namespace CondHandleDefault { + // need default constructor for VarHandleKeyArrayCommon<Base>::assign + template <class Base> + class Key : public Base { + public: + Key() : Base("") {} + + Key(std::string val) : Base(val) {} + + }; + } + + template <class T> + using ReadCondHandleKeyArray = HandleKeyArray<ReadCondHandle<T>, CondHandleDefault::Key<ReadCondHandleKey<T> >, Gaudi::DataHandle::Reader >; + + template <class T> + using WriteCondHandleKeyArray = HandleKeyArray<WriteCondHandle<T>,CondHandleDefault::Key<WriteCondHandleKey<T> >, Gaudi::DataHandle::Writer >; + +} // namespace SG + +#endif diff --git a/Control/StoreGate/StoreGate/HandleKeyArray.h b/Control/StoreGate/StoreGate/HandleKeyArray.h new file mode 100644 index 0000000000000000000000000000000000000000..2d8256f66ea6a36ff84050ed9ee3b1e0eeb6cd7f --- /dev/null +++ b/Control/StoreGate/StoreGate/HandleKeyArray.h @@ -0,0 +1,126 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef STOREGATE_HANDLEKEYARRAY_H +#define STOREGATE_HANDLEKEYARRAY_H 1 + +#include "StoreGate/VarHandleKeyArray.h" +#include "GaudiKernel/EventContext.h" + +#include <vector> +#include <string> + +namespace SG { + + /** + * @class SG::HandleKeyArray<T> + * @brief class to hold an array of HandleKeys + * + * since it inherits from std::vector, all vector operations are + * permitted. + * + * initialization can be done in three ways. + * 1: with an std::vector<HandleKey> as a parameter + * SG::Cond<foo>::ReadHandleKeyArray m_foo ( std::vector<ReadCondHandleKey> ); + * SG::Cond<foo>::WriteHandleKeyArray m_foo ( std::vector<WriteCondHandleKey> ); + * 2: with an initializer list of HandleKeys + * SG::Cond<foo>::ReadHandleKeyArray m_foo { ReadCondHandleKey<foo> k1, ReadCondHandleKey<foo> k2 }; + * SG::Cond<foo>::WriteHandleKeyArray m_foo { WriteCondHandleKey<foo> k1, WriteCondHandleKey<foo> k2 }; + * 3: with an initializer list of std::strings, that will be used to + * internally create HandleKeys with those initializers + * SG::Cond<foo>::ReadHandleKeyArray m_foo { "key1", "key2", "key3" }; + * SG::Cond<foo>::WriteHandleKeyArray m_foo { "key1", "key2", "key3" }; + */ + + template <class T_Handle, class T_HandleKey, Gaudi::DataHandle::Mode MODE> + class HandleKeyArray : public VarHandleKeyArrayCommon< T_HandleKey > { + public: + /** + * @brief default Constructor from a HandleKeyArray + */ + HandleKeyArray(){} + + /** + * @brief Constructor from a HandleKeyArray that takes a vector + * of ReadHandleKeys + * @param v vector of HandleKey + */ + HandleKeyArray( const std::vector<T_HandleKey>& v ) : + VarHandleKeyArrayCommon<T_HandleKey> ( v ) {} + + /** + * @brief Constructor from a HandleKeyArray that takes an + * initializer list of HandleKeys + * @param l initializer list of HandleKey + */ + HandleKeyArray( std::initializer_list<T_HandleKey> l ): + VarHandleKeyArrayCommon<T_HandleKey> {l} {} + + /** + * @brief Constructor from a HandleKeyArray that takes an + * initializer list of std::strings. + * @param l initializer list of std::strings used to create the + * HandleKeys + */ + HandleKeyArray( std::initializer_list<std::string> key_names): + VarHandleKeyArrayCommon<T_HandleKey> {key_names} {} + + /** + * @brief auto-declaring Property Constructor from a HandleKeyArray + * that takes an initializer list of std::strings, and associates the WHKA + * with the specified Property name + * @param name name of Property + * @param l initializer list of std::strings used to create the + * HandleKeys + * @param doc documentation string + */ + template <class OWNER, + typename = typename std::enable_if<std::is_base_of<IProperty, OWNER>::value>::type> + inline HandleKeyArray( OWNER* owner, + std::string name, + std::initializer_list<std::string> l, + std::string doc="") : + VarHandleKeyArrayCommon<T_HandleKey> {l} { + auto p = owner->declareProperty(std::move(name), *this, std::move(doc)); + p->template setOwnerType<OWNER>(); + } + + + /** + * @brief return the type (Read/Write/Update) of handle + */ + Gaudi::DataHandle::Mode mode() const { return MODE; } + + /** + * @brief create a vector of Handles from the HandleKeys + * in the array + */ + std::vector< T_Handle > makeHandles() const { + std::vector< T_Handle > hndl; + typename std::vector<T_HandleKey>::const_iterator itr; + for (itr = this->begin(); itr != this->end(); ++itr) { + hndl.push_back ( T_Handle( *itr) ); + } + return ( std::move( hndl ) ); + } + + /** + * @brief create a vector of Handles from the HandleKeys + * in the array, with explicit EventContext. + */ + std::vector< T_Handle > makeHandles (const EventContext& ctx) const + { + std::vector< T_Handle > hndl; + typename std::vector<T_HandleKey>::const_iterator itr; + for (itr = this->begin(); itr != this->end(); ++itr) { + hndl.push_back ( T_Handle( *itr, ctx) ); + } + return ( std::move( hndl ) ); + } + + }; + +} // namespace SG + +#endif diff --git a/Control/StoreGate/StoreGate/ReadHandleKeyArray.h b/Control/StoreGate/StoreGate/ReadHandleKeyArray.h index eba55f86312c65d868a45816e7d22e0758ad0712..1a60222a6edbf0f87e398491a284515b9afc949d 100644 --- a/Control/StoreGate/StoreGate/ReadHandleKeyArray.h +++ b/Control/StoreGate/StoreGate/ReadHandleKeyArray.h @@ -1,25 +1,22 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration */ #ifndef STOREGATE_READHANDLEKEYARRAY_H #define STOREGATE_READHANDLEKEYARRAY_H 1 -#include "StoreGate/VarHandleKeyArray.h" +#include "StoreGate/HandleKeyArray.h" #include "StoreGate/ReadHandleKey.h" #include "StoreGate/ReadHandle.h" -#include <vector> -#include <string> - namespace SG { /** * @class SG::ReadHandleKeyArray<T> * @brief class to hold an array of ReadHandleKeys * - * since it inherits from std::vector, all vector operations are + * since it inherits from std::vector, all vector operations are * permitted. * * initialization can be done in three ways. @@ -31,93 +28,8 @@ namespace SG { * internally create ReadHandleKeys with those initializers * SG::ReadHandleKeyArray<foo> m_foo { "key1", "key2", "key3" }; */ - template <class T> - class ReadHandleKeyArray : public VarHandleKeyArrayCommon< ReadHandleKey<T> > { - public: - /** - * @brief default Constructor from a ReadHandleKeyArray - */ - ReadHandleKeyArray(){}; - - /** - * @brief Constructor from a ReadHandleKeyArray that takes a vector - * of ReadHandleKeys - * @param v vector of ReadHandleKey - */ - ReadHandleKeyArray( const std::vector<ReadHandleKey<T>>& v ): - VarHandleKeyArrayCommon<ReadHandleKey<T>> ( v ) {}; - - /** - * @brief Constructor from a ReadHandleKeyArray that takes an - * initializer list of ReadHandleKeys - * @param l initializer list of ReadHandleKey - */ - ReadHandleKeyArray( std::initializer_list<ReadHandleKey<T>> l ): - VarHandleKeyArrayCommon<ReadHandleKey<T>> {l} {}; - - /** - * @brief Constructor from a ReadHandleKeyArray that takes an - * initializer list of std::strings. - * @param l initializer list of std::strings used to create the - * ReadHandleKeys - */ - ReadHandleKeyArray( std::initializer_list<std::string> l ): - VarHandleKeyArrayCommon<ReadHandleKey<T>> {l} {}; - - /** - * @brief auto-declaring Property Constructor from a ReadHandleKeyArray - * that takes an initializer list of std::strings, and associates the RHKA - * with the specified Property name - * @param name name of Property - * @param l initializer list of std::strings used to create the - * ReadHandleKeys - * @param doc documentation string - */ - template <class OWNER, - typename = typename std::enable_if<std::is_base_of<IProperty, OWNER>::value>::type> - inline ReadHandleKeyArray( OWNER* owner, - std::string name, - std::initializer_list<std::string> l, - std::string doc="") : - VarHandleKeyArrayCommon<ReadHandleKey<T>> {l} { - auto p = owner->declareProperty(std::move(name), *this, std::move(doc)); - p->template setOwnerType<OWNER>(); - } - - /** - * @brief return the type (Read/Write/Update) of handle - */ - Gaudi::DataHandle::Mode mode() const { return Gaudi::DataHandle::Reader; } - - /** - * @brief create a vector of ReadHandles from the ReadHandleKeys - * in the array - */ - std::vector< ReadHandle<T> > makeHandles() const { - std::vector< ReadHandle<T> > hndl; - typename std::vector<ReadHandleKey<T>>::const_iterator itr; - for (itr = this->begin(); itr != this->end(); ++itr) { - hndl.push_back ( ReadHandle<T>( *itr) ); - } - return ( std::move( hndl ) ); - } - - /** - * @brief create a vector of ReadHandles from the ReadHandleKeys - * in the array, with explicit EventContext. - */ - std::vector< ReadHandle<T> > makeHandles (const EventContext& ctx) const - { - std::vector< ReadHandle<T> > hndl; - typename std::vector<ReadHandleKey<T>>::const_iterator itr; - for (itr = this->begin(); itr != this->end(); ++itr) { - hndl.push_back ( ReadHandle<T>( *itr, ctx ) ); - } - return ( std::move( hndl ) ); - } - - }; + using ReadHandleKeyArray = HandleKeyArray<ReadHandle<T>, ReadHandleKey<T>, Gaudi::DataHandle::Reader >; } // namespace SG diff --git a/Control/StoreGate/StoreGate/WriteHandleKeyArray.h b/Control/StoreGate/StoreGate/WriteHandleKeyArray.h index 171184eef0c59060218a3c5d55c4fd619bd5e010..b45e1018e5871445aff4b2579c0024dd7b4bacdd 100644 --- a/Control/StoreGate/StoreGate/WriteHandleKeyArray.h +++ b/Control/StoreGate/StoreGate/WriteHandleKeyArray.h @@ -1,25 +1,22 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration */ #ifndef STOREGATE_WRITEHANDLEKEYARRAY_H #define STOREGATE_WRITEHANDLEKEYARRAY_H 1 -#include "StoreGate/VarHandleKeyArray.h" +#include "StoreGate/HandleKeyArray.h" #include "StoreGate/WriteHandleKey.h" #include "StoreGate/WriteHandle.h" -#include <vector> -#include <string> - namespace SG { /** * @class SG::WriteHandleKeyArray<T> * @brief class to hold an array of WriteHandleKeys * - * since it inherits from std::vector, all vector operations are + * since it inherits from std::vector, all vector operations are * permitted. * * initialization can be done in three ways. @@ -31,95 +28,8 @@ namespace SG { * internally create WriteHandleKeys with those initializers * SG::WriteHandleKeyArray<foo> m_foo { "key1", "key2", "key3" }; */ - template <class T> - class WriteHandleKeyArray : public VarHandleKeyArrayCommon< WriteHandleKey<T> > { - public: - /** - * @brief default Constructor from a WriteHandleKeyArray - */ - WriteHandleKeyArray(){}; - - /** - * @brief Constructor from a WriteHandleKeyArray that takes a vector - * of ReadHandleKeys - * @param v vector of WriteHandleKey - */ - WriteHandleKeyArray( const std::vector<WriteHandleKey<T>>& v ) : - VarHandleKeyArrayCommon<WriteHandleKey<T>> ( v ) {}; - - /** - * @brief Constructor from a WriteHandleKeyArray that takes an - * initializer list of WriteHandleKeys - * @param l initializer list of WriteHandleKey - */ - WriteHandleKeyArray( std::initializer_list<WriteHandleKey<T>> l ): - VarHandleKeyArrayCommon<WriteHandleKey<T>> {l} {}; - - /** - * @brief Constructor from a WriteHandleKeyArray that takes an - * initializer list of std::strings. - * @param l initializer list of std::strings used to create the - * WriteHandleKeys - */ - WriteHandleKeyArray( std::initializer_list<std::string> l ): - VarHandleKeyArrayCommon<WriteHandleKey<T>> {l} {}; - - /** - * @brief auto-declaring Property Constructor from a WriteHandleKeyArray - * that takes an initializer list of std::strings, and associates the WHKA - * with the specified Property name - * @param name name of Property - * @param l initializer list of std::strings used to create the - * WriteHandleKeys - * @param doc documentation string - */ - template <class OWNER, - typename = typename std::enable_if<std::is_base_of<IProperty, OWNER>::value>::type> - inline WriteHandleKeyArray( OWNER* owner, - std::string name, - std::initializer_list<std::string> l, - std::string doc="") : - VarHandleKeyArrayCommon<WriteHandleKey<T>> {l} { - auto p = owner->declareProperty(std::move(name), *this, std::move(doc)); - p->template setOwnerType<OWNER>(); - } - - - /** - * @brief return the type (Read/Write/Update) of handle - */ - Gaudi::DataHandle::Mode mode() const { return Gaudi::DataHandle::Writer; } - - /** - * @brief create a vector of WriteHandles from the WriteHandleKeys - * in the array - */ - std::vector< WriteHandle<T> > makeHandles() const { - std::vector< WriteHandle<T> > hndl; - typename std::vector<WriteHandleKey<T>>::const_iterator itr; - for (itr = this->begin(); itr != this->end(); ++itr) { - hndl.push_back ( WriteHandle<T>( *itr) ); - } - return ( std::move( hndl ) ); - } - - /** - * @brief create a vector of WriteHandles from the WriteHandleKeys - * in the array, with explicit EventContext. - */ - std::vector< WriteHandle<T> > makeHandles (const EventContext& ctx) const - { - std::vector< WriteHandle<T> > hndl; - typename std::vector<WriteHandleKey<T>>::const_iterator itr; - for (itr = this->begin(); itr != this->end(); ++itr) { - hndl.push_back ( WriteHandle<T>( *itr, ctx) ); - } - return ( std::move( hndl ) ); - } - - }; - + using WriteHandleKeyArray = HandleKeyArray<WriteHandle<T>,WriteHandleKey<T>, Gaudi::DataHandle::Writer >; } // namespace SG diff --git a/Control/StoreGate/test/CondHandleKeyArray_test.cxx b/Control/StoreGate/test/CondHandleKeyArray_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e8d44d6f6ce2ee676dd708b5f0df2f1aa91f4636 --- /dev/null +++ b/Control/StoreGate/test/CondHandleKeyArray_test.cxx @@ -0,0 +1,135 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @brief Compile tests for WriteCondHandleKeyArray + * @TODO extend to also test functionality + */ + + +#undef NDEBUG +#include "StoreGate/CondHandleKeyArray.h" +#include "StoreGate/exceptions.h" +#include "SGTools/TestStore.h" +#include "SGTools/CLASS_DEF.h" +#include "SGTools/StorableConversions.h" +#include "SGTools/DataProxy.h" +#include "TestTools/initGaudi.h" +#include "TestTools/expect_exception.h" +#include "AthContainersInterfaces/IConstAuxStore.h" +#include "AthContainers/DataVector.h" +#include "AthContainers/ConstDataVector.h" +#include "AthenaKernel/errorcheck.h" +#include "AthenaKernel/ExtendedEventContext.h" +#include "CxxUtils/unused.h" +#include <cassert> +#include <iostream> + +#define DEBUG_VHB 1 + + +class MyObjAux + : public SG::IConstAuxStore, public ILockable +{ +public: + MyObjAux(int x=0) : x(x) {} + ~MyObjAux() { deleted.push_back (x); } + int x; + bool m_locked = false; + + virtual const void* getData (SG::auxid_t /*auxid*/) const override { return 0; } + virtual void* getDecoration (SG::auxid_t /*auxid*/, size_t /*size*/, size_t /*capacity*/) override { return 0; } + virtual const SG::auxid_set_t& getAuxIDs() const override { std::abort(); } + virtual void lock() override { m_locked = true; } + virtual bool clearDecorations() override { return false; } + virtual size_t size() const override { return 0; } + virtual void lockDecoration (SG::auxid_t) override { std::abort(); } + + static std::vector<int> deleted; +}; +std::vector<int> MyObjAux::deleted; +CLASS_DEF (MyObjAux, 293847296, 1) + +class MyObj +{ +public: + MyObj(int x=0) : x(x) {} + ~MyObj() { deleted.push_back (x); } + SG::IAuxStore* getStore() const { return nullptr; } + void setStore (SG::IConstAuxStore* store) {aux = dynamic_cast<MyObjAux*>(store); } + int x; + MyObjAux* aux {nullptr}; + + static std::vector<int> deleted; +}; +std::vector<int> MyObj::deleted; +CLASS_DEF (MyObj, 293847295, 1) +static const CLID MyCLID = 293847295; + +#include "AthenaKernel/CondCont.h" +CONDCONT_DEF(MyObj, 223019562 ); + + +CLASS_DEF (DataVector<MyObj>, 293847495, 1) + + +class MyObj2 {}; +CLASS_DEF (MyObj2, 293847395, 1) + + +class MyDObj : public DataObject +{ +public: + MyDObj(int x=0) : x(x) {} + ~MyDObj() { deleted.push_back (x); } + int x; + + static std::vector<int> deleted; +}; +std::vector<int> MyDObj::deleted; +CLASS_DEF (MyDObj, 293847297, 1) + + +std::pair<std::unique_ptr<MyObj>, std::unique_ptr<MyObjAux> > +makeWithAux (int x=0) +{ + auto obj = std::make_unique<MyObj>(x); + auto aux = std::make_unique<MyObjAux>(x+100); + obj->setStore (aux.get()); + return std::make_pair (std::move(obj), std::move(aux)); +} + + + + +// Ctors. +void test1() +{ + std::cout << "test1\n"; + + SG::WriteCondHandleKeyArray<MyObj> k1 {"MyObj"}; + + assert ( k1.size() == 1); + assert ( k1.mode() == Gaudi::DataHandle::Writer); + assert ( k1[0].key() == "MyObj"); + // need to setup conditions store + /* assert ( */ k1[0].initialize() /* .isSuccess())*/ ; + + try { + std::vector<SG::WriteCondHandle<MyObj> > h1( k1.makeHandles() ); + assert (h1[0].key() == "MyObj"); + } + catch(...) { + } + +} + +int main() +{ + ISvcLocator* pDum; + Athena_test::initGaudi(pDum); //need MessageSvc + + test1(); + return 0; +}