Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/rdf4cpp/storage/identifier/LiteralID.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cassert>
#include <compare>
#include <cstdint>
#include <ostream>

namespace rdf4cpp::storage::identifier {
/**
Expand Down Expand Up @@ -61,5 +62,11 @@ struct __attribute__((__packed__)) LiteralID {

constexpr std::strong_ordering operator<=>(LiteralID const &) const noexcept = default;
};

inline std::ostream &operator<<(std::ostream &os, LiteralID id) {
os << "{ .underlying = " << id.to_underlying() << " }";
return os;
}

} // namespace rdf4cpp::storage::identifier
#endif //RDF4CPP_LITERALID_HPP
31 changes: 28 additions & 3 deletions src/rdf4cpp/storage/identifier/LiteralType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <compare>
#include <cstddef>
#include <cstdint>
#include <ostream>
#include <rdf4cpp/TriBool.hpp>

namespace rdf4cpp::storage::identifier {
Expand All @@ -16,6 +17,21 @@ enum struct LiteralTypeTag : uint8_t {
Duration = 0b11,
};

constexpr std::string_view to_string_view(LiteralTypeTag tag) {
switch (tag) {
case LiteralTypeTag::Default: return "Default";
case LiteralTypeTag::Numeric: return "Numeric";
case LiteralTypeTag::Timepoint: return "Timepoint";
case LiteralTypeTag::Duration: return "Duration";
default: return "Undefined";
}
}

inline std::ostream &operator<<(std::ostream &os, LiteralTypeTag tag) {
os << to_string_view(tag);
return os;
}

/**
* <p>A literal type specifies the type of a literal. Types, which are not available within this enum class MUST be specified as LiteralType::OTHER.</p>
* <p>The purpose of this type is to provide a short-cut for common types like xsd:string or xsd:float when used within NodeID or NodeBackendHandle.
Expand Down Expand Up @@ -50,28 +66,32 @@ struct __attribute__((__packed__)) LiteralType {
return *this != LiteralType::other();
}

[[nodiscard]] constexpr LiteralTypeTag tag() const noexcept {
return static_cast<LiteralTypeTag>((underlying_ >> numeric_tagging_bit_shift) & 0b11);
}

[[nodiscard]] constexpr TriBool is_numeric() const noexcept {
if (!is_fixed()) {
return TriBool::Err;
}

return static_cast<LiteralTypeTag>((underlying_ >> numeric_tagging_bit_shift) & 0b11) == LiteralTypeTag::Numeric;
return tag() == LiteralTypeTag::Numeric;
}

[[nodiscard]] constexpr TriBool is_timepoint() const noexcept {
if (!is_fixed()) {
return TriBool::Err;
}

return static_cast<LiteralTypeTag>((underlying_ >> numeric_tagging_bit_shift) & 0b11) == LiteralTypeTag::Timepoint;
return tag() == LiteralTypeTag::Timepoint;
}

[[nodiscard]] constexpr TriBool is_duration() const noexcept {
if (!is_fixed()) {
return TriBool::Err;
}

return static_cast<LiteralTypeTag>((underlying_ >> numeric_tagging_bit_shift) & 0b11) == LiteralTypeTag::Duration;
return tag() == LiteralTypeTag::Duration;
}

[[nodiscard]] constexpr uint8_t type_id() const noexcept {
Expand All @@ -89,6 +109,11 @@ struct __attribute__((__packed__)) LiteralType {
constexpr std::strong_ordering operator<=>(LiteralType const &other) const noexcept = default;
};

inline std::ostream &operator<<(std::ostream &os, LiteralType type) {
os << "{ .tag = " << type.tag() << ", .id = " << static_cast<unsigned>(type.type_id()) << " }";
return os;
}

} // namespace rdf4cpp::storage::identifier

#endif //RDF4CPP_LITERALTYPE_HPP
5 changes: 5 additions & 0 deletions src/rdf4cpp/storage/identifier/NodeBackendHandle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ struct NodeBackendHandle {

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;
}

/**
* Constructor to create an IRI handle for the datatype of a Literal with fixed id datatype
* @param lit_handle handle of the literal
Expand Down
11 changes: 11 additions & 0 deletions src/rdf4cpp/storage/identifier/NodeBackendID.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,17 @@ struct alignas(uint64_t) NodeBackendID {
static_assert(sizeof(NodeBackendID) == sizeof(uint64_t));
static_assert(alignof(NodeBackendID) == alignof(uint64_t));

inline std::ostream &operator<<(std::ostream &os, NodeBackendID id) {
if (id.is_literal()) {
os << "{ .node_id = { .literal_id = " << id.node_id().literal_id() << ", .literal_type = " << id.node_id().literal_type()
<< " }, .type = " << id.type() << ", .is_inlined = " << std::boolalpha << id.is_inlined() << ", .free_tagging_bits = " << id.free_tagging_bits() << " }";
} else {
os << "{ .node_id = " << id.node_id() << ", .type = " << id.type() << ", .is_inlined = " << std::boolalpha << id.is_inlined() << ", .free_tagging_bits = " << id.free_tagging_bits() << " }";
}

return os;
}

/**
* Convert a NodeId for an IRI
* to a LiteralType.
Expand Down
5 changes: 5 additions & 0 deletions src/rdf4cpp/storage/identifier/NodeID.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ inline constexpr NodeID NodeID::min_iri_id{datatypes::registry::min_dynamic_data
inline constexpr NodeID NodeID::min_variable_id{1};
inline constexpr LiteralID NodeID::min_literal_id{1};

inline std::ostream &operator<<(std::ostream &os, NodeID id) {
os << "{ .underlying = " << id.to_underlying() << " }";
return os;
}

} // namespace rdf4cpp::storage::identifier

#ifndef DOXYGEN_PARSER
Expand Down
20 changes: 10 additions & 10 deletions src/rdf4cpp/storage/identifier/RDFNodeType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@ enum struct RDFNodeType : uint8_t {

constexpr std::string_view to_string_view(RDFNodeType const node_type) noexcept {
switch (node_type) {
case RDFNodeType::Variable:
return "variable";
case RDFNodeType::BNode:
return "blank node";
case RDFNodeType::IRI:
return "iri";
case RDFNodeType::Literal:
return "literal";
default:
return "undefined";
case RDFNodeType::Variable: return "Variable";
case RDFNodeType::BNode: return "BNode";
case RDFNodeType::IRI: return "IRI";
case RDFNodeType::Literal: return "Literal";
default: return "Undefined";
}
}

inline std::string to_string(RDFNodeType const node_type) noexcept {
return std::string{to_string_view(node_type)};
}

inline std::ostream &operator<<(std::ostream &os, RDFNodeType type) {
os << to_string_view(type);
return os;
}

} // namespace rdf4cpp::storage::identifier


Expand Down
7 changes: 7 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ target_link_libraries(tests_NodeStorage_helper_types
)
add_test(NAME tests_NodeStorage_helper_types COMMAND tests_NodeStorage_helper_types)

add_executable(tests_NodeStorage_ids nodes/tests_NodeStorage_ids.cpp)
target_link_libraries(tests_NodeStorage_ids
doctest::doctest
rdf4cpp
)
add_test(NAME tests_NodeStorage_ids COMMAND tests_NodeStorage_ids)


# RDF Core Types
add_executable(tests_String datatype/tests_String.cpp)
Expand Down
60 changes: 60 additions & 0 deletions tests/nodes/tests_NodeStorage_ids.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>

#include <rdf4cpp/storage/identifier/NodeBackendHandle.hpp>

TEST_SUITE("node storage identifier output") {
using namespace rdf4cpp::storage::identifier;

template<typename T>
void check_string_repr(T id, std::string_view expected) {
std::ostringstream oss;
oss << id;
CHECK_EQ(oss.str(), expected);
}

TEST_CASE("RDFNodeType") {
check_string_repr(RDFNodeType::Literal, "Literal");
check_string_repr(RDFNodeType::Variable, "Variable");
check_string_repr(RDFNodeType::BNode, "BNode");
check_string_repr(RDFNodeType::IRI, "IRI");
}

TEST_CASE("LiteralID") {
check_string_repr(LiteralID{123}, "{ .underlying = 123 }");
}

TEST_CASE("LiteralTypeTag") {
check_string_repr(LiteralTypeTag::Default, "Default");
check_string_repr(LiteralTypeTag::Duration, "Duration");
check_string_repr(LiteralTypeTag::Timepoint, "Timepoint");
check_string_repr(LiteralTypeTag::Numeric, "Numeric");
}

TEST_CASE("LiteralType") {
check_string_repr(LiteralType::from_parts(LiteralTypeTag::Default, 1), "{ .tag = Default, .id = 1 }");
check_string_repr(LiteralType::from_parts(LiteralTypeTag::Duration, 1), "{ .tag = Duration, .id = 1 }");
check_string_repr(LiteralType::from_parts(LiteralTypeTag::Timepoint, 1), "{ .tag = Timepoint, .id = 1 }");
check_string_repr(LiteralType::from_parts(LiteralTypeTag::Numeric, 1), "{ .tag = Numeric, .id = 1 }");
}

TEST_CASE("NodeID") {
check_string_repr(NodeID{LiteralID{1}, LiteralType::from_parts(LiteralTypeTag::Default, 1)}, "{ .underlying = 4398046511105 }");
check_string_repr(NodeID{123}, "{ .underlying = 123 }");
}

TEST_CASE("NodeBackendID") {
check_string_repr(NodeBackendID{NodeID{LiteralID{1}, LiteralType::from_parts(LiteralTypeTag::Default, 1)}, RDFNodeType::Literal},
"{ .node_id = { .literal_id = { .underlying = 1 }, .literal_type = { .tag = Default, .id = 1 } }, .type = Literal, .is_inlined = false, .free_tagging_bits = 0 }");
check_string_repr(NodeBackendID{NodeID{123}, RDFNodeType::IRI},
"{ .node_id = { .underlying = 123 }, .type = IRI, .is_inlined = false, .free_tagging_bits = 0 }");
}

TEST_CASE("NodeBackendHandle") {
check_string_repr(NodeBackendHandle{NodeBackendID{NodeID{123}, RDFNodeType::IRI}, nullptr},
"{ .id = { .node_id = { .underlying = 123 }, .type = IRI, .is_inlined = false, .free_tagging_bits = 0 }, .node_storage = { .backend = 0, .vtable = 0 } }");
check_string_repr(NodeBackendHandle{NodeBackendID{NodeID{123}, RDFNodeType::IRI}, rdf4cpp::storage::default_node_storage},
std::format("{{ .id = {{ .node_id = {{ .underlying = 123 }}, .type = IRI, .is_inlined = false, .free_tagging_bits = 0 }}, .node_storage = {{ .backend = {}, .vtable = {} }} }}",
rdf4cpp::storage::default_node_storage.backend(), static_cast<void const *>(rdf4cpp::storage::default_node_storage.vtable())));
}
}
Loading