back_ref_mixin.hpp
1 
6 #pragma once
7 
8 #include <memory>
9 #include <utility>
10 
11 #include <rapidsmpf/error.hpp>
12 #include <rapidsmpf/utils/misc.hpp>
13 
14 namespace rapidsmpf {
15 
24 template <typename BackRef>
25 class BackRefMixin {
26  public:
28  BackRefMixin() noexcept = default;
29 
40  BackRefMixin(BackRefMixin const& other)
41  : weak_{other.weak_},
42  strong_{other.strong_ ? other.strong_ : std::shared_ptr<BackRef>{other.weak_}} {
43  }
44 
56  if (this != &other) {
57  // Promote first so a throw leaves *this unchanged.
58  auto promoted =
59  other.strong_ ? other.strong_ : std::shared_ptr<BackRef>{other.weak_};
60  weak_ = other.weak_;
61  strong_ = std::move(promoted);
62  }
63  return *this;
64  }
65 
67  BackRefMixin(BackRefMixin&&) noexcept = default;
68 
73  BackRefMixin& operator=(BackRefMixin&&) noexcept = default;
74 
75  ~BackRefMixin() = default;
76 
84  [[nodiscard]] bool operator==(BackRefMixin const& other) const noexcept {
85  return owner_equal(weak_, other.weak_);
86  }
87 
104  void set_backref(std::weak_ptr<BackRef> backref) {
105  std::weak_ptr<BackRef> const empty_weak{};
106  RAPIDSMPF_EXPECTS(
107  !owner_equal(backref, empty_weak),
108  "set_backref: backref must not be empty",
109  std::invalid_argument
110  );
111  RAPIDSMPF_EXPECTS(
112  owner_equal(weak_, empty_weak),
113  "set_backref: backref is already set",
114  std::invalid_argument
115  );
116  weak_ = std::move(backref);
117  strong_.reset();
118  }
119 
120  private:
121  std::weak_ptr<BackRef> weak_{};
122  std::shared_ptr<BackRef> strong_{};
123 };
124 
125 } // namespace rapidsmpf
Mixin that lets copies of the this object keep an external object reference of type BackRef alive.
void set_backref(std::weak_ptr< BackRef > backref)
Install a back-reference on this instance.
BackRefMixin & operator=(BackRefMixin const &other)
Copy assignment with the same semantics as the copy constructor.
BackRefMixin() noexcept=default
Construct a mixin with no installed back-reference.
BackRefMixin(BackRefMixin &&) noexcept=default
Move constructor.
RAPIDS Multi-Processor interfaces.
Definition: backend.hpp:14
requires constexpr std::same_as< typename A::element_type, typename B::element_type > bool owner_equal(A const &a, B const &b) noexcept
Backport of std::weak_ptr::owner_equal / std::owner_equal from C++26.
Definition: misc.hpp:368