.. _program_listing_file_src_rdf4cpp_Node.cpp: Program Listing for File Node.cpp ================================= |exhale_lsh| :ref:`Return to documentation for file ` (``src/rdf4cpp/Node.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "Node.hpp" #include #include #include #include #include #include namespace rdf4cpp { Node::Node(storage::identifier::NodeBackendHandle id) noexcept : handle_(id) {} Node Node::make_null() noexcept { return Node{}; } Node Node::to_node_storage(storage::DynNodeStoragePtr node_storage) const { switch (handle_.type()) { case storage::identifier::RDFNodeType::Variable: { return query::Variable{handle_}.to_node_storage(node_storage); } case storage::identifier::RDFNodeType::BNode: { return BlankNode{handle_}.to_node_storage(node_storage); } case storage::identifier::RDFNodeType::IRI: { return IRI{handle_}.to_node_storage(node_storage); } case storage::identifier::RDFNodeType::Literal: { return Literal{handle_}.to_node_storage(node_storage); } default: { RDF4CPP_UNREACHABLE; } } } Node Node::try_get_in_node_storage(storage::DynNodeStoragePtr node_storage) const noexcept { switch (handle_.type()) { case storage::identifier::RDFNodeType::Variable: { return query::Variable{handle_}.try_get_in_node_storage(node_storage); } case storage::identifier::RDFNodeType::BNode: { return BlankNode{handle_}.try_get_in_node_storage(node_storage); } case storage::identifier::RDFNodeType::IRI: { return IRI{handle_}.try_get_in_node_storage(node_storage); } case storage::identifier::RDFNodeType::Literal: { return Literal{handle_}.try_get_in_node_storage(node_storage); } default: { RDF4CPP_UNREACHABLE; } } } bool Node::serialize(writer::BufWriterParts const writer, NodeSerializationOpts opts) const noexcept { if (null()) { return rdf4cpp::writer::write_str("null", writer); } switch (handle_.type()) { [[likely]] case storage::identifier::RDFNodeType::IRI: { return IRI{handle_}.serialize(writer); } case storage::identifier::RDFNodeType::Variable: { return query::Variable{handle_}.serialize(writer); } case storage::identifier::RDFNodeType::BNode: { return BlankNode{handle_}.serialize(writer); } case storage::identifier::RDFNodeType::Literal: { return Literal{handle_}.serialize(writer, opts); } default: { RDF4CPP_UNREACHABLE; } } } Node::operator std::string() const noexcept { switch (handle_.type()) { [[likely]] case storage::identifier::RDFNodeType::IRI: { return std::string{IRI{handle_}}; } case storage::identifier::RDFNodeType::Variable: { return std::string{query::Variable{handle_}}; } case storage::identifier::RDFNodeType::BNode: { return std::string{BlankNode{handle_}}; } case storage::identifier::RDFNodeType::Literal: { return std::string{Literal{handle_}}; } default: { RDF4CPP_UNREACHABLE; } } } TriBool Node::is_literal() const noexcept { return handle_.is_literal(); } TriBool Node::is_variable() const noexcept { return handle_.is_variable(); } TriBool Node::is_blank_node() const noexcept { return handle_.is_blank_node(); } TriBool Node::is_iri() const noexcept { return handle_.is_iri(); } bool Node::is_inlined() const noexcept { return handle_.is_inlined(); } TriBool Node::eq_impl(Node const &other) const noexcept { if (null() || other.null()) { // "Apart from BOUND, COALESCE, NOT EXISTS and EXISTS, all functions and operators operate on RDF Terms and will produce a type error if any arguments are unbound." // - https://www.w3.org/TR/sparql11-query/#evaluation return TriBool::Err; } if (handle_ == other.handle_) { return TriBool::True; } if (handle_.type() != other.handle_.type()) { return TriBool::Err; } using storage::identifier::RDFNodeType; switch (handle_.type()) { case RDFNodeType::Literal: { return Literal{handle_}.eq(Literal{other.handle_}); } case RDFNodeType::IRI: { return handle_.iri_backend() == other.handle_.iri_backend(); } case RDFNodeType::BNode: { return BlankNode{handle_}.eq(BlankNode{other.handle_}); } case RDFNodeType::Variable: { return query::Variable{handle_}.eq(query::Variable{other.handle_}); } default: { RDF4CPP_UNREACHABLE; } } } std::partial_ordering Node::compare_impl(Node const &other) const noexcept { if (null() || other.null()) { // "Apart from BOUND, COALESCE, NOT EXISTS and EXISTS, all functions and operators operate on RDF Terms and will produce a type error if any arguments are unbound." // - https://www.w3.org/TR/sparql11-query/#evaluation return std::partial_ordering::unordered; } if (handle_ == other.handle_) { return std::partial_ordering::equivalent; } if (handle_.type() != other.handle_.type() || handle_.type() != storage::identifier::RDFNodeType::Literal) { // mismatched node types are not comparable // and nodes other than literals are not comparable with <,<=,>,>= return std::partial_ordering::unordered; } return Literal{handle_}.compare(Literal{other.handle_}); } std::strong_ordering Node::order(Node const &other) const noexcept { if (this->handle_ == other.handle_) { return std::strong_ordering::equivalent; } // null nodes are the smallest nodes // https://www.w3.org/TR/sparql11-query/#modOrderBy if (this->null() && other.null()) { return this->handle_.type() <=> other.handle_.type(); } if (this->null()) { return std::strong_ordering::less; } if (other.null()) { return std::strong_ordering::greater; } // different type if (std::strong_ordering const type_comp = this->handle_.type() <=> other.handle_.type(); type_comp != std::strong_ordering::equivalent) { return type_comp; } switch (this->handle_.type()) { case storage::identifier::RDFNodeType::IRI: return this->handle_.iri_backend() <=> other.handle_.iri_backend(); case storage::identifier::RDFNodeType::BNode: return BlankNode{handle_}.order(BlankNode{other.handle_}); case storage::identifier::RDFNodeType::Literal: return Literal{handle_}.order(Literal{other.handle_}); case storage::identifier::RDFNodeType::Variable: return query::Variable{this->handle_}.order(query::Variable{other.handle_}); default:{ // this will never be reached because RDFNodeType has only 4 values. RDF4CPP_UNREACHABLE; } } } TriBool Node::eq(Node const &other) const noexcept { return eq_impl(other); } bool Node::order_eq(Node const &other) const noexcept { return order(other) == std::weak_ordering::equivalent; } TriBool Node::ne(Node const &other) const noexcept { return !eq_impl(other); } bool Node::order_ne(Node const &other) const noexcept { return order(other) != std::weak_ordering::equivalent; } TriBool Node::lt(Node const &other) const noexcept { return util::partial_weak_ordering_eq(compare_impl(other), std::weak_ordering::less); } bool Node::order_lt(Node const &other) const noexcept { return order(other) == std::weak_ordering::less; } TriBool Node::le(Node const &other) const noexcept { return !util::partial_weak_ordering_eq(compare_impl(other), std::weak_ordering::greater); } bool Node::order_le(Node const &other) const noexcept { return order(other) != std::weak_ordering::greater; } TriBool Node::gt(Node const &other) const noexcept { return util::partial_weak_ordering_eq(compare_impl(other), std::weak_ordering::greater); } bool Node::order_gt(Node const &other) const noexcept { return order(other) == std::weak_ordering::greater; } TriBool Node::ge(Node const &other) const noexcept { return !util::partial_weak_ordering_eq(compare_impl(other), std::weak_ordering::less); } bool Node::order_ge(Node const &other) const noexcept { return order(other) != std::weak_ordering::less; } Literal Node::as_eq(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(eq(other), select_node_storage(node_storage)); } Literal Node::as_order_eq(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(order_eq(other), select_node_storage(node_storage)); } Literal Node::as_ne(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(ne(other), select_node_storage(node_storage)); } Literal Node::as_order_ne(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(order_ne(other), select_node_storage(node_storage)); } Literal Node::as_lt(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(lt(other), select_node_storage(node_storage)); } Literal Node::as_order_lt(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(order_lt(other), select_node_storage(node_storage)); } Literal Node::as_le(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(le(other), select_node_storage(node_storage)); } Literal Node::as_order_le(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(order_le(other), select_node_storage(node_storage)); } Literal Node::as_gt(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(gt(other), select_node_storage(node_storage)); } Literal Node::as_order_gt(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(order_gt(other), select_node_storage(node_storage)); } Literal Node::as_ge(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(ge(other), select_node_storage(node_storage)); } Literal Node::as_order_ge(Node const &other, storage::DynNodeStoragePtr node_storage) const noexcept { return Literal::make_boolean(order_ge(other), select_node_storage(node_storage)); } std::partial_ordering Node::operator<=>(Node const &other) const noexcept { return order(other); } bool Node::operator==(const Node &other) const noexcept { return order_eq(other); } BlankNode Node::as_blank_node() const noexcept { if (!this->is_blank_node()) { return BlankNode{}; } return BlankNode{handle_}; } IRI Node::as_iri() const noexcept { if (!this->is_iri()) { return IRI{}; } return IRI{handle_}; } Literal Node::as_literal() const noexcept { if (!this->is_literal()) { return Literal{}; } return Literal{handle_}; } query::Variable Node::as_variable() const noexcept { if (!this->is_variable()) { return query::Variable{}; } return query::Variable{handle_}; } bool Node::null() const noexcept { return handle_.null(); } std::ostream &operator<<(std::ostream &os, Node const &node) { writer::BufOStreamWriter w{os}; node.serialize(w); w.finalize(); return os; } storage::identifier::NodeBackendHandle const &Node::backend_handle() const noexcept { return handle_; } storage::identifier::NodeBackendHandle &Node::backend_handle() noexcept { return handle_; } TriBool Node::ebv() const noexcept { if (this->null() || !this->is_literal()) { return TriBool::Err; } return Literal{handle_}.ebv(); } Literal Node::as_ebv(storage::DynNodeStoragePtr node_storage) const noexcept { return this->as_literal().as_ebv(node_storage); } Node::operator bool() const noexcept { return ebv(); } } // namespace rdf4cpp auto std::formatter::format(rdf4cpp::Node n, format_context &ctx) const -> decltype(ctx.out()) { rdf4cpp::writer::BufOutputIteratorWriter w{ctx.out()}; n.serialize(w); w.finalize(); return w.buffer().iter; }