From a969fb78170d25d8b48682f1a9a633ae479e7a37 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 26 Nov 2019 13:53:00 +0100 Subject: [PATCH] Bugfix: compilation error when trying to use get> There was compilation problem when using the InputRecord API with vectors of PODs. Adding also a test case to the unit test. --- .../Core/include/Framework/InputRecord.h | 20 +++++++++++-------- Framework/Core/test/test_DataAllocator.cxx | 18 ++++++++++++++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Framework/Core/include/Framework/InputRecord.h b/Framework/Core/include/Framework/InputRecord.h index 07ca7f7b3667b..35032f510e4ba 100644 --- a/Framework/Core/include/Framework/InputRecord.h +++ b/Framework/Core/include/Framework/InputRecord.h @@ -314,14 +314,18 @@ class InputRecord /// container, C++11 and beyond will implicitly apply return value optimization. /// @return std container object using NonConstT = typename std::remove_const::type; - // we expect the unique_ptr to hold an object, exception should have been thrown - // otherwise - auto object = DataRefUtils::as(ref); - // need to swap the content of the deserialized container to a local variable to force return - // value optimization - T container; - std::swap(const_cast(container), *object); - return container; + if constexpr (is_specialization::value == true || has_root_dictionary::value == true) { + // we expect the unique_ptr to hold an object, exception should have been thrown + // otherwise + auto object = DataRefUtils::as(ref); + // need to swap the content of the deserialized container to a local variable to force return + // value optimization + T container; + std::swap(const_cast(container), *object); + return container; + } else { + throw std::runtime_error("No supported conversion function for ROOT serialized message"); + } } else { throw std::runtime_error("Attempt to extract object from message with unsupported serialization type"); } diff --git a/Framework/Core/test/test_DataAllocator.cxx b/Framework/Core/test/test_DataAllocator.cxx index 4cdb49e74c40a..636945a8395a3 100644 --- a/Framework/Core/test/test_DataAllocator.cxx +++ b/Framework/Core/test/test_DataAllocator.cxx @@ -27,6 +27,7 @@ #include #include #include +#include // std::declval #include using namespace o2::framework; @@ -141,6 +142,11 @@ DataProcessorSpec getSourceSpec() pmrvec.reserve(100); pmrvec.emplace_back(o2::test::TriviallyCopyable{1, 2, 3}); pc.outputs().adoptContainer(pmrOutputSpec, std::move(pmrvec)); + + // make a vector of POD and set some data + pc.outputs().make>(OutputRef{"podvector"}) = {10, 21, 42}; + + // now we are done and signal this downstream pc.services().get().endOfStream(); pc.services().get().readyToQuit(QuitRequest::Me); @@ -169,7 +175,8 @@ DataProcessorSpec getSourceSpec() OutputSpec{"TST", "ROOTVECTOR", 0, Lifetime::Timeframe}, OutputSpec{"TST", "ROOTSERLZDVEC", 0, Lifetime::Timeframe}, OutputSpec{"TST", "ROOTSERLZDVEC2", 0, Lifetime::Timeframe}, - OutputSpec{"TST", "PMRTESTVECTOR", 0, Lifetime::Timeframe}}, + OutputSpec{"TST", "PMRTESTVECTOR", 0, Lifetime::Timeframe}, + OutputSpec{{"podvector"}, "TST", "PODVECTOR", 0, Lifetime::Timeframe}}, AlgorithmSpec(processingFct)}; } @@ -316,6 +323,14 @@ DataProcessorSpec getSinkSpec() auto header = o2::header::get(dataref.header); ASSERT_ERROR((header->payloadSize == sizeof(o2::test::TriviallyCopyable))); + LOG(INFO) << "extracting POD vector"; + // TODO: use the ReturnType helper once implemented + //InputRecord::ReturnType> podvector; + decltype(std::declval().get>(DataRef{nullptr, nullptr, nullptr})) podvector; + podvector = pc.inputs().get>("inputPODvector"); + ASSERT_ERROR(podvector.size() == 3); + ASSERT_ERROR(podvector[0] == 10 && podvector[1] == 21 && podvector[2] == 42); + pc.services().get().readyToQuit(QuitRequest::Me); }; @@ -336,6 +351,7 @@ DataProcessorSpec getSinkSpec() InputSpec{"input14", "TST", "ROOTSERLZBLOBJ", 0, Lifetime::Timeframe}, InputSpec{"input15", "TST", "ROOTSERLZBLVECT", 0, Lifetime::Timeframe}, InputSpec{"inputPMR", "TST", "PMRTESTVECTOR", 0, Lifetime::Timeframe}, + InputSpec{"inputPODvector", "TST", "PODVECTOR", 0, Lifetime::Timeframe}, InputSpec{"inputMP", ConcreteDataTypeMatcher{"TST", "MULTIPARTS"}, Lifetime::Timeframe}}, Outputs{OutputSpec{"TST", "MSGABLVECTORCPY", 0, Lifetime::Timeframe}}, AlgorithmSpec(processingFct)};