12 #include <type_traits> 13 #include <unordered_map> 16 #include <hilti/base/intrusive-ptr.h> 17 #include <hilti/base/optional-ref.h> 18 #include <hilti/base/util.h> 35 #ifdef HILTI_TYPE_ERASURE_PROFILE 44 void decrement() { --current; }
47 inline auto& instance_counters() {
48 static std::unordered_map<std::string, Counters> global_counters;
49 return global_counters;
55 extern void summary(std::ostream& out);
60 virtual const std::type_info& typeid_()
const = 0;
61 virtual std::string
typename_()
const = 0;
62 virtual uintptr_t identity()
const = 0;
65 virtual std::pair<const ConceptBase*, const void*> _childAs(
const std::type_info& ti)
const = 0;
66 virtual std::pair<ConceptBase*, void*> _childAs(
const std::type_info& ti) = 0;
70 template<
typename T,
typename Concept,
typename... ConceptArgs>
73 ModelBase(T data, ConceptArgs&&... args) : Concept(std::forward<ConceptArgs>(args)...), _data(std::move(data)) {
74 #ifdef HILTI_TYPE_ERASURE_PROFILE 75 detail::instance_counters()[
typeid(T).name()].increment();
80 #ifdef HILTI_TYPE_ERASURE_PROFILE 81 detail::instance_counters()[
typeid(T).name()].decrement();
92 const T& data()
const {
return this->_data; }
93 T& data() {
return _data; }
95 uintptr_t identity()
const final {
96 if constexpr ( std::is_base_of<trait::TypeErased, T>::value )
97 return _data.data()->identity();
99 return reinterpret_cast<uintptr_t
>(&_data);
102 const std::type_info& typeid_()
const final {
return typeid(T); }
106 if constexpr ( std::is_base_of<trait::TypeErased, T>::value )
107 return data().typename_();
109 return hilti::util::typename_<T>();
112 std::pair<const ConceptBase*, const void*> _childAs(
const std::type_info& ti)
const final {
115 if constexpr ( std::is_base_of<trait::TypeErased, T>::value )
116 base = _data.data().get();
118 if (
typeid(_data) == ti )
119 return {base, &_data};
121 return {base,
nullptr};
124 std::pair<ConceptBase*, void*> _childAs(
const std::type_info& ti)
final {
127 if constexpr ( std::is_base_of<trait::TypeErased, T>::value )
128 base = _data.data().get();
130 if (
typeid(_data) == ti )
131 return {base, &_data};
133 return {base,
nullptr};
141 template<
typename Trait,
typename Concept,
template<
typename T>
typename Model,
typename... ConceptArgs>
151 template<
typename T, IF_DERIVED_FROM(T, Trait)>
153 : _data(make_intrusive<Model<T>>(std::move(t), std::forward<ConceptArgs>(args)...)) {}
156 _data = std::move(data);
168 return _data->typeid_();
176 std::string
typename_()
const {
return _data ? _data->typename_() :
"<nullptr>"; }
183 const T&
as()
const {
184 if (
auto p = _tryAs<T>() )
187 std::cerr <<
hilti::util::fmt(
"internal error: unexpected type, want %s but have %s",
188 hilti::util::typename_<T>(),
typename_())
199 if (
auto p = _tryAs<T>() )
202 std::cerr <<
hilti::util::fmt(
"internal error: unexpected type, want %s but have %s",
203 hilti::util::typename_<T>(),
typename_())
214 return _tryAs<T>() !=
nullptr;
220 if (
auto p = _tryAs<T>() )
227 auto&
data()
const {
return _data; }
233 uintptr_t
identity()
const {
return _data ? _data->identity() : 0; }
237 const T* _tryAs()
const {
238 if constexpr ( std::is_base_of<ErasedBase, T>::value )
239 return static_cast<const T*
>(
this);
241 if (
typeid(Model<T>) ==
typeid(*_data) )
242 return &(::hilti::cast_intrusive<
const Model<T>>(_data))->data();
244 std::pair<const ConceptBase*, const void*> c = {_data.get(),
nullptr};
247 c = c.first->_childAs(
typeid(T));
250 return static_cast<const T*
>(c.second);
258 if constexpr ( std::is_base_of<ErasedBase, T>::value )
259 return static_cast<T*
>(
this);
261 if (
typeid(Model<T>) ==
typeid(*_data) )
262 return &(hilti::cast_intrusive<Model<T>>(_data))->data();
264 std::pair<ConceptBase*, void*> c = {_data.get(),
nullptr};
267 c = c.first->_childAs(
typeid(T));
270 return static_cast<T*
>(c.second);
std::string typename_() const
Definition: type_erase.h:176
Definition: type_erase.h:71
const T & as() const
Definition: type_erase.h:183
std::string typename_()
Definition: util.h:74
void abort_with_backtrace()
Definition: util.cc:179
Definition: intrusive-ptr.h:28
uintptr_t identity() const
Definition: type_erase.h:233
auto & data() const
Definition: type_erase.h:227
const std::type_info & typeid_() const
Definition: type_erase.h:166
Definition: optional-ref.h:22
T & as()
Definition: type_erase.h:198
std::string fmt(const char *fmt, const Args &... args)
Definition: util.h:80
Definition: intrusive-ptr.h:69
bool isA() const
Definition: type_erase.h:213
Definition: type_erase.h:30
Definition: type_erase.h:142
auto & data()
Definition: type_erase.h:230
Definition: type_erase.h:20
Definition: type_erase.h:58
optional_ref< const T > tryAs() const
Definition: type_erase.h:219
Definition: type_erase.h:29