Skip to content

Commit

Permalink
Replace std::optional with JOptional
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanwbrei committed Sep 20, 2024
1 parent 34088d0 commit d29d6aa
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 15 deletions.
9 changes: 4 additions & 5 deletions src/libraries/JANA/Components/JStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <typeindex>
#include <vector>
#include <memory>
#include <optional>


class JFactory;
Expand All @@ -26,10 +25,10 @@ class JStorage {
// Fields
Status m_status = Status::Empty;
std::string m_collection_name;
std::optional<std::string> m_collection_tag = std::nullopt;
JOptional<std::string> m_collection_tag;
std::string m_type_name;
JFactory* m_factory = nullptr;
std::optional<std::type_index> m_inner_type_index = std::nullopt; // e.g. Hit, Cluster
JOptional<std::type_index> m_inner_type_index;
mutable JCallGraphRecorder::JDataOrigin m_insert_origin = JCallGraphRecorder::ORIGIN_NOT_AVAILABLE;

protected:
Expand All @@ -45,9 +44,9 @@ class JStorage {
// Getters
Status GetStatus() const { return m_status; }
std::string GetCollectionName() const { return m_collection_name; }
std::optional<std::string> GetCollectionTag() const { return m_collection_tag; }
JOptional<std::string> GetCollectionTag() const { return m_collection_tag; }
std::string GetTypeName() const { return m_type_name; }
std::optional<std::type_index> GetTypeIndex() const { return m_inner_type_index; }
JOptional<std::type_index> GetTypeIndex() const { return m_inner_type_index; }
JCallGraphRecorder::JDataOrigin GetInsertOrigin() const { return m_insert_origin; } ///< If objects were placed here by JEvent::Insert() this records whether that call was made from a source or factory.
JFactory* GetFactory() const { return m_factory; }

Expand Down
3 changes: 1 addition & 2 deletions src/libraries/JANA/JFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <vector>
#include <unordered_map>
#include <functional>
#include <optional>


class JEvent;
Expand Down Expand Up @@ -165,7 +164,7 @@ class JFactory : public jana::components::JComponent,
virtual void Process(const std::shared_ptr<const JEvent>&) {}
virtual void Finish() {}

virtual std::optional<std::type_index> GetObjectType() const { return std::nullopt; }
virtual std::type_index GetObjectType() const { throw JException("GetObjectType not supported for non-JFactoryT's"); }

virtual std::size_t GetNumObjects() const {
throw JException("Not implemented!");
Expand Down
17 changes: 10 additions & 7 deletions src/libraries/JANA/JFactorySet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ bool JFactorySet::Add(JFactory* aFactory)


mAllFactories.push_back(aFactory);
auto object_type = aFactory->GetObjectType();
if (object_type != std::nullopt) {

if (aFactory->GetOutputs().empty()) {
// We have an old-style JFactory!

auto typed_key = std::make_pair( *object_type, aFactory->GetTag() );
auto typed_key = std::make_pair( aFactory->GetObjectType(), aFactory->GetTag() );
auto untyped_key = std::make_pair( aFactory->GetObjectName(), aFactory->GetTag() );

auto typed_result = mFactories.find(typed_key);
Expand Down Expand Up @@ -291,10 +291,13 @@ void JFactorySet::Print() const

/// Release() loops over all contained factories, clearing their data
void JFactorySet::Release() {

for (const auto& sFactoryPair : mFactories) {
auto sFactory = sFactoryPair.second;
sFactory->ClearData();
for (auto* fac : mAllFactories) {
fac->ClearData();
}
for (auto& it : mCollectionsFromName) {
if (it.second->GetFactory() == nullptr) {
it.second->ClearData();
}
}
}

2 changes: 1 addition & 1 deletion src/libraries/JANA/JFactoryT.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class JFactoryT : public JFactory {
void Process(const std::shared_ptr<const JEvent>&) override {}


std::optional<std::type_index> GetObjectType(void) const override {
std::type_index GetObjectType(void) const override {
return std::type_index(typeid(T));
}

Expand Down
68 changes: 68 additions & 0 deletions src/libraries/JANA/Utils/JAny.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// Subject to the terms in the LICENSE file found in the top-level directory.

#pragma once
#include <utility>
#include <stdexcept>
#include <type_traits>

/// Ideally we'd just use std::any, but we are restricted to C++14 for the time being
struct JAny {
Expand All @@ -17,3 +20,68 @@ struct JAnyT : JAny {
~JAnyT() override = default; // deletes the t
};


template <typename T>
class JOptional {
private:
using StorageT = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
bool has_value;
StorageT storage;

public:
JOptional() : has_value(false) {}

JOptional(const T& val) : has_value(true) {
new (&storage) T(val);
}

JOptional(T&& val) : has_value(true) {
new (&storage) T(std::move(val));
}

~JOptional() {
reset();
}

// Checks if there is a value
bool hasValue() const { return has_value; }

// Accesses the value, throws if not present
T& get() {
if (!has_value) {
throw std::runtime_error("No value present");
}
return *reinterpret_cast<T*>(&storage); // Access without launder (C++14)
}

const T& get() const {
if (!has_value) {
throw std::runtime_error("No value present");
}
return *reinterpret_cast<const T*>(&storage); // Access without launder (C++14)
}

// Resets the optional (removes the value)
void reset() {
if (has_value) {
reinterpret_cast<T*>(&storage)->~T(); // Explicitly call destructor
has_value = false;
}
}

// Set the value
void set(const T& val) {
reset();
new (&storage) T(val); // Placement new
has_value = true;
}

// Set using move semantics
void set(T&& val) {
reset();
new (&storage) T(std::move(val)); // Placement new
has_value = true;
}
};


0 comments on commit d29d6aa

Please sign in to comment.