DLG4::VolumeBuilders
A fluent interface for Geant4 geometry definition.
Loading...
Searching...
No Matches
i_shared_ptr.hh
Go to the documentation of this file.
1#ifndef ISHAREDother_HH
2#define ISHAREDother_HH
10
11//#include <atomic> // for std::atomic
12#include <G4LogicalVolume.hh>
13#include <G4VSolid.hh>
14#include <memory>
15#include "IVolumeBuilder.hh"
16
17
18namespace DLG4 {
35 template <typename T>
36 class i_shared_ptr: public std::shared_ptr<T> {
37 public:
39 using std::shared_ptr<T>::shared_ptr;
40
41 //Getting all the ctors to work where needed was admitedly a bit of whack-a-mole.
42 //and likely is not optimal:
43
44 template <typename U, typename = std::enable_if_t<std::is_convertible_v<U *, T *>>>
45 i_shared_ptr(const std::shared_ptr<U> &ptr) : std::shared_ptr<T>(ptr) {
46 }
47
49 template <typename U, typename std::enable_if<!std::is_same<T, U>::value
50 //&& std::is_constructible<T, U>::value
51 , int>::type = 0>
52 i_shared_ptr(const i_shared_ptr<U> &other) : std::shared_ptr<T>(other) {
53 }
54
55 // Explicit constructor for std::shared_ptr<const T>
56 i_shared_ptr(const std::shared_ptr<std::remove_const_t<T>> &other)
57 : std::shared_ptr<T>(other) {
58 }
59
60 private:
61 template <typename U, typename V = T>
62 struct enable_if_abstract: std::enable_if<std::is_abstract<V>::value> {
63 };
64
65 public:
66 // Template constructor from i_shared_ptr<U> where T is abstract (move version)
67 template <typename U>
69 typename enable_if_abstract<U>::type * = nullptr)
70 : std::shared_ptr<T>(std::move(other)) {
71 }
72
73 // /// Template constructor from i_shared_ptr<U> where U can construct T (move version)
74 // template <typename U>
75 // i_shared_ptr(i_shared_ptr<U> &&other) : std::shared_ptr<T>(std::move(other)) {
76 // }
77
79 i_shared_ptr(std::shared_ptr<T> &&other) : std::shared_ptr<T>(std::move(other)) {
80 }
81
82 private:
83 template <typename X>
84 struct is_exact_std_shared_ptr: std::false_type {
85 };
86
87 template <typename U>
88 struct is_exact_std_shared_ptr<std::shared_ptr<U>>: std::true_type {
89 };
90
91 template <typename Y>
92 struct is_exact_i_shared_ptr: std::false_type {
93 };
94
95 template <typename Z>
96 struct is_exact_i_shared_ptr<i_shared_ptr<Z>>: std::true_type {
97 };
98
99 public:
100 template <typename First, typename... Rest,
101 typename = std::enable_if_t<
102 !std::is_same_v<std::decay_t<First>, i_shared_ptr<T>>
103 && !is_exact_std_shared_ptr<std::decay_t<First>>::value
104 //&& !is_exact_i_shared_ptr<std::decay_t<First>>::value
105 >>
106 i_shared_ptr(First &&first, Rest &&... rest)
107 : std::shared_ptr<T>(new T(std::forward<First>(first), std::forward<Rest>(rest)...)) {
108 }
109
110
112 i_shared_ptr(T *other) : std::shared_ptr<T>(other) {
113 }
114
115 template <typename X = T, typename = std::enable_if_t<std::is_base_of_v<
117 operator G4VSolid *() {
118 auto other = static_cast<VolumeBuilders::IVolumeBuilder *>(this->get());
119 return other->GetFinalSolid();
120 }
121
123 template <typename X = T, typename = std::enable_if_t<std::is_base_of_v<
125 operator G4LogicalVolume *() {
126 auto other = static_cast<VolumeBuilders::IVolumeBuilder *>(this->get());
127 return other->GetLogicalVolume();
128 }
129
131 template <typename X = T, typename = std::enable_if_t<std::is_base_of_v<
133 operator G4VPhysicalVolume *() {
134 auto other = static_cast<VolumeBuilders::IVolumeBuilder *>(this->get());
135 return other->GetPlacement();
136 }
137
139 template <typename X = T, typename = std::enable_if_t<std::is_base_of_v<
141 operator G4Transform3D() const {
142 static_assert(std::is_base_of_v<VolumeBuilders::IVolumeBuilder, X>,
143 "T must derive from IVolumeBuilder");
144 auto other = static_cast<const VolumeBuilders::IVolumeBuilder *>(this->get());
145 return other->GetPhysTransform();
146 }
147 };
148
149 template <typename TargetType, typename SourceType>
150 i_shared_ptr<TargetType>
152 using SharedPtrToTarget = std::shared_ptr<TargetType>;
153 if (auto *rawPointer = dynamic_cast<typename SharedPtrToTarget::element_type *>(sourcePtr.
154 get())) {
155 return SharedPtrToTarget(sourcePtr, rawPointer);
156 }
157 return SharedPtrToTarget();
158 }
159}
160
161
162#endif // ISHAREDother_HH
virtual G4VSolid * GetFinalSolid()=0
virtual G4Transform3D GetPhysTransform() const =0
virtual G4LogicalVolume * GetLogicalVolume()=0
virtual G4VPhysicalVolume * GetPlacement()=0
A wrapper for std::shared_ptr that allows and facilitates many implicit(i) type conversions.
i_shared_ptr(std::shared_ptr< T > &&other)
Explicit constructor from std::shared_ptr<T> (move)
i_shared_ptr(T *other)
Implicit constructor from raw pointer (danger: takes ownership)
i_shared_ptr(const std::shared_ptr< std::remove_const_t< T > > &other)
i_shared_ptr(i_shared_ptr< U > &&other, typename enable_if_abstract< U >::type *=nullptr)
i_shared_ptr(const i_shared_ptr< U > &other)
Template constructor from i_shared_ptr where U can construct T.
i_shared_ptr(const std::shared_ptr< U > &ptr)
i_shared_ptr(First &&first, Rest &&... rest)
i_shared_ptr< TargetType > i_dynamic_pointer_cast(const i_shared_ptr< SourceType > &sourcePtr) noexcept