Add equality operators

This commit is contained in:
King_DuckZ 2022-05-24 16:07:16 +02:00
commit e8db08931a
3 changed files with 74 additions and 0 deletions

View file

@ -20,13 +20,20 @@
#include "string_bt.hpp"
#include <string_view>
#include <cstdint>
#include <cassert>
#include <type_traits>
namespace wren {
class ModuleAndName;
namespace detail {
template <dhandy::bt::string S>
struct ModuleAndNameStaticStorage {
static constexpr const auto value = S;
};
[[gnu::const]]
bool deep_equal (const ModuleAndName& a, const ModuleAndName& b) noexcept;
} //unnamed namespace
//Non-owning, lightweight class for storing a module nome/class name pair.
@ -40,10 +47,15 @@ namespace wren {
//of this class get hardcoded in the dynamic functions that DynafuncMaker
//spits out.
class ModuleAndName {
friend bool detail::deep_equal(const ModuleAndName&, const ModuleAndName&) noexcept;
public:
constexpr ModuleAndName();
constexpr ModuleAndName (const char* base, std::uint32_t hash, std::size_t mod_name_len, std::size_t class_name_len);
constexpr bool operator==(const ModuleAndName& other) const noexcept;
constexpr bool operator!=(const ModuleAndName& other) const noexcept;
constexpr bool deep_equal(const ModuleAndName& other) const noexcept;
constexpr const char* module_name_char() const noexcept { return m_base; }
constexpr const char* class_name_char() const noexcept { return m_base + 1 + m_mod_name_len; }
constexpr std::size_t module_name_len() const noexcept { return m_mod_name_len; }
@ -53,6 +65,8 @@ namespace wren {
constexpr const char* buffer_address() const noexcept { return m_base; }
private:
constexpr std::size_t raw_buffer_size() const noexcept;
const char* m_base;
std::uint32_t m_hash;
std::uint16_t m_mod_name_len;
@ -85,6 +99,35 @@ namespace wren {
m_class_name_len(class_name_len)
{}
constexpr bool ModuleAndName::operator==(const ModuleAndName& other) const noexcept {
const bool retval = (this->m_hash == other.m_hash);
assert(not retval or deep_equal(other));
return retval;
}
constexpr bool ModuleAndName::operator!=(const ModuleAndName& other) const noexcept {
return not this->operator==(other);
}
constexpr bool ModuleAndName::deep_equal(const ModuleAndName& other) const noexcept {
if (not std::is_constant_evaluated()) {
return detail::deep_equal(*this, other);
}
else {
if (this->raw_buffer_size() != other.raw_buffer_size())
return false;
for (std::size_t z = 0; z < raw_buffer_size(); ++z) {
if (this->m_base[z] != other.m_base[z])
return false;
}
return true;
}
}
constexpr std::size_t ModuleAndName::raw_buffer_size() const noexcept {
return m_mod_name_len + m_class_name_len + 2;
}
template <dhandy::bt::string S1, dhandy::bt::string S2>
constexpr ModuleAndName make_module_and_name() {
using dhandy::bt::string;