Add equality operators

This commit is contained in:
King_DuckZ 2022-05-24 16:07:16 +02:00
parent e97c7bad10
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;

View file

@ -74,6 +74,7 @@ wrenpp = library(meson.project_name(),
'src/class_manager.cpp',
'src/wren_class_name_from_type.cpp',
'src/crc32.cpp',
'src/module_and_name.cpp',
dependencies: [wren_dep],
include_directories: public_incl,
install: (not meson.is_subproject() or get_option('default_library')=='shared'),

30
src/module_and_name.cpp Normal file
View file

@ -0,0 +1,30 @@
/* Copyright 2020-2022, Michele Santullo
* This file is part of wrenpp.
*
* Wrenpp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Wrenpp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wrenpp. If not, see <http://www.gnu.org/licenses/>.
*/
#include "wrenpp/detail/module_and_name.hpp"
#include <algorithm>
namespace wren::detail {
bool deep_equal(const ModuleAndName& a, const ModuleAndName& b) noexcept {
const auto a_size = a.raw_buffer_size();
const auto b_size = b.raw_buffer_size();
if (a_size != b_size)
return false;
return std::equal(a.m_base, a.m_base + a_size, b.m_base);
}
} //namespace wren::detail