1515#define EMSCRIPTEN_ALWAYS_INLINE __attribute__ ((always_inline))
1616
1717namespace emscripten {
18+ #ifndef EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES
19+ #define EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES 1
20+ #endif
21+
22+
23+ #if EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES
24+ constexpr bool has_unbound_type_names = true ;
25+ #else
26+ constexpr bool has_unbound_type_names = false ;
27+ #endif
28+
1829 namespace internal {
1930 typedef void (*GenericFunction)();
2031
21- typedef const struct _TYPEID * TYPEID;
32+ typedef const struct _TYPEID {}* TYPEID;
33+
34+
35+ // We don't need the full std::type_info implementation. We
36+ // just need a unique identifier per type and polymorphic type
37+ // identification.
38+
39+ template <typename T>
40+ struct CanonicalizedID {
41+ static TYPEID get () {
42+ static _TYPEID c;
43+ return &c;
44+ }
45+ };
46+
47+ template <typename T>
48+ struct Canonicalized {
49+ typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
50+ };
51+
52+ template <typename T>
53+ struct LightTypeID {
54+ static TYPEID get () {
55+ typedef typename Canonicalized<T>::type C;
56+ if (has_unbound_type_names || std::is_polymorphic<C>::value) {
57+ return reinterpret_cast <TYPEID>(&typeid (C));
58+ } else {
59+ return CanonicalizedID<C>::get ();
60+ }
61+ }
62+ };
63+
64+ template <typename T>
65+ const TYPEID getLightTypeID (const T& value) {
66+ typedef typename Canonicalized<T>::type C;
67+ if (has_unbound_type_names || std::is_polymorphic<C>::value) {
68+ return reinterpret_cast <TYPEID>(&typeid (value));
69+ } else {
70+ return LightTypeID<T>::get ();
71+ }
72+ }
2273
23- // This implementation is technically not legal, as it's not
24- // required that two calls to typeid produce the same exact
25- // std::type_info instance. That said, it's likely to work
26- // given Emscripten compiles everything into one binary.
27- // Should it not work in the future: replace TypeID with an
28- // int, and store all TypeInfo we see in a map, allocating new
29- // TypeIDs as we add new items to the map.
3074 template <typename T>
3175 struct TypeID {
3276 static TYPEID get () {
33- return reinterpret_cast <TYPEID>(& typeid (T) );
77+ return LightTypeID<T>:: get ( );
3478 }
3579 };
3680
@@ -53,7 +97,7 @@ namespace emscripten {
5397 template <typename T>
5498 struct TypeID <AllowedRawPointer<T>> {
5599 static TYPEID get () {
56- return reinterpret_cast <TYPEID>(& typeid (T*) );
100+ return LightTypeID<T*>:: get ( );
57101 }
58102 };
59103
0 commit comments