src/objects/Object.hpp

Definition of Object base class. More…

Namespaces

Name
allpix
Helper class to hold support layers for a detector model.

Classes

Name
class allpix::Object
Base class for internal objects.
class allpix::Object::BaseWrapper
class allpix::Object::PointerWrapper

Functions

Name
std::ostream & operator«(std::ostream & out, const allpix::Object & obj)
Overloaded ostream operator for printing of object data.
bool operator<(const TRef & ref1, const TRef & ref2)
Missing comparison operator for TRef (to filter out unique)

Detailed Description

Definition of Object base class.

Copyright: Copyright (c) 2017-2024 CERN and the Allpix Squared authors. This software is distributed under the terms of the MIT License, copied verbatim in the file “LICENSE.md”. In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. SPDX-License-Identifier: MIT

Functions Documentation

function operator«

std::ostream & operator<<(
    std::ostream & out,
    const allpix::Object & obj
)

Overloaded ostream operator for printing of object data.

Parameters:

  • out Stream to write output to
  • obj Object to print to stream

Return: Stream where output was written to

function operator<

bool operator<(
    const TRef & ref1,
    const TRef & ref2
)

Missing comparison operator for TRef (to filter out unique)

Parameters:

  • ref1 First TRef
  • ref2 Second TRef

Return: bool Returns true if first TRef should be ordered before second TRef

Source code


#ifndef ALLPIX_OBJECT_H
#define ALLPIX_OBJECT_H

#include <atomic>
#include <iostream>
#include <mutex>

#include <TObject.h>
#include <TRef.h>

namespace allpix {
    template <typename T> class Message;

    class Object : public TObject {
    public:
        friend std::ostream& operator<<(std::ostream& out, const allpix::Object& obj);

        Object() = default;
        ~Object() override = default;


        Object(const Object&) = default;
        Object& operator=(const Object&) = default;


        Object(Object&&) = default;
        Object& operator=(Object&&) = default;

        ClassDefOverride(Object, 4); // NOLINT

        virtual void loadHistory() = 0;
        virtual void petrifyHistory() = 0;

        void markForStorage() {
            // Using bit 14 of the TObject bit field, unused by ROOT:
            this->SetBit(1ull << 14);
        }

    protected:
        virtual void print(std::ostream& out) const { out << "<unknown object>"; };

        void Print(Option_t*) const override {
            print(std::cout);
            std::cout << std::endl;
        }

    public:
        template <class T> class BaseWrapper {
        public:
            BaseWrapper() = default;
            explicit BaseWrapper(const T* obj) : ptr_(const_cast<T*>(obj)) {} // NOLINT


            BaseWrapper(const BaseWrapper& rhs) = default;
            BaseWrapper& operator=(const BaseWrapper& rhs) = default;


            BaseWrapper(BaseWrapper&& rhs) = default;            // NOLINT
            BaseWrapper& operator=(BaseWrapper&& rhs) = default; // NOLINT

            virtual T* get() const = 0;

            void store() {
                if(markedForStorage()) {
                    ref_ = get();
                }
            }

            ClassDef(BaseWrapper, 1); // NOLINT

        protected:
            virtual ~BaseWrapper() = default;

            bool markedForStorage() const { return get() == nullptr ? false : get()->TestBit(1ull << 14); }

            mutable T* ptr_{}; 
            TRef ref_{};
        };

        template <class T> class PointerWrapper : public BaseWrapper<T> {
        public:
            PointerWrapper() = default;

            explicit PointerWrapper(const T* obj) : BaseWrapper<T>(obj), loaded_(true) {} // NOLINT

            ~PointerWrapper() override = default;

            PointerWrapper(const PointerWrapper& rhs) : BaseWrapper<T>(rhs), loaded_(rhs.loaded_.load()){};

            PointerWrapper& operator=(const PointerWrapper& rhs) {
                BaseWrapper<T>::operator=(rhs);
                loaded_ = rhs.loaded_.load();
                return *this;
            };

            PointerWrapper(PointerWrapper&& rhs) noexcept : BaseWrapper<T>(std::move(rhs)), loaded_(rhs.loaded_.load()){};

            PointerWrapper& operator=(PointerWrapper&& rhs) noexcept {
                BaseWrapper<T>::operator=(std::move(rhs));
                loaded_ = rhs.loaded_.load();
                return *this;
            };

            T* get() const override {
                // Lazy loading of pointer from TRef
                if(!this->loaded_) {
                    std::call_once(load_flag_, [&]() {
                        this->ptr_ = static_cast<T*>(this->ref_.GetObject());
                        this->loaded_ = true;
                    });
                }
                return this->ptr_;
            };

            ClassDefOverride(PointerWrapper, 1); // NOLINT

        private:
            mutable std::once_flag load_flag_;       
            mutable std::atomic_bool loaded_{false}; 
        };
    };

    std::ostream& operator<<(std::ostream& out, const allpix::Object& obj);
} // namespace allpix

bool operator<(const TRef& ref1, const TRef& ref2);

#endif /* ALLPIX_OBJECT_H */

Updated on 2024-12-13 at 08:31:37 +0000