diff --git a/GaudiAlg/include/GaudiAlg/FunctionalDetails.h b/GaudiAlg/include/GaudiAlg/FunctionalDetails.h index c0bd4e6c05849a1f5c3e3098b5f71d20db5990e1..7de44f2394fa172c8cfc0470eb98ca6524de0a19 100644 --- a/GaudiAlg/include/GaudiAlg/FunctionalDetails.h +++ b/GaudiAlg/include/GaudiAlg/FunctionalDetails.h @@ -144,13 +144,13 @@ namespace Gaudi::Functional::details { template <typename Out1, typename Out2, typename = std::enable_if_t<std::is_constructible_v<Out1, Out2> && std::is_base_of_v<DataObject, Out1>>> - Out1* put( const DataObjectHandle<Out1>& out_handle, Out2&& out ) { + auto put( const DataObjectHandle<Out1>& out_handle, Out2&& out ) { return out_handle.put( std::make_unique<Out1>( std::forward<Out2>( out ) ) ); } template <typename Out1, typename Out2, typename = std::enable_if_t<std::is_constructible_v<Out1, Out2>>> - void put( const DataObjectHandle<AnyDataWrapper<Out1>>& out_handle, Out2&& out ) { - out_handle.put( std::forward<Out2>( out ) ); + auto put( const DataObjectHandle<AnyDataWrapper<Out1>>& out_handle, Out2&& out ) { + return out_handle.put( std::forward<Out2>( out ) ); } // optional put diff --git a/GaudiAlg/include/GaudiAlg/FunctionalUtilities.h b/GaudiAlg/include/GaudiAlg/FunctionalUtilities.h index bd1206baba2cb715d0fdde9173c7f4eb0434c7f8..b4efb000c38a585e94d6401fc32e12a768616a6f 100644 --- a/GaudiAlg/include/GaudiAlg/FunctionalUtilities.h +++ b/GaudiAlg/include/GaudiAlg/FunctionalUtilities.h @@ -85,6 +85,12 @@ namespace Gaudi::Functional { using OutputHandle = Handle<T>; }; + template <typename Data, typename View> + struct writeViewFor { + template <typename T> + using OutputHandle = std::enable_if_t<std::is_same_v<T, Data>, DataObjectWriteHandle<View, Data>>; + }; + // this uses the defaults -- and it itself is the default ;-) using useDefaults = use_<>; diff --git a/GaudiAlg/include/GaudiAlg/GetData.h b/GaudiAlg/include/GaudiAlg/GetData.h index b3e6b32b9e99bd53ed2eea99c030f5cabdadfbc6..4e6f8c1731a0aa2872238ed25cdb859e14982012 100644 --- a/GaudiAlg/include/GaudiAlg/GetData.h +++ b/GaudiAlg/include/GaudiAlg/GetData.h @@ -79,13 +79,9 @@ namespace Gaudi { typename _GetType<TYPE>::return_type getFromTS( IDataProviderSvc* service, std::string_view location ) { DataObject* obj = nullptr; // Return the casted pointer if the retrieve was successful or nullptr otherwise. - StatusCode sc = service->retrieveObject( location, obj ); - if ( sc.isSuccess() ) { - typename _GetType<TYPE>::return_type tobj = dynamic_cast<typename _GetType<TYPE>::return_type>( obj ); - return tobj; - } else { - return nullptr; - } + return service->retrieveObject( location, obj ).isSuccess() + ? dynamic_cast<typename _GetType<TYPE>::return_type>( obj ) + : nullptr; } // ======================================================================== /** Helper function to provide the minimal lookup and cast functionality @@ -98,17 +94,13 @@ namespace Gaudi { DataObject* obj = nullptr; // Return the casted pointer if the retrieve was successful or nullptr otherwise. StatusCode sc = service->retrieveObject( location, obj ); - if ( sc.isSuccess() ) { - typename _GetType<TYPE>::return_type tobj = dynamic_cast<typename _GetType<TYPE>::return_type>( obj ); - if ( !tobj ) { - // try with AnyDataWrapper - AnyDataWrapper<TYPE>* tobj2 = dynamic_cast<AnyDataWrapper<TYPE>*>( obj ); - if ( tobj2 ) { tobj = &( tobj2->getData() ); } - } - return tobj; - } else { - return nullptr; + if ( sc.isFailure() ) return nullptr; + auto tobj = dynamic_cast<typename _GetType<TYPE>::return_type>( obj ); + if ( !tobj ) { + // try with AnyDataWrapper + if ( auto tobj2 = dynamic_cast<AnyDataWrapper<TYPE>*>( obj ); tobj2 ) { tobj = &( tobj2->getData() ); } } + return tobj; } // ======================================================================== /** @struct GetData GaudiUtils/GetData.h diff --git a/GaudiExamples/CMakeLists.txt b/GaudiExamples/CMakeLists.txt index b53f9a657f38c7e35494fe52e17331a875dc7062..adfe9509b3213e47d90331c354dc8c679dc6bc27 100644 --- a/GaudiExamples/CMakeLists.txt +++ b/GaudiExamples/CMakeLists.txt @@ -40,8 +40,8 @@ gaudi_add_module(GaudiExamples src/AlgTools/TestToolAlg.cpp src/AlgTools/TestToolAlgFailure.cpp src/AlgTools/TestToolFailing.cpp - src/AnyData/AnyDataGetAlgorithm.cpp - src/AnyData/AnyDataPutAlgorithm.cpp + src/AnyData/AnyDataAlgorithm.cpp + src/AnyData/AnyViewAlgorithm.cpp src/Auditors/AuditorTestAlg.cpp src/Auditors/LoggingAuditor.cpp src/bug_34121/bug34121_MyAlgorithm.cpp diff --git a/GaudiExamples/src/AnyData/AnyDataAlgorithm.cpp b/GaudiExamples/src/AnyData/AnyDataAlgorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..18b423516b454167a46a5bc6958dca01a63808a3 --- /dev/null +++ b/GaudiExamples/src/AnyData/AnyDataAlgorithm.cpp @@ -0,0 +1,92 @@ +/***********************************************************************************\ +* (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * +* * +* This software is distributed under the terms of the Apache version 2 licence, * +* copied verbatim in the file "LICENSE". * +* * +* In applying this licence, CERN does not waive the privileges and immunities * +* granted to it by virtue of its status as an Intergovernmental Organization * +* or submit itself to any jurisdiction. * +\***********************************************************************************/ +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/AnyDataWrapper.h" +#include "GaudiKernel/DataObjectHandle.h" +#include <string> +#include <vector> +//----------------------------------------------------------------------------- +// Implementation file for class : AnyData{Get,Put}Algorithm +// +// 2016-05-26 : Roel Aaij +//----------------------------------------------------------------------------- +/** @class AnyDataPutAlgorithm AnyDataPutAlgorithm.h AnyData/AnyDataPutAlgorithm.h + * + * + * @author Roel Aaij + * @date 2016-05-26 + */ +class AnyDataPutAlgorithm : public GaudiAlgorithm { + Gaudi::Property<std::string> m_loc{this, "Location", "Test"}; + DataObjectWriteHandle<std::vector<int>> m_ids{this, "Output", "/Event/Test/Ids"}; + std::vector<DataObjectWriteHandle<int>> m_id_vec; + +public: + AnyDataPutAlgorithm( const std::string& name, ISvcLocator* pSvcLocator ) : GaudiAlgorithm( name, pSvcLocator ) { + for ( int i = 0; i < 100; i++ ) { m_id_vec.emplace_back( "/Event/Test/Ids" + std::to_string( i ), this ); } + } + + StatusCode execute() override { + if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg; + + auto i = std::make_unique<AnyDataWrapper<int>>( 0 ); + auto j = std::make_unique<AnyDataWrapper<std::vector<int>>>( std::vector<int>{0, 1, 2, 3} ); + + put( std::move( i ), m_loc + "/One" ); + put( std::move( j ), m_loc + "/Two" ); + + m_ids.put( std::vector<int>( {42, 84} ) ); + + for ( int i = 0; i < 100; ++i ) m_id_vec[i].put( std::move( i ) ); + + return StatusCode::SUCCESS; + } +}; + +// Declaration of the Algorithm Factory +DECLARE_COMPONENT( AnyDataPutAlgorithm ) +/** @class AnyDataGetAlgorithm AnyDataGetAlgorithm.h AnyData/AnyDataGetAlgorithm.h + * + * + * @author Roel Aaij + * @date 2016-05-26 + */ +template <class T> +class AnyDataGetAlgorithm : public GaudiAlgorithm { + Gaudi::Property<std::string> m_location{this, "Location"}; + + DataObjectReadHandle<std::vector<int>> m_ids{this, "Input", "/Event/Test/Ids"}; + +public: + using GaudiAlgorithm::GaudiAlgorithm; + + StatusCode execute() override { + if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg; + + auto base = getIfExists<AnyDataWrapperBase>( m_location ); + if ( base ) { info() << "Got base from " << m_location.value() << endmsg; } + const auto i = dynamic_cast<const AnyDataWrapper<T>*>( base ); + if ( i ) { + info() << "Got " << System::typeinfoName( typeid( T ) ) << " from " << m_location.value() << ": " << i->getData() + << endmsg; + } + + const auto& ids = m_ids.get(); + info() << "AnyDataHandler holds:"; + for ( const auto& i : *ids ) info() << i << " "; + info() << endmsg; + return StatusCode::SUCCESS; + } +}; + +// Declaration of the Algorithm Factory +DECLARE_COMPONENT_WITH_ID( AnyDataGetAlgorithm<int>, "AnyDataGetAlgorithm_Int" ) +DECLARE_COMPONENT_WITH_ID( AnyDataGetAlgorithm<std::vector<int>>, "AnyDataGetAlgorithm_VectorInt" ) diff --git a/GaudiExamples/src/AnyData/AnyDataGetAlgorithm.cpp b/GaudiExamples/src/AnyData/AnyDataGetAlgorithm.cpp deleted file mode 100644 index f02a7162d6544057b5afa88976ffd5b3beb8e951..0000000000000000000000000000000000000000 --- a/GaudiExamples/src/AnyData/AnyDataGetAlgorithm.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/***********************************************************************************\ -* (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * -* * -* This software is distributed under the terms of the Apache version 2 licence, * -* copied verbatim in the file "LICENSE". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\***********************************************************************************/ -// Include files -#include <vector> - -// from Gaudi -#include "GaudiKernel/AnyDataWrapper.h" - -// local -#include "AnyDataGetAlgorithm.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : AnyDataGetAlgorithm -// -// 2016-05-26 : Roel Aaij -//----------------------------------------------------------------------------- - -// Declaration of the Algorithm Factory -DECLARE_COMPONENT_WITH_ID( AnyDataGetAlgorithm<int>, "AnyDataGetAlgorithm_Int" ) -DECLARE_COMPONENT_WITH_ID( AnyDataGetAlgorithm<std::vector<int>>, "AnyDataGetAlgorithm_VectorInt" ) - -namespace { - using std::vector; -} - -//============================================================================= -// Main execution -//============================================================================= -template <class T> -StatusCode AnyDataGetAlgorithm<T>::execute() { - - if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg; - - auto base = getIfExists<AnyDataWrapperBase>( m_location ); - if ( base ) { info() << "Got base from " << m_location.value() << endmsg; } - const auto i = dynamic_cast<const AnyDataWrapper<T>*>( base ); - if ( i ) { - info() << "Got " << System::typeinfoName( typeid( T ) ) << " from " << m_location.value() << ": " << i->getData() - << endmsg; - } - - const auto& ids = m_ids.get(); - info() << "AnyDataHandler holds:"; - for ( const auto& i : *ids ) info() << i << " "; - info() << endmsg; - return StatusCode::SUCCESS; -} diff --git a/GaudiExamples/src/AnyData/AnyDataGetAlgorithm.h b/GaudiExamples/src/AnyData/AnyDataGetAlgorithm.h deleted file mode 100644 index e7320d77f45a190d9f0f7dfad3325f4b95ed1ee1..0000000000000000000000000000000000000000 --- a/GaudiExamples/src/AnyData/AnyDataGetAlgorithm.h +++ /dev/null @@ -1,40 +0,0 @@ -/***********************************************************************************\ -* (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * -* * -* This software is distributed under the terms of the Apache version 2 licence, * -* copied verbatim in the file "LICENSE". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\***********************************************************************************/ -#ifndef ANYDATA_ANADATAGETALGORITHM_H -#define ANYDATA_ANADATAGETALGORITHM_H 1 - -// Include files -#include <string> -#include <vector> - -// from Gaudi -#include "GaudiAlg/GaudiAlgorithm.h" -#include "GaudiKernel/DataObjectHandle.h" -/** @class AnyDataGetAlgorithm AnyDataGetAlgorithm.h AnyData/AnyDataGetAlgorithm.h - * - * - * @author Roel Aaij - * @date 2016-05-26 - */ -template <class T> -class AnyDataGetAlgorithm : public GaudiAlgorithm { -public: - /// Standard constructor - AnyDataGetAlgorithm( const std::string& name, ISvcLocator* svcLoc ) : GaudiAlgorithm( name, svcLoc ) {} - - StatusCode execute() override; ///< Algorithm execution - -private: - Gaudi::Property<std::string> m_location{this, "Location"}; - - DataObjectReadHandle<std::vector<int>> m_ids{this, "Input", "/Event/Test/Ids"}; -}; -#endif // ANYDATA_ANADATAGETALGORITHM_H diff --git a/GaudiExamples/src/AnyData/AnyDataPutAlgorithm.cpp b/GaudiExamples/src/AnyData/AnyDataPutAlgorithm.cpp deleted file mode 100644 index b62d799e9e094053059bdfad0219b747c2636732..0000000000000000000000000000000000000000 --- a/GaudiExamples/src/AnyData/AnyDataPutAlgorithm.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/***********************************************************************************\ -* (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * -* * -* This software is distributed under the terms of the Apache version 2 licence, * -* copied verbatim in the file "LICENSE". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\***********************************************************************************/ -// Include files -#include <string> -#include <vector> - -// from Gaudi -#include "GaudiKernel/AnyDataWrapper.h" - -// local -#include "AnyDataPutAlgorithm.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : AnyDataPutAlgorithm -// -// 2016-05-26 : Roel Aaij -//----------------------------------------------------------------------------- - -// Declaration of the Algorithm Factory -DECLARE_COMPONENT( AnyDataPutAlgorithm ) - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -AnyDataPutAlgorithm::AnyDataPutAlgorithm( const std::string& name, ISvcLocator* pSvcLocator ) - : GaudiAlgorithm( name, pSvcLocator ) { - for ( int i = 0; i < 100; i++ ) { m_id_vec.emplace_back( "/Event/Test/Ids" + std::to_string( i ), this ); } -} - -//============================================================================= -// Main execution -//============================================================================= -StatusCode AnyDataPutAlgorithm::execute() { - - if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg; - - auto i = std::make_unique<AnyDataWrapper<int>>( 0 ); - auto j = std::make_unique<AnyDataWrapper<std::vector<int>>>( std::vector<int>{0, 1, 2, 3} ); - - put( std::move( i ), m_loc + "/One" ); - put( std::move( j ), m_loc + "/Two" ); - - m_ids.put( std::vector<int>( {42, 84} ) ); - - for ( int i = 0; i < 100; ++i ) m_id_vec[i].put( std::move( i ) ); - - return StatusCode::SUCCESS; -} diff --git a/GaudiExamples/src/AnyData/AnyDataPutAlgorithm.h b/GaudiExamples/src/AnyData/AnyDataPutAlgorithm.h deleted file mode 100644 index bf85324eb40f16703e7969ce9ae9f974f5b81377..0000000000000000000000000000000000000000 --- a/GaudiExamples/src/AnyData/AnyDataPutAlgorithm.h +++ /dev/null @@ -1,42 +0,0 @@ -/***********************************************************************************\ -* (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * -* * -* This software is distributed under the terms of the Apache version 2 licence, * -* copied verbatim in the file "LICENSE". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\***********************************************************************************/ -#ifndef ANYDATA_ANADATAPUTALGORITHM_H -#define ANYDATA_ANADATAPUTALGORITHM_H 1 - -// Include files -#include <string> -#include <vector> - -// from Gaudi -#include "GaudiAlg/GaudiAlgorithm.h" -#include "GaudiKernel/AnyDataHandle.h" - -/** @class AnyDataPutAlgorithm AnyDataPutAlgorithm.h AnyData/AnyDataPutAlgorithm.h - * - * - * @author Roel Aaij - * @date 2016-05-26 - */ -class AnyDataPutAlgorithm : public GaudiAlgorithm { -public: - /// Standard constructor - AnyDataPutAlgorithm( const std::string& name, ISvcLocator* pSvcLocator ); - - StatusCode execute() override; ///< Algorithm execution - -private: - Gaudi::Property<std::string> m_loc{this, "Location", "Test"}; - - DataObjectWriteHandle<std::vector<int>> m_ids{this, "Output", "/Event/Test/Ids"}; - - std::vector<DataObjectWriteHandle<int>> m_id_vec; -}; -#endif // ANYDATA_ANADATAPUTALGORITHM_H diff --git a/GaudiExamples/src/AnyData/AnyViewAlgorithm.cpp b/GaudiExamples/src/AnyData/AnyViewAlgorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a655d56965bb3110826effb0fe9d5c89905fd217 --- /dev/null +++ b/GaudiExamples/src/AnyData/AnyViewAlgorithm.cpp @@ -0,0 +1,65 @@ +/***********************************************************************************\ +* (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * +* * +* This software is distributed under the terms of the Apache version 2 licence, * +* copied verbatim in the file "LICENSE". * +* * +* In applying this licence, CERN does not waive the privileges and immunities * +* granted to it by virtue of its status as an Intergovernmental Organization * +* or submit itself to any jurisdiction. * +\***********************************************************************************/ +#include "GaudiAlg/Consumer.h" +#include "GaudiAlg/Producer.h" +#include "GaudiKernel/Algorithm.h" +#include "GaudiKernel/DataObjectHandle.h" +#include <gsl/span> +#include <string> +#include <string_view> +#include <vector> + +using BaseClass_t = Gaudi::Functional::Traits::BaseClass_t<Gaudi::Algorithm>; + +template <typename Data, typename View> +using writeViewFor = Gaudi::Functional::Traits::use_<Gaudi::Functional::Traits::writeViewFor<Data, View>, BaseClass_t>; + +struct ProduceStringView : Gaudi::Functional::Producer<std::string(), writeViewFor<std::string, std::string_view>> { + ProduceStringView( const std::string& name, ISvcLocator* svcLoc ) + : Producer{name, svcLoc, {"Output", "/Event/Test/StringView"}} {} + + std::string operator()() const override { return "Hello World"; } +}; +DECLARE_COMPONENT( ProduceStringView ) + +struct ProduceIntView + : Gaudi::Functional::Producer<std::vector<int>(), writeViewFor<std::vector<int>, gsl::span<const int>>> { + ProduceIntView( const std::string& name, ISvcLocator* svcLoc ) + : Producer{name, svcLoc, {"Output", "/Event/Test/IntView"}} {} + + std::vector<int> operator()() const override { + std::vector<int> vi{1, 2, 3, 5, 8, 13, 21, 34}; + info() << "made vector with data at : " << vi.data() << endmsg; + return vi; + } +}; +DECLARE_COMPONENT( ProduceIntView ) + +struct GetStringView : Gaudi::Functional::Consumer<void( std::string_view const& ), BaseClass_t> { + GetStringView( const std::string& name, ISvcLocator* svcLoc ) + : Consumer{name, svcLoc, {"Input", "/Event/Test/StringView"}} {} + + void operator()( const std::string_view& sv ) const override { info() << sv << endmsg; } +}; +DECLARE_COMPONENT( GetStringView ) + +struct GetIntView : Gaudi::Functional::Consumer<void( gsl::span<const int> const& ), BaseClass_t> { + GetIntView( const std::string& name, ISvcLocator* svcLoc ) + : Consumer{name, svcLoc, {"Input", "/Event/Test/IntView"}} {} + + void operator()( const gsl::span<const int>& view ) const override { + info() << "got a span with data at : " << view.data() << endmsg; + auto& out = info(); + for ( int i : view ) out << i << " "; + out << endmsg; + } +}; +DECLARE_COMPONENT( GetIntView ) diff --git a/GaudiExamples/tests/qmtest/gaudiexamples.qms/anyview.qmt b/GaudiExamples/tests/qmtest/gaudiexamples.qms/anyview.qmt new file mode 100644 index 0000000000000000000000000000000000000000..02880029edf05bd5d4feb9adbd78a12ce347b816 --- /dev/null +++ b/GaudiExamples/tests/qmtest/gaudiexamples.qms/anyview.qmt @@ -0,0 +1,29 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<!-- + (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations + + This software is distributed under the terms of the Apache version 2 licence, + copied verbatim in the file "LICENSE". + + In applying this licence, CERN does not waive the privileges and immunities + granted to it by virtue of its status as an Intergovernmental Organization + or submit itself to any jurisdiction. +--> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="options"><text> +from Gaudi.Configuration import * + +from Configurables import ProduceStringView, ProduceIntView, GetStringView, GetIntView + +from Configurables import EvtDataSvc +EvtDataSvc("EventDataSvc").RootCLID = 1 +EvtDataSvc("EventDataSvc").RootName = "/Event" +EvtDataSvc("EventDataSvc").ForceLeaves = True +app = ApplicationMgr(TopAlg = [ ProduceStringView(), ProduceIntView(), GetStringView(), GetIntView() ], + EvtSel = "NONE", + EvtMax = 2) +</text></argument> + <argument name="reference"><text>refs/anyview.ref</text></argument> + <argument name="exit_code"><integer>0</integer></argument> +</extension> diff --git a/GaudiExamples/tests/qmtest/refs/anyview.ref b/GaudiExamples/tests/qmtest/refs/anyview.ref new file mode 100644 index 0000000000000000000000000000000000000000..a524bead12ddbb34697b970c6248407ab2887d7b --- /dev/null +++ b/GaudiExamples/tests/qmtest/refs/anyview.ref @@ -0,0 +1,25 @@ +# setting LC_ALL to "C" +# --> Including file '/tmp/tmpz_UACG.py' +# <-- End of file '/tmp/tmpz_UACG.py' +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to ApplicationMgr (GaudiCoreSvc v34r1) + running on stbc-i1.nikhef.nl on Sat Nov 7 15:16:48 2020 +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +EventLoopMgr WARNING Unable to locate service "EventSelector" +EventLoopMgr WARNING No events will be processed from external input. +ApplicationMgr INFO Application Manager Initialized successfully +ApplicationMgr INFO Application Manager Started successfully +ProduceIntView INFO made vector with data at : 0x1f6baf0 +GetStringView INFO Hello World +GetIntView INFO got a span with data at : 0x1f6baf0 +GetIntView INFO 1 2 3 5 8 13 21 34 +ProduceIntView INFO made vector with data at : 0x1f6baf0 +GetStringView INFO Hello World +GetIntView INFO got a span with data at : 0x1f6baf0 +GetIntView INFO 1 2 3 5 8 13 21 34 +ApplicationMgr INFO Application Manager Stopped successfully +EventLoopMgr INFO Histograms converted successfully according to request. +ApplicationMgr INFO Application Manager Finalized successfully +ApplicationMgr INFO Application Manager Terminated successfully diff --git a/GaudiKernel/include/GaudiKernel/AnyDataWrapper.h b/GaudiKernel/include/GaudiKernel/AnyDataWrapper.h index 50536abf8d0484a9b23827af293afdbe8e93fc26..6b101e2ee1cf79e61bd288be9cf8a525f694c7da 100644 --- a/GaudiKernel/include/GaudiKernel/AnyDataWrapper.h +++ b/GaudiKernel/include/GaudiKernel/AnyDataWrapper.h @@ -8,14 +8,12 @@ * granted to it by virtue of its status as an Intergovernmental Organization * * or submit itself to any jurisdiction. * \***********************************************************************************/ -#ifndef GAUDIKERNEL_ANYDATAWRAPPER_H -#define GAUDIKERNEL_ANYDATAWRAPPER_H - -// Include files +#pragma once #include "GaudiKernel/DataObject.h" #include <cstddef> #include <iterator> #include <optional> +#include <utility> namespace details { using std::size; @@ -32,24 +30,37 @@ struct GAUDI_API AnyDataWrapperBase : DataObject { virtual std::optional<std::size_t> size() const = 0; }; -template <class T> -class GAUDI_API AnyDataWrapper final : public AnyDataWrapperBase { -public: - AnyDataWrapper( T&& data ) : m_data( std::move( data ) ){}; +template <typename T> +class GAUDI_API AnyDataWrapper : public AnyDataWrapperBase { +protected: + T m_data; - AnyDataWrapper( AnyDataWrapper&& other ) - : AnyDataWrapperBase( std::move( other ) ), m_data( std::move( other.m_data ) ){}; +public: + AnyDataWrapper( T&& data ) : m_data{std::move( data )} {}; + AnyDataWrapper( AnyDataWrapper&& ) = delete; + AnyDataWrapper( AnyDataWrapper const& ) = delete; + AnyDataWrapper& operator=( AnyDataWrapper&& ) = delete; + AnyDataWrapper& operator=( AnyDataWrapper const& ) = delete; const T& getData() const { return m_data; } T& getData() { return m_data; } std::optional<std::size_t> size() const override { using details::size; - return size( m_data ); + return size( getData() ); } - -private: - T m_data; }; -#endif +template <typename ViewType, typename OwnedType> +class GAUDI_API AnyDataWithViewWrapper : public AnyDataWrapper<ViewType> { + OwnedType m_owned; + +public: + AnyDataWithViewWrapper( OwnedType&& data ) : AnyDataWrapper<ViewType>{{}}, m_owned{std::move( data )} { + AnyDataWrapper<ViewType>::m_data = ViewType{std::as_const( m_owned )}; + } + AnyDataWithViewWrapper( AnyDataWithViewWrapper&& ) = delete; + AnyDataWithViewWrapper( AnyDataWithViewWrapper const& ) = delete; + AnyDataWithViewWrapper& operator=( AnyDataWithViewWrapper&& ) = delete; + AnyDataWithViewWrapper& operator=( AnyDataWithViewWrapper const& ) = delete; +}; diff --git a/GaudiKernel/include/GaudiKernel/DataObjectHandle.h b/GaudiKernel/include/GaudiKernel/DataObjectHandle.h index 99fae9a7bd6581aa9c20c6f11bd05c24c764c16b..3d8e9cf5570e45dfb4ba3fcd86306f909a61baee 100644 --- a/GaudiKernel/include/GaudiKernel/DataObjectHandle.h +++ b/GaudiKernel/include/GaudiKernel/DataObjectHandle.h @@ -69,21 +69,24 @@ namespace details { return ok; } - template <typename T> + template <typename T, typename U> struct Payload_helper { - using type = std::conditional_t<std::is_base_of_v<DataObject, T>, T, AnyDataWrapper<std::remove_const_t<T>>>; + using type = + std::conditional_t<std::is_base_of_v<DataObject, T> && std::is_same_v<T, U>, T, + std::conditional_t<std::is_same_v<T, U>, AnyDataWrapper<std::remove_const_t<T>>, + AnyDataWithViewWrapper<std::remove_const_t<T>, std::remove_const_t<U>>>>; }; - template <typename T> - struct Payload_helper<Gaudi::Range_<T>> { + template <typename T, typename U> + struct Payload_helper<Gaudi::Range_<T>, U> { using type = Gaudi::Range_<T>; }; - template <typename T> - struct Payload_helper<Gaudi::NamedRange_<T>> { + template <typename T, typename U> + struct Payload_helper<Gaudi::NamedRange_<T>, U> { using type = Gaudi::NamedRange_<T>; }; - template <typename T> - using Payload_t = typename Payload_helper<T>::type; + template <typename T, typename U = T> + using Payload_t = typename Payload_helper<T, U>::type; } // namespace details //--------------------------------------------------------------------------- @@ -173,10 +176,8 @@ T* DataObjectHandle<T>::get( bool mustExist ) const { template <typename T> T* DataObjectHandle<T>::put( std::unique_ptr<T> objectp ) const { assert( m_init ); - StatusCode rc = m_EDS->registerObject( objKey(), objectp.get() ); - if ( !rc.isSuccess() ) { - throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", StatusCode::FAILURE ); - } + StatusCode sc = m_EDS->registerObject( objKey(), objectp.get() ); + if ( !sc.isSuccess() ) { throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", sc ); } return objectp.release(); } @@ -296,7 +297,14 @@ public: /** * Register object in transient store */ - const T* put( T&& object ) const; + const T* put( T&& obj ) const { + assert( m_init ); + auto objectp = std::make_unique<AnyDataWrapper<T>>( std::move( obj ) ); + if ( auto sc = m_EDS->registerObject( objKey(), objectp.get() ); sc.isFailure() ) { + throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<AnyDataWrapper<T>>::put", sc ); + } + return &objectp.release()->getData(); + } /** * Size of boxed item, if boxed item has a 'size' method @@ -310,40 +318,81 @@ public: } private: - AnyDataWrapper<T>* _get( bool mustExist ) const; - mutable bool m_goodType = false; + AnyDataWrapper<T>* _get( bool mustExist ) const { + auto obj = fetch(); + if ( UNLIKELY( !obj ) ) { + if ( mustExist ) { + throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.", + m_owner ? owner()->name() : "no owner", StatusCode::FAILURE ); + + } else { + return nullptr; + } + } + if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<AnyDataWrapper<T>>( obj ); + return static_cast<AnyDataWrapper<T>*>( obj ); + } + mutable bool m_goodType = false; }; //--------------------------------------------------------------------------- +/// specialization for AnyDataWithViewWrapper +template <typename View, typename Owned> +class DataObjectHandle<AnyDataWithViewWrapper<View, Owned>> : public DataObjectHandleBase { +public: + using DataObjectHandleBase::DataObjectHandleBase; -template <typename T> -AnyDataWrapper<T>* DataObjectHandle<AnyDataWrapper<T>>::_get( bool mustExist ) const { - auto obj = fetch(); - if ( UNLIKELY( !obj ) ) { - if ( mustExist ) { - throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.", - m_owner ? owner()->name() : "no owner", StatusCode::FAILURE ); + /** + * Retrieve object from transient data store + */ + View* get() const { return &_get( true )->getData(); } + View* getIfExists() const { + auto data = _get( false ); + return data ? &data->getData() : nullptr; + } - } else { - return nullptr; + /** + * Register object in transient store + */ + const View* put( std::unique_ptr<AnyDataWithViewWrapper<View, Owned>> objectp ) const { + assert( m_init ); + if ( auto sc = m_EDS->registerObject( objKey(), objectp.get() ); sc.isFailure() ) { + throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<AnyDataWithViewWrapper<T>::put", sc ); } + return &objectp.release()->getData(); + } + const View* put( Owned&& obj ) const { + return put( std::make_unique<AnyDataWithViewWrapper<View, Owned>>( std::move( obj ) ) ); } - if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<AnyDataWrapper<T>>( obj ); - return static_cast<AnyDataWrapper<T>*>( obj ); -} -//--------------------------------------------------------------------------- + /** + * Size of boxed item, if boxed item has a 'size' method + */ + std::optional<std::size_t> size() const { return _get()->size(); } -template <typename T> -const T* DataObjectHandle<AnyDataWrapper<T>>::put( T&& obj ) const { - assert( m_init ); - auto objectp = std::make_unique<AnyDataWrapper<T>>( std::move( obj ) ); - StatusCode rc = m_EDS->registerObject( objKey(), objectp.get() ); - if ( rc.isFailure() ) { - throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", StatusCode::FAILURE ); + std::string pythonRepr() const override { + auto repr = DataObjectHandleBase::pythonRepr(); + boost::replace_all( repr, default_type, System::typeinfoName( typeid( View ) ) ); + return repr; } - return &objectp.release()->getData(); -} + +private: + AnyDataWithViewWrapper<View, Owned>* _get( bool mustExist ) const { + auto obj = fetch(); + if ( UNLIKELY( !obj ) ) { + if ( mustExist ) { + throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.", + m_owner ? owner()->name() : "no owner", StatusCode::FAILURE ); + + } else { + return nullptr; + } + } + if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<AnyDataWithViewWrapper<View, Owned>>( obj ); + return static_cast<AnyDataWithViewWrapper<View, Owned>*>( obj ); + } + mutable bool m_goodType = false; +}; //---------------------------- user-facing interface ---------- @@ -369,22 +418,22 @@ public: : DataObjectReadHandle( args, std::index_sequence_for<Args...>{} ) {} }; -template <typename T> -class DataObjectWriteHandle : public DataObjectHandle<::details::Payload_t<T>> { +template <typename T, typename U = T> +class DataObjectWriteHandle : public DataObjectHandle<::details::Payload_t<T, U>> { template <typename... Args, std::size_t... Is> DataObjectWriteHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> ) : DataObjectWriteHandle( std::get<Is>( args )... ) {} public: DataObjectWriteHandle( const DataObjID& k, IDataHandleHolder* owner ) - : DataObjectHandle<::details::Payload_t<T>>{k, Gaudi::DataHandle::Writer, owner} {} + : DataObjectHandle<::details::Payload_t<T, U>>{k, Gaudi::DataHandle::Writer, owner} {} /// Autodeclaring constructor with property name, mode, key and documentation. /// @note the use std::enable_if is required to avoid ambiguities template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of_v<IProperty, OWNER>>> DataObjectWriteHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" ) - : DataObjectHandle<::details::Payload_t<T>>( owner, Gaudi::DataHandle::Writer, std::move( propertyName ), key, - std::move( doc ) ) {} + : DataObjectHandle<::details::Payload_t<T, U>>( owner, Gaudi::DataHandle::Writer, std::move( propertyName ), key, + std::move( doc ) ) {} template <typename... Args> DataObjectWriteHandle( const std::tuple<Args...>& args )