Program Listing for File Node.hpp

Return to documentation for file (src/rdf4cpp/Node.hpp)

#ifndef RDF4CPP_NODE_HPP
#define RDF4CPP_NODE_HPP

#include <rdf4cpp/TriBool.hpp>
#include <rdf4cpp/storage/NodeStorage.hpp>
#include <rdf4cpp/storage/identifier/NodeBackendHandle.hpp>
#include <rdf4cpp/writer/BufWriter.hpp>

#include <memory>
#include <optional>
#include <string>

namespace rdf4cpp {

struct Literal;
struct BlankNode;
struct IRI;
namespace query {
    struct Variable;
} // namespace rdf4cpp

enum struct FetchOrSerializeResult {
    Fetched, //< result was already materialized and was fetched
    Serialized, //< result was successfully serialized
    SerializationFailed, //< result had to be serialized, but serialization failed
};

struct NodeSerializationOpts {
    bool use_short_form;
    bool use_prefixes;

    [[nodiscard]] static NodeSerializationOpts long_form() noexcept {
        return NodeSerializationOpts{};
    }

    [[nodiscard]] static NodeSerializationOpts short_form() noexcept {
        return NodeSerializationOpts{.use_short_form = true, .use_prefixes = false};
    }

    [[nodiscard]] static NodeSerializationOpts prefixed() noexcept {
        return NodeSerializationOpts{.use_short_form = false, .use_prefixes = true};
    }

    [[nodiscard]] static NodeSerializationOpts prefixed_and_short_form() noexcept {
        return NodeSerializationOpts{.use_short_form = true, .use_prefixes = true};
    }
};

inline constexpr storage::DynNodeStoragePtr keep_node_storage{nullptr};

struct Node {
protected:
    storage::identifier::NodeBackendHandle handle_;

    [[nodiscard]] storage::DynNodeStoragePtr select_node_storage(storage::DynNodeStoragePtr node_storage) const noexcept {
        if (node_storage == keep_node_storage) {
            return handle_.storage();
        } else {
            return node_storage;
        }
    }

    [[nodiscard]] TriBool eq_impl(Node const &other) const noexcept;

    [[nodiscard]] std::partial_ordering compare_impl(Node const &other) const noexcept;

public:
    explicit Node(storage::identifier::NodeBackendHandle id) noexcept;

    Node to_node_storage(storage::DynNodeStoragePtr node_storage) const;

    [[nodiscard]] Node try_get_in_node_storage(storage::DynNodeStoragePtr node_storage) const noexcept;

    Node() noexcept = default;

    [[nodiscard]] static Node make_null() noexcept;

    bool serialize(writer::BufWriterParts writer, NodeSerializationOpts opts = NodeSerializationOpts::long_form()) const noexcept;

    [[nodiscard]] explicit operator std::string() const noexcept;

    friend std::ostream &operator<<(std::ostream &os, const Node &node);

    [[nodiscard]] TriBool is_literal() const noexcept;

    [[nodiscard]] TriBool is_variable() const noexcept;

    [[nodiscard]] TriBool is_blank_node() const noexcept;

    [[nodiscard]] TriBool is_iri() const noexcept;

    [[nodiscard]] bool is_inlined() const noexcept;


    // [[nodiscard]] std::partial_ordering compare(Node const &other) const noexcept;

    [[nodiscard]] std::strong_ordering order(Node const &other) const noexcept;

    [[nodiscard]] TriBool eq(Node const &other) const noexcept;
    [[nodiscard]] bool order_eq(Node const &other) const noexcept;
    [[nodiscard]] TriBool ne(Node const &other) const noexcept;
    [[nodiscard]] bool order_ne(Node const &other) const noexcept;
    [[nodiscard]] TriBool lt(Node const &other) const noexcept;
    [[nodiscard]] bool order_lt(Node const &other) const noexcept;
    [[nodiscard]] TriBool le(Node const &other) const noexcept;
    [[nodiscard]] bool order_le(Node const &other) const noexcept;
    [[nodiscard]] TriBool gt(Node const &other) const noexcept;
    [[nodiscard]] bool order_gt(Node const &other) const noexcept;
    [[nodiscard]] TriBool ge(Node const &other) const noexcept;
    [[nodiscard]] bool order_ge(Node const &other) const noexcept;

    [[nodiscard]] Literal as_eq(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_order_eq(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_ne(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_order_ne(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_lt(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_order_lt(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_le(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_order_le(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_gt(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_order_gt(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_ge(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;
    [[nodiscard]] Literal as_order_ge(Node const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;

    bool operator==(const Node &other) const noexcept;

    std::partial_ordering operator<=>(Node const &other) const noexcept;

    [[nodiscard]] TriBool ebv() const noexcept;

    [[nodiscard]] Literal as_ebv(storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept;

    explicit operator bool() const noexcept;

    [[nodiscard]] BlankNode as_blank_node() const noexcept;

    [[nodiscard]] IRI as_iri() const noexcept;

    [[nodiscard]] Literal as_literal() const noexcept;

    [[nodiscard]] query::Variable as_variable() const noexcept;


    [[nodiscard]] bool null() const noexcept;

    [[nodiscard]] storage::identifier::NodeBackendHandle const &backend_handle() const noexcept;

    [[nodiscard]] storage::identifier::NodeBackendHandle &backend_handle() noexcept;
};

static_assert(sizeof(Node) == sizeof(void *) * 3);
static_assert(alignof(Node) == alignof(void *));

}  // namespace rdf4cpp

template<>
struct std::hash<rdf4cpp::Node> {
    inline size_t operator()(rdf4cpp::Node const &v) const noexcept {
        return std::hash<rdf4cpp::storage::identifier::NodeBackendHandle>()(v.backend_handle());
    }
};

template<typename Policy>
struct dice::hash::dice_hash_overload<Policy, rdf4cpp::Node> {
    static inline size_t dice_hash(rdf4cpp::Node const &x) noexcept {
        return dice::hash::dice_hash_templates<Policy>::dice_hash(x.backend_handle());
    }
};

template<>
struct std::formatter<rdf4cpp::Node> {
    constexpr auto parse(format_parse_context &ctx) {
        auto b = ctx.begin();
        if (b != ctx.end() && *b == '}') {
            return b;
        }
        if (b != ctx.end())
            throw std::format_error("parameters");
        return ctx.end();
    }
    auto format(rdf4cpp::Node n, format_context &ctx) const -> decltype(ctx.out());
};

#include <ostream>
#include <rdf4cpp/BlankNode.hpp>
#include <rdf4cpp/IRI.hpp>
#include <rdf4cpp/Literal.hpp>
#include <rdf4cpp/query/Variable.hpp>

#endif  //RDF4CPP_NODE_HPP