6 #ifndef METALL_JSON_KEY_VALUE_PAIR_HPP
7 #define METALL_JSON_KEY_VALUE_PAIR_HPP
16 #include <metall/detail/utilities.hpp>
24 template <
typename char_type,
typename char_traits,
typename allocator_type,
25 typename other_key_value_pair_type>
28 const other_key_value_pair_type &other_key_value) noexcept {
29 if (key_value.key().length() != other_key_value.key().length())
31 if (std::strcmp(key_value.key_c_str(), other_key_value.key_c_str()) != 0)
33 return key_value.value() == other_key_value.value();
41 template <
typename char_type = char,
42 typename char_traits = std::char_traits<char_type>,
43 typename Alloc = std::allocator<char_type>>
45 template <
typename _
char_type,
typename _
char_traits,
typename Alloc>
49 using char_allocator_type =
50 typename std::allocator_traits<Alloc>::template rebind_alloc<_char_type>;
52 typename std::allocator_traits<char_allocator_type>::pointer;
58 using key_type = std::basic_string_view<char_type, char_traits>;
70 : m_value(
value, alloc) {
81 : m_value(std::move(
value), alloc) {
87 priv_allocate_key(other.
key_c_str(), other.m_key_length,
93 : m_value(other.m_value, alloc) {
94 priv_allocate_key(other.
key_c_str(), other.m_key_length,
100 : m_value(std::move(other.m_value)) {
101 if (other.priv_short_key()) {
105 other.m_long_key =
nullptr;
107 m_key_length = other.m_key_length;
108 other.m_key_length = 0;
114 if (alloc == other.get_allocator()) {
115 if (other.priv_short_key()) {
119 other.m_long_key =
nullptr;
121 m_key_length = other.m_key_length;
122 other.m_key_length = 0;
124 priv_allocate_key(other.key_c_str(), other.m_key_length,
get_allocator());
125 other.priv_deallocate_key(other.get_allocator());
127 m_value = std::move(other.m_value);
132 if (
this == &other)
return *
this;
136 m_value = other.m_value;
146 if (
this == &other)
return *
this;
151 auto other_allocator = other.m_value.get_allocator();
152 m_value = std::move(other.m_value);
155 if (other.priv_short_key()) {
159 other.m_long_key =
nullptr;
161 m_key_length = other.m_key_length;
162 other.m_key_length = 0;
164 priv_allocate_key(other.key_c_str(), other.m_key_length,
get_allocator());
165 other.priv_deallocate_key(other_allocator);
173 if constexpr (!std::is_same_v<
174 typename std::allocator_traits<
183 if (priv_short_key()) {
188 swap(m_key_length, other.m_key_length);
190 swap(m_value, other.m_value);
229 return !(lhs == rhs);
238 static constexpr uint32_t k_short_key_max_length =
239 sizeof(char_pointer) - 1;
241 const char_type *priv_key_c_str() const noexcept {
242 if (priv_short_key()) {
248 bool priv_short_key() const noexcept {
249 return (m_key_length <= k_short_key_max_length);
252 bool priv_long_key() const noexcept {
return !priv_short_key(); }
255 char_allocator_type alloc) {
256 assert(m_key_length == 0);
257 m_key_length = length;
259 if (priv_short_key()) {
260 std::char_traits<char_type>::copy(
m_short_key,
key, m_key_length);
261 std::char_traits<char_type>::assign(
m_short_key[m_key_length],
'\0');
263 m_long_key = std::allocator_traits<char_allocator_type>::allocate(
264 alloc, m_key_length + 1);
271 std::char_traits<char_type>::copy(metall::to_raw_pointer(
m_long_key),
key,
273 std::char_traits<char_type>::assign(
m_long_key[m_key_length],
'\0');
279 bool priv_deallocate_key(char_allocator_type alloc) {
280 if (m_key_length > k_short_key_max_length) {
281 std::allocator_traits<char_allocator_type>::deallocate(alloc,
m_long_key,
291 static_assert(
sizeof(
char_type) * (k_short_key_max_length + 1) <=
293 "sizeof(m_short_key) is bigger than sizeof(uint64_t)");
304 template <
typename char_type,
typename char_traits,
typename allocator_type>