From 22acc16e317930fa5de22769e79be1689008c900 Mon Sep 17 00:00:00 2001 From: Frank Winklmeier Date: Wed, 7 Feb 2018 13:08:48 +0100 Subject: [PATCH] Add category support to StatusCode The StatusCode now consists of a value and category/domain. By default StatusCodes are created within a "default category". But users can define new categories and StatusCodes using typed enums. The design is mainly borrowed from std::error_code. Main changes: - StatusCode::setCode has been removed - No implicit conversions from/to bool or int anymore. This greatly increases type safety. - Converted all unscoped enums in Gaudi to their own StatusCode category (Clients will have to adjust their code to the scoped enum names (e.g. ERR -> Status::ERR) - Added operator bool() that is equivalent to isSuccess() - Added ternary (bitwise) AND(&) and OR(|) operators to combine StatusCodes according to three-valued logic - Added extensive unit tests for all StatusCode features Impact on clients: - Code that relies on the implicit StatusCode<->bool/int conversion has to be changed to explicitly construct/convert StatusCodes via either the constructor, operator bool() or getCode(). - Clients using Gaudi StatusCodes need to adjust to using the scoped enums. E.g. clients of the ConversionSvc need to change BAD_STORAGE_TYPE to Status::BAD_STORAGE_TYPE when checking for specific StatusCode return types. --- GaudiAlg/GaudiAlg/TupleObj.h | 68 ++-- GaudiAlg/GaudiAlg/TuplePut.h | 10 +- GaudiAlg/src/lib/GaudiCommon.icpp | 6 +- GaudiAlg/src/lib/TupleObj.cpp | 40 +- GaudiCommonSvc/src/CounterSvc.cpp | 12 +- GaudiCommonSvc/src/DataSvc/MultiStoreSvc.cpp | 248 ++++++------ .../src/DataSvc/PartitionSwitchAlg.cpp | 4 +- .../src/DataSvc/PartitionSwitchTool.cpp | 16 +- .../src/PersistencySvc/PersistencySvc.cpp | 20 +- .../src/ApplicationMgr/DLLClassManager.cpp | 1 + .../src/ApplicationMgr/DLLClassManager.h | 1 + GaudiHive/src/HiveWhiteBoard.cpp | 6 +- GaudiKernel/GaudiKernel/GaudiException.h | 26 +- GaudiKernel/GaudiKernel/IConversionSvc.h | 16 +- GaudiKernel/GaudiKernel/IConverter.h | 16 - GaudiKernel/GaudiKernel/ICounterSvc.h | 5 +- GaudiKernel/GaudiKernel/IDataProviderSvc.h | 4 +- GaudiKernel/GaudiKernel/IInterface.h | 6 +- GaudiKernel/GaudiKernel/IPartitionControl.h | 5 +- GaudiKernel/GaudiKernel/StatusCode.h | 334 +++++++++++----- GaudiKernel/src/Lib/AlgTool.cpp | 6 +- GaudiKernel/src/Lib/ConversionSvc.cpp | 18 +- GaudiKernel/src/Lib/DataSvc.cpp | 180 ++++----- GaudiKernel/src/Lib/IConversionSvc.cpp | 33 ++ GaudiKernel/src/Lib/ICounterSvc.cpp | 26 ++ GaudiKernel/src/Lib/IDataProviderSvc.cpp | 43 +++ GaudiKernel/src/Lib/IInterface.cpp | 25 ++ GaudiKernel/src/Lib/IPartitionControl.cpp | 27 ++ GaudiKernel/src/Lib/StatusCode.cpp | 30 +- GaudiKernel/src/Lib/TsDataSvc.cpp | 182 ++++----- GaudiKernel/tests/src/test_StatusCode.cpp | 363 ++++++++++++++++-- GaudiSvc/src/DetectorDataSvc/DetDataSvc.cpp | 4 +- GaudiSvc/src/NTupleSvc/NTupleSvc.cpp | 26 +- GaudiSvc/src/NTupleSvc/TagCollectionSvc.cpp | 4 +- GaudiUtils/GaudiUtils/IFileCatalog.h | 2 + GaudiUtils/src/component/IODataManager.cpp | 16 +- RootCnv/RootCnv/RootDataConnection.h | 5 +- RootCnv/src/RootDataConnection.cpp | 24 +- RootCnv/src/RootTool.h | 4 +- 39 files changed, 1273 insertions(+), 589 deletions(-) create mode 100644 GaudiKernel/src/Lib/IConversionSvc.cpp create mode 100644 GaudiKernel/src/Lib/IDataProviderSvc.cpp create mode 100644 GaudiKernel/src/Lib/IInterface.cpp create mode 100644 GaudiKernel/src/Lib/IPartitionControl.cpp diff --git a/GaudiAlg/GaudiAlg/TupleObj.h b/GaudiAlg/GaudiAlg/TupleObj.h index 283bf6ce91..002945104b 100644 --- a/GaudiAlg/GaudiAlg/TupleObj.h +++ b/GaudiAlg/GaudiAlg/TupleObj.h @@ -93,7 +93,7 @@ namespace Tuples * @author Vanya BELYAEV Ivan.Belyaev@itep.ru * @date 2004-01-23 */ - enum ErrorCodes { + enum class ErrorCodes : StatusCode::code_t { InvalidTuple = 100, InvalidColumn, InvalidOperation, @@ -101,6 +101,12 @@ namespace Tuples InvalidItem, TruncateValue = 200 }; +} + +STATUSCODE_ENUM_DECL( Tuples::ErrorCodes ) + +namespace Tuples +{ // ========================================================================== /** @class TupleObj TupleObj.h GaudiAlg/TupleObj.h * @@ -1010,8 +1016,8 @@ namespace Tuples StatusCode farray( const std::string& name, const FUNCTION& function, ITERATOR first, ITERATOR last, const std::string& length, size_t maxv ) { - if ( invalid() ) return InvalidTuple; - if ( rowWise() ) return InvalidOperation; + if ( invalid() ) return ErrorCodes::InvalidTuple; + if ( rowWise() ) return ErrorCodes::InvalidOperation; // adjust the length if ( std::distance( first, last ) > static_cast( maxv ) ) { @@ -1021,14 +1027,14 @@ namespace Tuples // get the length item Int* len = ints( length, 0, maxv ); - if ( !len ) return InvalidColumn; + if ( !len ) return ErrorCodes::InvalidColumn; // adjust the length *len = std::distance( first, last ); // get the array itself FArray* var = fArray( name, len ); - if ( !var ) return InvalidColumn; + if ( !var ) return ErrorCodes::InvalidColumn; // fill the array std::transform( first, last, std::begin( *var ), std::cref( function ) ); @@ -1067,8 +1073,8 @@ namespace Tuples StatusCode farray_impl( FunIterator first_item, FunIterator last_item, DataIterator first, DataIterator last, const std::string& length, size_t maxv ) { - if ( invalid() ) return InvalidTuple; - if ( rowWise() ) return InvalidOperation; + if ( invalid() ) return ErrorCodes::InvalidTuple; + if ( rowWise() ) return ErrorCodes::InvalidOperation; // adjust the length if ( std::distance( first, last ) > static_cast( maxv ) ) { @@ -1082,7 +1088,7 @@ namespace Tuples // get the length item Int* len = ints( length, 0, maxv ); - if ( !len ) return InvalidColumn; + if ( !len ) return ErrorCodes::InvalidColumn; // adjust the length *len = std::distance( first, last ); @@ -1093,7 +1099,7 @@ namespace Tuples std::transform( first_item, last_item, std::back_inserter( vars ), [&]( const auto& item ) { return this->fArray( item.first, len ); } ); if ( std::any_of( vars.begin(), vars.end(), []( const FArray* f ) { return !f; } ) ) { - return InvalidColumn; + return ErrorCodes::InvalidColumn; } // fill the array @@ -1318,8 +1324,8 @@ namespace Tuples StatusCode fmatrix( const std::string& name, const MATRIX& data, size_t rows, const MIndex& cols, const std::string& length, size_t maxv ) { - if ( invalid() ) return InvalidTuple; - if ( rowWise() ) return InvalidOperation; + if ( invalid() ) return ErrorCodes::InvalidTuple; + if ( rowWise() ) return ErrorCodes::InvalidOperation; // adjust the length if ( rows >= maxv ) { @@ -1329,14 +1335,14 @@ namespace Tuples // get the length item Int* len = ints( length, 0, maxv ); - if ( !len ) return InvalidColumn; + if ( !len ) return ErrorCodes::InvalidColumn; // adjust the length item *len = rows; // get the array itself FMatrix* var = fMatrix( name, len, cols ); - if ( !var ) return InvalidColumn; + if ( !var ) return ErrorCodes::InvalidColumn; /// fill the matrix for ( size_t iCol = 0; iCol < cols; ++iCol ) { @@ -1388,8 +1394,8 @@ namespace Tuples StatusCode fmatrix( const std::string& name, DATA first, DATA last, const MIndex& cols, const std::string& length, size_t maxv ) { - if ( invalid() ) return InvalidTuple; - if ( rowWise() ) return InvalidOperation; + if ( invalid() ) return ErrorCodes::InvalidTuple; + if ( rowWise() ) return ErrorCodes::InvalidOperation; // adjust the length if ( first + maxv < last ) { @@ -1399,14 +1405,14 @@ namespace Tuples // get the length item Int* len = ints( length, 0, maxv ); - if ( !len ) return InvalidColumn; + if ( !len ) return ErrorCodes::InvalidColumn; // adjust the length item *len = last - first; // get the array itself FMatrix* var = fMatrix( name, len, cols ); - if ( !var ) return InvalidColumn; + if ( !var ) return ErrorCodes::InvalidColumn; /// fill the matrix size_t iRow = 0; @@ -1504,8 +1510,8 @@ namespace Tuples StatusCode fmatrix( const std::string& name, FUN funF, FUN funL, DATA first, DATA last, const std::string& length, size_t maxv ) { - if ( invalid() ) return InvalidTuple; - if ( rowWise() ) return InvalidOperation; + if ( invalid() ) return ErrorCodes::InvalidTuple; + if ( rowWise() ) return ErrorCodes::InvalidOperation; // adjust the length if ( std::distance( first, last ) > static_cast( maxv ) ) { @@ -1515,7 +1521,8 @@ namespace Tuples // get the length item Int* len = ints( length, 0, maxv ); - if ( !len ) return InvalidColumn; + + if ( !len ) return ErrorCodes::InvalidColumn; // adjust the length item *len = std::distance( first, last ); @@ -1523,7 +1530,7 @@ namespace Tuples // get the array itself auto cols = std::distance( funF, funL ); FMatrix* var = fMatrix( name, len, cols ); - if ( !var ) return InvalidColumn; + if ( !var ) return ErrorCodes::InvalidColumn; /// fill the matrix size_t iRow = 0; @@ -1567,15 +1574,15 @@ namespace Tuples StatusCode array( const std::string& name, DATA first, DATA last ) { - if ( invalid() ) return InvalidTuple; - if ( rowWise() ) return InvalidOperation; + if ( invalid() ) return ErrorCodes::InvalidTuple; + if ( rowWise() ) return ErrorCodes::InvalidOperation; // get the length (fixed!) auto length = std::distance( first, last ); // get the array itself FArray* var = fArray( name, length ); - if ( !var ) return InvalidColumn; + if ( !var ) return ErrorCodes::InvalidColumn; /// fill the array std::copy( first, last, std::begin( *var ) ); @@ -1723,12 +1730,12 @@ namespace Tuples template StatusCode matrix( const std::string& name, const MATRIX& data, const MIndex& rows, const MIndex& cols ) { - if ( invalid() ) return InvalidTuple; - if ( rowWise() ) return InvalidOperation; + if ( invalid() ) return ErrorCodes::InvalidTuple; + if ( rowWise() ) return ErrorCodes::InvalidOperation; // get the matrix itself FMatrix* var = fMatrix( name, rows, cols ); - if ( !var ) return InvalidColumn; + if ( !var ) return ErrorCodes::InvalidColumn; /// fill the matrix for ( size_t iCol = 0; iCol < cols; ++iCol ) { @@ -1825,12 +1832,12 @@ namespace Tuples template StatusCode matrix( const std::string& name, const ROOT::Math::SMatrix& mtrx ) { - if ( invalid() ) return InvalidTuple; - if ( rowWise() ) return InvalidOperation; + if ( invalid() ) return ErrorCodes::InvalidTuple; + if ( rowWise() ) return ErrorCodes::InvalidOperation; // get the matrix itself FMatrix* var = fMatrix( name, (MIndex)D1, (MIndex)D2 ); - if ( !var ) return InvalidColumn; + if ( !var ) return ErrorCodes::InvalidColumn; /// fill the matrix for ( size_t iCol = 0; iCol < D2; ++iCol ) { @@ -2107,6 +2114,7 @@ namespace Tuples }; // ========================================================================== } // end of namespace Tuples + // ============================================================================ // GaudiAlg // ============================================================================ diff --git a/GaudiAlg/GaudiAlg/TuplePut.h b/GaudiAlg/GaudiAlg/TuplePut.h index 15d51d190b..a8fc1df350 100644 --- a/GaudiAlg/GaudiAlg/TuplePut.h +++ b/GaudiAlg/GaudiAlg/TuplePut.h @@ -116,10 +116,10 @@ template inline StatusCode Tuples::TupleObj::put( const std::string& name, const TYPE* obj ) { if ( invalid() ) { - return InvalidTuple; + return ErrorCodes::InvalidTuple; } // RETURN if ( !evtColType() ) { - return InvalidOperation; + return ErrorCodes::InvalidOperation; } // RETURN // static block: The type description & the flag @@ -127,14 +127,14 @@ inline StatusCode Tuples::TupleObj::put( const std::string& name, const TYPE* ob static TClass* s_type = nullptr; // STATIC // check the status if ( s_fail ) { - return InvalidItem; + return ErrorCodes::InvalidItem; } // RETURN else if ( !s_type ) { s_type = TClass::GetClass( typeid( TYPE ) ); if ( !s_type ) { s_fail = true; return Error( " put('" + name + "'," + System::typeinfoName( typeid( TYPE ) ) + ") :Invalid ROOT Type", - InvalidItem ); // RETURN + ErrorCodes::InvalidItem ); // RETURN } } // the local storage of items @@ -142,7 +142,7 @@ inline StatusCode Tuples::TupleObj::put( const std::string& name, const TYPE* ob // get the variable by name: auto item = s_map.getItem( name, this ); if ( !item ) { - return Error( " put('" + name + "'): invalid item detected", InvalidItem ); + return Error( " put('" + name + "'): invalid item detected", ErrorCodes::InvalidItem ); } // assign the item! ( *item ) = const_cast( obj ); // THATS ALL!! diff --git a/GaudiAlg/src/lib/GaudiCommon.icpp b/GaudiAlg/src/lib/GaudiCommon.icpp index c25730ca77..78f86919ad 100644 --- a/GaudiAlg/src/lib/GaudiCommon.icpp +++ b/GaudiAlg/src/lib/GaudiCommon.icpp @@ -238,7 +238,7 @@ StatusCode GaudiCommon:: this->debug() << endmsg; } while ( !m_managedTools.empty() ) { - sc = releaseTool( m_managedTools.back() ) && sc; + sc = ( releaseTool( m_managedTools.back() ) && sc ) ? StatusCode::SUCCESS : StatusCode::FAILURE; } // release all located services @@ -248,7 +248,7 @@ StatusCode GaudiCommon:: this->debug() << endmsg; } while ( !m_services.empty() ) { - sc = releaseSvc( m_services.front() ) && sc; + sc = ( releaseSvc( m_services.front() ) && sc ) ? StatusCode::SUCCESS : StatusCode::FAILURE; } // release the CounterSummarySvc manually @@ -273,7 +273,7 @@ StatusCode GaudiCommon:: m_statEntityList.clear(); // finalize base class - return sc && PBASE::finalize(); + return ( sc && PBASE::finalize() ? StatusCode::SUCCESS : StatusCode::FAILURE ); } //============================================================================= diff --git a/GaudiAlg/src/lib/TupleObj.cpp b/GaudiAlg/src/lib/TupleObj.cpp index 51ef537ad9..6bf2542c50 100644 --- a/GaudiAlg/src/lib/TupleObj.cpp +++ b/GaudiAlg/src/lib/TupleObj.cpp @@ -145,17 +145,45 @@ namespace ExtraArgs&&... ea ) { if ( parent->invalid() ) { - return Tuples::InvalidTuple; + return Tuples::ErrorCodes::InvalidTuple; } auto item = find_or_create( parent, name, container, std::forward( ea )... ); if ( !item ) { - return Tuples::InvalidColumn; + return Tuples::ErrorCodes::InvalidColumn; } *item = std::forward( value ); return StatusCode::SUCCESS; } + + struct TuplesCategory : StatusCode::Category { + const char* name() const override { return "Tuples"; } + + bool isRecoverable( StatusCode::code_t ) const override { return false; } + + std::string message( StatusCode::code_t code ) const override + { + switch ( static_cast( code ) ) { + case Tuples::ErrorCodes::InvalidTuple: + return "InvalidTuple"; + case Tuples::ErrorCodes::InvalidColumn: + return "InvalidColumn"; + case Tuples::ErrorCodes::InvalidOperation: + return "InvalidOperation"; + case Tuples::ErrorCodes::InvalidObject: + return "InvalidObject"; + case Tuples::ErrorCodes::InvalidItem: + return "InvalidItem"; + case Tuples::ErrorCodes::TruncateValue: + return "TruncateValue"; + default: + return StatusCode::default_category().message( code ); + } + } + }; } +STATUSCODE_ENUM_IMPL( Tuples::ErrorCodes, TuplesCategory ) + namespace Tuples { namespace Local @@ -237,7 +265,7 @@ void Tuples::TupleObj::release() StatusCode Tuples::TupleObj::write() { if ( invalid() ) { - return InvalidTuple; + return ErrorCodes::InvalidTuple; } return tuple()->write(); } @@ -270,7 +298,7 @@ StatusCode Tuples::TupleObj::fill( const char* format... ) { // check the underlying tuple if ( invalid() ) { - return InvalidTuple; + return ErrorCodes::InvalidTuple; } // decode format string into tokens auto tokens = tokenize( format, " ,;" ); @@ -298,10 +326,10 @@ StatusCode Tuples::TupleObj::fill( const char* format... ) StatusCode Tuples::TupleObj::column( const std::string& name, IOpaqueAddress* address ) { if ( !evtColType() ) { - return InvalidOperation; + return ErrorCodes::InvalidOperation; } if ( !address ) { - return Error( "column('" + name + "') IOpaqueAddress* is NULL!", InvalidObject ); + return Error( "column('" + name + "') IOpaqueAddress* is NULL!", ErrorCodes::InvalidObject ); } return column_( this, m_addresses, name, address ); } diff --git a/GaudiCommonSvc/src/CounterSvc.cpp b/GaudiCommonSvc/src/CounterSvc.cpp index 37db09d1a7..dac91b7691 100644 --- a/GaudiCommonSvc/src/CounterSvc.cpp +++ b/GaudiCommonSvc/src/CounterSvc.cpp @@ -227,7 +227,7 @@ StatusCode CounterSvc::create( const std::string& grp, const std::string& nam, l // try to find existing counter: refpCounter = get( grp, nam ); if ( refpCounter ) { - return COUNTER_EXISTS; + return StatusCode( Status::COUNTER_EXISTS ); } // RETURN // create the new counter auto newc = new Counter(); @@ -268,11 +268,11 @@ StatusCode CounterSvc::remove( const std::string& grp, const std::string& nam ) { auto i = m_counts.find( grp ); if ( m_counts.end() == i ) { - return COUNTER_NOT_PRESENT; + return StatusCode( Status::COUNTER_NOT_PRESENT ); } // RETURN auto j = i->second.find( nam ); if ( i->second.end() == j ) { - return COUNTER_NOT_PRESENT; + return StatusCode( Status::COUNTER_NOT_PRESENT ); } // RETURN delete j->second; i->second.erase( j ); @@ -285,7 +285,7 @@ StatusCode CounterSvc::remove( const std::string& grp ) { auto i = m_counts.find( grp ); if ( m_counts.end() == i ) { - return COUNTER_NOT_PRESENT; + return StatusCode( Status::COUNTER_NOT_PRESENT ); } // RETURN for ( auto& j : i->second ) delete j.second; i->second.clear(); @@ -308,7 +308,7 @@ StatusCode CounterSvc::print( const std::string& grp, const std::string& nam, Pr { const Counter* c = get( grp, nam ); if ( !c ) { - return COUNTER_NOT_PRESENT; + return StatusCode( Status::COUNTER_NOT_PRESENT ); } // RETURN // create the stream and use it! return printer( msgStream(), c ); @@ -341,7 +341,7 @@ StatusCode CounterSvc::print( const std::string& grp, Printout& printer ) const { auto i = m_counts.find( grp ); if ( m_counts.end() == i ) { - return COUNTER_NOT_PRESENT; + return StatusCode( Status::COUNTER_NOT_PRESENT ); } // Force printing in alphabetical order diff --git a/GaudiCommonSvc/src/DataSvc/MultiStoreSvc.cpp b/GaudiCommonSvc/src/DataSvc/MultiStoreSvc.cpp index b4cd89b933..28730f970b 100644 --- a/GaudiCommonSvc/src/DataSvc/MultiStoreSvc.cpp +++ b/GaudiCommonSvc/src/DataSvc/MultiStoreSvc.cpp @@ -44,7 +44,6 @@ typedef const std::string CSTR; typedef IDataStoreAgent AGENT; typedef DataObject OBJECT; typedef IOpaqueAddress ADDRESS; -typedef StatusCode STATUS; namespace { @@ -127,10 +126,10 @@ protected: // member templates to help writing the function calls template - STATUS fwd( Fun f ) + StatusCode fwd( Fun f ) { auto* svc = m_current.get>>(); - return svc ? f( *svc ) : static_cast( IDataProviderSvc::INVALID_ROOT ); + return svc ? f( *svc ) : IDataProviderSvc::Status::INVALID_ROOT; } public: @@ -140,67 +139,67 @@ public: const std::string& rootName() const override { return m_rootName; } /// IDataManagerSvc: Register object address with the data store. - STATUS registerAddress( boost::string_ref path, ADDRESS* pAddr ) override + StatusCode registerAddress( boost::string_ref path, ADDRESS* pAddr ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.registerAddress( path, pAddr ); } ); } /// IDataManagerSvc: Register object address with the data store. - STATUS registerAddress( OBJECT* parent, boost::string_ref path, ADDRESS* pAddr ) override + StatusCode registerAddress( OBJECT* parent, boost::string_ref path, ADDRESS* pAddr ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.registerAddress( parent, path, pAddr ); } ); } /// IDataManagerSvc: Register object address with the data store. - STATUS registerAddress( IRegistry* parent, boost::string_ref path, ADDRESS* pAddr ) override + StatusCode registerAddress( IRegistry* parent, boost::string_ref path, ADDRESS* pAddr ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.registerAddress( parent, path, pAddr ); } ); } /// IDataManagerSvc: Unregister object address from the data store. - STATUS unregisterAddress( boost::string_ref path ) override + StatusCode unregisterAddress( boost::string_ref path ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.unregisterAddress( path ); } ); } /// IDataManagerSvc: Unregister object address from the data store. - STATUS unregisterAddress( OBJECT* pParent, boost::string_ref path ) override + StatusCode unregisterAddress( OBJECT* pParent, boost::string_ref path ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.unregisterAddress( pParent, path ); } ); } /// IDataManagerSvc: Unregister object address from the data store. - STATUS unregisterAddress( IRegistry* pParent, boost::string_ref path ) override + StatusCode unregisterAddress( IRegistry* pParent, boost::string_ref path ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.unregisterAddress( pParent, path ); } ); } /// Explore the object store: retrieve all leaves attached to the object - STATUS objectLeaves( const OBJECT* pObject, std::vector& leaves ) override + StatusCode objectLeaves( const OBJECT* pObject, std::vector& leaves ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.objectLeaves( pObject, leaves ); } ); } /// Explore the object store: retrieve all leaves attached to the object - STATUS objectLeaves( const IRegistry* pObject, std::vector& leaves ) override + StatusCode objectLeaves( const IRegistry* pObject, std::vector& leaves ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.objectLeaves( pObject, leaves ); } ); } /// IDataManagerSvc: Explore the object store: retrieve the object's parent - STATUS objectParent( const OBJECT* pObject, IRegistry*& refpParent ) override + StatusCode objectParent( const OBJECT* pObject, IRegistry*& refpParent ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.objectParent( pObject, refpParent ); } ); } /// IDataManagerSvc: Explore the object store: retrieve the object's parent - STATUS objectParent( const IRegistry* pObject, IRegistry*& refpParent ) override + StatusCode objectParent( const IRegistry* pObject, IRegistry*& refpParent ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.objectParent( pObject, refpParent ); } ); } /// Remove all data objects below the sub tree identified - STATUS clearSubTree( boost::string_ref path ) override + StatusCode clearSubTree( boost::string_ref path ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.clearSubTree( path ); } ); } /// Remove all data objects below the sub tree identified - STATUS clearSubTree( OBJECT* pObject ) override + StatusCode clearSubTree( OBJECT* pObject ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.clearSubTree( pObject ); } ); } /// IDataManagerSvc: Remove all data objects in the data store. - STATUS clearStore() override + StatusCode clearStore() override { for ( auto& i : m_partitions ) { i.second.dataManager->clearStore().ignore(); @@ -212,26 +211,26 @@ public: []( boost::blank ) {} ); m_root.root = {}; m_root.path.clear(); - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } /// Analyze by traversing all data objects below the sub tree - STATUS traverseSubTree( boost::string_ref path, AGENT* pAgent ) override + StatusCode traverseSubTree( boost::string_ref path, AGENT* pAgent ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.traverseSubTree( path, pAgent ); } ); } /// IDataManagerSvc: Analyze by traversing all data objects below the sub tree - STATUS traverseSubTree( OBJECT* pObject, AGENT* pAgent ) override + StatusCode traverseSubTree( OBJECT* pObject, AGENT* pAgent ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.traverseSubTree( pObject, pAgent ); } ); } /// IDataManagerSvc: Analyze by traversing all data objects in the data store. - STATUS traverseTree( AGENT* pAgent ) override + StatusCode traverseTree( AGENT* pAgent ) override { return fwd( [&]( IDataManagerSvc& svc ) { return svc.traverseTree( pAgent ); } ); } /** Initialize data store for new event by giving new event path and root object. Takes care to clear the store before reinitializing it */ - STATUS setRoot( std::string path, OBJECT* pObj ) override + StatusCode setRoot( std::string path, OBJECT* pObj ) override { dispatch_variant( m_root.root, []( auto* p ) { @@ -246,7 +245,7 @@ public: /** Initialize data store for new event by giving new event path and address of root object. Takes care to clear the store before reinitializing it */ - STATUS setRoot( std::string path, ADDRESS* pAddr ) override + StatusCode setRoot( std::string path, ADDRESS* pAddr ) override { dispatch_variant( m_root.root, []( auto* p ) { @@ -255,313 +254,313 @@ public: []( boost::blank ) {} ); m_root.path = std::move( path ); m_root.root = pAddr; - if ( !pAddr ) return STATUS::FAILURE; + if ( !pAddr ) return StatusCode::FAILURE; pAddr->addRef(); preparePartitions(); return activate( m_defaultPartition ); } /// IDataManagerSvc: Pass a default data loader to the service. - STATUS setDataLoader( IConversionSvc* pDataLoader, IDataProviderSvc* dpsvc = nullptr ) override + StatusCode setDataLoader( IConversionSvc* pDataLoader, IDataProviderSvc* dpsvc = nullptr ) override { m_dataLoader = pDataLoader; if ( m_dataLoader ) m_dataLoader->setDataProvider( dpsvc ? dpsvc : this ); for ( auto& i : m_partitions ) { i.second.dataManager->setDataLoader( m_dataLoader.get() ).ignore(); } - return SUCCESS; + return StatusCode::SUCCESS; } /// Add an item to the preload list - STATUS addPreLoadItem( const DataStoreItem& item ) override + StatusCode addPreLoadItem( const DataStoreItem& item ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.addPreLoadItem( item ); } ); } /// Add an item to the preload list - STATUS addPreLoadItem( std::string item ) override + StatusCode addPreLoadItem( std::string item ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.addPreLoadItem( std::move( item ) ); } ); } /// Remove an item from the preload list - STATUS removePreLoadItem( const DataStoreItem& item ) override + StatusCode removePreLoadItem( const DataStoreItem& item ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.removePreLoadItem( item ); } ); } /// Add an item to the preload list - STATUS removePreLoadItem( std::string item ) override + StatusCode removePreLoadItem( std::string item ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.removePreLoadItem( std::move( item ) ); } ); } /// Clear the preload list - STATUS resetPreLoad() override + StatusCode resetPreLoad() override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.resetPreLoad(); } ); } /// load all preload items of the list - STATUS preLoad() override + StatusCode preLoad() override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.preLoad(); } ); } /// Register object with the data store. - STATUS registerObject( boost::string_ref path, OBJECT* pObj ) override + StatusCode registerObject( boost::string_ref path, OBJECT* pObj ) override { return registerObject( nullptr, path, pObj ); } /// Register object with the data store. - STATUS registerObject( boost::string_ref parent, boost::string_ref obj, OBJECT* pObj ) override + StatusCode registerObject( boost::string_ref parent, boost::string_ref obj, OBJECT* pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.registerObject( parent, obj, pObj ); } ); } /// Register object with the data store. - STATUS registerObject( boost::string_ref parent, int item, OBJECT* pObj ) override + StatusCode registerObject( boost::string_ref parent, int item, OBJECT* pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.registerObject( parent, item, pObj ); } ); } /// Register object with the data store. - STATUS registerObject( OBJECT* parent, boost::string_ref obj, OBJECT* pObj ) override + StatusCode registerObject( OBJECT* parent, boost::string_ref obj, OBJECT* pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.registerObject( parent, obj, pObj ); } ); } /// Register object with the data store. - STATUS registerObject( OBJECT* parent, int obj, OBJECT* pObj ) override + StatusCode registerObject( OBJECT* parent, int obj, OBJECT* pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.registerObject( parent, obj, pObj ); } ); } /// Unregister object from the data store. - STATUS unregisterObject( boost::string_ref path ) override + StatusCode unregisterObject( boost::string_ref path ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unregisterObject( path ); } ); } /// Unregister object from the data store. - STATUS unregisterObject( boost::string_ref parent, boost::string_ref obj ) override + StatusCode unregisterObject( boost::string_ref parent, boost::string_ref obj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unregisterObject( parent, obj ); } ); } /// Unregister object from the data store. - STATUS unregisterObject( boost::string_ref parent, int obj ) override + StatusCode unregisterObject( boost::string_ref parent, int obj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unregisterObject( parent, obj ); } ); } /// Unregister object from the data store. - STATUS unregisterObject( OBJECT* pObj ) override + StatusCode unregisterObject( OBJECT* pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unregisterObject( pObj ); } ); } /// Unregister object from the data store. - STATUS unregisterObject( OBJECT* pObj, boost::string_ref path ) override + StatusCode unregisterObject( OBJECT* pObj, boost::string_ref path ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unregisterObject( pObj, path ); } ); } /// Unregister object from the data store. - STATUS unregisterObject( OBJECT* pObj, int item ) override + StatusCode unregisterObject( OBJECT* pObj, int item ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unregisterObject( pObj, item ); } ); } /// Retrieve object from data store. - STATUS retrieveObject( IRegistry* parent, boost::string_ref path, OBJECT*& pObj ) override + StatusCode retrieveObject( IRegistry* parent, boost::string_ref path, OBJECT*& pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.retrieveObject( parent, path, pObj ); } ); } /// Retrieve object identified by its full path from the data store. - STATUS retrieveObject( boost::string_ref path, OBJECT*& pObj ) override + StatusCode retrieveObject( boost::string_ref path, OBJECT*& pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.retrieveObject( path, pObj ); } ); } /// Retrieve object from data store. - STATUS retrieveObject( boost::string_ref parent, boost::string_ref path, OBJECT*& pObj ) override + StatusCode retrieveObject( boost::string_ref parent, boost::string_ref path, OBJECT*& pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.retrieveObject( parent, path, pObj ); } ); } /// Retrieve object from data store. - STATUS retrieveObject( boost::string_ref parent, int item, OBJECT*& pObj ) override + StatusCode retrieveObject( boost::string_ref parent, int item, OBJECT*& pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.retrieveObject( parent, item, pObj ); } ); } /// Retrieve object from data store. - STATUS retrieveObject( OBJECT* parent, boost::string_ref path, OBJECT*& pObj ) override + StatusCode retrieveObject( OBJECT* parent, boost::string_ref path, OBJECT*& pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.retrieveObject( parent, path, pObj ); } ); } /// Retrieve object from data store. - STATUS retrieveObject( OBJECT* parent, int item, OBJECT*& pObj ) override + StatusCode retrieveObject( OBJECT* parent, int item, OBJECT*& pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.retrieveObject( parent, item, pObj ); } ); } /// Find object identified by its full path in the data store. - STATUS findObject( boost::string_ref path, OBJECT*& pObj ) override + StatusCode findObject( boost::string_ref path, OBJECT*& pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.retrieveObject( path, pObj ); } ); } /// Find object identified by its full path in the data store. - STATUS findObject( IRegistry* parent, boost::string_ref path, OBJECT*& pObj ) override + StatusCode findObject( IRegistry* parent, boost::string_ref path, OBJECT*& pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.findObject( parent, path, pObj ); } ); } /// Find object in the data store. - STATUS findObject( boost::string_ref parent, boost::string_ref path, OBJECT*& pObj ) override + StatusCode findObject( boost::string_ref parent, boost::string_ref path, OBJECT*& pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.retrieveObject( parent, path, pObj ); } ); } /// Find object in the data store. - STATUS findObject( boost::string_ref parent, int item, OBJECT*& pObject ) override + StatusCode findObject( boost::string_ref parent, int item, OBJECT*& pObject ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.findObject( parent, item, pObject ); } ); } /// Find object in the data store. - STATUS findObject( OBJECT* parent, boost::string_ref path, OBJECT*& pObject ) override + StatusCode findObject( OBJECT* parent, boost::string_ref path, OBJECT*& pObject ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.findObject( parent, path, pObject ); } ); } /// Find object in the data store. - STATUS findObject( OBJECT* parent, int item, OBJECT*& pObject ) override + StatusCode findObject( OBJECT* parent, int item, OBJECT*& pObject ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.findObject( parent, item, pObject ); } ); } /// Add a link to another object. - STATUS linkObject( IRegistry* from, boost::string_ref objPath, OBJECT* to ) override + StatusCode linkObject( IRegistry* from, boost::string_ref objPath, OBJECT* to ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.linkObject( from, objPath, to ); } ); } /// Add a link to another object. - STATUS linkObject( boost::string_ref from, boost::string_ref objPath, OBJECT* to ) override + StatusCode linkObject( boost::string_ref from, boost::string_ref objPath, OBJECT* to ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.linkObject( from, objPath, to ); } ); } /// Add a link to another object. - STATUS linkObject( OBJECT* from, boost::string_ref objPath, OBJECT* to ) override + StatusCode linkObject( OBJECT* from, boost::string_ref objPath, OBJECT* to ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.linkObject( from, objPath, to ); } ); } /// Add a link to another object. - STATUS linkObject( boost::string_ref fullPath, OBJECT* to ) override + StatusCode linkObject( boost::string_ref fullPath, OBJECT* to ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.linkObject( fullPath, to ); } ); } /// Remove a link to another object. - STATUS unlinkObject( IRegistry* from, boost::string_ref objPath ) override + StatusCode unlinkObject( IRegistry* from, boost::string_ref objPath ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unlinkObject( from, objPath ); } ); } /// Remove a link to another object. - STATUS unlinkObject( boost::string_ref from, boost::string_ref objPath ) override + StatusCode unlinkObject( boost::string_ref from, boost::string_ref objPath ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unlinkObject( from, objPath ); } ); } /// Remove a link to another object. - STATUS unlinkObject( OBJECT* from, boost::string_ref objPath ) override + StatusCode unlinkObject( OBJECT* from, boost::string_ref objPath ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unlinkObject( from, objPath ); } ); } /// Remove a link to another object. - STATUS unlinkObject( boost::string_ref path ) override + StatusCode unlinkObject( boost::string_ref path ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.unlinkObject( path ); } ); } /// Update object identified by its directory entry. - STATUS updateObject( IRegistry* pDirectory ) override + StatusCode updateObject( IRegistry* pDirectory ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.updateObject( pDirectory ); } ); } /// Update object. - STATUS updateObject( boost::string_ref path ) override + StatusCode updateObject( boost::string_ref path ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.updateObject( path ); } ); } /// Update object. - STATUS updateObject( OBJECT* pObj ) override + StatusCode updateObject( OBJECT* pObj ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.updateObject( pObj ); } ); } /// Update object. - STATUS updateObject( boost::string_ref parent, boost::string_ref updatePath ) override + StatusCode updateObject( boost::string_ref parent, boost::string_ref updatePath ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.updateObject( parent, updatePath ); } ); } /// Update object. - STATUS updateObject( OBJECT* parent, boost::string_ref updatePath ) override + StatusCode updateObject( OBJECT* parent, boost::string_ref updatePath ) override { return fwd( [&]( IDataProviderSvc& svc ) { return svc.updateObject( parent, updatePath ); } ); } /// Create a partition object. The name identifies the partition uniquely - STATUS create( CSTR& nam, CSTR& typ ) override + StatusCode create( CSTR& nam, CSTR& typ ) override { IInterface* pPartition = nullptr; return create( nam, typ, pPartition ); } /// Create a partition object. The name identifies the partition uniquely - STATUS create( CSTR& nam, CSTR& typ, IInterface*& pPartition ) override + StatusCode create( CSTR& nam, CSTR& typ, IInterface*& pPartition ) override { - if ( get( nam, pPartition ).isSuccess() ) return PARTITION_EXISTS; + if ( get( nam, pPartition ).isSuccess() ) return IPartitionControl::Status::PARTITION_EXISTS; /// @FIXME: In the old implementation the services were "unmanaged" (non-active) auto isvc = serviceLocator()->service( typ ); - if ( !isvc ) return NO_INTERFACE; + if ( !isvc ) return IInterface::Status::NO_INTERFACE; auto dataMgr = isvc.as(); auto dataProv = isvc.as(); - if ( !dataMgr || !dataProv ) return NO_INTERFACE; + if ( !dataMgr || !dataProv ) return IInterface::Status::NO_INTERFACE; m_partitions.emplace( nam, Partition{dataProv, dataMgr, nam} ); - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } /// Drop a partition object. The name identifies the partition uniquely - STATUS drop( CSTR& nam ) override + StatusCode drop( CSTR& nam ) override { auto i = m_partitions.find( nam ); - if ( i == m_partitions.end() ) return PARTITION_NOT_PRESENT; + if ( i == m_partitions.end() ) return IPartitionControl::Status::PARTITION_NOT_PRESENT; if ( i->second.dataManager == m_current.dataManager ) { m_current = Partition(); } i->second.dataManager->clearStore().ignore(); m_partitions.erase( i ); - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } /// Drop a partition object. The name identifies the partition uniquely - STATUS drop( IInterface* pPartition ) override + StatusCode drop( IInterface* pPartition ) override { auto provider = SmartIF( pPartition ); - if ( !provider ) return NO_INTERFACE; + if ( !provider ) return IInterface::Status::NO_INTERFACE; auto i = std::find_if( std::begin( m_partitions ), std::end( m_partitions ), [&]( Partitions::const_reference p ) { return p.second.dataProvider == provider; } ); - if ( i == std::end( m_partitions ) ) return PARTITION_NOT_PRESENT; + if ( i == std::end( m_partitions ) ) return IPartitionControl::Status::PARTITION_NOT_PRESENT; i->second.dataManager->clearStore().ignore(); m_partitions.erase( i ); - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } /// Activate a partition object. The name identifies the partition uniquely. - STATUS activate( CSTR& nam ) override + StatusCode activate( CSTR& nam ) override { auto i = m_partitions.find( nam ); if ( i != m_partitions.end() ) { m_current = i->second; - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } m_current = {}; - return PARTITION_NOT_PRESENT; + return IPartitionControl::Status::PARTITION_NOT_PRESENT; } /// Activate a partition object. - STATUS activate( IInterface* pPartition ) override + StatusCode activate( IInterface* pPartition ) override { auto provider = SmartIF( pPartition ); m_current = Partition(); - if ( !provider ) return NO_INTERFACE; + if ( !provider ) return IInterface::Status::NO_INTERFACE; auto i = std::find_if( std::begin( m_partitions ), std::end( m_partitions ), [&]( Partitions::const_reference p ) { return p.second.dataProvider == provider; } ); - if ( i == std::end( m_partitions ) ) return PARTITION_NOT_PRESENT; + if ( i == std::end( m_partitions ) ) return IPartitionControl::Status::PARTITION_NOT_PRESENT; m_current = i->second; - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } /// Access a partition object. The name identifies the partition uniquely. - STATUS get( CSTR& nam, IInterface*& pPartition ) const override + StatusCode get( CSTR& nam, IInterface*& pPartition ) const override { auto i = m_partitions.find( nam ); if ( i != m_partitions.end() ) { pPartition = i->second.dataProvider; - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } pPartition = nullptr; - return PARTITION_NOT_PRESENT; + return IPartitionControl::Status::PARTITION_NOT_PRESENT; } /// Access the active partition object. @@ -570,14 +569,14 @@ public: if ( m_current.dataProvider ) { nam = m_current.name; pPartition = m_current.dataProvider; - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } nam.clear(); pPartition = nullptr; - return NO_ACTIVE_PARTITION; + return IPartitionControl::Status::NO_ACTIVE_PARTITION; } - STATUS attachServices() + StatusCode attachServices() { // Attach address creator facility m_addrCreator = service( m_loader, true ); @@ -601,18 +600,18 @@ public: return sc; } - STATUS detachServices() + StatusCode detachServices() { m_addrCreator.reset(); m_dataLoader.reset(); - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } /// Service initialisation - STATUS initialize() override + StatusCode initialize() override { // Nothing to do: just call base class initialisation - STATUS sc = Service::initialize(); + StatusCode sc = Service::initialize(); if ( !sc.isSuccess() ) return sc; sc = makePartitions(); if ( !sc.isSuccess() ) { @@ -623,9 +622,9 @@ public: } /// Service initialisation - STATUS reinitialize() override + StatusCode reinitialize() override { - STATUS sc = Service::reinitialize(); + StatusCode sc = Service::reinitialize(); if ( !sc.isSuccess() ) { error() << "Enable to reinitialize base class" << endmsg; return sc; @@ -642,11 +641,11 @@ public: return sc; } // return - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } /// Service initialisation - STATUS finalize() override + StatusCode finalize() override { setDataLoader( nullptr ).ignore(); clearStore().ignore(); @@ -671,41 +670,42 @@ public: } /// Prepare partition for usage - STATUS preparePartitions() + StatusCode preparePartitions() { - STATUS iret = STATUS::SUCCESS; + StatusCode iret = StatusCode::SUCCESS; for ( auto& i : m_partitions ) { - STATUS sc = dispatch_variant( m_root.root, - [&]( ADDRESS* address ) -> STATUS { - if ( !address ) return STATUS::FAILURE; - ADDRESS* pAdd = nullptr; - ADDRESS* p = address; - auto sc = m_addrCreator->createAddress( p->svcType(), p->clID(), p->par(), - p->ipar(), pAdd ); - return sc.isSuccess() ? i.second.dataManager->setRoot( m_root.path, pAdd ) : sc; - }, - [&]( OBJECT* object ) -> STATUS { - if ( object && object->clID() == CLID_DataObject ) { - return i.second.dataManager->setRoot( m_root.path, new DataObject() ); - } - return STATUS::FAILURE; - }, - []( boost::blank ) -> STATUS { return STATUS::FAILURE; } ); + StatusCode sc = + dispatch_variant( m_root.root, + [&]( ADDRESS* address ) -> StatusCode { + if ( !address ) return StatusCode::FAILURE; + ADDRESS* pAdd = nullptr; + ADDRESS* p = address; + auto sc = + m_addrCreator->createAddress( p->svcType(), p->clID(), p->par(), p->ipar(), pAdd ); + return sc.isSuccess() ? i.second.dataManager->setRoot( m_root.path, pAdd ) : sc; + }, + [&]( OBJECT* object ) -> StatusCode { + if ( object && object->clID() == CLID_DataObject ) { + return i.second.dataManager->setRoot( m_root.path, new DataObject() ); + } + return StatusCode::FAILURE; + }, + []( boost::blank ) -> StatusCode { return StatusCode::FAILURE; } ); if ( !sc.isSuccess() ) iret = sc; } return iret; } /// Clear all partitions - STATUS clearPartitions() + StatusCode clearPartitions() { for ( auto& i : m_partitions ) i.second.dataManager->clearStore().ignore(); m_partitions.clear(); - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } /// Create all partitions according to job options - STATUS makePartitions() + StatusCode makePartitions() { using Parser = Gaudi::Utils::AttribStringParser; std::string typ, nam; @@ -721,11 +721,11 @@ public: break; } } - STATUS sc = create( nam, typ ); + StatusCode sc = create( nam, typ ); if ( !sc.isSuccess() ) return sc; if ( m_defaultPartition.empty() ) m_defaultPartition = nam; } - return STATUS::SUCCESS; + return StatusCode::SUCCESS; } }; diff --git a/GaudiCommonSvc/src/DataSvc/PartitionSwitchAlg.cpp b/GaudiCommonSvc/src/DataSvc/PartitionSwitchAlg.cpp index ecf8f235f1..9fe034c22c 100644 --- a/GaudiCommonSvc/src/DataSvc/PartitionSwitchAlg.cpp +++ b/GaudiCommonSvc/src/DataSvc/PartitionSwitchAlg.cpp @@ -90,12 +90,12 @@ private: template StatusCode fwd_( StatusCode ( IPartitionControl::*fun )( FArgs... ), Args&&... args ) { - return m_actor ? ( m_actor->*fun )( std::forward( args )... ) : NO_INTERFACE; + return m_actor ? ( m_actor->*fun )( std::forward( args )... ) : IInterface::Status::NO_INTERFACE; } template StatusCode fwd_( StatusCode ( IPartitionControl::*fun )( FArgs... ) const, Args&&... args ) const { - return m_actor ? ( m_actor->*fun )( std::forward( args )... ) : NO_INTERFACE; + return m_actor ? ( m_actor->*fun )( std::forward( args )... ) : IInterface::Status::NO_INTERFACE; } public: diff --git a/GaudiCommonSvc/src/DataSvc/PartitionSwitchTool.cpp b/GaudiCommonSvc/src/DataSvc/PartitionSwitchTool.cpp index 16cb829411..5b8c889d42 100644 --- a/GaudiCommonSvc/src/DataSvc/PartitionSwitchTool.cpp +++ b/GaudiCommonSvc/src/DataSvc/PartitionSwitchTool.cpp @@ -57,49 +57,49 @@ public: /// Create a partition object. The name identifies the partition uniquely STATUS create( CSTR nam, CSTR typ ) override { - STATUS sc = m_actor ? m_actor->create( nam, typ ) : NO_INTERFACE; + STATUS sc = m_actor ? m_actor->create( nam, typ ) : IInterface::Status::NO_INTERFACE; CHECK( sc, "Cannot create partition: " + nam + " of type " + typ ); } /// Create a partition object. The name identifies the partition uniquely STATUS create( CSTR nam, CSTR typ, IInterface*& pPartition ) override { - STATUS sc = m_actor ? m_actor->create( nam, typ, pPartition ) : NO_INTERFACE; + STATUS sc = m_actor ? m_actor->create( nam, typ, pPartition ) : IInterface::Status::NO_INTERFACE; CHECK( sc, "Cannot create partition: " + nam + " of type " + typ ); } /// Drop a partition object. The name identifies the partition uniquely STATUS drop( CSTR nam ) override { - STATUS sc = m_actor ? m_actor->drop( nam ) : NO_INTERFACE; + STATUS sc = m_actor ? m_actor->drop( nam ) : IInterface::Status::NO_INTERFACE; CHECK( sc, "Cannot drop partition: " + nam ); } /// Drop a partition object. The name identifies the partition uniquely STATUS drop( IInterface* pPartition ) override { - STATUS sc = m_actor ? m_actor->drop( pPartition ) : NO_INTERFACE; + STATUS sc = m_actor ? m_actor->drop( pPartition ) : IInterface::Status::NO_INTERFACE; CHECK( sc, "Cannot drop partition by Interface." ); } /// Activate a partition object. The name identifies the partition uniquely. STATUS activate( CSTR nam ) override { - STATUS sc = m_actor ? m_actor->activate( nam ) : NO_INTERFACE; + STATUS sc = m_actor ? m_actor->activate( nam ) : IInterface::Status::NO_INTERFACE; CHECK( sc, "Cannot activate partition: " + nam ); } /// Activate a partition object. STATUS activate( IInterface* pPartition ) override { - STATUS sc = m_actor ? m_actor->activate( pPartition ) : NO_INTERFACE; + STATUS sc = m_actor ? m_actor->activate( pPartition ) : IInterface::Status::NO_INTERFACE; CHECK( sc, "Cannot activate partition by Interface." ); } /// Access a partition object. The name identifies the partition uniquely. STATUS get( CSTR nam, IInterface*& pPartition ) const override { - STATUS sc = m_actor ? m_actor->get( nam, pPartition ) : NO_INTERFACE; + STATUS sc = m_actor ? m_actor->get( nam, pPartition ) : IInterface::Status::NO_INTERFACE; CHECK( sc, "Cannot get partition " + nam ); } /// Access the active partition object. STATUS activePartition( std::string& nam, IInterface*& pPartition ) const override { - STATUS sc = m_actor ? m_actor->activePartition( nam, pPartition ) : NO_INTERFACE; + STATUS sc = m_actor ? m_actor->activePartition( nam, pPartition ) : IInterface::Status::NO_INTERFACE; CHECK( sc, "Cannot determine active partition." ); } }; diff --git a/GaudiCommonSvc/src/PersistencySvc/PersistencySvc.cpp b/GaudiCommonSvc/src/PersistencySvc/PersistencySvc.cpp index 21fbc94fc4..cb89d68105 100644 --- a/GaudiCommonSvc/src/PersistencySvc/PersistencySvc.cpp +++ b/GaudiCommonSvc/src/PersistencySvc/PersistencySvc.cpp @@ -65,9 +65,9 @@ StatusCode PersistencySvc::makeCall( int typ, IOpaqueAddress*& pAddress, DataObj svc = m_cnvDefault; break; default: - if ( !pAddress ) return INVALID_ADDRESS; + if ( !pAddress ) return Status::INVALID_ADDRESS; svc = service( pAddress->svcType() ); - if ( !svc ) return BAD_STORAGE_TYPE; + if ( !svc ) return Status::BAD_STORAGE_TYPE; break; } @@ -202,16 +202,16 @@ StatusCode PersistencySvc::addConverter( const CLID& /* clid */ ) { return Statu /// Add converter object to conversion service. StatusCode PersistencySvc::addConverter( IConverter* pConverter ) { - if ( !pConverter ) return NO_CONVERTER; + if ( !pConverter ) return Status::NO_CONVERTER; IConversionSvc* svc = service( pConverter->repSvcType() ); - return svc ? svc->addConverter( pConverter ) : BAD_STORAGE_TYPE; + return svc ? svc->addConverter( pConverter ) : Status::BAD_STORAGE_TYPE; } /// Remove converter object from conversion service (if present). StatusCode PersistencySvc::removeConverter( const CLID& clid ) { // Remove converter type from all services - StatusCode status = NO_CONVERTER, iret = StatusCode::SUCCESS; + StatusCode status = Status::NO_CONVERTER, iret = StatusCode::SUCCESS; for ( auto& i : m_cnvServices ) { iret = i.second.conversionSvc()->removeConverter( clid ); if ( iret.isSuccess() ) status = iret; @@ -258,7 +258,7 @@ SmartIF& PersistencySvc::service( long type ) /// Add data service StatusCode PersistencySvc::addCnvService( IConversionSvc* servc ) { - if ( !servc ) return BAD_STORAGE_TYPE; + if ( !servc ) return Status::BAD_STORAGE_TYPE; long type = servc->repSvcType(); long def_typ = ( m_cnvDefault ? m_cnvDefault->repSvcType() : 0 ); auto it = m_cnvServices.find( type ); @@ -291,7 +291,7 @@ StatusCode PersistencySvc::addCnvService( IConversionSvc* servc ) StatusCode PersistencySvc::removeCnvService( long svctype ) { auto it = m_cnvServices.find( svctype ); - if ( it == m_cnvServices.end() ) return BAD_STORAGE_TYPE; + if ( it == m_cnvServices.end() ) return Status::BAD_STORAGE_TYPE; it->second.service()->release(); it->second.addrCreator()->release(); m_cnvServices.erase( it ); @@ -326,7 +326,7 @@ StatusCode PersistencySvc::createAddress( long svc_type, const CLID& clid, const { refpAddress = nullptr; IAddressCreator* svc = addressCreator( svc_type ); - return svc ? svc->createAddress( svc_type, clid, pars, ipars, refpAddress ) : BAD_STORAGE_TYPE; + return svc ? svc->createAddress( svc_type, clid, pars, ipars, refpAddress ) : Status::BAD_STORAGE_TYPE; } /// Convert an address to string form @@ -342,7 +342,7 @@ StatusCode PersistencySvc::convertAddress( const IOpaqueAddress* pAddress, std:: clid = pAddress->clID(); } IAddressCreator* svc = addressCreator( svc_type ); - StatusCode status = BAD_STORAGE_TYPE; // Preset error + StatusCode status = Status::BAD_STORAGE_TYPE; // Preset error refAddress.clear(); if ( svc ) { @@ -368,7 +368,7 @@ StatusCode PersistencySvc::createAddress( long /* svc_type */, const CLID& /* cl std::string address_trailer; decodeAddrHdr( refAddress, new_svc_type, new_clid, address_trailer ); IAddressCreator* svc = addressCreator( new_svc_type ); - return svc ? svc->createAddress( new_svc_type, new_clid, address_trailer, refpAddress ) : BAD_STORAGE_TYPE; + return svc ? svc->createAddress( new_svc_type, new_clid, address_trailer, refpAddress ) : Status::BAD_STORAGE_TYPE; } /// Retrieve string from storage type and clid diff --git a/GaudiCoreSvc/src/ApplicationMgr/DLLClassManager.cpp b/GaudiCoreSvc/src/ApplicationMgr/DLLClassManager.cpp index 9f8712cabd..464bd89683 100644 --- a/GaudiCoreSvc/src/ApplicationMgr/DLLClassManager.cpp +++ b/GaudiCoreSvc/src/ApplicationMgr/DLLClassManager.cpp @@ -3,6 +3,7 @@ #include "GaudiKernel/GaudiException.h" #include "GaudiKernel/IAlgManager.h" #include "GaudiKernel/IIncidentSvc.h" +#include "GaudiKernel/IMessageSvc.h" #include "GaudiKernel/IService.h" #include "GaudiKernel/ISvcLocator.h" #include "GaudiKernel/ISvcManager.h" diff --git a/GaudiCoreSvc/src/ApplicationMgr/DLLClassManager.h b/GaudiCoreSvc/src/ApplicationMgr/DLLClassManager.h index e5f91a8a58..c48891cab3 100644 --- a/GaudiCoreSvc/src/ApplicationMgr/DLLClassManager.h +++ b/GaudiCoreSvc/src/ApplicationMgr/DLLClassManager.h @@ -15,6 +15,7 @@ class ICnvManager; class IAlgManager; class ISvcManager; class IObjManager; +class IMessageSvc; // // ClassName: DLLClassManager diff --git a/GaudiHive/src/HiveWhiteBoard.cpp b/GaudiHive/src/HiveWhiteBoard.cpp index 3258218830..ab566a0805 100644 --- a/GaudiHive/src/HiveWhiteBoard.cpp +++ b/GaudiHive/src/HiveWhiteBoard.cpp @@ -129,10 +129,10 @@ namespace template StatusCode fwd( Fun f ) { - if ( !s_current ) return IDataProviderSvc::INVALID_ROOT; + if ( !s_current ) return IDataProviderSvc::Status::INVALID_ROOT; return s_current->with_lock( [&]( Partition& p ) { auto* svc = p.get>>(); - return svc ? f( *svc ) : static_cast( IDataProviderSvc::INVALID_ROOT ); + return svc ? f( *svc ) : IDataProviderSvc::Status::INVALID_ROOT; } ); } } @@ -304,7 +304,7 @@ public: if ( pDataLoader ) pDataLoader->setDataProvider( this ); m_dataLoader = pDataLoader; for_( m_partitions, [&]( Partition& p ) { p.dataManager->setDataLoader( m_dataLoader, this ).ignore(); } ); - return SUCCESS; + return StatusCode::SUCCESS; } /// Add an item to the preload list StatusCode addPreLoadItem( const DataStoreItem& item ) override diff --git a/GaudiKernel/GaudiKernel/GaudiException.h b/GaudiKernel/GaudiKernel/GaudiException.h index 19418d2835..24515a731d 100644 --- a/GaudiKernel/GaudiKernel/GaudiException.h +++ b/GaudiKernel/GaudiKernel/GaudiException.h @@ -131,36 +131,14 @@ public: /// methods for overloaded printout to std::ostream& and MsgStream& virtual std::ostream& printOut( std::ostream& os = std::cerr ) const { - os << tag() << " \t " << message(); - switch ( code() ) { - case StatusCode::SUCCESS: - os << "\t StatusCode=SUCCESS"; - break; - case StatusCode::FAILURE: - os << "\t StatusCode=FAILURE"; - break; - default: - os << "\t StatusCode=" << code(); - break; - } + os << tag() << " \t " << message() << "\t StatusCode=" << code(); return ( 0 != previous() ) ? previous()->printOut( os << std::endl ) : os; } /// Output the exception to the Gaudi MsgStream virtual MsgStream& printOut( MsgStream& os ) const { - os << tag() << "\t" << message(); - switch ( code() ) { - case StatusCode::SUCCESS: - os << "\t StatusCode=SUCCESS"; - break; - case StatusCode::FAILURE: - os << "\t StatusCode=FAILURE"; - break; - default: - os << "\t StatusCode=" << code().getCode(); - break; - } + os << tag() << " \t " << message() << "\t StatusCode=" << code(); return ( 0 != previous() ) ? previous()->printOut( os << endmsg ) : os; } diff --git a/GaudiKernel/GaudiKernel/IConversionSvc.h b/GaudiKernel/GaudiKernel/IConversionSvc.h index a5360f9afd..d01793af2b 100644 --- a/GaudiKernel/GaudiKernel/IConversionSvc.h +++ b/GaudiKernel/GaudiKernel/IConversionSvc.h @@ -90,12 +90,22 @@ public: virtual StatusCode commitOutput( const std::string& outputFile, bool do_commit ) = 0; /// Status code definitions - enum Status { - /// Success - CONVERSIONSVC_NO_ERROR = ICONVERSIONSVC_LAST_ERROR + 1, + enum class Status : StatusCode::code_t { + /// Invalid address information + INVALID_ADDRESS = static_cast( IInterface::Status::LAST_ERROR ) + 1, + /// Object to be converted is invalid + INVALID_OBJECT, + /// No more memory available + NO_MEMORY, + /// Invalid storage type + BAD_STORAGE_TYPE, + /// Error retrieving source data from source store + NO_SOURCE_OBJECT, /// No proper converter is available to the service NO_CONVERTER }; }; +STATUSCODE_ENUM_DECL( IConversionSvc::Status ) + #endif // GAUDIKERNEL_ICONVERSIONSVC_H diff --git a/GaudiKernel/GaudiKernel/IConverter.h b/GaudiKernel/GaudiKernel/IConverter.h index b05190bdd9..0ea20b59d5 100644 --- a/GaudiKernel/GaudiKernel/IConverter.h +++ b/GaudiKernel/GaudiKernel/IConverter.h @@ -197,22 +197,6 @@ public: @param pObject Pointer to location of the object */ virtual StatusCode updateRepRefs( IOpaqueAddress* pAddress, DataObject* pObject ) = 0; - - /// Status code - enum Status { - /// Invalid address information - INVALID_ADDRESS = IInterface::LAST_ERROR + 1, - /// Object to be converted is invalid - INVALID_OBJECT, - /// No more memory available - NO_MEMORY, - /// Invalid storage type - BAD_STORAGE_TYPE, - /// Error retrieving source data from source store - NO_SOURCE_OBJECT, - /// Last entry - ICONVERSIONSVC_LAST_ERROR - }; }; #endif // GAUDIKERNEL_ICONVERTER_H diff --git a/GaudiKernel/GaudiKernel/ICounterSvc.h b/GaudiKernel/GaudiKernel/ICounterSvc.h index 1e77f14cb1..c7eac53700 100644 --- a/GaudiKernel/GaudiKernel/ICounterSvc.h +++ b/GaudiKernel/GaudiKernel/ICounterSvc.h @@ -223,12 +223,15 @@ public: /// Default Printout for counters virtual StatusCode defaultPrintout( MsgStream& log, const Counter* pCounter ) const = 0; // Return codes: - enum { + enum class Status : StatusCode::code_t { COUNTER_NOT_PRESENT = 2, // Error COUNTER_EXISTS = 4, // Error ? COUNTER_REMOVED = 3 // Type of success. Low bit set }; }; + +STATUSCODE_ENUM_DECL( ICounterSvc::Status ) + // ============================================================================ /// output operator for the counter object // ============================================================================ diff --git a/GaudiKernel/GaudiKernel/IDataProviderSvc.h b/GaudiKernel/GaudiKernel/IDataProviderSvc.h index 18ee02571b..63dcaa3cbf 100644 --- a/GaudiKernel/GaudiKernel/IDataProviderSvc.h +++ b/GaudiKernel/GaudiKernel/IDataProviderSvc.h @@ -485,7 +485,7 @@ public: virtual StatusCode unlinkObject( boost::string_ref fullPath ) = 0; /// Status code definitions - enum Status { + enum class Status : StatusCode::code_t { /// Success IDataProviderSvc_NO_ERROR = 1, /// The path for this objects is already in use @@ -515,4 +515,6 @@ public: }; }; +STATUSCODE_ENUM_DECL( IDataProviderSvc::Status ) + #endif // GAUDIKERNEL_IDATAPROVIDERSVC_H diff --git a/GaudiKernel/GaudiKernel/IInterface.h b/GaudiKernel/GaudiKernel/IInterface.h index 4553a85e57..978a5f937a 100644 --- a/GaudiKernel/GaudiKernel/IInterface.h +++ b/GaudiKernel/GaudiKernel/IInterface.h @@ -328,7 +328,9 @@ public: virtual StatusCode queryInterface( const InterfaceID& ti, void** pp ) = 0; /// Return status - enum Status { + enum class Status : StatusCode::code_t { + /// Failure + FAILURE = 0, /// Normal successful completion SUCCESS = 1, /// Requested interface is not available @@ -343,6 +345,8 @@ public: virtual ~IInterface() = default; }; +STATUSCODE_ENUM_DECL( IInterface::Status ) + namespace Gaudi { /// Cast a IInterface pointer to an IInterface specialization (TARGET). diff --git a/GaudiKernel/GaudiKernel/IPartitionControl.h b/GaudiKernel/GaudiKernel/IPartitionControl.h index 3bbb436b97..c49a725726 100644 --- a/GaudiKernel/GaudiKernel/IPartitionControl.h +++ b/GaudiKernel/GaudiKernel/IPartitionControl.h @@ -172,6 +172,9 @@ public: virtual StatusCode activePartition( std::string& name, IInterface*& pPartition ) const = 0; // Return codes: - enum { PARTITION_NOT_PRESENT = 2, PARTITION_EXISTS = 4, NO_ACTIVE_PARTITION = 6 }; + enum class Status : StatusCode::code_t { PARTITION_NOT_PRESENT = 2, PARTITION_EXISTS = 4, NO_ACTIVE_PARTITION = 6 }; }; + +STATUSCODE_ENUM_DECL( IPartitionControl::Status ) + #endif // GAUDIKERNEL_IPARTITIONCONTROL_H diff --git a/GaudiKernel/GaudiKernel/StatusCode.h b/GaudiKernel/GaudiKernel/StatusCode.h index b908e71760..09c2956bb3 100644 --- a/GaudiKernel/GaudiKernel/StatusCode.h +++ b/GaudiKernel/GaudiKernel/StatusCode.h @@ -1,42 +1,125 @@ #ifndef GAUDIKERNEL_STATUSCODE_H #define GAUDIKERNEL_STATUSCODE_H +#include "boost/preprocessor/facilities/overload.hpp" #include +#include #include #include "GaudiKernel/Kernel.h" +template +struct is_StatusCode_enum : std::false_type { +}; + /** - * @class StatusCode StatusCode.h GaudiKernel/StatusCode.h + * @class StatusCode * * This class is used for returning status codes from appropriate routines. + * A StatusCode is comprised of an (integer) value and a category (similar to std::error_code). + * By default StatusCodes are created within a default StatusCode::Category, which + * defines the isSuccess(), isFailure() and isRecoverable() behaviour depending on + * the value of the StatusCode. This behaviour can be modified by defining a custom + * StatusCode::Category and overriding the respective methods. + * + * To define a new StatusCode::Category, do the following: + * - Define an enum class with the values of the StatusCode + * - Register the enum with `STATUSCODE_ENUM_DECL( MyEnum )` + * - Derive your category from StatusCode::Category and implement/override the relevant methods + * - Register the new category with `STATUSCODE_ENUM_IMPL( MyEnum, MyCategory )` in a .cpp file * - * @author Iain Last - * @author Pere Mato - * @author Sebastien Ponce + * \par Combining StatusCodes + * - The bitwise logic operators (&, |, &=, |=) can be used to combine StatusCodes and follows + * three-valued (ternary) logic with RECOVERABLE being the third state. No short-circuiting is applied: + * \code + * StatusCode sc = sc1 & sc2; + * sc |= sc3; + * \endcode + * - The boolean logic operators (&&, ||) perform regular two-valued logic only considering + * success/failure. The usual short-circuiting applies: + * \code + * bool b = sc1 && sc2; + * \endcode + * + * \note + * The StatusCode values 0 and 1 are considered FAILURE/SUCCESS for all categories, i.e. + * - operator==() and operator!=() ignore the category for these two values + * - isSuccess() and isFailure() cannot be overridden for these two values + * + * \remark See https://akrzemi1.wordpress.com/2017/07/12/your-own-error-code for details on the underlying design */ - -class IMessageSvc; -class IStatusCodeSvc; - -class IgnoreError -{ -}; - class StatusCode final { public: - enum { FAILURE = 0, SUCCESS = 1, RECOVERABLE = 2 }; + typedef unsigned long code_t; ///< type of StatusCode value + + enum class ErrorCode : code_t { FAILURE = 0, SUCCESS = 1, RECOVERABLE = 2 }; + + /** + * @class StatusCode::Category + * + * The category assigned to a StatusCode. Derive from this class to implement your own category. + * The mapping of StatusCode values to success and recoverable conditions can be defined by + * overriding the appropriate methods. + */ + struct Category { + constexpr Category() noexcept = default; + virtual ~Category() {} + + /// Name of the category + virtual const char* name() const = 0; + + /// Description for code within this category + virtual std::string message( code_t code ) const { return "UNKNOWN(" + std::to_string( code ) + ")"; } + + /// Is code considered success ? + /// \note isFailure() cannot be overridden as it is defined as `!`isSuccess() + virtual bool isSuccess( code_t code ) const { return code == static_cast( ErrorCode::SUCCESS ); } + + /// Is code considered recoverable ? + virtual bool isRecoverable( code_t code ) const { return code == static_cast( ErrorCode::RECOVERABLE ); } + }; + + /// Default Gaudi StatusCode category + static const Category& default_category() noexcept; + + // Provide shorthands for default code values + constexpr const static auto SUCCESS = ErrorCode::SUCCESS; + constexpr const static auto FAILURE = ErrorCode::FAILURE; + constexpr const static auto RECOVERABLE = ErrorCode::RECOVERABLE; + + /// Default constructor + constexpr StatusCode() = default; - /// Constructor. - StatusCode() = default; + /// Constructor from enum type (allowing implicit conversion) + template ::value>::type> + StatusCode( T sc, bool checked = false ) noexcept + { + *this = StatusCode( static_cast( sc ), is_StatusCode_enum::instance ); + m_checked = checked; + } + + /// Constructor from code_t in the default category (explicit conversion only) + explicit StatusCode( code_t code, const StatusCode::Category& cat = default_category(), + bool checked = false ) noexcept + : m_cat( &cat ), m_code( code ), m_checked( checked ) + { + } - StatusCode( unsigned long code, bool checked = false ) : d_code( code ), m_checked( checked ) {} + /// Constructor from code_t and category (explicit conversion only) + explicit StatusCode( code_t code, bool checked ) noexcept : StatusCode( code, default_category(), checked ) {} - StatusCode( const StatusCode& rhs ) : d_code( rhs.d_code ), m_checked( rhs.m_checked ) { rhs.m_checked = true; } + /// Copy constructor + StatusCode( const StatusCode& rhs ) noexcept : m_cat( rhs.m_cat ), m_code( rhs.m_code ), m_checked( rhs.m_checked ) + { + rhs.m_checked = true; + } - /// Move constructor. - StatusCode( StatusCode&& rhs ) noexcept : d_code( rhs.d_code ), m_checked( rhs.m_checked ) { rhs.m_checked = true; } + /// Move constructor + StatusCode( StatusCode&& rhs ) noexcept : m_cat( rhs.m_cat ), m_code( rhs.m_code ), m_checked( rhs.m_checked ) + { + rhs.m_checked = true; + } /// Destructor. ~StatusCode() @@ -44,77 +127,66 @@ public: if ( UNLIKELY( s_checking ) ) check(); } - /** Test for a status code of SUCCESS. - * N.B. This is the only case where a function has succeeded. - */ - bool isSuccess() const + StatusCode& operator=( const StatusCode& rhs ) noexcept { - m_checked = true; - return ( d_code == SUCCESS ); + m_cat = rhs.m_cat; + m_code = rhs.m_code; + m_checked = std::exchange( rhs.m_checked, true ); + return *this; } - /** Test for a status code of FAILURE. - * N.B. This is a specific type of failure where there aren't any more - * appropriate status codes. To test for any failure use : - * if ( !StatusCode.isSuccess() ) ... - */ + bool isSuccess() const; bool isFailure() const { return !isSuccess(); } - bool isRecoverable() const - { - m_checked = true; - return ( d_code == RECOVERABLE ); - } + bool isRecoverable() const; + + /// Shorthand for isSuccess() + explicit operator bool() const { return isSuccess(); } - /// Get the status code by value. - unsigned long getCode() const + /// Retrieve value ("checks" the StatusCode) + code_t getCode() const { m_checked = true; - return d_code; + return m_code; } - /// Set the status code by value. - void setCode( unsigned long value ) - { - m_checked = false; - d_code = value; - } + /// Check/uncheck StatusCode + void setChecked( bool checked = true ) const { m_checked = checked; } - /// Ignore the checking code; - void setChecked() const { m_checked = true; } - void ignore() const { setChecked(); } + /// Ignore/check StatusCode + void ignore() const { setChecked( true ); } /// Has the StatusCode been checked? bool checked() const { return m_checked; } - /// Cast operator. - operator unsigned long() const { return getCode(); } + /// Retrieve category (does not "check" the StatusCode) + const StatusCode::Category& getCategory() const { return *m_cat; } - /// Assignment operator. - StatusCode& operator=( unsigned long value ) - { - setCode( value ); - return *this; - } - StatusCode& operator=( const StatusCode& rhs ) + /// Description (or name) of StatusCode value + std::string message() const { return getCategory().message( m_code ); } + + friend std::ostream& operator<<( std::ostream& s, const StatusCode& sc ) { - d_code = rhs.d_code; - m_checked = std::exchange( rhs.m_checked, true ); - return *this; + s << sc.message(); + return s; } - /// Comparison operator. - friend bool operator<( const StatusCode& a, const StatusCode& b ) { return a.d_code < b.d_code; } + /// Check if StatusCode value and category are the same + /// \note For code values `0(FAILURE)` and `1(SUCCESS)` the category is ignored + /// \note e.g. `sc==StatusCode::SUCCESS` is equivalent to `sc.isSuccess()` for all categories + friend bool operator==( const StatusCode& lhs, const StatusCode& rhs ); + friend bool operator!=( const StatusCode& lhs, const StatusCode& rhs ) { return !( lhs == rhs ); } - /// Comparison operator. - friend bool operator>( const StatusCode& a, const StatusCode& b ) { return a.d_code > b.d_code; } - -#ifndef _WIN32 - operator IgnoreError() const + /// Comparison (values are grouped by category first) + friend bool operator<( const StatusCode& lhs, const StatusCode& rhs ) { - m_checked = true; - return IgnoreError(); + lhs.m_checked = true; + rhs.m_checked = true; + return ( lhs.m_cat < rhs.m_cat || ( lhs.m_cat == rhs.m_cat && lhs.m_code < rhs.m_code ) ); } -#endif + + /// Ternary logic operator with RECOVERABLE being the "third" state + StatusCode& operator&=( const StatusCode& rhs ); + StatusCode& operator|=( const StatusCode& rhs ); ///< @copydoc operator&= static GAUDI_API void enableChecking(); static GAUDI_API void disableChecking(); @@ -149,27 +221,115 @@ public: } }; -protected: - /// The status code. - unsigned long d_code = SUCCESS; ///< The status code - mutable bool m_checked = false; ///< If the Status code has been checked - - static bool s_checking; ///< Global flag to control if StatusCode need to be checked - private: - void check(); + const Category* m_cat{&default_category()}; ///< The status code category + code_t m_code{static_cast( ErrorCode::SUCCESS )}; ///< The status code value + mutable bool m_checked{false}; ///< If the StatusCode has been checked + static bool s_checking; ///< Global flag to control if StatusCode need to be checked + + ErrorCode default_value() const; ///< Project onto the default StatusCode values + void check(); ///< Do StatusCode check }; -inline std::ostream& operator<<( std::ostream& s, const StatusCode& sc ) +/* + * Macros to declare/implement StatusCode enums/categories + */ + +/// Declare an enum to be used as StatusCode value +/// @param ENUM enum class +#define STATUSCODE_ENUM_DECL( ENUM ) \ + template <> \ + struct is_StatusCode_enum : std::true_type { \ + static const StatusCode::Category& instance; \ + }; + +/// Assign a category to the StatusCode enum declared with STATUSCODE_ENUM_DECL( ENUM ) +/// @param ENUM enum class +/// @param CATEGORY (optional) category, otherwise use default StatusCode category +#define STATUSCODE_ENUM_IMPL( ... ) BOOST_PP_OVERLOAD( STATUSCODE_ENUM_IMPL_, __VA_ARGS__ )( __VA_ARGS__ ) + +#define STATUSCODE_ENUM_IMPL_1( ENUM ) \ + const StatusCode::Category& is_StatusCode_enum::instance = StatusCode::default_category(); + +#define STATUSCODE_ENUM_IMPL_2( ENUM, CATEGORY ) \ + const StatusCode::Category& is_StatusCode_enum::instance = CATEGORY{}; + +// Declare the default StatusCode enum +STATUSCODE_ENUM_DECL( StatusCode::ErrorCode ) + +/* + * Inline methods + */ + +inline const StatusCode::Category& StatusCode::default_category() noexcept { - if ( sc.isSuccess() ) { - return s << "SUCCESS"; - } - if ( sc.isRecoverable() ) { - return s << "RECOVERABLE"; - } - s << "FAILURE"; - return ( StatusCode::FAILURE != sc.getCode() ) ? s << "(" << sc.getCode() << ")" : s; + return is_StatusCode_enum::instance; } -#endif // GAUDIKERNEL_STATUSCODES_H +inline bool StatusCode::isSuccess() const +{ + m_checked = true; + return ( m_code == static_cast( ErrorCode::SUCCESS ) || m_cat->isSuccess( m_code ) ); +} + +inline bool StatusCode::isRecoverable() const +{ + m_checked = true; + return m_cat->isRecoverable( m_code ); +} + +inline StatusCode::ErrorCode StatusCode::default_value() const +{ + bool save_checked = m_checked; // Preserve checked status + auto r = isSuccess() ? ErrorCode::SUCCESS : ( isRecoverable() ? ErrorCode::RECOVERABLE : ErrorCode::FAILURE ); + m_checked = save_checked; + return r; +} + +inline bool operator==( const StatusCode& lhs, const StatusCode& rhs ) +{ + lhs.m_checked = true; + rhs.m_checked = true; + return ( lhs.m_code == rhs.m_code ) && + ( lhs.m_code == static_cast( StatusCode::ErrorCode::SUCCESS ) || + lhs.m_code == static_cast( StatusCode::ErrorCode::FAILURE ) || + ( lhs.m_cat == rhs.m_cat ) ); +} + +inline StatusCode& StatusCode::operator&=( const StatusCode& rhs ) +{ + // Ternary AND lookup matrix + static constexpr StatusCode::code_t AND[3][3] = {{0, 0, 0}, {0, 1, 2}, {0, 2, 2}}; + + StatusCode::code_t l = static_cast( default_value() ); + StatusCode::code_t r = static_cast( rhs.default_value() ); + m_code = AND[l][r]; + rhs.m_checked = true; + return *this; +} + +inline StatusCode& StatusCode::operator|=( const StatusCode& rhs ) +{ + // Ternary OR lookup matrix + static constexpr StatusCode::code_t OR[3][3] = {{0, 1, 2}, {1, 1, 1}, {2, 1, 2}}; + + StatusCode::code_t l = static_cast( default_value() ); + StatusCode::code_t r = static_cast( rhs.default_value() ); + m_code = OR[l][r]; + rhs.m_checked = true; + return *this; +} + +/// Ternary AND operator +inline StatusCode operator&( StatusCode lhs, const StatusCode& rhs ) { return lhs &= rhs; } + +/// Ternary OR operator +inline StatusCode operator|( StatusCode lhs, const StatusCode& rhs ) { return lhs |= rhs; } + +/// Boolean AND assignment operator +inline bool& operator&=( bool& lhs, const StatusCode& sc ) { return lhs &= sc.isSuccess(); } + +/// Boolean OR assignment operator +inline bool& operator|=( bool& lhs, const StatusCode& sc ) { return lhs |= sc.isSuccess(); } + +#endif // GAUDIKERNEL_STATUSCODE_H diff --git a/GaudiKernel/src/Lib/AlgTool.cpp b/GaudiKernel/src/Lib/AlgTool.cpp index 8822795384..a11e6358e9 100644 --- a/GaudiKernel/src/Lib/AlgTool.cpp +++ b/GaudiKernel/src/Lib/AlgTool.cpp @@ -53,11 +53,11 @@ StatusCode AlgTool::queryInterface( const InterfaceID& riid, void** ppvi ) [&]( const std::pair& item ) { return item.first.versionMatch( riid ); } ); if ( i == std::end( m_interfaceList ) ) { *ppvi = nullptr; - return NO_INTERFACE; // RETURN + return Status::NO_INTERFACE; // RETURN } *ppvi = i->second; addRef(); - return SUCCESS; // RETURN + return StatusCode::SUCCESS; // RETURN } //------------------------------------------------------------------------------ const std::string& AlgTool::name() const @@ -160,7 +160,7 @@ AlgTool::AlgTool( const std::string& type, const std::string& name, const IInter } else { throw GaudiException( "Failure to create tool '" + type + "/" + name + "': illegal parent type '" + System::typeinfoName( typeid( *_p ) ) + "'", - "AlgTool", 0 ); + "AlgTool", StatusCode::FAILURE ); } // initialize output level from MessageSvc and initialize messaging (before enabling update handler) diff --git a/GaudiKernel/src/Lib/ConversionSvc.cpp b/GaudiKernel/src/Lib/ConversionSvc.cpp index fbc55f2996..dc65e3294e 100644 --- a/GaudiKernel/src/Lib/ConversionSvc.cpp +++ b/GaudiKernel/src/Lib/ConversionSvc.cpp @@ -29,8 +29,8 @@ namespace StatusCode ConversionSvc::makeCall( int typ, bool ignore_add, bool ignore_obj, bool update, IOpaqueAddress*& pAddress, DataObject*& pObject ) { - if ( !pAddress && !ignore_add ) return INVALID_ADDRESS; - if ( !pObject && !ignore_obj ) return INVALID_OBJECT; + if ( !pAddress && !ignore_add ) return Status::INVALID_ADDRESS; + if ( !pObject && !ignore_obj ) return Status::INVALID_OBJECT; const CLID& obj_class = ( pObject && !ignore_obj ) ? pObject->clID() : ( pAddress && !ignore_add ) ? pAddress->clID() : CLID_NULL; IConverter* cnv = converter( obj_class ); @@ -84,7 +84,7 @@ StatusCode ConversionSvc::makeCall( int typ, bool ignore_add, bool ignore_obj, b msgStream() << System::typeinfoName( typeid( *pObject ) ); } msgStream() << " CLID= " << obj_class << endmsg; - return NO_CONVERTER; + return Status::NO_CONVERTER; } void ConversionSvc::loadConverter( DataObject* ) {} @@ -221,7 +221,7 @@ StatusCode ConversionSvc::addConverter( const CLID& clid ) } pConverter->release(); } - return NO_CONVERTER; + return Status::NO_CONVERTER; } /// Add converter object to conversion service. @@ -233,7 +233,7 @@ StatusCode ConversionSvc::addConverter( IConverter* pConverter ) m_workers.emplace_back( clid, pConverter ); return StatusCode::SUCCESS; } - return NO_CONVERTER; + return Status::NO_CONVERTER; } /// Remove converter object from conversion service (if present). @@ -242,7 +242,7 @@ StatusCode ConversionSvc::removeConverter( const CLID& clid ) auto i = std::partition( std::begin( m_workers ), std::end( m_workers ), [f = CnvTest( clid )]( const WorkerEntry& we ) { return !f( we ); } ); - if ( i == std::end( m_workers ) ) return NO_CONVERTER; + if ( i == std::end( m_workers ) ) return Status::NO_CONVERTER; std::for_each( i, std::end( m_workers ), []( WorkerEntry& w ) { w.converter()->finalize().ignore(); } ); m_workers.erase( i, std::end( m_workers ) ); return StatusCode::SUCCESS; @@ -282,7 +282,7 @@ IConverter* ConversionSvc::createConverter( long typ, const CLID& clid, const IC /// Configure the freshly created converter StatusCode ConversionSvc::configureConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter ) { - if ( !pConverter ) return NO_CONVERTER; + if ( !pConverter ) return Status::NO_CONVERTER; pConverter->setConversionSvc( this ).ignore(); pConverter->setAddressCreator( m_addressCreator ).ignore(); pConverter->setDataProvider( m_dataSvc ).ignore(); @@ -292,13 +292,13 @@ StatusCode ConversionSvc::configureConverter( long /* typ */, const CLID& /* cli /// Initialize new converter StatusCode ConversionSvc::initializeConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter ) { - return pConverter ? pConverter->initialize() : NO_CONVERTER; + return pConverter ? pConverter->initialize() : Status::NO_CONVERTER; } /// Activate the freshly created converter StatusCode ConversionSvc::activateConverter( long /* typ */, const CLID& /* clid */, IConverter* pConverter ) { - return pConverter ? StatusCode::SUCCESS : StatusCode( NO_CONVERTER ); + return pConverter ? StatusCode::SUCCESS : StatusCode( Status::NO_CONVERTER ); } /// Retrieve the class type of objects the converter produces. diff --git a/GaudiKernel/src/Lib/DataSvc.cpp b/GaudiKernel/src/Lib/DataSvc.cpp index 088a4589cb..c07170fc93 100644 --- a/GaudiKernel/src/Lib/DataSvc.cpp +++ b/GaudiKernel/src/Lib/DataSvc.cpp @@ -87,9 +87,9 @@ StatusCode DataSvc::clearSubTree( boost::string_ref sub_tree_path ) StatusCode status = findObject( sub_tree_path, pObject ); if ( !status.isSuccess() ) return status; RegEntry* node_entry = CAST_REGENTRY( RegEntry*, pObject->registry() ); - if ( !node_entry ) return INVALID_OBJECT; + if ( !node_entry ) return Status::INVALID_OBJECT; RegEntry* parent = node_entry->parentEntry(); - if ( !parent ) return INVALID_PARENT; + if ( !parent ) return Status::INVALID_PARENT; parent->remove( node_entry ); return StatusCode::SUCCESS; } @@ -99,22 +99,22 @@ StatusCode DataSvc::clearSubTree( boost::string_ref sub_tree_path ) */ StatusCode DataSvc::clearSubTree( DataObject* pObject ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() ); - if ( !entry ) return INVALID_OBJECT; + if ( !entry ) return Status::INVALID_OBJECT; RegEntry* parent = entry->parentEntry(); - if ( !parent ) return INVALID_PARENT; + if ( !parent ) return Status::INVALID_PARENT; parent->remove( entry ); - return SUCCESS; + return StatusCode::SUCCESS; } /// IDataManagerSvc: Remove all data objects in the data store. StatusCode DataSvc::clearStore() { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; m_root->release(); m_root = nullptr; - return SUCCESS; + return StatusCode::SUCCESS; } /** IDataManagerSvc: Analyse by traversing all data objects below the @@ -130,16 +130,16 @@ StatusCode DataSvc::traverseSubTree( boost::string_ref sub_tree_path, IDataStore /// IDataManagerSvc: Analyse by traversing all data objects below the sub tree StatusCode DataSvc::traverseSubTree( DataObject* pObject, IDataStoreAgent* pAgent ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() ); - if ( !entry ) return INVALID_OBJECT; + if ( !entry ) return Status::INVALID_OBJECT; return entry->traverseTree( pAgent ); } /// IDataManagerSvc: Analyse by traversing all data objects in the data store. StatusCode DataSvc::traverseTree( IDataStoreAgent* pAgent ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; return m_root->traverseTree( pAgent ); } @@ -166,7 +166,7 @@ StatusCode DataSvc::i_setRoot( std::string root_path, DataObject* pRootObj ) m_root->setDataSvc( this ); // No done with GaudiHive. preLoad().ignore(); } - return SUCCESS; + return StatusCode::SUCCESS; } /** @@ -192,7 +192,7 @@ StatusCode DataSvc::i_setRoot( std::string root_path, IOpaqueAddress* pRootAddr m_root->setDataSvc( this ); // Not done with GaudiHive. preLoad().ignore(); } - return SUCCESS; + return StatusCode::SUCCESS; } /// IDataManagerSvc: Pass a default data loader to the service. @@ -200,21 +200,21 @@ StatusCode DataSvc::setDataLoader( IConversionSvc* pDataLoader, IDataProviderSvc { m_dataLoader = pDataLoader; if ( m_dataLoader ) m_dataLoader->setDataProvider( dpsvc ? dpsvc : this ).ignore(); - return SUCCESS; + return StatusCode::SUCCESS; } /// IDataManagerSvc: Explore the object store: retrieve the object's parent StatusCode DataSvc::objectParent( const DataObject* pObject, IRegistry*& refpParent ) { - if ( !pObject ) return INVALID_OBJECT; + if ( !pObject ) return Status::INVALID_OBJECT; return objectParent( pObject->registry(), refpParent ); } /// IDataManagerSvc: Explore the object store: retrieve the object's parent StatusCode DataSvc::objectParent( const IRegistry* pRegistry, IRegistry*& refpParent ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry ); - if ( !node_entry ) return INVALID_OBJECT; + if ( !node_entry ) return Status::INVALID_OBJECT; refpParent = node_entry->parent(); return StatusCode::SUCCESS; } @@ -222,7 +222,7 @@ StatusCode DataSvc::objectParent( const IRegistry* pRegistry, IRegistry*& refpPa /// IDataManagerSvc: Explore an object identified by its pointer. StatusCode DataSvc::objectLeaves( const DataObject* pObject, std::vector& leaves ) { - if ( !pObject ) return INVALID_OBJECT; + if ( !pObject ) return Status::INVALID_OBJECT; return objectLeaves( pObject->registry(), leaves ); } @@ -231,9 +231,9 @@ StatusCode DataSvc::objectLeaves( const DataObject* pObject, std::vector& leaves ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry ); - if ( !node_entry ) return INVALID_OBJECT; + if ( !node_entry ) return Status::INVALID_OBJECT; leaves = node_entry->leaves(); return StatusCode::SUCCESS; } @@ -241,7 +241,7 @@ StatusCode DataSvc::objectLeaves( const IRegistry* pRegistry, std::vector 0 && sep != boost::string_ref::npos ) { @@ -287,17 +287,17 @@ StatusCode DataSvc::registerAddress( IRegistry* parentObj, boost::string_ref obj if ( sc.isFailure() ) delete pLeaf; p_entry = par_entry->findLeaf( p_path ); } - if ( !p_entry ) return INVALID_PARENT; + if ( !p_entry ) return Status::INVALID_PARENT; return registerAddress( p_entry, o_path, pAddress ); } StatusCode status = par_entry->add( to_string( objPath ), pAddress ); - return status.isSuccess() ? status : DOUBL_OBJ_PATH; + return status.isSuccess() ? status : Status::DOUBL_OBJ_PATH; } /// IDataManagerSvc: Unregister object address from the data store. StatusCode DataSvc::unregisterAddress( boost::string_ref fullPath ) { - if ( fullPath.empty() ) return INVALID_OBJ_PATH; + if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH; return unregisterAddress( fullPath.front() != SEPARATOR ? m_root : nullptr, fullPath ); } @@ -310,8 +310,8 @@ StatusCode DataSvc::unregisterAddress( DataObject* pParent, boost::string_ref ob /// IDataManagerSvc: Unregister object address from the data store. StatusCode DataSvc::unregisterAddress( IRegistry* pParent, boost::string_ref objPath ) { - if ( !checkRoot() ) return INVALID_ROOT; - if ( objPath.empty() ) return INVALID_OBJ_PATH; + if ( !checkRoot() ) return Status::INVALID_ROOT; + if ( objPath.empty() ) return Status::INVALID_OBJ_PATH; if ( !pParent ) { if ( objPath.front() != SEPARATOR ) return unregisterAddress( m_root, objPath ); @@ -319,7 +319,7 @@ StatusCode DataSvc::unregisterAddress( IRegistry* pParent, boost::string_ref obj if ( sep != boost::string_ref::npos && objPath.substr( 0, sep ) == m_rootName ) { return unregisterAddress( m_root, objPath.substr( sep ) ); } - return INVALID_PARENT; + return Status::INVALID_PARENT; } if ( objPath.front() != SEPARATOR ) { return unregisterAddress( pParent, char( SEPARATOR ) + objPath ); @@ -336,7 +336,7 @@ StatusCode DataSvc::unregisterAddress( IRegistry* pParent, boost::string_ref obj if ( status.isSuccess() ) return status; } } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Register object with the data store. @@ -373,7 +373,7 @@ StatusCode DataSvc::registerObject( DataObject* parentObj, int item, DataObject* /// Register object with the data store. StatusCode DataSvc::registerObject( DataObject* parentObj, boost::string_ref objPath, DataObject* pObject ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; if ( !parentObj ) { if ( !objPath.empty() ) { @@ -385,11 +385,11 @@ StatusCode DataSvc::registerObject( DataObject* parentObj, boost::string_ref obj return registerObject( objPath.substr( 0, sep ), objPath.substr( sep ), pObject ); } } - return INVALID_OBJ_PATH; + return Status::INVALID_OBJ_PATH; } RegEntry* node_entry = CAST_REGENTRY( RegEntry*, parentObj->registry() ); if ( node_entry ) { - StatusCode status = INVALID_PARENT; + StatusCode status = Status::INVALID_PARENT; auto sep = find( objPath, SEPARATOR, 1 ); if ( sep != boost::string_ref::npos ) { auto p_path = objPath.substr( 0, sep ); @@ -432,13 +432,13 @@ StatusCode DataSvc::registerObject( DataObject* parentObj, boost::string_ref obj leaf->setObject( pObject ); status = StatusCode::SUCCESS; } else { - status = DOUBL_OBJ_PATH; + status = Status::DOUBL_OBJ_PATH; } } } return status; } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Unregister object from the data store. @@ -448,10 +448,10 @@ StatusCode DataSvc::unregisterObject( boost::string_ref fullPath ) StatusCode status = findObject( fullPath, pObject ); if ( status.isFailure() ) return status; RegEntry* pEntry = CAST_REGENTRY( RegEntry*, pObject->registry() ); - if ( !pEntry ) return INVALID_ROOT; - if ( !pEntry->isEmpty() ) return DIR_NOT_EMPTY; + if ( !pEntry ) return Status::INVALID_ROOT; + if ( !pEntry->isEmpty() ) return Status::DIR_NOT_EMPTY; RegEntry* pParent = pEntry->parentEntry(); - if ( !pParent ) return INVALID_PARENT; + if ( !pParent ) return Status::INVALID_PARENT; if ( pObject ) pObject->addRef(); pParent->remove( pEntry ); return StatusCode::SUCCESS; @@ -474,15 +474,15 @@ StatusCode DataSvc::unregisterObject( boost::string_ref parentPath, int item ) /// Unregister object from the data store. StatusCode DataSvc::unregisterObject( DataObject* pObject ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; RegEntry* entry = m_root->findLeaf( pObject ); - if ( !entry ) return INVALID_OBJECT; + if ( !entry ) return Status::INVALID_OBJECT; RegEntry* parent = entry->parentEntry(); - if ( !parent ) return INVALID_PARENT; - if ( !entry->isEmpty() ) return DIR_NOT_EMPTY; + if ( !parent ) return Status::INVALID_PARENT; + if ( !entry->isEmpty() ) return Status::DIR_NOT_EMPTY; if ( entry->object() ) entry->object()->addRef(); if ( parent ) parent->remove( entry ); - return SUCCESS; + return StatusCode::SUCCESS; } /// Unregister object from the data store. @@ -499,17 +499,17 @@ StatusCode DataSvc::unregisterObject( DataObject* pParentObj, boost::string_ref entry->object()->addRef(); } parent->remove( entry ); - return SUCCESS; + return StatusCode::SUCCESS; } - return DIR_NOT_EMPTY; + return Status::DIR_NOT_EMPTY; } - return INVALID_OBJECT; + return Status::INVALID_OBJECT; } } catch ( ... ) { } - return INVALID_PARENT; + return Status::INVALID_PARENT; } - return INVALID_ROOT; + return Status::INVALID_ROOT; } /// Unregister object from the data store. @@ -570,13 +570,13 @@ StatusCode DataSvc::loadObject( IRegistry* pRegistry ) */ StatusCode DataSvc::loadObject( IConversionSvc* pLoader, IRegistry* pRegistry ) { - StatusCode status = INVALID_OBJ_ADDR; + StatusCode status = Status::INVALID_OBJ_ADDR; DataObject* pObject = nullptr; if ( !pLoader ) { // Precondition: Data loader must be present - return handleDataFault( pRegistry ) ? StatusCode{SUCCESS} : NO_DATA_LOADER; + return handleDataFault( pRegistry ) ? StatusCode::SUCCESS : StatusCode( Status::NO_DATA_LOADER ); } if ( !pRegistry ) { // Precondition: Directory must be valid - return handleDataFault( pRegistry ) ? StatusCode{SUCCESS} : INVALID_OBJ_ADDR; + return handleDataFault( pRegistry ) ? StatusCode::SUCCESS : StatusCode( Status::INVALID_OBJ_ADDR ); } VERMSG << "Requested object " << pRegistry->identifier() << endmsg; @@ -589,12 +589,12 @@ StatusCode DataSvc::loadObject( IConversionSvc* pLoader, IRegistry* pRegistry ) if ( !m_inhibitPathes.empty() ) { auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), pRegistry->identifier() ); if ( inhibit != m_inhibitPathes.end() ) { - return NO_ACCESS; + return Status::NO_ACCESS; } } IOpaqueAddress* pAddress = pRegistry->address(); - if ( !pAddress ) { // Precondition: - return INVALID_OBJ_ADDR; // Address must be valid + if ( !pAddress ) { // Precondition: + return Status::INVALID_OBJ_ADDR; // Address must be valid } try { status = pLoader->createObj( pAddress, pObject ); // Call data loader @@ -610,20 +610,20 @@ StatusCode DataSvc::loadObject( IConversionSvc* pLoader, IRegistry* pRegistry ) } } catch ( const GaudiException& exc ) { if ( handleDataFault( pRegistry ) ) { - return SUCCESS; + return StatusCode::SUCCESS; } throw GaudiException( "GaudiException in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE, exc ); } catch ( const std::exception& x ) { if ( handleDataFault( pRegistry ) ) { - return SUCCESS; + return StatusCode::SUCCESS; } throw GaudiException( "std::exception in loadObject() " + pRegistry->identifier() + ": " + System::typeinfoName( typeid( x ) ) + ", " + x.what(), name(), StatusCode::FAILURE ); } catch ( ... ) { if ( handleDataFault( pRegistry ) ) { - return SUCCESS; + return StatusCode::SUCCESS; } throw GaudiException( "UNKN exception in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE ); } @@ -648,7 +648,7 @@ StatusCode DataSvc::retrieveEntry( RegEntry* parentObj, boost::string_ref path, StatusCode DataSvc::i_retrieveEntry( RegEntry* parentObj, boost::string_ref path, RegEntry*& pEntry ) { // A.Valassi 16.08.2001 avoid core dump if store is empty - if ( !checkRoot() ) return StatusCode( INVALID_ROOT, true ); + if ( !checkRoot() ) return StatusCode( Status::INVALID_ROOT, true ); static const auto empty = boost::string_ref{}; auto sep = find( path, SEPARATOR, 1 ); @@ -669,12 +669,12 @@ StatusCode DataSvc::i_retrieveEntry( RegEntry* parentObj, boost::string_ref path parentObj = m_root; path = path.substr( sep ); } else { - return INVALID_OBJ_PATH; + return Status::INVALID_OBJ_PATH; } sep = find( path, SEPARATOR, 1 ); } - StatusCode status = StatusCode( INVALID_ROOT, true ); + StatusCode status = StatusCode( Status::INVALID_ROOT, true ); if ( sep != boost::string_ref::npos ) { // the string contains a separator (after pos 0) if ( !parentObj->object() ) { // if the parent object has not been loaded yet, load it now status = loadObject( parentObj ); @@ -718,7 +718,7 @@ StatusCode DataSvc::i_retrieveEntry( RegEntry* parentObj, boost::string_ref path } // Check results and return - if ( !pEntry ) return INVALID_OBJ_PATH; + if ( !pEntry ) return Status::INVALID_OBJ_PATH; if ( !pEntry->object() ) return loadObject( pEntry ); if ( m_enableAccessHdlr ) { @@ -728,9 +728,9 @@ StatusCode DataSvc::i_retrieveEntry( RegEntry* parentObj, boost::string_ref path // // DataIncident incident(name(), m_accessName, pEntry->identifier()); // m_incidentSvc->fireIncident(incident); - return SUCCESS; + return StatusCode::SUCCESS; } - return SUCCESS; + return StatusCode::SUCCESS; } /// Retrieve object identified by its directory from the data store. @@ -785,20 +785,20 @@ StatusCode DataSvc::findObject( IRegistry* pRegistry, boost::string_ref path, Da RegEntry* root_entry = CAST_REGENTRY( RegEntry*, pReg ); if ( root_entry ) { if ( !path.empty() ) pReg = root_entry->find( path ); - if ( !pReg ) return INVALID_OBJ_PATH; + if ( !pReg ) return Status::INVALID_OBJ_PATH; pObject = pReg->object(); } - return ( !pObject ) ? OBJ_NOT_LOADED : IDataProviderSvc_NO_ERROR; + return ( !pObject ) ? Status::OBJ_NOT_LOADED : Status::IDataProviderSvc_NO_ERROR; } /// Find object identified by its full path in the data store. StatusCode DataSvc::findObject( boost::string_ref path, DataObject*& pObject ) { pObject = nullptr; - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; if ( path.empty() || path == m_rootName.value() ) { pObject = m_root->object(); - return !pObject ? OBJ_NOT_LOADED : IDataProviderSvc_NO_ERROR; + return !pObject ? Status::OBJ_NOT_LOADED : Status::IDataProviderSvc_NO_ERROR; } return ( path.front() != SEPARATOR ) ? findObject( m_rootName.value(), path, pObject ) : findObject( static_cast( nullptr ), path, pObject ); @@ -842,8 +842,8 @@ StatusCode DataSvc::updateObject( boost::string_ref updatePath ) /// Update object. StatusCode DataSvc::updateObject( IRegistry* pRegistry ) { - if ( !pRegistry ) { // Precondition: - return INVALID_OBJ_ADDR; // Addres must be valid + if ( !pRegistry ) { // Precondition: + return Status::INVALID_OBJ_ADDR; // Addres must be valid } DataObject* toUpdate = pRegistry->object(); if ( !toUpdate ) { // Try first to load @@ -855,26 +855,26 @@ StatusCode DataSvc::updateObject( IRegistry* pRegistry ) /// Update object. StatusCode DataSvc::updateObject( DataObject* toUpdate ) { - StatusCode status = INVALID_OBJ_ADDR; - if ( !toUpdate ) { // Precondition: - return INVALID_OBJECT; // Address must be valid + StatusCode status = Status::INVALID_OBJ_ADDR; + if ( !toUpdate ) { // Precondition: + return Status::INVALID_OBJECT; // Address must be valid } IRegistry* pRegistry = toUpdate->registry(); // Precondition: if ( !pRegistry ) { // Need valid registry - return INVALID_OBJECT; + return Status::INVALID_OBJECT; } IOpaqueAddress* pAddress = pRegistry->address(); // Precondition: if ( !pAddress ) { // Need valid address - return INVALID_OBJ_ADDR; + return Status::INVALID_OBJ_ADDR; } IConversionSvc* pLoader = getDataLoader( pRegistry ); - if ( !pLoader ) { // Precondition: - return NO_DATA_LOADER; // Data loader must be present + if ( !pLoader ) { // Precondition: + return Status::NO_DATA_LOADER; // Data loader must be present } if ( !m_inhibitPathes.empty() ) { auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), pRegistry->identifier() ); if ( inhibit != m_inhibitPathes.end() ) { - return NO_ACCESS; + return Status::NO_ACCESS; } } try { @@ -913,13 +913,13 @@ StatusCode DataSvc::updateObject( DataObject* parent, boost::string_ref updatePa // Link object StatusCode DataSvc::linkObject( IRegistry* from, boost::string_ref objPath, DataObject* to ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; try { RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from ); if ( from_entry ) { // First check if both objects are already registered to the store RegEntry* to_entry = m_root->findLeaf( to ); - if ( !to_entry ) return INVALID_OBJECT; + if ( !to_entry ) return Status::INVALID_OBJECT; auto sep = objPath.rfind( SEPARATOR ); if ( sep > 0 && sep != boost::string_ref::npos ) { // in case the objPath is a sub-directory itself DataObject* pO = nullptr; @@ -928,17 +928,17 @@ StatusCode DataSvc::linkObject( IRegistry* from, boost::string_ref objPath, Data } // Now register the soft link StatusCode status = from_entry->add( to_string( objPath ), to, true ); - return status.isSuccess() ? IDataProviderSvc_NO_ERROR : DOUBL_OBJ_PATH; + return status.isSuccess() ? Status::IDataProviderSvc_NO_ERROR : Status::DOUBL_OBJ_PATH; } } catch ( ... ) { } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Add a link to another object. StatusCode DataSvc::linkObject( boost::string_ref fullPath, DataObject* to ) { - if ( fullPath.empty() ) return INVALID_OBJ_PATH; + if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH; if ( fullPath.front() != SEPARATOR ) { return linkObject( m_rootName.value(), fullPath, to ); } @@ -963,13 +963,13 @@ StatusCode DataSvc::linkObject( DataObject* from, boost::string_ref objPath, Dat return linkObject( from_entry, objPath, to ); } } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Remove a link to another object. StatusCode DataSvc::unlinkObject( IRegistry* from, boost::string_ref objPath ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; try { RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from ); if ( from_entry ) { @@ -981,17 +981,17 @@ StatusCode DataSvc::unlinkObject( IRegistry* from, boost::string_ref objPath ) } StatusCode status = from_entry->remove( objPath ); if ( status.isSuccess() ) return status; - return INVALID_OBJ_PATH; + return Status::INVALID_OBJ_PATH; } } catch ( ... ) { } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Remove a link to another object. StatusCode DataSvc::unlinkObject( boost::string_ref fullPath ) { - if ( fullPath.empty() ) return INVALID_OBJ_PATH; + if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH; if ( fullPath.front() != SEPARATOR ) { return unlinkObject( m_rootName.value(), fullPath ); } @@ -1010,7 +1010,7 @@ StatusCode DataSvc::unlinkObject( boost::string_ref from, boost::string_ref objP /// Remove a link to another object. StatusCode DataSvc::unlinkObject( DataObject* from, boost::string_ref objPath ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; IRegistry* from_entry = m_root->findLeaf( from ); return unlinkObject( from_entry, objPath ); } diff --git a/GaudiKernel/src/Lib/IConversionSvc.cpp b/GaudiKernel/src/Lib/IConversionSvc.cpp new file mode 100644 index 0000000000..6d52fc33ff --- /dev/null +++ b/GaudiKernel/src/Lib/IConversionSvc.cpp @@ -0,0 +1,33 @@ +#include "GaudiKernel/IConversionSvc.h" +#include "GaudiKernel/StatusCode.h" + +namespace +{ + struct IConvSvcCategory : StatusCode::Category { + const char* name() const override { return "IConversionSvc"; } + + bool isRecoverable( StatusCode::code_t ) const override { return false; } + + std::string message( StatusCode::code_t code ) const override + { + switch ( static_cast( code ) ) { + case IConversionSvc::Status::INVALID_ADDRESS: + return "INVALID_ADDRESS"; + case IConversionSvc::Status::INVALID_OBJECT: + return "INVALID_OBJECT"; + case IConversionSvc::Status::NO_MEMORY: + return "NO_MEMORY"; + case IConversionSvc::Status::BAD_STORAGE_TYPE: + return "BAD_STORAGE_TYPE"; + case IConversionSvc::Status::NO_SOURCE_OBJECT: + return "NO_SOURCE_OBJECT"; + case IConversionSvc::Status::NO_CONVERTER: + return "NO_CONVERTER"; + default: + return StatusCode::default_category().message( code ); + } + } + }; +} + +STATUSCODE_ENUM_IMPL( IConversionSvc::Status, IConvSvcCategory ) diff --git a/GaudiKernel/src/Lib/ICounterSvc.cpp b/GaudiKernel/src/Lib/ICounterSvc.cpp index 998acb3ec1..16eaf84b0b 100644 --- a/GaudiKernel/src/Lib/ICounterSvc.cpp +++ b/GaudiKernel/src/Lib/ICounterSvc.cpp @@ -9,6 +9,32 @@ // ============================================================================ #include "GaudiKernel/ICounterSvc.h" #include "GaudiKernel/StatEntity.h" + +namespace +{ + struct ICounterSvcCategory : StatusCode::Category { + const char* name() const override { return "ICounterSvc"; } + + bool isRecoverable( StatusCode::code_t ) const override { return false; } + + std::string message( StatusCode::code_t code ) const override + { + switch ( static_cast( code ) ) { + case ICounterSvc::Status::COUNTER_NOT_PRESENT: + return "COUNTER_NOT_PRESENT"; + case ICounterSvc::Status::COUNTER_EXISTS: + return "COUNTER_EXISTS"; + case ICounterSvc::Status::COUNTER_REMOVED: + return "COUNTER_REMOVED"; + default: + return StatusCode::default_category().message( code ); + } + } + }; +} + +STATUSCODE_ENUM_IMPL( ICounterSvc::Status, ICounterSvcCategory ) + // ============================================================================ /** @file * Implementation file with helper methods for interface ICounterSvc diff --git a/GaudiKernel/src/Lib/IDataProviderSvc.cpp b/GaudiKernel/src/Lib/IDataProviderSvc.cpp new file mode 100644 index 0000000000..81fb011fc5 --- /dev/null +++ b/GaudiKernel/src/Lib/IDataProviderSvc.cpp @@ -0,0 +1,43 @@ +#include "GaudiKernel/IDataProviderSvc.h" +#include "GaudiKernel/StatusCode.h" + +namespace +{ + struct IDataProviderSvcCategory : StatusCode::Category { + const char* name() const override { return "IDataProviderSvc"; } + + bool isRecoverable( StatusCode::code_t ) const override { return false; } + + std::string message( StatusCode::code_t code ) const override + { + switch ( static_cast( code ) ) { + case IDataProviderSvc::Status::DOUBL_OBJ_PATH: + return "DOUBL_OBJ_PATH"; + case IDataProviderSvc::Status::INVALID_OBJ_PATH: + return "INVALID_OBJ_PATH"; + case IDataProviderSvc::Status::INVALID_ROOT: + return "INVALID_ROOT"; + case IDataProviderSvc::Status::INVALID_OBJECT: + return "INVALID_OBJECT"; + case IDataProviderSvc::Status::INVALID_PARENT: + return "INVALID_PARENT"; + case IDataProviderSvc::Status::OBJ_NOT_LOADED: + return "OBJ_NOT_LOADED"; + case IDataProviderSvc::Status::NO_DATA_LOADER: + return "NO_DATA_LOADER"; + case IDataProviderSvc::Status::INVALID_OBJ_ADDR: + return "INVALID_OBJ_ADDR"; + case IDataProviderSvc::Status::DIR_NOT_EMPTY: + return "DIR_NOT_EMPTY"; + case IDataProviderSvc::Status::NO_MORE_LEVELS: + return "NO_MORE_LEVELS"; + case IDataProviderSvc::Status::NO_ACCESS: + return "NO_ACCESS"; + default: + return StatusCode::default_category().message( code ); + } + } + }; +} + +STATUSCODE_ENUM_IMPL( IDataProviderSvc::Status, IDataProviderSvcCategory ) diff --git a/GaudiKernel/src/Lib/IInterface.cpp b/GaudiKernel/src/Lib/IInterface.cpp new file mode 100644 index 0000000000..2df9cfcd5f --- /dev/null +++ b/GaudiKernel/src/Lib/IInterface.cpp @@ -0,0 +1,25 @@ +#include "GaudiKernel/IInterface.h" +#include "GaudiKernel/StatusCode.h" + +namespace +{ + struct IInterfaceCategory : StatusCode::Category { + const char* name() const override { return "IInterface"; } + + bool isRecoverable( StatusCode::code_t ) const override { return false; } + + std::string message( StatusCode::code_t code ) const override + { + switch ( static_cast( code ) ) { + case IInterface::Status::NO_INTERFACE: + return "NO_INTERFACE"; + case IInterface::Status::VERSMISMATCH: + return "VERSMISMATCH"; + default: + return StatusCode::default_category().message( code ); + } + } + }; +} + +STATUSCODE_ENUM_IMPL( IInterface::Status, IInterfaceCategory ) diff --git a/GaudiKernel/src/Lib/IPartitionControl.cpp b/GaudiKernel/src/Lib/IPartitionControl.cpp new file mode 100644 index 0000000000..8085e406db --- /dev/null +++ b/GaudiKernel/src/Lib/IPartitionControl.cpp @@ -0,0 +1,27 @@ +#include "GaudiKernel/IPartitionControl.h" +#include "GaudiKernel/StatusCode.h" + +namespace +{ + struct IPartitionControlCategory : StatusCode::Category { + const char* name() const override { return "IPartitionControl"; } + + bool isRecoverable( StatusCode::code_t ) const override { return false; } + + std::string message( StatusCode::code_t code ) const override + { + switch ( static_cast( code ) ) { + case IPartitionControl::Status::PARTITION_NOT_PRESENT: + return "PARTITION_NOT_PRESENT"; + case IPartitionControl::Status::PARTITION_EXISTS: + return "PARTITION_EXISTS"; + case IPartitionControl::Status::NO_ACTIVE_PARTITION: + return "NO_ACTIVE_PARTITION"; + default: + return StatusCode::default_category().message( code ); + } + } + }; +} + +STATUSCODE_ENUM_IMPL( IPartitionControl::Status, IPartitionControlCategory ) diff --git a/GaudiKernel/src/Lib/StatusCode.cpp b/GaudiKernel/src/Lib/StatusCode.cpp index 6017bd4221..a307863563 100644 --- a/GaudiKernel/src/Lib/StatusCode.cpp +++ b/GaudiKernel/src/Lib/StatusCode.cpp @@ -8,13 +8,35 @@ #include "GaudiKernel/MsgStream.h" #include "GaudiKernel/System.h" #include -#include -#include -#include -#include +// statics bool StatusCode::s_checking( false ); +namespace +{ + /// Default StatusCode category + struct DefaultCategory : public StatusCode::Category { + + const char* name() const override { return "Gaudi"; } + + std::string message( StatusCode::code_t code ) const override + { + switch ( static_cast( code ) ) { + case StatusCode::ErrorCode::SUCCESS: + return "SUCCESS"; + case StatusCode::ErrorCode::FAILURE: + return "FAILURE"; + case StatusCode::ErrorCode::RECOVERABLE: + return "RECOVERABLE"; + default: + return "UNKNOWN(" + std::to_string( code ) + ")"; + } + } + }; +} + +STATUSCODE_ENUM_IMPL( StatusCode::ErrorCode, DefaultCategory ) + void StatusCode::enableChecking() { s_checking = true; } void StatusCode::disableChecking() { s_checking = false; } diff --git a/GaudiKernel/src/Lib/TsDataSvc.cpp b/GaudiKernel/src/Lib/TsDataSvc.cpp index 8eef2a232b..a2cd98a44f 100644 --- a/GaudiKernel/src/Lib/TsDataSvc.cpp +++ b/GaudiKernel/src/Lib/TsDataSvc.cpp @@ -92,9 +92,9 @@ StatusCode TsDataSvc::clearSubTree( boost::string_ref sub_tree_path ) StatusCode status = findObject( sub_tree_path, pObject ); if ( !status.isSuccess() ) return status; RegEntry* node_entry = CAST_REGENTRY( RegEntry*, pObject->registry() ); - if ( !node_entry ) return INVALID_OBJECT; + if ( !node_entry ) return Status::INVALID_OBJECT; RegEntry* parent = node_entry->parentEntry(); - if ( !parent ) return INVALID_PARENT; + if ( !parent ) return Status::INVALID_PARENT; parent->remove( node_entry ); return StatusCode::SUCCESS; } @@ -104,22 +104,22 @@ StatusCode TsDataSvc::clearSubTree( boost::string_ref sub_tree_path ) */ StatusCode TsDataSvc::clearSubTree( DataObject* pObject ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() ); - if ( !entry ) return INVALID_OBJECT; + if ( !entry ) return Status::INVALID_OBJECT; RegEntry* parent = entry->parentEntry(); - if ( !parent ) return INVALID_PARENT; + if ( !parent ) return Status::INVALID_PARENT; parent->remove( entry ); - return SUCCESS; + return StatusCode::SUCCESS; } /// IDataManagerSvc: Remove all data objects in the data store. StatusCode TsDataSvc::clearStore() { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; m_root->release(); m_root = nullptr; - return SUCCESS; + return StatusCode::SUCCESS; } /** IDataManagerSvc: Analyse by traversing all data objects below the @@ -137,9 +137,9 @@ StatusCode TsDataSvc::traverseSubTree( boost::string_ref sub_tree_path, IDataSto StatusCode TsDataSvc::traverseSubTree( DataObject* pObject, IDataStoreAgent* pAgent ) { STD_LOCK_GUARD_MACRO - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() ); - if ( !entry ) return INVALID_OBJECT; + if ( !entry ) return Status::INVALID_OBJECT; return entry->traverseTree( pAgent ); } @@ -147,7 +147,7 @@ StatusCode TsDataSvc::traverseSubTree( DataObject* pObject, IDataStoreAgent* pAg StatusCode TsDataSvc::traverseTree( IDataStoreAgent* pAgent ) { STD_LOCK_GUARD_MACRO - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; return m_root->traverseTree( pAgent ); } @@ -174,7 +174,7 @@ StatusCode TsDataSvc::i_setRoot( std::string root_path, DataObject* pRootObj ) m_root->setDataSvc( this ); // No done with GaudiHive. preLoad().ignore(); } - return SUCCESS; + return StatusCode::SUCCESS; } /** @@ -200,7 +200,7 @@ StatusCode TsDataSvc::i_setRoot( std::string root_path, IOpaqueAddress* pRootAdd m_root->setDataSvc( this ); // Not done with GaudiHive. preLoad().ignore(); } - return SUCCESS; + return StatusCode::SUCCESS; } /// IDataManagerSvc: Pass a default data loader to the service. @@ -212,23 +212,23 @@ StatusCode TsDataSvc::setDataLoader( IConversionSvc* pDataLoader, IDataProviderS pDataLoader->setDataProvider( dpsvc == nullptr ? this : dpsvc ).ignore(); } m_dataLoader = pDataLoader; - return SUCCESS; + return StatusCode::SUCCESS; } /// IDataManagerSvc: Explore the object store: retrieve the object's parent StatusCode TsDataSvc::objectParent( const DataObject* pObject, IRegistry*& refpParent ) { STD_LOCK_GUARD_MACRO - if ( !pObject ) return INVALID_OBJECT; + if ( !pObject ) return Status::INVALID_OBJECT; return objectParent( pObject->registry(), refpParent ); } /// IDataManagerSvc: Explore the object store: retrieve the object's parent StatusCode TsDataSvc::objectParent( const IRegistry* pRegistry, IRegistry*& refpParent ) { STD_LOCK_GUARD_MACRO - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry ); - if ( !node_entry ) return INVALID_OBJECT; + if ( !node_entry ) return Status::INVALID_OBJECT; refpParent = node_entry->parent(); return StatusCode::SUCCESS; } @@ -237,7 +237,7 @@ StatusCode TsDataSvc::objectParent( const IRegistry* pRegistry, IRegistry*& refp StatusCode TsDataSvc::objectLeaves( const DataObject* pObject, std::vector& leaves ) { STD_LOCK_GUARD_MACRO - if ( !pObject ) return INVALID_OBJECT; + if ( !pObject ) return Status::INVALID_OBJECT; return objectLeaves( pObject->registry(), leaves ); } @@ -247,9 +247,9 @@ StatusCode TsDataSvc::objectLeaves( const DataObject* pObject, std::vector& leaves ) { STD_LOCK_GUARD_MACRO - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry ); - if ( !node_entry ) return INVALID_OBJECT; + if ( !node_entry ) return Status::INVALID_OBJECT; leaves.insert( leaves.end(), node_entry->leaves().begin(), node_entry->leaves().end() ); // leaves = node_entry->leaves(); return StatusCode::SUCCESS; @@ -258,7 +258,7 @@ StatusCode TsDataSvc::objectLeaves( const IRegistry* pRegistry, std::vector 0 && sep != boost::string_ref::npos ) { auto p_path = objPath.substr( 0, sep ); @@ -306,17 +306,17 @@ StatusCode TsDataSvc::registerAddress( IRegistry* parentObj, boost::string_ref o if ( !sc.isSuccess() ) delete pLeaf; p_entry = par_entry->findLeaf( p_path ); } - if ( !p_entry ) return INVALID_PARENT; + if ( !p_entry ) return Status::INVALID_PARENT; return registerAddress( p_entry, o_path, pAddress ); } StatusCode status = par_entry->add( to_string( objPath ), pAddress ); - return status.isSuccess() ? status : DOUBL_OBJ_PATH; + return status.isSuccess() ? status : Status::DOUBL_OBJ_PATH; } /// IDataManagerSvc: Unregister object address from the data store. StatusCode TsDataSvc::unregisterAddress( boost::string_ref fullPath ) { - if ( fullPath.empty() ) return INVALID_OBJ_PATH; + if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH; IRegistry* pRegistry = nullptr; if ( fullPath.front() != SEPARATOR ) { return unregisterAddress( m_root, fullPath ); @@ -334,16 +334,16 @@ StatusCode TsDataSvc::unregisterAddress( DataObject* pParent, boost::string_ref /// IDataManagerSvc: Unregister object address from the data store. StatusCode TsDataSvc::unregisterAddress( IRegistry* pParent, boost::string_ref objPath ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; - if ( objPath.empty() ) return INVALID_OBJ_PATH; + if ( objPath.empty() ) return Status::INVALID_OBJ_PATH; if ( !pParent ) { if ( objPath.front() != SEPARATOR ) { return unregisterAddress( m_root, objPath ); } auto sep = find( objPath, SEPARATOR, 1 ); if ( sep == boost::string_ref::npos || objPath.substr( 0, sep ) != m_rootName.value() ) { - return INVALID_PARENT; + return Status::INVALID_PARENT; } return unregisterAddress( m_root, objPath.substr( sep ) ); } @@ -362,7 +362,7 @@ StatusCode TsDataSvc::unregisterAddress( IRegistry* pParent, boost::string_ref o if ( status.isSuccess() ) return status; } } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Register object with the data store. @@ -399,7 +399,7 @@ StatusCode TsDataSvc::registerObject( DataObject* parentObj, int item, DataObjec /// Register object with the data store. StatusCode TsDataSvc::registerObject( DataObject* parentObj, boost::string_ref objPath, DataObject* pObject ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; if ( !parentObj ) { if ( !objPath.empty() ) { if ( objPath.front() != SEPARATOR ) { @@ -410,11 +410,11 @@ StatusCode TsDataSvc::registerObject( DataObject* parentObj, boost::string_ref o return registerObject( objPath.substr( 0, sep ), objPath.substr( sep ), pObject ); } } - return INVALID_OBJ_PATH; + return Status::INVALID_OBJ_PATH; } RegEntry* node_entry = CAST_REGENTRY( RegEntry*, parentObj->registry() ); if ( node_entry ) { - StatusCode status = INVALID_PARENT; + StatusCode status = Status::INVALID_PARENT; auto sep = find( objPath, SEPARATOR, 1 ); if ( sep != boost::string_ref::npos ) { auto p_path = objPath.substr( 0, sep ); @@ -458,13 +458,13 @@ StatusCode TsDataSvc::registerObject( DataObject* parentObj, boost::string_ref o leaf->setObject( pObject ); status = StatusCode::SUCCESS; } else { - status = DOUBL_OBJ_PATH; + status = Status::DOUBL_OBJ_PATH; } } } return status; } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Unregister object from the data store. @@ -474,10 +474,10 @@ StatusCode TsDataSvc::unregisterObject( boost::string_ref fullPath ) StatusCode status = findObject( fullPath, pObject ); if ( status.isFailure() ) return status; RegEntry* pEntry = CAST_REGENTRY( RegEntry*, pObject->registry() ); - if ( !pEntry ) return INVALID_ROOT; - if ( !pEntry->isEmpty() ) return DIR_NOT_EMPTY; + if ( !pEntry ) return Status::INVALID_ROOT; + if ( !pEntry->isEmpty() ) return Status::DIR_NOT_EMPTY; RegEntry* pParent = pEntry->parentEntry(); - if ( !pParent ) return INVALID_PARENT; + if ( !pParent ) return Status::INVALID_PARENT; if ( pObject ) pObject->addRef(); pParent->remove( pEntry ); return StatusCode::SUCCESS; @@ -500,34 +500,34 @@ StatusCode TsDataSvc::unregisterObject( boost::string_ref parentPath, int item ) /// Unregister object from the data store. StatusCode TsDataSvc::unregisterObject( DataObject* pObject ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; RegEntry* entry = m_root->findLeaf( pObject ); - if ( !entry ) return INVALID_OBJECT; + if ( !entry ) return Status::INVALID_OBJECT; RegEntry* parent = entry->parentEntry(); - if ( !parent ) return INVALID_PARENT; - if ( !entry->isEmpty() ) return DIR_NOT_EMPTY; + if ( !parent ) return Status::INVALID_PARENT; + if ( !entry->isEmpty() ) return Status::DIR_NOT_EMPTY; if ( entry->object() ) entry->object()->addRef(); if ( parent ) parent->remove( entry ); - return SUCCESS; + return StatusCode::SUCCESS; } /// Unregister object from the data store. StatusCode TsDataSvc::unregisterObject( DataObject* pParentObj, boost::string_ref objectPath ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; try { RegEntry* parent = CAST_REGENTRY( RegEntry*, pParentObj->registry() ); if ( parent ) { RegEntry* entry = parent->findLeaf( objectPath ); - if ( !entry ) return INVALID_OBJECT; - if ( !entry->isEmpty() ) return DIR_NOT_EMPTY; + if ( !entry ) return Status::INVALID_OBJECT; + if ( !entry->isEmpty() ) return Status::DIR_NOT_EMPTY; if ( entry->object() ) entry->object()->addRef(); parent->remove( entry ); - return SUCCESS; + return StatusCode::SUCCESS; } } catch ( ... ) { } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Unregister object from the data store. @@ -581,19 +581,19 @@ StatusCode TsDataSvc::loadObject( IRegistry* pRegistry ) StatusCode TsDataSvc::loadObject( IConversionSvc* pLoader, IRegistry* pRegistry ) { STD_LOCK_GUARD_MACRO - StatusCode status = INVALID_OBJ_ADDR; + StatusCode status = Status::INVALID_OBJ_ADDR; DataObject* pObject = nullptr; if ( !pLoader ) { // Precondition: Data loader must be present if ( handleDataFault( pRegistry ) ) - return SUCCESS; + return StatusCode::SUCCESS; else - return NO_DATA_LOADER; + return Status::NO_DATA_LOADER; } if ( !pRegistry ) { // Precondition: Directory must be valid if ( handleDataFault( pRegistry ) ) - return SUCCESS; + return StatusCode::SUCCESS; else - return INVALID_OBJ_ADDR; + return Status::INVALID_OBJ_ADDR; } VERMSG << "Requested object " << pRegistry->identifier() << endmsg; @@ -606,11 +606,11 @@ StatusCode TsDataSvc::loadObject( IConversionSvc* pLoader, IRegistry* pRegistry if ( !m_inhibitPathes.empty() ) { const auto& ident = pRegistry->identifier(); auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), ident ); - if ( inhibit != m_inhibitPathes.end() ) return NO_ACCESS; + if ( inhibit != m_inhibitPathes.end() ) return Status::NO_ACCESS; } IOpaqueAddress* pAddress = pRegistry->address(); - if ( !pAddress ) { // Precondition: - return INVALID_OBJ_ADDR; // Address must be valid + if ( !pAddress ) { // Precondition: + return Status::INVALID_OBJ_ADDR; // Address must be valid } try { status = pLoader->createObj( pAddress, pObject ); // Call data loader @@ -625,16 +625,16 @@ StatusCode TsDataSvc::loadObject( IConversionSvc* pLoader, IRegistry* pRegistry status = pLoader->fillObjRefs( pAddress, pObject ); } } catch ( const GaudiException& exc ) { - if ( handleDataFault( pRegistry ) ) return SUCCESS; + if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS; throw GaudiException( "GaudiException in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE, exc ); } catch ( const std::exception& x ) { - if ( handleDataFault( pRegistry ) ) return SUCCESS; + if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS; throw GaudiException( "std::exception in loadObject() " + pRegistry->identifier() + ": " + System::typeinfoName( typeid( x ) ) + ", " + x.what(), name(), StatusCode::FAILURE ); } catch ( ... ) { - if ( handleDataFault( pRegistry ) ) return SUCCESS; + if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS; throw GaudiException( "UNKN exception in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE ); } if ( !status.isSuccess() ) { @@ -652,14 +652,14 @@ StatusCode TsDataSvc::retrieveEntry( RegEntry* parentObj, boost::string_ref path { STD_LOCK_GUARD_MACRO auto sep = find( path, SEPARATOR, 1 ); - StatusCode status = StatusCode( INVALID_ROOT, true ); + StatusCode status = StatusCode( Status::INVALID_ROOT, true ); pEntry = nullptr; // A.Valassi 16.08.2001 avoid core dump if store is empty if ( checkRoot() ) { if ( !parentObj ) { if ( path.empty() || path == m_rootName ) return retrieveEntry( m_root, "", pEntry ); if ( path.front() != SEPARATOR ) return retrieveEntry( m_root, path, pEntry ); - if ( sep == boost::string_ref::npos ) return INVALID_OBJ_PATH; + if ( sep == boost::string_ref::npos ) return Status::INVALID_OBJ_PATH; if ( !m_root->object() ) { RegEntry* r = nullptr; status = retrieveEntry( m_root, "", r ); @@ -711,7 +711,7 @@ StatusCode TsDataSvc::retrieveEntry( RegEntry* parentObj, boost::string_ref path } // Check results and return if ( !pEntry ) { - status = INVALID_OBJ_PATH; + status = Status::INVALID_OBJ_PATH; } else if ( !pEntry->object() ) { status = loadObject( pEntry ); } else if ( m_enableAccessHdlr ) { @@ -721,9 +721,9 @@ StatusCode TsDataSvc::retrieveEntry( RegEntry* parentObj, boost::string_ref path // // DataIncident incident(name(), m_accessName, pEntry->identifier()); // m_incidentSvc->fireIncident(incident); - status = SUCCESS; + status = StatusCode::SUCCESS; } else { - status = SUCCESS; + status = StatusCode::SUCCESS; } } return status; @@ -783,10 +783,10 @@ StatusCode TsDataSvc::findObject( IRegistry* pRegistry, boost::string_ref path, RegEntry* root_entry = CAST_REGENTRY( RegEntry*, pReg ); if ( root_entry ) { if ( !path.empty() ) pReg = root_entry->find( path ); - if ( !pReg ) return INVALID_OBJ_PATH; + if ( !pReg ) return Status::INVALID_OBJ_PATH; pObject = pReg->object(); } - return pObject ? IDataProviderSvc_NO_ERROR : OBJ_NOT_LOADED; + return pObject ? Status::IDataProviderSvc_NO_ERROR : Status::OBJ_NOT_LOADED; } /// Find object identified by its full path in the data store. @@ -794,10 +794,10 @@ StatusCode TsDataSvc::findObject( boost::string_ref path, DataObject*& pObject ) { STD_LOCK_GUARD_MACRO pObject = nullptr; - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; if ( path.empty() || path == m_rootName ) { pObject = m_root->object(); - return !pObject ? OBJ_NOT_LOADED : IDataProviderSvc_NO_ERROR; + return !pObject ? Status::OBJ_NOT_LOADED : Status::IDataProviderSvc_NO_ERROR; } if ( path.front() != SEPARATOR ) { return findObject( m_rootName.value(), path, pObject ); @@ -842,8 +842,8 @@ StatusCode TsDataSvc::updateObject( boost::string_ref updatePath ) /// Update object. StatusCode TsDataSvc::updateObject( IRegistry* pRegistry ) { - if ( !pRegistry ) { // Precondition: - return INVALID_OBJ_ADDR; // Addres must be valid + if ( !pRegistry ) { // Precondition: + return Status::INVALID_OBJ_ADDR; // Addres must be valid } DataObject* toUpdate = pRegistry->object(); if ( !toUpdate ) { // Try first to load @@ -856,26 +856,26 @@ StatusCode TsDataSvc::updateObject( IRegistry* pRegistry ) StatusCode TsDataSvc::updateObject( DataObject* toUpdate ) { STD_LOCK_GUARD_MACRO - StatusCode status = INVALID_OBJ_ADDR; - if ( !toUpdate ) { // Precondition: - return INVALID_OBJECT; // Address must be valid + StatusCode status = Status::INVALID_OBJ_ADDR; + if ( !toUpdate ) { // Precondition: + return Status::INVALID_OBJECT; // Address must be valid } IRegistry* pRegistry = toUpdate->registry(); // Precondition: if ( !pRegistry ) { // Need valid registry - return INVALID_OBJECT; + return Status::INVALID_OBJECT; } IOpaqueAddress* pAddress = pRegistry->address(); // Precondition: if ( !pAddress ) { // Need valid address - return INVALID_OBJ_ADDR; + return Status::INVALID_OBJ_ADDR; } IConversionSvc* pLoader = getDataLoader( pRegistry ); - if ( !pLoader ) { // Precondition: - return NO_DATA_LOADER; // Data loader must be present + if ( !pLoader ) { // Precondition: + return Status::NO_DATA_LOADER; // Data loader must be present } if ( !m_inhibitPathes.empty() ) { auto& ident = pRegistry->identifier(); auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), ident ); - if ( inhibit != m_inhibitPathes.end() ) return NO_ACCESS; + if ( inhibit != m_inhibitPathes.end() ) return Status::NO_ACCESS; } try { status = pLoader->updateObj( pAddress, toUpdate ); // Call data loader @@ -914,13 +914,13 @@ StatusCode TsDataSvc::updateObject( DataObject* parent, boost::string_ref update StatusCode TsDataSvc::linkObject( IRegistry* from, boost::string_ref objPath, DataObject* to ) { STD_LOCK_GUARD_MACRO - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; try { RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from ); if ( from_entry ) { // First check if both objects are already registered to the store RegEntry* to_entry = m_root->findLeaf( to ); - if ( !to_entry ) return INVALID_OBJECT; + if ( !to_entry ) return Status::INVALID_OBJECT; auto sep = objPath.rfind( SEPARATOR ); if ( sep > 0 && sep != boost::string_ref::npos ) { // in case the objPath is a sub-directory itself DataObject* pO = nullptr; @@ -929,18 +929,18 @@ StatusCode TsDataSvc::linkObject( IRegistry* from, boost::string_ref objPath, Da } // Now register the soft link StatusCode status = from_entry->add( to_string( objPath ), to, true ); - return status.isSuccess() ? IDataProviderSvc_NO_ERROR : DOUBL_OBJ_PATH; + return status.isSuccess() ? Status::IDataProviderSvc_NO_ERROR : Status::DOUBL_OBJ_PATH; } } catch ( ... ) { } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Add a link to another object. StatusCode TsDataSvc::linkObject( boost::string_ref fullPath, DataObject* to ) { STD_LOCK_GUARD_MACRO - if ( fullPath.empty() ) return INVALID_OBJ_PATH; + if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH; if ( fullPath.front() != SEPARATOR ) return linkObject( m_rootName.value(), fullPath, to ); auto sep = fullPath.rfind( SEPARATOR ); return linkObject( fullPath.substr( 0, sep ), fullPath.substr( sep ), to ); @@ -963,14 +963,14 @@ StatusCode TsDataSvc::linkObject( DataObject* from, boost::string_ref objPath, D IRegistry* from_entry = from->registry(); if ( from_entry ) return linkObject( from_entry, objPath, to ); } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Remove a link to another object. StatusCode TsDataSvc::unlinkObject( IRegistry* from, boost::string_ref objPath ) { STD_LOCK_GUARD_MACRO - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; try { RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from ); if ( from_entry ) { @@ -981,17 +981,17 @@ StatusCode TsDataSvc::unlinkObject( IRegistry* from, boost::string_ref objPath ) return sc.isSuccess() ? unlinkObject( pO->registry(), objPath.substr( sep ) ) : sc; } StatusCode status = from_entry->remove( objPath ); - return status.isSuccess() ? status : INVALID_OBJ_PATH; + return status.isSuccess() ? status : Status::INVALID_OBJ_PATH; } } catch ( ... ) { } - return INVALID_PARENT; + return Status::INVALID_PARENT; } /// Remove a link to another object. StatusCode TsDataSvc::unlinkObject( boost::string_ref fullPath ) { - if ( fullPath.empty() ) return INVALID_OBJ_PATH; + if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH; if ( fullPath.front() != SEPARATOR ) { return unlinkObject( m_rootName.value(), fullPath ); } @@ -1010,7 +1010,7 @@ StatusCode TsDataSvc::unlinkObject( boost::string_ref from, boost::string_ref ob /// Remove a link to another object. StatusCode TsDataSvc::unlinkObject( DataObject* from, boost::string_ref objPath ) { - if ( !checkRoot() ) return INVALID_ROOT; + if ( !checkRoot() ) return Status::INVALID_ROOT; return unlinkObject( m_root->findLeaf( from ), objPath ); } diff --git a/GaudiKernel/tests/src/test_StatusCode.cpp b/GaudiKernel/tests/src/test_StatusCode.cpp index a50d5c7fba..3b46124b4d 100644 --- a/GaudiKernel/tests/src/test_StatusCode.cpp +++ b/GaudiKernel/tests/src/test_StatusCode.cpp @@ -4,6 +4,58 @@ #include "GaudiKernel/StatusCode.h" +// Define my own error enum/category +enum class MyErr : StatusCode::code_t { + FAILURE = 0, + SUCCESS = 1, + RECOVERABLE = 2, + WARNING = 10, + OTHER_RECOVERABLE = 20 +}; + +STATUSCODE_ENUM_DECL( MyErr ) + +namespace +{ + struct MyCategory : StatusCode::Category { + const char* name() const override { return "My"; } + + bool isSuccess( StatusCode::code_t code ) const override + { + const MyErr e = static_cast( code ); + return e == MyErr::SUCCESS || ( e > MyErr::RECOVERABLE && e < MyErr::OTHER_RECOVERABLE ); + } + + bool isRecoverable( StatusCode::code_t code ) const override + { + return static_cast( code ) == MyErr::RECOVERABLE || static_cast( code ) == MyErr::OTHER_RECOVERABLE; + } + + std::string message( StatusCode::code_t code ) const override + { + switch ( static_cast( code ) ) { + case MyErr::WARNING: + return "WARNING"; + case MyErr::OTHER_RECOVERABLE: + return "OTHER_RECOVERABLE"; + default: + return StatusCode::default_category().message( code ); + } + } + }; +} + +STATUSCODE_ENUM_IMPL( MyErr, MyCategory ) + +// Test old-style enums +enum OtherErrors { ERROR_1 = 100, ERROR_2 = 200 }; + +STATUSCODE_ENUM_DECL( OtherErrors ) +STATUSCODE_ENUM_IMPL( OtherErrors ) + +// A test function +StatusCode func() { return StatusCode::SUCCESS; } + BOOST_AUTO_TEST_CASE( values ) { // default should be SUCCESS @@ -16,7 +68,6 @@ BOOST_AUTO_TEST_CASE( values ) { StatusCode sc( StatusCode::SUCCESS ); BOOST_CHECK( sc == StatusCode::SUCCESS ); - BOOST_CHECK( sc.getCode() == StatusCode::SUCCESS ); BOOST_CHECK( sc.isSuccess() == true ); BOOST_CHECK( sc.isFailure() == false ); BOOST_CHECK( sc.isRecoverable() == false ); @@ -27,7 +78,6 @@ BOOST_AUTO_TEST_CASE( values ) { StatusCode sc( StatusCode::FAILURE ); BOOST_CHECK( sc == StatusCode::FAILURE ); - BOOST_CHECK( sc.getCode() == StatusCode::FAILURE ); BOOST_CHECK( sc.isSuccess() == false ); BOOST_CHECK( sc.isFailure() == true ); BOOST_CHECK( sc.isRecoverable() == false ); @@ -38,27 +88,10 @@ BOOST_AUTO_TEST_CASE( values ) { StatusCode sc( StatusCode::RECOVERABLE ); BOOST_CHECK( sc == StatusCode::RECOVERABLE ); - BOOST_CHECK( sc.getCode() == StatusCode::RECOVERABLE ); BOOST_CHECK( sc.isSuccess() == false ); BOOST_CHECK( sc.isFailure() == true ); // !!! note, this particularity BOOST_CHECK( sc.isRecoverable() == true ); - BOOST_CHECK( static_cast( sc ) == true ); // !!! - } -} - -BOOST_AUTO_TEST_CASE( user_values ) -{ - enum Status { ERR1 = 10, ERR2 = 12 }; - - { - StatusCode sc( Status::ERR1 ); - BOOST_CHECK( sc.isSuccess() == false ); - BOOST_CHECK( sc.isFailure() == true ); - BOOST_CHECK( sc.isRecoverable() == false ); - BOOST_CHECK( static_cast( sc ) == true ); // !!! - - sc = Status::ERR2; - BOOST_CHECK( sc == Status::ERR2 ); + BOOST_CHECK( static_cast( sc ) == false ); } } @@ -70,16 +103,140 @@ BOOST_AUTO_TEST_CASE( comparison ) StatusCode sc2( sc ); BOOST_CHECK( sc == sc2 ); - sc2.setCode( StatusCode::FAILURE ); - BOOST_CHECK( sc > sc2 ); + sc2 = StatusCode::FAILURE; + // BOOST_CHECK( sc > sc2 ); // not implemented BOOST_CHECK( sc2 < sc ); } + // Comparison ignores category for SUCCESS/FAILURE + { + StatusCode sc1 = StatusCode::FAILURE; + StatusCode sc2 = MyErr::FAILURE; + BOOST_CHECK( sc1 == sc2 ); + } + // ...but not for other values + { + StatusCode sc1 = StatusCode::RECOVERABLE; + StatusCode sc2 = MyErr::RECOVERABLE; + BOOST_CHECK( sc1 != sc2 ); + } +} + +BOOST_AUTO_TEST_CASE( ternary_and ) +{ + StatusCode s = StatusCode::SUCCESS; + StatusCode f = StatusCode::FAILURE; + StatusCode r = StatusCode::RECOVERABLE; + + BOOST_CHECK( ( s & s ).isSuccess() ); + BOOST_CHECK( ( f & f ).isFailure() ); + BOOST_CHECK( ( r & r ).isRecoverable() ); + BOOST_CHECK( ( s & f ).isFailure() ); + BOOST_CHECK( ( f & s ).isFailure() ); + BOOST_CHECK( ( s & r ).isRecoverable() ); + BOOST_CHECK( ( r & s ).isRecoverable() ); + BOOST_CHECK( ( f & r ).isFailure() ); + BOOST_CHECK( ( r & f ).isFailure() ); + + // Test compound assignment (just compilation, logic is checked above) + StatusCode sc; + BOOST_CHECK( ( ( sc = s ) &= f ).isFailure() ); +} + +BOOST_AUTO_TEST_CASE( ternary_or ) +{ + StatusCode s = StatusCode::SUCCESS; + StatusCode f = StatusCode::FAILURE; + StatusCode r = StatusCode::RECOVERABLE; + + BOOST_CHECK( ( s | s ).isSuccess() ); + BOOST_CHECK( ( f | f ).isFailure() ); + BOOST_CHECK( ( r | r ).isRecoverable() ); + BOOST_CHECK( ( s | f ).isSuccess() ); + BOOST_CHECK( ( f | s ).isSuccess() ); + BOOST_CHECK( ( s | r ).isSuccess() ); + BOOST_CHECK( ( r | s ).isSuccess() ); + BOOST_CHECK( ( f | r ).isRecoverable() ); + BOOST_CHECK( ( r | f ).isRecoverable() ); + + StatusCode sc; + BOOST_CHECK( ( ( sc = s ) |= f ).isSuccess() ); +} + +BOOST_AUTO_TEST_CASE( boolean_logic ) +{ + StatusCode s = StatusCode::SUCCESS; + StatusCode f = StatusCode::FAILURE; + bool b = false; + b &= s; + BOOST_CHECK( b == false ); + b |= s; + BOOST_CHECK( b == true ); + b &= f; + BOOST_CHECK( b == false ); +} + +BOOST_AUTO_TEST_CASE( short_circuiting ) +{ + struct F { + StatusCode run( const StatusCode& sc ) + { + done = true; + return sc; + } + bool done{false}; + }; + + // Check AND short-circuiting + { + F a, b; + if ( a.run( StatusCode::FAILURE ) && b.run( StatusCode::SUCCESS ) ) { + } + BOOST_CHECK( a.done ); + BOOST_CHECK( b.done == false ); + } + { + F a, b; + if ( a.run( StatusCode::SUCCESS ) && b.run( StatusCode::SUCCESS ) ) { + } + BOOST_CHECK( a.done ); + BOOST_CHECK( b.done ); + } + // Check OR short-circuiting + { + F a, b; + if ( a.run( StatusCode::FAILURE ) || b.run( StatusCode::SUCCESS ) ) { + } + BOOST_CHECK( a.done ); + BOOST_CHECK( b.done ); + } + { + F a, b; + if ( a.run( StatusCode::SUCCESS ) || b.run( StatusCode::SUCCESS ) ) { + } + BOOST_CHECK( a.done ); + BOOST_CHECK( b.done == false ); + } + // Bitwise operators do not short-circuit + { + F a, b; + if ( a.run( StatusCode::FAILURE ) & b.run( StatusCode::SUCCESS ) ) { + } + BOOST_CHECK( a.done ); + BOOST_CHECK( b.done ); + } + { + F a, b; + if ( a.run( StatusCode::SUCCESS ) | b.run( StatusCode::SUCCESS ) ) { + } + BOOST_CHECK( a.done ); + BOOST_CHECK( b.done ); + } } BOOST_AUTO_TEST_CASE( checking ) { { - StatusCode sc( StatusCode::SUCCESS ); + StatusCode sc; BOOST_CHECK( sc.checked() == false ); sc.isSuccess(); BOOST_CHECK( sc.checked() == true ); @@ -89,26 +246,23 @@ BOOST_AUTO_TEST_CASE( checking ) sc.ignore(); BOOST_CHECK( sc.checked() == true ); } - // Comparison invokes implicit cast --> checked + // Comparison checks { StatusCode sc( StatusCode::SUCCESS ); if ( sc == StatusCode::SUCCESS ) ; BOOST_CHECK( sc.checked() == true ); } - // Using the comparison operator does not check - // This is probably unintentional and we may want to change this { StatusCode sc1( StatusCode::SUCCESS ); StatusCode sc2( StatusCode::FAILURE ); - BOOST_CHECK( sc1 > sc2 ); - BOOST_CHECK( sc1.checked() == false ); // !!! - BOOST_CHECK( sc2.checked() == false ); // !!! + BOOST_CHECK( sc2 < sc1 ); + BOOST_CHECK( sc1.checked() == true ); + BOOST_CHECK( sc2.checked() == true ); } - // Cast to long --> checked + // Cast to bool --> checked { StatusCode sc; - BOOST_CHECK( sc.checked() == false ); if ( sc ) ; BOOST_CHECK( sc.checked() == true ); @@ -128,4 +282,151 @@ BOOST_AUTO_TEST_CASE( checking ) BOOST_CHECK( sc1.checked() == true ); BOOST_CHECK( sc2.checked() == false ); } + // Function return check + { + StatusCode sc = func(); + BOOST_CHECK( sc.checked() == false ); + BOOST_CHECK( func().checked() == false ); + } + // Logical AND checks both if first is SUCCESS + { + StatusCode sc1( StatusCode::SUCCESS ); + StatusCode sc2( StatusCode::FAILURE ); + bool b = sc1 && sc2; + BOOST_CHECK( b == false ); + BOOST_CHECK( sc1.checked() == true ); + BOOST_CHECK( sc2.checked() == true ); + } + // Logical OR checks only first if SUCCESS + { + StatusCode sc1( StatusCode::SUCCESS ); + StatusCode sc2( StatusCode::FAILURE ); + bool b = sc1 || sc2; + BOOST_CHECK( b == true ); + BOOST_CHECK( sc1.checked() == true ); + BOOST_CHECK( sc2.checked() == false ); + } + // Ternary AND checks both + { + StatusCode sc1( StatusCode::SUCCESS ); + StatusCode sc2( StatusCode::FAILURE ); + StatusCode sc3 = sc1 & sc2; + BOOST_CHECK( sc1.checked() == true ); + BOOST_CHECK( sc2.checked() == true ); + BOOST_CHECK( sc3.checked() == false ); + } + // Ternary OR checks both + { + StatusCode sc1( StatusCode::SUCCESS ); + StatusCode sc2( StatusCode::FAILURE ); + StatusCode sc3 = sc1 | sc2; + BOOST_CHECK( sc1.checked() == true ); + BOOST_CHECK( sc2.checked() == true ); + BOOST_CHECK( sc3.checked() == false ); + } + // AND assignment checks rhs + { + StatusCode sc; + bool b = false; + b &= sc; + BOOST_CHECK( sc.checked() == true ); + } + // OR assignment checks rhs + { + StatusCode sc; + bool b = true; + b |= sc; + BOOST_CHECK( sc.checked() == true ); + } + // Ternary AND assignment checks rhs + { + StatusCode r, sc; + r &= sc; + BOOST_CHECK( sc.checked() == true ); + BOOST_CHECK( r.checked() == false ); + } + // Ternary OR assignment checks rhs + { + StatusCode r, sc; + r |= sc; + BOOST_CHECK( sc.checked() == true ); + BOOST_CHECK( r.checked() == false ); + } +} + +BOOST_AUTO_TEST_CASE( user_values ) +{ + { + enum Status { ERR1 = 10, ERR2 = 12 }; + + StatusCode sc( Status::ERR1 ); // need explicit conversion as enum is not registered + BOOST_CHECK( sc.isSuccess() == false ); + BOOST_CHECK( sc.isFailure() == true ); + BOOST_CHECK( sc.isRecoverable() == false ); + BOOST_CHECK( static_cast( sc ) == false ); + + sc = StatusCode( Status::ERR2 ); + BOOST_CHECK( sc.getCode() == Status::ERR2 ); + } + + { + StatusCode sc; + sc = OtherErrors::ERROR_1; // implicit conversion is OK here + BOOST_CHECK( sc.isSuccess() == false ); + BOOST_CHECK( sc.isFailure() == true ); + BOOST_CHECK( sc.isRecoverable() == false ); + BOOST_CHECK( static_cast( sc ) == false ); + + sc = OtherErrors::ERROR_2; + BOOST_CHECK( sc.getCode() == OtherErrors::ERROR_2 ); + } +} + +BOOST_AUTO_TEST_CASE( user_categories ) +{ + { + StatusCode sc( MyErr::FAILURE ); + BOOST_CHECK( sc.isSuccess() == false ); + BOOST_CHECK( sc.isFailure() == true ); + BOOST_CHECK( sc.isRecoverable() == false ); + BOOST_CHECK( sc == StatusCode::FAILURE ); + BOOST_CHECK( sc.getCategory().name() == std::string( "My" ) ); + BOOST_CHECK( sc.message() == std::string( "FAILURE" ) ); + } + { + StatusCode sc( MyErr::SUCCESS ); + BOOST_CHECK( sc.isSuccess() == true ); + BOOST_CHECK( sc.isFailure() == false ); + BOOST_CHECK( sc.isRecoverable() == false ); + BOOST_CHECK( sc == StatusCode::SUCCESS ); + BOOST_CHECK( sc.message() == std::string( "SUCCESS" ) ); + } + { + StatusCode sc( MyErr::WARNING ); + BOOST_CHECK( sc.isSuccess() == true ); + BOOST_CHECK( sc.isFailure() == false ); + BOOST_CHECK( sc.isRecoverable() == false ); + BOOST_CHECK( sc.message() == std::string( "WARNING" ) ); + } + { + StatusCode sc( MyErr::OTHER_RECOVERABLE ); + BOOST_CHECK( sc.isSuccess() == false ); + BOOST_CHECK( sc.isFailure() == true ); + BOOST_CHECK( sc.isRecoverable() == true ); + } +} + +BOOST_AUTO_TEST_CASE( conversions ) +{ + StatusCode sc; + + // Default codes + sc = StatusCode::SUCCESS; + // User defined enum class + sc = MyErr::SUCCESS; + // User defined enum + sc = OtherErrors::ERROR_1; + + // sc = 42; // no implicit conversion from int + // int i = sc; // no implicit conversion to int } diff --git a/GaudiSvc/src/DetectorDataSvc/DetDataSvc.cpp b/GaudiSvc/src/DetectorDataSvc/DetDataSvc.cpp index 52892b36ff..2bf5325f6f 100644 --- a/GaudiSvc/src/DetectorDataSvc/DetDataSvc.cpp +++ b/GaudiSvc/src/DetectorDataSvc/DetDataSvc.cpp @@ -213,7 +213,7 @@ StatusCode DetDataSvc::updateObject( DataObject* toUpdate ) // Check that object to update exists if ( !toUpdate ) { error() << "There is no DataObject to update" << endmsg; - return INVALID_OBJECT; + return Status::INVALID_OBJECT; } // Retrieve IValidity interface of object to update @@ -243,7 +243,7 @@ StatusCode DetDataSvc::updateObject( DataObject* toUpdate ) StatusCode status = TsDataSvc::updateObject( toUpdate ); if ( !status.isSuccess() ) { error() << "Could not update DataObject" << endmsg; - if ( status == NO_DATA_LOADER ) error() << "There is no data loader" << endmsg; + if ( status == Status::NO_DATA_LOADER ) error() << "There is no data loader" << endmsg; return status; } diff --git a/GaudiSvc/src/NTupleSvc/NTupleSvc.cpp b/GaudiSvc/src/NTupleSvc/NTupleSvc.cpp index 29f38ec384..9064fec46e 100644 --- a/GaudiSvc/src/NTupleSvc/NTupleSvc.cpp +++ b/GaudiSvc/src/NTupleSvc/NTupleSvc.cpp @@ -526,7 +526,7 @@ StatusCode NTupleSvc::save( const std::string& fullPath ) { NTuple::Tuple* pObj = nullptr; StatusCode status = findObject( fullPath, *pp_cast( &pObj ) ); // Check if object is present - return status.isSuccess() ? save( pObj ) : INVALID_OBJ_PATH; + return status.isSuccess() ? save( pObj ) : Status::INVALID_OBJ_PATH; } /// Save N tuple to disk. Must be called in order to close the ntuple file properly @@ -545,11 +545,11 @@ StatusCode NTupleSvc::save( NTuple::Tuple* n_tuple ) } return status; } - return IDataProviderSvc::NO_DATA_LOADER; + return Status::NO_DATA_LOADER; } catch ( ... ) { } } - return INVALID_OBJECT; + return Status::INVALID_OBJECT; } /// Save N tuple to disk. Must be called in order to close the ntuple file properly @@ -557,7 +557,7 @@ StatusCode NTupleSvc::save( DataObject* pParent, const std::string& relPath ) { NTuple::Tuple* pObj = nullptr; StatusCode status = findObject( pParent, relPath, *pp_cast( &pObj ) ); // Check if object is present - return status.isSuccess() ? save( pObj ) : INVALID_OBJ_PATH; + return status.isSuccess() ? save( pObj ) : Status::INVALID_OBJ_PATH; } /// Write single record to N tuple. @@ -581,11 +581,11 @@ StatusCode NTupleSvc::writeRecord( NTuple::Tuple* n_tuple ) } return status; } - return IDataProviderSvc::NO_DATA_LOADER; + return Status::NO_DATA_LOADER; } catch ( ... ) { } } - return INVALID_OBJECT; + return Status::INVALID_OBJECT; } /// Write single record to N tuple. @@ -593,7 +593,7 @@ StatusCode NTupleSvc::writeRecord( const std::string& fullPath ) { NTuple::Tuple* pObj = nullptr; StatusCode status = findObject( fullPath, *pp_cast( &pObj ) ); // Check if object is present - return status.isSuccess() ? writeRecord( pObj ) : INVALID_OBJ_PATH; + return status.isSuccess() ? writeRecord( pObj ) : Status::INVALID_OBJ_PATH; } /// Write single record to N tuple. @@ -601,13 +601,13 @@ StatusCode NTupleSvc::writeRecord( DataObject* pParent, const std::string& relPa { NTuple::Tuple* pObj = nullptr; StatusCode status = findObject( pParent, relPath, *pp_cast( &pObj ) ); // Check if object is present - return status.isSuccess() ? writeRecord( pObj ) : INVALID_OBJ_PATH; + return status.isSuccess() ? writeRecord( pObj ) : Status::INVALID_OBJ_PATH; } /// Read single record from N tuple. StatusCode NTupleSvc::readRecord( NTuple::Tuple* n_tuple ) { - StatusCode status = INVALID_OBJECT; + StatusCode status = Status::INVALID_OBJECT; NTuple::TupleImp* tuple = (NTuple::TupleImp*)n_tuple; if ( tuple ) { try { @@ -625,9 +625,9 @@ StatusCode NTupleSvc::readRecord( NTuple::Tuple* n_tuple ) } return status; } - status = IDataProviderSvc::NO_DATA_LOADER; + status = Status::NO_DATA_LOADER; } catch ( ... ) { - status = INVALID_OBJECT; + status = Status::INVALID_OBJECT; } } return status; @@ -638,7 +638,7 @@ StatusCode NTupleSvc::readRecord( const std::string& fullPath ) { NTuple::Tuple* pObj = nullptr; StatusCode status = findObject( fullPath, *pp_cast( &pObj ) ); // Check if object is present - return status.isSuccess() ? readRecord( pObj ) : INVALID_OBJ_PATH; + return status.isSuccess() ? readRecord( pObj ) : Status::INVALID_OBJ_PATH; } /// Read single record from N tuple. @@ -646,5 +646,5 @@ StatusCode NTupleSvc::readRecord( DataObject* pParent, const std::string& relPat { NTuple::Tuple* pObj = nullptr; StatusCode status = findObject( pParent, relPath, *pp_cast( &pObj ) ); // Check if object is present - return status.isSuccess() ? readRecord( pObj ) : INVALID_OBJ_PATH; + return status.isSuccess() ? readRecord( pObj ) : Status::INVALID_OBJ_PATH; } diff --git a/GaudiSvc/src/NTupleSvc/TagCollectionSvc.cpp b/GaudiSvc/src/NTupleSvc/TagCollectionSvc.cpp index 6f2ca78e8d..15e9a34c09 100644 --- a/GaudiSvc/src/NTupleSvc/TagCollectionSvc.cpp +++ b/GaudiSvc/src/NTupleSvc/TagCollectionSvc.cpp @@ -51,7 +51,7 @@ StatusCode TagCollectionSvc::connect( const std::string& ident, std::string& log DataObject* pO = nullptr; StatusCode status = findObject( m_rootName.value(), pO ); if ( status.isSuccess() ) { - status = INVALID_ROOT; + status = Status::INVALID_ROOT; if ( pO->registry() ) { char typ = 0; std::vector props; @@ -157,7 +157,7 @@ StatusCode TagCollectionSvc::createService( const std::string& nam, const std::s auto mgr = serviceLocator()->as(); // TagCollectionSvc has to directly create a ConversionSvc to manage it directly. - StatusCode status = NO_INTERFACE; + StatusCode status = IInterface::Status::NO_INTERFACE; if ( mgr ) { SmartIF isvc = mgr->createService( TypeNameString( nam, typ ) ); if ( isvc ) { diff --git a/GaudiUtils/GaudiUtils/IFileCatalog.h b/GaudiUtils/GaudiUtils/IFileCatalog.h index bed3a715e3..376bcf107d 100644 --- a/GaudiUtils/GaudiUtils/IFileCatalog.h +++ b/GaudiUtils/GaudiUtils/IFileCatalog.h @@ -7,6 +7,8 @@ #include #include +class IMessageSvc; + /* * Gaudi namespace declaration */ diff --git a/GaudiUtils/src/component/IODataManager.cpp b/GaudiUtils/src/component/IODataManager.cpp index 8e6990fed5..9e6a0ef0ff 100644 --- a/GaudiUtils/src/component/IODataManager.cpp +++ b/GaudiUtils/src/component/IODataManager.cpp @@ -251,7 +251,7 @@ StatusCode IODataManager::connectDataIO( int typ, IoType rw, CSTR dataset, CSTR if ( std::find( s_badFiles.begin(), s_badFiles.end(), dsn ) != s_badFiles.end() ) { m_incSvc->fireIncident( Incident( dsn, IncidentType::FailInputFile ) ); - return IDataConnection::BAD_DATA_CONNECTION; + return StatusCode( IDataConnection::BAD_DATA_CONNECTION ); } if ( typ == FID ) { auto fi = m_connectionMap.find( dsn ); @@ -263,7 +263,7 @@ StatusCode IODataManager::connectDataIO( int typ, IoType rw, CSTR dataset, CSTR if ( m_quarantine ) s_badFiles.insert( dsn ); m_incSvc->fireIncident( Incident( dsn, IncidentType::FailInputFile ) ); error( "connectDataIO> failed to resolve FID:" + dsn, false ).ignore(); - return IDataConnection::BAD_DATA_CONNECTION; + return StatusCode( IDataConnection::BAD_DATA_CONNECTION ); } else if ( dsn.length() == 36 && dsn[8] == '-' && dsn[13] == '-' ) { std::string gfal_name = "gfal:guid:" + dsn; m_fidMap[dsn] = m_fidMap[dataset] = m_fidMap[gfal_name] = dsn; @@ -274,7 +274,7 @@ StatusCode IODataManager::connectDataIO( int typ, IoType rw, CSTR dataset, CSTR if ( m_quarantine ) s_badFiles.insert( dsn ); m_incSvc->fireIncident( Incident( dsn, IncidentType::FailInputFile ) ); error( "connectDataIO> Failed to resolve FID:" + dsn, false ).ignore(); - return IDataConnection::BAD_DATA_CONNECTION; + return StatusCode( IDataConnection::BAD_DATA_CONNECTION ); } // keep track of the current return code before we start iterating over // replicas @@ -299,7 +299,7 @@ StatusCode IODataManager::connectDataIO( int typ, IoType rw, CSTR dataset, CSTR } log << MSG::ERROR << "Failed to open dsn:" << dsn << " Federated file could not be resolved from " << files.size() << " entries." << endmsg; - return IDataConnection::BAD_DATA_CONNECTION; + return StatusCode( IDataConnection::BAD_DATA_CONNECTION ); } return StatusCode::FAILURE; } @@ -313,7 +313,7 @@ StatusCode IODataManager::connectDataIO( int typ, IoType rw, CSTR dataset, CSTR if ( fid.empty() ) { m_incSvc->fireIncident( Incident( dsn, IncidentType::FailInputFile ) ); log << MSG::ERROR << "Failed to resolve LFN:" << dsn << " Cannot access this dataset." << endmsg; - return IDataConnection::BAD_DATA_CONNECTION; + return StatusCode( IDataConnection::BAD_DATA_CONNECTION ); } break; case PFN: @@ -346,7 +346,7 @@ StatusCode IODataManager::connectDataIO( int typ, IoType rw, CSTR dataset, CSTR if ( m_quarantine ) s_badFiles.insert( dsn ); m_incSvc->fireIncident( Incident( dsn, IncidentType::FailInputFile ) ); error( "connectDataIO> Cannot connect to database: PFN=" + dsn + " FID=" + fid, false ).ignore(); - return IDataConnection::BAD_DATA_CONNECTION; + return StatusCode( IDataConnection::BAD_DATA_CONNECTION ); } fid = connection->fid(); m_fidMap[dataset] = m_fidMap[dsn] = m_fidMap[fid] = fid; @@ -365,7 +365,7 @@ StatusCode IODataManager::connectDataIO( int typ, IoType rw, CSTR dataset, CSTR if ( m_quarantine ) s_badFiles.insert( dsn ); m_incSvc->fireIncident( Incident( dsn, IncidentType::FailInputFile ) ); error( "connectDataIO> Cannot connect to database: PFN=" + dsn + " FID=" + fid, false ).ignore(); - return IDataConnection::BAD_DATA_CONNECTION; + return StatusCode( IDataConnection::BAD_DATA_CONNECTION ); } return StatusCode::SUCCESS; } @@ -384,5 +384,5 @@ StatusCode IODataManager::connectDataIO( int typ, IoType rw, CSTR dataset, CSTR m_incSvc->fireIncident( Incident( dsn, IncidentType::FailInputFile ) ); error( "connectDataIO> The dataset " + dsn + " cannot be opened.", false ).ignore(); s_badFiles.insert( dsn ); - return IDataConnection::BAD_DATA_CONNECTION; + return StatusCode( IDataConnection::BAD_DATA_CONNECTION ); } diff --git a/RootCnv/RootCnv/RootDataConnection.h b/RootCnv/RootCnv/RootDataConnection.h index a6ccf51bc1..fcfa99a241 100644 --- a/RootCnv/RootCnv/RootDataConnection.h +++ b/RootCnv/RootCnv/RootDataConnection.h @@ -94,7 +94,7 @@ namespace Gaudi class GAUDI_API RootDataConnection : virtual public Gaudi::IDataConnection { public: - enum { ROOT_READ_ERROR = 0x2, ROOT_OPEN_ERROR = 0x4 }; + enum class Status : StatusCode::code_t { ROOT_READ_ERROR = 0x2, ROOT_OPEN_ERROR = 0x4 }; /** @class ContainerSection RootDataConnection.h GaudiRootCnv/RootDataConnection.h * @@ -337,4 +337,7 @@ namespace Gaudi } }; } // End namespace Gaudi + +STATUSCODE_ENUM_DECL( Gaudi::RootDataConnection::Status ) + #endif // GAUDIROOT_ROOTDATACONNECTION_H diff --git a/RootCnv/src/RootDataConnection.cpp b/RootCnv/src/RootDataConnection.cpp index d1ed1ae7e4..1e467d1e90 100644 --- a/RootCnv/src/RootDataConnection.cpp +++ b/RootCnv/src/RootDataConnection.cpp @@ -54,8 +54,28 @@ namespace std::iota( std::begin( table ), std::end( table ), 0 ); return table; } + + struct RootDataConnectionCategory : StatusCode::Category { + const char* name() const override { return "RootDataConnection"; } + + bool isRecoverable( StatusCode::code_t ) const override { return false; } + + std::string message( StatusCode::code_t code ) const override + { + switch ( static_cast( code ) ) { + case RootDataConnection::Status::ROOT_READ_ERROR: + return "ROOT_READ_ERROR"; + case RootDataConnection::Status::ROOT_OPEN_ERROR: + return "ROOT_OPEN_ERROR"; + default: + return StatusCode::default_category().message( code ); + } + } + }; } +STATUSCODE_ENUM_IMPL( Gaudi::RootDataConnection::Status, RootDataConnectionCategory ) + static bool match_wild( const char* str, const char* pat ) { // @@ -228,7 +248,7 @@ StatusCode RootDataConnection::connectRead() sc = m_tool->readRefs(); sc.ignore(); #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 ) - if ( sc == ROOT_READ_ERROR ) { + if ( sc == Status::ROOT_READ_ERROR ) { IIncidentSvc* inc = m_setup->incidentSvc(); if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); @@ -297,7 +317,7 @@ StatusCode RootDataConnection::connectWrite( IoType typ ) if ( makeTool() ) { StatusCode sc = m_tool->readRefs(); sc.ignore(); - if ( sc == ROOT_READ_ERROR ) { + if ( sc == Status::ROOT_READ_ERROR ) { #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 ) IIncidentSvc* inc = m_setup->incidentSvc(); if ( inc ) { diff --git a/RootCnv/src/RootTool.h b/RootCnv/src/RootTool.h index 80f75f5d7a..3bc67d02d1 100644 --- a/RootCnv/src/RootTool.h +++ b/RootCnv/src/RootTool.h @@ -122,14 +122,14 @@ namespace Gaudi msgSvc() << "Add Value[" << b->GetName() << "]:" << p << endmsg; ( this->*pmf )( v, p ); } else { - sc = RootDataConnection::ROOT_READ_ERROR; + sc = RootDataConnection::Status::ROOT_READ_ERROR; } } return sc; } } msgSvc() << MSG::ERROR << "Failed to read '" << nam << "' table." << endmsg; - return RootDataConnection::ROOT_READ_ERROR; + return RootDataConnection::Status::ROOT_READ_ERROR; } /// Analyze the Sections table entries bool get( const string& dsc, pair& e ) -- GitLab