Skip to content

Commit 982e166

Browse files
committed
Use CTTI instead of RTTI where possible
1 parent d1fcec8 commit 982e166

25 files changed

+2957
-9
lines changed

include/cereal/cereal.hpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#include "cereal/details/helpers.hpp"
4646
#include "cereal/types/base_class.hpp"
4747

48+
#include "cereal/external/ctti/type_id.hpp"
49+
4850
namespace cereal
4951
{
5052
// ######################################################################
@@ -269,8 +271,9 @@ namespace cereal
269271
{ \
270272
static std::uint32_t registerVersion() \
271273
{ \
272-
::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace( \
273-
std::type_index(typeid(TYPE)).hash_code(), VERSION_NUMBER ); \
274+
::cereal::detail::StaticObject<Versions>::getInstance().mapping \
275+
.emplace(std::hash<ctti::type_id_t>()(ctti::type_id<TYPE>()), \
276+
VERSION_NUMBER); \
274277
return VERSION_NUMBER; \
275278
} \
276279
static inline const std::uint32_t version = registerVersion(); \
@@ -285,8 +288,9 @@ namespace cereal
285288
static const std::uint32_t version; \
286289
static std::uint32_t registerVersion() \
287290
{ \
288-
::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace( \
289-
std::type_index(typeid(TYPE)).hash_code(), VERSION_NUMBER ); \
291+
::cereal::detail::StaticObject<Versions>::getInstance().mapping \
292+
.emplace(std::hash<ctti::type_id_t>()(ctti::type_id<TYPE>()), \
293+
VERSION_NUMBER); \
290294
return VERSION_NUMBER; \
291295
} \
292296
CEREAL_UNUSED_FUNCTION \
@@ -595,7 +599,7 @@ namespace cereal
595599
template <class T> inline
596600
std::uint32_t registerClassVersion()
597601
{
598-
static const auto hash = std::type_index(typeid(T)).hash_code();
602+
static const auto hash = std::hash<ctti::type_id_t>()(ctti::type_id<T>());
599603
const auto insertResult = itsVersionedTypes.insert( hash );
600604
const auto lock = detail::StaticObject<detail::Versions>::lock();
601605
const auto version =
@@ -1013,7 +1017,7 @@ namespace cereal
10131017
template <class T> inline
10141018
std::uint32_t loadClassVersion()
10151019
{
1016-
static const auto hash = std::type_index(typeid(T)).hash_code();
1020+
static const auto hash = std::hash<ctti::type_id_t>()(ctti::type_id<T>());
10171021
auto lookupResult = itsVersionedTypes.find( hash );
10181022

10191023
if( lookupResult != itsVersionedTypes.end() ) // already exists

include/cereal/details/traits.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#include "cereal/macros.hpp"
4343
#include "cereal/access.hpp"
4444

45+
#include "cereal/external/ctti/type_id.hpp"
46+
4547
namespace cereal
4648
{
4749
namespace traits
@@ -1146,15 +1148,15 @@ namespace cereal
11461148
{
11471149
template<class T>
11481150
base_class_id(T const * const t) :
1149-
type(typeid(T)),
1151+
type(ctti::type_id<T>()),
11501152
ptr(t),
1151-
hash(std::hash<std::type_index>()(typeid(T)) ^ (std::hash<void const *>()(t) << 1))
1153+
hash(std::hash<ctti::type_id_t>()(ctti::type_id<T>()) ^ (std::hash<void const *>()(t) << 1))
11521154
{ }
11531155

11541156
bool operator==(base_class_id const & other) const
11551157
{ return (type == other.type) && (ptr == other.ptr); }
11561158

1157-
std::type_index type;
1159+
ctti::type_id_t type;
11581160
void const * ptr;
11591161
size_t hash;
11601162
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License
2+
3+
Copyright (c) 2015 Manuel Sánchez
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef CTTI_DETAIL_ALGORITHM_HPP
2+
#define CTTI_DETAIL_ALGORITHM_HPP
3+
4+
#include <cstdint>
5+
6+
namespace ctti
7+
{
8+
9+
namespace detail
10+
{
11+
12+
template<typename T, std::size_t N>
13+
constexpr const T* begin(const T(&array)[N])
14+
{
15+
return &array[0];
16+
}
17+
18+
template<typename T, std::size_t N>
19+
constexpr const T* end(const T(&array)[N])
20+
{
21+
return &array[N];
22+
}
23+
24+
template<typename LhsIt, typename RhsIt>
25+
constexpr bool equal_range(LhsIt lhsBegin, LhsIt lhsEnd, RhsIt rhsBegin, RhsIt rhsEnd)
26+
{
27+
return (lhsBegin != lhsEnd && rhsBegin != rhsEnd) ? *lhsBegin == *rhsBegin &&
28+
equal_range(lhsBegin + 1, lhsEnd, rhsBegin + 1, rhsEnd) : (lhsBegin == lhsEnd && rhsBegin == rhsEnd);
29+
}
30+
31+
template<typename T>
32+
constexpr const T& max(const T& lhs, const T& rhs)
33+
{
34+
return (lhs >= rhs) ? lhs : rhs;
35+
}
36+
37+
template<typename T>
38+
constexpr const T& min(const T& lhs, const T& rhs)
39+
{
40+
return (lhs <= rhs) ? lhs : rhs;
41+
}
42+
43+
}
44+
45+
}
46+
47+
#endif // CTTI_DETAIL_ALGORITHM_HPP
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#ifndef CTTI_DETAIL_CSTRING_HPP
2+
#define CTTI_DETAIL_CSTRING_HPP
3+
4+
#include "hash.hpp"
5+
#include "algorithm.hpp"
6+
#include <ostream>
7+
#include <string>
8+
9+
namespace ctti
10+
{
11+
12+
namespace detail
13+
{
14+
15+
class cstring
16+
{
17+
public:
18+
template<std::size_t N>
19+
constexpr cstring(const char (&str)[N]) :
20+
cstring{&str[0], N - 1}
21+
{}
22+
23+
constexpr cstring(const char* begin, std::size_t length) :
24+
_str{begin},
25+
_length{length}
26+
{}
27+
28+
constexpr cstring(const char* begin, const char* end) :
29+
cstring{begin, static_cast<std::size_t>(end - begin)}
30+
{}
31+
32+
constexpr cstring(const char* begin) :
33+
cstring{begin, length(begin)}
34+
{}
35+
36+
static constexpr std::size_t length(const char* str)
37+
{
38+
return *str ? 1 + length(str + 1) : 0;
39+
}
40+
41+
constexpr std::size_t length() const
42+
{
43+
return _length;
44+
}
45+
46+
constexpr std::size_t size() const
47+
{
48+
return length();
49+
}
50+
51+
constexpr hash_t hash() const
52+
{
53+
return fnv1a_hash(length(), begin());
54+
}
55+
56+
std::string cppstring() const
57+
{
58+
return {begin(), end()};
59+
}
60+
61+
std::string str() const
62+
{
63+
return cppstring();
64+
}
65+
66+
constexpr const char* begin() const
67+
{
68+
return _str;
69+
}
70+
71+
constexpr const char* end() const
72+
{
73+
return _str + _length;
74+
}
75+
76+
constexpr char operator[](std::size_t i) const
77+
{
78+
return _str[i];
79+
}
80+
81+
constexpr const char* operator()(std::size_t i) const
82+
{
83+
return _str + i;
84+
}
85+
86+
constexpr cstring operator()(std::size_t begin, std::size_t end) const
87+
{
88+
return {_str + begin, _str + end};
89+
}
90+
91+
constexpr cstring pad(std::size_t begin_offset, std::size_t end_offset) const
92+
{
93+
return operator()(begin_offset, size() - end_offset);
94+
}
95+
96+
friend std::ostream& operator<<(std::ostream& os, const cstring& str)
97+
{
98+
for(const char c : str)
99+
{
100+
os << c;
101+
}
102+
103+
return os;
104+
}
105+
106+
private:
107+
const char* _str;
108+
std::size_t _length;
109+
};
110+
111+
constexpr bool operator==(const cstring& lhs, const cstring& rhs)
112+
{
113+
return ctti::detail::equal_range(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
114+
}
115+
116+
constexpr bool operator!=(const cstring& lhs, const cstring& rhs)
117+
{
118+
return !(lhs == rhs);
119+
}
120+
121+
}
122+
123+
}
124+
125+
#endif // CTTI_DETAIL_CSTRING_HPP
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#ifndef CTTI_DETAIL_ENTITY_NAME_HPP
2+
#define CTTI_DETAIL_ENTITY_NAME_HPP
3+
4+
#include "cstring.hpp"
5+
6+
namespace ctti
7+
{
8+
9+
namespace detail
10+
{
11+
12+
class entity_name
13+
{
14+
public:
15+
constexpr entity_name(const ctti::detail::cstring& str) :
16+
_str{str}
17+
{}
18+
19+
constexpr ctti::detail::cstring str() const
20+
{
21+
return _str;
22+
}
23+
24+
constexpr ctti::detail::cstring operator[](std::size_t i) const
25+
{
26+
return colon_scan(_str.begin(), _str.end(), i);
27+
}
28+
29+
private:
30+
ctti::detail::cstring _str;
31+
32+
constexpr ctti::detail::cstring colon_scan(const char* begin, const char* end, std::size_t i) const
33+
{
34+
return (begin == end) ? {begin, end} :
35+
(i == 0) ? {begin, end}
36+
(colon_count == 0 && *begin == ':') ? colon_scan(++begin, end, i, ++colon_count) :
37+
(colon_count == 1 && *begin == ':') ? colon_scan(++begin, end, i - 1, 0)
38+
(
39+
}
40+
};
41+
42+
}
43+
44+
}
45+
46+
#endif // CTTI_DETAIL_ENTITY_NAME_HPP
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef CTTI_DETAIL_HASH_HPP
2+
#define CTTI_DETAIL_HASH_HPP
3+
4+
#include <cstdint>
5+
6+
namespace ctti
7+
{
8+
namespace detail
9+
{
10+
// From https://github.com/foonathan/string_id. As usually, thanks Jonathan.
11+
12+
using hash_t = std::uint64_t;
13+
14+
// See http://www.isthe.com/chongo/tech/comp/fnv/#FNV-param
15+
constexpr hash_t fnv_basis = 14695981039346656037ull;
16+
constexpr hash_t fnv_prime = 1099511628211ull;
17+
18+
// FNV-1a 64 bit hash
19+
constexpr hash_t fnv1a_hash(std::size_t n, const char *str, hash_t hash = fnv_basis)
20+
{
21+
return n > 0 ? fnv1a_hash(n - 1, str + 1, (hash ^ *str) * fnv_prime) : hash;
22+
}
23+
24+
template<std::size_t N>
25+
constexpr hash_t fnv1a_hash(const char (&array)[N])
26+
{
27+
return fnv1a_hash(N - 1, &array[0]);
28+
}
29+
}
30+
}
31+
32+
#endif /* CTTI_DETAIL_HASH_HPP */
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef CTTI_LANGUAGE_FEATURES_HPP
2+
#define CTTI_LANGUAGE_FEATURES_HPP
3+
4+
#ifdef __cpp_variable_templates
5+
#define CTTI_HAS_VARIABLE_TEMPLATES
6+
#endif // __cpp_variable_templates
7+
8+
#define CTTI_HAS_CONSTEXPR_PRETTY_FUNCTION
9+
10+
#if defined(__GCC__) && __GCC__ < 5
11+
#undef CTTI_HAS_CONSTEXPR_PRETTY_FUNCTION
12+
#endif // GCC 4.x
13+
14+
#ifdef __clang__
15+
#define CTTI_HAS_ENUM_AWARE_PRETTY_FUNCTION
16+
#endif // __clang__
17+
18+
#endif // CTTI_LANGUAGE_FEATURES_HPP

0 commit comments

Comments
 (0)