aboutsummaryrefslogtreecommitdiffstats
path: root/doc/cpp/overview.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-06-16 10:26:47 -0400
committerDavid Robillard <d@drobilla.net>2022-01-28 21:57:29 -0500
commit8b1ad067d9450b4c9c4384b6bf2859c70a6b0cce (patch)
tree2a5cc8b0031658a472c44b8fd8e95cb583d24fc7 /doc/cpp/overview.cpp
parent3f74afa8c0e60a778566db975894044c67a3b386 (diff)
downloadserd-8b1ad067d9450b4c9c4384b6bf2859c70a6b0cce.tar.gz
serd-8b1ad067d9450b4c9c4384b6bf2859c70a6b0cce.tar.bz2
serd-8b1ad067d9450b4c9c4384b6bf2859c70a6b0cce.zip
[WIP] Add C++ bindings
Diffstat (limited to 'doc/cpp/overview.cpp')
-rw-r--r--doc/cpp/overview.cpp370
1 files changed, 370 insertions, 0 deletions
diff --git a/doc/cpp/overview.cpp b/doc/cpp/overview.cpp
new file mode 100644
index 00000000..63c4f690
--- /dev/null
+++ b/doc/cpp/overview.cpp
@@ -0,0 +1,370 @@
+/*
+ Copyright 2021 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/*
+ Example code that is included in the documentation. Code in the
+ documentation is included from here rather than written inline so that it can
+ be tested and avoid rotting. The code here doesn't make much sense, but is
+ written such that it at least compiles and will run without crashing.
+*/
+
+#include "serd/serd.hpp"
+
+#include <cassert>
+#include <cstddef>
+#include <iostream>
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunused-variable"
+#elif defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
+using namespace serd; // NOLINT(google-build-using-namespace)
+
+static void
+statements()
+{
+ // begin statement-new
+ Statement triple{make_uri("http://example.org/drobilla"), // Subject
+ make_uri("http://example.org/firstName"), // Predicate
+ make_string("David")}; // Object
+ // end statement-new
+
+ // begin statement-new-graph
+ Statement quad{make_uri("http://example.org/drobilla"), // Subject
+ make_uri("http://example.org/firstName"), // Predicate
+ make_string("David"), // Object
+ make_uri("http://example.org/userData")}; // Graph
+ // end statement-new-graph
+
+ // begin statement-new-cursor
+ Node file{make_uri("file:///tmp/userdata.ttl")};
+ Statement triple2{make_uri("http://example.org/drobilla"), // Subject
+ make_uri("http://example.org/firstName"), // Predicate
+ make_string("David"), // Object
+ Caret{file, 4, 27}}; // Caret
+ // end statement-new-cursor
+
+ // begin statement-new-graph-cursor
+ Statement quad2{make_uri("http://example.org/drobilla"), // Subject
+ make_uri("http://example.org/firstName"), // Predicate
+ make_string("David"), // Object
+ make_uri("http://example.org/userData"), // Graph
+ Caret{file, 4, 27}}; // Caret
+ // end statement-new-graph-cursor
+}
+
+static void
+statements_accessing_fields()
+{
+ Node ss{make_uri("http://example.org/s")};
+ Node sp{make_uri("http://example.org/p")};
+ Node so{make_uri("http://example.org/o")};
+
+ Statement statement{ss, sp, so};
+
+ // begin get-subject
+ NodeView s = statement.node(Field::subject);
+ // end get-subject
+
+ // begin get-pog
+ NodeView p = statement.predicate();
+ NodeView o = statement.object();
+ Optional<NodeView> g = statement.graph();
+ // end get-pog
+
+ // begin get-caret
+ Optional<CaretView> c = statement.caret();
+ // end get-caret
+}
+
+static void
+statements_comparison()
+{
+ Node ss{make_uri("http://example.org/s")};
+ Node sp{make_uri("http://example.org/p")};
+ Node so{make_uri("http://example.org/o")};
+
+ Statement statement1{ss, sp, so};
+ Statement statement2{ss, sp, so};
+
+ // begin statement-equals
+ if (statement1 == statement2) {
+ std::cout << "Match" << std::endl;
+ }
+ // end statement-equals
+
+ const Statement& statement = statement1;
+
+ // begin statement-matches
+ if (statement.matches({}, make_uri("http://example.org/name"), {})) {
+ std::cout << statement.subject() << " has name " << statement.object()
+ << std::endl;
+ }
+ // end statement-matches
+}
+
+static void
+world()
+{
+ // begin world-new
+ World world;
+ // end world-new
+
+ // begin get-blank
+ Node blank = world.get_blank();
+ // end get-blank
+}
+
+static void
+model()
+{
+ World world;
+
+ // begin model-new
+ Model model{world, StatementOrder::SPO, {}};
+ // end model-new
+
+ // begin fancy-model-new
+ Model fancy_model{world, StatementOrder::SPO, ModelFlag::store_carets};
+ fancy_model.add_index(StatementOrder::PSO);
+ // end fancy-model-new
+
+ // begin model-copy
+ Model copy{model};
+ assert(copy == model);
+
+ copy = fancy_model;
+ assert(copy == fancy_model);
+ // end model-copy
+
+ // begin model-size
+ if (model.empty()) {
+ std::cout << "Model is empty" << std::endl;
+ } else if (model.size() > 9000) {
+ std::cout << "Model has over 9000 statements" << std::endl;
+ }
+ // end model-size
+
+ // begin model-add
+ Node s{make_uri("http://example.org/thing")};
+ Node p{make_uri("http://example.org/name")};
+ Node o{make_string("Thing")};
+
+ model.insert(s, p, o);
+ // end model-add
+
+ Model other_model{model};
+
+ // begin model-insert
+ model.insert(*other_model.begin());
+ // end model-insert
+
+ // begin model-add-range
+ model.insert_statements(other_model.begin());
+ // end model-add-range
+
+ // begin model-begin-end
+ Cursor i = model.begin();
+ if (i == model.end()) {
+ std::cout << "Model is empty" << std::endl;
+ } else {
+ std::cout << "First statement subject: " << i->subject() << std::endl;
+ }
+ // end model-begin-end
+
+ // begin iter-next
+ if (++i != model.end()) {
+ std::cout << "Second statement subject: " << i->subject() << std::endl;
+ }
+ // end iter-next
+
+ // begin model-iteration
+ for (const StatementView& statement : model) {
+ std::cout << "Model statement subject: " << statement.subject()
+ << std::endl;
+ }
+ // end model-iteration
+
+ // begin model-all
+ Cursor all = model.begin();
+ // end model-all
+
+ // begin model-ordered
+ Cursor ordered = model.begin_ordered(StatementOrder::OPS);
+ // end model-ordered
+
+ // begin range-iteration
+ // FIXME
+ // for (const StatementView& statement : all) {
+ // std::cout << "Cursor statement subject: " << statement.subject()
+ // << std::endl;
+ // }
+ // end range-iteration
+
+ // begin model-ask
+ Node rdf_type = make_uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
+
+ if (model.ask({}, rdf_type, {}, {})) {
+ std::cout << "Model contains a type statement" << std::endl;
+ }
+ // end model-ask
+
+ // Add a statement so that the searching examples below work
+ Node inst{make_uri("http://example.org/i")};
+ Node type{make_uri("http://example.org/T")};
+ model.insert(inst, rdf_type, type);
+
+ // begin model-find
+ Model::Range it = model.find({}, rdf_type, {});
+
+ NodeView instance = it.begin()->subject();
+ // end model-find
+
+ // begin model-count
+ size_t n = model.count(instance, rdf_type, {});
+ std::cout << "Instance has " << n << " types" << std::endl;
+ // end model-count
+
+ // begin model-range
+ for (const StatementView& statement : model.find(instance, rdf_type, {})) {
+ std::cout << "Instance has type " << statement.object() << std::endl;
+ }
+ // end model-range
+
+ // begin model-get
+ Optional<NodeView> t = model.get(instance, rdf_type, {});
+ if (t) {
+ std::cout << "Instance has type " << *t << std::endl;
+ }
+ // end model-get
+
+ // begin model-get-statement
+ Optional<StatementView> ts = model.get_statement(instance, rdf_type, {});
+ if (ts) {
+ std::cout << "Instance " << ts->subject() << " has type " << ts->object()
+ << std::endl;
+ }
+ // end model-get-statement
+
+ // begin model-erase
+ Model::Range itype = model.find({}, rdf_type, {});
+ model.erase(itype.begin());
+ // end model-erase
+
+ // begin model-erase-range
+ // FIXME
+ // Model::Range all_types = model.find({}, rdf_type, {});
+ // model.erase_statements(all_types);
+ // end model-erase-range
+}
+
+static void
+reading_writing()
+{
+ World world;
+
+ // begin env-new
+ Node base = make_file_uri("/some/file.ttl");
+
+ Env env{world, base};
+ // end env-new
+
+ // begin env-set-prefix
+ env.set_prefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
+ // end env-set-prefix
+
+ // begin byte-sink-new
+ OutputStream out = serd::open_output_file("/tmp/eg.ttl");
+ // end byte-sink-new
+
+ // begin writer-new
+ Writer writer{world, serd::Syntax::Turtle, {}, env, out};
+ // end writer-new
+
+ // begin reader-new
+ Reader reader{world, Syntax::Turtle, {}, env, writer.sink(), 4096};
+ // end reader-new
+
+ // begin read-document
+ Status st = reader.read_document();
+ if (st != Status::success) {
+ std::cout << "Error reading document: " << strerror(st) << std::endl;
+ }
+ // end read-document
+
+ // begin byte-sink-close
+ // out.close();
+ // end byte-sink-close
+
+ // begin inserter-new
+ Model model{world, StatementOrder::SPO, {}};
+ SinkWrapper<SerdSink> inserter = make_inserter(model);
+ // end inserter-new
+
+ // begin model-reader-new
+ Reader model_reader{world, Syntax::Turtle, {}, env, inserter, 4096};
+
+ st = model_reader.read_document();
+ if (st != Status::success) {
+ std::cout << "Error loading model: " << strerror(st) << std::endl;
+ }
+ // end model-reader-new
+
+ // begin write-range
+ // FIXME
+ // model.all().write(writer.sink(), {});
+ // end write-range
+
+ // begin canon-new
+ SinkWrapper<SerdSink> canon = make_canon(world, inserter, {});
+ // end canon-new
+
+ Node rdf_type = make_uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
+
+ // begin filter-new
+ SinkWrapper<SerdSink> filter = make_filter(world,
+ inserter, // Target
+ {}, // Subject
+ rdf_type, // Predicate
+ {}, // Object
+ {}, // Graph
+ true); // Inclusive
+ // end filter-new
+}
+
+int
+main()
+{
+ statements();
+ statements_accessing_fields();
+ statements_comparison();
+ world();
+ model();
+ reading_writing();
+
+ return 0;
+}
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#elif defined(__GNUC__)
+# pragma GCC diagnostic pop
+#endif