@@ -47,6 +47,33 @@ struct is_shared_ptr<std::shared_ptr<U>> : std::true_type
47
47
{
48
48
};
49
49
50
+ // Trait to detect if a type is complete
51
+ template <typename T, typename = void >
52
+ struct is_complete : std::false_type
53
+ {
54
+ };
55
+
56
+ template <typename T>
57
+ struct is_complete <T, decltype (void (sizeof (T)))> : std::true_type
58
+ {
59
+ };
60
+
61
+ // Trait to detect if a trait is complete and polymorphic
62
+ template <typename T, typename = void >
63
+ struct is_polymorphic_safe : std::false_type
64
+ {
65
+ };
66
+
67
+ // Specialization only enabled if T is complete
68
+ template <typename T>
69
+ struct is_polymorphic_safe <T, std::enable_if_t <is_complete<T>::value>>
70
+ : std::integral_constant<bool , std::is_polymorphic<T>::value>
71
+ {
72
+ };
73
+
74
+ template <typename T>
75
+ inline constexpr bool is_polymorphic_safe_v = is_polymorphic_safe<T>::value;
76
+
50
77
// Rational: since type erased numbers will always use at least 8 bytes
51
78
// it is faster to cast everything to either double, uint64_t or int64_t.
52
79
class Any
@@ -83,12 +110,12 @@ class Any
83
110
};
84
111
85
112
template <typename T>
86
- struct IsPolymorphicSharedPtr <T, std:: void_t < typename T::element_type>>
87
- : std::integral_constant<
88
- bool ,
89
- is_shared_ptr<T>::value && std::is_polymorphic_v <typename T::element_type> &&
90
- !std::is_same_v<typename any_cast_base<typename T::element_type>::type,
91
- void >>
113
+ struct IsPolymorphicSharedPtr <
114
+ T,
115
+ std:: enable_if_t <
116
+ is_shared_ptr<T>::value && is_polymorphic_safe_v <typename T::element_type> &&
117
+ !std::is_same_v<typename any_cast_base<typename T::element_type>::type, void >>>
118
+ : std::true_type
92
119
{
93
120
};
94
121
@@ -159,7 +186,7 @@ class Any
159
186
// store as base class if specialized
160
187
if constexpr (!std::is_same_v<Base, void >)
161
188
{
162
- static_assert (std::is_polymorphic_v <Base>, " Any Base trait specialization must be "
189
+ static_assert (is_polymorphic_safe_v <Base>, " Any Base trait specialization must be "
163
190
" polymorphic" );
164
191
_any = std::static_pointer_cast<Base>(value);
165
192
}
@@ -633,7 +660,7 @@ inline nonstd::expected<T, std::string> Any::tryCast() const
633
660
using Derived = typename T::element_type;
634
661
using Base = typename any_cast_base<Derived>::type;
635
662
636
- if constexpr (std::is_polymorphic_v <Derived> && !std::is_same_v<Base, void >)
663
+ if constexpr (is_polymorphic_safe_v <Derived> && !std::is_same_v<Base, void >)
637
664
{
638
665
// Attempt to retrieve the stored shared_ptr<Base> from the Any container
639
666
auto base_ptr = linb::any_cast<std::shared_ptr<Base>>(_any);
0 commit comments