.. _program_listing_file_src_rdf4cpp_Literal.hpp: Program Listing for File Literal.hpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/rdf4cpp/Literal.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef RDF4CPP_LITERAL_HPP #define RDF4CPP_LITERAL_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace rdf4cpp { struct Literal : Node { private: [[nodiscard]] static bool lexical_form_needs_escape(std::string_view lexical_form) noexcept; template requires std::is_nothrow_invocable_r_v [[nodiscard]] Literal numeric_binop_impl(OpSelect op_select, Literal const &other, storage::DynNodeStoragePtr node_storage) const; template requires std::is_nothrow_invocable_r_v [[nodiscard]] Literal numeric_unop_impl(OpSelect op_select, storage::DynNodeStoragePtr node_storage) const; template [[nodiscard]] std::optional run_binop(Literal const &other, datatypes::registry::DatatypeIDView const &this_datatype, datatypes::registry::DatatypeRegistry::DatatypeEntry const &this_entry, datatypes::registry::DatatypeIDView const &other_datatype, datatypes::registry::DatatypeRegistry::DatatypeEntry const &other_entry, storage::DynNodeStoragePtr node_storage, Op &&op) const; template [[nodiscard]] std::optional run_binop_cast_rhs(Literal const &other, datatypes::registry::DatatypeRegistry::DatatypeEntry const &other_entry, datatypes::registry::DatatypeIDView const &other_target, storage::DynNodeStoragePtr node_storage, Op &&op) const; [[nodiscard]] std::optional chrono_add_impl(Literal const &other, storage::DynNodeStoragePtr node_storage) const; [[nodiscard]] std::optional chrono_sub_impl(Literal const &other, storage::DynNodeStoragePtr node_storage) const; [[nodiscard]] std::optional chrono_mul_impl(Literal const &other, storage::DynNodeStoragePtr node_storage) const; [[nodiscard]] std::optional chrono_div_impl(Literal const &other, storage::DynNodeStoragePtr node_storage) const; std::partial_ordering compare_impl(Literal const &other, std::strong_ordering *out_alternative_ordering = nullptr) const noexcept; [[nodiscard]] datatypes::registry::DatatypeIDView datatype_id() const noexcept; [[nodiscard]] bool is_fixed() const noexcept; [[nodiscard]] bool is_fixed_not_numeric() const noexcept; [[nodiscard]] bool is_fixed_not_timepoint() const noexcept; [[nodiscard]] bool is_fixed_not_duration() const noexcept; [[nodiscard]] bool is_string_like() const noexcept; [[nodiscard]] static Literal make_simple_unchecked(std::string_view lexical_form, bool needs_escape, storage::DynNodeStoragePtr node_storage); [[nodiscard]] static Literal make_noninlined_typed_unchecked(std::string_view lexical_form, bool needs_escape, IRI const &datatype, storage::DynNodeStoragePtr node_storage); [[nodiscard]] static Literal make_noninlined_special_unchecked(std::any &&value, storage::identifier::LiteralType fixed_id, storage::DynNodeStoragePtr node_storage); [[nodiscard]] static Literal make_inlined_typed_unchecked(storage::identifier::LiteralID inlined_value, storage::identifier::LiteralType fixed_id, storage::DynNodeStoragePtr node_storage) noexcept; [[nodiscard]] static Literal make_typed_unchecked(std::any &&value, datatypes::registry::DatatypeIDView datatype, datatypes::registry::DatatypeRegistry::DatatypeEntry const &entry, storage::DynNodeStoragePtr node_storage); [[nodiscard]] static Literal make_lang_tagged_unchecked(std::string_view lexical_form, bool needs_escape, std::string_view lang, storage::DynNodeStoragePtr node_storage); [[nodiscard]] static Literal make_lang_tagged_unchecked_from_node_id(std::string_view lang, storage::DynNodeStoragePtr node_storage, storage::identifier::NodeBackendID node_id) noexcept; // TODO needs escape flag [[nodiscard]] static Literal make_string_like_copy_lang_tag(std::string_view str, Literal const &lang_tag_src, storage::DynNodeStoragePtr node_storage); [[nodiscard]] Literal lang_tagged_get_de_inlined() const noexcept; [[nodiscard]] bool dynamic_datatype_eq_impl(std::string_view datatype) const noexcept; template bool serialize_impl(writer::BufWriterParts writer) const noexcept; template auto serialize_lexical_form_impl(C &&consume) const noexcept; [[nodiscard]] Literal cast_impl(datatypes::registry::DatatypeIDView target_dtid, storage::DynNodeStoragePtr node_storage) const; explicit Literal(storage::identifier::NodeBackendHandle handle) noexcept; public: Literal() noexcept; [[nodiscard]] static Literal make_null() noexcept; [[nodiscard]] static Literal make_simple(std::string_view lexical_form, storage::DynNodeStoragePtr node_storage = storage::default_node_storage); [[nodiscard]] static Literal make_simple_normalize(std::string_view lexical_form, storage::DynNodeStoragePtr node_storage = storage::default_node_storage); [[nodiscard]] static Literal make_lang_tagged(std::string_view lexical_form, std::string_view lang_tag, storage::DynNodeStoragePtr node_storage = storage::default_node_storage); [[nodiscard]] static Literal make_lang_tagged_normalize(std::string_view lexical_form, std::string_view lang_tag, storage::DynNodeStoragePtr node_storage = storage::default_node_storage); [[nodiscard]] static Literal make_typed(std::string_view lexical_form, IRI const &datatype, storage::DynNodeStoragePtr node_storage = storage::default_node_storage); template [[nodiscard]] static Literal make_typed(std::string_view lexical_form, storage::DynNodeStoragePtr node_storage = storage::default_node_storage) { if constexpr (std::is_same_v) { // see: https://www.w3.org/TR/rdf11-concepts/#section-Graph-Literal throw std::invalid_argument{"cannot construct rdf:langString without a language tag, please call one of the other factory functions"}; } else if constexpr (std::is_same_v) { return Literal::make_simple(lexical_form, node_storage); } auto value = T::from_string(lexical_form); if constexpr (datatypes::IsInlineable) { if (auto const maybe_inlined = T::try_into_inlined(value); maybe_inlined.has_value()) { return Literal::make_inlined_typed_unchecked(*maybe_inlined, T::fixed_id, node_storage); } } if constexpr (datatypes::HasFixedId) { if (node_storage.has_specialized_storage_for(T::fixed_id)) { return Literal::make_noninlined_special_unchecked(std::any{std::move(value)}, T::fixed_id, node_storage); } } auto const lex = writer::StringWriter::oneshot([&value](writer::StringWriter &w) noexcept { return T::serialize_canonical_string(value, w); }); auto const needs_escape = lexical_form_needs_escape(lex); return Literal::make_noninlined_typed_unchecked(lex, needs_escape, IRI{T::identifier, node_storage}, node_storage); } template [[nodiscard]] static Literal make_typed_from_value(typename T::cpp_type const &compatible_value, storage::DynNodeStoragePtr node_storage = storage::default_node_storage) { if constexpr (std::is_same_v) { return Literal::make_lang_tagged(compatible_value.lexical_form, compatible_value.language_tag, node_storage); } if constexpr (std::is_same_v) { return Literal::make_simple(compatible_value, node_storage); } if constexpr (datatypes::IsInlineable) { if (auto const maybe_inlined = T::try_into_inlined(compatible_value); maybe_inlined.has_value()) { return Literal::make_inlined_typed_unchecked(*maybe_inlined, T::fixed_id, node_storage); } } if constexpr (datatypes::HasFixedId) { if (node_storage.has_specialized_storage_for(T::fixed_id)) { return Literal{storage::identifier::NodeBackendHandle{node_storage.find_or_make_id(storage::view::ValueLiteralBackendView{ .datatype = T::fixed_id, .value = std::any{compatible_value}}), node_storage}}; } } auto const lex = writer::StringWriter::oneshot([&compatible_value](writer::StringWriter &w) noexcept { return T::serialize_canonical_string(compatible_value, w); }); auto const needs_escape = lexical_form_needs_escape(lex); return Literal::make_noninlined_typed_unchecked(lex, needs_escape, IRI{T::datatype_id, node_storage}, node_storage); } static Literal make_boolean(TriBool b, storage::DynNodeStoragePtr node_storage = storage::default_node_storage) noexcept; [[nodiscard]] static Literal make_string_uuid(storage::DynNodeStoragePtr node_storage = storage::default_node_storage); [[nodiscard]] static Literal generate_random_double(storage::DynNodeStoragePtr node_storage = storage::default_node_storage); template [[nodiscard]] static Literal generate_random_double(Rng &rng, storage::DynNodeStoragePtr node_storage = storage::default_node_storage) { // uniform_real_distribution does not have any state, therefore we can construct a new one for each call std::uniform_real_distribution dist{0.0, 1.0}; return Literal::make_typed_from_value(dist(rng), node_storage); } Literal to_node_storage(storage::DynNodeStoragePtr node_storage) const; [[nodiscard]] Literal try_get_in_node_storage(storage::DynNodeStoragePtr node_storage) const noexcept; private: [[nodiscard]] static storage::identifier::NodeBackendID find_datatype_iri(datatypes::registry::DatatypeIDView id, storage::DynNodeStoragePtr node_storage) noexcept; public: [[nodiscard]] static Literal find_simple(std::string_view lexical_form, storage::DynNodeStoragePtr node_storage = storage::default_node_storage) noexcept; [[nodiscard]] static Literal find_lang_tagged(std::string_view lexical_form, std::string_view lang_tag, storage::DynNodeStoragePtr node_storage = storage::default_node_storage) noexcept; template [[nodiscard]] static Literal find_typed_from_value(typename T::cpp_type const &compatible_value, storage::DynNodeStoragePtr node_storage = storage::default_node_storage) noexcept { if constexpr (std::is_same_v) { return find_lang_tagged(compatible_value.lexical_form, compatible_value.language_tag, node_storage); } if constexpr (std::is_same_v) { return find_simple(compatible_value, node_storage); } if constexpr (datatypes::IsInlineable) { if (auto const maybe_inlined = T::try_into_inlined(compatible_value); maybe_inlined.has_value()) { return Literal::make_inlined_typed_unchecked(*maybe_inlined, T::fixed_id, node_storage); } } if constexpr (datatypes::HasFixedId) { if (node_storage.has_specialized_storage_for(T::fixed_id)) { auto nid = node_storage.find_id(storage::view::ValueLiteralBackendView{ .datatype = T::fixed_id, .value = std::any{compatible_value}}); if (nid.null()) return Literal{}; return Literal{storage::identifier::NodeBackendHandle{nid, node_storage}}; } } auto dty = find_datatype_iri(T::datatype_id, node_storage); if (dty.null()) return Literal{}; auto const lex = writer::StringWriter::oneshot([&compatible_value](W &w) noexcept { return T::serialize_canonical_string(compatible_value, w); }); auto const needs_escape = lexical_form_needs_escape(lex); auto nid = node_storage.find_id(storage::view::LexicalFormLiteralBackendView{ .datatype_id = dty, .lexical_form = lex, .language_tag = "", .needs_escape = needs_escape}); if (nid.null()) return Literal{}; return Literal{storage::identifier::NodeBackendHandle{nid, node_storage}}; } template requires(!std::same_as) [[nodiscard]] static Literal find_typed(std::string_view lexical_form, storage::DynNodeStoragePtr node_storage = storage::default_node_storage) noexcept { if constexpr (std::is_same_v) { return find_simple(lexical_form, node_storage); } if constexpr (datatypes::HasFixedId) { auto value = T::from_string(lexical_form); if constexpr (datatypes::IsInlineable) { if (auto const maybe_inlined = T::try_into_inlined(value); maybe_inlined.has_value()) { return Literal::make_inlined_typed_unchecked(*maybe_inlined, T::fixed_id, node_storage); } } if (node_storage.has_specialized_storage_for(T::fixed_id)) { auto nid = node_storage.find_id(storage::view::ValueLiteralBackendView{ .datatype = T::fixed_id, .value = std::any{value}}); if (nid.null()) return Literal{}; return Literal{storage::identifier::NodeBackendHandle{nid, node_storage}}; } } auto dty = find_datatype_iri(T::datatype_id, node_storage); if (dty.null()) return Literal{}; auto const needs_escape = lexical_form_needs_escape(lexical_form); auto nid = node_storage.find_id(storage::view::LexicalFormLiteralBackendView{ .datatype_id = dty, .lexical_form = lexical_form, .language_tag = "", .needs_escape = needs_escape}); if (nid.null()) return Literal{}; return Literal{storage::identifier::NodeBackendHandle{nid, node_storage}}; } template [[nodiscard]] bool datatype_eq() const noexcept { if constexpr (datatypes::HasFixedId) { if (auto const type = this->handle_.node_id().literal_type(); type.is_fixed()) { return type == T::fixed_id; } return false; } return this->dynamic_datatype_eq_impl(T::identifier); } [[nodiscard]] bool datatype_eq(IRI const &datatype) const noexcept; [[nodiscard]] bool datatype_eq(Literal const &other) const noexcept; template [[nodiscard]] Literal as_datatype_eq(storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept { if (this->null()) { return Literal{}; } return Literal::make_boolean(this->datatype_eq(), select_node_storage(node_storage)); } [[nodiscard]] Literal as_datatype_eq(IRI const &datatype, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_datatype_eq(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal cast(IRI const &target, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; template [[nodiscard]] Literal cast(storage::DynNodeStoragePtr node_storage = keep_node_storage) const { return this->cast_impl(T::datatype_id, node_storage); } template requires (!std::same_as) std::optional cast_to_value() const noexcept { using namespace datatypes::registry; using namespace datatypes::xsd; if (this->null()) { return std::nullopt; } auto const this_dtid = this->datatype_id(); DatatypeIDView const target_dtid = T::datatype_id; if (this_dtid == target_dtid) { return this->value(); } if (this_dtid == String::datatype_id) { // string -> any try { return T::from_string(this->lexical_form()); } catch (...) { return std::nullopt; } } if constexpr (std::same_as) { // any -> bool TriBool const t = this->ebv(); if (t == TriBool::Err) return std::nullopt; else if (t == TriBool::True) return true; else return false; } auto const *target_e = DatatypeRegistry::get_entry(target_dtid); if (target_e == nullptr) { // target not registered return std::nullopt; } if (this_dtid == Boolean::datatype_id && target_e->numeric_ops.has_value()) { // bool -> numeric if (target_e->numeric_ops->is_impl()) { auto value = this->template value() ? target_e->numeric_ops->get_impl().one_value_fptr() : target_e->numeric_ops->get_impl().zero_value_fptr(); return std::any_cast(value); } else { auto const &impl_converter = DatatypeRegistry::get_numeric_op_impl_conversion(*target_e); auto const *target_num_impl = DatatypeRegistry::get_numerical_ops(impl_converter.target_type_id); RDF4CPP_ASSERT(target_num_impl != nullptr); // perform conversion as impl numeric type auto const value = this->template value() ? target_num_impl->get_impl().one_value_fptr() : target_num_impl->get_impl().zero_value_fptr(); // downcast to target auto target_value = impl_converter.inverted_convert(value); if (!target_value.has_value()) { // not representable as target type return std::nullopt; } return std::any_cast(*target_value); } } auto const *this_e = DatatypeRegistry::get_entry(this_dtid); if (this_e == nullptr) { // this datatype not registered return std::nullopt; } if (auto const common_conversion = DatatypeRegistry::get_common_type_conversion(this_e->conversion_table, target_e->conversion_table); common_conversion.has_value()) { // general cast // TODO: if performance is bad split into separate cases for up-, down- and cross-casting to avoid one set of std::any wrapping and unwrapping for the former 2 auto const common_type_value = common_conversion->convert_lhs(this->value()); // upcast to common auto target_value = common_conversion->inverted_convert_rhs(common_type_value); // downcast to target if (!target_value.has_value()) { // downcast failed return std::nullopt; } return std::any_cast(*target_value); } // no conversion found return std::nullopt; } [[nodiscard]] CowString lexical_form() const noexcept; [[nodiscard]] FetchOrSerializeResult fetch_or_serialize_lexical_form(std::string_view &out_lex_form, writer::BufWriterParts writer) const noexcept; [[nodiscard]] Literal as_lexical_form(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] CowString simplified_lexical_form() const noexcept; [[nodiscard]] FetchOrSerializeResult fetch_or_serialize_simplified_lexical_form(std::string_view &out_lex_form, writer::BufWriterParts writer) const noexcept; [[nodiscard]] Literal as_simplified_lexical_form(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] IRI datatype() const noexcept; [[nodiscard]] std::string_view language_tag() const noexcept; [[nodiscard]] Literal as_language_tag(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] TriBool language_tag_eq(std::string_view lang_tag) const noexcept; [[nodiscard]] TriBool language_tag_eq(Literal const &other) const noexcept; [[nodiscard]] Literal as_language_tag_eq(std::string_view lang_tag, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_language_tag_eq(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; bool serialize(writer::BufWriterParts writer, NodeSerializationOpts opts = NodeSerializationOpts::long_form()) const noexcept; bool serialize_lexical_form(writer::BufWriterParts writer) const noexcept; bool serialize_simplified_lexical_form(writer::BufWriterParts writer) const noexcept; [[nodiscard]] explicit operator std::string() const noexcept; friend std::ostream &operator<<(std::ostream &os, const Literal &literal); [[nodiscard]] std::any value() const noexcept; template typename T::cpp_type value() const { if (!this->datatype_eq()) [[unlikely]] { throw std::runtime_error{"Literal::value error: incompatible type"}; } if constexpr (std::is_same_v) { auto const view = this->handle_.literal_backend(); auto const &lit = view.get_lexical(); return lit.lexical_form; } if constexpr (std::is_same_v) { auto const handle = this->is_inlined() ? this->lang_tagged_get_de_inlined().backend_handle() : this->backend_handle(); auto const view = handle.literal_backend(); auto const &lit = view.get_lexical(); return datatypes::registry::LangStringRepr{.lexical_form = lit.lexical_form, .language_tag = lit.language_tag}; } if constexpr (datatypes::IsInlineable) { if (this->is_inlined()) { auto const inlined_value = this->handle_.node_id().literal_id(); return T::from_inlined(inlined_value); } } auto const backend = handle_.literal_backend(); return backend.visit( [](storage::view::LexicalFormLiteralBackendView const &lexical) noexcept { return T::from_string(lexical.lexical_form); }, [](storage::view::ValueLiteralBackendView const &any) noexcept { RDF4CPP_ASSERT(any.datatype == T::datatype_id); return std::any_cast(any.value); }); } bool is_literal() const noexcept = delete; bool is_variable() const noexcept = delete; bool is_blank_node() const noexcept = delete; bool is_iri() const noexcept = delete; [[nodiscard]] bool is_numeric() const noexcept; [[nodiscard]] bool is_timepoint() const noexcept; [[nodiscard]] bool is_duration() const noexcept; [[nodiscard]] std::partial_ordering compare(Literal const &other) const noexcept; [[nodiscard]] std::strong_ordering order(Literal const &other) const noexcept; [[nodiscard]] TriBool eq(Literal const &other) const noexcept; [[nodiscard]] bool order_eq(Literal const &other) const noexcept; [[nodiscard]] TriBool ne(Literal const &other) const noexcept; [[nodiscard]] bool order_ne(Literal const &other) const noexcept; [[nodiscard]] TriBool lt(Literal const &other) const noexcept; [[nodiscard]] bool order_lt(Literal const &other) const noexcept; [[nodiscard]] TriBool le(Literal const &other) const noexcept; [[nodiscard]] bool order_le(Literal const &other) const noexcept; [[nodiscard]] TriBool gt(Literal const &other) const noexcept; [[nodiscard]] bool order_gt(Literal const &other) const noexcept; [[nodiscard]] TriBool ge(Literal const &other) const noexcept; [[nodiscard]] bool order_ge(Literal const &other) const noexcept; [[nodiscard]] Literal as_eq(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_order_eq(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_ne(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_order_ne(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_lt(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_order_lt(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_le(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_order_le(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_gt(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_order_gt(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_ge(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_order_ge(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; std::partial_ordering operator<=>(Literal const &other) const noexcept; bool operator==(Literal const &other) const noexcept; [[nodiscard]] Literal add(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; Literal operator+(Literal const &other) const; Literal &add_assign(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage); Literal &operator+=(Literal const &other); [[nodiscard]] Literal sub(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; Literal operator-(Literal const &other) const; Literal &sub_assign(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage); Literal &operator-=(Literal const &other); [[nodiscard]] Literal mul(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; Literal operator*(Literal const &other) const; Literal &mul_assign(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage); Literal &operator*=(Literal const &other); [[nodiscard]] Literal div(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; Literal operator/(Literal const &other) const; Literal &div_assign(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage); Literal &operator/=(Literal const &other); [[nodiscard]] Literal pos(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; Literal operator+() const; [[nodiscard]] Literal neg(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; Literal operator-() const; [[nodiscard]] Literal abs(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal round(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal floor(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal ceil(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] std::optional strlen() const noexcept; [[nodiscard]] Literal as_strlen(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] TriBool language_tag_matches_range(std::string_view lang_range) const noexcept; [[nodiscard]] Literal as_language_tag_matches_range(std::string_view lang_range, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_language_tag_matches_range(Literal const &lang_range, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] TriBool regex_matches(regex::Regex const &pattern) const noexcept; [[nodiscard]] Literal as_regex_matches(regex::Regex const &pattern, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_regex_matches(Literal const &pattern, Literal const &flags = Literal::make_simple(""), storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] regex::Regex make_regex(Literal const &flags = Literal::make_simple("")) const; [[nodiscard]] Literal regex_replace(regex::RegexReplacer const &replacer, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal regex_replace(Literal const &pattern, Literal const &replacement, Literal const &flags = Literal::make_simple(""), storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] TriBool contains(std::string_view needle) const noexcept; [[nodiscard]] Literal as_contains(std::string_view needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_contains(Literal const &needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal substr_before(std::string_view needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal substr_before(Literal const &needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal substr_after(std::string_view needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal substr_after(Literal const &needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] TriBool str_starts_with(std::string_view needle) const noexcept; [[nodiscard]] Literal as_str_starts_with(std::string_view needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_str_starts_with(Literal const &needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] TriBool str_ends_with(std::string_view needle) const noexcept; [[nodiscard]] Literal as_str_ends_with(std::string_view needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal as_str_ends_with(Literal const &needle, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal uppercase(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal lowercase(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal concat(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] static Literal encode_for_uri(std::string_view string, storage::DynNodeStoragePtr node_storage = storage::default_node_storage); [[nodiscard]] Literal encode_for_uri(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal substr(size_t start, size_t len = std::string_view::npos, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal substr(Literal const &start, Literal const &len = Literal::make_typed_from_value(std::numeric_limits::infinity()), storage::DynNodeStoragePtr node_storage = keep_node_storage) const; private: [[nodiscard]] Literal hash_with(const char *alg, storage::DynNodeStoragePtr node_storage) const; public: [[nodiscard]] Literal md5(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal sha1(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal sha256(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal sha384(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal sha512(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] static Literal now(storage::DynNodeStoragePtr node_storage = storage::default_node_storage); [[nodiscard]] std::optional year() const noexcept; [[nodiscard]] Literal as_year(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] std::optional month() const noexcept; [[nodiscard]] Literal as_month(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] std::optional day() const noexcept; [[nodiscard]] Literal as_day(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] std::optional hours() const noexcept; [[nodiscard]] Literal as_hours(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] std::optional minutes() const noexcept; [[nodiscard]] Literal as_minutes(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] std::optional seconds() const noexcept; [[nodiscard]] Literal as_seconds(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] std::optional timezone() const noexcept; [[nodiscard]] Literal as_timezone(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] std::optional tz() const noexcept; [[nodiscard]] Literal as_tz(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] TriBool ebv() const noexcept; [[nodiscard]] Literal as_ebv(storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; [[nodiscard]] Literal logical_and(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; Literal operator&&(Literal const &other) const noexcept; [[nodiscard]] Literal logical_or(Literal const &other, storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; Literal operator||(Literal const &other) const noexcept; [[nodiscard]] Literal logical_not(storage::DynNodeStoragePtr node_storage = keep_node_storage) const noexcept; Literal operator!() const noexcept; friend struct Node; friend Literal lang_matches(Literal const &lang_tag, Literal const &lang_range, storage::DynNodeStoragePtr node_storage) noexcept; [[nodiscard]] static Literal math_pi(storage::DynNodeStoragePtr node_storage = storage::default_node_storage); [[nodiscard]] Literal math_exp(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_exp10(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_log(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_log10(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_pow(Literal exp, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_sqrt(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_sin(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_cos(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_tan(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_asin(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_acos(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_atan(storage::DynNodeStoragePtr node_storage = keep_node_storage) const; [[nodiscard]] Literal math_atan2(Literal y, storage::DynNodeStoragePtr node_storage = keep_node_storage) const; }; [[nodiscard]] std::string normalize_unicode(std::string_view utf8); [[nodiscard]] bool lang_matches(std::string_view lang_tag, std::string_view lang_range) noexcept; [[nodiscard]] Literal lang_matches(Literal const &lang_tag, Literal const &lang_range, storage::DynNodeStoragePtr node_storage = keep_node_storage) noexcept; inline namespace shorthands { Literal operator""_xsd_string(char const *str, size_t len); Literal operator""_xsd_double(long double d); Literal operator""_xsd_float(long double d) noexcept; Literal operator""_xsd_decimal(char const *str, size_t len); Literal operator""_xsd_integer(unsigned long long int i); Literal operator""_xsd_byte(unsigned long long int i) noexcept; Literal operator""_xsd_ubyte(unsigned long long int i) noexcept; Literal operator""_xsd_short(unsigned long long int i) noexcept; Literal operator""_xsd_ushort(unsigned long long int i) noexcept; Literal operator""_xsd_int(unsigned long long int i) noexcept; Literal operator""_xsd_uint(unsigned long long int i) noexcept; Literal operator""_xsd_long(unsigned long long int i); Literal operator""_xsd_ulong(unsigned long long int i); } // namespace shorthands struct LiteralOrderByLess { bool operator()(Literal lhs, Literal rhs) const noexcept { return lhs.order_lt(rhs); } }; struct LiteralOrderByGreater { bool operator()(Literal lhs, Literal rhs) const noexcept { return lhs.order_gt(rhs); } }; } // namespace rdf4cpp template<> struct std::hash { inline size_t operator()(rdf4cpp::Literal const &v) const noexcept { return std::hash()(v); } }; template<> struct std::formatter : std::formatter { auto format(rdf4cpp::Literal n, format_context &ctx) const -> decltype(ctx.out()); }; #endif //RDF4CPP_LITERAL_HPP