Skip to content

Commit ef354fb

Browse files
committed
Added and_then function to Service class
Instead of testing for `isAvailable` and then running some code, one can pass the code to `and_then`. This mirrors what std::optional does in C++23.
1 parent 365705a commit ef354fb

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

FWCore/ServiceRegistry/interface/Service.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919
//
2020

2121
// system include files
22+
#include <optional>
2223

2324
// user include files
2425
#include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
2526

2627
// forward declarations
2728

2829
namespace edm {
29-
template <class T>
30+
template <typename T>
3031
class Service {
3132
public:
3233
Service() {}
@@ -41,6 +42,28 @@ namespace edm {
4142

4243
operator bool() const { return isAvailable(); }
4344

45+
///iF should be a functor and will only be called if the Service is available
46+
template <typename F>
47+
requires(!requires(F&& iF, T* t) {
48+
{ iF(*t) } -> std::same_as<void>;
49+
})
50+
auto and_then(F&& iF, T* t) -> std::optional<decltype(iF(*t))> const {
51+
if (isAvailable()) {
52+
return iF(*(operator->()));
53+
}
54+
return std::nullopt;
55+
}
56+
57+
template <typename F>
58+
requires(requires(F&& iF, T* t) {
59+
{ iF(*t) } -> std::same_as<void>;
60+
})
61+
void and_then(F&& iF) const {
62+
if (isAvailable()) {
63+
iF(*(operator->()));
64+
}
65+
}
66+
4467
// ---------- static member functions --------------------
4568

4669
// ---------- member functions ---------------------------

IOMC/RandomEngine/plugins/RandomEngineStateProducer.cc

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,20 @@ RandomEngineStateProducer::RandomEngineStateProducer(edm::ParameterSet const&) {
1919
RandomEngineStateProducer::~RandomEngineStateProducer() {}
2020

2121
void RandomEngineStateProducer::produce(edm::StreamID iID, edm::Event& ev, edm::EventSetup const&) const {
22-
edm::Service<edm::RandomNumberGenerator> randomService;
23-
if (randomService.isAvailable()) {
22+
edm::Service<edm::RandomNumberGenerator>().and_then([&ev](auto const& randomService) {
2423
auto states = std::make_unique<edm::RandomEngineStates>();
25-
states->setRandomEngineStates(randomService->getEventCache(ev.streamID()));
24+
states->setRandomEngineStates(randomService.getEventCache(ev.streamID()));
2625
ev.put(std::move(states));
27-
}
26+
});
2827
}
2928

3029
void RandomEngineStateProducer::globalBeginLuminosityBlockProduce(edm::LuminosityBlock& lb,
3130
edm::EventSetup const&) const {
32-
edm::Service<edm::RandomNumberGenerator> randomService;
33-
if (randomService.isAvailable()) {
31+
edm::Service<edm::RandomNumberGenerator>().and_then([&lb](auto const& randomService) {
3432
auto states = std::make_unique<edm::RandomEngineStates>();
35-
states->setRandomEngineStates(randomService->getLumiCache(lb.index()));
33+
states->setRandomEngineStates(randomService.getLumiCache(lb.index()));
3634
lb.put(std::move(states), "beginLumi");
37-
}
35+
});
3836
}
3937

4038
void RandomEngineStateProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {

0 commit comments

Comments
 (0)