Skip to content

Commit

Permalink
Merge pull request #262 from veprbl/pr/deprecate_PodioTypeMap
Browse files Browse the repository at this point in the history
Deprecate PodioTypeMap
  • Loading branch information
nathanwbrei authored Nov 15, 2023
2 parents e0392f1 + 44b25c5 commit 99522e4
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 30 deletions.
7 changes: 6 additions & 1 deletion src/examples/PodioExample/DatamodelGlue.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@
#ifndef JANA2_DATAMODELGLUE_H
#define JANA2_DATAMODELGLUE_H

#include <podio/podioVersion.h>

#include <datamodel/ExampleHit.h>
#include <datamodel/ExampleHitCollection.h>
#include <datamodel/ExampleCluster.h>
#include <datamodel/ExampleClusterCollection.h>
#include <datamodel/EventInfo.h>
#include <datamodel/EventInfoCollection.h>

#if podio_VERSION < PODIO_VERSION(0, 17, 0)
/// Legacy PODIO support
template <typename T>
struct PodioTypeMap {
};
Expand All @@ -34,6 +38,7 @@ struct PodioTypeMap<EventInfo> {
using mutable_t = MutableEventInfo;
using collection_t = EventInfoCollection;
};
#endif


template<typename ... Ts>
Expand Down Expand Up @@ -61,7 +66,7 @@ void visitPodioType(const std::string& podio_typename, F& helper, ArgsT... args)
/*
visitPodioType(coll->getValueTypeName(),
[&]<typename T>(const podio::CollectionBase* coll, std::string name) {
using CollT = const typename PodioTypeMap<T>::collection_t;
using CollT = const typename T::collection_type;
CollT* typed_col = static_cast<CollT*>(coll);
std::cout << name << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion src/examples/PodioExample/PodioExampleProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct PrintingVisitor {
template <typename T>
void operator() (const podio::CollectionBase* collection, std::string collection_name) {
auto* typed_collection = static_cast<const typename PodioTypeMap<T>::collection_t*>(collection);
auto* typed_collection = static_cast<const typename T::collection_type*>(collection);
std::cout << collection_name << " :: " << collection->getValueTypeName() << " = [";
for (const T& object : *typed_collection) {
Expand Down
14 changes: 7 additions & 7 deletions src/libraries/JANA/JEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ class JEvent : public JResettable, public std::enable_shared_from_this<JEvent>
#ifdef HAVE_PODIO
std::vector<std::string> GetAllCollectionNames() const;
const podio::CollectionBase* GetCollectionBase(std::string name) const;
template <typename T> const typename PodioTypeMap<T>::collection_t* GetCollection(std::string name) const;
template <typename T> JFactoryPodioT<T>* InsertCollection(typename PodioTypeMap<T>::collection_t&& collection, std::string name);
template <typename T> JFactoryPodioT<T>* InsertCollectionAlreadyInFrame(const typename PodioTypeMap<T>::collection_t* collection, std::string name);
template <typename T> const typename JFactoryPodioT<T>::CollectionT* GetCollection(std::string name) const;
template <typename T> JFactoryPodioT<T>* InsertCollection(typename JFactoryPodioT<T>::CollectionT&& collection, std::string name);
template <typename T> JFactoryPodioT<T>* InsertCollectionAlreadyInFrame(const typename JFactoryPodioT<T>::CollectionT* collection, std::string name);
#endif

//SETTERS
Expand Down Expand Up @@ -457,20 +457,20 @@ inline const podio::CollectionBase* JEvent::GetCollectionBase(std::string name)
}

template <typename T>
const typename PodioTypeMap<T>::collection_t* JEvent::GetCollection(std::string name) const {
const typename JFactoryPodioT<T>::CollectionT* JEvent::GetCollection(std::string name) const {
JFactoryT<T>* factory = GetFactory<T>(name, true);
JFactoryPodioT<T>* typed_factory = dynamic_cast<JFactoryPodioT<T>*>(factory);
if (typed_factory == nullptr) {
throw JException("Factory must inherit from JFactoryPodioT in order to use JEvent::GetCollection()");
}
JCallGraphEntryMaker cg_entry(mCallGraph, typed_factory); // times execution until this goes out of scope
typed_factory->Create(this->shared_from_this());
return static_cast<const typename PodioTypeMap<T>::collection_t*>(typed_factory->GetCollection());
return static_cast<const typename JFactoryPodioT<T>::CollectionT*>(typed_factory->GetCollection());
}


template <typename T>
JFactoryPodioT<T>* JEvent::InsertCollection(typename PodioTypeMap<T>::collection_t&& collection, std::string name) {
JFactoryPodioT<T>* JEvent::InsertCollection(typename JFactoryPodioT<T>::CollectionT&& collection, std::string name) {
/// InsertCollection inserts the provided PODIO collection into both the podio::Frame and then a JFactoryPodioT<T>

auto frame = GetOrCreateFrame(shared_from_this());
Expand All @@ -480,7 +480,7 @@ JFactoryPodioT<T>* JEvent::InsertCollection(typename PodioTypeMap<T>::collection


template <typename T>
JFactoryPodioT<T>* JEvent::InsertCollectionAlreadyInFrame(const typename PodioTypeMap<T>::collection_t* collection, std::string name) {
JFactoryPodioT<T>* JEvent::InsertCollectionAlreadyInFrame(const typename JFactoryPodioT<T>::CollectionT* collection, std::string name) {
/// InsertCollection inserts the provided PODIO collection into a JFactoryPodioT<T>. It assumes that the collection pointer
/// is _already_ owned by the podio::Frame corresponding to this JEvent. This is meant to be used if you are starting out
/// with a PODIO frame (e.g. a JEventSource that uses podio::ROOTFrameReader).
Expand Down
8 changes: 4 additions & 4 deletions src/libraries/JANA/JMultifactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ class JMultifactory {
void DeclarePodioOutput(std::string tag, bool owns_data=true);

template <typename T>
void SetCollection(std::string tag, typename PodioTypeMap<T>::collection_t&& collection);
void SetCollection(std::string tag, typename JFactoryPodioT<T>::CollectionT&& collection);

template <typename T>
void SetCollection(std::string tag, std::unique_ptr<typename PodioTypeMap<T>::collection_t> collection);
void SetCollection(std::string tag, std::unique_ptr<typename JFactoryPodioT<T>::CollectionT> collection);

#endif

Expand Down Expand Up @@ -183,7 +183,7 @@ void JMultifactory::DeclarePodioOutput(std::string tag, bool owns_data) {
}

template <typename T>
void JMultifactory::SetCollection(std::string tag, typename PodioTypeMap<T>::collection_t&& collection) {
void JMultifactory::SetCollection(std::string tag, typename JFactoryPodioT<T>::CollectionT&& collection) {
JFactoryT<T>* helper = mHelpers.GetFactory<T>(tag);
if (helper == nullptr) {
throw JException("JMultifactory: Attempting to SetData() without corresponding DeclareOutput()");
Expand All @@ -198,7 +198,7 @@ void JMultifactory::SetCollection(std::string tag, typename PodioTypeMap<T>::col
}

template <typename T>
void JMultifactory::SetCollection(std::string tag, std::unique_ptr<typename PodioTypeMap<T>::collection_t> collection) {
void JMultifactory::SetCollection(std::string tag, std::unique_ptr<typename JFactoryPodioT<T>::CollectionT> collection) {
JFactoryT<T>* helper = mHelpers.GetFactory<T>(tag);
if (helper == nullptr) {
throw JException("JMultifactory: Attempting to SetData() without corresponding DeclareOutput()");
Expand Down
23 changes: 15 additions & 8 deletions src/libraries/JANA/Podio/JFactoryPodioT.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
#define JANA2_JFACTORYPODIOT_H

#include <JANA/JFactoryT.h>
#include <podio/podioVersion.h>
#include <podio/Frame.h>

#if podio_VERSION < PODIO_VERSION(0, 17, 0)
template <typename S> struct PodioTypeMap;
#endif

/// The point of this additional base class is to allow us _untyped_ access to the underlying PODIO collection,
/// at the cost of some weird multiple inheritance. The JEvent can trigger the untyped factory using Create(), then
Expand Down Expand Up @@ -38,7 +41,11 @@ class JFactoryPodio {
template <typename T>
class JFactoryPodioT : public JFactoryT<T>, public JFactoryPodio {
public:
#if podio_VERSION >= PODIO_VERSION(0, 17, 0)
using CollectionT = typename T::collection_type;
#else
using CollectionT = typename PodioTypeMap<T>::collection_t;
#endif
private:
// mCollection is owned by the frame.
// mFrame is owned by the JFactoryT<podio::Frame>.
Expand Down Expand Up @@ -87,7 +94,7 @@ JFactoryPodioT<T>::~JFactoryPodioT() {
}

template <typename T>
void JFactoryPodioT<T>::SetCollection(typename PodioTypeMap<T>::collection_t&& collection) {
void JFactoryPodioT<T>::SetCollection(CollectionT&& collection) {
/// Provide a PODIO collection. Note that PODIO assumes ownership of this collection, and the
/// collection pointer should be assumed to be invalid after this call

Expand All @@ -107,15 +114,15 @@ void JFactoryPodioT<T>::SetCollection(typename PodioTypeMap<T>::collection_t&& c


template <typename T>
void JFactoryPodioT<T>::SetCollection(std::unique_ptr<typename PodioTypeMap<T>::collection_t> collection) {
void JFactoryPodioT<T>::SetCollection(std::unique_ptr<CollectionT> collection) {
/// Provide a PODIO collection. Note that PODIO assumes ownership of this collection, and the
/// collection pointer should be assumed to be invalid after this call

if (this->mFrame == nullptr) {
throw JException("JFactoryPodioT: Unable to add collection to frame as frame is missing!");
}
this->mFrame->put(std::move(collection), this->GetTag());
const auto* moved = &this->mFrame->template get<typename PodioTypeMap<T>::collection_t>(this->GetTag());
const auto* moved = &this->mFrame->template get<CollectionT>(this->GetTag());
this->mCollection = moved;

for (const T& item : *moved) {
Expand Down Expand Up @@ -169,20 +176,20 @@ void JFactoryPodioT<T>::Create(const std::shared_ptr<const JEvent>& event) {
if (mCollection == nullptr) {
// If calling Create() excepts, we still create an empty collection
// so that podio::ROOTFrameWriter doesn't segfault on the null mCollection pointer
SetCollection(typename PodioTypeMap<T>::collection_t());
SetCollection(CollectionT());
}
throw;
}
if (mCollection == nullptr) {
SetCollection(typename PodioTypeMap<T>::collection_t());
SetCollection(CollectionT());
// If calling Process() didn't result in a call to Set() or SetCollection(), we create an empty collection
// so that podio::ROOTFrameWriter doesn't segfault on the null mCollection pointer
}
}

template <typename T>
void JFactoryPodioT<T>::Set(const std::vector<T*>& aData) {
typename PodioTypeMap<T>::collection_t collection;
CollectionT collection;
if (mIsSubsetCollection) collection.setSubsetCollection(true);
for (T* item : aData) {
collection.push_back(*item);
Expand All @@ -192,7 +199,7 @@ void JFactoryPodioT<T>::Set(const std::vector<T*>& aData) {

template <typename T>
void JFactoryPodioT<T>::Set(std::vector<T*>&& aData) {
typename PodioTypeMap<T>::collection_t collection;
CollectionT collection;
if (mIsSubsetCollection) collection.setSubsetCollection(true);
for (T* item : aData) {
collection.push_back(*item);
Expand All @@ -202,7 +209,7 @@ void JFactoryPodioT<T>::Set(std::vector<T*>&& aData) {

template <typename T>
void JFactoryPodioT<T>::Insert(T* aDatum) {
typename PodioTypeMap<T>::collection_t collection;
CollectionT collection;
if (mIsSubsetCollection) collection->setSubsetCollection(true);
collection->push_back(*aDatum);
SetCollection(std::move(collection));
Expand Down
18 changes: 11 additions & 7 deletions src/libraries/JANA/Podio/JPodioTypeHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,9 @@

#include <type_traits>

#include <podio/podioVersion.h>

/// These allow us to have both a PODIO-enabled and a PODIO-free definition of certain key structures and functions.
/// Ideally, we would use concepts for this. However, we are limiting ourselves to C++17 for now.
/// The user is expected to provide some datamodel glue which specializes PodioTypeMap like this:
/// template <> struct PodioTypeMap<ExampleHit> {
/// using collection_t = ExampleHitCollection;
/// using mutable_t = MutableExampleHit;
/// }
/// Eventually we hope to hang these type relations off of the Podio types themselves.

#ifdef HAVE_PODIO
// Sadly, this will only work with C++17 or higher, and for now JANA still supports C++14 (when not using PODIO)
Expand All @@ -27,7 +22,16 @@ template <typename, typename=void>
struct is_podio : std::false_type {};

template <typename T>
#if podio_VERSION >= PODIO_VERSION(0, 17, 0)
struct is_podio<T, std::void_t<typename T::collection_type>> : std::true_type {};
#else
/// The user was expected to provide some datamodel glue which specializes PodioTypeMap like this:
/// template <> struct PodioTypeMap<ExampleHit> {
/// using collection_t = ExampleHitCollection;
/// using mutable_t = MutableExampleHit;
/// }
struct is_podio<T, std::void_t<typename PodioTypeMap<T>::collection_t>> : std::true_type {};
#endif

template <typename T>
static constexpr bool is_podio_v = is_podio<T>::value;
Expand Down
4 changes: 2 additions & 2 deletions src/programs/unit_tests/PodioTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ struct MyWrapper {
};

template <typename T>
struct MyWrapper<T, std::void_t<typename PodioTypeMap<T>::collection_t>> {
struct MyWrapper<T, std::void_t<typename T::collection_type>> {
int x = 2;
bool have_podio() {
return true;
Expand All @@ -224,7 +224,7 @@ template <typename, typename=void>
struct is_podio : std::false_type {};

template <typename T>
struct is_podio<T, std::void_t<typename PodioTypeMap<T>::collection_t>> : std::true_type {};
struct is_podio<T, std::void_t<typename T::collection_type>> : std::true_type {};

template <typename T>
static constexpr bool is_podio_v = is_podio<T>::value;
Expand Down

0 comments on commit 99522e4

Please sign in to comment.