Program Listing for File NodeBackendHandle.hpp

Return to documentation for file (src/rdf4cpp/storage/identifier/NodeBackendHandle.hpp)

#ifndef RDF4CPP_NODEBACKENDHANDLE_HPP
#define RDF4CPP_NODEBACKENDHANDLE_HPP

#include <rdf4cpp/storage/NodeStorage.hpp>
#include <rdf4cpp/storage/identifier/NodeBackendID.hpp>
#include <rdf4cpp/storage/view/BNodeBackendView.hpp>
#include <rdf4cpp/storage/view/IRIBackendView.hpp>
#include <rdf4cpp/storage/view/LiteralBackendView.hpp>
#include <rdf4cpp/storage/view/VariableBackendView.hpp>

#include <compare>
#include <cstdint>

namespace rdf4cpp::storage::identifier {
struct NodeBackendHandle {
private:
    NodeBackendID id_;
    DynNodeStoragePtr storage_;


public:
    NodeBackendHandle() noexcept = default;

    NodeBackendHandle(NodeBackendID id,
                      DynNodeStoragePtr storage) noexcept : id_{id},
                                                            storage_{storage} {
    }

    NodeBackendHandle(NodeID const node_id,
                      RDFNodeType const node_type,
                      DynNodeStoragePtr storage,
                      bool const inlined = false,
                      uint16_t const tagging_bits = 0) noexcept : id_{node_id, node_type, inlined, tagging_bits},
                                                                  storage_{storage} {
        RDF4CPP_ASSERT(tagging_bits < (1 << 13));
    }

    [[nodiscard]] constexpr RDFNodeType type() const noexcept {
        return id_.type();
    }

    [[nodiscard]] constexpr TriBool is_iri() const noexcept {
        if (id_.null()) {
            return TriBool::Err;
        }
        return id_.is_iri();
    }

    [[nodiscard]] constexpr TriBool is_literal() const noexcept {
        if (id_.null()) {
            return TriBool::Err;
        }
        return id_.is_literal();
    }

    [[nodiscard]] constexpr TriBool is_blank_node() const noexcept {
        if (id_.null()) {
            return TriBool::Err;
        }
        return id_.is_blank_node();
    }

    [[nodiscard]] constexpr TriBool is_variable() const noexcept {
        if (id_.null()) {
            return TriBool::Err;
        }
        return id_.is_variable();
    }

    [[nodiscard]] constexpr bool null() const noexcept {
        return id_.null();
    }

    [[nodiscard]] constexpr NodeID node_id() const noexcept {
        return id_.node_id();
    }

    [[nodiscard]] constexpr bool is_inlined() const noexcept {
        return id_.is_inlined();
    }

    [[nodiscard]] constexpr uint16_t free_tagging_bits() const noexcept {
        return id_.free_tagging_bits();
    }

    constexpr void set_free_tagging_bits(uint16_t new_value) noexcept {
        id_.set_free_tagging_bits(new_value);
    }

    [[nodiscard]] NodeBackendID id() const noexcept {
        return id_;
    }

    [[nodiscard]] DynNodeStoragePtr storage() const noexcept {
        return storage_;
    }

    constexpr std::strong_ordering operator<=>(NodeBackendHandle const &other) const noexcept {
        return std::tie(id_, storage_) <=> std::tie(other.id_, other.storage_);
    }

    constexpr bool operator==(NodeBackendHandle const &other) const noexcept {
        return std::tie(id_, storage_) == std::tie(other.id_, other.storage_);
    }

    [[nodiscard]] view::IRIBackendView iri_backend() const noexcept {
        RDF4CPP_ASSERT(id_.is_iri());
        return storage_.find_iri_backend(id_);
    }

    [[nodiscard]] view::LiteralBackendView literal_backend() const noexcept {
        RDF4CPP_ASSERT(id_.is_literal());
        return storage_.find_literal_backend(id_);
    }

    [[nodiscard]] view::BNodeBackendView bnode_backend() const noexcept {
        RDF4CPP_ASSERT(id_.is_blank_node());
        return storage_.find_bnode_backend(id_);
    }

    [[nodiscard]] view::VariableBackendView variable_backend() const noexcept {
        RDF4CPP_ASSERT(id_.is_variable());
        return storage_.find_variable_backend(id_);
    }
};

static_assert(sizeof(NodeBackendHandle) == 3 * sizeof(void *));

inline std::ostream &operator<<(std::ostream &os, NodeBackendHandle handle) {
    os << "{ .id = " << handle.id() << ", .node_storage = { .backend = " << handle.storage().backend() << ", .vtable = " << handle.storage().vtable() << " } }";
    return os;
}

[[nodiscard]] inline NodeBackendHandle datatype_iri_handle_for_fixed_lit_handle(NodeBackendHandle lit_handle) noexcept {
    RDF4CPP_ASSERT(lit_handle.is_literal());
    RDF4CPP_ASSERT(lit_handle.node_id().literal_type().is_fixed());
    return NodeBackendHandle{literal_type_to_iri_node_id(lit_handle.node_id().literal_type()),
                             lit_handle.storage()};
}

}  // namespace rdf4cpp::storage::identifier


template<typename Policy>
struct dice::hash::dice_hash_overload<Policy, rdf4cpp::storage::identifier::NodeBackendHandle> {
    static inline size_t dice_hash(rdf4cpp::storage::identifier::NodeBackendHandle const &x) noexcept {
        return dice::hash::dice_hash_templates<Policy>::dice_hash(std::make_tuple(x.id(), x.storage()));
    }
};

template<>
struct std::hash<rdf4cpp::storage::identifier::NodeBackendHandle> {
    inline size_t operator()(rdf4cpp::storage::identifier::NodeBackendHandle const &v) const noexcept {
        return ::dice::hash::dice_hash_templates<::dice::hash::Policies::wyhash>::dice_hash(v);
    }
};

#endif  //RDF4CPP_NODEBACKENDHANDLE_HPP