Skip to content

Commit 5874c8a

Browse files
author
Julian LALU
committed
Improve Hashset
1 parent 430bf27 commit 5874c8a

File tree

1 file changed

+90
-35
lines changed

1 file changed

+90
-35
lines changed

interface/core/containers/hashset.h

Lines changed: 90 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -972,14 +972,15 @@ namespace hud
972972
[[nodiscard]]
973973
constexpr iterator find(K &&key) noexcept
974974
{
975-
if constexpr (is_hashable_and_comparable_v<K>)
976-
{
977-
return find_impl(hud::forward<K>(key));
978-
}
979-
else
980-
{
981-
return find_impl(key_type(hud::forward<K>(key)));
982-
}
975+
return find_impl(forward_key(hud::forward<K>(key)));
976+
// if constexpr (is_hashable_and_comparable_v<K>)
977+
// {
978+
// return find_impl(hud::forward<K>(key));
979+
// }
980+
// else
981+
// {
982+
// return find_impl(key_type(hud::forward<K>(key)));
983+
// }
983984
}
984985

985986
constexpr void rehash(i32 count) noexcept
@@ -1033,10 +1034,20 @@ namespace hud
10331034
return const_cast<hashset_impl *>(this)->contains(hud::forward<K>(key));
10341035
}
10351036

1036-
// template<typename K, typename... Args>
1037-
// iterator try_emplace(K &&key, Args) noexcept
1038-
// {
1039-
// }
1037+
/** Find the given key. If it exist, return it, else insert the value by constructing it with args */
1038+
template<typename K, typename... Args>
1039+
iterator try_emplace(K &&key, Args &&...args) noexcept
1040+
{
1041+
return try_emplace_impl(forward_key(hud::forward<K>(key)));
1042+
// if constexpr (is_hashable_and_comparable_v<K>)
1043+
// {
1044+
// return try_emplace_impl(hud::forward<K>(key));
1045+
// }
1046+
// else
1047+
// {
1048+
// return try_emplace_impl(key_type(hud::forward<K>(key)));
1049+
// }
1050+
}
10401051

10411052
constexpr void swap(hashset_impl &other) noexcept
10421053
requires(hud::is_swappable_v<slot_type>)
@@ -1163,6 +1174,43 @@ namespace hud
11631174
return {control_ptr_ + res.first, slot_ptr};
11641175
}
11651176

1177+
template<typename K>
1178+
[[nodiscard]] constexpr decltype(auto) forward_key(K &&k) noexcept
1179+
{
1180+
if constexpr (is_hashable_and_comparable_v<K>)
1181+
{
1182+
return hud::forward<K>(k);
1183+
}
1184+
else
1185+
{
1186+
return key_type(hud::forward<K>(k));
1187+
}
1188+
}
1189+
1190+
template<typename... Args>
1191+
[[nodiscard]] constexpr decltype(auto) forward_key(hud::tuple<Args...> &&tuple) noexcept
1192+
{
1193+
constexpr auto forward_key_tuple_impl = []<usize... indices_key>(
1194+
hud::tuple<Args...> &&key_tuple,
1195+
hud::index_sequence<indices_key...>
1196+
) -> decltype(auto)
1197+
{
1198+
if constexpr (is_hashable_and_comparable_v<hud::tuple<Args...>>)
1199+
{
1200+
static_assert(hud::is_constructible_v<key_type, decltype(hud::get<indices_key>(key_tuple))...>, "key_type is hashable and comparable with the given tuple but cannot be constructed from its values. ");
1201+
return hud::forward<hud::tuple<Args...>>(key_tuple);
1202+
}
1203+
else
1204+
{
1205+
static_assert(hud::is_constructible_v<key_type, decltype(hud::get<indices_key>(key_tuple))...>, "key_type is neither hashable nor comparable with the given tuple, and cannot be constructed from its values. "
1206+
"Ensure that hud::equal and hud::hash support hud::tuple<...&&>&&, or provide a constructor for key_type that accepts the tuple elements.");
1207+
return key_type(hud::get<indices_key>(key_tuple)...);
1208+
}
1209+
};
1210+
1211+
return forward_key_tuple_impl(hud::forward<hud::tuple<Args...>>(tuple), hud::make_index_sequence<hud::tuple_size_v<hud::tuple<Args...>>> {});
1212+
}
1213+
11661214
/**
11671215
* Adds a new element to the container using piecewise construction of the key and value.
11681216
*
@@ -1184,29 +1232,29 @@ namespace hud
11841232
template<typename key_tuple_t, typename value_tuple_t>
11851233
constexpr iterator add(hud::tag_piecewise_construct_t, key_tuple_t &&key_tuple, value_tuple_t &&value_tuple) noexcept
11861234
{
1187-
/**
1188-
* If the tuple can't be used directly as a hashable/comparable key,
1189-
* we unpack its elements and construct a key_type from them.
1190-
*/
1191-
constexpr auto forward_key = []<usize... indices_key>(
1192-
key_tuple_t &&key_tuple,
1193-
hud::index_sequence<indices_key...>
1194-
) -> decltype(auto)
1195-
{
1196-
if constexpr (is_hashable_and_comparable_v<key_tuple_t>)
1197-
{
1198-
static_assert(hud::is_constructible_v<key_type, decltype(hud::get<indices_key>(key_tuple))...>, "key_type is hashable and comparable with the given tuple but cannot be constructed from its values. ");
1199-
return hud::forward<key_tuple_t>(key_tuple);
1200-
}
1201-
else
1202-
{
1203-
static_assert(hud::is_constructible_v<key_type, decltype(hud::get<indices_key>(key_tuple))...>, "key_type is neither hashable nor comparable with the given tuple, and cannot be constructed from its values. "
1204-
"Ensure that hud::equal and hud::hash support hud::tuple<...&&>&&, or provide a constructor for key_type that accepts the tuple elements.");
1205-
return key_type(hud::get<indices_key>(key_tuple)...);
1206-
}
1207-
};
1208-
1209-
hud::pair<usize, bool> res = find_or_insert_no_construct(forward_key(hud::forward<key_tuple_t>(key_tuple), hud::make_index_sequence<hud::tuple_size_v<key_tuple_t>> {}));
1235+
// /**
1236+
// * If the tuple can't be used directly as a hashable/comparable key,
1237+
// * we unpack its elements and construct a key_type from them.
1238+
// */
1239+
// constexpr auto forward_key = []<usize... indices_key>(
1240+
// key_tuple_t &&key_tuple,
1241+
// hud::index_sequence<indices_key...>
1242+
// ) -> decltype(auto)
1243+
// {
1244+
// if constexpr (is_hashable_and_comparable_v<key_tuple_t>)
1245+
// {
1246+
// static_assert(hud::is_constructible_v<key_type, decltype(hud::get<indices_key>(key_tuple))...>, "key_type is hashable and comparable with the given tuple but cannot be constructed from its values. ");
1247+
// return hud::forward<key_tuple_t>(key_tuple);
1248+
// }
1249+
// else
1250+
// {
1251+
// static_assert(hud::is_constructible_v<key_type, decltype(hud::get<indices_key>(key_tuple))...>, "key_type is neither hashable nor comparable with the given tuple, and cannot be constructed from its values. "
1252+
// "Ensure that hud::equal and hud::hash support hud::tuple<...&&>&&, or provide a constructor for key_type that accepts the tuple elements.");
1253+
// return key_type(hud::get<indices_key>(key_tuple)...);
1254+
// }
1255+
// };
1256+
1257+
hud::pair<usize, bool> res = find_or_insert_no_construct(forward_key(hud::forward<key_tuple_t>(key_tuple)));
12101258
slot_type *slot_ptr {slot_ptr_ + res.first};
12111259
if (res.second)
12121260
{
@@ -1250,6 +1298,13 @@ namespace hud
12501298
}
12511299
}
12521300

1301+
template<typename K>
1302+
[[nodiscard]]
1303+
constexpr iterator try_emplace_impl(K &&key) noexcept
1304+
{
1305+
find_or_insert_no_construct(key);
1306+
}
1307+
12531308
template<typename K>
12541309
[[nodiscard]] constexpr u64 compute_hash(K &&key) noexcept
12551310
{

0 commit comments

Comments
 (0)