From beed9c20da5fbacf8626e2d4b747bb84ae7f6d93 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Sat, 7 Nov 2026 17:49:12 +0100 Subject: Moved docs around --- docs/.nix/derivation.nix | 42 ---- docs/Doxygen.in | 8 - docs/Makefile | 20 -- docs/data/core/array_buffer.json | 31 +++ docs/data/core/branch.json | 103 +++++++++ docs/data/core/buffer.json | 182 +++++++++++++++ docs/data/core/buffer_view.json | 74 ++++++ docs/data/core/chain_array_buffer.json | 50 ++++ docs/data/core/err/already_exists.json | 35 +++ docs/data/core/err/buffer_exhausted.json | 35 +++ docs/data/core/err/critical.json | 37 +++ docs/data/core/err/invalid_state.json | 35 +++ docs/data/core/err/no_error.json | 38 +++ docs/data/core/err/not_found.json | 38 +++ docs/data/core/err/not_implemented.json | 40 ++++ docs/data/core/err/not_supported.json | 40 ++++ docs/data/core/err/out_of_memory.json | 38 +++ docs/data/core/err/recoverable.json | 35 +++ docs/data/core/error.json | 168 ++++++++++++++ docs/data/core/error_builder.json | 65 ++++++ docs/data/core/error_or.json | 110 +++++++++ docs/data/core/error_or.nested.json | 24 ++ docs/data/core/error_or_value.json | 26 +++ docs/data/core/heap.json | 23 ++ docs/data/core/id.json | 67 ++++++ docs/data/core/lent.json | 21 ++ docs/data/core/maybe.json | 21 ++ docs/data/core/our.json | 24 ++ docs/data/core/own.json | 30 +++ docs/data/core/parameter_key_pack_index.json | 35 +++ docs/data/core/parameter_key_pack_type.json | 32 +++ docs/data/core/parameter_pack_index.json | 32 +++ docs/data/core/parameter_pack_type.json | 27 +++ docs/data/core/parameter_pack_value.json | 33 +++ docs/data/core/ptr.json | 64 +++++ docs/data/core/ref.json | 47 ++++ docs/data/core/ring_buffer.json | 55 +++++ docs/data/core/share.json | 25 ++ docs/data/core/string_literal.json | 74 ++++++ docs/data/core/tmpl_concat.json | 34 +++ docs/data/core/tmpl_group.json | 39 ++++ docs/data/core/tmpl_reduce.json | 31 +++ docs/data/core/tmpl_value_group.json | 41 ++++ docs/data/core/tree.json | 75 ++++++ docs/data/core/tree_container.json | 78 +++++++ docs/data/core/void_t.json | 20 ++ docs/data/remote/data_client.json | 31 +++ docs/data/remote/data_client.loopback.json | 112 +++++++++ docs/data/remote/data_or_id.json | 78 +++++++ docs/data/remote/data_server.json | 44 ++++ docs/data/remote/data_server.loopback.json | 165 +++++++++++++ docs/data/remote/i_data_server.json | 53 +++++ docs/data/remote/i_rpc_server.json | 53 +++++ docs/data/remote/loopback.json | 15 ++ docs/data/remote/remote.json | 36 +++ docs/data/remote/remote.loopback.json | 182 +++++++++++++++ docs/data/remote/remote_address.json | 34 +++ docs/data/remote/remote_address.loopback.json | 43 ++++ docs/data/remote/remote_data.json | 30 +++ docs/data/remote/remote_data.loopback.json | 70 ++++++ docs/data/remote/rpc_client.json | 30 +++ docs/data/remote/rpc_client.loopback.json | 136 +++++++++++ docs/data/remote/rpc_function_id.json | 40 ++++ docs/data/remote/rpc_server.json | 66 ++++++ docs/data/remote/rpc_server.loopback.json | 180 +++++++++++++++ docs/entity.schema.json | 269 ++++++++++++++++++++++ docs/source/_static/css/custom.css | 15 -- docs/source/async/introduction.rst | 6 - docs/source/codec/introduction.rst | 12 - docs/source/conf.py | 30 --- docs/source/core/introduction.rst | 5 - docs/source/index.rst | 36 --- docs/source/manual/introduction.rst | 14 -- docs_old/.nix/derivation.nix | 42 ++++ docs_old/Doxygen.in | 8 + docs_old/Makefile | 20 ++ docs_old/source/_static/css/custom.css | 15 ++ docs_old/source/async/introduction.rst | 6 + docs_old/source/codec/introduction.rst | 12 + docs_old/source/conf.py | 30 +++ docs_old/source/core/introduction.rst | 5 + docs_old/source/index.rst | 36 +++ docs_old/source/manual/introduction.rst | 14 ++ docs_oos/data/core/array_buffer.json | 31 --- docs_oos/data/core/branch.json | 103 --------- docs_oos/data/core/buffer.json | 182 --------------- docs_oos/data/core/buffer_view.json | 74 ------ docs_oos/data/core/chain_array_buffer.json | 50 ---- docs_oos/data/core/err/already_exists.json | 35 --- docs_oos/data/core/err/buffer_exhausted.json | 35 --- docs_oos/data/core/err/critical.json | 37 --- docs_oos/data/core/err/invalid_state.json | 35 --- docs_oos/data/core/err/no_error.json | 38 --- docs_oos/data/core/err/not_found.json | 38 --- docs_oos/data/core/err/not_implemented.json | 40 ---- docs_oos/data/core/err/not_supported.json | 40 ---- docs_oos/data/core/err/out_of_memory.json | 38 --- docs_oos/data/core/err/recoverable.json | 35 --- docs_oos/data/core/error.json | 168 -------------- docs_oos/data/core/error_builder.json | 65 ------ docs_oos/data/core/error_or.json | 110 --------- docs_oos/data/core/error_or.nested.json | 24 -- docs_oos/data/core/error_or_value.json | 26 --- docs_oos/data/core/heap.json | 23 -- docs_oos/data/core/id.json | 67 ------ docs_oos/data/core/lent.json | 21 -- docs_oos/data/core/maybe.json | 21 -- docs_oos/data/core/our.json | 24 -- docs_oos/data/core/own.json | 30 --- docs_oos/data/core/parameter_key_pack_index.json | 35 --- docs_oos/data/core/parameter_key_pack_type.json | 32 --- docs_oos/data/core/parameter_pack_index.json | 32 --- docs_oos/data/core/parameter_pack_type.json | 27 --- docs_oos/data/core/parameter_pack_value.json | 33 --- docs_oos/data/core/ptr.json | 64 ----- docs_oos/data/core/ref.json | 47 ---- docs_oos/data/core/ring_buffer.json | 55 ----- docs_oos/data/core/share.json | 25 -- docs_oos/data/core/string_literal.json | 74 ------ docs_oos/data/core/tmpl_concat.json | 34 --- docs_oos/data/core/tmpl_group.json | 39 ---- docs_oos/data/core/tmpl_reduce.json | 31 --- docs_oos/data/core/tmpl_value_group.json | 41 ---- docs_oos/data/core/tree.json | 75 ------ docs_oos/data/core/tree_container.json | 78 ------- docs_oos/data/core/void_t.json | 20 -- docs_oos/data/remote/data_client.json | 31 --- docs_oos/data/remote/data_client.loopback.json | 112 --------- docs_oos/data/remote/data_or_id.json | 78 ------- docs_oos/data/remote/data_server.json | 44 ---- docs_oos/data/remote/data_server.loopback.json | 165 ------------- docs_oos/data/remote/i_data_server.json | 53 ----- docs_oos/data/remote/i_rpc_server.json | 53 ----- docs_oos/data/remote/loopback.json | 15 -- docs_oos/data/remote/remote.json | 36 --- docs_oos/data/remote/remote.loopback.json | 182 --------------- docs_oos/data/remote/remote_address.json | 34 --- docs_oos/data/remote/remote_address.loopback.json | 43 ---- docs_oos/data/remote/remote_data.json | 30 --- docs_oos/data/remote/remote_data.loopback.json | 70 ------ docs_oos/data/remote/rpc_client.json | 30 --- docs_oos/data/remote/rpc_client.loopback.json | 136 ----------- docs_oos/data/remote/rpc_function_id.json | 40 ---- docs_oos/data/remote/rpc_server.json | 66 ------ docs_oos/data/remote/rpc_server.loopback.json | 180 --------------- docs_oos/entity.schema.json | 269 ---------------------- 146 files changed, 3987 insertions(+), 3987 deletions(-) delete mode 100644 docs/.nix/derivation.nix delete mode 100644 docs/Doxygen.in delete mode 100644 docs/Makefile create mode 100644 docs/data/core/array_buffer.json create mode 100644 docs/data/core/branch.json create mode 100644 docs/data/core/buffer.json create mode 100644 docs/data/core/buffer_view.json create mode 100644 docs/data/core/chain_array_buffer.json create mode 100644 docs/data/core/err/already_exists.json create mode 100644 docs/data/core/err/buffer_exhausted.json create mode 100644 docs/data/core/err/critical.json create mode 100644 docs/data/core/err/invalid_state.json create mode 100644 docs/data/core/err/no_error.json create mode 100644 docs/data/core/err/not_found.json create mode 100644 docs/data/core/err/not_implemented.json create mode 100644 docs/data/core/err/not_supported.json create mode 100644 docs/data/core/err/out_of_memory.json create mode 100644 docs/data/core/err/recoverable.json create mode 100644 docs/data/core/error.json create mode 100644 docs/data/core/error_builder.json create mode 100644 docs/data/core/error_or.json create mode 100644 docs/data/core/error_or.nested.json create mode 100644 docs/data/core/error_or_value.json create mode 100644 docs/data/core/heap.json create mode 100644 docs/data/core/id.json create mode 100644 docs/data/core/lent.json create mode 100644 docs/data/core/maybe.json create mode 100644 docs/data/core/our.json create mode 100644 docs/data/core/own.json create mode 100644 docs/data/core/parameter_key_pack_index.json create mode 100644 docs/data/core/parameter_key_pack_type.json create mode 100644 docs/data/core/parameter_pack_index.json create mode 100644 docs/data/core/parameter_pack_type.json create mode 100644 docs/data/core/parameter_pack_value.json create mode 100644 docs/data/core/ptr.json create mode 100644 docs/data/core/ref.json create mode 100644 docs/data/core/ring_buffer.json create mode 100644 docs/data/core/share.json create mode 100644 docs/data/core/string_literal.json create mode 100644 docs/data/core/tmpl_concat.json create mode 100644 docs/data/core/tmpl_group.json create mode 100644 docs/data/core/tmpl_reduce.json create mode 100644 docs/data/core/tmpl_value_group.json create mode 100644 docs/data/core/tree.json create mode 100644 docs/data/core/tree_container.json create mode 100644 docs/data/core/void_t.json create mode 100644 docs/data/remote/data_client.json create mode 100644 docs/data/remote/data_client.loopback.json create mode 100644 docs/data/remote/data_or_id.json create mode 100644 docs/data/remote/data_server.json create mode 100644 docs/data/remote/data_server.loopback.json create mode 100644 docs/data/remote/i_data_server.json create mode 100644 docs/data/remote/i_rpc_server.json create mode 100644 docs/data/remote/loopback.json create mode 100644 docs/data/remote/remote.json create mode 100644 docs/data/remote/remote.loopback.json create mode 100644 docs/data/remote/remote_address.json create mode 100644 docs/data/remote/remote_address.loopback.json create mode 100644 docs/data/remote/remote_data.json create mode 100644 docs/data/remote/remote_data.loopback.json create mode 100644 docs/data/remote/rpc_client.json create mode 100644 docs/data/remote/rpc_client.loopback.json create mode 100644 docs/data/remote/rpc_function_id.json create mode 100644 docs/data/remote/rpc_server.json create mode 100644 docs/data/remote/rpc_server.loopback.json create mode 100644 docs/entity.schema.json delete mode 100644 docs/source/_static/css/custom.css delete mode 100644 docs/source/async/introduction.rst delete mode 100644 docs/source/codec/introduction.rst delete mode 100644 docs/source/conf.py delete mode 100644 docs/source/core/introduction.rst delete mode 100644 docs/source/index.rst delete mode 100644 docs/source/manual/introduction.rst create mode 100644 docs_old/.nix/derivation.nix create mode 100644 docs_old/Doxygen.in create mode 100644 docs_old/Makefile create mode 100644 docs_old/source/_static/css/custom.css create mode 100644 docs_old/source/async/introduction.rst create mode 100644 docs_old/source/codec/introduction.rst create mode 100644 docs_old/source/conf.py create mode 100644 docs_old/source/core/introduction.rst create mode 100644 docs_old/source/index.rst create mode 100644 docs_old/source/manual/introduction.rst delete mode 100644 docs_oos/data/core/array_buffer.json delete mode 100644 docs_oos/data/core/branch.json delete mode 100644 docs_oos/data/core/buffer.json delete mode 100644 docs_oos/data/core/buffer_view.json delete mode 100644 docs_oos/data/core/chain_array_buffer.json delete mode 100644 docs_oos/data/core/err/already_exists.json delete mode 100644 docs_oos/data/core/err/buffer_exhausted.json delete mode 100644 docs_oos/data/core/err/critical.json delete mode 100644 docs_oos/data/core/err/invalid_state.json delete mode 100644 docs_oos/data/core/err/no_error.json delete mode 100644 docs_oos/data/core/err/not_found.json delete mode 100644 docs_oos/data/core/err/not_implemented.json delete mode 100644 docs_oos/data/core/err/not_supported.json delete mode 100644 docs_oos/data/core/err/out_of_memory.json delete mode 100644 docs_oos/data/core/err/recoverable.json delete mode 100644 docs_oos/data/core/error.json delete mode 100644 docs_oos/data/core/error_builder.json delete mode 100644 docs_oos/data/core/error_or.json delete mode 100644 docs_oos/data/core/error_or.nested.json delete mode 100644 docs_oos/data/core/error_or_value.json delete mode 100644 docs_oos/data/core/heap.json delete mode 100644 docs_oos/data/core/id.json delete mode 100644 docs_oos/data/core/lent.json delete mode 100644 docs_oos/data/core/maybe.json delete mode 100644 docs_oos/data/core/our.json delete mode 100644 docs_oos/data/core/own.json delete mode 100644 docs_oos/data/core/parameter_key_pack_index.json delete mode 100644 docs_oos/data/core/parameter_key_pack_type.json delete mode 100644 docs_oos/data/core/parameter_pack_index.json delete mode 100644 docs_oos/data/core/parameter_pack_type.json delete mode 100644 docs_oos/data/core/parameter_pack_value.json delete mode 100644 docs_oos/data/core/ptr.json delete mode 100644 docs_oos/data/core/ref.json delete mode 100644 docs_oos/data/core/ring_buffer.json delete mode 100644 docs_oos/data/core/share.json delete mode 100644 docs_oos/data/core/string_literal.json delete mode 100644 docs_oos/data/core/tmpl_concat.json delete mode 100644 docs_oos/data/core/tmpl_group.json delete mode 100644 docs_oos/data/core/tmpl_reduce.json delete mode 100644 docs_oos/data/core/tmpl_value_group.json delete mode 100644 docs_oos/data/core/tree.json delete mode 100644 docs_oos/data/core/tree_container.json delete mode 100644 docs_oos/data/core/void_t.json delete mode 100644 docs_oos/data/remote/data_client.json delete mode 100644 docs_oos/data/remote/data_client.loopback.json delete mode 100644 docs_oos/data/remote/data_or_id.json delete mode 100644 docs_oos/data/remote/data_server.json delete mode 100644 docs_oos/data/remote/data_server.loopback.json delete mode 100644 docs_oos/data/remote/i_data_server.json delete mode 100644 docs_oos/data/remote/i_rpc_server.json delete mode 100644 docs_oos/data/remote/loopback.json delete mode 100644 docs_oos/data/remote/remote.json delete mode 100644 docs_oos/data/remote/remote.loopback.json delete mode 100644 docs_oos/data/remote/remote_address.json delete mode 100644 docs_oos/data/remote/remote_address.loopback.json delete mode 100644 docs_oos/data/remote/remote_data.json delete mode 100644 docs_oos/data/remote/remote_data.loopback.json delete mode 100644 docs_oos/data/remote/rpc_client.json delete mode 100644 docs_oos/data/remote/rpc_client.loopback.json delete mode 100644 docs_oos/data/remote/rpc_function_id.json delete mode 100644 docs_oos/data/remote/rpc_server.json delete mode 100644 docs_oos/data/remote/rpc_server.loopback.json delete mode 100644 docs_oos/entity.schema.json diff --git a/docs/.nix/derivation.nix b/docs/.nix/derivation.nix deleted file mode 100644 index a6dee7d..0000000 --- a/docs/.nix/derivation.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ lib -, stdenvNoCC -, python3 -, python3Packages -, doxygen -, gasp -, version -}: - -stdenvNoCC.mkDerivation { - pname = "forstio-docs"; - inherit version; - - src = ../../.; - - nativeBuildInputs = [ - python3 - python3Packages.sphinx - python3Packages.sphinx-rtd-theme - doxygen - gasp - ]; - - buildPhase = '' - # C++ API generation - pushd docs - doxygen Doxygen.in - python3 ${gasp.outPath}/bin/gasp.py xml --namespace saw > cpp_map.json - # C++ and C template generation - mkdir -p source/cpp_api - python3 ${gasp.outPath}/bin/make_rst.py --title="C++" -t ${gasp.outPath}/templates/rst -m cpp_map.json -o source/cpp_api - make html - popd - ''; - - installPhase = '' - mkdir -p $out - pushd docs - mv build/html $out/html - popd - ''; -} diff --git a/docs/Doxygen.in b/docs/Doxygen.in deleted file mode 100644 index 6124483..0000000 --- a/docs/Doxygen.in +++ /dev/null @@ -1,8 +0,0 @@ -GENERATE_XML = YES -GENERATE_LATEX= NO -GENERATE_HTML = NO -PROJECT_NAME = forstio -RECURSIVE = YES -FILE_PATTERNS = *.cpp *.hpp -INPUT = ../modules -EXCLUDE_SYMBOLS = *::impl::* diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d0c3cbf..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/data/core/array_buffer.json b/docs/data/core/array_buffer.json new file mode 100644 index 0000000..24b5cca --- /dev/null +++ b/docs/data/core/array_buffer.json @@ -0,0 +1,31 @@ +{ + "format": 1, + "id": "saw-array_buffer", + "kind": "class", + "name": "array_buffer", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/buffer.hpp", + "brief_description": "One time buffer.", + "detailed_description": [ + [ + "Filled once and read once. The cursors only move forward and the storage is never reused, so what was read is gone and what was written cannot be taken back." + ], + [ + "The right choice for a single message of known size." + ] + ], + "bases": [ + [{"name": "buffer", "id": "saw-buffer"}] + ], + "functions": { + "saw-array_buffer-ctor": { + "id": "saw-array_buffer-ctor", + "name": "array_buffer", + "type": [], + "parameters": [ + {"name": "size", "type": ["size_t"]} + ] + } + } +} diff --git a/docs/data/core/branch.json b/docs/data/core/branch.json new file mode 100644 index 0000000..d30c42f --- /dev/null +++ b/docs/data/core/branch.json @@ -0,0 +1,103 @@ +{ + "format": 1, + "id": "saw-branch", + "kind": "class", + "name": "branch", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/tree.hpp", + "brief_description": "Container with a simplistic approach to a branch.", + "detailed_description": [ + [ + "The edge in a", + {"name": "tree_container", "id": "saw-tree_container"}, + "It holds either a leaf value or a whole sub tree, as a variant of the two, so the recursion lives in the data rather than in a pointer chain." + ], + [ + "Access comes in two flavours: get asserts what is held, while extract and replace hand the content out or swap it and report a mismatch as an error instead." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "Leaf value type."}, + {"name": "Tree", "kind": "type", "brief_description": "Sub tree type."} + ], + "aliases": { + "saw-branch-type": { + "id": "saw-branch-type", + "name": "type", + "type": ["std::variant< Tree, T >"], + "brief_description": "Either a sub tree or a leaf." + } + }, + "functions": { + "saw-branch-is": { + "id": "saw-branch-is", + "name": "is", + "type": ["bool"], + "const": true, + "brief_description": "Whether the branch holds the given alternative.", + "templates": [ + {"name": "NT", "kind": "type"} + ] + }, + "saw-branch-is_tree": { + "id": "saw-branch-is_tree", + "name": "is_tree", + "type": ["bool"], + "const": true, + "brief_description": "Whether the branch continues into a sub tree." + }, + "saw-branch-is_value": { + "id": "saw-branch-is_value", + "name": "is_value", + "type": ["bool"], + "const": true, + "brief_description": "Whether the branch ends in a leaf." + }, + "saw-branch-get_tree": { + "id": "saw-branch-get_tree", + "name": "get_tree", + "type": ["Tree &"], + "brief_description": "The sub tree. Only valid if is_tree." + }, + "saw-branch-get_value": { + "id": "saw-branch-get_value", + "name": "get_value", + "type": ["T &"], + "brief_description": "The leaf. Only valid if is_value." + }, + "saw-branch-extract_tree": { + "id": "saw-branch-extract_tree", + "name": "extract_tree", + "type": ["error_or< Tree >"], + "brief_description": "Takes the sub tree out, failing if the branch holds a leaf." + }, + "saw-branch-extract_value": { + "id": "saw-branch-extract_value", + "name": "extract_value", + "type": ["error_or< T >"], + "brief_description": "Takes the leaf out, failing if the branch holds a sub tree." + }, + "saw-branch-replace_tree": { + "id": "saw-branch-replace_tree", + "name": "replace_tree", + "type": ["error_or< Tree >"], + "brief_description": "Swaps in new content and returns the sub tree which was there.", + "parameters": [ + {"name": "nd", "type": ["type"]} + ] + }, + "saw-branch-replace_value": { + "id": "saw-branch-replace_value", + "name": "replace_value", + "type": ["error_or< T >"], + "brief_description": "Swaps in new content and returns the leaf which was there.", + "parameters": [ + {"name": "nd", "type": ["type"]} + ] + } + }, + "notes": [ + "Copy is forbidden, move is allowed." + ] +} diff --git a/docs/data/core/buffer.json b/docs/data/core/buffer.json new file mode 100644 index 0000000..cee07fd --- /dev/null +++ b/docs/data/core/buffer.json @@ -0,0 +1,182 @@ +{ + "format": 1, + "id": "saw-buffer", + "kind": "class", + "name": "buffer", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/buffer.hpp", + "brief_description": "Access class to reduce templated buffer segment bloat.", + "detailed_description": [ + [ + "A buffer has two independent cursors, one for reading and one for writing, and may be split into segments which are contiguous only up to a point. Everything is phrased around that: composite length is what remains in total, segment length is what remains without a jump." + ], + [ + "Code which copies in bulk loops on the segment length; code which works byte by byte uses read and write with an offset. Both cursors move only through the advance calls, so a reader can look ahead without consuming." + ] + ], + "functions": { + "saw-buffer-read_position": { + "id": "saw-buffer-read_position", + "name": "read_position", + "type": ["size_t"], + "const": true, + "virtual": true, + "brief_description": "Where the read cursor currently is." + }, + "saw-buffer-read_composite_length": { + "id": "saw-buffer-read_composite_length", + "name": "read_composite_length", + "type": ["size_t"], + "const": true, + "virtual": true, + "brief_description": "How many bytes can be read in total, across segments." + }, + "saw-buffer-read_segment_length": { + "id": "saw-buffer-read_segment_length", + "name": "read_segment_length", + "type": ["size_t"], + "const": true, + "virtual": true, + "brief_description": "How many bytes can be read contiguously from an offset.", + "parameters": [ + {"name": "offset", "type": ["size_t"], "default": "0"} + ] + }, + "saw-buffer-read_advance": { + "id": "saw-buffer-read_advance", + "name": "read_advance", + "type": ["void"], + "virtual": true, + "brief_description": "Consumes bytes from the read side.", + "parameters": [ + {"name": "bytes", "type": ["size_t"]} + ] + }, + "saw-buffer-read": { + "id": "saw-buffer-read", + "name": "read", + "type": ["uint8_t &"], + "virtual": true, + "brief_description": "The byte at an offset from the read cursor, without consuming it.", + "parameters": [ + {"name": "i", "type": ["size_t"], "default": "0"} + ] + }, + "saw-buffer-write_position": { + "id": "saw-buffer-write_position", + "name": "write_position", + "type": ["size_t"], + "const": true, + "virtual": true, + "brief_description": "Where the write cursor currently is." + }, + "saw-buffer-write_composite_length": { + "id": "saw-buffer-write_composite_length", + "name": "write_composite_length", + "type": ["size_t"], + "const": true, + "virtual": true, + "brief_description": "How many bytes can be written in total, across segments." + }, + "saw-buffer-write_segment_length": { + "id": "saw-buffer-write_segment_length", + "name": "write_segment_length", + "type": ["size_t"], + "const": true, + "virtual": true, + "brief_description": "How many bytes can be written contiguously from an offset.", + "parameters": [ + {"name": "offset", "type": ["size_t"], "default": "0"} + ] + }, + "saw-buffer-write_advance": { + "id": "saw-buffer-write_advance", + "name": "write_advance", + "type": ["void"], + "virtual": true, + "brief_description": "Marks bytes as written.", + "parameters": [ + {"name": "bytes", "type": ["size_t"]} + ] + }, + "saw-buffer-write": { + "id": "saw-buffer-write", + "name": "write", + "type": ["uint8_t &"], + "virtual": true, + "brief_description": "The byte at an offset from the write cursor.", + "parameters": [ + {"name": "i", "type": ["size_t"], "default": "0"} + ] + }, + "saw-buffer-write_require_length": { + "id": "saw-buffer-write_require_length", + "name": "write_require_length", + "type": [{"name": "error", "id": "saw-error"}], + "virtual": true, + "brief_description": "Asks for room before writing in bulk.", + "detailed_description": [ + [ + "Nothing can be done if the read side has not been filled, but the write side can grow on demand. Call this before pushing a run of bytes, so a failure happens once up front instead of halfway through." + ] + ], + "parameters": [ + {"name": "bytes", "type": ["size_t"]} + ] + }, + "saw-buffer-push-1": { + "id": "saw-buffer-push-1", + "name": "push", + "type": [{"name": "error", "id": "saw-error"}], + "brief_description": "Writes one byte.", + "detailed_description": [ + ["Fails with", {"name": "buffer_exhausted", "id": "saw-err-buffer_exhausted"}, "if there is no room."] + ], + "parameters": [ + {"name": "value", "type": ["const uint8_t &"]} + ] + }, + "saw-buffer-push-2": { + "id": "saw-buffer-push-2", + "name": "push", + "type": [{"name": "error", "id": "saw-error"}], + "brief_description": "Writes a run of bytes, segment by segment.", + "parameters": [ + {"name": "buffer", "type": ["const uint8_t &"], "brief_description": "First byte of the run."}, + {"name": "size", "type": ["size_t"]} + ] + }, + "saw-buffer-pop-1": { + "id": "saw-buffer-pop-1", + "name": "pop", + "type": [{"name": "error", "id": "saw-error"}], + "brief_description": "Reads one byte and consumes it.", + "parameters": [ + {"name": "value", "type": ["uint8_t &"]} + ] + }, + "saw-buffer-pop-2": { + "id": "saw-buffer-pop-2", + "name": "pop", + "type": [{"name": "error", "id": "saw-error"}], + "brief_description": "Reads a run of bytes and consumes them.", + "parameters": [ + {"name": "buffer", "type": ["uint8_t &"]}, + {"name": "size", "type": ["size_t"]} + ] + }, + "saw-buffer-write_from": { + "id": "saw-buffer-write_from", + "name": "write_from", + "type": ["error_or< uint64_t >"], + "brief_description": "Reads from another buffer and writes into this one.", + "parameters": [ + {"name": "buff", "type": ["const buffer &"]} + ] + } + }, + "notes": [ + "The concrete buffers differ in what happens when space runs out, which is the thing to pick on." + ] +} diff --git a/docs/data/core/buffer_view.json b/docs/data/core/buffer_view.json new file mode 100644 index 0000000..bf07694 --- /dev/null +++ b/docs/data/core/buffer_view.json @@ -0,0 +1,74 @@ +{ + "format": 1, + "id": "saw-buffer_view", + "kind": "class", + "name": "buffer_view", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/buffer.hpp", + "brief_description": "A viewer class for buffers.", + "detailed_description": [ + [ + "Carries its own cursors over somebody else's", + {"name": "buffer", "id": "saw-buffer"}, + "so a decoder can walk forward, discover the input is incomplete, and leave the underlying buffer untouched. Only once the operation succeeded does the caller advance the real buffer by the view's offset." + ], + [ + "That is the whole speculative parsing mechanism in this codebase. The codecs decode into a view and commit afterwards." + ], + [ + "Working on the referenced buffer invalidates the view." + ] + ], + "bases": [ + [{"name": "buffer", "id": "saw-buffer"}] + ], + "functions": { + "saw-buffer_view-ctor-1": { + "id": "saw-buffer_view-ctor-1", + "name": "buffer_view", + "type": [], + "parameters": [ + {"name": "buffer", "type": [{"name": "buffer", "id": "saw-buffer"}, "&"]} + ] + }, + "saw-buffer_view-ctor-2": { + "id": "saw-buffer_view-ctor-2", + "name": "buffer_view", + "type": [], + "brief_description": "With an upper bound on what may be read and written through it.", + "parameters": [ + {"name": "buffer", "type": [{"name": "buffer", "id": "saw-buffer"}, "&"]}, + {"name": "limit_read_len", "type": ["uint64_t"]}, + {"name": "limit_write_len", "type": ["uint64_t"]} + ] + }, + "saw-buffer_view-read_offset": { + "id": "saw-buffer_view-read_offset", + "name": "read_offset", + "type": ["size_t"], + "const": true, + "brief_description": "How far the view has read ahead of the underlying buffer.", + "detailed_description": [ + ["This is what gets handed to read_advance on the real buffer once the read is known to have succeeded."] + ] + }, + "saw-buffer_view-write_offset": { + "id": "saw-buffer_view-write_offset", + "name": "write_offset", + "type": ["size_t"], + "const": true, + "brief_description": "How far the view has written ahead of the underlying buffer." + } + }, + "examples": [ + { + "title": "Decoding without consuming on failure", + "description": [ + ["The shape every codec uses. If the decode fails, the buffer is left exactly as it was and the caller can try again once more data arrived."] + ], + "language": "cpp", + "code": "buffer_view buff_v{from_decode.get_buffer()};\n\nauto eov = impl::json_decode::decode(buff_v, to_decode, cfg_);\nif(eov.is_error()){\n\treturn std::move(eov.get_error());\n}\n\n/// Only now is the input really consumed.\nfrom_decode.get_buffer().read_advance(buff_v.read_offset());\n" + } + ] +} diff --git a/docs/data/core/chain_array_buffer.json b/docs/data/core/chain_array_buffer.json new file mode 100644 index 0000000..a9459bd --- /dev/null +++ b/docs/data/core/chain_array_buffer.json @@ -0,0 +1,50 @@ +{ + "format": 1, + "id": "saw-chain_array_buffer", + "kind": "class", + "name": "chain_array_buffer", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/buffer.hpp", + "brief_description": "A growing chain of one time buffers.", + "detailed_description": [ + [ + "Holds a deque of", + {"name": "array_buffer", "id": "saw-array_buffer"}, + "so capacity can be added without moving what is already there. This is the buffer for a stream of unknown length, where a ring buffer would run out and a single array buffer would have to be guessed in advance." + ], + [ + "It is also why the buffer interface speaks of segments: a read which crosses from one link to the next is not contiguous, so segment length stops at the boundary." + ] + ], + "bases": [ + [{"name": "buffer", "id": "saw-buffer"}] + ], + "functions": { + "saw-chain_array_buffer-ctor": { + "id": "saw-chain_array_buffer-ctor", + "name": "chain_array_buffer", + "type": [] + }, + "saw-chain_array_buffer-extract_front": { + "id": "saw-chain_array_buffer-extract_front", + "name": "extract_front", + "type": ["error_or<", {"name": "array_buffer", "id": "saw-array_buffer"}, ">"], + "brief_description": "Takes the first link out of the chain instead of copying out of it.", + "detailed_description": [ + [ + "The size has to match what the front link still holds exactly. A partial extraction fails with", + {"name": "invalid_state", "id": "saw-err-invalid_state"}, + "and the caller is told to view and copy instead." + ], + [ + "An empty chain fails with", + {"name": "recoverable", "id": "saw-err-recoverable"} + ] + ], + "parameters": [ + {"name": "size", "type": ["uint64_t"]} + ] + } + } +} diff --git a/docs/data/core/err/already_exists.json b/docs/data/core/err/already_exists.json new file mode 100644 index 0000000..3d6c4ff --- /dev/null +++ b/docs/data/core/err/already_exists.json @@ -0,0 +1,35 @@ +{ + "format": 1, + "id": "saw-err-already_exists", + "kind": "struct", + "name": "already_exists", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "Something is already there under that name or id.", + "detailed_description": [ + [ + "Recoverable. Storing into an occupied slot, or binding a second server to an address which is already taken. The existing entry is left untouched, so the caller can decide whether to pick another id or treat it as success." + ] + ], + "attributes": { + "saw-err-already_exists-description": { + "id": "saw-err-already_exists-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"Already exists\"" + }, + "saw-err-already_exists-is_critical": { + "id": "saw-err-already_exists-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "false" + } + } +} diff --git a/docs/data/core/err/buffer_exhausted.json b/docs/data/core/err/buffer_exhausted.json new file mode 100644 index 0000000..a8651f1 --- /dev/null +++ b/docs/data/core/err/buffer_exhausted.json @@ -0,0 +1,35 @@ +{ + "format": 1, + "id": "saw-err-buffer_exhausted", + "kind": "struct", + "name": "buffer_exhausted", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "A buffer ran out of room to read or write.", + "detailed_description": [ + [ + "Recoverable, and deliberately so: a decoder hitting the end of what has arrived so far is the normal state of a stream, not a defect. Code which decodes incrementally checks for this kind and waits for more instead of failing." + ] + ], + "attributes": { + "saw-err-buffer_exhausted-description": { + "id": "saw-err-buffer_exhausted-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"Buffer Exhausted\"" + }, + "saw-err-buffer_exhausted-is_critical": { + "id": "saw-err-buffer_exhausted-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "false" + } + } +} diff --git a/docs/data/core/err/critical.json b/docs/data/core/err/critical.json new file mode 100644 index 0000000..006d6c7 --- /dev/null +++ b/docs/data/core/err/critical.json @@ -0,0 +1,37 @@ +{ + "format": 1, + "id": "saw-err-critical", + "kind": "struct", + "name": "critical", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "Generic critical error.", + "detailed_description": [ + [ + "The counterpart of", + {"name": "recoverable", "id": "saw-err-recoverable"}, + "for a failure the caller is not expected to continue through. Same advice applies: a named kind is worth defining as soon as anything wants to branch on it." + ] + ], + "attributes": { + "saw-err-critical-description": { + "id": "saw-err-critical-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"Generic critical error\"" + }, + "saw-err-critical-is_critical": { + "id": "saw-err-critical-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "true" + } + } +} diff --git a/docs/data/core/err/invalid_state.json b/docs/data/core/err/invalid_state.json new file mode 100644 index 0000000..343d218 --- /dev/null +++ b/docs/data/core/err/invalid_state.json @@ -0,0 +1,35 @@ +{ + "format": 1, + "id": "saw-err-invalid_state", + "kind": "struct", + "name": "invalid_state", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "Something was not in the state the operation requires.", + "detailed_description": [ + [ + "Critical. The catch all for a situation which should not have been reachable: malformed input where the grammar left no choice, a cast between mismatched class ids, a default constructed result which nobody filled in." + ] + ], + "attributes": { + "saw-err-invalid_state-description": { + "id": "saw-err-invalid_state-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"Invalid state\"" + }, + "saw-err-invalid_state-is_critical": { + "id": "saw-err-invalid_state-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "true" + } + } +} diff --git a/docs/data/core/err/no_error.json b/docs/data/core/err/no_error.json new file mode 100644 index 0000000..0fa4974 --- /dev/null +++ b/docs/data/core/err/no_error.json @@ -0,0 +1,38 @@ +{ + "format": 1, + "id": "saw-err-no_error", + "kind": "struct", + "name": "no_error", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "No error has occured.", + "detailed_description": [ + [ + "The absence of a failure, expressed as an error kind so that a function returning a plain", + {"name": "error", "id": "saw-error"}, + "can report success. Preregistered as code zero, which is why failed is defined as not being of this kind." + ] + ], + "attributes": { + "saw-err-no_error-description": { + "id": "saw-err-no_error-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"No error has occured\"", + "brief_description": "The category text. This is the portable identity of the error." + }, + "saw-err-no_error-is_critical": { + "id": "saw-err-no_error-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "false" + } + } +} diff --git a/docs/data/core/err/not_found.json b/docs/data/core/err/not_found.json new file mode 100644 index 0000000..e0e0dee --- /dev/null +++ b/docs/data/core/err/not_found.json @@ -0,0 +1,38 @@ +{ + "format": 1, + "id": "saw-err-not_found", + "kind": "struct", + "name": "not_found", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "Something was looked up and is not there.", + "detailed_description": [ + [ + "Recoverable, because asking for something absent is a normal outcome rather than a defect. Used when an id has no value stored under it, or when no server listens on an address." + ], + [ + "One of the three kinds preregistered in the registry." + ] + ], + "attributes": { + "saw-err-not_found-description": { + "id": "saw-err-not_found-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"Not found\"" + }, + "saw-err-not_found-is_critical": { + "id": "saw-err-not_found-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "false" + } + } +} diff --git a/docs/data/core/err/not_implemented.json b/docs/data/core/err/not_implemented.json new file mode 100644 index 0000000..2aecf9d --- /dev/null +++ b/docs/data/core/err/not_implemented.json @@ -0,0 +1,40 @@ +{ + "format": 1, + "id": "saw-err-not_implemented", + "kind": "struct", + "name": "not_implemented", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "The operation exists but has no implementation yet.", + "detailed_description": [ + [ + "Critical. A placeholder in a backend or codec which is still being built, so the gap surfaces as a failure at runtime instead of as a link error or, worse, as silently wrong behaviour." + ], + [ + "Distinct from", + {"name": "not_supported", "id": "saw-err-not_supported"}, + "which means the operation is never going to exist for this type." + ] + ], + "attributes": { + "saw-err-not_implemented-description": { + "id": "saw-err-not_implemented-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"Not implemented\"" + }, + "saw-err-not_implemented-is_critical": { + "id": "saw-err-not_implemented-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "true" + } + } +} diff --git a/docs/data/core/err/not_supported.json b/docs/data/core/err/not_supported.json new file mode 100644 index 0000000..bb509e7 --- /dev/null +++ b/docs/data/core/err/not_supported.json @@ -0,0 +1,40 @@ +{ + "format": 1, + "id": "saw-err-not_supported", + "kind": "struct", + "name": "not_supported", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "The operation does not apply here and never will.", + "detailed_description": [ + [ + "Recoverable, because the caller can reasonably ask and then do something else. The json decoder uses it for a leading plus on a number, which is valid in some languages and simply not part of json." + ], + [ + "Distinct from", + {"name": "not_implemented", "id": "saw-err-not_implemented"}, + "which means the gap is going to be filled later." + ] + ], + "attributes": { + "saw-err-not_supported-description": { + "id": "saw-err-not_supported-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"Not supported\"" + }, + "saw-err-not_supported-is_critical": { + "id": "saw-err-not_supported-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "false" + } + } +} diff --git a/docs/data/core/err/out_of_memory.json b/docs/data/core/err/out_of_memory.json new file mode 100644 index 0000000..47cab53 --- /dev/null +++ b/docs/data/core/err/out_of_memory.json @@ -0,0 +1,38 @@ +{ + "format": 1, + "id": "saw-err-out_of_memory", + "kind": "struct", + "name": "out_of_memory", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "An allocation failed.", + "detailed_description": [ + [ + "Critical. This is what a caught std::bad_alloc or a failed container insert turns into, which is how allocation failure stays inside the error path instead of becoming an exception." + ], + [ + "One of the three kinds preregistered in the registry." + ] + ], + "attributes": { + "saw-err-out_of_memory-description": { + "id": "saw-err-out_of_memory-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"Out of memory\"" + }, + "saw-err-out_of_memory-is_critical": { + "id": "saw-err-out_of_memory-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "true" + } + } +} diff --git a/docs/data/core/err/recoverable.json b/docs/data/core/err/recoverable.json new file mode 100644 index 0000000..fecd820 --- /dev/null +++ b/docs/data/core/err/recoverable.json @@ -0,0 +1,35 @@ +{ + "format": 1, + "id": "saw-err-recoverable", + "kind": "struct", + "name": "recoverable", + "namespace": "saw::err", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "Generic recoverable error.", + "detailed_description": [ + [ + "For a failure which has no kind of its own and which the caller can act on. Prefer defining a tag struct when the kind means something; a named category is what makes an error distinguishable in another process." + ] + ], + "attributes": { + "saw-err-recoverable-description": { + "id": "saw-err-recoverable-description", + "name": "description", + "type": ["std::string_view"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"Generic recoverable error\"" + }, + "saw-err-recoverable-is_critical": { + "id": "saw-err-recoverable-is_critical", + "name": "is_critical", + "type": ["bool"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "false" + } + } +} diff --git a/docs/data/core/error.json b/docs/data/core/error.json new file mode 100644 index 0000000..8f7a524 --- /dev/null +++ b/docs/data/core/error.json @@ -0,0 +1,168 @@ +{ + "format": 1, + "id": "saw-error", + "kind": "class", + "name": "error", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "Exception replacement. Carries a code, a criticality and a message.", + "detailed_description": [ + [ + "The library is written without exceptions, so this takes their place. An error is either recoverable or critical, and the code distinguishes the kind. Additional kinds are added by defining a tag struct with a description and an is_critical flag, which registers itself the first time it is used." + ], + [ + "The code is an index into a process local registry handed out in first use order. Only", + {"name": "no_error", "id": "saw-err-no_error"}, + {"name": "not_found", "id": "saw-err-not_found"}, + "and", + {"name": "out_of_memory", "id": "saw-err-out_of_memory"}, + "are preregistered, so the same error has different codes in two processes. A code must therefore never be sent anywhere; the category string is the portable identity." + ], + [ + "Copying is forbidden on purpose. An error is moved, or copied explicitly through copy_error, so passing one around stays visible at the call site." + ] + ], + "attributes": { + "saw-error-error_code_": { + "id": "saw-error-error_code_", + "name": "error_code_", + "type": ["code"], + "visibility": "private", + "brief_description": "Distinguishes the different error types." + }, + "saw-error-is_critical_": { + "id": "saw-error-is_critical_", + "name": "is_critical_", + "type": ["bool"], + "visibility": "private", + "brief_description": "Kept next to the code so checking doesn't need the registry." + }, + "saw-error-error_message_": { + "id": "saw-error-error_message_", + "name": "error_message_", + "type": ["std::variant< std::string_view, std::string >"], + "visibility": "private", + "brief_description": "A variant for the edge case of being out of memory, where a string cannot be built." + } + }, + "aliases": { + "saw-error-code": { + "id": "saw-error-code", + "name": "code", + "type": ["uint32_t"], + "brief_description": "Type representing the error code." + } + }, + "functions": { + "saw-error-ctor-1": { + "id": "saw-error-ctor-1", + "name": "error", + "type": [], + "parameters": [ + {"name": "id", "type": ["error::code"]}, + {"name": "is_critical", "type": ["bool"]} + ] + }, + "saw-error-ctor-2": { + "id": "saw-error-ctor-2", + "name": "error", + "type": [], + "brief_description": "With a message which outlives the error, such as a literal.", + "parameters": [ + {"name": "id", "type": ["error::code"]}, + {"name": "is_critical", "type": ["bool"]}, + {"name": "msg", "type": ["const std::string_view &"]} + ] + }, + "saw-error-ctor-3": { + "id": "saw-error-ctor-3", + "name": "error", + "type": [], + "brief_description": "With an owned message, for text built at the point of failure.", + "parameters": [ + {"name": "id", "type": ["error::code"]}, + {"name": "is_critical", "type": ["bool"]}, + {"name": "msg", "type": ["std::string &&"]} + ] + }, + "saw-error-get_message": { + "id": "saw-error-get_message", + "name": "get_message", + "type": ["const std::string_view"], + "const": true, + "brief_description": "Returns a string view to the message." + }, + "saw-error-get_category": { + "id": "saw-error-get_category", + "name": "get_category", + "type": ["const std::string_view"], + "const": true, + "brief_description": "Returns a view describing which error this is.", + "detailed_description": [ + ["Looked up in the registry. This, not the code, is the identity which means the same thing in another process."] + ] + }, + "saw-error-failed": { + "id": "saw-error-failed", + "name": "failed", + "type": ["bool"], + "const": true, + "brief_description": "Checks if it is an error at all, since the code zero is reserved for no error." + }, + "saw-error-is_critical": { + "id": "saw-error-is_critical", + "name": "is_critical", + "type": ["bool"], + "const": true, + "brief_description": "Checks if the error is critical." + }, + "saw-error-is_recoverable": { + "id": "saw-error-is_recoverable", + "name": "is_recoverable", + "type": ["bool"], + "const": true, + "brief_description": "Checks if the error is recoverable." + }, + "saw-error-copy_error": { + "id": "saw-error-copy_error", + "name": "copy_error", + "type": ["error"], + "const": true, + "brief_description": "Replaces the copy constructor, so copying an error is always explicit.", + "detailed_description": [ + ["If copying the message runs out of memory, the copy keeps the code and gets a static message instead of failing."] + ] + }, + "saw-error-get_id": { + "id": "saw-error-get_id", + "name": "get_id", + "type": ["error::code"], + "const": true, + "brief_description": "Returns the code." + }, + "saw-error-is_type": { + "id": "saw-error-is_type", + "name": "is_type", + "type": ["bool"], + "const": true, + "brief_description": "Checks whether this error is of a given kind.", + "detailed_description": [ + ["The way to branch on an error. Comparing codes directly only works inside one process."] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "An error tag struct, e.g. err::not_found."} + ], + "examples": [ + { + "title": "Branching on the kind of failure", + "language": "cpp", + "code": "auto eov = srv.receive(dat_id);\nif(eov.is_error()){\n\tauto& err = eov.get_error();\n\tif(err.is_type()){\n\t\t/// Nothing stored under that id yet.\n\t\treturn make_void();\n\t}\n\treturn std::move(err);\n}\n" + } + ] + } + }, + "notes": [ + "Copy is forbidden; use copy_error when a second instance is genuinely needed." + ] +} diff --git a/docs/data/core/error_builder.json b/docs/data/core/error_builder.json new file mode 100644 index 0000000..4385514 --- /dev/null +++ b/docs/data/core/error_builder.json @@ -0,0 +1,65 @@ +{ + "format": 1, + "id": "saw-error_builder", + "kind": "struct", + "name": "error_builder", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "Builds an error message lazily, only when the error is actually created.", + "detailed_description": [ + [ + "Composing a message costs an allocation and some string work, which is wasted on the path where nothing fails. The builder holds a callable instead and runs it at the moment the error is made." + ], + [ + "If building the message throws, the error is still produced with the generic message passed in, so an out of memory situation cannot turn a failure into a crash." + ] + ], + "attributes": { + "saw-error_builder-func_": { + "id": "saw-error_builder-func_", + "name": "func_", + "type": ["std::function< std::string() >"], + "visibility": "private" + } + }, + "functions": { + "saw-error_builder-ctor": { + "id": "saw-error_builder-ctor", + "name": "error_builder", + "type": [], + "templates": [ + {"name": "Func", "kind": "type", "brief_description": "Callable returning the message."} + ], + "parameters": [ + {"name": "func__", "type": ["Func &&"]} + ] + }, + "saw-error_builder-make_error": { + "id": "saw-error_builder-make_error", + "name": "make_error", + "type": [{"name": "error", "id": "saw-error"}], + "brief_description": "Runs the callable and produces the error.", + "detailed_description": [ + ["The callable is cleared afterwards, so a builder yields its message once."] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "The error tag struct to produce."} + ], + "parameters": [ + { + "name": "generic", + "type": ["const std::string_view &"], + "brief_description": "Fallback message if building the real one fails." + } + ], + "examples": [ + { + "title": "A message which is only built on failure", + "language": "cpp", + "code": "return build_error([&](){\n\treturn std::string{\"Expect ',' or '}', but got \"}\n\t\t+ std::string{static_cast(buff.read())};\n}).make_error(\"Struct separator expected\");\n" + } + ] + } + } +} diff --git a/docs/data/core/error_or.json b/docs/data/core/error_or.json new file mode 100644 index 0000000..a4a0d3b --- /dev/null +++ b/docs/data/core/error_or.json @@ -0,0 +1,110 @@ +{ + "format": 1, + "id": "saw-error_or", + "kind": "class", + "name": "error_or", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "Holds either a value or an error.", + "detailed_description": [ + [ + "The return type of nearly everything which can fail. It is a variant of an", + {"name": "error", "id": "saw-error"}, + "and the value, with void represented by an internal empty type so error_or< void > works like any other." + ], + [ + "get_value and get_error return references into the object, so the error_or itself has to stay alive while the reference is used. Chaining the two, as in f().get_value(), hands back a reference into a temporary." + ], + [ + "The default constructor exists but fills in an invalid_state error, so a default constructed one is already failed rather than empty. The value type therefore does not have to be default constructible." + ] + ], + "bases": [ + [{"name": "error_or_value", "id": "saw-error_or_value"}] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "The value type. May be void."} + ], + "attributes": { + "saw-error_or-value_or_error_": { + "id": "saw-error_or-value_or_error_", + "name": "value_or_error_", + "type": ["std::variant< error, fix_void< T > >"], + "visibility": "private" + } + }, + "functions": { + "saw-error_or-ctor-1": { + "id": "saw-error_or-ctor-1", + "name": "error_or", + "type": [], + "brief_description": "Default constructs to an invalid_state error, not to a value." + }, + "saw-error_or-ctor-2": { + "id": "saw-error_or-ctor-2", + "name": "error_or", + "type": [], + "brief_description": "From a value. Implicit, so a function can return the value directly.", + "parameters": [ + {"name": "value", "type": ["const fix_void< T > &"]} + ] + }, + "saw-error_or-ctor-3": { + "id": "saw-error_or-ctor-3", + "name": "error_or", + "type": [], + "brief_description": "From an error. Implicit, so a function can return make_error directly.", + "parameters": [ + {"name": "error", "type": ["error &&"]} + ] + }, + "saw-error_or-is_value": { + "id": "saw-error_or-is_value", + "name": "is_value", + "type": ["bool"], + "const": true, + "brief_description": "True if it holds the value." + }, + "saw-error_or-is_error": { + "id": "saw-error_or-is_error", + "name": "is_error", + "type": ["bool"], + "const": true, + "brief_description": "True if it holds an error." + }, + "saw-error_or-get_value": { + "id": "saw-error_or-get_value", + "name": "get_value", + "type": ["fix_void< T > &"], + "brief_description": "The value. Only valid if is_value." + }, + "saw-error_or-get_error": { + "id": "saw-error_or-get_error", + "name": "get_error", + "type": ["error &"], + "brief_description": "The error. Only valid if is_error." + } + }, + "specializations": [ + { + "name": "error_or< error_or< T > >", + "id": "saw-error_or-nested", + "brief_description": "Deleted. Guards against an error_or which wraps another one." + } + ], + "examples": [ + { + "title": "Passing a failure upwards", + "description": [ + [ + "The shape repeated throughout the codebase. The error is moved out, because", + {"name": "error", "id": "saw-error"}, + "forbids copying." + ] + ], + "language": "cpp", + "code": "error_or> load(id dat_id){\n\tauto eov = srv.receive(dat_id);\n\tif(eov.is_error()){\n\t\treturn std::move(eov.get_error());\n\t}\n\n\treturn std::move(eov.get_value());\n}\n" + } + ] +} diff --git a/docs/data/core/error_or.nested.json b/docs/data/core/error_or.nested.json new file mode 100644 index 0000000..34bd2b5 --- /dev/null +++ b/docs/data/core/error_or.nested.json @@ -0,0 +1,24 @@ +{ + "format": 1, + "id": "saw-error_or-nested", + "kind": "class", + "name": "error_or", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/error.hpp", + "is_special": true, + "specializes": "saw-error_or", + "arguments": ["error_or< T >"], + "brief_description": "Type safe guard against an error_or holding another error_or.", + "detailed_description": [ + [ + "Its only member is a deleted default constructor, so the type cannot be formed. It catches the case where an error_or is returned from something which already returns one, which is easy to do by accident once calls are nested a few levels deep." + ], + [ + "The failure then happens where the type is written instead of somewhere further down in a confusing overload." + ] + ], + "templates": [ + {"name": "T", "kind": "type"} + ] +} diff --git a/docs/data/core/error_or_value.json b/docs/data/core/error_or_value.json new file mode 100644 index 0000000..1b93ee9 --- /dev/null +++ b/docs/data/core/error_or_value.json @@ -0,0 +1,26 @@ +{ + "format": 1, + "id": "saw-error_or_value", + "kind": "class", + "name": "error_or_value", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/error.hpp", + "brief_description": "Type erased base of every error_or.", + "detailed_description": [ + [ + "Lets code hold a result whose value type it doesn't know, and recover it later with as. The cast is unchecked, so the caller has to know which type it stored." + ] + ], + "functions": { + "saw-error_or_value-as": { + "id": "saw-error_or_value-as", + "name": "as", + "type": [{"name": "error_or", "id": "saw-error_or"}, "< unfix_void< T > > &"], + "brief_description": "Recovers the concrete result.", + "templates": [ + {"name": "T", "kind": "type", "brief_description": "The value type which was stored."} + ] + } + } +} diff --git a/docs/data/core/heap.json b/docs/data/core/heap.json new file mode 100644 index 0000000..6500895 --- /dev/null +++ b/docs/data/core/heap.json @@ -0,0 +1,23 @@ +{ + "format": 1, + "id": "saw-heap", + "kind": "function", + "name": "heap", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/common.hpp", + "type": [{"name": "own", "id": "saw-own"}, "< T >"], + "brief_description": "Constructs an object on the heap and hands back sole ownership.", + "detailed_description": [ + [ + "The one place new is called. Arguments are forwarded to the constructor, so a type which forbids copying and moving can still be built here, which is exactly what the registered servers rely on." + ] + ], + "templates": [ + {"name": "T", "kind": "type"}, + {"name": "Args", "kind": "type", "pack": true} + ], + "parameters": [ + {"name": "args", "type": ["Args &&..."], "brief_description": "Forwarded to the constructor of T."} + ] +} diff --git a/docs/data/core/id.json b/docs/data/core/id.json new file mode 100644 index 0000000..dc22fac --- /dev/null +++ b/docs/data/core/id.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "id": "saw-id", + "kind": "class", + "name": "id", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/id.hpp", + "brief_description": "An identifier tied to the class it stands for.", + "detailed_description": [ + [ + "A number underneath, but a distinct type per subject, so an id for one schema cannot be handed where an id for another is expected. That is what makes the remote layer safe to work with: nothing there moves data, it moves these." + ], + [ + "Comparable and copyable, with no default constructor, so an id always refers to something somebody handed out." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "What the id refers to."} + ], + "attributes": { + "saw-id-value_": { + "id": "saw-id-value_", + "name": "value_", + "type": ["uint64_t"], + "visibility": "private" + } + }, + "functions": { + "saw-id-ctor": { + "id": "saw-id-ctor", + "name": "id", + "type": [], + "parameters": [ + {"name": "val", "type": ["uint64_t"]} + ] + }, + "saw-id-eq": { + "id": "saw-id-eq", + "name": "operator==", + "type": ["bool"], + "const": true, + "parameters": [ + {"name": "rhs", "type": ["const id< T > &"]} + ] + }, + "saw-id-neq": { + "id": "saw-id-neq", + "name": "operator!=", + "type": ["bool"], + "const": true, + "parameters": [ + {"name": "rhs", "type": ["const id< T > &"]} + ] + }, + "saw-id-get_value": { + "id": "saw-id-get_value", + "name": "get_value", + "type": ["const uint64_t &"], + "const": true, + "brief_description": "The underlying number.", + "detailed_description": [ + ["Mostly for internal purposes, and for the moment an id has to be put somewhere which only understands numbers."] + ] + } + } +} diff --git a/docs/data/core/lent.json b/docs/data/core/lent.json new file mode 100644 index 0000000..06a6751 --- /dev/null +++ b/docs/data/core/lent.json @@ -0,0 +1,21 @@ +{ + "format": 1, + "id": "saw-lent", + "kind": "alias", + "name": "lent", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/common.hpp", + "type": ["std::weak_ptr< T >"], + "brief_description": "A borrow of a shared object which does not keep it alive.", + "detailed_description": [ + [ + "The counterpart of", + {"name": "our", "id": "saw-our"}, + "for a party which wants access but must not extend the lifetime, which is how cycles between the two are avoided." + ] + ], + "templates": [ + {"name": "T", "kind": "type"} + ] +} diff --git a/docs/data/core/maybe.json b/docs/data/core/maybe.json new file mode 100644 index 0000000..82ff6a0 --- /dev/null +++ b/docs/data/core/maybe.json @@ -0,0 +1,21 @@ +{ + "format": 1, + "id": "saw-maybe", + "kind": "alias", + "name": "maybe", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/common.hpp", + "type": ["std::optional< T >"], + "brief_description": "A value which may be absent, without that absence being a failure.", + "detailed_description": [ + [ + "Distinct from", + {"name": "error_or", "id": "saw-error_or"}, + "which says something went wrong. A maybe says a value is legitimately not there, as with an optional response slot where the caller may or may not have picked one." + ] + ], + "templates": [ + {"name": "T", "kind": "type"} + ] +} diff --git a/docs/data/core/our.json b/docs/data/core/our.json new file mode 100644 index 0000000..e1ab459 --- /dev/null +++ b/docs/data/core/our.json @@ -0,0 +1,24 @@ +{ + "format": 1, + "id": "saw-our", + "kind": "alias", + "name": "our", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/common.hpp", + "type": ["std::shared_ptr< T >"], + "brief_description": "Shared ownership of a heap object.", + "detailed_description": [ + [ + "Used where several parties genuinely keep something alive, such as a device handle held by both a server and the data allocated on it. Where one owner is enough, prefer", + {"name": "own", "id": "saw-own"} + ], + [ + "Created through", + {"name": "share", "id": "saw-share"} + ] + ], + "templates": [ + {"name": "T", "kind": "type"} + ] +} diff --git a/docs/data/core/own.json b/docs/data/core/own.json new file mode 100644 index 0000000..1716ab3 --- /dev/null +++ b/docs/data/core/own.json @@ -0,0 +1,30 @@ +{ + "format": 1, + "id": "saw-own", + "kind": "alias", + "name": "own", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/common.hpp", + "type": ["std::unique_ptr< T >"], + "brief_description": "Sole ownership of a heap object.", + "detailed_description": [ + [ + "One of the four ownership words the codebase uses in place of raw pointers: own is sole ownership,", + {"name": "our", "id": "saw-our"}, + "is shared,", + {"name": "lent", "id": "saw-lent"}, + "is a weak borrow, and", + {"name": "ptr", "id": "saw-ptr"}, + "owns nothing at all." + ], + [ + "Created through", + {"name": "heap", "id": "saw-heap"}, + "rather than by calling new." + ] + ], + "templates": [ + {"name": "T", "kind": "type"} + ] +} diff --git a/docs/data/core/parameter_key_pack_index.json b/docs/data/core/parameter_key_pack_index.json new file mode 100644 index 0000000..1d88931 --- /dev/null +++ b/docs/data/core/parameter_key_pack_index.json @@ -0,0 +1,35 @@ +{ + "format": 1, + "id": "saw-parameter_key_pack_index", + "kind": "struct", + "name": "parameter_key_pack_index", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/templates.hpp", + "brief_description": "Returns the position of a name in a pack of string literals.", + "detailed_description": [ + [ + "What turns a written name into an index. Looking a struct member up by its name, or an interface function by the literal handed to call, goes through this and then through", + {"name": "parameter_pack_type", "id": "saw-parameter_pack_type"}, + "to reach the type sitting at the same position." + ], + [ + "A name which is not in the pack is a compile error, which is why a misspelled member name fails at the call site." + ] + ], + "templates": [ + {"name": "V", "kind": "non_type", "type": "string_literal", "brief_description": "The name being looked for."}, + {"name": "Keys", "kind": "non_type", "type": "string_literal", "pack": true} + ], + "attributes": { + "saw-parameter_key_pack_index-value": { + "id": "saw-parameter_key_pack_index-value", + "name": "value", + "type": ["uint64_t"], + "visibility": "public", + "static": true, + "constexpr": true, + "brief_description": "Zero based position of the name." + } + } +} diff --git a/docs/data/core/parameter_key_pack_type.json b/docs/data/core/parameter_key_pack_type.json new file mode 100644 index 0000000..bd3041f --- /dev/null +++ b/docs/data/core/parameter_key_pack_type.json @@ -0,0 +1,32 @@ +{ + "format": 1, + "id": "saw-parameter_key_pack_type", + "kind": "struct", + "name": "parameter_key_pack_type", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/templates.hpp", + "brief_description": "Returns the name at a position in a pack of string literals.", + "detailed_description": [ + [ + "The inverse of", + {"name": "parameter_key_pack_index", "id": "saw-parameter_key_pack_index"}, + "and the piece which makes compile time loops over named members possible: at index i it yields the literal, which can then be used as a template argument again." + ] + ], + "templates": [ + {"name": "i", "kind": "non_type", "type": "uint64_t", "brief_description": "Zero based position."}, + {"name": "Keys", "kind": "non_type", "type": "string_literal", "pack": true} + ], + "attributes": { + "saw-parameter_key_pack_type-literal": { + "id": "saw-parameter_key_pack_type-literal", + "name": "literal", + "type": [{"name": "string_literal", "id": "saw-string_literal"}], + "visibility": "public", + "static": true, + "constexpr": true, + "brief_description": "The name at that position." + } + } +} diff --git a/docs/data/core/parameter_pack_index.json b/docs/data/core/parameter_pack_index.json new file mode 100644 index 0000000..a553e31 --- /dev/null +++ b/docs/data/core/parameter_pack_index.json @@ -0,0 +1,32 @@ +{ + "format": 1, + "id": "saw-parameter_pack_index", + "kind": "struct", + "name": "parameter_pack_index", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/templates.hpp", + "brief_description": "Returns the position of a type in a parameter pack.", + "detailed_description": [ + [ + "The inverse of", + {"name": "parameter_pack_type", "id": "saw-parameter_pack_type"}, + "Recurses until the head matches, so a type which is not in the pack fails to compile rather than yielding a wrong index." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "The type being looked for."}, + {"name": "TL", "kind": "type", "pack": true, "brief_description": "The pack to search."} + ], + "attributes": { + "saw-parameter_pack_index-value": { + "id": "saw-parameter_pack_index-value", + "name": "value", + "type": ["size_t"], + "visibility": "public", + "static": true, + "constexpr": true, + "brief_description": "Zero based position of T in the pack." + } + } +} diff --git a/docs/data/core/parameter_pack_type.json b/docs/data/core/parameter_pack_type.json new file mode 100644 index 0000000..2175cdd --- /dev/null +++ b/docs/data/core/parameter_pack_type.json @@ -0,0 +1,27 @@ +{ + "format": 1, + "id": "saw-parameter_pack_type", + "kind": "struct", + "name": "parameter_pack_type", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/templates.hpp", + "brief_description": "Returns the type at a position in a parameter pack.", + "detailed_description": [ + [ + "The workhorse of every compile time loop in this codebase. Recursion over an index plus this is how a struct, a tuple or an interface is walked member by member, since a pack cannot be indexed directly." + ] + ], + "templates": [ + {"name": "N", "kind": "non_type", "type": "size_t", "brief_description": "Zero based position."}, + {"name": "T", "kind": "type", "pack": true} + ], + "aliases": { + "saw-parameter_pack_type-type": { + "id": "saw-parameter_pack_type-type", + "name": "type", + "type": ["the Nth type of T..."], + "brief_description": "The type at that position." + } + } +} diff --git a/docs/data/core/parameter_pack_value.json b/docs/data/core/parameter_pack_value.json new file mode 100644 index 0000000..920bd09 --- /dev/null +++ b/docs/data/core/parameter_pack_value.json @@ -0,0 +1,33 @@ +{ + "format": 1, + "id": "saw-parameter_pack_value", + "kind": "struct", + "name": "parameter_pack_value", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/templates.hpp", + "brief_description": "Returns the value at a position in a value pack.", + "detailed_description": [ + [ + "The value counterpart of", + {"name": "parameter_pack_type", "id": "saw-parameter_pack_type"}, + "used where a pack of numbers has to be indexed, such as the dimensions of a fixed size array." + ] + ], + "templates": [ + {"name": "i", "kind": "non_type", "type": "uint64_t", "brief_description": "Zero based position."}, + {"name": "T", "kind": "type", "brief_description": "Type of the values."}, + {"name": "V", "kind": "non_type", "type": "T", "pack": true} + ], + "attributes": { + "saw-parameter_pack_value-value": { + "id": "saw-parameter_pack_value-value", + "name": "value", + "type": ["T"], + "visibility": "public", + "static": true, + "constexpr": true, + "brief_description": "The value at that position." + } + } +} diff --git a/docs/data/core/ptr.json b/docs/data/core/ptr.json new file mode 100644 index 0000000..50fea1a --- /dev/null +++ b/docs/data/core/ptr.json @@ -0,0 +1,64 @@ +{ + "format": 1, + "id": "saw-ptr", + "kind": "class", + "name": "ptr", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/common.hpp", + "brief_description": "Non owning pointer which may be empty.", + "detailed_description": [ + [ + "States in the type system that something is referred to but not owned. Copyable and reassignable, unlike", + {"name": "ref", "id": "saw-ref"}, + "and checkable, unlike a reference." + ], + [ + "Dereferencing goes through the call operator rather than through star or arrow, which keeps the indirection visible at every use." + ], + [ + "Nothing here tracks lifetime. A ptr outliving its target is a bug the type cannot catch, which is why the classes holding one, such as the data servers, forbid moving themselves." + ] + ], + "templates": [ + {"name": "T", "kind": "type"} + ], + "attributes": { + "saw-ptr-ptr_": { + "id": "saw-ptr-ptr_", + "name": "ptr_", + "type": ["T *"], + "visibility": "private" + } + }, + "functions": { + "saw-ptr-ctor-1": { + "id": "saw-ptr-ctor-1", + "name": "ptr", + "type": [], + "brief_description": "Empty." + }, + "saw-ptr-ctor-2": { + "id": "saw-ptr-ctor-2", + "name": "ptr", + "type": [], + "brief_description": "Pointing at an object. Implicit, so passing an object where a ptr is expected just works.", + "parameters": [ + {"name": "ptr__", "type": ["T &"]} + ] + }, + "saw-ptr-call": { + "id": "saw-ptr-call", + "name": "operator()", + "type": ["T &"], + "brief_description": "The pointed at object. Undefined if empty." + }, + "saw-ptr-is_valid": { + "id": "saw-ptr-is_valid", + "name": "is_valid", + "type": ["bool"], + "const": true, + "brief_description": "Whether it points at anything." + } + } +} diff --git a/docs/data/core/ref.json b/docs/data/core/ref.json new file mode 100644 index 0000000..518a5d6 --- /dev/null +++ b/docs/data/core/ref.json @@ -0,0 +1,47 @@ +{ + "format": 1, + "id": "saw-ref", + "kind": "class", + "name": "ref", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/common.hpp", + "brief_description": "Reference class for easier distinction of references and their referenced types.", + "detailed_description": [ + [ + "Always refers to something, so unlike", + {"name": "ptr", "id": "saw-ptr"}, + "it has no empty state and no validity check." + ], + [ + "Moving is forbidden, since that would invalidate the type, while copying is allowed. It is constexpr throughout, so it can be formed and followed at compile time." + ] + ], + "templates": [ + {"name": "T", "kind": "type"} + ], + "attributes": { + "saw-ref-ref_": { + "id": "saw-ref-ref_", + "name": "ref_", + "type": ["T *"], + "visibility": "private" + } + }, + "functions": { + "saw-ref-ctor": { + "id": "saw-ref-ctor", + "name": "ref", + "type": [], + "parameters": [ + {"name": "ref__", "type": ["T &"]} + ] + }, + "saw-ref-call": { + "id": "saw-ref-call", + "name": "operator()", + "type": ["T &"], + "brief_description": "The referenced object." + } + } +} diff --git a/docs/data/core/ring_buffer.json b/docs/data/core/ring_buffer.json new file mode 100644 index 0000000..eb6a0d0 --- /dev/null +++ b/docs/data/core/ring_buffer.json @@ -0,0 +1,55 @@ +{ + "format": 1, + "id": "saw-ring_buffer", + "kind": "class", + "name": "ring_buffer", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/buffer.hpp", + "brief_description": "Buffer wrapping around if the read cursor caught up.", + "detailed_description": [ + [ + "Fixed capacity, reused in place. Suited to a stream where bytes are produced and consumed continuously, since nothing is allocated after construction." + ], + [ + "The capacity does not grow, so a write beyond what the reader has freed fails with", + {"name": "buffer_exhausted", "id": "saw-err-buffer_exhausted"}, + "rather than resizing." + ] + ], + "bases": [ + [{"name": "buffer", "id": "saw-buffer"}] + ], + "attributes": { + "saw-ring_buffer-write_reached_read_": { + "id": "saw-ring_buffer-write_reached_read_", + "name": "write_reached_read_", + "type": ["bool"], + "visibility": "private", + "brief_description": "Distinguishes a full buffer from an empty one, since both have equal cursors." + } + }, + "functions": { + "saw-ring_buffer-ctor-1": { + "id": "saw-ring_buffer-ctor-1", + "name": "ring_buffer", + "type": [], + "brief_description": "With the default capacity of RING_BUFFER_MAX_SIZE bytes." + }, + "saw-ring_buffer-ctor-2": { + "id": "saw-ring_buffer-ctor-2", + "name": "ring_buffer", + "type": [], + "parameters": [ + {"name": "size", "type": ["size_t"]} + ] + }, + "saw-ring_buffer-size": { + "id": "saw-ring_buffer-size", + "name": "size", + "type": ["size_t"], + "const": true, + "brief_description": "Total capacity, not the amount currently held." + } + } +} diff --git a/docs/data/core/share.json b/docs/data/core/share.json new file mode 100644 index 0000000..4d1df1f --- /dev/null +++ b/docs/data/core/share.json @@ -0,0 +1,25 @@ +{ + "format": 1, + "id": "saw-share", + "kind": "function", + "name": "share", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/common.hpp", + "type": [{"name": "our", "id": "saw-our"}, "< T >"], + "brief_description": "Constructs an object on the heap under shared ownership.", + "detailed_description": [ + [ + "The counterpart of", + {"name": "heap", "id": "saw-heap"}, + "for the cases where ownership is genuinely shared." + ] + ], + "templates": [ + {"name": "T", "kind": "type"}, + {"name": "Args", "kind": "type", "pack": true} + ], + "parameters": [ + {"name": "args", "type": ["Args &&..."], "brief_description": "Forwarded to the constructor of T."} + ] +} diff --git a/docs/data/core/string_literal.json b/docs/data/core/string_literal.json new file mode 100644 index 0000000..4bd6e9b --- /dev/null +++ b/docs/data/core/string_literal.json @@ -0,0 +1,74 @@ +{ + "format": 1, + "id": "saw-string_literal", + "kind": "class", + "name": "string_literal", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/string_literal.hpp", + "brief_description": "Helper object which turns a string literal into a template parameter.", + "detailed_description": [ + [ + "It guarantees compile time uniqueness and thus allows using strings in template parameters. Everything in this codebase which is addressed by name rests on it: struct members, interface functions, and the schema hashes derived from them." + ], + [ + "Because the length is part of the type, two literals of different length are different types, and comparing them is a compile time false rather than an error." + ] + ], + "templates": [ + {"name": "CharT", "kind": "type"}, + {"name": "N", "kind": "non_type", "type": "size_t", "brief_description": "Length including the null terminator."} + ], + "attributes": { + "saw-string_literal-data": { + "id": "saw-string_literal-data", + "name": "data", + "type": ["std::array< CharT, N >"], + "visibility": "public" + } + }, + "functions": { + "saw-string_literal-ctor": { + "id": "saw-string_literal-ctor", + "name": "string_literal", + "type": [], + "brief_description": "From a literal. Copies it character by character so the whole thing is constexpr.", + "parameters": [ + {"name": "input", "type": ["const CharT (&)[N]"]} + ] + }, + "saw-string_literal-view": { + "id": "saw-string_literal-view", + "name": "view", + "type": ["std::string_view"], + "const": true, + "brief_description": "The literal as a view, for the places which compare against runtime strings." + }, + "saw-string_literal-eq": { + "id": "saw-string_literal-eq", + "name": "operator==", + "type": ["bool"], + "const": true, + "brief_description": "Equality. A literal of different length is never equal.", + "parameters": [ + {"name": "rhs", "type": ["const string_literal< CharTR, NR > &"]} + ] + }, + "saw-string_literal-plus": { + "id": "saw-string_literal-plus", + "name": "operator+", + "type": ["string_literal< CharT, N+NR-1 >"], + "const": true, + "brief_description": "Concatenation, dropping the null terminator of the left side.", + "templates": [ + {"name": "NR", "kind": "non_type", "type": "size_t"} + ], + "parameters": [ + {"name": "rhs", "type": ["const string_literal< CharT, NR > &"]} + ] + } + }, + "notes": [ + "The literal operator \"\"_sl builds one from a quoted string." + ] +} diff --git a/docs/data/core/tmpl_concat.json b/docs/data/core/tmpl_concat.json new file mode 100644 index 0000000..8260faa --- /dev/null +++ b/docs/data/core/tmpl_concat.json @@ -0,0 +1,34 @@ +{ + "format": 1, + "id": "saw-tmpl_concat", + "kind": "struct", + "name": "tmpl_concat", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/templates.hpp", + "brief_description": "Concats two groups into one.", + "detailed_description": [ + [ + "Declared only; the work happens in the specializations, one for", + {"name": "tmpl_group", "id": "saw-tmpl_group"}, + "and one for", + {"name": "tmpl_value_group", "id": "saw-tmpl_value_group"}, + "so concatenating anything else is a compile error rather than a surprise." + ], + [ + "The value groups have to agree on their value type, which the specialization enforces by binding it once for both sides." + ] + ], + "templates": [ + {"name": "T", "kind": "type"}, + {"name": "U", "kind": "type"} + ], + "aliases": { + "saw-tmpl_concat-type": { + "id": "saw-tmpl_concat-type", + "name": "type", + "type": ["tmpl_group< T..., U... >"], + "brief_description": "The joined group. Only present on the specializations." + } + } +} diff --git a/docs/data/core/tmpl_group.json b/docs/data/core/tmpl_group.json new file mode 100644 index 0000000..c999492 --- /dev/null +++ b/docs/data/core/tmpl_group.json @@ -0,0 +1,39 @@ +{ + "format": 1, + "id": "saw-tmpl_group", + "kind": "struct", + "name": "tmpl_group", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/templates.hpp", + "brief_description": "A list of types, carried as a type.", + "detailed_description": [ + [ + "Lets a pack be passed around, stored in an alias and handed to another template, which a bare parameter pack cannot. The remote layer uses one to name every schema an interface mentions, and then maps it to a tuple of servers." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "pack": true} + ], + "attributes": { + "saw-tmpl_group-name": { + "id": "saw-tmpl_group-name", + "name": "name", + "type": [{"name": "string_literal", "id": "saw-string_literal"}], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"tmpl_group\"", + "brief_description": "Used when hashing a group." + }, + "saw-tmpl_group-size": { + "id": "saw-tmpl_group-size", + "name": "size", + "type": ["uint64_t"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "sizeof...(T)" + } + } +} diff --git a/docs/data/core/tmpl_reduce.json b/docs/data/core/tmpl_reduce.json new file mode 100644 index 0000000..495738d --- /dev/null +++ b/docs/data/core/tmpl_reduce.json @@ -0,0 +1,31 @@ +{ + "format": 1, + "id": "saw-tmpl_reduce", + "kind": "struct", + "name": "tmpl_reduce", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/reduce_templates.hpp", + "brief_description": "Removes duplicate types from a group.", + "detailed_description": [ + [ + "Turns a", + {"name": "tmpl_group", "id": "saw-tmpl_group"}, + "into one where every type appears once. The remote layer needs it because an interface mentions a schema once per function, while there must be exactly one data server per schema." + ], + [ + "It is also what makes the tuple lookups work: fetching an element by type requires that type to occur exactly once." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "The group to reduce."} + ], + "aliases": { + "saw-tmpl_reduce-type": { + "id": "saw-tmpl_reduce-type", + "name": "type", + "type": ["typename impl::tmpl_group_reduce< T >::reduced_type"], + "brief_description": "The group without duplicates." + } + } +} diff --git a/docs/data/core/tmpl_value_group.json b/docs/data/core/tmpl_value_group.json new file mode 100644 index 0000000..0ebff2c --- /dev/null +++ b/docs/data/core/tmpl_value_group.json @@ -0,0 +1,41 @@ +{ + "format": 1, + "id": "saw-tmpl_value_group", + "kind": "struct", + "name": "tmpl_value_group", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/templates.hpp", + "brief_description": "A list of values of one type, carried as a type.", + "detailed_description": [ + [ + "The value counterpart of", + {"name": "tmpl_group", "id": "saw-tmpl_group"}, + "for packs of numbers such as array dimensions." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "Type of the values."}, + {"name": "values", "kind": "non_type", "type": "T", "pack": true} + ], + "attributes": { + "saw-tmpl_value_group-name": { + "id": "saw-tmpl_value_group-name", + "name": "name", + "type": [{"name": "string_literal", "id": "saw-string_literal"}], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "\"tmpl_value_group\"" + }, + "saw-tmpl_value_group-size": { + "id": "saw-tmpl_value_group-size", + "name": "size", + "type": ["uint64_t"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "sizeof...(values)" + } + } +} diff --git a/docs/data/core/tree.json b/docs/data/core/tree.json new file mode 100644 index 0000000..3236859 --- /dev/null +++ b/docs/data/core/tree.json @@ -0,0 +1,75 @@ +{ + "format": 1, + "id": "saw-tree", + "kind": "class", + "name": "tree", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/tree.hpp", + "brief_description": "A tree of values, tying the recursive knot.", + "detailed_description": [ + [ + "A thin wrapper over a", + {"name": "tree_container", "id": "saw-tree_container"}, + "whose branches hold this very type. The container and the", + {"name": "branch", "id": "saw-branch"}, + "are written against an open Tree parameter precisely so that this class can close it, which keeps the two of them usable for other node types as well." + ], + [ + "This is the type to reach for; the other two are the machinery underneath." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "Leaf value type."} + ], + "attributes": { + "saw-tree-data_": { + "id": "saw-tree-data_", + "name": "data_", + "type": [{"name": "tree_container", "id": "saw-tree_container"}, "< T, tree< T > >"], + "visibility": "private" + } + }, + "functions": { + "saw-tree-reserve": { + "id": "saw-tree-reserve", + "name": "reserve", + "type": ["error_or< void >"], + "brief_description": "Reserves room for branches up front.", + "parameters": [ + {"name": "size", "type": ["std::size_t"]} + ] + }, + "saw-tree-size": { + "id": "saw-tree-size", + "name": "size", + "type": ["size_t"], + "const": true, + "brief_description": "Number of branches directly below this node." + }, + "saw-tree-add-1": { + "id": "saw-tree-add-1", + "name": "add", + "type": ["error_or< size_t >"], + "brief_description": "Adds a branch holding a sub tree and returns its index." + }, + "saw-tree-add-2": { + "id": "saw-tree-add-2", + "name": "add", + "type": ["error_or< size_t >"], + "brief_description": "Adds a branch holding a leaf and returns its index.", + "parameters": [ + {"name": "leaf", "type": ["T"]} + ] + }, + "saw-tree-at": { + "id": "saw-tree-at", + "name": "at", + "type": [{"name": "branch", "id": "saw-branch"}, "< T, tree< T > > &"], + "brief_description": "The branch at an index.", + "parameters": [ + {"name": "i", "type": ["size_t"]} + ] + } + } +} diff --git a/docs/data/core/tree_container.json b/docs/data/core/tree_container.json new file mode 100644 index 0000000..5f01db8 --- /dev/null +++ b/docs/data/core/tree_container.json @@ -0,0 +1,78 @@ +{ + "format": 1, + "id": "saw-tree_container", + "kind": "class", + "name": "tree_container", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/tree.hpp", + "brief_description": "Tree object holding branches.", + "detailed_description": [ + [ + "The name comes from the fact that a tree acts as a node while the", + {"name": "branch", "id": "saw-branch"}, + "class is the edge to a leaf or to other nodes. A container holds the branches, and each branch either has a leaf or another sub tree." + ], + [ + "Growing is done through add, which reports failure as a value instead of throwing, so a tree can be built in code which must not throw." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "Leaf value type."}, + {"name": "Tree", "kind": "type", "brief_description": "The tree type a branch may hold instead of a leaf."} + ], + "attributes": { + "saw-tree_container-children_": { + "id": "saw-tree_container-children_", + "name": "children_", + "type": ["std::vector<", {"name": "branch", "id": "saw-branch"}, "< T, Tree > >"], + "visibility": "private", + "brief_description": "Object holding the branch instances." + } + }, + "functions": { + "saw-tree_container-reserve": { + "id": "saw-tree_container-reserve", + "name": "reserve", + "type": ["error_or< void >"], + "brief_description": "Reserves room for branches up front.", + "parameters": [ + {"name": "siz", "type": ["std::size_t"]} + ] + }, + "saw-tree_container-add-1": { + "id": "saw-tree_container-add-1", + "name": "add", + "type": ["error_or< std::size_t >"], + "brief_description": "Adds a branch holding a leaf.", + "parameters": [ + {"name": "leaf", "type": ["T"]} + ] + }, + "saw-tree_container-add-2": { + "id": "saw-tree_container-add-2", + "name": "add", + "type": ["error_or< std::size_t >"], + "brief_description": "Adds a branch holding a sub tree." + }, + "saw-tree_container-size": { + "id": "saw-tree_container-size", + "name": "size", + "type": ["std::size_t"], + "const": true, + "brief_description": "Number of branches." + }, + "saw-tree_container-at": { + "id": "saw-tree_container-at", + "name": "at", + "type": [{"name": "branch", "id": "saw-branch"}, "< T, Tree > &"], + "brief_description": "The branch at an index.", + "parameters": [ + {"name": "i", "type": ["std::size_t"]} + ] + } + }, + "notes": [ + "Copy is forbidden, move is allowed." + ] +} diff --git a/docs/data/core/void_t.json b/docs/data/core/void_t.json new file mode 100644 index 0000000..c21bc20 --- /dev/null +++ b/docs/data/core/void_t.json @@ -0,0 +1,20 @@ +{ + "format": 1, + "id": "saw-void_t", + "kind": "struct", + "name": "void_t", + "namespace": "saw", + "module": "core", + "header": "modules/core/c++/common.hpp", + "brief_description": "Struct describing a void type.", + "detailed_description": [ + [ + "An empty type standing in for void where a real type is needed. It is what lets", + {"name": "error_or", "id": "saw-error_or"}, + "< void > hold a variant at all, since a variant cannot have a void alternative." + ], + [ + "The substitution happens in fix_void and is undone by unfix_void, so the stand in stays an implementation detail of the templates rather than something a caller writes. Returning make_void is how a function which succeeded but has nothing to say says so." + ] + ] +} diff --git a/docs/data/remote/data_client.json b/docs/data/remote/data_client.json new file mode 100644 index 0000000..fc717b6 --- /dev/null +++ b/docs/data/remote/data_client.json @@ -0,0 +1,31 @@ +{ + "format": 1, + "id": "saw-data_client", + "kind": "class", + "name": "data_client", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer.hpp", + "brief_description": "Handle on a data server of one schema.", + "detailed_description": [ + [ + "The caller side of the transport layer. Values are sent and received through it, and ids are what comes back, since the data itself stays on the", + {"name": "data_server", "id": "saw-data_server"} + ], + [ + "Only declared by the primary template and defined per backend." + ] + ], + "templates": [ + {"name": "Schema", "kind": "type", "brief_description": "Schema of the transported data."}, + {"name": "Encoding", "kind": "type", "brief_description": "Encoding of the transported data."}, + {"name": "Remote", "kind": "type", "brief_description": "Tag type of the backend."} + ], + "specializations": [ + { + "name": "data_client< Schema, Encoding, rmt::Loopback >", + "id": "saw-data_client-loopback", + "brief_description": "Talks to a server in the same process, so nothing is serialized." + } + ] +} diff --git a/docs/data/remote/data_client.loopback.json b/docs/data/remote/data_client.loopback.json new file mode 100644 index 0000000..515209d --- /dev/null +++ b/docs/data/remote/data_client.loopback.json @@ -0,0 +1,112 @@ +{ + "format": 1, + "id": "saw-data_client-loopback", + "kind": "class", + "name": "data_client", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer_loopback.hpp", + "is_special": true, + "specializes": "saw-data_client", + "arguments": ["Schema", "Encoding", "rmt::Loopback"], + "brief_description": "Talks to a data server in the same process.", + "detailed_description": [ + [ + "Every call forwards straight to the server, so nothing is serialized and nothing can fail on the way. Ids are asked for rather than guessed, because the server is the only instance which knows about every client." + ] + ], + "templates": [ + {"name": "Schema", "kind": "type"}, + {"name": "Encoding", "kind": "type"} + ], + "attributes": { + "saw-data_client-loopback-srv_": { + "id": "saw-data_client-loopback-srv_", + "name": "srv_", + "type": ["ptr<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< Schema, Encoding, rmt::Loopback > >"], + "visibility": "private" + } + }, + "functions": { + "saw-data_client-loopback-next_free_id": { + "id": "saw-data_client-loopback-next_free_id", + "name": "next_free_id", + "type": ["error_or< id< Schema > >"], + "brief_description": "Asks the remote for an id which is not in use yet.", + "detailed_description": [ + [ + "Free here, a roundtrip on a backend which is not in process. Worth avoiding when the server can pick the id itself." + ] + ] + }, + "saw-data_client-loopback-send-1": { + "id": "saw-data_client-loopback-send-1", + "name": "send", + "type": ["error_or< id< Schema > >"], + "brief_description": "Sends data to the remote and returns the id it was stored under.", + "parameters": [ + {"name": "dat", "type": ["const data< Schema, Encoding > &"]} + ] + }, + "saw-data_client-loopback-send-2": { + "id": "saw-data_client-loopback-send-2", + "name": "send", + "type": ["error_or< void >"], + "brief_description": "Sends data to the remote and stores it under a specific id.", + "parameters": [ + {"name": "dat", "type": ["const data< Schema, Encoding > &"]}, + {"name": "dat_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_client-loopback-allocate": { + "id": "saw-data_client-loopback-allocate", + "name": "allocate", + "type": ["error_or< id< Schema > >"], + "brief_description": "Preallocates data on the remote without sending a value.", + "parameters": [ + { + "name": "meta", + "type": ["const data< typename meta_schema< Schema >::MetaSchema, Encoding > &"], + "brief_description": "Dimensions and whatever else the schema needs to exist." + } + ] + }, + "saw-data_client-loopback-receive": { + "id": "saw-data_client-loopback-receive", + "name": "receive", + "type": ["conveyor< data< Schema, Encoding > >"], + "brief_description": "Receives the data stored under an id.", + "detailed_description": [ + [ + "A conveyor even though this backend answers immediately, so code written against it keeps working on a backend which has to wait." + ] + ], + "parameters": [ + {"name": "dat_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_client-loopback-erase": { + "id": "saw-data_client-loopback-erase", + "name": "erase", + "type": ["error_or< void >"], + "brief_description": "Erases the data stored under an id.", + "parameters": [ + {"name": "dat_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_client-loopback-find": { + "id": "saw-data_client-loopback-find", + "name": "find", + "type": ["error_or< ptr< data< Schema, Encoding > > >"], + "brief_description": "Returns a pointer to the stored data itself.", + "detailed_description": [ + [ + "An exception for this backend. Here it is safe to use find from the client side, because the data never left the process." + ] + ], + "parameters": [ + {"name": "dat_id", "type": ["id< Schema >"]} + ] + } + } +} diff --git a/docs/data/remote/data_or_id.json b/docs/data/remote/data_or_id.json new file mode 100644 index 0000000..c3152e9 --- /dev/null +++ b/docs/data/remote/data_or_id.json @@ -0,0 +1,78 @@ +{ + "format": 1, + "id": "saw-data_or_id", + "kind": "class", + "name": "data_or_id", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Helper for rpc calls. Either a value or its place on the remote.", + "detailed_description": [ + [ + "A parameter is in one of two states: still here, or already on the remote from an earlier call. This carries both so a call site doesn't have to branch, and so a result can be fed into the next call without a roundtrip." + ], + [ + "Both constructors are implicit, which is what lets a plain value be passed where a call expects one of these." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "Schema of the data."}, + {"name": "Encoding", "kind": "type"} + ], + "attributes": { + "saw-data_or_id-doi_": { + "id": "saw-data_or_id-doi_", + "name": "doi_", + "type": ["std::variant< id< T >, data< T, Encoding > >"], + "visibility": "private", + "brief_description": "Variant representing either the id or the data class." + } + }, + "functions": { + "saw-data_or_id-ctor-1": { + "id": "saw-data_or_id-ctor-1", + "name": "data_or_id", + "type": [], + "brief_description": "Refers to data already on the remote.", + "parameters": [ + {"name": "val", "type": ["const id< T > &"]} + ] + }, + "saw-data_or_id-ctor-2": { + "id": "saw-data_or_id-ctor-2", + "name": "data_or_id", + "type": [], + "brief_description": "Carries data which still has to be sent.", + "parameters": [ + {"name": "val", "type": ["data< T, Encoding >"]} + ] + }, + "saw-data_or_id-is_id": { + "id": "saw-data_or_id-is_id", + "name": "is_id", + "type": ["bool"], + "const": true, + "brief_description": "Checks if this class holds an id." + }, + "saw-data_or_id-is_data": { + "id": "saw-data_or_id-is_data", + "name": "is_data", + "type": ["bool"], + "const": true, + "brief_description": "Checks if this class holds data." + }, + "saw-data_or_id-get_id": { + "id": "saw-data_or_id-get_id", + "name": "get_id", + "type": ["id< T >"], + "const": true, + "brief_description": "Returns the id." + }, + "saw-data_or_id-get_data": { + "id": "saw-data_or_id-get_data", + "name": "get_data", + "type": ["data< T, Encoding > &"], + "brief_description": "Returns a data reference." + } + } +} diff --git a/docs/data/remote/data_server.json b/docs/data/remote/data_server.json new file mode 100644 index 0000000..1be7c93 --- /dev/null +++ b/docs/data/remote/data_server.json @@ -0,0 +1,44 @@ +{ + "format": 1, + "id": "saw-data_server", + "kind": "class", + "name": "data_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer.hpp", + "brief_description": "Owns the data of one schema on one backend.", + "detailed_description": [ + [ + "The transport layer. A data server stores values under ids and is the only thing which knows where they physically live." + ], + [ + "The", + {"name": "rpc_server", "id": "saw-rpc_server"}, + "is an overlay on top of it and never touches the data itself, only the ids. That split is what lets the same interface run against memory, a file or a device." + ] + ], + "templates": [ + { + "name": "Schema", + "kind": "type", + "brief_description": "Schema of the stored data." + }, + { + "name": "Encoding", + "kind": "type", + "brief_description": "Encoding the data is stored in." + }, + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "specializations": [ + { + "name": "data_server< Schema, Encoding, rmt::Loopback >", + "id": "saw-data_server-loopback", + "brief_description": "Keeps the values in a map in this process." + } + ] +} diff --git a/docs/data/remote/data_server.loopback.json b/docs/data/remote/data_server.loopback.json new file mode 100644 index 0000000..daca8e0 --- /dev/null +++ b/docs/data/remote/data_server.loopback.json @@ -0,0 +1,165 @@ +{ + "format": 1, + "id": "saw-data_server-loopback", + "kind": "class", + "name": "data_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer_loopback.hpp", + "is_special": true, + "specializes": "saw-data_server", + "arguments": ["Schema", "Encoding", "rmt::Loopback"], + "brief_description": "Keeps the values of one schema in a map in this process.", + "detailed_description": [ + [ + "Registers itself with its", + {"name": "remote", "id": "saw-remote-loopback"}, + "on construction and deregisters on destruction, so its lifetime is what a client sees as the server being reachable." + ], + [ + "Ids are owned by the server, since it is the only instance which knows about every client." + ] + ], + "templates": [ + {"name": "Schema", "kind": "type"}, + {"name": "Encoding", "kind": "type"} + ], + "attributes": { + "saw-data_server-loopback-class_id": { + "id": "saw-data_server-loopback-class_id", + "name": "class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "{schema_hash::apply(), schema_hash::apply()}", + "brief_description": "Unique key for identifying an underlying data type without using typeid." + }, + "saw-data_server-loopback-values_": { + "id": "saw-data_server-loopback-values_", + "name": "values_", + "type": ["std::unordered_map< uint64_t, data< Schema, Encoding > >"], + "visibility": "private" + }, + "saw-data_server-loopback-next_id_": { + "id": "saw-data_server-loopback-next_id_", + "name": "next_id_", + "type": ["uint64_t"], + "visibility": "private", + "initializer": "0u", + "brief_description": "Counter for handing out ids." + } + }, + "functions": { + "saw-data_server-loopback-get_class_id": { + "id": "saw-data_server-loopback-get_class_id", + "name": "get_class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "const": true, + "override": true, + "brief_description": "Returns the schema id." + }, + "saw-data_server-loopback-next_free_id": { + "id": "saw-data_server-loopback-next_free_id", + "name": "next_free_id", + "type": ["id< Schema >"], + "brief_description": "Hands out the next id which is not in use yet.", + "detailed_description": [ + [ + "The id is not reserved by this call. It is only in use once something is stored under it, so two calls without a store in between return the same id." + ] + ] + }, + "saw-data_server-loopback-send-1": { + "id": "saw-data_server-loopback-send-1", + "name": "send", + "type": ["error_or< void >"], + "brief_description": "Stores a value under an id without taking over the source.", + "detailed_description": [ + ["Fails with already_exists if the id is taken."] + ], + "parameters": [ + {"name": "dat", "type": ["ref< data< Schema, Encoding > >"]}, + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-send-2": { + "id": "saw-data_server-loopback-send-2", + "name": "send", + "type": ["error_or< void >"], + "brief_description": "Stores a value under an id, taking it over.", + "detailed_description": [ + ["Fails with already_exists if the id is taken."] + ], + "parameters": [ + {"name": "dat", "type": ["data< Schema, Encoding >"]}, + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-allocate": { + "id": "saw-data_server-loopback-allocate", + "name": "allocate", + "type": ["error_or< void >"], + "brief_description": "Reserves storage described by the meta schema without sending a value.", + "detailed_description": [ + [ + "The counterpart to sending for backends where the output has to exist before it is written, such as a device buffer." + ] + ], + "parameters": [ + { + "name": "meta", + "type": ["data< typename meta_schema< Schema >::MetaSchema, Encoding >"], + "brief_description": "Dimensions and whatever else the schema needs to exist." + }, + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-receive": { + "id": "saw-data_server-loopback-receive", + "name": "receive", + "type": ["error_or< data< Schema, Encoding > >"], + "brief_description": "Returns a copy of the value stored under an id.", + "detailed_description": [ + ["Fails with not_found if nothing is stored under that id."] + ], + "parameters": [ + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-erase": { + "id": "saw-data_server-loopback-erase", + "name": "erase", + "type": ["error_or< void >"], + "brief_description": "Drops the value stored under an id.", + "detailed_description": [ + ["Fails with not_found if nothing is stored under that id."] + ], + "parameters": [ + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-find": { + "id": "saw-data_server-loopback-find", + "name": "find", + "type": ["error_or< ptr< data< Schema, Encoding > > >"], + "brief_description": "Returns a pointer to the stored value itself.", + "detailed_description": [ + [ + "An exception for this backend. Only meaningful because the data is in process, and a store may invalidate the pointer." + ], + [ + "The", + {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, + "uses it to hand a parameter to an interface function without copying it out of the server first." + ] + ], + "parameters": [ + {"name": "store_id", "type": ["id< Schema >"]} + ] + } + }, + "notes": [ + "Copy and move are forbidden, because the remote holds a pointer to this object while it is registered." + ] +} diff --git a/docs/data/remote/i_data_server.json b/docs/data/remote/i_data_server.json new file mode 100644 index 0000000..ecde59c --- /dev/null +++ b/docs/data/remote/i_data_server.json @@ -0,0 +1,53 @@ +{ + "format": 1, + "id": "saw-i_data_server", + "kind": "class", + "name": "i_data_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer.hpp", + "brief_description": "Registry handle for a data server of unknown schema.", + "detailed_description": [ + [ + "The one place the library erases a type. A", + {"name": "remote", "id": "saw-remote"}, + "holds servers for many schemas in one map, which is only possible if they share a type. The class id recovers what was erased: a caller which knows the schema it wants asks for exactly that one and gets an error if the stored server is a different one." + ], + [ + "The destructor is protected, so nothing can be deleted through this handle." + ] + ], + "templates": [ + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "functions": { + "saw-i_data_server-get_class_id": { + "id": "saw-i_data_server-get_class_id", + "name": "get_class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "const": true, + "virtual": true, + "brief_description": "Schema hash and encoding hash of the server behind this handle." + }, + "saw-i_data_server-cast_to": { + "id": "saw-i_data_server-cast_to", + "name": "cast_to", + "type": ["error_or< ptr< To > >"], + "brief_description": "Recovers the concrete server.", + "detailed_description": [ + ["Fails with invalid_state if the class ids don't match, which is what keeps the erasure honest."] + ], + "templates": [ + { + "name": "To", + "kind": "type", + "brief_description": "The concrete data server expected behind this handle." + } + ] + } + } +} diff --git a/docs/data/remote/i_rpc_server.json b/docs/data/remote/i_rpc_server.json new file mode 100644 index 0000000..b648f4c --- /dev/null +++ b/docs/data/remote/i_rpc_server.json @@ -0,0 +1,53 @@ +{ + "format": 1, + "id": "saw-i_rpc_server", + "kind": "class", + "name": "i_rpc_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Registry handle for an rpc server of unknown interface.", + "detailed_description": [ + [ + "The counterpart of", + {"name": "i_data_server", "id": "saw-i_data_server"}, + "for the rpc layer. It exists so a remote can keep servers of different interfaces in one map and hand back the right one when a client requests it." + ], + [ + "Here the class id is the interface hash together with the encoding hash, so connecting with a different interface than the one being served fails instead of reinterpreting the server." + ] + ], + "templates": [ + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "functions": { + "saw-i_rpc_server-get_class_id": { + "id": "saw-i_rpc_server-get_class_id", + "name": "get_class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "const": true, + "virtual": true, + "brief_description": "Interface hash and encoding hash of the server behind this handle." + }, + "saw-i_rpc_server-cast_to": { + "id": "saw-i_rpc_server-cast_to", + "name": "cast_to", + "type": ["error_or< ptr< To > >"], + "brief_description": "Recovers the concrete server.", + "detailed_description": [ + ["Fails with invalid_state if the class ids don't match."] + ], + "templates": [ + { + "name": "To", + "kind": "type", + "brief_description": "The concrete rpc server expected behind this handle." + } + ] + } + } +} diff --git a/docs/data/remote/loopback.json b/docs/data/remote/loopback.json new file mode 100644 index 0000000..e0d150e --- /dev/null +++ b/docs/data/remote/loopback.json @@ -0,0 +1,15 @@ +{ + "format": 1, + "id": "saw-rmt-loopback", + "kind": "struct", + "name": "Loopback", + "namespace": "saw::rmt", + "module": "remote", + "header": "modules/remote/c++/remote_loopback_base.hpp", + "brief_description": "Tag of the in process backend.", + "detailed_description": [ + [ + "An empty type. It carries no state and is never instantiated; it exists to select the specializations which make up a backend, and it is the argument every class in the remote module is specialized on." + ] + ] +} diff --git a/docs/data/remote/remote.json b/docs/data/remote/remote.json new file mode 100644 index 0000000..3c9e1a6 --- /dev/null +++ b/docs/data/remote/remote.json @@ -0,0 +1,36 @@ +{ + "format": 1, + "id": "saw-remote", + "kind": "class", + "name": "remote", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Reference backend structure.", + "detailed_description": [ + [ + "The primary template is never defined. A backend is added by specializing this class on its tag type, which is the only place the backend itself appears in the public api. An unsupported tag fails with a static_assert instead of a linker error." + ], + [ + "Every", + {"name": "data_server", "id": "saw-data_server"}, + "and", + {"name": "rpc_server", "id": "saw-rpc_server"}, + "of a backend is owned and handed out by its remote, which is also the registry a client searches when it connects." + ] + ], + "templates": [ + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend, e.g. rmt::Loopback." + } + ], + "specializations": [ + { + "name": "remote< rmt::Loopback >", + "id": "saw-remote-loopback", + "brief_description": "In process backend. Data stays where it is and calls are answered inline." + } + ] +} diff --git a/docs/data/remote/remote.loopback.json b/docs/data/remote/remote.loopback.json new file mode 100644 index 0000000..83c2ee8 --- /dev/null +++ b/docs/data/remote/remote.loopback.json @@ -0,0 +1,182 @@ +{ + "format": 1, + "id": "saw-remote-loopback", + "kind": "class", + "name": "remote", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback_base.hpp", + "is_special": true, + "specializes": "saw-remote", + "arguments": ["rmt::Loopback"], + "brief_description": "In process backend.", + "detailed_description": [ + [ + "The reference implementation every other backend is measured against. Nothing is serialized and nothing is copied across a boundary, so what remains is the bookkeeping every backend has to do." + ], + [ + "Servers are registered under the address they listen on together with their class id, so a client asking for a schema on an address finds the one server which owns it." + ] + ], + "examples": [ + { + "title": "Serving an interface and calling it", + "description": [ + [ + "The whole flow on one address: bring up the data servers, bind an interface to them, connect, call. Error handling is left out, but note that every error_or is kept in a named variable, because get_value hands back a reference into it." + ], + [ + "The data servers have to exist before", + {"name": "rpc_listen", "id": "saw-remote-loopback-rpc_listen"}, + "is called, since that is where the parameter and the answer live." + ] + ], + "language": "cpp", + "code": "using TestInterface = schema::Interface<\n\tschema::Member, \"foo\">\n>;\n\nevent_loop loop;\nwait_scope wait{loop};\n\nremote rmt;\n\nauto eo_addr = rmt.parse_address(0u);\nauto& addr = eo_addr.get_value();\n\n/// The transport layer, one server per schema the interface mentions.\nauto eo_u32_srv = rmt.data_listen(*addr);\nauto eo_i64_srv = rmt.data_listen(*addr);\n\nauto iface = interface_factory::create(\n\t[](data input)\n\t\t-> error_or>\n\t{\n\t\tdata rv;\n\t\trv.set(input.get() * 2);\n\t\treturn rv;\n\t});\n\nauto eo_rpc_srv = rmt.rpc_listen(*addr, std::move(iface));\n\n/// The overlay on top of it.\nauto cvr_client = rmt.rpc_connect(*addr);\nauto eo_client = cvr_client.take();\nauto& client = eo_client.get_value();\n\ndata inp{21};\n\nauto cvr_result = client.call<\"foo\">(std::move(inp));\nauto eo_result = cvr_result.take();\nauto& result = eo_result.get_value();\n\n/// The answer never left the server. result only knows the id it picked.\nauto eo_value = result.wait(wait);\n/// eo_value.get_value().get() == 42\n" + } + ], + "attributes": { + "saw-remote-loopback-registered_data_servers_": { + "id": "saw-remote-loopback-registered_data_servers_", + "name": "registered_data_servers_", + "type": ["std::map< key_t, ptr<", {"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > > >"], + "visibility": "private", + "brief_description": "Keyed by address id, schema hash and encoding hash." + }, + "saw-remote-loopback-registered_rpc_servers_": { + "id": "saw-remote-loopback-registered_rpc_servers_", + "name": "registered_rpc_servers_", + "type": ["std::map< key_t, ptr<", {"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > > >"], + "visibility": "private", + "brief_description": "Keyed by address id, interface hash and encoding hash." + } + }, + "functions": { + "saw-remote-loopback-parse_address": { + "id": "saw-remote-loopback-parse_address", + "name": "parse_address", + "type": ["error_or< own<", {"name": "remote_address", "id": "saw-remote_address-loopback"}, "< rmt::Loopback > > >"], + "brief_description": "Resolves an address for the remote.", + "parameters": [ + { + "name": "id", + "type": ["data< schema::UInt64 >"], + "brief_description": "Identifier standing in for what a network address would be." + } + ] + }, + "saw-remote-loopback-data_listen": { + "id": "saw-remote-loopback-data_listen", + "name": "data_listen", + "type": ["error_or< own<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< Schema, Encode, rmt::Loopback > > >"], + "brief_description": "Starts a data server for one schema on an address.", + "detailed_description": [ + [ + "Fails with already_exists if a server for the same schema and encoding is already bound to that address. The returned server registers itself and stays reachable until it is destroyed." + ] + ], + "templates": [ + {"name": "Schema", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-data_connect": { + "id": "saw-remote-loopback-data_connect", + "name": "data_connect", + "type": ["conveyor<", {"name": "data_client", "id": "saw-data_client-loopback"}, "< Schema, Encode, rmt::Loopback > >"], + "brief_description": "Connects to a data server.", + "detailed_description": [ + ["Fails with not_found if nothing listens for that schema on that address."] + ], + "templates": [ + {"name": "Schema", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-rpc_listen": { + "id": "saw-remote-loopback-rpc_listen", + "name": "rpc_listen", + "type": ["error_or< own<", {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, "< Iface, Encode, rmt::Loopback > > >"], + "brief_description": "Starts an rpc server for an interface on an address.", + "detailed_description": [ + [ + "Every schema the interface mentions needs a data server on the same address beforehand, since that is where parameters and responses live. A missing one fails the call with not_found." + ] + ], + "templates": [ + {"name": "Iface", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "parameters": [ + {"name": "addr", "type": ["remote_address< rmt::Loopback > &"]}, + { + "name": "iface", + "type": ["typename rpc_server< Iface, Encode, rmt::Loopback >::InterfaceT"], + "brief_description": "The implementations backing the interface." + } + ] + }, + "saw-remote-loopback-rpc_connect": { + "id": "saw-remote-loopback-rpc_connect", + "name": "rpc_connect", + "type": ["conveyor<", {"name": "rpc_client", "id": "saw-rpc_client-loopback"}, "< Iface, Encode, rmt::Loopback > >"], + "brief_description": "Connects to an rpc server.", + "detailed_description": [ + ["Defined in remote_loopback.hpp, since the client has to be a complete type at that point."] + ], + "templates": [ + {"name": "Iface", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-register_data_server": { + "id": "saw-remote-loopback-register_data_server", + "name": "register_data_server", + "type": ["error_or< void >"], + "brief_description": "Internal. Called by a data server on construction.", + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, + {"name": "srv", "type": [{"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-deregister_data_server": { + "id": "saw-remote-loopback-deregister_data_server", + "name": "deregister_data_server", + "type": ["error_or< void >"], + "brief_description": "Internal. Called by a data server on destruction.", + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, + {"name": "srv", "type": [{"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-register_rpc_server": { + "id": "saw-remote-loopback-register_rpc_server", + "name": "register_rpc_server", + "type": ["error_or< void >"], + "brief_description": "Internal. Called by an rpc server on construction.", + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, + {"name": "srv", "type": [{"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-deregister_rpc_server": { + "id": "saw-remote-loopback-deregister_rpc_server", + "name": "deregister_rpc_server", + "type": ["error_or< void >"], + "brief_description": "Internal. Called by an rpc server on destruction.", + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, + {"name": "srv", "type": [{"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > &"]} + ] + } + } +} diff --git a/docs/data/remote/remote_address.json b/docs/data/remote/remote_address.json new file mode 100644 index 0000000..783527c --- /dev/null +++ b/docs/data/remote/remote_address.json @@ -0,0 +1,34 @@ +{ + "format": 1, + "id": "saw-remote_address", + "kind": "class", + "name": "remote_address", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Representation of a remote. Partially similar to a network address.", + "detailed_description": [ + [ + "What an address is depends entirely on the backend. A loopback address is a number, a file address is a path, a socket address is host and port." + ], + [ + "Addresses are produced by the parse_address of their own", + {"name": "remote", "id": "saw-remote"}, + "and are meaningless to any other backend." + ] + ], + "templates": [ + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "specializations": [ + { + "name": "remote_address< rmt::Loopback >", + "id": "saw-remote_address-loopback", + "brief_description": "A plain identifier, since there is nothing to address but the process itself." + } + ] +} diff --git a/docs/data/remote/remote_address.loopback.json b/docs/data/remote/remote_address.loopback.json new file mode 100644 index 0000000..ec7d5e4 --- /dev/null +++ b/docs/data/remote/remote_address.loopback.json @@ -0,0 +1,43 @@ +{ + "format": 1, + "id": "saw-remote_address-loopback", + "kind": "class", + "name": "remote_address", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback_base.hpp", + "is_special": true, + "specializes": "saw-remote_address", + "arguments": ["rmt::Loopback"], + "brief_description": "Address of an in process endpoint.", + "detailed_description": [ + [ + "There is nothing to address but the process itself, so the address is a plain number. It still has to exist, because it is the component which separates two endpoints serving the same schema." + ] + ], + "attributes": { + "saw-remote_address-loopback-addr_id_": { + "id": "saw-remote_address-loopback-addr_id_", + "name": "addr_id_", + "type": ["data< schema::UInt64 >"], + "visibility": "private" + } + }, + "functions": { + "saw-remote_address-loopback-ctor": { + "id": "saw-remote_address-loopback-ctor", + "name": "remote_address", + "type": [], + "parameters": [ + {"name": "addr_id__", "type": ["data< schema::UInt64 >"]} + ] + }, + "saw-remote_address-loopback-get_address_id": { + "id": "saw-remote_address-loopback-get_address_id", + "name": "get_address_id", + "type": ["const data< schema::UInt64 > &"], + "const": true, + "brief_description": "The identifier this address stands for." + } + } +} diff --git a/docs/data/remote/remote_data.json b/docs/data/remote/remote_data.json new file mode 100644 index 0000000..1086ca4 --- /dev/null +++ b/docs/data/remote/remote_data.json @@ -0,0 +1,30 @@ +{ + "format": 1, + "id": "saw-remote_data", + "kind": "class", + "name": "remote_data", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Representing data on the remote.", + "detailed_description": [ + [ + "What an rpc call hands back. It is an id plus a way to resolve it, not the value, so a result can be passed into the next call without ever being pulled across." + ], + [ + "Only declared by the primary template and defined per backend." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "Schema of the data on the remote."}, + {"name": "Encoding", "kind": "type"}, + {"name": "Remote", "kind": "type", "brief_description": "Tag type of the backend."} + ], + "specializations": [ + { + "name": "remote_data< T, Encoding, rmt::Loopback >", + "id": "saw-remote_data-loopback", + "brief_description": "Resolves immediately, since the call it came from was answered inline." + } + ] +} diff --git a/docs/data/remote/remote_data.loopback.json b/docs/data/remote/remote_data.loopback.json new file mode 100644 index 0000000..32786aa --- /dev/null +++ b/docs/data/remote/remote_data.loopback.json @@ -0,0 +1,70 @@ +{ + "format": 1, + "id": "saw-remote_data-loopback", + "kind": "class", + "name": "remote_data", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback.hpp", + "is_special": true, + "specializes": "saw-remote_data", + "arguments": ["T", "Encoding", "rmt::Loopback"], + "brief_description": "Handle for data which is stored on an in process remote.", + "detailed_description": [ + [ + "The result of an rpc call. Resolving it goes back through the data layer rather than through the rpc layer, which is why the handle carries the data server and not the rpc server." + ], + [ + "This backend answers calls inline, so the data is already present whenever the call succeeded and waiting costs nothing." + ] + ], + "templates": [ + {"name": "T", "kind": "type"}, + {"name": "Encoding", "kind": "type"} + ], + "attributes": { + "saw-remote_data-loopback-id_": { + "id": "saw-remote_data-loopback-id_", + "name": "id_", + "type": ["id< T >"], + "visibility": "private" + }, + "saw-remote_data-loopback-srv_": { + "id": "saw-remote_data-loopback-srv_", + "name": "srv_", + "type": ["ptr<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< T, Encoding, rmt::Loopback > >"], + "visibility": "private" + } + }, + "functions": { + "saw-remote_data-loopback-get_id": { + "id": "saw-remote_data-loopback-get_id", + "name": "get_id", + "type": ["const id< T > &"], + "const": true, + "brief_description": "Id of the data on the remote.", + "detailed_description": [ + ["Hand this to the next call to keep a result where it is instead of pulling it across."] + ] + }, + "saw-remote_data-loopback-wait": { + "id": "saw-remote_data-loopback-wait", + "name": "wait", + "type": ["error_or< data< T, Encoding > >"], + "brief_description": "Waits until the data arrives.", + "parameters": [ + { + "name": "wait", + "type": ["wait_scope &"], + "brief_description": "Unused here, since there is nothing to wait for." + } + ] + }, + "saw-remote_data-loopback-on_receive": { + "id": "saw-remote_data-loopback-on_receive", + "name": "on_receive", + "type": ["conveyor< data< T, Encoding > >"], + "brief_description": "Asynchronously waits for the result." + } + } +} diff --git a/docs/data/remote/rpc_client.json b/docs/data/remote/rpc_client.json new file mode 100644 index 0000000..b9dd5ca --- /dev/null +++ b/docs/data/remote/rpc_client.json @@ -0,0 +1,30 @@ +{ + "format": 1, + "id": "saw-rpc_client", + "kind": "class", + "name": "rpc_client", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Client RPC reference structure.", + "detailed_description": [ + [ + "The caller side of the overlay. Parameters and return values are moved by the data clients; the rpc layer only ties ids to a function call on the remote." + ], + [ + "Only declared by the primary template and defined per backend." + ] + ], + "templates": [ + {"name": "Iface", "kind": "type", "brief_description": "Interface schema being called."}, + {"name": "Encoding", "kind": "type", "brief_description": "Encoding of the parameters and responses."}, + {"name": "Remote", "kind": "type", "brief_description": "Tag type of the backend."} + ], + "specializations": [ + { + "name": "rpc_client< Iface, Encoding, rmt::Loopback >", + "id": "saw-rpc_client-loopback", + "brief_description": "Calls a server in the same process, which answers before the call returns." + } + ] +} diff --git a/docs/data/remote/rpc_client.loopback.json b/docs/data/remote/rpc_client.loopback.json new file mode 100644 index 0000000..c305255 --- /dev/null +++ b/docs/data/remote/rpc_client.loopback.json @@ -0,0 +1,136 @@ +{ + "format": 1, + "id": "saw-rpc_client-loopback", + "kind": "class", + "name": "rpc_client", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback.hpp", + "is_special": true, + "specializes": "saw-rpc_client", + "arguments": ["Iface", "Encoding", "rmt::Loopback"], + "brief_description": "Calls an rpc server in the same process.", + "detailed_description": [ + [ + "Holds one", + {"name": "data_client", "id": "saw-data_client-loopback"}, + "per schema the interface mentions, all of them handles on the data servers the server is already bound to. A parameter which is not on the remote yet goes through the data layer first, and only its id reaches the rpc layer." + ] + ], + "templates": [ + {"name": "Iface", "kind": "type"}, + {"name": "Encoding", "kind": "type"} + ], + "aliases": { + "saw-rpc_client-loopback-ServerT": { + "id": "saw-rpc_client-loopback-ServerT", + "name": "ServerT", + "type": [{"name": "rpc_server", "id": "saw-rpc_server-loopback"}, "< Iface, Encoding, rmt::Loopback >"] + }, + "saw-rpc_client-loopback-TypeGroup": { + "id": "saw-rpc_client-loopback-TypeGroup", + "name": "TypeGroup", + "type": ["typename schema_iface_type_group< Iface >::Type"], + "brief_description": "Every schema the interface mentions, reduced to unique types." + }, + "saw-rpc_client-loopback-DataClients": { + "id": "saw-rpc_client-loopback-DataClients", + "name": "DataClients", + "type": ["std::tuple<", {"name": "data_client", "id": "saw-data_client-loopback"}, "< T, Encoding, rmt::Loopback >... >"], + "brief_description": "One data client per schema in the type group." + } + }, + "functions": { + "saw-rpc_client-loopback-get_data_client": { + "id": "saw-rpc_client-loopback-get_data_client", + "name": "get_data_client", + "type": [{"name": "data_client", "id": "saw-data_client-loopback"}, "< IdT, Encoding, rmt::Loopback > &"], + "brief_description": "The data client of one of the interface types.", + "detailed_description": [ + ["Useful when a parameter is meant to be sent once and reused in several calls."] + ], + "templates": [ + {"name": "IdT", "kind": "type", "brief_description": "One of the schemas the interface mentions."} + ], + "examples": [ + { + "title": "Sending a parameter once and calling with it twice", + "description": [ + [ + "Handing a value to call sends it every time. Sending it once and passing the id instead keeps it on the remote, which is the point of", + {"name": "data_or_id", "id": "saw-data_or_id"} + ] + ], + "language": "cpp", + "code": "data inp{21};\n\nauto& u32_client = client.get_data_client();\nauto eo_param = u32_client.send(inp);\nauto param = eo_param.get_value();\n\n/// Both calls refer to the same value on the remote.\nauto first = client.call<\"foo\">(param).take();\nauto second = client.call<\"foo\">(param).take();\n" + } + ] + }, + "saw-rpc_client-loopback-request_data": { + "id": "saw-rpc_client-loopback-request_data", + "name": "request_data", + "type": [{"name": "remote_data", "id": "saw-remote_data-loopback"}, "< IdT, Encoding, rmt::Loopback >"], + "brief_description": "Requests the data from the remote.", + "templates": [ + {"name": "IdT", "kind": "type"} + ], + "parameters": [ + {"name": "dat_id", "type": ["id< IdT >"]} + ] + }, + "saw-rpc_client-loopback-call-1": { + "id": "saw-rpc_client-loopback-call-1", + "name": "call", + "type": ["conveyor<", {"name": "remote_data", "id": "saw-remote_data-loopback"}, "< ResponseT, Encoding, rmt::Loopback > >"], + "brief_description": "Calls a function on the remote.", + "detailed_description": [ + [ + "The parameter is either already present on the remote, in which case only its id is handed over, or it is sent through the data layer first." + ], + [ + "The id of the response is picked by the server and travels back with the answer, so this is asynchronous in the id as well, not only in the data." + ] + ], + "templates": [ + { + "name": "Name", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member to call." + } + ], + "parameters": [ + { + "name": "input", + "type": [{"name": "data_or_id", "id": "saw-data_or_id"}, "< RequestT, Encoding >"], + "brief_description": "The parameter, or the id of one already on the remote." + } + ] + }, + "saw-rpc_client-loopback-call-2": { + "id": "saw-rpc_client-loopback-call-2", + "name": "call", + "type": ["conveyor<", {"name": "remote_data", "id": "saw-remote_data-loopback"}, "< ResponseT, Encoding, rmt::Loopback > >"], + "brief_description": "Calls a function and stores the response in a slot allocated beforehand.", + "templates": [ + { + "name": "Name", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member to call." + } + ], + "parameters": [ + { + "name": "input", + "type": [{"name": "data_or_id", "id": "saw-data_or_id"}, "< RequestT, Encoding >"] + }, + { + "name": "resp_id", + "type": ["id< ResponseT >"], + "brief_description": "Slot the answer has to end up in." + } + ] + } + } +} diff --git a/docs/data/remote/rpc_function_id.json b/docs/data/remote/rpc_function_id.json new file mode 100644 index 0000000..b5788f4 --- /dev/null +++ b/docs/data/remote/rpc_function_id.json @@ -0,0 +1,40 @@ +{ + "format": 1, + "id": "saw-rpc_function_id", + "kind": "struct", + "name": "rpc_function_id", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Identifier of an interface function on the wire.", + "detailed_description": [ + [ + "Keyed on the member name rather than on its index, so reordering an interface doesn't silently rebind calls between two versions." + ], + [ + "This is the number a backend hands to call_by_id of the", + {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, + "when the called function arrives as data instead of as a template argument." + ] + ], + "templates": [ + { + "name": "Lit", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member." + } + ], + "attributes": { + "saw-rpc_function_id-value": { + "id": "saw-rpc_function_id-value", + "name": "value", + "type": ["uint32_t"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "hash_literal::apply(0u)", + "brief_description": "crc32 of the member name." + } + } +} diff --git a/docs/data/remote/rpc_server.json b/docs/data/remote/rpc_server.json new file mode 100644 index 0000000..eb21128 --- /dev/null +++ b/docs/data/remote/rpc_server.json @@ -0,0 +1,66 @@ +{ + "format": 1, + "id": "saw-rpc_server", + "kind": "class", + "name": "rpc_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Implementation of a remote server on the backend.", + "detailed_description": [ + [ + "Holds the interface whose functions clients call." + ], + [ + "The server never receives a parameter as data, only the id of a value already sitting in the matching", + {"name": "data_server", "id": "saw-data_server"}, + "which is what keeps the rpc layer an overlay on the transport layer." + ] + ], + "templates": [ + { + "name": "Iface", + "kind": "type", + "brief_description": "Interface schema the server provides." + }, + { + "name": "Encoding", + "kind": "type", + "brief_description": "Encoding of the parameters and responses." + }, + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "attributes": { + "saw-rpc_server-iface_": { + "id": "saw-rpc_server-iface_", + "name": "iface_", + "type": ["interface< Iface, Encoding >"], + "visibility": "private" + } + }, + "functions": { + "saw-rpc_server-ctor": { + "id": "saw-rpc_server-ctor", + "name": "rpc_server", + "type": [], + "parameters": [ + { + "name": "iface", + "type": ["interface< Iface, Encoding >"], + "brief_description": "The functions this server answers with." + } + ] + } + }, + "specializations": [ + { + "name": "rpc_server< Iface, Encode, rmt::Loopback >", + "id": "saw-rpc_server-loopback", + "brief_description": "Answers calls inline, resolving ids against the data servers of the same address." + } + ] +} diff --git a/docs/data/remote/rpc_server.loopback.json b/docs/data/remote/rpc_server.loopback.json new file mode 100644 index 0000000..3f43ab2 --- /dev/null +++ b/docs/data/remote/rpc_server.loopback.json @@ -0,0 +1,180 @@ +{ + "format": 1, + "id": "saw-rpc_server-loopback", + "kind": "class", + "name": "rpc_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback.hpp", + "is_special": true, + "specializes": "saw-rpc_server", + "arguments": ["Iface", "Encode", "rmt::Loopback"], + "brief_description": "Answers calls inline against the data servers of its address.", + "detailed_description": [ + [ + "Translates a call on an id into a call on the local interface: it looks the parameter up in the data server of the request schema, calls the function, and stores the answer in the data server of the response schema." + ], + [ + "The data itself never passes through the rpc layer. Registering with its", + {"name": "remote", "id": "saw-remote-loopback"}, + "on construction is what makes rpc_connect able to find it." + ] + ], + "templates": [ + {"name": "Iface", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "aliases": { + "saw-rpc_server-loopback-InterfaceT": { + "id": "saw-rpc_server-loopback-InterfaceT", + "name": "InterfaceT", + "type": ["interface< Iface, Encode >"], + "brief_description": "The implementations backing the interface." + }, + "saw-rpc_server-loopback-TypeGroup": { + "id": "saw-rpc_server-loopback-TypeGroup", + "name": "TypeGroup", + "type": ["typename schema_iface_type_group< Iface >::Type"], + "brief_description": "Every schema the interface mentions, reduced to unique types." + }, + "saw-rpc_server-loopback-DataServers": { + "id": "saw-rpc_server-loopback-DataServers", + "name": "DataServers", + "type": ["std::tuple< ptr<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< T, Encode, rmt::Loopback > >... >"], + "brief_description": "One data server pointer per schema in the type group." + } + }, + "attributes": { + "saw-rpc_server-loopback-class_id": { + "id": "saw-rpc_server-loopback-class_id", + "name": "class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "{schema_hash::apply(), schema_hash::apply()}", + "brief_description": "Identifies which interface this server provides." + }, + "saw-rpc_server-loopback-iface_": { + "id": "saw-rpc_server-loopback-iface_", + "name": "iface_", + "type": ["InterfaceT"], + "visibility": "private" + }, + "saw-rpc_server-loopback-dat_srvs_": { + "id": "saw-rpc_server-loopback-dat_srvs_", + "name": "dat_srvs_", + "type": ["DataServers"], + "visibility": "private" + } + }, + "functions": { + "saw-rpc_server-loopback-get_class_id": { + "id": "saw-rpc_server-loopback-get_class_id", + "name": "get_class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "const": true, + "override": true, + "brief_description": "Returns the interface id." + }, + "saw-rpc_server-loopback-get_data_servers": { + "id": "saw-rpc_server-loopback-get_data_servers", + "name": "get_data_servers", + "type": ["const DataServers &"], + "const": true, + "brief_description": "The data servers this rpc server moves its parameters and responses through." + }, + "saw-rpc_server-loopback-call-1": { + "id": "saw-rpc_server-loopback-call-1", + "name": "call", + "type": ["error_or< id< ResponseT > >"], + "brief_description": "Calls a function and lets the server decide where the response is stored.", + "detailed_description": [ + [ + "A client cannot know which ids are free without asking, so this is the variant which costs no roundtrip beforehand." + ], + [ + "The slot is picked after the function returned, which is the latest and therefore most accurate moment." + ] + ], + "templates": [ + { + "name": "Lit", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member to call." + } + ], + "parameters": [ + { + "name": "id_param", + "type": ["id< typename schema_member_type< Lit, Iface >::type::RequestT >"], + "brief_description": "Id of a value already sitting in the request data server." + } + ] + }, + "saw-rpc_server-loopback-call-2": { + "id": "saw-rpc_server-loopback-call-2", + "name": "call", + "type": ["error_or< void >"], + "brief_description": "Calls a function and stores the response in a slot allocated beforehand.", + "detailed_description": [ + [ + "Meant for backends where the output exists before the call, such as a device buffer allocated on the remote." + ] + ], + "templates": [ + { + "name": "Lit", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member to call." + } + ], + "parameters": [ + {"name": "id_param", "type": ["id< typename schema_member_type< Lit, Iface >::type::RequestT >"]}, + { + "name": "id_resp", + "type": ["id< typename schema_member_type< Lit, Iface >::type::ResponseT >"], + "brief_description": "Slot the answer has to end up in." + } + ] + }, + "saw-rpc_server-loopback-call_by_id-1": { + "id": "saw-rpc_server-loopback-call_by_id-1", + "name": "call_by_id", + "type": ["error_or< uint64_t >"], + "brief_description": "Calls a function which is only known at runtime.", + "detailed_description": [ + [ + "The entry point for every backend which transports the call itself. The ids are untyped here, since such a backend only knows the function id and a number." + ], + [ + "The id the response ended up in is meant to travel back in the reply. Fails with not_found if no interface member carries that function id." + ] + ], + "parameters": [ + { + "name": "func_id", + "type": ["uint32_t"], + "brief_description": "rpc_function_id of the member name." + }, + {"name": "id_param", "type": ["uint64_t"]} + ] + }, + "saw-rpc_server-loopback-call_by_id-2": { + "id": "saw-rpc_server-loopback-call_by_id-2", + "name": "call_by_id", + "type": ["error_or< void >"], + "brief_description": "Runtime call into a slot the caller allocated beforehand.", + "parameters": [ + {"name": "func_id", "type": ["uint32_t"]}, + {"name": "id_param", "type": ["uint64_t"]}, + {"name": "id_resp", "type": ["uint64_t"]} + ] + } + }, + "notes": [ + "Copy and move are forbidden, because the remote holds a pointer to this object while it is registered." + ] +} diff --git a/docs/entity.schema.json b/docs/entity.schema.json new file mode 100644 index 0000000..de85b95 --- /dev/null +++ b/docs/entity.schema.json @@ -0,0 +1,269 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "forstio/docs_oos/entity.schema.json", + "title": "forstio out of source api entity", + "description": "One file per entity, written by hand instead of derived from doxygen. A primary template and each of its specializations are separate files with their own id; the primary links the specializations, which the tree renders as a sublist underneath it. The generator collects every file under docs_oos/data into one map keyed by id, which is the shape the rst templates consume.", + "type": "object", + "required": ["format", "id", "kind", "name", "namespace", "header"], + "additionalProperties": false, + "properties": { + "format": { + "const": 1 + }, + "id": { + "type": "string", + "pattern": "^[a-z0-9_]+(-[a-z0-9_]+)*$", + "description": "Stable identifier. Becomes the rst file name, the label and the :ref: target, so it replaces the doxygen refid. Convention: namespace and name joined by a dash, with a slug for a specialization, e.g. saw-data_server and saw-data_server-loopback." + }, + "kind": { + "enum": ["class", "struct", "alias", "function", "variable", "enum", "concept", "namespace", "macro"] + }, + "name": { + "type": "string", + "description": "Unqualified name without namespace and without template arguments. A specialization carries the same name as its primary." + }, + "namespace": { + "type": "string", + "description": "Where it lives, e.g. saw or saw::rmt. Kept apart from the name so the heading stays readable and the namespace can still be shown." + }, + "module": { + "type": "string", + "description": "Module directory, e.g. remote." + }, + "header": { + "type": "string", + "description": "Declaring header, relative to the repository root." + }, + "brief_description": { + "type": "string" + }, + "detailed_description": { + "$ref": "#/$defs/paragraphs" + }, + "type": { + "$ref": "#/$defs/type_tuple", + "description": "Only for an alias, variable or function entity: the aliased type, the variable type, or the return type. A class has no type of its own." + }, + "parameters": { + "type": "array", + "description": "Only for a function entity.", + "items": {"$ref": "#/$defs/parameter"} + }, + "templates": { + "type": "array", + "description": "Template parameters. A partial specialization lists the parameters it introduces, not the ones it binds.", + "items": {"$ref": "#/$defs/template_parameter"} + }, + "bases": { + "type": "array", + "description": "Base classes, for the few places which use inheritance. Entries are type tuples, so a base which is itself documented links.", + "items": {"$ref": "#/$defs/type_tuple"} + }, + "is_special": { + "type": "boolean", + "default": false, + "description": "True on a specialization. The index skips these; they are reachable through their primary." + }, + "specializes": { + "type": "string", + "description": "Only on a specialization: id of the primary." + }, + "arguments": { + "type": "array", + "description": "Only on a specialization: the arguments it binds, in order, as written.", + "items": {"type": "string"} + }, + "specializations": { + "type": "array", + "description": "Only on a primary. Rendered as the sublist under the entity.", + "items": {"$ref": "#/$defs/specialization_link"} + }, + "aliases": { + "type": "object", + "description": "Member type aliases keyed by id. These carry weight here, e.g. DataServers or InterfaceT.", + "additionalProperties": {"$ref": "#/$defs/alias"} + }, + "attributes": { + "type": "object", + "description": "Data members keyed by id.", + "additionalProperties": {"$ref": "#/$defs/attribute"} + }, + "functions": { + "type": "object", + "description": "Member functions keyed by id. Overloads get distinct ids.", + "additionalProperties": {"$ref": "#/$defs/function"} + }, + "examples": { + "type": "array", + "description": "Usage examples for the entity as a whole.", + "items": {"$ref": "#/$defs/example"} + }, + "notes": { + "type": "array", + "description": "Remarks which don't belong to a single member.", + "items": {"type": "string"} + } + }, + "$defs": { + "example": { + "type": "object", + "required": ["code"], + "additionalProperties": false, + "properties": { + "title": {"type": "string"}, + "language": { + "type": "string", + "default": "cpp", + "description": "Rendered as the code block language." + }, + "description": {"$ref": "#/$defs/paragraphs"}, + "code": { + "type": "string", + "description": "Source as a single string with newlines. Error handling may be left out for readability, but then the description has to say so." + } + } + }, + "paragraphs": { + "type": "array", + "description": "A list of paragraphs. Each paragraph is a list of fragments: plain strings, or a reference object which renders as a link to another entity.", + "items": { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + {"$ref": "#/$defs/type_ref"} + ] + } + } + }, + "type_ref": { + "type": "object", + "required": ["name", "id"], + "additionalProperties": false, + "properties": { + "name": {"type": "string", "description": "Text to display."}, + "id": {"type": "string", "description": "id of the entity being linked."} + } + }, + "type_tuple": { + "type": "array", + "description": "A type as a sequence of fragments, so the parts which are entities link and the rest stays text.", + "items": { + "oneOf": [ + {"type": "string"}, + {"$ref": "#/$defs/type_ref"} + ] + } + }, + "parameter": { + "type": "object", + "required": ["name", "type"], + "additionalProperties": false, + "properties": { + "name": {"type": "string"}, + "type": {"$ref": "#/$defs/type_tuple"}, + "default": {"type": "string"}, + "brief_description": {"type": "string"} + } + }, + "template_parameter": { + "type": "object", + "required": ["name", "kind"], + "additionalProperties": false, + "properties": { + "name": {"type": "string"}, + "kind": { + "enum": ["type", "non_type", "template"], + "description": "type for class/typename, non_type for a value parameter such as uint64_t N or string_literal Lit." + }, + "type": { + "type": "string", + "description": "Required for non_type, e.g. uint64_t or string_literal." + }, + "pack": {"type": "boolean", "default": false}, + "default": {"type": "string", "description": "Default argument as written."}, + "brief_description": {"type": "string"} + } + }, + "specialization_link": { + "type": "object", + "required": ["name", "id"], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "Specialized name as it should read in the sublist, e.g. data_server< Schema, Encoding, rmt::Loopback >." + }, + "id": {"type": "string"}, + "brief_description": { + "type": "string", + "description": "One line, so the sublist says what the specialization is for without opening it." + } + } + }, + "alias": { + "type": "object", + "required": ["id", "name", "type"], + "additionalProperties": false, + "properties": { + "id": {"type": "string"}, + "name": {"type": "string"}, + "type": {"$ref": "#/$defs/type_tuple"}, + "visibility": {"enum": ["public", "protected", "private"], "default": "public"}, + "brief_description": {"type": "string"}, + "detailed_description": {"$ref": "#/$defs/paragraphs"} + } + }, + "attribute": { + "type": "object", + "required": ["id", "name", "type"], + "additionalProperties": false, + "properties": { + "id": {"type": "string"}, + "name": {"type": "string"}, + "type": {"$ref": "#/$defs/type_tuple"}, + "visibility": {"enum": ["public", "protected", "private"], "default": "private"}, + "static": {"type": "boolean", "default": false}, + "const": {"type": "boolean", "default": false}, + "constexpr": {"type": "boolean", "default": false}, + "initializer": {"type": "string", "default": ""}, + "brief_description": {"type": "string"}, + "detailed_description": {"$ref": "#/$defs/paragraphs"} + } + }, + "function": { + "type": "object", + "required": ["id", "name", "type"], + "additionalProperties": false, + "properties": { + "id": {"type": "string"}, + "name": {"type": "string"}, + "type": { + "$ref": "#/$defs/type_tuple", + "description": "Return type. Empty for constructors and destructors." + }, + "templates": { + "type": "array", + "description": "Template parameters of the function itself, e.g. the string_literal naming an interface member.", + "items": {"$ref": "#/$defs/template_parameter"} + }, + "parameters": { + "type": "array", + "items": {"$ref": "#/$defs/parameter"} + }, + "visibility": {"enum": ["public", "protected", "private"], "default": "public"}, + "static": {"type": "boolean", "default": false}, + "const": {"type": "boolean", "default": false}, + "virtual": {"type": "boolean", "default": false}, + "override": {"type": "boolean", "default": false}, + "brief_description": {"type": "string"}, + "detailed_description": {"$ref": "#/$defs/paragraphs"}, + "examples": { + "type": "array", + "description": "Usage examples for this member.", + "items": {"$ref": "#/$defs/example"} + } + } + } + } +} diff --git a/docs/source/_static/css/custom.css b/docs/source/_static/css/custom.css deleted file mode 100644 index ba76c62..0000000 --- a/docs/source/_static/css/custom.css +++ /dev/null @@ -1,15 +0,0 @@ -:root { - --content-background-color: #fff5e1; - --navbar-background-color: #263547; - --navbar-heading-color: #eeeeee; -} - -.wy-nav-side { - background: var(--navbar-background-color); -} - -.classref-section-separator { - border-color: var(--navbar-heading-color); - border-top-width: 3px; - margin: 36px 0; -} diff --git a/docs/source/async/introduction.rst b/docs/source/async/introduction.rst deleted file mode 100644 index 7a6c05f..0000000 --- a/docs/source/async/introduction.rst +++ /dev/null @@ -1,6 +0,0 @@ -Introduction -============ - -The async module provides async functionality. -It introduces a basic event loop, which have to be activated and bound to a local thread through the wait scope class. -On a thread with an active event loop we can create async call graphs which automatically resolve the item moving through this graph. diff --git a/docs/source/codec/introduction.rst b/docs/source/codec/introduction.rst deleted file mode 100644 index 8cda2ac..0000000 --- a/docs/source/codec/introduction.rst +++ /dev/null @@ -1,12 +0,0 @@ -Introduction -============ - -The codec module provides basic functionality and is in fact a vital component for almost all other modules. -It's the module which provides the separation of logical structure and encoding of data. - -I am not aware of any programming languages which provide compile time separation of those concerns. -For the less powerful compile time reflection capabilities there's limited support in some languages. -C++26, regular C++ and Rust with minor additional hints etc come to mind. But this is only on native data. - -The separation enables treating data purely declaretively instead of imperative actions when moving it across encoding boundaries. -A regular file has the structure diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index 07c21ad..0000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,30 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -project = 'forstio docs' -copyright = '2024, Claudius "keldu" Holeksa' -author = 'Claudius "keldu" Holeksa' -release = '2024' - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = [ - 'sphinx_rtd_theme' -] - -templates_path = ['_templates'] -exclude_patterns = [] - - - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_theme = 'sphinx_rtd_theme' -html_static_path = ['_static'] diff --git a/docs/source/core/introduction.rst b/docs/source/core/introduction.rst deleted file mode 100644 index 1b70070..0000000 --- a/docs/source/core/introduction.rst +++ /dev/null @@ -1,5 +0,0 @@ -Introduction -============ - -The core module represents the most essential parts of this code base. -This module provides basic functionality in regards to memory control, error functionalities and other minor things. diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index 600797b..0000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,36 +0,0 @@ -.. Gasp Example documentation master file, created by - sphinx-quickstart on Tue Aug 22 16:01:56 2023. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to forstio's documentation! -=================================== - -.. toctree:: - :hidden: - :maxdepth: 2 - :caption: Manual - - manual/introduction - -.. toctree:: - :hidden: - :maxdepth: 2 - :caption: Core - - core/introduction - -.. toctree:: - :hidden: - :maxdepth: 2 - :caption: Async - - async/introduction - -.. toctree:: - :hidden: - :maxdepth: 2 - :caption: API Reference - - c_api/index - cpp_api/index diff --git a/docs/source/manual/introduction.rst b/docs/source/manual/introduction.rst deleted file mode 100644 index 920741d..0000000 --- a/docs/source/manual/introduction.rst +++ /dev/null @@ -1,14 +0,0 @@ -Introduction -============ - -Forstio is a modular library focused on providing many convenience functions -I find useful in a style I find easy to use. - -It is mostly an asynchronous, network and codec library. Due to the approach to -networking it is also applicable to be used in acceleration contexts. -Due to the same approach it's also possible to use it for language binding -generation. - -You don't have to use everything and the modular nature of the library attempts to separate all those concerns as much as possible. -A drawback of this is that I simplify everything through the nix package manager which you probably don't use. -I'm open to suggestions allowing this modular structure while not making it harder for me. diff --git a/docs_old/.nix/derivation.nix b/docs_old/.nix/derivation.nix new file mode 100644 index 0000000..a6dee7d --- /dev/null +++ b/docs_old/.nix/derivation.nix @@ -0,0 +1,42 @@ +{ lib +, stdenvNoCC +, python3 +, python3Packages +, doxygen +, gasp +, version +}: + +stdenvNoCC.mkDerivation { + pname = "forstio-docs"; + inherit version; + + src = ../../.; + + nativeBuildInputs = [ + python3 + python3Packages.sphinx + python3Packages.sphinx-rtd-theme + doxygen + gasp + ]; + + buildPhase = '' + # C++ API generation + pushd docs + doxygen Doxygen.in + python3 ${gasp.outPath}/bin/gasp.py xml --namespace saw > cpp_map.json + # C++ and C template generation + mkdir -p source/cpp_api + python3 ${gasp.outPath}/bin/make_rst.py --title="C++" -t ${gasp.outPath}/templates/rst -m cpp_map.json -o source/cpp_api + make html + popd + ''; + + installPhase = '' + mkdir -p $out + pushd docs + mv build/html $out/html + popd + ''; +} diff --git a/docs_old/Doxygen.in b/docs_old/Doxygen.in new file mode 100644 index 0000000..6124483 --- /dev/null +++ b/docs_old/Doxygen.in @@ -0,0 +1,8 @@ +GENERATE_XML = YES +GENERATE_LATEX= NO +GENERATE_HTML = NO +PROJECT_NAME = forstio +RECURSIVE = YES +FILE_PATTERNS = *.cpp *.hpp +INPUT = ../modules +EXCLUDE_SYMBOLS = *::impl::* diff --git a/docs_old/Makefile b/docs_old/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/docs_old/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs_old/source/_static/css/custom.css b/docs_old/source/_static/css/custom.css new file mode 100644 index 0000000..ba76c62 --- /dev/null +++ b/docs_old/source/_static/css/custom.css @@ -0,0 +1,15 @@ +:root { + --content-background-color: #fff5e1; + --navbar-background-color: #263547; + --navbar-heading-color: #eeeeee; +} + +.wy-nav-side { + background: var(--navbar-background-color); +} + +.classref-section-separator { + border-color: var(--navbar-heading-color); + border-top-width: 3px; + margin: 36px 0; +} diff --git a/docs_old/source/async/introduction.rst b/docs_old/source/async/introduction.rst new file mode 100644 index 0000000..7a6c05f --- /dev/null +++ b/docs_old/source/async/introduction.rst @@ -0,0 +1,6 @@ +Introduction +============ + +The async module provides async functionality. +It introduces a basic event loop, which have to be activated and bound to a local thread through the wait scope class. +On a thread with an active event loop we can create async call graphs which automatically resolve the item moving through this graph. diff --git a/docs_old/source/codec/introduction.rst b/docs_old/source/codec/introduction.rst new file mode 100644 index 0000000..8cda2ac --- /dev/null +++ b/docs_old/source/codec/introduction.rst @@ -0,0 +1,12 @@ +Introduction +============ + +The codec module provides basic functionality and is in fact a vital component for almost all other modules. +It's the module which provides the separation of logical structure and encoding of data. + +I am not aware of any programming languages which provide compile time separation of those concerns. +For the less powerful compile time reflection capabilities there's limited support in some languages. +C++26, regular C++ and Rust with minor additional hints etc come to mind. But this is only on native data. + +The separation enables treating data purely declaretively instead of imperative actions when moving it across encoding boundaries. +A regular file has the structure diff --git a/docs_old/source/conf.py b/docs_old/source/conf.py new file mode 100644 index 0000000..07c21ad --- /dev/null +++ b/docs_old/source/conf.py @@ -0,0 +1,30 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'forstio docs' +copyright = '2024, Claudius "keldu" Holeksa' +author = 'Claudius "keldu" Holeksa' +release = '2024' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + 'sphinx_rtd_theme' +] + +templates_path = ['_templates'] +exclude_patterns = [] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'sphinx_rtd_theme' +html_static_path = ['_static'] diff --git a/docs_old/source/core/introduction.rst b/docs_old/source/core/introduction.rst new file mode 100644 index 0000000..1b70070 --- /dev/null +++ b/docs_old/source/core/introduction.rst @@ -0,0 +1,5 @@ +Introduction +============ + +The core module represents the most essential parts of this code base. +This module provides basic functionality in regards to memory control, error functionalities and other minor things. diff --git a/docs_old/source/index.rst b/docs_old/source/index.rst new file mode 100644 index 0000000..600797b --- /dev/null +++ b/docs_old/source/index.rst @@ -0,0 +1,36 @@ +.. Gasp Example documentation master file, created by + sphinx-quickstart on Tue Aug 22 16:01:56 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to forstio's documentation! +=================================== + +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: Manual + + manual/introduction + +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: Core + + core/introduction + +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: Async + + async/introduction + +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: API Reference + + c_api/index + cpp_api/index diff --git a/docs_old/source/manual/introduction.rst b/docs_old/source/manual/introduction.rst new file mode 100644 index 0000000..920741d --- /dev/null +++ b/docs_old/source/manual/introduction.rst @@ -0,0 +1,14 @@ +Introduction +============ + +Forstio is a modular library focused on providing many convenience functions +I find useful in a style I find easy to use. + +It is mostly an asynchronous, network and codec library. Due to the approach to +networking it is also applicable to be used in acceleration contexts. +Due to the same approach it's also possible to use it for language binding +generation. + +You don't have to use everything and the modular nature of the library attempts to separate all those concerns as much as possible. +A drawback of this is that I simplify everything through the nix package manager which you probably don't use. +I'm open to suggestions allowing this modular structure while not making it harder for me. diff --git a/docs_oos/data/core/array_buffer.json b/docs_oos/data/core/array_buffer.json deleted file mode 100644 index 24b5cca..0000000 --- a/docs_oos/data/core/array_buffer.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "format": 1, - "id": "saw-array_buffer", - "kind": "class", - "name": "array_buffer", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/buffer.hpp", - "brief_description": "One time buffer.", - "detailed_description": [ - [ - "Filled once and read once. The cursors only move forward and the storage is never reused, so what was read is gone and what was written cannot be taken back." - ], - [ - "The right choice for a single message of known size." - ] - ], - "bases": [ - [{"name": "buffer", "id": "saw-buffer"}] - ], - "functions": { - "saw-array_buffer-ctor": { - "id": "saw-array_buffer-ctor", - "name": "array_buffer", - "type": [], - "parameters": [ - {"name": "size", "type": ["size_t"]} - ] - } - } -} diff --git a/docs_oos/data/core/branch.json b/docs_oos/data/core/branch.json deleted file mode 100644 index d30c42f..0000000 --- a/docs_oos/data/core/branch.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "format": 1, - "id": "saw-branch", - "kind": "class", - "name": "branch", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/tree.hpp", - "brief_description": "Container with a simplistic approach to a branch.", - "detailed_description": [ - [ - "The edge in a", - {"name": "tree_container", "id": "saw-tree_container"}, - "It holds either a leaf value or a whole sub tree, as a variant of the two, so the recursion lives in the data rather than in a pointer chain." - ], - [ - "Access comes in two flavours: get asserts what is held, while extract and replace hand the content out or swap it and report a mismatch as an error instead." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "Leaf value type."}, - {"name": "Tree", "kind": "type", "brief_description": "Sub tree type."} - ], - "aliases": { - "saw-branch-type": { - "id": "saw-branch-type", - "name": "type", - "type": ["std::variant< Tree, T >"], - "brief_description": "Either a sub tree or a leaf." - } - }, - "functions": { - "saw-branch-is": { - "id": "saw-branch-is", - "name": "is", - "type": ["bool"], - "const": true, - "brief_description": "Whether the branch holds the given alternative.", - "templates": [ - {"name": "NT", "kind": "type"} - ] - }, - "saw-branch-is_tree": { - "id": "saw-branch-is_tree", - "name": "is_tree", - "type": ["bool"], - "const": true, - "brief_description": "Whether the branch continues into a sub tree." - }, - "saw-branch-is_value": { - "id": "saw-branch-is_value", - "name": "is_value", - "type": ["bool"], - "const": true, - "brief_description": "Whether the branch ends in a leaf." - }, - "saw-branch-get_tree": { - "id": "saw-branch-get_tree", - "name": "get_tree", - "type": ["Tree &"], - "brief_description": "The sub tree. Only valid if is_tree." - }, - "saw-branch-get_value": { - "id": "saw-branch-get_value", - "name": "get_value", - "type": ["T &"], - "brief_description": "The leaf. Only valid if is_value." - }, - "saw-branch-extract_tree": { - "id": "saw-branch-extract_tree", - "name": "extract_tree", - "type": ["error_or< Tree >"], - "brief_description": "Takes the sub tree out, failing if the branch holds a leaf." - }, - "saw-branch-extract_value": { - "id": "saw-branch-extract_value", - "name": "extract_value", - "type": ["error_or< T >"], - "brief_description": "Takes the leaf out, failing if the branch holds a sub tree." - }, - "saw-branch-replace_tree": { - "id": "saw-branch-replace_tree", - "name": "replace_tree", - "type": ["error_or< Tree >"], - "brief_description": "Swaps in new content and returns the sub tree which was there.", - "parameters": [ - {"name": "nd", "type": ["type"]} - ] - }, - "saw-branch-replace_value": { - "id": "saw-branch-replace_value", - "name": "replace_value", - "type": ["error_or< T >"], - "brief_description": "Swaps in new content and returns the leaf which was there.", - "parameters": [ - {"name": "nd", "type": ["type"]} - ] - } - }, - "notes": [ - "Copy is forbidden, move is allowed." - ] -} diff --git a/docs_oos/data/core/buffer.json b/docs_oos/data/core/buffer.json deleted file mode 100644 index cee07fd..0000000 --- a/docs_oos/data/core/buffer.json +++ /dev/null @@ -1,182 +0,0 @@ -{ - "format": 1, - "id": "saw-buffer", - "kind": "class", - "name": "buffer", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/buffer.hpp", - "brief_description": "Access class to reduce templated buffer segment bloat.", - "detailed_description": [ - [ - "A buffer has two independent cursors, one for reading and one for writing, and may be split into segments which are contiguous only up to a point. Everything is phrased around that: composite length is what remains in total, segment length is what remains without a jump." - ], - [ - "Code which copies in bulk loops on the segment length; code which works byte by byte uses read and write with an offset. Both cursors move only through the advance calls, so a reader can look ahead without consuming." - ] - ], - "functions": { - "saw-buffer-read_position": { - "id": "saw-buffer-read_position", - "name": "read_position", - "type": ["size_t"], - "const": true, - "virtual": true, - "brief_description": "Where the read cursor currently is." - }, - "saw-buffer-read_composite_length": { - "id": "saw-buffer-read_composite_length", - "name": "read_composite_length", - "type": ["size_t"], - "const": true, - "virtual": true, - "brief_description": "How many bytes can be read in total, across segments." - }, - "saw-buffer-read_segment_length": { - "id": "saw-buffer-read_segment_length", - "name": "read_segment_length", - "type": ["size_t"], - "const": true, - "virtual": true, - "brief_description": "How many bytes can be read contiguously from an offset.", - "parameters": [ - {"name": "offset", "type": ["size_t"], "default": "0"} - ] - }, - "saw-buffer-read_advance": { - "id": "saw-buffer-read_advance", - "name": "read_advance", - "type": ["void"], - "virtual": true, - "brief_description": "Consumes bytes from the read side.", - "parameters": [ - {"name": "bytes", "type": ["size_t"]} - ] - }, - "saw-buffer-read": { - "id": "saw-buffer-read", - "name": "read", - "type": ["uint8_t &"], - "virtual": true, - "brief_description": "The byte at an offset from the read cursor, without consuming it.", - "parameters": [ - {"name": "i", "type": ["size_t"], "default": "0"} - ] - }, - "saw-buffer-write_position": { - "id": "saw-buffer-write_position", - "name": "write_position", - "type": ["size_t"], - "const": true, - "virtual": true, - "brief_description": "Where the write cursor currently is." - }, - "saw-buffer-write_composite_length": { - "id": "saw-buffer-write_composite_length", - "name": "write_composite_length", - "type": ["size_t"], - "const": true, - "virtual": true, - "brief_description": "How many bytes can be written in total, across segments." - }, - "saw-buffer-write_segment_length": { - "id": "saw-buffer-write_segment_length", - "name": "write_segment_length", - "type": ["size_t"], - "const": true, - "virtual": true, - "brief_description": "How many bytes can be written contiguously from an offset.", - "parameters": [ - {"name": "offset", "type": ["size_t"], "default": "0"} - ] - }, - "saw-buffer-write_advance": { - "id": "saw-buffer-write_advance", - "name": "write_advance", - "type": ["void"], - "virtual": true, - "brief_description": "Marks bytes as written.", - "parameters": [ - {"name": "bytes", "type": ["size_t"]} - ] - }, - "saw-buffer-write": { - "id": "saw-buffer-write", - "name": "write", - "type": ["uint8_t &"], - "virtual": true, - "brief_description": "The byte at an offset from the write cursor.", - "parameters": [ - {"name": "i", "type": ["size_t"], "default": "0"} - ] - }, - "saw-buffer-write_require_length": { - "id": "saw-buffer-write_require_length", - "name": "write_require_length", - "type": [{"name": "error", "id": "saw-error"}], - "virtual": true, - "brief_description": "Asks for room before writing in bulk.", - "detailed_description": [ - [ - "Nothing can be done if the read side has not been filled, but the write side can grow on demand. Call this before pushing a run of bytes, so a failure happens once up front instead of halfway through." - ] - ], - "parameters": [ - {"name": "bytes", "type": ["size_t"]} - ] - }, - "saw-buffer-push-1": { - "id": "saw-buffer-push-1", - "name": "push", - "type": [{"name": "error", "id": "saw-error"}], - "brief_description": "Writes one byte.", - "detailed_description": [ - ["Fails with", {"name": "buffer_exhausted", "id": "saw-err-buffer_exhausted"}, "if there is no room."] - ], - "parameters": [ - {"name": "value", "type": ["const uint8_t &"]} - ] - }, - "saw-buffer-push-2": { - "id": "saw-buffer-push-2", - "name": "push", - "type": [{"name": "error", "id": "saw-error"}], - "brief_description": "Writes a run of bytes, segment by segment.", - "parameters": [ - {"name": "buffer", "type": ["const uint8_t &"], "brief_description": "First byte of the run."}, - {"name": "size", "type": ["size_t"]} - ] - }, - "saw-buffer-pop-1": { - "id": "saw-buffer-pop-1", - "name": "pop", - "type": [{"name": "error", "id": "saw-error"}], - "brief_description": "Reads one byte and consumes it.", - "parameters": [ - {"name": "value", "type": ["uint8_t &"]} - ] - }, - "saw-buffer-pop-2": { - "id": "saw-buffer-pop-2", - "name": "pop", - "type": [{"name": "error", "id": "saw-error"}], - "brief_description": "Reads a run of bytes and consumes them.", - "parameters": [ - {"name": "buffer", "type": ["uint8_t &"]}, - {"name": "size", "type": ["size_t"]} - ] - }, - "saw-buffer-write_from": { - "id": "saw-buffer-write_from", - "name": "write_from", - "type": ["error_or< uint64_t >"], - "brief_description": "Reads from another buffer and writes into this one.", - "parameters": [ - {"name": "buff", "type": ["const buffer &"]} - ] - } - }, - "notes": [ - "The concrete buffers differ in what happens when space runs out, which is the thing to pick on." - ] -} diff --git a/docs_oos/data/core/buffer_view.json b/docs_oos/data/core/buffer_view.json deleted file mode 100644 index bf07694..0000000 --- a/docs_oos/data/core/buffer_view.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "format": 1, - "id": "saw-buffer_view", - "kind": "class", - "name": "buffer_view", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/buffer.hpp", - "brief_description": "A viewer class for buffers.", - "detailed_description": [ - [ - "Carries its own cursors over somebody else's", - {"name": "buffer", "id": "saw-buffer"}, - "so a decoder can walk forward, discover the input is incomplete, and leave the underlying buffer untouched. Only once the operation succeeded does the caller advance the real buffer by the view's offset." - ], - [ - "That is the whole speculative parsing mechanism in this codebase. The codecs decode into a view and commit afterwards." - ], - [ - "Working on the referenced buffer invalidates the view." - ] - ], - "bases": [ - [{"name": "buffer", "id": "saw-buffer"}] - ], - "functions": { - "saw-buffer_view-ctor-1": { - "id": "saw-buffer_view-ctor-1", - "name": "buffer_view", - "type": [], - "parameters": [ - {"name": "buffer", "type": [{"name": "buffer", "id": "saw-buffer"}, "&"]} - ] - }, - "saw-buffer_view-ctor-2": { - "id": "saw-buffer_view-ctor-2", - "name": "buffer_view", - "type": [], - "brief_description": "With an upper bound on what may be read and written through it.", - "parameters": [ - {"name": "buffer", "type": [{"name": "buffer", "id": "saw-buffer"}, "&"]}, - {"name": "limit_read_len", "type": ["uint64_t"]}, - {"name": "limit_write_len", "type": ["uint64_t"]} - ] - }, - "saw-buffer_view-read_offset": { - "id": "saw-buffer_view-read_offset", - "name": "read_offset", - "type": ["size_t"], - "const": true, - "brief_description": "How far the view has read ahead of the underlying buffer.", - "detailed_description": [ - ["This is what gets handed to read_advance on the real buffer once the read is known to have succeeded."] - ] - }, - "saw-buffer_view-write_offset": { - "id": "saw-buffer_view-write_offset", - "name": "write_offset", - "type": ["size_t"], - "const": true, - "brief_description": "How far the view has written ahead of the underlying buffer." - } - }, - "examples": [ - { - "title": "Decoding without consuming on failure", - "description": [ - ["The shape every codec uses. If the decode fails, the buffer is left exactly as it was and the caller can try again once more data arrived."] - ], - "language": "cpp", - "code": "buffer_view buff_v{from_decode.get_buffer()};\n\nauto eov = impl::json_decode::decode(buff_v, to_decode, cfg_);\nif(eov.is_error()){\n\treturn std::move(eov.get_error());\n}\n\n/// Only now is the input really consumed.\nfrom_decode.get_buffer().read_advance(buff_v.read_offset());\n" - } - ] -} diff --git a/docs_oos/data/core/chain_array_buffer.json b/docs_oos/data/core/chain_array_buffer.json deleted file mode 100644 index a9459bd..0000000 --- a/docs_oos/data/core/chain_array_buffer.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "format": 1, - "id": "saw-chain_array_buffer", - "kind": "class", - "name": "chain_array_buffer", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/buffer.hpp", - "brief_description": "A growing chain of one time buffers.", - "detailed_description": [ - [ - "Holds a deque of", - {"name": "array_buffer", "id": "saw-array_buffer"}, - "so capacity can be added without moving what is already there. This is the buffer for a stream of unknown length, where a ring buffer would run out and a single array buffer would have to be guessed in advance." - ], - [ - "It is also why the buffer interface speaks of segments: a read which crosses from one link to the next is not contiguous, so segment length stops at the boundary." - ] - ], - "bases": [ - [{"name": "buffer", "id": "saw-buffer"}] - ], - "functions": { - "saw-chain_array_buffer-ctor": { - "id": "saw-chain_array_buffer-ctor", - "name": "chain_array_buffer", - "type": [] - }, - "saw-chain_array_buffer-extract_front": { - "id": "saw-chain_array_buffer-extract_front", - "name": "extract_front", - "type": ["error_or<", {"name": "array_buffer", "id": "saw-array_buffer"}, ">"], - "brief_description": "Takes the first link out of the chain instead of copying out of it.", - "detailed_description": [ - [ - "The size has to match what the front link still holds exactly. A partial extraction fails with", - {"name": "invalid_state", "id": "saw-err-invalid_state"}, - "and the caller is told to view and copy instead." - ], - [ - "An empty chain fails with", - {"name": "recoverable", "id": "saw-err-recoverable"} - ] - ], - "parameters": [ - {"name": "size", "type": ["uint64_t"]} - ] - } - } -} diff --git a/docs_oos/data/core/err/already_exists.json b/docs_oos/data/core/err/already_exists.json deleted file mode 100644 index 3d6c4ff..0000000 --- a/docs_oos/data/core/err/already_exists.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "format": 1, - "id": "saw-err-already_exists", - "kind": "struct", - "name": "already_exists", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "Something is already there under that name or id.", - "detailed_description": [ - [ - "Recoverable. Storing into an occupied slot, or binding a second server to an address which is already taken. The existing entry is left untouched, so the caller can decide whether to pick another id or treat it as success." - ] - ], - "attributes": { - "saw-err-already_exists-description": { - "id": "saw-err-already_exists-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"Already exists\"" - }, - "saw-err-already_exists-is_critical": { - "id": "saw-err-already_exists-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "false" - } - } -} diff --git a/docs_oos/data/core/err/buffer_exhausted.json b/docs_oos/data/core/err/buffer_exhausted.json deleted file mode 100644 index a8651f1..0000000 --- a/docs_oos/data/core/err/buffer_exhausted.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "format": 1, - "id": "saw-err-buffer_exhausted", - "kind": "struct", - "name": "buffer_exhausted", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "A buffer ran out of room to read or write.", - "detailed_description": [ - [ - "Recoverable, and deliberately so: a decoder hitting the end of what has arrived so far is the normal state of a stream, not a defect. Code which decodes incrementally checks for this kind and waits for more instead of failing." - ] - ], - "attributes": { - "saw-err-buffer_exhausted-description": { - "id": "saw-err-buffer_exhausted-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"Buffer Exhausted\"" - }, - "saw-err-buffer_exhausted-is_critical": { - "id": "saw-err-buffer_exhausted-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "false" - } - } -} diff --git a/docs_oos/data/core/err/critical.json b/docs_oos/data/core/err/critical.json deleted file mode 100644 index 006d6c7..0000000 --- a/docs_oos/data/core/err/critical.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "format": 1, - "id": "saw-err-critical", - "kind": "struct", - "name": "critical", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "Generic critical error.", - "detailed_description": [ - [ - "The counterpart of", - {"name": "recoverable", "id": "saw-err-recoverable"}, - "for a failure the caller is not expected to continue through. Same advice applies: a named kind is worth defining as soon as anything wants to branch on it." - ] - ], - "attributes": { - "saw-err-critical-description": { - "id": "saw-err-critical-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"Generic critical error\"" - }, - "saw-err-critical-is_critical": { - "id": "saw-err-critical-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "true" - } - } -} diff --git a/docs_oos/data/core/err/invalid_state.json b/docs_oos/data/core/err/invalid_state.json deleted file mode 100644 index 343d218..0000000 --- a/docs_oos/data/core/err/invalid_state.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "format": 1, - "id": "saw-err-invalid_state", - "kind": "struct", - "name": "invalid_state", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "Something was not in the state the operation requires.", - "detailed_description": [ - [ - "Critical. The catch all for a situation which should not have been reachable: malformed input where the grammar left no choice, a cast between mismatched class ids, a default constructed result which nobody filled in." - ] - ], - "attributes": { - "saw-err-invalid_state-description": { - "id": "saw-err-invalid_state-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"Invalid state\"" - }, - "saw-err-invalid_state-is_critical": { - "id": "saw-err-invalid_state-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "true" - } - } -} diff --git a/docs_oos/data/core/err/no_error.json b/docs_oos/data/core/err/no_error.json deleted file mode 100644 index 0fa4974..0000000 --- a/docs_oos/data/core/err/no_error.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "format": 1, - "id": "saw-err-no_error", - "kind": "struct", - "name": "no_error", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "No error has occured.", - "detailed_description": [ - [ - "The absence of a failure, expressed as an error kind so that a function returning a plain", - {"name": "error", "id": "saw-error"}, - "can report success. Preregistered as code zero, which is why failed is defined as not being of this kind." - ] - ], - "attributes": { - "saw-err-no_error-description": { - "id": "saw-err-no_error-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"No error has occured\"", - "brief_description": "The category text. This is the portable identity of the error." - }, - "saw-err-no_error-is_critical": { - "id": "saw-err-no_error-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "false" - } - } -} diff --git a/docs_oos/data/core/err/not_found.json b/docs_oos/data/core/err/not_found.json deleted file mode 100644 index e0e0dee..0000000 --- a/docs_oos/data/core/err/not_found.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "format": 1, - "id": "saw-err-not_found", - "kind": "struct", - "name": "not_found", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "Something was looked up and is not there.", - "detailed_description": [ - [ - "Recoverable, because asking for something absent is a normal outcome rather than a defect. Used when an id has no value stored under it, or when no server listens on an address." - ], - [ - "One of the three kinds preregistered in the registry." - ] - ], - "attributes": { - "saw-err-not_found-description": { - "id": "saw-err-not_found-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"Not found\"" - }, - "saw-err-not_found-is_critical": { - "id": "saw-err-not_found-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "false" - } - } -} diff --git a/docs_oos/data/core/err/not_implemented.json b/docs_oos/data/core/err/not_implemented.json deleted file mode 100644 index 2aecf9d..0000000 --- a/docs_oos/data/core/err/not_implemented.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "format": 1, - "id": "saw-err-not_implemented", - "kind": "struct", - "name": "not_implemented", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "The operation exists but has no implementation yet.", - "detailed_description": [ - [ - "Critical. A placeholder in a backend or codec which is still being built, so the gap surfaces as a failure at runtime instead of as a link error or, worse, as silently wrong behaviour." - ], - [ - "Distinct from", - {"name": "not_supported", "id": "saw-err-not_supported"}, - "which means the operation is never going to exist for this type." - ] - ], - "attributes": { - "saw-err-not_implemented-description": { - "id": "saw-err-not_implemented-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"Not implemented\"" - }, - "saw-err-not_implemented-is_critical": { - "id": "saw-err-not_implemented-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "true" - } - } -} diff --git a/docs_oos/data/core/err/not_supported.json b/docs_oos/data/core/err/not_supported.json deleted file mode 100644 index bb509e7..0000000 --- a/docs_oos/data/core/err/not_supported.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "format": 1, - "id": "saw-err-not_supported", - "kind": "struct", - "name": "not_supported", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "The operation does not apply here and never will.", - "detailed_description": [ - [ - "Recoverable, because the caller can reasonably ask and then do something else. The json decoder uses it for a leading plus on a number, which is valid in some languages and simply not part of json." - ], - [ - "Distinct from", - {"name": "not_implemented", "id": "saw-err-not_implemented"}, - "which means the gap is going to be filled later." - ] - ], - "attributes": { - "saw-err-not_supported-description": { - "id": "saw-err-not_supported-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"Not supported\"" - }, - "saw-err-not_supported-is_critical": { - "id": "saw-err-not_supported-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "false" - } - } -} diff --git a/docs_oos/data/core/err/out_of_memory.json b/docs_oos/data/core/err/out_of_memory.json deleted file mode 100644 index 47cab53..0000000 --- a/docs_oos/data/core/err/out_of_memory.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "format": 1, - "id": "saw-err-out_of_memory", - "kind": "struct", - "name": "out_of_memory", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "An allocation failed.", - "detailed_description": [ - [ - "Critical. This is what a caught std::bad_alloc or a failed container insert turns into, which is how allocation failure stays inside the error path instead of becoming an exception." - ], - [ - "One of the three kinds preregistered in the registry." - ] - ], - "attributes": { - "saw-err-out_of_memory-description": { - "id": "saw-err-out_of_memory-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"Out of memory\"" - }, - "saw-err-out_of_memory-is_critical": { - "id": "saw-err-out_of_memory-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "true" - } - } -} diff --git a/docs_oos/data/core/err/recoverable.json b/docs_oos/data/core/err/recoverable.json deleted file mode 100644 index fecd820..0000000 --- a/docs_oos/data/core/err/recoverable.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "format": 1, - "id": "saw-err-recoverable", - "kind": "struct", - "name": "recoverable", - "namespace": "saw::err", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "Generic recoverable error.", - "detailed_description": [ - [ - "For a failure which has no kind of its own and which the caller can act on. Prefer defining a tag struct when the kind means something; a named category is what makes an error distinguishable in another process." - ] - ], - "attributes": { - "saw-err-recoverable-description": { - "id": "saw-err-recoverable-description", - "name": "description", - "type": ["std::string_view"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"Generic recoverable error\"" - }, - "saw-err-recoverable-is_critical": { - "id": "saw-err-recoverable-is_critical", - "name": "is_critical", - "type": ["bool"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "false" - } - } -} diff --git a/docs_oos/data/core/error.json b/docs_oos/data/core/error.json deleted file mode 100644 index 8f7a524..0000000 --- a/docs_oos/data/core/error.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "format": 1, - "id": "saw-error", - "kind": "class", - "name": "error", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "Exception replacement. Carries a code, a criticality and a message.", - "detailed_description": [ - [ - "The library is written without exceptions, so this takes their place. An error is either recoverable or critical, and the code distinguishes the kind. Additional kinds are added by defining a tag struct with a description and an is_critical flag, which registers itself the first time it is used." - ], - [ - "The code is an index into a process local registry handed out in first use order. Only", - {"name": "no_error", "id": "saw-err-no_error"}, - {"name": "not_found", "id": "saw-err-not_found"}, - "and", - {"name": "out_of_memory", "id": "saw-err-out_of_memory"}, - "are preregistered, so the same error has different codes in two processes. A code must therefore never be sent anywhere; the category string is the portable identity." - ], - [ - "Copying is forbidden on purpose. An error is moved, or copied explicitly through copy_error, so passing one around stays visible at the call site." - ] - ], - "attributes": { - "saw-error-error_code_": { - "id": "saw-error-error_code_", - "name": "error_code_", - "type": ["code"], - "visibility": "private", - "brief_description": "Distinguishes the different error types." - }, - "saw-error-is_critical_": { - "id": "saw-error-is_critical_", - "name": "is_critical_", - "type": ["bool"], - "visibility": "private", - "brief_description": "Kept next to the code so checking doesn't need the registry." - }, - "saw-error-error_message_": { - "id": "saw-error-error_message_", - "name": "error_message_", - "type": ["std::variant< std::string_view, std::string >"], - "visibility": "private", - "brief_description": "A variant for the edge case of being out of memory, where a string cannot be built." - } - }, - "aliases": { - "saw-error-code": { - "id": "saw-error-code", - "name": "code", - "type": ["uint32_t"], - "brief_description": "Type representing the error code." - } - }, - "functions": { - "saw-error-ctor-1": { - "id": "saw-error-ctor-1", - "name": "error", - "type": [], - "parameters": [ - {"name": "id", "type": ["error::code"]}, - {"name": "is_critical", "type": ["bool"]} - ] - }, - "saw-error-ctor-2": { - "id": "saw-error-ctor-2", - "name": "error", - "type": [], - "brief_description": "With a message which outlives the error, such as a literal.", - "parameters": [ - {"name": "id", "type": ["error::code"]}, - {"name": "is_critical", "type": ["bool"]}, - {"name": "msg", "type": ["const std::string_view &"]} - ] - }, - "saw-error-ctor-3": { - "id": "saw-error-ctor-3", - "name": "error", - "type": [], - "brief_description": "With an owned message, for text built at the point of failure.", - "parameters": [ - {"name": "id", "type": ["error::code"]}, - {"name": "is_critical", "type": ["bool"]}, - {"name": "msg", "type": ["std::string &&"]} - ] - }, - "saw-error-get_message": { - "id": "saw-error-get_message", - "name": "get_message", - "type": ["const std::string_view"], - "const": true, - "brief_description": "Returns a string view to the message." - }, - "saw-error-get_category": { - "id": "saw-error-get_category", - "name": "get_category", - "type": ["const std::string_view"], - "const": true, - "brief_description": "Returns a view describing which error this is.", - "detailed_description": [ - ["Looked up in the registry. This, not the code, is the identity which means the same thing in another process."] - ] - }, - "saw-error-failed": { - "id": "saw-error-failed", - "name": "failed", - "type": ["bool"], - "const": true, - "brief_description": "Checks if it is an error at all, since the code zero is reserved for no error." - }, - "saw-error-is_critical": { - "id": "saw-error-is_critical", - "name": "is_critical", - "type": ["bool"], - "const": true, - "brief_description": "Checks if the error is critical." - }, - "saw-error-is_recoverable": { - "id": "saw-error-is_recoverable", - "name": "is_recoverable", - "type": ["bool"], - "const": true, - "brief_description": "Checks if the error is recoverable." - }, - "saw-error-copy_error": { - "id": "saw-error-copy_error", - "name": "copy_error", - "type": ["error"], - "const": true, - "brief_description": "Replaces the copy constructor, so copying an error is always explicit.", - "detailed_description": [ - ["If copying the message runs out of memory, the copy keeps the code and gets a static message instead of failing."] - ] - }, - "saw-error-get_id": { - "id": "saw-error-get_id", - "name": "get_id", - "type": ["error::code"], - "const": true, - "brief_description": "Returns the code." - }, - "saw-error-is_type": { - "id": "saw-error-is_type", - "name": "is_type", - "type": ["bool"], - "const": true, - "brief_description": "Checks whether this error is of a given kind.", - "detailed_description": [ - ["The way to branch on an error. Comparing codes directly only works inside one process."] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "An error tag struct, e.g. err::not_found."} - ], - "examples": [ - { - "title": "Branching on the kind of failure", - "language": "cpp", - "code": "auto eov = srv.receive(dat_id);\nif(eov.is_error()){\n\tauto& err = eov.get_error();\n\tif(err.is_type()){\n\t\t/// Nothing stored under that id yet.\n\t\treturn make_void();\n\t}\n\treturn std::move(err);\n}\n" - } - ] - } - }, - "notes": [ - "Copy is forbidden; use copy_error when a second instance is genuinely needed." - ] -} diff --git a/docs_oos/data/core/error_builder.json b/docs_oos/data/core/error_builder.json deleted file mode 100644 index 4385514..0000000 --- a/docs_oos/data/core/error_builder.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "format": 1, - "id": "saw-error_builder", - "kind": "struct", - "name": "error_builder", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "Builds an error message lazily, only when the error is actually created.", - "detailed_description": [ - [ - "Composing a message costs an allocation and some string work, which is wasted on the path where nothing fails. The builder holds a callable instead and runs it at the moment the error is made." - ], - [ - "If building the message throws, the error is still produced with the generic message passed in, so an out of memory situation cannot turn a failure into a crash." - ] - ], - "attributes": { - "saw-error_builder-func_": { - "id": "saw-error_builder-func_", - "name": "func_", - "type": ["std::function< std::string() >"], - "visibility": "private" - } - }, - "functions": { - "saw-error_builder-ctor": { - "id": "saw-error_builder-ctor", - "name": "error_builder", - "type": [], - "templates": [ - {"name": "Func", "kind": "type", "brief_description": "Callable returning the message."} - ], - "parameters": [ - {"name": "func__", "type": ["Func &&"]} - ] - }, - "saw-error_builder-make_error": { - "id": "saw-error_builder-make_error", - "name": "make_error", - "type": [{"name": "error", "id": "saw-error"}], - "brief_description": "Runs the callable and produces the error.", - "detailed_description": [ - ["The callable is cleared afterwards, so a builder yields its message once."] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "The error tag struct to produce."} - ], - "parameters": [ - { - "name": "generic", - "type": ["const std::string_view &"], - "brief_description": "Fallback message if building the real one fails." - } - ], - "examples": [ - { - "title": "A message which is only built on failure", - "language": "cpp", - "code": "return build_error([&](){\n\treturn std::string{\"Expect ',' or '}', but got \"}\n\t\t+ std::string{static_cast(buff.read())};\n}).make_error(\"Struct separator expected\");\n" - } - ] - } - } -} diff --git a/docs_oos/data/core/error_or.json b/docs_oos/data/core/error_or.json deleted file mode 100644 index a4a0d3b..0000000 --- a/docs_oos/data/core/error_or.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "format": 1, - "id": "saw-error_or", - "kind": "class", - "name": "error_or", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "Holds either a value or an error.", - "detailed_description": [ - [ - "The return type of nearly everything which can fail. It is a variant of an", - {"name": "error", "id": "saw-error"}, - "and the value, with void represented by an internal empty type so error_or< void > works like any other." - ], - [ - "get_value and get_error return references into the object, so the error_or itself has to stay alive while the reference is used. Chaining the two, as in f().get_value(), hands back a reference into a temporary." - ], - [ - "The default constructor exists but fills in an invalid_state error, so a default constructed one is already failed rather than empty. The value type therefore does not have to be default constructible." - ] - ], - "bases": [ - [{"name": "error_or_value", "id": "saw-error_or_value"}] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "The value type. May be void."} - ], - "attributes": { - "saw-error_or-value_or_error_": { - "id": "saw-error_or-value_or_error_", - "name": "value_or_error_", - "type": ["std::variant< error, fix_void< T > >"], - "visibility": "private" - } - }, - "functions": { - "saw-error_or-ctor-1": { - "id": "saw-error_or-ctor-1", - "name": "error_or", - "type": [], - "brief_description": "Default constructs to an invalid_state error, not to a value." - }, - "saw-error_or-ctor-2": { - "id": "saw-error_or-ctor-2", - "name": "error_or", - "type": [], - "brief_description": "From a value. Implicit, so a function can return the value directly.", - "parameters": [ - {"name": "value", "type": ["const fix_void< T > &"]} - ] - }, - "saw-error_or-ctor-3": { - "id": "saw-error_or-ctor-3", - "name": "error_or", - "type": [], - "brief_description": "From an error. Implicit, so a function can return make_error directly.", - "parameters": [ - {"name": "error", "type": ["error &&"]} - ] - }, - "saw-error_or-is_value": { - "id": "saw-error_or-is_value", - "name": "is_value", - "type": ["bool"], - "const": true, - "brief_description": "True if it holds the value." - }, - "saw-error_or-is_error": { - "id": "saw-error_or-is_error", - "name": "is_error", - "type": ["bool"], - "const": true, - "brief_description": "True if it holds an error." - }, - "saw-error_or-get_value": { - "id": "saw-error_or-get_value", - "name": "get_value", - "type": ["fix_void< T > &"], - "brief_description": "The value. Only valid if is_value." - }, - "saw-error_or-get_error": { - "id": "saw-error_or-get_error", - "name": "get_error", - "type": ["error &"], - "brief_description": "The error. Only valid if is_error." - } - }, - "specializations": [ - { - "name": "error_or< error_or< T > >", - "id": "saw-error_or-nested", - "brief_description": "Deleted. Guards against an error_or which wraps another one." - } - ], - "examples": [ - { - "title": "Passing a failure upwards", - "description": [ - [ - "The shape repeated throughout the codebase. The error is moved out, because", - {"name": "error", "id": "saw-error"}, - "forbids copying." - ] - ], - "language": "cpp", - "code": "error_or> load(id dat_id){\n\tauto eov = srv.receive(dat_id);\n\tif(eov.is_error()){\n\t\treturn std::move(eov.get_error());\n\t}\n\n\treturn std::move(eov.get_value());\n}\n" - } - ] -} diff --git a/docs_oos/data/core/error_or.nested.json b/docs_oos/data/core/error_or.nested.json deleted file mode 100644 index 34bd2b5..0000000 --- a/docs_oos/data/core/error_or.nested.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "format": 1, - "id": "saw-error_or-nested", - "kind": "class", - "name": "error_or", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/error.hpp", - "is_special": true, - "specializes": "saw-error_or", - "arguments": ["error_or< T >"], - "brief_description": "Type safe guard against an error_or holding another error_or.", - "detailed_description": [ - [ - "Its only member is a deleted default constructor, so the type cannot be formed. It catches the case where an error_or is returned from something which already returns one, which is easy to do by accident once calls are nested a few levels deep." - ], - [ - "The failure then happens where the type is written instead of somewhere further down in a confusing overload." - ] - ], - "templates": [ - {"name": "T", "kind": "type"} - ] -} diff --git a/docs_oos/data/core/error_or_value.json b/docs_oos/data/core/error_or_value.json deleted file mode 100644 index 1b93ee9..0000000 --- a/docs_oos/data/core/error_or_value.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "format": 1, - "id": "saw-error_or_value", - "kind": "class", - "name": "error_or_value", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/error.hpp", - "brief_description": "Type erased base of every error_or.", - "detailed_description": [ - [ - "Lets code hold a result whose value type it doesn't know, and recover it later with as. The cast is unchecked, so the caller has to know which type it stored." - ] - ], - "functions": { - "saw-error_or_value-as": { - "id": "saw-error_or_value-as", - "name": "as", - "type": [{"name": "error_or", "id": "saw-error_or"}, "< unfix_void< T > > &"], - "brief_description": "Recovers the concrete result.", - "templates": [ - {"name": "T", "kind": "type", "brief_description": "The value type which was stored."} - ] - } - } -} diff --git a/docs_oos/data/core/heap.json b/docs_oos/data/core/heap.json deleted file mode 100644 index 6500895..0000000 --- a/docs_oos/data/core/heap.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "format": 1, - "id": "saw-heap", - "kind": "function", - "name": "heap", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/common.hpp", - "type": [{"name": "own", "id": "saw-own"}, "< T >"], - "brief_description": "Constructs an object on the heap and hands back sole ownership.", - "detailed_description": [ - [ - "The one place new is called. Arguments are forwarded to the constructor, so a type which forbids copying and moving can still be built here, which is exactly what the registered servers rely on." - ] - ], - "templates": [ - {"name": "T", "kind": "type"}, - {"name": "Args", "kind": "type", "pack": true} - ], - "parameters": [ - {"name": "args", "type": ["Args &&..."], "brief_description": "Forwarded to the constructor of T."} - ] -} diff --git a/docs_oos/data/core/id.json b/docs_oos/data/core/id.json deleted file mode 100644 index dc22fac..0000000 --- a/docs_oos/data/core/id.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "format": 1, - "id": "saw-id", - "kind": "class", - "name": "id", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/id.hpp", - "brief_description": "An identifier tied to the class it stands for.", - "detailed_description": [ - [ - "A number underneath, but a distinct type per subject, so an id for one schema cannot be handed where an id for another is expected. That is what makes the remote layer safe to work with: nothing there moves data, it moves these." - ], - [ - "Comparable and copyable, with no default constructor, so an id always refers to something somebody handed out." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "What the id refers to."} - ], - "attributes": { - "saw-id-value_": { - "id": "saw-id-value_", - "name": "value_", - "type": ["uint64_t"], - "visibility": "private" - } - }, - "functions": { - "saw-id-ctor": { - "id": "saw-id-ctor", - "name": "id", - "type": [], - "parameters": [ - {"name": "val", "type": ["uint64_t"]} - ] - }, - "saw-id-eq": { - "id": "saw-id-eq", - "name": "operator==", - "type": ["bool"], - "const": true, - "parameters": [ - {"name": "rhs", "type": ["const id< T > &"]} - ] - }, - "saw-id-neq": { - "id": "saw-id-neq", - "name": "operator!=", - "type": ["bool"], - "const": true, - "parameters": [ - {"name": "rhs", "type": ["const id< T > &"]} - ] - }, - "saw-id-get_value": { - "id": "saw-id-get_value", - "name": "get_value", - "type": ["const uint64_t &"], - "const": true, - "brief_description": "The underlying number.", - "detailed_description": [ - ["Mostly for internal purposes, and for the moment an id has to be put somewhere which only understands numbers."] - ] - } - } -} diff --git a/docs_oos/data/core/lent.json b/docs_oos/data/core/lent.json deleted file mode 100644 index 06a6751..0000000 --- a/docs_oos/data/core/lent.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "format": 1, - "id": "saw-lent", - "kind": "alias", - "name": "lent", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/common.hpp", - "type": ["std::weak_ptr< T >"], - "brief_description": "A borrow of a shared object which does not keep it alive.", - "detailed_description": [ - [ - "The counterpart of", - {"name": "our", "id": "saw-our"}, - "for a party which wants access but must not extend the lifetime, which is how cycles between the two are avoided." - ] - ], - "templates": [ - {"name": "T", "kind": "type"} - ] -} diff --git a/docs_oos/data/core/maybe.json b/docs_oos/data/core/maybe.json deleted file mode 100644 index 82ff6a0..0000000 --- a/docs_oos/data/core/maybe.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "format": 1, - "id": "saw-maybe", - "kind": "alias", - "name": "maybe", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/common.hpp", - "type": ["std::optional< T >"], - "brief_description": "A value which may be absent, without that absence being a failure.", - "detailed_description": [ - [ - "Distinct from", - {"name": "error_or", "id": "saw-error_or"}, - "which says something went wrong. A maybe says a value is legitimately not there, as with an optional response slot where the caller may or may not have picked one." - ] - ], - "templates": [ - {"name": "T", "kind": "type"} - ] -} diff --git a/docs_oos/data/core/our.json b/docs_oos/data/core/our.json deleted file mode 100644 index e1ab459..0000000 --- a/docs_oos/data/core/our.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "format": 1, - "id": "saw-our", - "kind": "alias", - "name": "our", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/common.hpp", - "type": ["std::shared_ptr< T >"], - "brief_description": "Shared ownership of a heap object.", - "detailed_description": [ - [ - "Used where several parties genuinely keep something alive, such as a device handle held by both a server and the data allocated on it. Where one owner is enough, prefer", - {"name": "own", "id": "saw-own"} - ], - [ - "Created through", - {"name": "share", "id": "saw-share"} - ] - ], - "templates": [ - {"name": "T", "kind": "type"} - ] -} diff --git a/docs_oos/data/core/own.json b/docs_oos/data/core/own.json deleted file mode 100644 index 1716ab3..0000000 --- a/docs_oos/data/core/own.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "format": 1, - "id": "saw-own", - "kind": "alias", - "name": "own", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/common.hpp", - "type": ["std::unique_ptr< T >"], - "brief_description": "Sole ownership of a heap object.", - "detailed_description": [ - [ - "One of the four ownership words the codebase uses in place of raw pointers: own is sole ownership,", - {"name": "our", "id": "saw-our"}, - "is shared,", - {"name": "lent", "id": "saw-lent"}, - "is a weak borrow, and", - {"name": "ptr", "id": "saw-ptr"}, - "owns nothing at all." - ], - [ - "Created through", - {"name": "heap", "id": "saw-heap"}, - "rather than by calling new." - ] - ], - "templates": [ - {"name": "T", "kind": "type"} - ] -} diff --git a/docs_oos/data/core/parameter_key_pack_index.json b/docs_oos/data/core/parameter_key_pack_index.json deleted file mode 100644 index 1d88931..0000000 --- a/docs_oos/data/core/parameter_key_pack_index.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "format": 1, - "id": "saw-parameter_key_pack_index", - "kind": "struct", - "name": "parameter_key_pack_index", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/templates.hpp", - "brief_description": "Returns the position of a name in a pack of string literals.", - "detailed_description": [ - [ - "What turns a written name into an index. Looking a struct member up by its name, or an interface function by the literal handed to call, goes through this and then through", - {"name": "parameter_pack_type", "id": "saw-parameter_pack_type"}, - "to reach the type sitting at the same position." - ], - [ - "A name which is not in the pack is a compile error, which is why a misspelled member name fails at the call site." - ] - ], - "templates": [ - {"name": "V", "kind": "non_type", "type": "string_literal", "brief_description": "The name being looked for."}, - {"name": "Keys", "kind": "non_type", "type": "string_literal", "pack": true} - ], - "attributes": { - "saw-parameter_key_pack_index-value": { - "id": "saw-parameter_key_pack_index-value", - "name": "value", - "type": ["uint64_t"], - "visibility": "public", - "static": true, - "constexpr": true, - "brief_description": "Zero based position of the name." - } - } -} diff --git a/docs_oos/data/core/parameter_key_pack_type.json b/docs_oos/data/core/parameter_key_pack_type.json deleted file mode 100644 index bd3041f..0000000 --- a/docs_oos/data/core/parameter_key_pack_type.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "format": 1, - "id": "saw-parameter_key_pack_type", - "kind": "struct", - "name": "parameter_key_pack_type", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/templates.hpp", - "brief_description": "Returns the name at a position in a pack of string literals.", - "detailed_description": [ - [ - "The inverse of", - {"name": "parameter_key_pack_index", "id": "saw-parameter_key_pack_index"}, - "and the piece which makes compile time loops over named members possible: at index i it yields the literal, which can then be used as a template argument again." - ] - ], - "templates": [ - {"name": "i", "kind": "non_type", "type": "uint64_t", "brief_description": "Zero based position."}, - {"name": "Keys", "kind": "non_type", "type": "string_literal", "pack": true} - ], - "attributes": { - "saw-parameter_key_pack_type-literal": { - "id": "saw-parameter_key_pack_type-literal", - "name": "literal", - "type": [{"name": "string_literal", "id": "saw-string_literal"}], - "visibility": "public", - "static": true, - "constexpr": true, - "brief_description": "The name at that position." - } - } -} diff --git a/docs_oos/data/core/parameter_pack_index.json b/docs_oos/data/core/parameter_pack_index.json deleted file mode 100644 index a553e31..0000000 --- a/docs_oos/data/core/parameter_pack_index.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "format": 1, - "id": "saw-parameter_pack_index", - "kind": "struct", - "name": "parameter_pack_index", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/templates.hpp", - "brief_description": "Returns the position of a type in a parameter pack.", - "detailed_description": [ - [ - "The inverse of", - {"name": "parameter_pack_type", "id": "saw-parameter_pack_type"}, - "Recurses until the head matches, so a type which is not in the pack fails to compile rather than yielding a wrong index." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "The type being looked for."}, - {"name": "TL", "kind": "type", "pack": true, "brief_description": "The pack to search."} - ], - "attributes": { - "saw-parameter_pack_index-value": { - "id": "saw-parameter_pack_index-value", - "name": "value", - "type": ["size_t"], - "visibility": "public", - "static": true, - "constexpr": true, - "brief_description": "Zero based position of T in the pack." - } - } -} diff --git a/docs_oos/data/core/parameter_pack_type.json b/docs_oos/data/core/parameter_pack_type.json deleted file mode 100644 index 2175cdd..0000000 --- a/docs_oos/data/core/parameter_pack_type.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "format": 1, - "id": "saw-parameter_pack_type", - "kind": "struct", - "name": "parameter_pack_type", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/templates.hpp", - "brief_description": "Returns the type at a position in a parameter pack.", - "detailed_description": [ - [ - "The workhorse of every compile time loop in this codebase. Recursion over an index plus this is how a struct, a tuple or an interface is walked member by member, since a pack cannot be indexed directly." - ] - ], - "templates": [ - {"name": "N", "kind": "non_type", "type": "size_t", "brief_description": "Zero based position."}, - {"name": "T", "kind": "type", "pack": true} - ], - "aliases": { - "saw-parameter_pack_type-type": { - "id": "saw-parameter_pack_type-type", - "name": "type", - "type": ["the Nth type of T..."], - "brief_description": "The type at that position." - } - } -} diff --git a/docs_oos/data/core/parameter_pack_value.json b/docs_oos/data/core/parameter_pack_value.json deleted file mode 100644 index 920bd09..0000000 --- a/docs_oos/data/core/parameter_pack_value.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "format": 1, - "id": "saw-parameter_pack_value", - "kind": "struct", - "name": "parameter_pack_value", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/templates.hpp", - "brief_description": "Returns the value at a position in a value pack.", - "detailed_description": [ - [ - "The value counterpart of", - {"name": "parameter_pack_type", "id": "saw-parameter_pack_type"}, - "used where a pack of numbers has to be indexed, such as the dimensions of a fixed size array." - ] - ], - "templates": [ - {"name": "i", "kind": "non_type", "type": "uint64_t", "brief_description": "Zero based position."}, - {"name": "T", "kind": "type", "brief_description": "Type of the values."}, - {"name": "V", "kind": "non_type", "type": "T", "pack": true} - ], - "attributes": { - "saw-parameter_pack_value-value": { - "id": "saw-parameter_pack_value-value", - "name": "value", - "type": ["T"], - "visibility": "public", - "static": true, - "constexpr": true, - "brief_description": "The value at that position." - } - } -} diff --git a/docs_oos/data/core/ptr.json b/docs_oos/data/core/ptr.json deleted file mode 100644 index 50fea1a..0000000 --- a/docs_oos/data/core/ptr.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "format": 1, - "id": "saw-ptr", - "kind": "class", - "name": "ptr", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/common.hpp", - "brief_description": "Non owning pointer which may be empty.", - "detailed_description": [ - [ - "States in the type system that something is referred to but not owned. Copyable and reassignable, unlike", - {"name": "ref", "id": "saw-ref"}, - "and checkable, unlike a reference." - ], - [ - "Dereferencing goes through the call operator rather than through star or arrow, which keeps the indirection visible at every use." - ], - [ - "Nothing here tracks lifetime. A ptr outliving its target is a bug the type cannot catch, which is why the classes holding one, such as the data servers, forbid moving themselves." - ] - ], - "templates": [ - {"name": "T", "kind": "type"} - ], - "attributes": { - "saw-ptr-ptr_": { - "id": "saw-ptr-ptr_", - "name": "ptr_", - "type": ["T *"], - "visibility": "private" - } - }, - "functions": { - "saw-ptr-ctor-1": { - "id": "saw-ptr-ctor-1", - "name": "ptr", - "type": [], - "brief_description": "Empty." - }, - "saw-ptr-ctor-2": { - "id": "saw-ptr-ctor-2", - "name": "ptr", - "type": [], - "brief_description": "Pointing at an object. Implicit, so passing an object where a ptr is expected just works.", - "parameters": [ - {"name": "ptr__", "type": ["T &"]} - ] - }, - "saw-ptr-call": { - "id": "saw-ptr-call", - "name": "operator()", - "type": ["T &"], - "brief_description": "The pointed at object. Undefined if empty." - }, - "saw-ptr-is_valid": { - "id": "saw-ptr-is_valid", - "name": "is_valid", - "type": ["bool"], - "const": true, - "brief_description": "Whether it points at anything." - } - } -} diff --git a/docs_oos/data/core/ref.json b/docs_oos/data/core/ref.json deleted file mode 100644 index 518a5d6..0000000 --- a/docs_oos/data/core/ref.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "format": 1, - "id": "saw-ref", - "kind": "class", - "name": "ref", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/common.hpp", - "brief_description": "Reference class for easier distinction of references and their referenced types.", - "detailed_description": [ - [ - "Always refers to something, so unlike", - {"name": "ptr", "id": "saw-ptr"}, - "it has no empty state and no validity check." - ], - [ - "Moving is forbidden, since that would invalidate the type, while copying is allowed. It is constexpr throughout, so it can be formed and followed at compile time." - ] - ], - "templates": [ - {"name": "T", "kind": "type"} - ], - "attributes": { - "saw-ref-ref_": { - "id": "saw-ref-ref_", - "name": "ref_", - "type": ["T *"], - "visibility": "private" - } - }, - "functions": { - "saw-ref-ctor": { - "id": "saw-ref-ctor", - "name": "ref", - "type": [], - "parameters": [ - {"name": "ref__", "type": ["T &"]} - ] - }, - "saw-ref-call": { - "id": "saw-ref-call", - "name": "operator()", - "type": ["T &"], - "brief_description": "The referenced object." - } - } -} diff --git a/docs_oos/data/core/ring_buffer.json b/docs_oos/data/core/ring_buffer.json deleted file mode 100644 index eb6a0d0..0000000 --- a/docs_oos/data/core/ring_buffer.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "format": 1, - "id": "saw-ring_buffer", - "kind": "class", - "name": "ring_buffer", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/buffer.hpp", - "brief_description": "Buffer wrapping around if the read cursor caught up.", - "detailed_description": [ - [ - "Fixed capacity, reused in place. Suited to a stream where bytes are produced and consumed continuously, since nothing is allocated after construction." - ], - [ - "The capacity does not grow, so a write beyond what the reader has freed fails with", - {"name": "buffer_exhausted", "id": "saw-err-buffer_exhausted"}, - "rather than resizing." - ] - ], - "bases": [ - [{"name": "buffer", "id": "saw-buffer"}] - ], - "attributes": { - "saw-ring_buffer-write_reached_read_": { - "id": "saw-ring_buffer-write_reached_read_", - "name": "write_reached_read_", - "type": ["bool"], - "visibility": "private", - "brief_description": "Distinguishes a full buffer from an empty one, since both have equal cursors." - } - }, - "functions": { - "saw-ring_buffer-ctor-1": { - "id": "saw-ring_buffer-ctor-1", - "name": "ring_buffer", - "type": [], - "brief_description": "With the default capacity of RING_BUFFER_MAX_SIZE bytes." - }, - "saw-ring_buffer-ctor-2": { - "id": "saw-ring_buffer-ctor-2", - "name": "ring_buffer", - "type": [], - "parameters": [ - {"name": "size", "type": ["size_t"]} - ] - }, - "saw-ring_buffer-size": { - "id": "saw-ring_buffer-size", - "name": "size", - "type": ["size_t"], - "const": true, - "brief_description": "Total capacity, not the amount currently held." - } - } -} diff --git a/docs_oos/data/core/share.json b/docs_oos/data/core/share.json deleted file mode 100644 index 4d1df1f..0000000 --- a/docs_oos/data/core/share.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "format": 1, - "id": "saw-share", - "kind": "function", - "name": "share", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/common.hpp", - "type": [{"name": "our", "id": "saw-our"}, "< T >"], - "brief_description": "Constructs an object on the heap under shared ownership.", - "detailed_description": [ - [ - "The counterpart of", - {"name": "heap", "id": "saw-heap"}, - "for the cases where ownership is genuinely shared." - ] - ], - "templates": [ - {"name": "T", "kind": "type"}, - {"name": "Args", "kind": "type", "pack": true} - ], - "parameters": [ - {"name": "args", "type": ["Args &&..."], "brief_description": "Forwarded to the constructor of T."} - ] -} diff --git a/docs_oos/data/core/string_literal.json b/docs_oos/data/core/string_literal.json deleted file mode 100644 index 4bd6e9b..0000000 --- a/docs_oos/data/core/string_literal.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "format": 1, - "id": "saw-string_literal", - "kind": "class", - "name": "string_literal", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/string_literal.hpp", - "brief_description": "Helper object which turns a string literal into a template parameter.", - "detailed_description": [ - [ - "It guarantees compile time uniqueness and thus allows using strings in template parameters. Everything in this codebase which is addressed by name rests on it: struct members, interface functions, and the schema hashes derived from them." - ], - [ - "Because the length is part of the type, two literals of different length are different types, and comparing them is a compile time false rather than an error." - ] - ], - "templates": [ - {"name": "CharT", "kind": "type"}, - {"name": "N", "kind": "non_type", "type": "size_t", "brief_description": "Length including the null terminator."} - ], - "attributes": { - "saw-string_literal-data": { - "id": "saw-string_literal-data", - "name": "data", - "type": ["std::array< CharT, N >"], - "visibility": "public" - } - }, - "functions": { - "saw-string_literal-ctor": { - "id": "saw-string_literal-ctor", - "name": "string_literal", - "type": [], - "brief_description": "From a literal. Copies it character by character so the whole thing is constexpr.", - "parameters": [ - {"name": "input", "type": ["const CharT (&)[N]"]} - ] - }, - "saw-string_literal-view": { - "id": "saw-string_literal-view", - "name": "view", - "type": ["std::string_view"], - "const": true, - "brief_description": "The literal as a view, for the places which compare against runtime strings." - }, - "saw-string_literal-eq": { - "id": "saw-string_literal-eq", - "name": "operator==", - "type": ["bool"], - "const": true, - "brief_description": "Equality. A literal of different length is never equal.", - "parameters": [ - {"name": "rhs", "type": ["const string_literal< CharTR, NR > &"]} - ] - }, - "saw-string_literal-plus": { - "id": "saw-string_literal-plus", - "name": "operator+", - "type": ["string_literal< CharT, N+NR-1 >"], - "const": true, - "brief_description": "Concatenation, dropping the null terminator of the left side.", - "templates": [ - {"name": "NR", "kind": "non_type", "type": "size_t"} - ], - "parameters": [ - {"name": "rhs", "type": ["const string_literal< CharT, NR > &"]} - ] - } - }, - "notes": [ - "The literal operator \"\"_sl builds one from a quoted string." - ] -} diff --git a/docs_oos/data/core/tmpl_concat.json b/docs_oos/data/core/tmpl_concat.json deleted file mode 100644 index 8260faa..0000000 --- a/docs_oos/data/core/tmpl_concat.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "format": 1, - "id": "saw-tmpl_concat", - "kind": "struct", - "name": "tmpl_concat", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/templates.hpp", - "brief_description": "Concats two groups into one.", - "detailed_description": [ - [ - "Declared only; the work happens in the specializations, one for", - {"name": "tmpl_group", "id": "saw-tmpl_group"}, - "and one for", - {"name": "tmpl_value_group", "id": "saw-tmpl_value_group"}, - "so concatenating anything else is a compile error rather than a surprise." - ], - [ - "The value groups have to agree on their value type, which the specialization enforces by binding it once for both sides." - ] - ], - "templates": [ - {"name": "T", "kind": "type"}, - {"name": "U", "kind": "type"} - ], - "aliases": { - "saw-tmpl_concat-type": { - "id": "saw-tmpl_concat-type", - "name": "type", - "type": ["tmpl_group< T..., U... >"], - "brief_description": "The joined group. Only present on the specializations." - } - } -} diff --git a/docs_oos/data/core/tmpl_group.json b/docs_oos/data/core/tmpl_group.json deleted file mode 100644 index c999492..0000000 --- a/docs_oos/data/core/tmpl_group.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "format": 1, - "id": "saw-tmpl_group", - "kind": "struct", - "name": "tmpl_group", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/templates.hpp", - "brief_description": "A list of types, carried as a type.", - "detailed_description": [ - [ - "Lets a pack be passed around, stored in an alias and handed to another template, which a bare parameter pack cannot. The remote layer uses one to name every schema an interface mentions, and then maps it to a tuple of servers." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "pack": true} - ], - "attributes": { - "saw-tmpl_group-name": { - "id": "saw-tmpl_group-name", - "name": "name", - "type": [{"name": "string_literal", "id": "saw-string_literal"}], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"tmpl_group\"", - "brief_description": "Used when hashing a group." - }, - "saw-tmpl_group-size": { - "id": "saw-tmpl_group-size", - "name": "size", - "type": ["uint64_t"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "sizeof...(T)" - } - } -} diff --git a/docs_oos/data/core/tmpl_reduce.json b/docs_oos/data/core/tmpl_reduce.json deleted file mode 100644 index 495738d..0000000 --- a/docs_oos/data/core/tmpl_reduce.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "format": 1, - "id": "saw-tmpl_reduce", - "kind": "struct", - "name": "tmpl_reduce", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/reduce_templates.hpp", - "brief_description": "Removes duplicate types from a group.", - "detailed_description": [ - [ - "Turns a", - {"name": "tmpl_group", "id": "saw-tmpl_group"}, - "into one where every type appears once. The remote layer needs it because an interface mentions a schema once per function, while there must be exactly one data server per schema." - ], - [ - "It is also what makes the tuple lookups work: fetching an element by type requires that type to occur exactly once." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "The group to reduce."} - ], - "aliases": { - "saw-tmpl_reduce-type": { - "id": "saw-tmpl_reduce-type", - "name": "type", - "type": ["typename impl::tmpl_group_reduce< T >::reduced_type"], - "brief_description": "The group without duplicates." - } - } -} diff --git a/docs_oos/data/core/tmpl_value_group.json b/docs_oos/data/core/tmpl_value_group.json deleted file mode 100644 index 0ebff2c..0000000 --- a/docs_oos/data/core/tmpl_value_group.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "format": 1, - "id": "saw-tmpl_value_group", - "kind": "struct", - "name": "tmpl_value_group", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/templates.hpp", - "brief_description": "A list of values of one type, carried as a type.", - "detailed_description": [ - [ - "The value counterpart of", - {"name": "tmpl_group", "id": "saw-tmpl_group"}, - "for packs of numbers such as array dimensions." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "Type of the values."}, - {"name": "values", "kind": "non_type", "type": "T", "pack": true} - ], - "attributes": { - "saw-tmpl_value_group-name": { - "id": "saw-tmpl_value_group-name", - "name": "name", - "type": [{"name": "string_literal", "id": "saw-string_literal"}], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "\"tmpl_value_group\"" - }, - "saw-tmpl_value_group-size": { - "id": "saw-tmpl_value_group-size", - "name": "size", - "type": ["uint64_t"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "sizeof...(values)" - } - } -} diff --git a/docs_oos/data/core/tree.json b/docs_oos/data/core/tree.json deleted file mode 100644 index 3236859..0000000 --- a/docs_oos/data/core/tree.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "format": 1, - "id": "saw-tree", - "kind": "class", - "name": "tree", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/tree.hpp", - "brief_description": "A tree of values, tying the recursive knot.", - "detailed_description": [ - [ - "A thin wrapper over a", - {"name": "tree_container", "id": "saw-tree_container"}, - "whose branches hold this very type. The container and the", - {"name": "branch", "id": "saw-branch"}, - "are written against an open Tree parameter precisely so that this class can close it, which keeps the two of them usable for other node types as well." - ], - [ - "This is the type to reach for; the other two are the machinery underneath." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "Leaf value type."} - ], - "attributes": { - "saw-tree-data_": { - "id": "saw-tree-data_", - "name": "data_", - "type": [{"name": "tree_container", "id": "saw-tree_container"}, "< T, tree< T > >"], - "visibility": "private" - } - }, - "functions": { - "saw-tree-reserve": { - "id": "saw-tree-reserve", - "name": "reserve", - "type": ["error_or< void >"], - "brief_description": "Reserves room for branches up front.", - "parameters": [ - {"name": "size", "type": ["std::size_t"]} - ] - }, - "saw-tree-size": { - "id": "saw-tree-size", - "name": "size", - "type": ["size_t"], - "const": true, - "brief_description": "Number of branches directly below this node." - }, - "saw-tree-add-1": { - "id": "saw-tree-add-1", - "name": "add", - "type": ["error_or< size_t >"], - "brief_description": "Adds a branch holding a sub tree and returns its index." - }, - "saw-tree-add-2": { - "id": "saw-tree-add-2", - "name": "add", - "type": ["error_or< size_t >"], - "brief_description": "Adds a branch holding a leaf and returns its index.", - "parameters": [ - {"name": "leaf", "type": ["T"]} - ] - }, - "saw-tree-at": { - "id": "saw-tree-at", - "name": "at", - "type": [{"name": "branch", "id": "saw-branch"}, "< T, tree< T > > &"], - "brief_description": "The branch at an index.", - "parameters": [ - {"name": "i", "type": ["size_t"]} - ] - } - } -} diff --git a/docs_oos/data/core/tree_container.json b/docs_oos/data/core/tree_container.json deleted file mode 100644 index 5f01db8..0000000 --- a/docs_oos/data/core/tree_container.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "format": 1, - "id": "saw-tree_container", - "kind": "class", - "name": "tree_container", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/tree.hpp", - "brief_description": "Tree object holding branches.", - "detailed_description": [ - [ - "The name comes from the fact that a tree acts as a node while the", - {"name": "branch", "id": "saw-branch"}, - "class is the edge to a leaf or to other nodes. A container holds the branches, and each branch either has a leaf or another sub tree." - ], - [ - "Growing is done through add, which reports failure as a value instead of throwing, so a tree can be built in code which must not throw." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "Leaf value type."}, - {"name": "Tree", "kind": "type", "brief_description": "The tree type a branch may hold instead of a leaf."} - ], - "attributes": { - "saw-tree_container-children_": { - "id": "saw-tree_container-children_", - "name": "children_", - "type": ["std::vector<", {"name": "branch", "id": "saw-branch"}, "< T, Tree > >"], - "visibility": "private", - "brief_description": "Object holding the branch instances." - } - }, - "functions": { - "saw-tree_container-reserve": { - "id": "saw-tree_container-reserve", - "name": "reserve", - "type": ["error_or< void >"], - "brief_description": "Reserves room for branches up front.", - "parameters": [ - {"name": "siz", "type": ["std::size_t"]} - ] - }, - "saw-tree_container-add-1": { - "id": "saw-tree_container-add-1", - "name": "add", - "type": ["error_or< std::size_t >"], - "brief_description": "Adds a branch holding a leaf.", - "parameters": [ - {"name": "leaf", "type": ["T"]} - ] - }, - "saw-tree_container-add-2": { - "id": "saw-tree_container-add-2", - "name": "add", - "type": ["error_or< std::size_t >"], - "brief_description": "Adds a branch holding a sub tree." - }, - "saw-tree_container-size": { - "id": "saw-tree_container-size", - "name": "size", - "type": ["std::size_t"], - "const": true, - "brief_description": "Number of branches." - }, - "saw-tree_container-at": { - "id": "saw-tree_container-at", - "name": "at", - "type": [{"name": "branch", "id": "saw-branch"}, "< T, Tree > &"], - "brief_description": "The branch at an index.", - "parameters": [ - {"name": "i", "type": ["std::size_t"]} - ] - } - }, - "notes": [ - "Copy is forbidden, move is allowed." - ] -} diff --git a/docs_oos/data/core/void_t.json b/docs_oos/data/core/void_t.json deleted file mode 100644 index c21bc20..0000000 --- a/docs_oos/data/core/void_t.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "format": 1, - "id": "saw-void_t", - "kind": "struct", - "name": "void_t", - "namespace": "saw", - "module": "core", - "header": "modules/core/c++/common.hpp", - "brief_description": "Struct describing a void type.", - "detailed_description": [ - [ - "An empty type standing in for void where a real type is needed. It is what lets", - {"name": "error_or", "id": "saw-error_or"}, - "< void > hold a variant at all, since a variant cannot have a void alternative." - ], - [ - "The substitution happens in fix_void and is undone by unfix_void, so the stand in stays an implementation detail of the templates rather than something a caller writes. Returning make_void is how a function which succeeded but has nothing to say says so." - ] - ] -} diff --git a/docs_oos/data/remote/data_client.json b/docs_oos/data/remote/data_client.json deleted file mode 100644 index fc717b6..0000000 --- a/docs_oos/data/remote/data_client.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "format": 1, - "id": "saw-data_client", - "kind": "class", - "name": "data_client", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/transfer.hpp", - "brief_description": "Handle on a data server of one schema.", - "detailed_description": [ - [ - "The caller side of the transport layer. Values are sent and received through it, and ids are what comes back, since the data itself stays on the", - {"name": "data_server", "id": "saw-data_server"} - ], - [ - "Only declared by the primary template and defined per backend." - ] - ], - "templates": [ - {"name": "Schema", "kind": "type", "brief_description": "Schema of the transported data."}, - {"name": "Encoding", "kind": "type", "brief_description": "Encoding of the transported data."}, - {"name": "Remote", "kind": "type", "brief_description": "Tag type of the backend."} - ], - "specializations": [ - { - "name": "data_client< Schema, Encoding, rmt::Loopback >", - "id": "saw-data_client-loopback", - "brief_description": "Talks to a server in the same process, so nothing is serialized." - } - ] -} diff --git a/docs_oos/data/remote/data_client.loopback.json b/docs_oos/data/remote/data_client.loopback.json deleted file mode 100644 index 515209d..0000000 --- a/docs_oos/data/remote/data_client.loopback.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "format": 1, - "id": "saw-data_client-loopback", - "kind": "class", - "name": "data_client", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/transfer_loopback.hpp", - "is_special": true, - "specializes": "saw-data_client", - "arguments": ["Schema", "Encoding", "rmt::Loopback"], - "brief_description": "Talks to a data server in the same process.", - "detailed_description": [ - [ - "Every call forwards straight to the server, so nothing is serialized and nothing can fail on the way. Ids are asked for rather than guessed, because the server is the only instance which knows about every client." - ] - ], - "templates": [ - {"name": "Schema", "kind": "type"}, - {"name": "Encoding", "kind": "type"} - ], - "attributes": { - "saw-data_client-loopback-srv_": { - "id": "saw-data_client-loopback-srv_", - "name": "srv_", - "type": ["ptr<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< Schema, Encoding, rmt::Loopback > >"], - "visibility": "private" - } - }, - "functions": { - "saw-data_client-loopback-next_free_id": { - "id": "saw-data_client-loopback-next_free_id", - "name": "next_free_id", - "type": ["error_or< id< Schema > >"], - "brief_description": "Asks the remote for an id which is not in use yet.", - "detailed_description": [ - [ - "Free here, a roundtrip on a backend which is not in process. Worth avoiding when the server can pick the id itself." - ] - ] - }, - "saw-data_client-loopback-send-1": { - "id": "saw-data_client-loopback-send-1", - "name": "send", - "type": ["error_or< id< Schema > >"], - "brief_description": "Sends data to the remote and returns the id it was stored under.", - "parameters": [ - {"name": "dat", "type": ["const data< Schema, Encoding > &"]} - ] - }, - "saw-data_client-loopback-send-2": { - "id": "saw-data_client-loopback-send-2", - "name": "send", - "type": ["error_or< void >"], - "brief_description": "Sends data to the remote and stores it under a specific id.", - "parameters": [ - {"name": "dat", "type": ["const data< Schema, Encoding > &"]}, - {"name": "dat_id", "type": ["id< Schema >"]} - ] - }, - "saw-data_client-loopback-allocate": { - "id": "saw-data_client-loopback-allocate", - "name": "allocate", - "type": ["error_or< id< Schema > >"], - "brief_description": "Preallocates data on the remote without sending a value.", - "parameters": [ - { - "name": "meta", - "type": ["const data< typename meta_schema< Schema >::MetaSchema, Encoding > &"], - "brief_description": "Dimensions and whatever else the schema needs to exist." - } - ] - }, - "saw-data_client-loopback-receive": { - "id": "saw-data_client-loopback-receive", - "name": "receive", - "type": ["conveyor< data< Schema, Encoding > >"], - "brief_description": "Receives the data stored under an id.", - "detailed_description": [ - [ - "A conveyor even though this backend answers immediately, so code written against it keeps working on a backend which has to wait." - ] - ], - "parameters": [ - {"name": "dat_id", "type": ["id< Schema >"]} - ] - }, - "saw-data_client-loopback-erase": { - "id": "saw-data_client-loopback-erase", - "name": "erase", - "type": ["error_or< void >"], - "brief_description": "Erases the data stored under an id.", - "parameters": [ - {"name": "dat_id", "type": ["id< Schema >"]} - ] - }, - "saw-data_client-loopback-find": { - "id": "saw-data_client-loopback-find", - "name": "find", - "type": ["error_or< ptr< data< Schema, Encoding > > >"], - "brief_description": "Returns a pointer to the stored data itself.", - "detailed_description": [ - [ - "An exception for this backend. Here it is safe to use find from the client side, because the data never left the process." - ] - ], - "parameters": [ - {"name": "dat_id", "type": ["id< Schema >"]} - ] - } - } -} diff --git a/docs_oos/data/remote/data_or_id.json b/docs_oos/data/remote/data_or_id.json deleted file mode 100644 index c3152e9..0000000 --- a/docs_oos/data/remote/data_or_id.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "format": 1, - "id": "saw-data_or_id", - "kind": "class", - "name": "data_or_id", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote.hpp", - "brief_description": "Helper for rpc calls. Either a value or its place on the remote.", - "detailed_description": [ - [ - "A parameter is in one of two states: still here, or already on the remote from an earlier call. This carries both so a call site doesn't have to branch, and so a result can be fed into the next call without a roundtrip." - ], - [ - "Both constructors are implicit, which is what lets a plain value be passed where a call expects one of these." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "Schema of the data."}, - {"name": "Encoding", "kind": "type"} - ], - "attributes": { - "saw-data_or_id-doi_": { - "id": "saw-data_or_id-doi_", - "name": "doi_", - "type": ["std::variant< id< T >, data< T, Encoding > >"], - "visibility": "private", - "brief_description": "Variant representing either the id or the data class." - } - }, - "functions": { - "saw-data_or_id-ctor-1": { - "id": "saw-data_or_id-ctor-1", - "name": "data_or_id", - "type": [], - "brief_description": "Refers to data already on the remote.", - "parameters": [ - {"name": "val", "type": ["const id< T > &"]} - ] - }, - "saw-data_or_id-ctor-2": { - "id": "saw-data_or_id-ctor-2", - "name": "data_or_id", - "type": [], - "brief_description": "Carries data which still has to be sent.", - "parameters": [ - {"name": "val", "type": ["data< T, Encoding >"]} - ] - }, - "saw-data_or_id-is_id": { - "id": "saw-data_or_id-is_id", - "name": "is_id", - "type": ["bool"], - "const": true, - "brief_description": "Checks if this class holds an id." - }, - "saw-data_or_id-is_data": { - "id": "saw-data_or_id-is_data", - "name": "is_data", - "type": ["bool"], - "const": true, - "brief_description": "Checks if this class holds data." - }, - "saw-data_or_id-get_id": { - "id": "saw-data_or_id-get_id", - "name": "get_id", - "type": ["id< T >"], - "const": true, - "brief_description": "Returns the id." - }, - "saw-data_or_id-get_data": { - "id": "saw-data_or_id-get_data", - "name": "get_data", - "type": ["data< T, Encoding > &"], - "brief_description": "Returns a data reference." - } - } -} diff --git a/docs_oos/data/remote/data_server.json b/docs_oos/data/remote/data_server.json deleted file mode 100644 index 1be7c93..0000000 --- a/docs_oos/data/remote/data_server.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "format": 1, - "id": "saw-data_server", - "kind": "class", - "name": "data_server", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/transfer.hpp", - "brief_description": "Owns the data of one schema on one backend.", - "detailed_description": [ - [ - "The transport layer. A data server stores values under ids and is the only thing which knows where they physically live." - ], - [ - "The", - {"name": "rpc_server", "id": "saw-rpc_server"}, - "is an overlay on top of it and never touches the data itself, only the ids. That split is what lets the same interface run against memory, a file or a device." - ] - ], - "templates": [ - { - "name": "Schema", - "kind": "type", - "brief_description": "Schema of the stored data." - }, - { - "name": "Encoding", - "kind": "type", - "brief_description": "Encoding the data is stored in." - }, - { - "name": "Remote", - "kind": "type", - "brief_description": "Tag type of the backend." - } - ], - "specializations": [ - { - "name": "data_server< Schema, Encoding, rmt::Loopback >", - "id": "saw-data_server-loopback", - "brief_description": "Keeps the values in a map in this process." - } - ] -} diff --git a/docs_oos/data/remote/data_server.loopback.json b/docs_oos/data/remote/data_server.loopback.json deleted file mode 100644 index daca8e0..0000000 --- a/docs_oos/data/remote/data_server.loopback.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "format": 1, - "id": "saw-data_server-loopback", - "kind": "class", - "name": "data_server", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/transfer_loopback.hpp", - "is_special": true, - "specializes": "saw-data_server", - "arguments": ["Schema", "Encoding", "rmt::Loopback"], - "brief_description": "Keeps the values of one schema in a map in this process.", - "detailed_description": [ - [ - "Registers itself with its", - {"name": "remote", "id": "saw-remote-loopback"}, - "on construction and deregisters on destruction, so its lifetime is what a client sees as the server being reachable." - ], - [ - "Ids are owned by the server, since it is the only instance which knows about every client." - ] - ], - "templates": [ - {"name": "Schema", "kind": "type"}, - {"name": "Encoding", "kind": "type"} - ], - "attributes": { - "saw-data_server-loopback-class_id": { - "id": "saw-data_server-loopback-class_id", - "name": "class_id", - "type": ["std::pair< uint32_t, uint32_t >"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "{schema_hash::apply(), schema_hash::apply()}", - "brief_description": "Unique key for identifying an underlying data type without using typeid." - }, - "saw-data_server-loopback-values_": { - "id": "saw-data_server-loopback-values_", - "name": "values_", - "type": ["std::unordered_map< uint64_t, data< Schema, Encoding > >"], - "visibility": "private" - }, - "saw-data_server-loopback-next_id_": { - "id": "saw-data_server-loopback-next_id_", - "name": "next_id_", - "type": ["uint64_t"], - "visibility": "private", - "initializer": "0u", - "brief_description": "Counter for handing out ids." - } - }, - "functions": { - "saw-data_server-loopback-get_class_id": { - "id": "saw-data_server-loopback-get_class_id", - "name": "get_class_id", - "type": ["std::pair< uint32_t, uint32_t >"], - "const": true, - "override": true, - "brief_description": "Returns the schema id." - }, - "saw-data_server-loopback-next_free_id": { - "id": "saw-data_server-loopback-next_free_id", - "name": "next_free_id", - "type": ["id< Schema >"], - "brief_description": "Hands out the next id which is not in use yet.", - "detailed_description": [ - [ - "The id is not reserved by this call. It is only in use once something is stored under it, so two calls without a store in between return the same id." - ] - ] - }, - "saw-data_server-loopback-send-1": { - "id": "saw-data_server-loopback-send-1", - "name": "send", - "type": ["error_or< void >"], - "brief_description": "Stores a value under an id without taking over the source.", - "detailed_description": [ - ["Fails with already_exists if the id is taken."] - ], - "parameters": [ - {"name": "dat", "type": ["ref< data< Schema, Encoding > >"]}, - {"name": "store_id", "type": ["id< Schema >"]} - ] - }, - "saw-data_server-loopback-send-2": { - "id": "saw-data_server-loopback-send-2", - "name": "send", - "type": ["error_or< void >"], - "brief_description": "Stores a value under an id, taking it over.", - "detailed_description": [ - ["Fails with already_exists if the id is taken."] - ], - "parameters": [ - {"name": "dat", "type": ["data< Schema, Encoding >"]}, - {"name": "store_id", "type": ["id< Schema >"]} - ] - }, - "saw-data_server-loopback-allocate": { - "id": "saw-data_server-loopback-allocate", - "name": "allocate", - "type": ["error_or< void >"], - "brief_description": "Reserves storage described by the meta schema without sending a value.", - "detailed_description": [ - [ - "The counterpart to sending for backends where the output has to exist before it is written, such as a device buffer." - ] - ], - "parameters": [ - { - "name": "meta", - "type": ["data< typename meta_schema< Schema >::MetaSchema, Encoding >"], - "brief_description": "Dimensions and whatever else the schema needs to exist." - }, - {"name": "store_id", "type": ["id< Schema >"]} - ] - }, - "saw-data_server-loopback-receive": { - "id": "saw-data_server-loopback-receive", - "name": "receive", - "type": ["error_or< data< Schema, Encoding > >"], - "brief_description": "Returns a copy of the value stored under an id.", - "detailed_description": [ - ["Fails with not_found if nothing is stored under that id."] - ], - "parameters": [ - {"name": "store_id", "type": ["id< Schema >"]} - ] - }, - "saw-data_server-loopback-erase": { - "id": "saw-data_server-loopback-erase", - "name": "erase", - "type": ["error_or< void >"], - "brief_description": "Drops the value stored under an id.", - "detailed_description": [ - ["Fails with not_found if nothing is stored under that id."] - ], - "parameters": [ - {"name": "store_id", "type": ["id< Schema >"]} - ] - }, - "saw-data_server-loopback-find": { - "id": "saw-data_server-loopback-find", - "name": "find", - "type": ["error_or< ptr< data< Schema, Encoding > > >"], - "brief_description": "Returns a pointer to the stored value itself.", - "detailed_description": [ - [ - "An exception for this backend. Only meaningful because the data is in process, and a store may invalidate the pointer." - ], - [ - "The", - {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, - "uses it to hand a parameter to an interface function without copying it out of the server first." - ] - ], - "parameters": [ - {"name": "store_id", "type": ["id< Schema >"]} - ] - } - }, - "notes": [ - "Copy and move are forbidden, because the remote holds a pointer to this object while it is registered." - ] -} diff --git a/docs_oos/data/remote/i_data_server.json b/docs_oos/data/remote/i_data_server.json deleted file mode 100644 index ecde59c..0000000 --- a/docs_oos/data/remote/i_data_server.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "format": 1, - "id": "saw-i_data_server", - "kind": "class", - "name": "i_data_server", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/transfer.hpp", - "brief_description": "Registry handle for a data server of unknown schema.", - "detailed_description": [ - [ - "The one place the library erases a type. A", - {"name": "remote", "id": "saw-remote"}, - "holds servers for many schemas in one map, which is only possible if they share a type. The class id recovers what was erased: a caller which knows the schema it wants asks for exactly that one and gets an error if the stored server is a different one." - ], - [ - "The destructor is protected, so nothing can be deleted through this handle." - ] - ], - "templates": [ - { - "name": "Remote", - "kind": "type", - "brief_description": "Tag type of the backend." - } - ], - "functions": { - "saw-i_data_server-get_class_id": { - "id": "saw-i_data_server-get_class_id", - "name": "get_class_id", - "type": ["std::pair< uint32_t, uint32_t >"], - "const": true, - "virtual": true, - "brief_description": "Schema hash and encoding hash of the server behind this handle." - }, - "saw-i_data_server-cast_to": { - "id": "saw-i_data_server-cast_to", - "name": "cast_to", - "type": ["error_or< ptr< To > >"], - "brief_description": "Recovers the concrete server.", - "detailed_description": [ - ["Fails with invalid_state if the class ids don't match, which is what keeps the erasure honest."] - ], - "templates": [ - { - "name": "To", - "kind": "type", - "brief_description": "The concrete data server expected behind this handle." - } - ] - } - } -} diff --git a/docs_oos/data/remote/i_rpc_server.json b/docs_oos/data/remote/i_rpc_server.json deleted file mode 100644 index b648f4c..0000000 --- a/docs_oos/data/remote/i_rpc_server.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "format": 1, - "id": "saw-i_rpc_server", - "kind": "class", - "name": "i_rpc_server", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote.hpp", - "brief_description": "Registry handle for an rpc server of unknown interface.", - "detailed_description": [ - [ - "The counterpart of", - {"name": "i_data_server", "id": "saw-i_data_server"}, - "for the rpc layer. It exists so a remote can keep servers of different interfaces in one map and hand back the right one when a client requests it." - ], - [ - "Here the class id is the interface hash together with the encoding hash, so connecting with a different interface than the one being served fails instead of reinterpreting the server." - ] - ], - "templates": [ - { - "name": "Remote", - "kind": "type", - "brief_description": "Tag type of the backend." - } - ], - "functions": { - "saw-i_rpc_server-get_class_id": { - "id": "saw-i_rpc_server-get_class_id", - "name": "get_class_id", - "type": ["std::pair< uint32_t, uint32_t >"], - "const": true, - "virtual": true, - "brief_description": "Interface hash and encoding hash of the server behind this handle." - }, - "saw-i_rpc_server-cast_to": { - "id": "saw-i_rpc_server-cast_to", - "name": "cast_to", - "type": ["error_or< ptr< To > >"], - "brief_description": "Recovers the concrete server.", - "detailed_description": [ - ["Fails with invalid_state if the class ids don't match."] - ], - "templates": [ - { - "name": "To", - "kind": "type", - "brief_description": "The concrete rpc server expected behind this handle." - } - ] - } - } -} diff --git a/docs_oos/data/remote/loopback.json b/docs_oos/data/remote/loopback.json deleted file mode 100644 index e0d150e..0000000 --- a/docs_oos/data/remote/loopback.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "format": 1, - "id": "saw-rmt-loopback", - "kind": "struct", - "name": "Loopback", - "namespace": "saw::rmt", - "module": "remote", - "header": "modules/remote/c++/remote_loopback_base.hpp", - "brief_description": "Tag of the in process backend.", - "detailed_description": [ - [ - "An empty type. It carries no state and is never instantiated; it exists to select the specializations which make up a backend, and it is the argument every class in the remote module is specialized on." - ] - ] -} diff --git a/docs_oos/data/remote/remote.json b/docs_oos/data/remote/remote.json deleted file mode 100644 index 3c9e1a6..0000000 --- a/docs_oos/data/remote/remote.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "format": 1, - "id": "saw-remote", - "kind": "class", - "name": "remote", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote.hpp", - "brief_description": "Reference backend structure.", - "detailed_description": [ - [ - "The primary template is never defined. A backend is added by specializing this class on its tag type, which is the only place the backend itself appears in the public api. An unsupported tag fails with a static_assert instead of a linker error." - ], - [ - "Every", - {"name": "data_server", "id": "saw-data_server"}, - "and", - {"name": "rpc_server", "id": "saw-rpc_server"}, - "of a backend is owned and handed out by its remote, which is also the registry a client searches when it connects." - ] - ], - "templates": [ - { - "name": "Remote", - "kind": "type", - "brief_description": "Tag type of the backend, e.g. rmt::Loopback." - } - ], - "specializations": [ - { - "name": "remote< rmt::Loopback >", - "id": "saw-remote-loopback", - "brief_description": "In process backend. Data stays where it is and calls are answered inline." - } - ] -} diff --git a/docs_oos/data/remote/remote.loopback.json b/docs_oos/data/remote/remote.loopback.json deleted file mode 100644 index 83c2ee8..0000000 --- a/docs_oos/data/remote/remote.loopback.json +++ /dev/null @@ -1,182 +0,0 @@ -{ - "format": 1, - "id": "saw-remote-loopback", - "kind": "class", - "name": "remote", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote_loopback_base.hpp", - "is_special": true, - "specializes": "saw-remote", - "arguments": ["rmt::Loopback"], - "brief_description": "In process backend.", - "detailed_description": [ - [ - "The reference implementation every other backend is measured against. Nothing is serialized and nothing is copied across a boundary, so what remains is the bookkeeping every backend has to do." - ], - [ - "Servers are registered under the address they listen on together with their class id, so a client asking for a schema on an address finds the one server which owns it." - ] - ], - "examples": [ - { - "title": "Serving an interface and calling it", - "description": [ - [ - "The whole flow on one address: bring up the data servers, bind an interface to them, connect, call. Error handling is left out, but note that every error_or is kept in a named variable, because get_value hands back a reference into it." - ], - [ - "The data servers have to exist before", - {"name": "rpc_listen", "id": "saw-remote-loopback-rpc_listen"}, - "is called, since that is where the parameter and the answer live." - ] - ], - "language": "cpp", - "code": "using TestInterface = schema::Interface<\n\tschema::Member, \"foo\">\n>;\n\nevent_loop loop;\nwait_scope wait{loop};\n\nremote rmt;\n\nauto eo_addr = rmt.parse_address(0u);\nauto& addr = eo_addr.get_value();\n\n/// The transport layer, one server per schema the interface mentions.\nauto eo_u32_srv = rmt.data_listen(*addr);\nauto eo_i64_srv = rmt.data_listen(*addr);\n\nauto iface = interface_factory::create(\n\t[](data input)\n\t\t-> error_or>\n\t{\n\t\tdata rv;\n\t\trv.set(input.get() * 2);\n\t\treturn rv;\n\t});\n\nauto eo_rpc_srv = rmt.rpc_listen(*addr, std::move(iface));\n\n/// The overlay on top of it.\nauto cvr_client = rmt.rpc_connect(*addr);\nauto eo_client = cvr_client.take();\nauto& client = eo_client.get_value();\n\ndata inp{21};\n\nauto cvr_result = client.call<\"foo\">(std::move(inp));\nauto eo_result = cvr_result.take();\nauto& result = eo_result.get_value();\n\n/// The answer never left the server. result only knows the id it picked.\nauto eo_value = result.wait(wait);\n/// eo_value.get_value().get() == 42\n" - } - ], - "attributes": { - "saw-remote-loopback-registered_data_servers_": { - "id": "saw-remote-loopback-registered_data_servers_", - "name": "registered_data_servers_", - "type": ["std::map< key_t, ptr<", {"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > > >"], - "visibility": "private", - "brief_description": "Keyed by address id, schema hash and encoding hash." - }, - "saw-remote-loopback-registered_rpc_servers_": { - "id": "saw-remote-loopback-registered_rpc_servers_", - "name": "registered_rpc_servers_", - "type": ["std::map< key_t, ptr<", {"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > > >"], - "visibility": "private", - "brief_description": "Keyed by address id, interface hash and encoding hash." - } - }, - "functions": { - "saw-remote-loopback-parse_address": { - "id": "saw-remote-loopback-parse_address", - "name": "parse_address", - "type": ["error_or< own<", {"name": "remote_address", "id": "saw-remote_address-loopback"}, "< rmt::Loopback > > >"], - "brief_description": "Resolves an address for the remote.", - "parameters": [ - { - "name": "id", - "type": ["data< schema::UInt64 >"], - "brief_description": "Identifier standing in for what a network address would be." - } - ] - }, - "saw-remote-loopback-data_listen": { - "id": "saw-remote-loopback-data_listen", - "name": "data_listen", - "type": ["error_or< own<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< Schema, Encode, rmt::Loopback > > >"], - "brief_description": "Starts a data server for one schema on an address.", - "detailed_description": [ - [ - "Fails with already_exists if a server for the same schema and encoding is already bound to that address. The returned server registers itself and stays reachable until it is destroyed." - ] - ], - "templates": [ - {"name": "Schema", "kind": "type"}, - {"name": "Encode", "kind": "type"} - ], - "parameters": [ - {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]} - ] - }, - "saw-remote-loopback-data_connect": { - "id": "saw-remote-loopback-data_connect", - "name": "data_connect", - "type": ["conveyor<", {"name": "data_client", "id": "saw-data_client-loopback"}, "< Schema, Encode, rmt::Loopback > >"], - "brief_description": "Connects to a data server.", - "detailed_description": [ - ["Fails with not_found if nothing listens for that schema on that address."] - ], - "templates": [ - {"name": "Schema", "kind": "type"}, - {"name": "Encode", "kind": "type"} - ], - "parameters": [ - {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]} - ] - }, - "saw-remote-loopback-rpc_listen": { - "id": "saw-remote-loopback-rpc_listen", - "name": "rpc_listen", - "type": ["error_or< own<", {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, "< Iface, Encode, rmt::Loopback > > >"], - "brief_description": "Starts an rpc server for an interface on an address.", - "detailed_description": [ - [ - "Every schema the interface mentions needs a data server on the same address beforehand, since that is where parameters and responses live. A missing one fails the call with not_found." - ] - ], - "templates": [ - {"name": "Iface", "kind": "type"}, - {"name": "Encode", "kind": "type"} - ], - "parameters": [ - {"name": "addr", "type": ["remote_address< rmt::Loopback > &"]}, - { - "name": "iface", - "type": ["typename rpc_server< Iface, Encode, rmt::Loopback >::InterfaceT"], - "brief_description": "The implementations backing the interface." - } - ] - }, - "saw-remote-loopback-rpc_connect": { - "id": "saw-remote-loopback-rpc_connect", - "name": "rpc_connect", - "type": ["conveyor<", {"name": "rpc_client", "id": "saw-rpc_client-loopback"}, "< Iface, Encode, rmt::Loopback > >"], - "brief_description": "Connects to an rpc server.", - "detailed_description": [ - ["Defined in remote_loopback.hpp, since the client has to be a complete type at that point."] - ], - "templates": [ - {"name": "Iface", "kind": "type"}, - {"name": "Encode", "kind": "type"} - ], - "parameters": [ - {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]} - ] - }, - "saw-remote-loopback-register_data_server": { - "id": "saw-remote-loopback-register_data_server", - "name": "register_data_server", - "type": ["error_or< void >"], - "brief_description": "Internal. Called by a data server on construction.", - "parameters": [ - {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, - {"name": "srv", "type": [{"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > &"]} - ] - }, - "saw-remote-loopback-deregister_data_server": { - "id": "saw-remote-loopback-deregister_data_server", - "name": "deregister_data_server", - "type": ["error_or< void >"], - "brief_description": "Internal. Called by a data server on destruction.", - "parameters": [ - {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, - {"name": "srv", "type": [{"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > &"]} - ] - }, - "saw-remote-loopback-register_rpc_server": { - "id": "saw-remote-loopback-register_rpc_server", - "name": "register_rpc_server", - "type": ["error_or< void >"], - "brief_description": "Internal. Called by an rpc server on construction.", - "parameters": [ - {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, - {"name": "srv", "type": [{"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > &"]} - ] - }, - "saw-remote-loopback-deregister_rpc_server": { - "id": "saw-remote-loopback-deregister_rpc_server", - "name": "deregister_rpc_server", - "type": ["error_or< void >"], - "brief_description": "Internal. Called by an rpc server on destruction.", - "parameters": [ - {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, - {"name": "srv", "type": [{"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > &"]} - ] - } - } -} diff --git a/docs_oos/data/remote/remote_address.json b/docs_oos/data/remote/remote_address.json deleted file mode 100644 index 783527c..0000000 --- a/docs_oos/data/remote/remote_address.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "format": 1, - "id": "saw-remote_address", - "kind": "class", - "name": "remote_address", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote.hpp", - "brief_description": "Representation of a remote. Partially similar to a network address.", - "detailed_description": [ - [ - "What an address is depends entirely on the backend. A loopback address is a number, a file address is a path, a socket address is host and port." - ], - [ - "Addresses are produced by the parse_address of their own", - {"name": "remote", "id": "saw-remote"}, - "and are meaningless to any other backend." - ] - ], - "templates": [ - { - "name": "Remote", - "kind": "type", - "brief_description": "Tag type of the backend." - } - ], - "specializations": [ - { - "name": "remote_address< rmt::Loopback >", - "id": "saw-remote_address-loopback", - "brief_description": "A plain identifier, since there is nothing to address but the process itself." - } - ] -} diff --git a/docs_oos/data/remote/remote_address.loopback.json b/docs_oos/data/remote/remote_address.loopback.json deleted file mode 100644 index ec7d5e4..0000000 --- a/docs_oos/data/remote/remote_address.loopback.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "format": 1, - "id": "saw-remote_address-loopback", - "kind": "class", - "name": "remote_address", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote_loopback_base.hpp", - "is_special": true, - "specializes": "saw-remote_address", - "arguments": ["rmt::Loopback"], - "brief_description": "Address of an in process endpoint.", - "detailed_description": [ - [ - "There is nothing to address but the process itself, so the address is a plain number. It still has to exist, because it is the component which separates two endpoints serving the same schema." - ] - ], - "attributes": { - "saw-remote_address-loopback-addr_id_": { - "id": "saw-remote_address-loopback-addr_id_", - "name": "addr_id_", - "type": ["data< schema::UInt64 >"], - "visibility": "private" - } - }, - "functions": { - "saw-remote_address-loopback-ctor": { - "id": "saw-remote_address-loopback-ctor", - "name": "remote_address", - "type": [], - "parameters": [ - {"name": "addr_id__", "type": ["data< schema::UInt64 >"]} - ] - }, - "saw-remote_address-loopback-get_address_id": { - "id": "saw-remote_address-loopback-get_address_id", - "name": "get_address_id", - "type": ["const data< schema::UInt64 > &"], - "const": true, - "brief_description": "The identifier this address stands for." - } - } -} diff --git a/docs_oos/data/remote/remote_data.json b/docs_oos/data/remote/remote_data.json deleted file mode 100644 index 1086ca4..0000000 --- a/docs_oos/data/remote/remote_data.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "format": 1, - "id": "saw-remote_data", - "kind": "class", - "name": "remote_data", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote.hpp", - "brief_description": "Representing data on the remote.", - "detailed_description": [ - [ - "What an rpc call hands back. It is an id plus a way to resolve it, not the value, so a result can be passed into the next call without ever being pulled across." - ], - [ - "Only declared by the primary template and defined per backend." - ] - ], - "templates": [ - {"name": "T", "kind": "type", "brief_description": "Schema of the data on the remote."}, - {"name": "Encoding", "kind": "type"}, - {"name": "Remote", "kind": "type", "brief_description": "Tag type of the backend."} - ], - "specializations": [ - { - "name": "remote_data< T, Encoding, rmt::Loopback >", - "id": "saw-remote_data-loopback", - "brief_description": "Resolves immediately, since the call it came from was answered inline." - } - ] -} diff --git a/docs_oos/data/remote/remote_data.loopback.json b/docs_oos/data/remote/remote_data.loopback.json deleted file mode 100644 index 32786aa..0000000 --- a/docs_oos/data/remote/remote_data.loopback.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "format": 1, - "id": "saw-remote_data-loopback", - "kind": "class", - "name": "remote_data", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote_loopback.hpp", - "is_special": true, - "specializes": "saw-remote_data", - "arguments": ["T", "Encoding", "rmt::Loopback"], - "brief_description": "Handle for data which is stored on an in process remote.", - "detailed_description": [ - [ - "The result of an rpc call. Resolving it goes back through the data layer rather than through the rpc layer, which is why the handle carries the data server and not the rpc server." - ], - [ - "This backend answers calls inline, so the data is already present whenever the call succeeded and waiting costs nothing." - ] - ], - "templates": [ - {"name": "T", "kind": "type"}, - {"name": "Encoding", "kind": "type"} - ], - "attributes": { - "saw-remote_data-loopback-id_": { - "id": "saw-remote_data-loopback-id_", - "name": "id_", - "type": ["id< T >"], - "visibility": "private" - }, - "saw-remote_data-loopback-srv_": { - "id": "saw-remote_data-loopback-srv_", - "name": "srv_", - "type": ["ptr<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< T, Encoding, rmt::Loopback > >"], - "visibility": "private" - } - }, - "functions": { - "saw-remote_data-loopback-get_id": { - "id": "saw-remote_data-loopback-get_id", - "name": "get_id", - "type": ["const id< T > &"], - "const": true, - "brief_description": "Id of the data on the remote.", - "detailed_description": [ - ["Hand this to the next call to keep a result where it is instead of pulling it across."] - ] - }, - "saw-remote_data-loopback-wait": { - "id": "saw-remote_data-loopback-wait", - "name": "wait", - "type": ["error_or< data< T, Encoding > >"], - "brief_description": "Waits until the data arrives.", - "parameters": [ - { - "name": "wait", - "type": ["wait_scope &"], - "brief_description": "Unused here, since there is nothing to wait for." - } - ] - }, - "saw-remote_data-loopback-on_receive": { - "id": "saw-remote_data-loopback-on_receive", - "name": "on_receive", - "type": ["conveyor< data< T, Encoding > >"], - "brief_description": "Asynchronously waits for the result." - } - } -} diff --git a/docs_oos/data/remote/rpc_client.json b/docs_oos/data/remote/rpc_client.json deleted file mode 100644 index b9dd5ca..0000000 --- a/docs_oos/data/remote/rpc_client.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "format": 1, - "id": "saw-rpc_client", - "kind": "class", - "name": "rpc_client", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote.hpp", - "brief_description": "Client RPC reference structure.", - "detailed_description": [ - [ - "The caller side of the overlay. Parameters and return values are moved by the data clients; the rpc layer only ties ids to a function call on the remote." - ], - [ - "Only declared by the primary template and defined per backend." - ] - ], - "templates": [ - {"name": "Iface", "kind": "type", "brief_description": "Interface schema being called."}, - {"name": "Encoding", "kind": "type", "brief_description": "Encoding of the parameters and responses."}, - {"name": "Remote", "kind": "type", "brief_description": "Tag type of the backend."} - ], - "specializations": [ - { - "name": "rpc_client< Iface, Encoding, rmt::Loopback >", - "id": "saw-rpc_client-loopback", - "brief_description": "Calls a server in the same process, which answers before the call returns." - } - ] -} diff --git a/docs_oos/data/remote/rpc_client.loopback.json b/docs_oos/data/remote/rpc_client.loopback.json deleted file mode 100644 index c305255..0000000 --- a/docs_oos/data/remote/rpc_client.loopback.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "format": 1, - "id": "saw-rpc_client-loopback", - "kind": "class", - "name": "rpc_client", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote_loopback.hpp", - "is_special": true, - "specializes": "saw-rpc_client", - "arguments": ["Iface", "Encoding", "rmt::Loopback"], - "brief_description": "Calls an rpc server in the same process.", - "detailed_description": [ - [ - "Holds one", - {"name": "data_client", "id": "saw-data_client-loopback"}, - "per schema the interface mentions, all of them handles on the data servers the server is already bound to. A parameter which is not on the remote yet goes through the data layer first, and only its id reaches the rpc layer." - ] - ], - "templates": [ - {"name": "Iface", "kind": "type"}, - {"name": "Encoding", "kind": "type"} - ], - "aliases": { - "saw-rpc_client-loopback-ServerT": { - "id": "saw-rpc_client-loopback-ServerT", - "name": "ServerT", - "type": [{"name": "rpc_server", "id": "saw-rpc_server-loopback"}, "< Iface, Encoding, rmt::Loopback >"] - }, - "saw-rpc_client-loopback-TypeGroup": { - "id": "saw-rpc_client-loopback-TypeGroup", - "name": "TypeGroup", - "type": ["typename schema_iface_type_group< Iface >::Type"], - "brief_description": "Every schema the interface mentions, reduced to unique types." - }, - "saw-rpc_client-loopback-DataClients": { - "id": "saw-rpc_client-loopback-DataClients", - "name": "DataClients", - "type": ["std::tuple<", {"name": "data_client", "id": "saw-data_client-loopback"}, "< T, Encoding, rmt::Loopback >... >"], - "brief_description": "One data client per schema in the type group." - } - }, - "functions": { - "saw-rpc_client-loopback-get_data_client": { - "id": "saw-rpc_client-loopback-get_data_client", - "name": "get_data_client", - "type": [{"name": "data_client", "id": "saw-data_client-loopback"}, "< IdT, Encoding, rmt::Loopback > &"], - "brief_description": "The data client of one of the interface types.", - "detailed_description": [ - ["Useful when a parameter is meant to be sent once and reused in several calls."] - ], - "templates": [ - {"name": "IdT", "kind": "type", "brief_description": "One of the schemas the interface mentions."} - ], - "examples": [ - { - "title": "Sending a parameter once and calling with it twice", - "description": [ - [ - "Handing a value to call sends it every time. Sending it once and passing the id instead keeps it on the remote, which is the point of", - {"name": "data_or_id", "id": "saw-data_or_id"} - ] - ], - "language": "cpp", - "code": "data inp{21};\n\nauto& u32_client = client.get_data_client();\nauto eo_param = u32_client.send(inp);\nauto param = eo_param.get_value();\n\n/// Both calls refer to the same value on the remote.\nauto first = client.call<\"foo\">(param).take();\nauto second = client.call<\"foo\">(param).take();\n" - } - ] - }, - "saw-rpc_client-loopback-request_data": { - "id": "saw-rpc_client-loopback-request_data", - "name": "request_data", - "type": [{"name": "remote_data", "id": "saw-remote_data-loopback"}, "< IdT, Encoding, rmt::Loopback >"], - "brief_description": "Requests the data from the remote.", - "templates": [ - {"name": "IdT", "kind": "type"} - ], - "parameters": [ - {"name": "dat_id", "type": ["id< IdT >"]} - ] - }, - "saw-rpc_client-loopback-call-1": { - "id": "saw-rpc_client-loopback-call-1", - "name": "call", - "type": ["conveyor<", {"name": "remote_data", "id": "saw-remote_data-loopback"}, "< ResponseT, Encoding, rmt::Loopback > >"], - "brief_description": "Calls a function on the remote.", - "detailed_description": [ - [ - "The parameter is either already present on the remote, in which case only its id is handed over, or it is sent through the data layer first." - ], - [ - "The id of the response is picked by the server and travels back with the answer, so this is asynchronous in the id as well, not only in the data." - ] - ], - "templates": [ - { - "name": "Name", - "kind": "non_type", - "type": "string_literal", - "brief_description": "Name of the interface member to call." - } - ], - "parameters": [ - { - "name": "input", - "type": [{"name": "data_or_id", "id": "saw-data_or_id"}, "< RequestT, Encoding >"], - "brief_description": "The parameter, or the id of one already on the remote." - } - ] - }, - "saw-rpc_client-loopback-call-2": { - "id": "saw-rpc_client-loopback-call-2", - "name": "call", - "type": ["conveyor<", {"name": "remote_data", "id": "saw-remote_data-loopback"}, "< ResponseT, Encoding, rmt::Loopback > >"], - "brief_description": "Calls a function and stores the response in a slot allocated beforehand.", - "templates": [ - { - "name": "Name", - "kind": "non_type", - "type": "string_literal", - "brief_description": "Name of the interface member to call." - } - ], - "parameters": [ - { - "name": "input", - "type": [{"name": "data_or_id", "id": "saw-data_or_id"}, "< RequestT, Encoding >"] - }, - { - "name": "resp_id", - "type": ["id< ResponseT >"], - "brief_description": "Slot the answer has to end up in." - } - ] - } - } -} diff --git a/docs_oos/data/remote/rpc_function_id.json b/docs_oos/data/remote/rpc_function_id.json deleted file mode 100644 index b5788f4..0000000 --- a/docs_oos/data/remote/rpc_function_id.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "format": 1, - "id": "saw-rpc_function_id", - "kind": "struct", - "name": "rpc_function_id", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote.hpp", - "brief_description": "Identifier of an interface function on the wire.", - "detailed_description": [ - [ - "Keyed on the member name rather than on its index, so reordering an interface doesn't silently rebind calls between two versions." - ], - [ - "This is the number a backend hands to call_by_id of the", - {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, - "when the called function arrives as data instead of as a template argument." - ] - ], - "templates": [ - { - "name": "Lit", - "kind": "non_type", - "type": "string_literal", - "brief_description": "Name of the interface member." - } - ], - "attributes": { - "saw-rpc_function_id-value": { - "id": "saw-rpc_function_id-value", - "name": "value", - "type": ["uint32_t"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "hash_literal::apply(0u)", - "brief_description": "crc32 of the member name." - } - } -} diff --git a/docs_oos/data/remote/rpc_server.json b/docs_oos/data/remote/rpc_server.json deleted file mode 100644 index eb21128..0000000 --- a/docs_oos/data/remote/rpc_server.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "format": 1, - "id": "saw-rpc_server", - "kind": "class", - "name": "rpc_server", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote.hpp", - "brief_description": "Implementation of a remote server on the backend.", - "detailed_description": [ - [ - "Holds the interface whose functions clients call." - ], - [ - "The server never receives a parameter as data, only the id of a value already sitting in the matching", - {"name": "data_server", "id": "saw-data_server"}, - "which is what keeps the rpc layer an overlay on the transport layer." - ] - ], - "templates": [ - { - "name": "Iface", - "kind": "type", - "brief_description": "Interface schema the server provides." - }, - { - "name": "Encoding", - "kind": "type", - "brief_description": "Encoding of the parameters and responses." - }, - { - "name": "Remote", - "kind": "type", - "brief_description": "Tag type of the backend." - } - ], - "attributes": { - "saw-rpc_server-iface_": { - "id": "saw-rpc_server-iface_", - "name": "iface_", - "type": ["interface< Iface, Encoding >"], - "visibility": "private" - } - }, - "functions": { - "saw-rpc_server-ctor": { - "id": "saw-rpc_server-ctor", - "name": "rpc_server", - "type": [], - "parameters": [ - { - "name": "iface", - "type": ["interface< Iface, Encoding >"], - "brief_description": "The functions this server answers with." - } - ] - } - }, - "specializations": [ - { - "name": "rpc_server< Iface, Encode, rmt::Loopback >", - "id": "saw-rpc_server-loopback", - "brief_description": "Answers calls inline, resolving ids against the data servers of the same address." - } - ] -} diff --git a/docs_oos/data/remote/rpc_server.loopback.json b/docs_oos/data/remote/rpc_server.loopback.json deleted file mode 100644 index 3f43ab2..0000000 --- a/docs_oos/data/remote/rpc_server.loopback.json +++ /dev/null @@ -1,180 +0,0 @@ -{ - "format": 1, - "id": "saw-rpc_server-loopback", - "kind": "class", - "name": "rpc_server", - "namespace": "saw", - "module": "remote", - "header": "modules/remote/c++/remote_loopback.hpp", - "is_special": true, - "specializes": "saw-rpc_server", - "arguments": ["Iface", "Encode", "rmt::Loopback"], - "brief_description": "Answers calls inline against the data servers of its address.", - "detailed_description": [ - [ - "Translates a call on an id into a call on the local interface: it looks the parameter up in the data server of the request schema, calls the function, and stores the answer in the data server of the response schema." - ], - [ - "The data itself never passes through the rpc layer. Registering with its", - {"name": "remote", "id": "saw-remote-loopback"}, - "on construction is what makes rpc_connect able to find it." - ] - ], - "templates": [ - {"name": "Iface", "kind": "type"}, - {"name": "Encode", "kind": "type"} - ], - "aliases": { - "saw-rpc_server-loopback-InterfaceT": { - "id": "saw-rpc_server-loopback-InterfaceT", - "name": "InterfaceT", - "type": ["interface< Iface, Encode >"], - "brief_description": "The implementations backing the interface." - }, - "saw-rpc_server-loopback-TypeGroup": { - "id": "saw-rpc_server-loopback-TypeGroup", - "name": "TypeGroup", - "type": ["typename schema_iface_type_group< Iface >::Type"], - "brief_description": "Every schema the interface mentions, reduced to unique types." - }, - "saw-rpc_server-loopback-DataServers": { - "id": "saw-rpc_server-loopback-DataServers", - "name": "DataServers", - "type": ["std::tuple< ptr<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< T, Encode, rmt::Loopback > >... >"], - "brief_description": "One data server pointer per schema in the type group." - } - }, - "attributes": { - "saw-rpc_server-loopback-class_id": { - "id": "saw-rpc_server-loopback-class_id", - "name": "class_id", - "type": ["std::pair< uint32_t, uint32_t >"], - "visibility": "public", - "static": true, - "constexpr": true, - "initializer": "{schema_hash::apply(), schema_hash::apply()}", - "brief_description": "Identifies which interface this server provides." - }, - "saw-rpc_server-loopback-iface_": { - "id": "saw-rpc_server-loopback-iface_", - "name": "iface_", - "type": ["InterfaceT"], - "visibility": "private" - }, - "saw-rpc_server-loopback-dat_srvs_": { - "id": "saw-rpc_server-loopback-dat_srvs_", - "name": "dat_srvs_", - "type": ["DataServers"], - "visibility": "private" - } - }, - "functions": { - "saw-rpc_server-loopback-get_class_id": { - "id": "saw-rpc_server-loopback-get_class_id", - "name": "get_class_id", - "type": ["std::pair< uint32_t, uint32_t >"], - "const": true, - "override": true, - "brief_description": "Returns the interface id." - }, - "saw-rpc_server-loopback-get_data_servers": { - "id": "saw-rpc_server-loopback-get_data_servers", - "name": "get_data_servers", - "type": ["const DataServers &"], - "const": true, - "brief_description": "The data servers this rpc server moves its parameters and responses through." - }, - "saw-rpc_server-loopback-call-1": { - "id": "saw-rpc_server-loopback-call-1", - "name": "call", - "type": ["error_or< id< ResponseT > >"], - "brief_description": "Calls a function and lets the server decide where the response is stored.", - "detailed_description": [ - [ - "A client cannot know which ids are free without asking, so this is the variant which costs no roundtrip beforehand." - ], - [ - "The slot is picked after the function returned, which is the latest and therefore most accurate moment." - ] - ], - "templates": [ - { - "name": "Lit", - "kind": "non_type", - "type": "string_literal", - "brief_description": "Name of the interface member to call." - } - ], - "parameters": [ - { - "name": "id_param", - "type": ["id< typename schema_member_type< Lit, Iface >::type::RequestT >"], - "brief_description": "Id of a value already sitting in the request data server." - } - ] - }, - "saw-rpc_server-loopback-call-2": { - "id": "saw-rpc_server-loopback-call-2", - "name": "call", - "type": ["error_or< void >"], - "brief_description": "Calls a function and stores the response in a slot allocated beforehand.", - "detailed_description": [ - [ - "Meant for backends where the output exists before the call, such as a device buffer allocated on the remote." - ] - ], - "templates": [ - { - "name": "Lit", - "kind": "non_type", - "type": "string_literal", - "brief_description": "Name of the interface member to call." - } - ], - "parameters": [ - {"name": "id_param", "type": ["id< typename schema_member_type< Lit, Iface >::type::RequestT >"]}, - { - "name": "id_resp", - "type": ["id< typename schema_member_type< Lit, Iface >::type::ResponseT >"], - "brief_description": "Slot the answer has to end up in." - } - ] - }, - "saw-rpc_server-loopback-call_by_id-1": { - "id": "saw-rpc_server-loopback-call_by_id-1", - "name": "call_by_id", - "type": ["error_or< uint64_t >"], - "brief_description": "Calls a function which is only known at runtime.", - "detailed_description": [ - [ - "The entry point for every backend which transports the call itself. The ids are untyped here, since such a backend only knows the function id and a number." - ], - [ - "The id the response ended up in is meant to travel back in the reply. Fails with not_found if no interface member carries that function id." - ] - ], - "parameters": [ - { - "name": "func_id", - "type": ["uint32_t"], - "brief_description": "rpc_function_id of the member name." - }, - {"name": "id_param", "type": ["uint64_t"]} - ] - }, - "saw-rpc_server-loopback-call_by_id-2": { - "id": "saw-rpc_server-loopback-call_by_id-2", - "name": "call_by_id", - "type": ["error_or< void >"], - "brief_description": "Runtime call into a slot the caller allocated beforehand.", - "parameters": [ - {"name": "func_id", "type": ["uint32_t"]}, - {"name": "id_param", "type": ["uint64_t"]}, - {"name": "id_resp", "type": ["uint64_t"]} - ] - } - }, - "notes": [ - "Copy and move are forbidden, because the remote holds a pointer to this object while it is registered." - ] -} diff --git a/docs_oos/entity.schema.json b/docs_oos/entity.schema.json deleted file mode 100644 index de85b95..0000000 --- a/docs_oos/entity.schema.json +++ /dev/null @@ -1,269 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "forstio/docs_oos/entity.schema.json", - "title": "forstio out of source api entity", - "description": "One file per entity, written by hand instead of derived from doxygen. A primary template and each of its specializations are separate files with their own id; the primary links the specializations, which the tree renders as a sublist underneath it. The generator collects every file under docs_oos/data into one map keyed by id, which is the shape the rst templates consume.", - "type": "object", - "required": ["format", "id", "kind", "name", "namespace", "header"], - "additionalProperties": false, - "properties": { - "format": { - "const": 1 - }, - "id": { - "type": "string", - "pattern": "^[a-z0-9_]+(-[a-z0-9_]+)*$", - "description": "Stable identifier. Becomes the rst file name, the label and the :ref: target, so it replaces the doxygen refid. Convention: namespace and name joined by a dash, with a slug for a specialization, e.g. saw-data_server and saw-data_server-loopback." - }, - "kind": { - "enum": ["class", "struct", "alias", "function", "variable", "enum", "concept", "namespace", "macro"] - }, - "name": { - "type": "string", - "description": "Unqualified name without namespace and without template arguments. A specialization carries the same name as its primary." - }, - "namespace": { - "type": "string", - "description": "Where it lives, e.g. saw or saw::rmt. Kept apart from the name so the heading stays readable and the namespace can still be shown." - }, - "module": { - "type": "string", - "description": "Module directory, e.g. remote." - }, - "header": { - "type": "string", - "description": "Declaring header, relative to the repository root." - }, - "brief_description": { - "type": "string" - }, - "detailed_description": { - "$ref": "#/$defs/paragraphs" - }, - "type": { - "$ref": "#/$defs/type_tuple", - "description": "Only for an alias, variable or function entity: the aliased type, the variable type, or the return type. A class has no type of its own." - }, - "parameters": { - "type": "array", - "description": "Only for a function entity.", - "items": {"$ref": "#/$defs/parameter"} - }, - "templates": { - "type": "array", - "description": "Template parameters. A partial specialization lists the parameters it introduces, not the ones it binds.", - "items": {"$ref": "#/$defs/template_parameter"} - }, - "bases": { - "type": "array", - "description": "Base classes, for the few places which use inheritance. Entries are type tuples, so a base which is itself documented links.", - "items": {"$ref": "#/$defs/type_tuple"} - }, - "is_special": { - "type": "boolean", - "default": false, - "description": "True on a specialization. The index skips these; they are reachable through their primary." - }, - "specializes": { - "type": "string", - "description": "Only on a specialization: id of the primary." - }, - "arguments": { - "type": "array", - "description": "Only on a specialization: the arguments it binds, in order, as written.", - "items": {"type": "string"} - }, - "specializations": { - "type": "array", - "description": "Only on a primary. Rendered as the sublist under the entity.", - "items": {"$ref": "#/$defs/specialization_link"} - }, - "aliases": { - "type": "object", - "description": "Member type aliases keyed by id. These carry weight here, e.g. DataServers or InterfaceT.", - "additionalProperties": {"$ref": "#/$defs/alias"} - }, - "attributes": { - "type": "object", - "description": "Data members keyed by id.", - "additionalProperties": {"$ref": "#/$defs/attribute"} - }, - "functions": { - "type": "object", - "description": "Member functions keyed by id. Overloads get distinct ids.", - "additionalProperties": {"$ref": "#/$defs/function"} - }, - "examples": { - "type": "array", - "description": "Usage examples for the entity as a whole.", - "items": {"$ref": "#/$defs/example"} - }, - "notes": { - "type": "array", - "description": "Remarks which don't belong to a single member.", - "items": {"type": "string"} - } - }, - "$defs": { - "example": { - "type": "object", - "required": ["code"], - "additionalProperties": false, - "properties": { - "title": {"type": "string"}, - "language": { - "type": "string", - "default": "cpp", - "description": "Rendered as the code block language." - }, - "description": {"$ref": "#/$defs/paragraphs"}, - "code": { - "type": "string", - "description": "Source as a single string with newlines. Error handling may be left out for readability, but then the description has to say so." - } - } - }, - "paragraphs": { - "type": "array", - "description": "A list of paragraphs. Each paragraph is a list of fragments: plain strings, or a reference object which renders as a link to another entity.", - "items": { - "type": "array", - "items": { - "oneOf": [ - {"type": "string"}, - {"$ref": "#/$defs/type_ref"} - ] - } - } - }, - "type_ref": { - "type": "object", - "required": ["name", "id"], - "additionalProperties": false, - "properties": { - "name": {"type": "string", "description": "Text to display."}, - "id": {"type": "string", "description": "id of the entity being linked."} - } - }, - "type_tuple": { - "type": "array", - "description": "A type as a sequence of fragments, so the parts which are entities link and the rest stays text.", - "items": { - "oneOf": [ - {"type": "string"}, - {"$ref": "#/$defs/type_ref"} - ] - } - }, - "parameter": { - "type": "object", - "required": ["name", "type"], - "additionalProperties": false, - "properties": { - "name": {"type": "string"}, - "type": {"$ref": "#/$defs/type_tuple"}, - "default": {"type": "string"}, - "brief_description": {"type": "string"} - } - }, - "template_parameter": { - "type": "object", - "required": ["name", "kind"], - "additionalProperties": false, - "properties": { - "name": {"type": "string"}, - "kind": { - "enum": ["type", "non_type", "template"], - "description": "type for class/typename, non_type for a value parameter such as uint64_t N or string_literal Lit." - }, - "type": { - "type": "string", - "description": "Required for non_type, e.g. uint64_t or string_literal." - }, - "pack": {"type": "boolean", "default": false}, - "default": {"type": "string", "description": "Default argument as written."}, - "brief_description": {"type": "string"} - } - }, - "specialization_link": { - "type": "object", - "required": ["name", "id"], - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "Specialized name as it should read in the sublist, e.g. data_server< Schema, Encoding, rmt::Loopback >." - }, - "id": {"type": "string"}, - "brief_description": { - "type": "string", - "description": "One line, so the sublist says what the specialization is for without opening it." - } - } - }, - "alias": { - "type": "object", - "required": ["id", "name", "type"], - "additionalProperties": false, - "properties": { - "id": {"type": "string"}, - "name": {"type": "string"}, - "type": {"$ref": "#/$defs/type_tuple"}, - "visibility": {"enum": ["public", "protected", "private"], "default": "public"}, - "brief_description": {"type": "string"}, - "detailed_description": {"$ref": "#/$defs/paragraphs"} - } - }, - "attribute": { - "type": "object", - "required": ["id", "name", "type"], - "additionalProperties": false, - "properties": { - "id": {"type": "string"}, - "name": {"type": "string"}, - "type": {"$ref": "#/$defs/type_tuple"}, - "visibility": {"enum": ["public", "protected", "private"], "default": "private"}, - "static": {"type": "boolean", "default": false}, - "const": {"type": "boolean", "default": false}, - "constexpr": {"type": "boolean", "default": false}, - "initializer": {"type": "string", "default": ""}, - "brief_description": {"type": "string"}, - "detailed_description": {"$ref": "#/$defs/paragraphs"} - } - }, - "function": { - "type": "object", - "required": ["id", "name", "type"], - "additionalProperties": false, - "properties": { - "id": {"type": "string"}, - "name": {"type": "string"}, - "type": { - "$ref": "#/$defs/type_tuple", - "description": "Return type. Empty for constructors and destructors." - }, - "templates": { - "type": "array", - "description": "Template parameters of the function itself, e.g. the string_literal naming an interface member.", - "items": {"$ref": "#/$defs/template_parameter"} - }, - "parameters": { - "type": "array", - "items": {"$ref": "#/$defs/parameter"} - }, - "visibility": {"enum": ["public", "protected", "private"], "default": "public"}, - "static": {"type": "boolean", "default": false}, - "const": {"type": "boolean", "default": false}, - "virtual": {"type": "boolean", "default": false}, - "override": {"type": "boolean", "default": false}, - "brief_description": {"type": "string"}, - "detailed_description": {"$ref": "#/$defs/paragraphs"}, - "examples": { - "type": "array", - "description": "Usage examples for this member.", - "items": {"$ref": "#/$defs/example"} - } - } - } - } -} -- cgit v1.3.1