DLG4::VolumeBuilders
A fluent interface for Geant4 geometry definition.
Loading...
Searching...
No Matches
Classes | Public Member Functions | List of all members
Linkable< T > Class Template Reference

#include <Linkable.hh>

Classes

struct  false_template
 

Public Member Functions

 Linkable ()
 
 ~Linkable ()
 
 Linkable (const Linkable< T > &other)
 
 Linkable (Linkable< T > &other, std::true_type)
 
 Linkable (const T &other)
 
template<typename U = T>
std::enable_if_t<!std::is_pointer_v< U >, U * > operator-> () const
 
template<typename U = T>
std::enable_if_t< std::is_pointer_v< U >, std::remove_pointer_t< U > * > operator-> () const
 
template<typename U = T>
std::enable_if_t<!std::is_pointer_v< U >, U & > operator* () const
 
template<typename U = T>
std::enable_if_t< std::is_pointer_v< U >, std::remove_pointer_t< U > & > operator* () const
 
const Linkable< T > & operator= (const Linkable< T > &other) const
 
Linkableoperator= (const T &other) const
 
void LinkToRaw (T *ptr)
 
void Link (Linkable< T > &other)
 
void ShareLink (std::shared_ptr< T > other)
 
template<typename... Args, std::enable_if_t< !(std::conjunction_v< std::is_same< std::decay_t< Args >, Linkable< T > >... >), int > = 0>
void ConstructAndLink (Args &&... args)
 
 operator bool () const noexcept
 
T * get_mutable () const
 
const T * get () const
 
void make_persistent ()
 
 operator T* () const
 

Detailed Description

template<typename T>
class DLG4::VolumeBuilders::_internals_::Linkable< T >

Definition at line 134 of file Linkable.hh.

Constructor & Destructor Documentation

◆ Linkable() [1/4]

template<typename T >
Linkable ( )
inline

Default constructor.

Definition at line 144 of file Linkable.hh.

145 : ref_() {
146 }

◆ ~Linkable()

template<typename T >
~Linkable ( )
inline

Definition at line 149 of file Linkable.hh.

149 {
150 std::lock_guard<std::recursive_mutex> lock(s_link_mutex);
151 // remove ourselves from the backlinks of the downlink
152 // this prevents corrupt backlink propagation after we are deleted.
153 if (downlink_) {
154 auto &parent_backlinks = downlink_->backlinks_;
155 auto it = std::remove(parent_backlinks.begin(), parent_backlinks.end(), this);
156 if (it != parent_backlinks.end()) {
157 parent_backlinks.erase(it, parent_backlinks.end());
158 }
159 }
160 // remove downlinks from our backlinks
161 // Does this orphan chains?:
162 // If we have a ref, link to will error anyway
163 // If we don't have a ref, we just become the root.
164 // No harm. Nothing linked, nothing lost.
165 // But backlinks become detatched from each other, have different views.
166 // So relink to the first backlink, making it the root.
167 Linkable<T> *first_link = nullptr;
168 for (auto *child : backlinks_) {
169 if (child->downlink_ == this) {
170 if (bool is_first_link = false; !is_first_link) {
171 first_link = child;
172 child->downlink_ = nullptr;
173 } else {
174 child->downlink_ = first_link;
175 }
176 }
177 }
178 backlinks_.clear();
179 //if this matters, something is already very wrong. But it can help unmask that.
180 }

◆ Linkable() [2/4]

template<typename T >
Linkable ( const Linkable< T > &  other)
inline

Copy constructor does deep copy, not link This is safest and default.

Definition at line 184 of file Linkable.hh.

184 :
185 ref_(std::make_shared<T>(*other.ref_)) {
186 }

◆ Linkable() [3/4]

template<typename T >
Linkable ( Linkable< T > &  other,
std::true_type   
)
inline

The EXPLICIT linking copy ctor.

Definition at line 189 of file Linkable.hh.

189 {
190 ref_ = nullptr;
191 LinkTreeTo(other);
192 }

◆ Linkable() [4/4]

template<typename T >
Linkable ( const T &  other)
inlineexplicit

Copy constructor does deep copy, not link This is safest and default.

Definition at line 196 of file Linkable.hh.

197 : ref_(std::make_shared<T>(other)) {
198 }

Member Function Documentation

◆ ConstructAndLink()

template<typename T >
template<typename... Args, std::enable_if_t< !(std::conjunction_v< std::is_same< std::decay_t< Args >, Linkable< T > >... >), int > = 0>
void ConstructAndLink ( Args &&...  args)
inline

Link and own a T and link to it.

Definition at line 279 of file Linkable.hh.

279 {
280 auto data = std::make_shared<T>(std::forward<Args>(args)...);
281 LinkTreeTo(data);
282 }

◆ get()

template<typename T >
const T * get ( ) const
inline

Definition at line 292 of file Linkable.hh.

292 {
293 return ref_.get();
294 };

◆ get_mutable()

template<typename T >
T * get_mutable ( ) const
inline

Definition at line 288 of file Linkable.hh.

288 {
289 return ref_.get();
290 };

◆ Link()

template<typename T >
void Link ( Linkable< T > &  other)
inline

Reset Link to another Linakble:

Definition at line 255 of file Linkable.hh.

255 {
256 LinkTreeTo(other);
257 }

◆ LinkToRaw()

template<typename T >
void LinkToRaw ( T *  ptr)
inline

Link to an existing T object via pointer (non-owning)

Definition at line 244 of file Linkable.hh.

244 {
245 auto data = std::shared_ptr<T>(ptr, [](T *)
246 {
247 /* do nothing */
248 });
249 LinkTreeTo(data);
250 }

◆ make_persistent()

template<typename T >
void make_persistent ( )
inline

Definition at line 296 of file Linkable.hh.

296 {
297 std::lock_guard<std::mutex> lock(s_registry_mutex);
298 black_hole.push_back(ref_);
299 }
std::vector< std::shared_ptr< void > > black_hole
Definition Linkable.hh:70

◆ operator bool()

template<typename T >
operator bool ( ) const
inlineexplicitnoexcept

Definition at line 284 of file Linkable.hh.

284 {
285 return static_cast<bool>(ref_);
286 }

◆ operator T*()

template<typename T >
operator T* ( ) const
inline

Definition at line 308 of file Linkable.hh.

308 {
309 if (!ref_) {
310 throw std::runtime_error("Attempt to convert empty Linkable to T*");
311 }
312 return ref_.get(); // Return a copy of the contained object
313 }

◆ operator*() [1/2]

template<typename T >
template<typename U = T>
std::enable_if_t<!std::is_pointer_v< U >, U & > operator* ( ) const
inline

operator* for non-pointer T: returns reference to T

Definition at line 220 of file Linkable.hh.

220 {
221 return *ref_;
222 }

◆ operator*() [2/2]

template<typename T >
template<typename U = T>
std::enable_if_t< std::is_pointer_v< U >, std::remove_pointer_t< U > & > operator* ( ) const
inline

operator* for pointer T: returns reference to the pointed-to object

Definition at line 227 of file Linkable.hh.

227 {
228 return **ref_;
229 }

◆ operator->() [1/2]

template<typename T >
template<typename U = T>
std::enable_if_t<!std::is_pointer_v< U >, U * > operator-> ( ) const
inline

-> foward For non-pointer T

Definition at line 206 of file Linkable.hh.

206 {
207 return ref_.get();
208 }

◆ operator->() [2/2]

template<typename T >
template<typename U = T>
std::enable_if_t< std::is_pointer_v< U >, std::remove_pointer_t< U > * > operator-> ( ) const
inline

operator-> forward For pointer T

Definition at line 213 of file Linkable.hh.

213 {
214 return *ref_;
215 }

◆ operator=() [1/2]

template<typename T >
const Linkable< T > & operator= ( const Linkable< T > &  other) const
inline

Allow CONTENT update (not reference) through assignment This is allowed even for const wrapper.

Definition at line 233 of file Linkable.hh.

233 {
234 *ref_ = *(other.ref_);
235 return *this; // return const ref to self.
236 }

◆ operator=() [2/2]

template<typename T >
Linkable & operator= ( const T &  other) const
inline

Definition at line 238 of file Linkable.hh.

238 {
239 *ref_ = other;
240 return *this;
241 }

◆ ShareLink()

template<typename T >
void ShareLink ( std::shared_ptr< T >  other)
inline

Definition at line 264 of file Linkable.hh.

264 {
265 if (!other) {
266 throw std::invalid_argument("\n Error in Linkable::Link: null pointer passed.\n");
267 }
268 auto data = other;
269 LinkTreeTo(data);
270 }

The documentation for this class was generated from the following file: