39 using std::shared_ptr<T>::shared_ptr;
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) {
49 template <typename U, typename std::enable_if<!std::is_same<T, U>::value
57 : std::shared_ptr<T>(other) {
61 template <
typename U,
typename V = T>
62 struct enable_if_abstract: std::enable_if<std::is_abstract<V>::value> {
69 typename enable_if_abstract<U>::type * =
nullptr)
70 : std::shared_ptr<T>(std::move(other)) {
79 i_shared_ptr(std::shared_ptr<T> &&other) : std::shared_ptr<T>(std::move(other)) {
84 struct is_exact_std_shared_ptr: std::false_type {
88 struct is_exact_std_shared_ptr<std::shared_ptr<U>>: std::true_type {
92 struct is_exact_i_shared_ptr: std::false_type {
96 struct is_exact_i_shared_ptr<
i_shared_ptr<Z>>: std::true_type {
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
107 : std::shared_ptr<T>(new T(std::forward<First>(first), std::forward<Rest>(rest)...)) {
115 template <
typename X = T,
typename = std::enable_if_t<std::is_base_of_v<
117 operator G4VSolid *() {
123 template <
typename X = T,
typename = std::enable_if_t<std::is_base_of_v<
125 operator G4LogicalVolume *() {
131 template <
typename X = T,
typename = std::enable_if_t<std::is_base_of_v<
133 operator G4VPhysicalVolume *() {
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");