Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:27

0001 /*
0002  * Project: RooFit
0003  * Authors:
0004  *   Jonas Rembser, CERN, Jun 2021
0005  *
0006  * Copyright (c) 2021, CERN
0007  *
0008  * Redistribution and use in source and binary forms,
0009  * with or without modification, are permitted according to the terms
0010  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
0011  */
0012 
0013 #ifndef roofit_roofitcore_RooFit_UniqueId_h
0014 #define roofit_roofitcore_RooFit_UniqueId_h
0015 
0016 #include <atomic>
0017 
0018 namespace RooFit {
0019 
0020 /// A UniqueId can be added as a class member to enhance any class with a
0021 /// unique identifier for each instantiated object.
0022 ///
0023 /// Example:
0024 /// ~~~{.cpp}
0025 /// class MyClass {
0026 ///
0027 /// public:
0028 ///    /// Return unique ID by reference.
0029 ///    /// Please always use the name `uniqueId` for the getter.
0030 ///    UniqueId<MyClass> const& uniqueId() const { return _uniqueId; }
0031 ///
0032 /// private:
0033 ///    const UniqueId<MyClass> _uniqueId; //! should be non-persistent
0034 ///
0035 /// };
0036 /// ~~~
0037 
0038 template <class Class>
0039 struct UniqueId {
0040 public:
0041    using Value_t = unsigned long;
0042 
0043    /// Create a new UniqueId with the next value from the static counter.
0044    UniqueId() : _val{++counter} {}
0045 
0046    // Disable all sorts of copying and moving to ensure uniqueness.
0047    UniqueId(const UniqueId &) = delete;
0048    UniqueId &operator=(const UniqueId &) = delete;
0049    UniqueId(UniqueId &&) = delete;
0050    UniqueId &operator=(UniqueId &&) = delete;
0051 
0052    operator Value_t() const { return _val; }
0053 
0054    /// Return numerical value of ID.
0055    /// Use only if necessary, as the UniqueId type information is lost and
0056    /// copying/moving is not prohibited for the value type.
0057    /// Please don't turn this into a cast operator, as a function with an
0058    /// explicit name is easier to track in the codebase.
0059    constexpr Value_t value() const { return _val; }
0060 
0061    bool operator==(UniqueId const &other) const { return _val == other._val; }
0062    bool operator<(UniqueId const &other) const { return _val < other._val; }
0063 
0064    /// Get an ID that is less than the ID of any object (similar to nullptr).
0065    static UniqueId const &nullid()
0066    {
0067       static const UniqueId nid{nullval};
0068       return nid;
0069    }
0070 
0071    static constexpr Value_t nullval = 0UL; ///< The value of the nullid.
0072 
0073 private:
0074    UniqueId(Value_t val) : _val{val} {}
0075 
0076    Value_t _val; ///< Numerical value of the ID.
0077 
0078    static std::atomic<Value_t> counter; ///< The static object counter to get the next ID value.
0079 };
0080 
0081 template <class Class>
0082 std::atomic<typename UniqueId<Class>::Value_t> UniqueId<Class>::counter{UniqueId<Class>::nullval};
0083 
0084 /// A helper function to replace pointer comparisons with UniqueId comparisons.
0085 /// With pointer comparisons, we can also have `nullptr`. In the UniqueId case,
0086 /// this translates to the `nullid`.
0087 template <class Class,
0088           class UniqueId_t = std::remove_reference_t<decltype(std::declval<std::remove_pointer_t<Class>>().uniqueId())>>
0089 UniqueId_t const &getUniqueId(Class const *ptr)
0090 {
0091    return ptr ? ptr->uniqueId() : UniqueId_t::nullid();
0092 }
0093 
0094 } // namespace RooFit
0095 
0096 #endif