diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ac4ba1cf..9eb27e312 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ option(BUILD_STATIC_LIBS "Build a static libjsonnet." ON) option(BUILD_SHARED_BINARIES "Link binaries to the shared libjsonnet instead of the static one." OFF) option(USE_SYSTEM_GTEST "Use system-provided gtest library" OFF) option(USE_SYSTEM_JSON "Use the system-provided json library" OFF) +# TODO: Support using a system Rapid YAML install. set(GLOBAL_OUTPUT_PATH_SUFFIX "" CACHE STRING "Output artifacts directory.") @@ -109,6 +110,7 @@ link_directories(${GLOBAL_OUTPUT_PATH}) include_directories( include third_party/md5 + third_party/rapidyaml core cpp) @@ -120,7 +122,7 @@ endif() add_subdirectory(include) add_subdirectory(stdlib) add_subdirectory(third_party/md5) -add_subdirectory(third_party/rapidyaml/rapidyaml ryml) +add_subdirectory(third_party/rapidyaml) add_subdirectory(core) add_subdirectory(cpp) add_subdirectory(cmd) diff --git a/Makefile b/Makefile index d2950cf10..9cda4dcd8 100644 --- a/Makefile +++ b/Makefile @@ -28,10 +28,10 @@ OPT ?= -O3 PREFIX ?= /usr/local CXXFLAGS ?= -g $(OPT) -Wall -Wextra -Woverloaded-virtual -pedantic -std=c++17 -fPIC -CXXFLAGS += -Iinclude -Ithird_party/md5 -Ithird_party/json -Ithird_party/rapidyaml/rapidyaml/src/ -Ithird_party/rapidyaml/rapidyaml/ext/c4core/src/ +CXXFLAGS += -Iinclude -Ithird_party/md5 -Ithird_party/json -Ithird_party/rapidyaml/ CFLAGS ?= -g $(OPT) -Wall -Wextra -pedantic -std=c99 -fPIC CFLAGS += -Iinclude -MAKEDEPENDFLAGS += -Iinclude -Ithird_party/md5 -Ithird_party/json -Ithird_party/rapidyaml/rapidyaml/src/ -Ithird_party/rapidyaml/rapidyaml/ext/c4core/src/ +MAKEDEPENDFLAGS += -Iinclude -Ithird_party/md5 -Ithird_party/json LDFLAGS ?= @@ -45,8 +45,7 @@ SOVERSION = 0 ################################################################################ RAPIDYAML_SRC = \ - $(wildcard third_party/rapidyaml/rapidyaml/src/c4/yml/*.cpp) \ - $(wildcard third_party/rapidyaml/rapidyaml/ext/c4core/src/c4/*.cpp) + third_party/rapidyaml/rapidyaml.cpp LIB_SRC = \ core/desugarer.cpp \ diff --git a/core/vm.cpp b/core/vm.cpp index bdff11bf1..819fc2db5 100644 --- a/core/vm.cpp +++ b/core/vm.cpp @@ -26,8 +26,7 @@ limitations under the License. #include #include "md5.h" #include "parser.h" -#include "ryml_std.hpp" // include this before any other ryml header -#include "ryml.hpp" +#include "ryml_all.hpp" #include "state.h" #include "static_analysis.h" #include "string_utils.h" @@ -1637,7 +1636,7 @@ class Interpreter { } const ryml::Tree treeFromString(const std::string& s) { - return ryml::parse(c4::to_csubstr(s)); + return ryml::parse_in_arena(ryml::to_csubstr(s)); } const std::vector split(const std::string& s, const std::string& delimiter) { diff --git a/setup.py b/setup.py index ab6b431cb..8256d7f84 100644 --- a/setup.py +++ b/setup.py @@ -32,18 +32,7 @@ 'core/string_utils.o', 'core/vm.o', 'third_party/md5/md5.o', - 'third_party/rapidyaml/rapidyaml/ext/c4core/src/c4/char_traits.o', - 'third_party/rapidyaml/rapidyaml/ext/c4core/src/c4/base64.o', - 'third_party/rapidyaml/rapidyaml/ext/c4core/src/c4/language.o', - 'third_party/rapidyaml/rapidyaml/ext/c4core/src/c4/memory_util.o', - 'third_party/rapidyaml/rapidyaml/ext/c4core/src/c4/format.o', - 'third_party/rapidyaml/rapidyaml/ext/c4core/src/c4/time.o', - 'third_party/rapidyaml/rapidyaml/ext/c4core/src/c4/memory_resource.o', - 'third_party/rapidyaml/rapidyaml/ext/c4core/src/c4/error.o', - 'third_party/rapidyaml/rapidyaml/src/c4/yml/parse.o', - 'third_party/rapidyaml/rapidyaml/src/c4/yml/preprocess.o', - 'third_party/rapidyaml/rapidyaml/src/c4/yml/common.o', - 'third_party/rapidyaml/rapidyaml/src/c4/yml/tree.o', + 'third_party/rapidyaml/rapidyaml.o', ] MODULE_SOURCES = ['python/_jsonnet.c'] diff --git a/third_party/rapidyaml/BUILD b/third_party/rapidyaml/BUILD index b726f5ef6..239da921a 100644 --- a/third_party/rapidyaml/BUILD +++ b/third_party/rapidyaml/BUILD @@ -1,43 +1,15 @@ licenses(["permissive"]) -package(default_visibility = ["//visibility:private"]) - -cc_library( - name = "debugbreak", - hdrs = glob(["rapidyaml/ext/c4core/src/c4/ext/debugbreak/debugbreak.h"]), - srcs = [], -) - -cc_library( - name = "fastfloat", - includes = ["rapidyaml/ext/c4core/src/c4/ext"], - hdrs = glob(["rapidyaml/ext/c4core/src/c4/ext/fast_float.hpp", "rapidyaml/ext/c4core/src/c4/ext/fast_float/**/*.h"]), - srcs = [], -) -cc_library( - name = "c4core", - deps = [ - ":debugbreak", - ":fastfloat", - ], - includes = ["rapidyaml/ext/c4core/src"], - hdrs = glob( - ["rapidyaml/ext/c4core/src/**/*.hpp"], - exclude = ["rapidyaml/ext/c4core/src/c4/ext/**/*"], - ), - srcs = glob( - ["rapidyaml/ext/c4core/src/**/*.cpp"], - exclude = ["rapidyaml/ext/c4core/src/c4/ext/**/*"], - ), -) +package(default_visibility = ["//visibility:private"]) cc_library( name = "ryml", - visibility = ["//visibility:public"], - deps = [ - ":c4core", + srcs = [ + "rapidyaml.cpp", + ], + hdrs = [ + "ryml_all.hpp", ], - includes = ["rapidyaml/src"], - hdrs = glob(["rapidyaml/src/**/*.hpp"]), - srcs = glob(["rapidyaml/src/**/*.cpp"]), + includes = ["."], + visibility = ["//visibility:public"], ) diff --git a/third_party/rapidyaml/CMakeLists.txt b/third_party/rapidyaml/CMakeLists.txt new file mode 100644 index 000000000..8ba871888 --- /dev/null +++ b/third_party/rapidyaml/CMakeLists.txt @@ -0,0 +1 @@ +add_library(ryml STATIC rapidyaml.cpp ryml_all.hpp) \ No newline at end of file diff --git a/third_party/rapidyaml/README.md b/third_party/rapidyaml/README.md index 6dc9c6089..685580b37 100644 --- a/third_party/rapidyaml/README.md +++ b/third_party/rapidyaml/README.md @@ -1,12 +1,8 @@ # Vendoring -``` -git clone \ - --depth=1 \ - --branch=master \ - --recursive \ - git@github.com:biojppm/rapidyaml \ - third_party/rapidyaml/rapidyaml \ -&& \ -rm -rf third_party/rapidyaml/rapidyaml/.git -``` +This uses the 'single header' release of Rapid YAML. +Download from: https://github.com/biojppm/rapidyaml/releases/tag/v0.5.0 + +`rapidyaml-0.5.0.hpp` (renamed to `ryml_all.hpp`) + +rapidyaml.cpp instantiates the library as a single translation unit. diff --git a/third_party/rapidyaml/rapidyaml.cpp b/third_party/rapidyaml/rapidyaml.cpp new file mode 100644 index 000000000..738d11bff --- /dev/null +++ b/third_party/rapidyaml/rapidyaml.cpp @@ -0,0 +1,2 @@ +#define RYML_SINGLE_HDR_DEFINE_NOW +#include "ryml_all.hpp" diff --git a/third_party/rapidyaml/rapidyaml/.gitchangelog.rc b/third_party/rapidyaml/rapidyaml/.gitchangelog.rc deleted file mode 100644 index d3fe54f8d..000000000 --- a/third_party/rapidyaml/rapidyaml/.gitchangelog.rc +++ /dev/null @@ -1,291 +0,0 @@ -# -*- coding: utf-8; mode: python -*- -## -## https://pypi.org/project/gitchangelog/ -## -## Format -## -## ACTION: [AUDIENCE:] COMMIT_MSG [!TAG ...] -## -## Description -## -## ACTION is one of 'chg', 'fix', 'new' -## -## Is WHAT the change is about. -## -## 'chg' is for refactor, small improvement, cosmetic changes... -## 'fix' is for bug fixes -## 'new' is for new features, big improvement -## -## AUDIENCE is optional and one of 'dev', 'usr', 'pkg', 'test', 'doc' -## -## Is WHO is concerned by the change. -## -## 'dev' is for developpers (API changes, refactors...) -## 'usr' is for final users (UI changes) -## 'pkg' is for packagers (packaging changes) -## 'test' is for testers (test only related changes) -## 'doc' is for doc guys (doc only changes) -## -## COMMIT_MSG is ... well ... the commit message itself. -## -## TAGs are additionnal adjective as 'refactor' 'minor' 'cosmetic' -## -## They are preceded with a '!' or a '@' (prefer the former, as the -## latter is wrongly interpreted in github.) Commonly used tags are: -## -## 'refactor' is obviously for refactoring code only -## 'minor' is for a very meaningless change (a typo, adding a comment) -## 'cosmetic' is for cosmetic driven change (re-indentation, 80-col...) -## 'wip' is for partial functionality but complete subfunctionality. -## -## Example: -## -## new: usr: support of bazaar implemented -## chg: re-indentend some lines !cosmetic -## new: dev: updated code to be compatible with last version of killer lib. -## fix: pkg: updated year of licence coverage. -## new: test: added a bunch of test around user usability of feature X. -## fix: typo in spelling my name in comment. !minor -## -## Please note that multi-line commit message are supported, and only the -## first line will be considered as the "summary" of the commit message. So -## tags, and other rules only applies to the summary. The body of the commit -## message will be displayed in the changelog without reformatting. - - -## -## ``ignore_regexps`` is a line of regexps -## -## Any commit having its full commit message matching any regexp listed here -## will be ignored and won't be reported in the changelog. -## -ignore_regexps = [ - r'@minor', r'!minor', - r'@cosmetic', r'!cosmetic', - r'@refactor', r'!refactor', - r'@wip', r'!wip', - r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[p|P]kg:', - r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[d|D]ev:', - r'^(.{3,3}\s*:)?\s*[fF]irst commit.?\s*$', - r'^$', ## ignore commits with empty messages -] - - -## ``section_regexps`` is a list of 2-tuples associating a string label and a -## list of regexp -## -## Commit messages will be classified in sections thanks to this. Section -## titles are the label, and a commit is classified under this section if any -## of the regexps associated is matching. -## -## Please note that ``section_regexps`` will only classify commits and won't -## make any changes to the contents. So you'll probably want to go check -## ``subject_process`` (or ``body_process``) to do some changes to the subject, -## whenever you are tweaking this variable. -## -section_regexps = [ - ('New', [ - r'^[nN]ew\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', - ]), - ('Changes', [ - r'^[cC]hg\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', - ]), - ('Fix', [ - r'^[fF]ix\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', - ]), - - ('Other', None ## Match all lines - ), - -] - - -## ``body_process`` is a callable -## -## This callable will be given the original body and result will -## be used in the changelog. -## -## Available constructs are: -## -## - any python callable that take one txt argument and return txt argument. -## -## - ReSub(pattern, replacement): will apply regexp substitution. -## -## - Indent(chars=" "): will indent the text with the prefix -## Please remember that template engines gets also to modify the text and -## will usually indent themselves the text if needed. -## -## - Wrap(regexp=r"\n\n"): re-wrap text in separate paragraph to fill 80-Columns -## -## - noop: do nothing -## -## - ucfirst: ensure the first letter is uppercase. -## (usually used in the ``subject_process`` pipeline) -## -## - final_dot: ensure text finishes with a dot -## (usually used in the ``subject_process`` pipeline) -## -## - strip: remove any spaces before or after the content of the string -## -## - SetIfEmpty(msg="No commit message."): will set the text to -## whatever given ``msg`` if the current text is empty. -## -## Additionally, you can `pipe` the provided filters, for instance: -#body_process = Wrap(regexp=r'\n(?=\w+\s*:)') | Indent(chars=" ") -#body_process = Wrap(regexp=r'\n(?=\w+\s*:)') -#body_process = noop -body_process = ReSub(r'((^|\n)[A-Z]\w+(-\w+)*: .*(\n\s+.*)*)+$', r'') | strip - - -## ``subject_process`` is a callable -## -## This callable will be given the original subject and result will -## be used in the changelog. -## -## Available constructs are those listed in ``body_process`` doc. -subject_process = (strip | - ReSub(r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n@]*)(@[a-z]+\s+)*$', r'\4') | - SetIfEmpty("No commit message.") | ucfirst | final_dot) - - -## ``tag_filter_regexp`` is a regexp -## -## Tags that will be used for the changelog must match this regexp. -## -tag_filter_regexp = r'^[0-9]+\.[0-9]+(\.[0-9]+)?$' - - -## ``unreleased_version_label`` is a string or a callable that outputs a string -## -## This label will be used as the changelog Title of the last set of changes -## between last valid tag and HEAD if any. -unreleased_version_label = "(unreleased)" - - -## ``output_engine`` is a callable -## -## This will change the output format of the generated changelog file -## -## Available choices are: -## -## - rest_py -## -## Legacy pure python engine, outputs ReSTructured text. -## This is the default. -## -## - mustache() -## -## Template name could be any of the available templates in -## ``templates/mustache/*.tpl``. -## Requires python package ``pystache``. -## Examples: -## - mustache("markdown") -## - mustache("restructuredtext") -## -## - makotemplate() -## -## Template name could be any of the available templates in -## ``templates/mako/*.tpl``. -## Requires python package ``mako``. -## Examples: -## - makotemplate("restructuredtext") -## -#output_engine = rest_py -#output_engine = mustache("restructuredtext") -output_engine = mustache("markdown") -#output_engine = makotemplate("restructuredtext") - - -## ``include_merge`` is a boolean -## -## This option tells git-log whether to include merge commits in the log. -## The default is to include them. -include_merge = True - - -## ``log_encoding`` is a string identifier -## -## This option tells gitchangelog what encoding is outputed by ``git log``. -## The default is to be clever about it: it checks ``git config`` for -## ``i18n.logOutputEncoding``, and if not found will default to git's own -## default: ``utf-8``. -#log_encoding = 'utf-8' - - -## ``publish`` is a callable -## -## Sets what ``gitchangelog`` should do with the output generated by -## the output engine. ``publish`` is a callable taking one argument -## that is an interator on lines from the output engine. -## -## Some helper callable are provided: -## -## Available choices are: -## -## - stdout -## -## Outputs directly to standard output -## (This is the default) -## -## - FileInsertAtFirstRegexMatch(file, pattern, idx=lamda m: m.start()) -## -## Creates a callable that will parse given file for the given -## regex pattern and will insert the output in the file. -## ``idx`` is a callable that receive the matching object and -## must return a integer index point where to insert the -## the output in the file. Default is to return the position of -## the start of the matched string. -## -## - FileRegexSubst(file, pattern, replace, flags) -## -## Apply a replace inplace in the given file. Your regex pattern must -## take care of everything and might be more complex. Check the README -## for a complete copy-pastable example. -## -# publish = FileInsertIntoFirstRegexMatch( -# "CHANGELOG.rst", -# r'/(?P[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n/', -# idx=lambda m: m.start(1) -# ) -#publish = stdout - - -## ``revs`` is a list of callable or a list of string -## -## callable will be called to resolve as strings and allow dynamical -## computation of these. The result will be used as revisions for -## gitchangelog (as if directly stated on the command line). This allows -## to filter exaclty which commits will be read by gitchangelog. -## -## To get a full documentation on the format of these strings, please -## refer to the ``git rev-list`` arguments. There are many examples. -## -## Using callables is especially useful, for instance, if you -## are using gitchangelog to generate incrementally your changelog. -## -## Some helpers are provided, you can use them:: -## -## - FileFirstRegexMatch(file, pattern): will return a callable that will -## return the first string match for the given pattern in the given file. -## If you use named sub-patterns in your regex pattern, it'll output only -## the string matching the regex pattern named "rev". -## -## - Caret(rev): will return the rev prefixed by a "^", which is a -## way to remove the given revision and all its ancestor. -## -## Please note that if you provide a rev-list on the command line, it'll -## replace this value (which will then be ignored). -## -## If empty, then ``gitchangelog`` will act as it had to generate a full -## changelog. -## -## The default is to use all commits to make the changelog. -#revs = ["^1.0.3", ] -#revs = [ -# Caret( -# FileFirstRegexMatch( -# "CHANGELOG.rst", -# r"(?P[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n")), -# "HEAD" -#] -revs = [] diff --git a/third_party/rapidyaml/rapidyaml/.github/.travis.yml.old b/third_party/rapidyaml/rapidyaml/.github/.travis.yml.old deleted file mode 100644 index c9bb6529c..000000000 --- a/third_party/rapidyaml/rapidyaml/.github/.travis.yml.old +++ /dev/null @@ -1,111 +0,0 @@ -sudo: required -dist: bionic -language: cpp -env: - global: - # cmake is installed into /usr/bin - - PATH=/usr/bin:/usr/local/bin:$PATH - -# we're not using combination parameters here to ensure that the builds -# run in the order we want. (We want to perform the fastest tests first so -# failed tests appear as early as possible). - -# NOTE: The compiler setting is unused. It simply makes the display on -# travis-ci.org more readable. -# WARNING: do not use the name CXX. Travis will ignore the value here. -matrix: - - include: - # every entry does both 64 and 32 bit - # SAN := sanitizers - # VG := valgrind - - # coverage: in bionic, lcov is incompatible with g++8 and later - - env: CXX_=g++-7 BT=Coverage STD=11 - - env: CXX_=g++-7 BT=Coverage STD=14 - - env: CXX_=g++-7 BT=Coverage STD=17 - - - env: CXX_=g++-9 BT=Debug STD=11 VG=ON - - env: CXX_=clang++-9 BT=Debug STD=11 VG=ON - - env: CXX_=g++-9 BT=Debug STD=14 VG=ON - - env: CXX_=clang++-9 BT=Debug STD=14 VG=ON - - env: CXX_=g++-9 BT=Debug STD=17 VG=ON - - env: CXX_=clang++-9 BT=Debug STD=17 VG=ON - - env: CXX_=g++-9 BT=Release STD=11 VG=ON - - env: CXX_=clang++-9 BT=Release STD=11 VG=ON - - env: CXX_=g++-9 BT=Release STD=14 VG=ON - - env: CXX_=clang++-9 BT=Release STD=14 VG=ON - - env: CXX_=g++-9 BT=Release STD=17 VG=ON - - env: CXX_=clang++-9 BT=Release STD=17 VG=ON - - - env: CXX_=clang++-9 BT=Debug STD=11 SAN=ALL - - env: CXX_=clang++-9 BT=Release STD=11 SAN=ALL - - env: CXX_=clang++-9 BT=Debug STD=14 SAN=ALL - - env: CXX_=clang++-9 BT=Release STD=14 SAN=ALL - - env: CXX_=clang++-9 BT=Debug STD=17 SAN=ALL - - env: CXX_=clang++-9 BT=Release STD=17 SAN=ALL - - - env: CXX_=g++-8 BT=Debug - - env: CXX_=g++-8 BT=Release - - env: CXX_=clang++-8 BT=Debug - - env: CXX_=clang++-8 BT=Release - - - env: CXX_=g++-7 BT=Debug - - env: CXX_=g++-7 BT=Release - - env: CXX_=clang++-7 BT=Debug - - env: CXX_=clang++-7 BT=Release - - - env: CXX_=g++-6 BT=Debug - - env: CXX_=g++-6 BT=Release - - env: CXX_=clang++-6.0 BT=Debug - - env: CXX_=clang++-6.0 BT=Release - - - env: CXX_=g++-5 BT=Debug - - env: CXX_=g++-5 BT=Release - - env: CXX_=clang++-5.0 BT=Debug - - env: CXX_=clang++-5.0 BT=Release - - # gcc 4.9 is not available in 18.04 -- https://stackoverflow.com/questions/48398475/ - #- env: CXX_=g++-4.9 BT=Debug - #- env: CXX_=g++-4.9 BT=Release - - env: CXX_=clang++-4.0 BT=Debug - - env: CXX_=clang++-4.0 BT=Release - - - env: CXX_=clang++-3.9 BT=Debug - - env: CXX_=clang++-3.9 BT=Release - - # ----------- clang-tidy - # - - env: CXX_=clang++-9 BT=Debug LINT=clang-tidy - - env: CXX_=clang++-9 BT=Release LINT=clang-tidy - -install: - - bash -x .ci/travis-install.sh - -script: - - source .ci/travis-setenv.sh - - - ryml_cfg_test 64 static - - ryml_run_test 64 static - - - ryml_cfg_test 32 static - - ryml_run_test 32 static - - - ryml_cfg_test 64 dynamic - - ryml_run_test 64 dynamic - - - echo "Running tests again, with the test suite enabled (~1300 tests)" - - addprojflags TEST_SUITE=ON - - ryml_cfg_test 64 static - - ryml_cfg_test 32 static - - ryml_run_test 64 static - - ryml_run_test 32 static - - - echo "Success!" - -after_success: - - source .ci/travis-setenv.sh - #- ryml_submit_coverage 32 static coveralls # coveralls only accepts one submission per job - - ryml_submit_coverage 64 static coveralls - - ryml_submit_coverage 32 static codecov - - ryml_submit_coverage 64 static codecov diff --git a/third_party/rapidyaml/rapidyaml/.github/appveyor.yml.old b/third_party/rapidyaml/rapidyaml/.github/appveyor.yml.old deleted file mode 100644 index 6bc7eed4c..000000000 --- a/third_party/rapidyaml/rapidyaml/.github/appveyor.yml.old +++ /dev/null @@ -1,127 +0,0 @@ -version: '{build}' - -image: Visual Studio 2019 - -environment: - matrix: - - - GEN: Visual Studio 16 2019 - ARCH: -A Win32 - CFG: Debug - compiler: msvc-16-seh - - - GEN: Visual Studio 16 2019 - ARCH: -A x64 - CFG: Debug - compiler: msvc-16-seh - - - GEN: Visual Studio 16 2019 - ARCH: -A Win32 - CFG: Release - compiler: msvc-16-seh - - - GEN: Visual Studio 16 2019 - ARCH: -A x64 - CFG: Release - compiler: msvc-16-seh - - - - GEN: Visual Studio 15 2017 - CFG: Debug - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - compiler: msvc-15-seh - - - GEN: Visual Studio 15 2017 Win64 - CFG: Debug - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - compiler: msvc-15-seh - - - GEN: Visual Studio 15 2017 - CFG: Release - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - compiler: msvc-15-seh - - - GEN: Visual Studio 15 2017 Win64 - CFG: Release - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - compiler: msvc-15-seh - - - #- GEN: Visual Studio 14 2015 - # CFG: Debug - # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - - #- GEN: Visual Studio 14 2015 Win64 - # CFG: Debug - # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - - #- GEN: Visual Studio 14 2015 - # CFG: Release - # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - - #- GEN: Visual Studio 14 2015 Win64 - # CFG: Release - # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - - - #- compiler: gcc-5.3.0-posix - # GEN: "MinGW Makefiles" - # cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin' - # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - # CFG: Quicktest - # externconfig: Debug - - -matrix: - fast_finish: true - -install: - - git submodule update --init --recursive - # git bash conflicts with MinGW makefiles - - set "PATH=%PATH:C:\Program Files\Git\usr\bin;=%" - - if not "%cxx_path%"=="" (set "PATH=%PATH%;%cxx_path%") - - cmake --version - -build_script: - - echo %GEN% - - echo %ARCH% - - echo %CFG% - - set NUM_JOBS=3 - - set PROJ_DIR=%cd% - - set BUILD_DIR=%PROJ_DIR%\build - - set INSTALL_DIR=%PROJ_DIR%\install - - set C4_EXTERN_DIR=%BUILD_DIR%\extern - - md %BUILD_DIR% - - md %BUILD_DIR%\static %BUILD_DIR%\shared %BUILD_DIR%\extern - - cmake -S %PROJ_DIR% -B %BUILD_DIR%/static -DRYML_DEV=ON -DRYML_TEST_SUITE=ON -DRYML_BUILD_BENCHMARKS=OFF -G "%GEN%" %ARCH% "-DCMAKE_BUILD_TYPE=%CFG%" "-DCMAKE_INSTALL_PREFIX=%INSTALL_DIR%/static" -DBUILD_SHARED_LIBS=OFF - - cmake -S %PROJ_DIR% -B %BUILD_DIR%/shared -DRYML_DEV=ON -DRYML_TEST_SUITE=ON -DRYML_BUILD_BENCHMARKS=OFF -G "%GEN%" %ARCH% "-DCMAKE_BUILD_TYPE=%CFG%" "-DCMAKE_INSTALL_PREFIX=%INSTALL_DIR%/shared" -DBUILD_SHARED_LIBS=ON - - cmake --build %BUILD_DIR%/static --config %CFG% --target test-build --parallel %NUM_JOBS% - - cmake --build %BUILD_DIR%/shared --config %CFG% --target test-build --parallel %NUM_JOBS% - -test_script: - - cmake --build %BUILD_DIR%\static --config %CFG% --target test - - cmake --build %BUILD_DIR%\shared --config %CFG% --target test - -#artifacts: -# - path: '%BUILD_DIR%/static/CMakeFiles/*.log' -# name: logs -# - path: '%BUILD_DIR%/static/Testing/**/*.xml' -# name: test_results - -skip_commits: - files: - - .gitignore - - .travis* - - .ci/travis* - - .ci/dev_* - - .ci/show_* - - .ci/vagrant* - - .ci/Vagrant* - - bm/html/* - - doc/* - - img/* - - CHANGELOG.md - - CONTRIBUTING.md - - LICENSE.txt - - README.* - - ROADMAP.* diff --git a/third_party/rapidyaml/rapidyaml/.github/release.yml b/third_party/rapidyaml/rapidyaml/.github/release.yml deleted file mode 100644 index 5792871f3..000000000 --- a/third_party/rapidyaml/rapidyaml/.github/release.yml +++ /dev/null @@ -1,194 +0,0 @@ -# https://cristianadam.eu/20191222/using-github-actions-with-c-plus-plus-and-cmake/ -name: CMake Build Matrix - -on: [push] - -jobs: - build: - name: ${{ matrix.config.name }} - runs-on: ${{ matrix.config.os }} - strategy: - fail-fast: false - matrix: - config: - - { - name: "Windows Latest MSVC", artifact: "Windows-MSVC.tar.xz", - os: windows-latest, - build_type: "Release", cc: "cl", cxx: "cl", - environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" - } - - { - name: "Windows Latest MinGW", artifact: "Windows-MinGW.tar.xz", - os: windows-latest, - build_type: "Release", cc: "gcc", cxx: "g++" - } - - { - name: "Ubuntu Latest GCC", artifact: "Linux.tar.xz", - os: ubuntu-latest, - build_type: "Release", cc: "gcc", cxx: "g++" - } - - { - name: "macOS Latest Clang", artifact: "macOS.tar.xz", - os: macos-latest, - build_type: "Release", cc: "clang", cxx: "clang++" - } - - steps: - - uses: actions/checkout@v1 - - # Get latest CMake and ninja - # https://github.com/marketplace/actions/get-cmake - - name: Get cmake+ninja - uses: lukka/get-cmake@latest - - - name: Configure - shell: cmake -P {0} - run: | - set(ENV{CC} ${{ matrix.config.cc }}) - set(ENV{CXX} ${{ matrix.config.cxx }}) - - if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") - execute_process( - COMMAND "${{ matrix.config.environment_script }}" && set - OUTPUT_FILE environment_script_output.txt - ) - file(STRINGS environment_script_output.txt output_lines) - foreach(line IN LISTS output_lines) - if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$") - set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") - endif() - endforeach() - endif() - - file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/ninja" ninja_program) - - execute_process( - COMMAND ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake - -S . - -B build - -D CMAKE_BUILD_TYPE=${{ matrix.config.build_type }} - -G Ninja - -D CMAKE_MAKE_PROGRAM=${ninja_program} - RESULT_VARIABLE result - ) - if (NOT result EQUAL 0) - message(FATAL_ERROR "Bad exit status") - endif() - - - - name: Build - shell: cmake -P {0} - run: | - set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ") - - if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") - file(STRINGS environment_script_output.txt output_lines) - foreach(line IN LISTS output_lines) - if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$") - set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") - endif() - endforeach() - endif() - - execute_process( - COMMAND ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake --build build - RESULT_VARIABLE result - ) - if (NOT result EQUAL 0) - message(FATAL_ERROR "Bad exit status") - endif() - - - - name: Run tests - shell: cmake -P {0} - run: | - include(ProcessorCount) - ProcessorCount(N) - - execute_process( - COMMAND ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/ctest -j ${N} - WORKING_DIRECTORY build - RESULT_VARIABLE result - ) - if (NOT result EQUAL 0) - message(FATAL_ERROR "Running tests failed!") - endif() - - - - name: Install Strip - run: ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake --install build --prefix instdir --strip - - - - name: Pack - working-directory: instdir - run: ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake -E tar cJfv ../${{ matrix.config.artifact }} . - - - - name: Upload - uses: actions/upload-artifact@v1 - with: - path: ./${{ matrix.config.artifact }} - name: ${{ matrix.config.artifact }} - - release: - if: contains(github.ref, 'tags/v') - runs-on: ubuntu-latest - needs: build - steps: - - name: Create Release - id: create_release - uses: actions/create-release@v1.0.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} - draft: false - prerelease: false - - name: Store Release url - run: | - echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url - - uses: actions/upload-artifact@v1 - with: - path: ./upload_url - name: upload_url - - publish: - if: contains(github.ref, 'tags/v') - name: ${{ matrix.config.name }} - runs-on: ${{ matrix.config.os }} - strategy: - fail-fast: false - matrix: - config: - - {name: Windows Latest MSVC, artifact: Windows-MSVC.tar.xz, os: ubuntu-latest} - - {name: Windows Latest MinGW, artifact: Windows-MinGW.tar.xz, os: ubuntu-latest} - - {name: Ubuntu Latest GCC, artifact: Linux.tar.xz, os: ubuntu-latest} - - {name: macOS Latest Clang, artifact: macOS.tar.xz, os: ubuntu-latest} - needs: release - - steps: - - name: Download artifact - uses: actions/download-artifact@v1 - with: - name: ${{ matrix.config.artifact }} - path: ./ - - name: Download URL - uses: actions/download-artifact@v1 - with: - name: upload_url - path: ./ - - id: set_upload_url - run: | - upload_url=`cat ./upload_url` - echo ::set-output name=upload_url::$upload_url - - name: Upload to Release - id: upload_to_release - uses: actions/upload-release-asset@v1.0.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.set_upload_url.outputs.upload_url }} - asset_path: ./${{ matrix.config.artifact }} - asset_name: ${{ matrix.config.artifact }} - asset_content_type: application/x-gtar diff --git a/third_party/rapidyaml/rapidyaml/.github/reqs.sh b/third_party/rapidyaml/rapidyaml/.github/reqs.sh deleted file mode 100644 index a1b29b478..000000000 --- a/third_party/rapidyaml/rapidyaml/.github/reqs.sh +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -# input environment variables: -# OS: the operating system -# CXX_: the compiler version. eg, g++-9 or clang++-6.0 -# BT: the build type -# VG: whether to install valgrind -# GITHUB_WORKFLOW: when run from github -# API: whether to install swig -# CMANY: whether to install cmany - - -#------------------------------------------------------------------------------- - -function c4_install_test_requirements() -{ - # this is only for ubuntu ------------------ - os=$1 - case "$os" in - ubuntu*) ;; - macos*) - if [ "$CMANY" == "ON" ] ; then - sudo pip3 install cmany - fi - return 0 - ;; - win*) - if [ "$CMANY" == "ON" ] ; then - pip install cmany - fi - if [ "$API" == "ON" ] ; then - choco install swig - which swig - fi - return 0 - ;; - *) - return 0 - ;; - esac - - # gather all the requirements ------------------ - - APT_PKG="" - PIP_PKG="" - - if [ "$GITHUB_WORKFLOW" != "" ] ; then - sudo dpkg --add-architecture i386 - else - # travis requires build-essential + cmake - _add_apt build-essential - _add_apt cmake - fi - - _add_apt linux-libc-dev:i386 - _add_apt libc6:i386 - _add_apt libc6-dev:i386 - _add_apt libc6-dbg:i386 - - _c4_gather_compilers "$CXX_" - - _add_apt python3-setuptools - _add_apt python3-pip - - #_add_apt iwyu - #_add_apt cppcheck - #_add_pip cpplint - # oclint? - if [ "$VG" == "ON" ] ; then - _add_apt valgrind - fi - - if [ "$BT" == "Coverage" ]; then - _add_apt lcov - _add_apt libffi-dev - _add_apt libssl-dev - _add_pip requests[security] - _add_pip pyopenssl - _add_pip ndg-httpsclient - _add_pip pyasn1 - _add_pip cpp-coveralls - fi - - if [ "$CMANY" != "" ] ; then - _add_pip cmany - fi - - wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - - sudo -E apt-add-repository --yes 'deb https://apt.kitware.com/ubuntu/ bionic main' - sudo -E add-apt-repository --yes ppa:ubuntu-toolchain-r/test - - echo "apt packages: $APT_PKG" - echo "pip packages: $PIP_PKG" - - # now install the requirements ------------------ - - if [ "$APT_PKG" != "" ] ; then - #sudo -E apt-get clean - sudo -E apt-get update - sudo -E apt-get install -y --force-yes $APT_PKG - fi - - if [ "$PIP_PKG" != "" ]; then - sudo pip3 install $PIP_PKG - fi - - echo 'INSTALL COMPLETE!' -} - - -#------------------------------------------------------------------------------- - -function _c4_gather_compilers() -{ - cxx=$1 - case $cxx in - g++-10 ) _c4_addgcc 10 ;; - g++-9 ) _c4_addgcc 9 ;; - g++-8 ) _c4_addgcc 8 ;; - g++-7 ) _c4_addgcc 7 ;; - g++-6 ) _c4_addgcc 6 ;; - g++-5 ) _c4_addgcc 5 ;; - g++-4.9 ) _c4_addgcc 4.9 ;; - clang++-10 ) _c4_addclang 10 ;; - clang++-9 ) _c4_addclang 9 ;; - clang++-8 ) _c4_addclang 8 ;; - clang++-7 ) _c4_addclang 7 ;; - clang++-6.0) _c4_addclang 6.0 ;; - clang++-5.0) _c4_addclang 5.0 ;; - clang++-4.0) _c4_addclang 4.0 ;; - clang++-3.9) _c4_addclang 3.9 ;; - all) - all="g++-10 g++-9 g++-8 g++-7 g++-6 g++-5 g++-4.9 clang++-10 clang++-9 clang++-8 clang++-7 clang++-6.0 clang++-5.0 clang++-4.0 clang++-3.9" - echo "installing all compilers: $all" - for cxx in $all ; do - _c4_gather_compilers $cxx - done - ;; - "") - # use default compiler - ;; - *) - echo "unknown compiler: $cxx" - exit 1 - ;; - esac -} - -# add a gcc compiler -function _c4_addgcc() -{ - version=$1 - _add_apt g++-$version - _add_apt g++-$version-multilib -} - -# add a clang compiler -function _c4_addclang() -{ - version=$1 - case $version in - # in 18.04, clang9 and later require PPAs - 9 | 10 ) _add_apt clang-$version "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-$version main" ;; - * ) _add_apt clang-$version ;; - esac - _add_apt g++-multilib # this is required for 32 bit https://askubuntu.com/questions/1057341/unable-to-find-stl-headers-in-ubuntu-18-04 - _add_apt clang-tidy-$version - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key 2>/dev/null | sudo apt-key add - -} - - -#------------------------------------------------------------------------------- - -# add a pip package to the list -function _add_pip() -{ - pkgs=$* - PIP_PKG="$PIP_PKG $pkgs" - echo "adding to pip packages: $pkgs" -} - -# add a debian package to the list -function _add_apt() -{ - pkgs=$1 - sourceslist=$2 - APT_PKG="$APT_PKG $pkgs" - echo "adding to apt packages: $pkgs" - #echo "APT_PKG=$APT_PKG" - _add_src "$sourceslist" "# for packages: $pkgs" -} - -# add an apt source -function _add_src() -{ - sourceslist=$1 - comment=$2 - if [ ! -z "$sourceslist" ] ; then - echo "adding apt source: $sourceslist" - sudo bash -c "cat >> /etc/apt/sources.list < $coverage_service" - cmake --build $build_dir --config $BT --target ${PROJ_PFX_TARGET}coverage-submit-$coverage_service -} - -# WIP -function c4_run_static_analysis() -{ - if _c4skipbitlink "$1" ; then return 0 ; fi - id=$1 - linktype=$(_c4linktype $id) - build_dir=`pwd`/build/$id - # https://blog.kitware.com/static-checks-with-cmake-cdash-iwyu-clang-tidy-lwyu-cpplint-and-cppcheck/ - pushd $PROJ_DIR -} - -function c4_cfg_test() -{ - if _c4skipbitlink "$1" ; then return 0 ; fi - id=$1 - # - build_dir=`pwd`/build/$id - install_dir=`pwd`/install/$id - mkdir -p $build_dir - mkdir -p $install_dir - # - if [ "$TOOLCHAIN" != "" ] ; then - toolchain_file=`pwd`/$TOOLCHAIN - if [ ! -f "$toolchain_file" ] ; then - echo "ERROR: toolchain not found: $toolchain_file" - exit 1 - fi - _addcmkflags -DCMAKE_TOOLCHAIN_FILE=$toolchain_file - else - bits=$(_c4bits $id) - linktype=$(_c4linktype $id) - case "$linktype" in - static) _addcmkflags -DBUILD_SHARED_LIBS=OFF ;; - shared) _addcmkflags -DBUILD_SHARED_LIBS=ON ;; - *) - echo "ERROR: unknown linktype: $linktype" - exit 1 - ;; - esac - fi - if [ "$STD" != "" ] ; then - _addcmkflags -DC4_CXX_STANDARD=$STD - _addprojflags CXX_STANDARD=$STD - fi - # - if [ "$DEV" != "OFF" ] ; then - _addprojflags DEV=ON - fi - case "$LINT" in - all ) _addprojflags LINT=ON LINT_TESTS=ON LINT_CLANG_TIDY=ON LINT_PVS_STUDIO=ON ;; - clang-tidy) _addprojflags LINT=ON LINT_TESTS=ON LINT_CLANG_TIDY=ON LINT_PVS_STUDIO=OFF ;; - pvs-studio) _addprojflags LINT=ON LINT_TESTS=ON LINT_CLANG_TIDY=OFF LINT_PVS_STUDIO=ON ;; - * ) _addprojflags LINT=OFF ;; - esac - case "$SAN" in - ALL) _addprojflags SANITIZE=ON ;; - A ) _addprojflags SANITIZE=ON ASAN=ON TSAN=OFF MSAN=OFF UBSAN=OFF ;; - T ) _addprojflags SANITIZE=ON ASAN=OFF TSAN=ON MSAN=OFF UBSAN=OFF ;; - M ) _addprojflags SANITIZE=ON ASAN=OFF TSAN=OFF MSAN=ON UBSAN=OFF ;; - UB ) _addprojflags SANITIZE=ON ASAN=OFF TSAN=OFF MSAN=OFF UBSAN=ON ;; - * ) _addprojflags SANITIZE=OFF ;; - esac - case "$SAN_ONLY" in - ON) _addprojflags SANITIZE_ONLY=ON ;; - * ) _addprojflags SANITIZE_ONLY=OFF ;; - esac - case "$VG" in - ON) _addprojflags VALGRIND=ON VALGRIND_SGCHECK=OFF ;; # FIXME SGCHECK should be ON - * ) _addprojflags VALGRIND=OFF VALGRIND_SGCHECK=OFF ;; - esac - case "$BM" in - ON) _addprojflags BUILD_BENCHMARKS=ON ;; - * ) _addprojflags BUILD_BENCHMARKS=OFF ;; - esac - if [ "$BT" == "Coverage" ] ; then - # the coverage repo tokens can be set in the travis environment: - # export CODECOV_TOKEN=....... - # export COVERALLS_REPO_TOKEN=....... - _addprojflags COVERAGE_CODECOV=ON COVERAGE_CODECOV_SILENT=ON - _addprojflags COVERAGE_COVERALLS=ON COVERAGE_COVERALLS_SILENT=ON - fi - _addcmkflags -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - if [ ! -z "$CMAKE_FLAGS" ] ; then - _addcmkflags $CMAKE_FLAGS - fi - - echo "building with additional cmake flags: $CMFLAGS" - - export C4_EXTERN_DIR=`pwd`/build/extern - mkdir -p $C4_EXTERN_DIR - - cmake --version - pwd - - # - # bash quote handling is a fiasco, and I could not find a way of storing - # quoted strings in variables and then expand the variables with correct quotes - # so we have to do this precious jewell of chicanery: - case "$CXX_" in - vs2019) - g='Visual Studio 16 2019' - case "$bits" in - 64) a=x64 ;; - 32) a=Win32 ;; - esac - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT -G "$g" -A $a $CMFLAGS - ;; - vs2017) - case "$bits" in - 64) g="Visual Studio 15 2017 Win64" ;; - 32) g="Visual Studio 15 2017" ;; - esac - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT -G "$g" $CMFLAGS - ;; - xcode) - g=Xcode - case "$bits" in - 64) a="x86_64" ;; - 32) a="i386" - exit 1 # i386 is deprecated in xcode - ;; - esac - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT -G "$g" -DCMAKE_OSX_ARCHITECTURES=$a $CMFLAGS - ;; - *g++*|*gcc*|*clang*) - export CC_=$(echo "$CXX_" | sed 's:clang++:clang:g' | sed 's:g++:gcc:g') - _c4_choose_clang_tidy $CXX_ - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT $CMFLAGS \ - -DCMAKE_C_COMPILER=$CC_ -DCMAKE_CXX_COMPILER=$CXX_ \ - -DCMAKE_C_FLAGS="-std=c99 -m$bits" -DCMAKE_CXX_FLAGS="-m$bits" - cmake --build $build_dir --target help | sed 1d | sort - ;; - arm*|"") - # for empty compiler - # or arm-* - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT $CMFLAGS - ;; - *) - echo "unknown compiler" - exit 1 - ;; - esac -} - -function _c4_choose_clang_tidy() -{ - cxx=$1 - # only for clang compilers. - case $cxx in - clang*) - # try with version first - clang_tidy_ver=$(echo $cxx | sed "s:++:-tidy:") - clang_tidy=$(echo $cxx | sed "s:++.*:-tidy:") - for n in $clang_tidy_ver $clang_tidy ; do - exe=$(which $n) - echo "searching for $n: $exe" - if [ -z "$exe" ] ; then - echo "could not find $clang_tidy" - else - _addcmkflags "-DCLANG_TIDY=$exe" - return 0 - fi - done - echo "error: could not find clang-tidy for $cxx" - exit 1 - ;; - esac -} - -# add cmake flags without project prefix -function _addcmkflags() -{ - for f in $* ; do - CMFLAGS="$CMFLAGS ${f}" - done -} - -# add cmake flags with project prefix -function _addprojflags() -{ - for f in $* ; do - CMFLAGS="$CMFLAGS -D${PROJ_PFX_CMAKE}${f}" - done -} - -function _c4_parallel_build_flags() -{ - case "$CXX_" in - vs2019|vs2017|vs2015) - # https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2019 - # https://stackoverflow.com/questions/2619198/how-to-get-number-of-cores-in-win32 - if [ -z "$NUM_JOBS_BUILD" ] ; then - echo "/maxcpucount:$NUMBER_OF_PROCESSORS" - else - echo "/maxcpucount:$NUM_JOBS_BUILD" - fi - ;; - xcode) - # https://stackoverflow.com/questions/5417835/how-to-modify-the-number-of-parallel-compilation-with-xcode - # https://gist.github.com/nlutsenko/ee245fbd239087d22137 - if [ -z "$NUM_JOBS_BUILD" ] ; then - echo "-IDEBuildOperationMaxNumberOfConcurrentCompileTasks=$(sysctl -n hw.ncpu)" - else - echo "-IDEBuildOperationMaxNumberOfConcurrentCompileTasks=$NUM_JOBS_BUILD" - fi - ;; - *g++*|*gcc*|*clang*) - if [ -z "$NUM_JOBS_BUILD" ] ; then - echo "-j $(nproc)" - else - echo "-j $NUM_JOBS_BUILD" - fi - ;; - "") # allow empty compiler - ;; - *) - echo "unknown compiler" - exit 1 - ;; - esac -} - -function _c4_generator_build_flags() -{ - case "$CXX_" in - vs2019|vs2017|vs2015) - ;; - xcode) - # WTF??? - # https://github.com/biojppm/rapidyaml/pull/97/checks?check_run_id=1504677928#step:7:964 - # https://stackoverflow.com/questions/51153525/xcode-10-unable-to-attach-db-error - echo "-UseModernBuildSystem=NO" - ;; - *g++*|*gcc*|*clang*) - ;; - "") # allow empty compiler - ;; - *) - echo "unknown compiler" - exit 1 - ;; - esac -} diff --git a/third_party/rapidyaml/rapidyaml/.github/travis-install.sh.old b/third_party/rapidyaml/rapidyaml/.github/travis-install.sh.old deleted file mode 100755 index 1d79b1b25..000000000 --- a/third_party/rapidyaml/rapidyaml/.github/travis-install.sh.old +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -# input environment variables: -# CXX_: the compiler version. eg, g++-9 or clang++-6.0 - -#------------------------------------------------------------------------------- - -# add a gcc compiler -function addgcc() -{ - version=$1 - addpkg g++-$version - addpkg g++-$version-multilib -} - -# add a clang compiler -function addclang() -{ - version=$1 - case $version in - # in 18.04, clang9 and later require PPAs - 9 | 10 ) addpkg clang-$version "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-$version main" ;; - * ) addpkg clang-$version ;; - esac - addpkg g++-multilib # this is required for 32 bit https://askubuntu.com/questions/1057341/unable-to-find-stl-headers-in-ubuntu-18-04 - addpkg clang-tidy-$version -} - -# add a debian package to the list -function addpkg() -{ - pkgs=$1 - sourceslist=$2 - DPKG="$DPKG $pkgs" - #echo "DPKG=$DPKG" - addsrc "$sourceslist" "# for packages: $pkgs" -} - -# add an apt source -function addsrc() -{ - sourceslist=$1 - comment=$2 - if [ ! -z "$sourceslist" ] ; then - sudo bash -c "cat >> /etc/apt/sources.list </dev/null | sudo apt-key add - -wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - - -sudo -E apt-add-repository --yes --no-update 'deb https://apt.kitware.com/ubuntu/ bionic main' -sudo -E add-apt-repository --yes --no-update ppa:ubuntu-toolchain-r/test - -sudo -E apt-get clean -sudo -E apt-get update - -sudo -E apt-get install -y --force-yes \ - build-essential \ - cmake \ - valgrind \ - linux-libc-dev:i386 \ - libc6:i386 \ - libc6-dev:i386 \ - libc6-dbg:i386 \ - $DPKG \ - python3-pip \ - python3-setuptools - -if [ "$BT" == "Coverage" ]; then - sudo pip3 install \ - requests[security] \ - pyopenssl \ - ndg-httpsclient \ - pyasn1 \ - cpp-coveralls -fi - -dpkg -s cmake -dpkg -L cmake -which cmake -cmake --version -$CXX_ --version -which $CXX_ - -echo "INSTALL COMPLETE: current directory: $(pwd)" diff --git a/third_party/rapidyaml/rapidyaml/.github/travis-setenv.sh.old b/third_party/rapidyaml/rapidyaml/.github/travis-setenv.sh.old deleted file mode 100755 index 5a9472efd..000000000 --- a/third_party/rapidyaml/rapidyaml/.github/travis-setenv.sh.old +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -NUM_JOBS=2 -PROJ_DIR=$(pwd) -PROJ_PFX=RYML_ - -pwd -export CC_=$(echo "$CXX_" | sed 's:clang++:clang:g' | sed 's:g++:gcc:g') -$CXX_ --version -$CC_ --version -cmake --version - -# add cmake flags, without project prefix -function addcmkflags() -{ - for f in $* ; do - CMFLAGS="$CMFLAGS ${f}" - done -} -# add cmake flags, with project prefix -function addprojflags() -{ - for f in $* ; do - CMFLAGS="$CMFLAGS -D${PROJ_PFX}${f}" - done -} - -addcmkflags -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -addprojflags DEV=ON - -case "$LINT" in - all ) addprojflags LINT=ON LINT_TESTS=ON LINT_CLANG_TIDY=ON LINT_PVS_STUDIO=ON ;; - clang-tidy) addprojflags LINT=ON LINT_TESTS=ON LINT_CLANG_TIDY=ON LINT_PVS_STUDIO=OFF ;; - pvs-studio) addprojflags LINT=ON LINT_TESTS=ON LINT_CLANG_TIDY=OFF LINT_PVS_STUDIO=ON ;; - * ) addprojflags LINT=OFF ;; -esac - -case "$SAN" in - ALL) addprojflags SANITIZE=ON ;; - A ) addprojflags SANITIZE=ON ASAN=ON TSAN=OFF MSAN=OFF UBSAN=OFF ;; - T ) addprojflags SANITIZE=ON ASAN=OFF TSAN=ON MSAN=OFF UBSAN=OFF ;; - M ) addprojflags SANITIZE=ON ASAN=OFF TSAN=OFF MSAN=ON UBSAN=OFF ;; - UB ) addprojflags SANITIZE=ON ASAN=OFF TSAN=OFF MSAN=OFF UBSAN=ON ;; - * ) addprojflags SANITIZE=OFF ;; -esac - -case "$SAN_ONLY" in - ON) addprojflags SANITIZE_ONLY=ON ;; - * ) addprojflags SANITIZE_ONLY=OFF ;; -esac - -case "$VG" in - ON) addprojflags VALGRIND=ON VALGRIND_SGCHECK=OFF ;; # FIXME SGCHECK should be ON - * ) addprojflags VALGRIND=OFF VALGRIND_SGCHECK=OFF ;; -esac - -case "$BM" in - ON) addprojflags BUILD_BENCHMARKS=ON ;; - * ) addprojflags BUILD_BENCHMARKS=OFF ;; -esac - -if [ "$STD" != "" ] ; then - addcmkflags -DC4_CXX_STANDARD=$STD - addprojflags CXX_STANDARD=$STD -fi - -if [ "$BT" == "Coverage" ] ; then - # the coverage repo tokens can be set in the travis environment: - # export CODECOV_TOKEN=....... - # export COVERALLS_REPO_TOKEN=....... - addprojflags COVERAGE_CODECOV=ON COVERAGE_CODECOV_SILENT=ON - addprojflags COVERAGE_COVERALLS=ON COVERAGE_COVERALLS_SILENT=ON -fi - -echo "building with additional cmake flags: $CMFLAGS" - -export C4_EXTERN_DIR=`pwd`/build/extern -mkdir -p $C4_EXTERN_DIR - - -function ryml_cfg_test() -{ - bits=$1 - linktype=$2 - # - build_dir=`pwd`/build/$bits-$linktype - install_dir=`pwd`/install/$bits-$linktype - mkdir -p $build_dir - mkdir -p $install_dir - # - case "$linktype" in - static) linktype="-DBUILD_SHARED_LIBS=OFF" ;; - dynamic) linktype="-DBUILD_SHARED_LIBS=ON" ;; - esac - cmake -S $PROJ_DIR -B $build_dir \ - -DCMAKE_C_COMPILER=$CC_ -DCMAKE_C_FLAGS="-std=c99 -m$bits" \ - -DCMAKE_CXX_COMPILER=$CXX_ -DCMAKE_CXX_FLAGS="-m$bits" \ - -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT \ - $CMFLAGS \ - $linktype - cmake --build $build_dir --target help | sed 1d | sort -} - -function ryml_run_test() -{ - bits=$1 - linktype=$2 - build_dir=`pwd`/build/$bits-$linktype - export CTEST_OUTPUT_ON_FAILURE=1 - cmake --build $build_dir --parallel $NUM_JOBS --target test -} - -function ryml_submit_coverage() -{ - if [ "$BT" == "Coverage" ] ; then - bits=$1 - linktype=$2 - coverage_service=$3 - build_dir=`pwd`/build/$bits-$linktype - echo "Submitting coverage data: $build_dir --> $coverage_service" - cmake --build $build_dir --parallel $NUM_JOBS --target ryml-coverage-submit-$coverage_service - fi -} diff --git a/third_party/rapidyaml/rapidyaml/.github/workflows/ci.yml b/third_party/rapidyaml/rapidyaml/.github/workflows/ci.yml deleted file mode 100644 index 89fcdff29..000000000 --- a/third_party/rapidyaml/rapidyaml/.github/workflows/ci.yml +++ /dev/null @@ -1,697 +0,0 @@ -name: ci - -defaults: - #if: "!contains(github.event.head_commit.message, 'skip ci')" # SKIP - run: - # Use a bash shell so we can use the same syntax for environment variable - # access regardless of the host operating system - shell: bash -e -x {0} - -on: - - push - - pull_request - - workflow_dispatch - -env: - PROJ_PFX_TARGET: ryml- - PROJ_PFX_CMAKE: RYML_ - CMAKE_FLAGS: -DRYML_TEST_SUITE=ON - NUM_JOBS_BUILD: # 4 - - -# ubuntu-20.04: -# # https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md -# gcc: 7.5.0, 8.4.0, 9.3.0, 10.2.0 -# clang: 8.0.1, 9.0.1, 10.0.0 -# ubuntu-18.04: -# # https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu1804-README.md -# gcc: 7.5.0, 8.4.0, 9.3.0, 10.1.0 -# clang: 6.0.0, 8.0.0, 9.0.0 -# ubuntu-16.04: -# # https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu1604-README.md -# gcc: 5.5.0, 7.5.0, 8.4.0, 9.3.0 -# clang: 6.0.0, 8.0.0, 9.0.1 -# macos-11.0: macOS Big Sur 11.0 -# # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11.0-Readme.md -# Xcode 12.1 11.7 -# clang/LLVM 10.0.1 -# gcc-8 gcc-9 -# macos-10.15: macOS Catalina 10.15 -# # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-10.15-Readme.md -# Xcode 12.1 11.7 -# clang/LLVM 11.0.0 -# gcc-8 gcc-9 -# windows-2019: -# # https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md -# vs2019 -# windows-2016: -# # https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md -# vs2017 -jobs: - - #---------------------------------------------------------------------------- - test_coverage: - # if: github.ref == 'refs/heads/master' - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - - {std: 11, cxx: g++-7, bt: Coverage, os: ubuntu-18.04, bitlinks: shared64 static64} - - {std: 11, cxx: g++-7, bt: Coverage, os: ubuntu-18.04, bitlinks: shared32 static32} - - {std: 17, cxx: g++-7, bt: Coverage, os: ubuntu-18.04, bitlinks: shared64 static64} - - {std: 17, cxx: g++-7, bt: Coverage, os: ubuntu-18.04, bitlinks: shared32 static32} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}", CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}", COVERALLS_REPO_TOKEN: "${{secrets.COVERALLS_REPO_TOKEN}}"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info} - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} - - {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64} - - name: shared64-submit - run: | - source .github/setenv.sh - c4_submit_coverage shared64 codecov - #c4_submit_coverage shared64 coveralls # only accepts one submission per job - - name: static64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static64 - - {name: static64-build, run: source .github/setenv.sh && c4_build_test static64} - - {name: static64-run, run: source .github/setenv.sh && c4_run_test static64} - - name: static64-submit - run: | - source .github/setenv.sh - c4_submit_coverage static64 codecov - c4_submit_coverage static64 coveralls - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - name: static32-submit - run: | - source .github/setenv.sh - c4_submit_coverage static32 codecov - #c4_submit_coverage static32 coveralls # only accepts one submission per job - - name: shared32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared32 - - {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32} - - {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32} - - name: shared32-submit - run: | - source .github/setenv.sh - c4_submit_coverage shared32 codecov - #c4_submit_coverage shared32 coveralls # only accepts one submission per job - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - name: static32-submit - run: | - source .github/setenv.sh - c4_submit_coverage static32 codecov - #c4_submit_coverage static32 coveralls # only accepts one submission per job - - #---------------------------------------------------------------------------- - test_windows: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - - {std: 11, cxx: vs2017, bt: Debug , os: windows-2016, bitlinks: shared64 static32} - - {std: 11, cxx: vs2017, bt: Release, os: windows-2016, bitlinks: shared64 static32} - - {std: 14, cxx: vs2017, bt: Debug , os: windows-2016, bitlinks: shared64 static32} - - {std: 14, cxx: vs2017, bt: Release, os: windows-2016, bitlinks: shared64 static32} - - {std: 11, cxx: vs2019, bt: Debug , os: windows-2019, bitlinks: shared64 static32} - - {std: 11, cxx: vs2019, bt: Release, os: windows-2019, bitlinks: shared64 static32} - - {std: 17, cxx: vs2019, bt: Debug , os: windows-2019, bitlinks: shared64 static32} - - {std: 17, cxx: vs2019, bt: Release, os: windows-2019, bitlinks: shared64 static32} - - {std: 20, cxx: vs2019, bt: Debug , os: windows-2019, bitlinks: shared64 static32} - - {std: 20, cxx: vs2019, bt: Release, os: windows-2019, bitlinks: shared64 static32} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info} - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} - - {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64} - - {name: shared64-pack, run: source .github/setenv.sh && c4_package shared64} - - name: static64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static64 - - {name: static64-build, run: source .github/setenv.sh && c4_build_test static64} - - {name: static64-run, run: source .github/setenv.sh && c4_run_test static64} - - {name: static64-pack, run: source .github/setenv.sh && c4_package static64} - - name: shared32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared32 - - {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32} - - {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32} - - {name: shared32-pack, run: source .github/setenv.sh && c4_package shared32} - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - {name: static32-pack, run: source .github/setenv.sh && c4_package static32} - - #---------------------------------------------------------------------------- - test_macosx: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - - {std: 11, cxx: xcode, bt: Debug , os: macos-11.0, bitlinks: shared64 static64} - - {std: 11, cxx: xcode, bt: Release, os: macos-11.0, bitlinks: shared64 static64} - - {std: 17, cxx: xcode, bt: Debug , os: macos-11.0, bitlinks: shared64 static64} - - {std: 17, cxx: xcode, bt: Release, os: macos-11.0, bitlinks: shared64 static64} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info} - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} - - {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64} - - {name: shared64-pack, run: source .github/setenv.sh && c4_package shared64} - - name: static64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static64 - - {name: static64-build, run: source .github/setenv.sh && c4_build_test static64} - - {name: static64-run, run: source .github/setenv.sh && c4_run_test static64} - - {name: static64-pack, run: source .github/setenv.sh && c4_package static64} - - name: shared32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared32 - - {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32} - - {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32} - - {name: shared32-pack, run: source .github/setenv.sh && c4_package shared32} - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - {name: static32-pack, run: source .github/setenv.sh && c4_package static32} - - #---------------------------------------------------------------------------- - test_gcc_canary: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - - {std: 11, cxx: g++-7 , bt: Debug , os: ubuntu-18.04, bitlinks: shared64 static32} - - {std: 11, cxx: g++-7 , bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} - - {std: 20, cxx: g++-10 , bt: Debug , os: ubuntu-18.04, bitlinks: shared64 static32} - - {std: 20, cxx: g++-10 , bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} - - {std: 11, cxx: g++-5 , bt: Debug , os: ubuntu-16.04, bitlinks: shared64 static32} - - {std: 11, cxx: g++-5 , bt: Release, os: ubuntu-16.04, bitlinks: shared64 static32} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info} - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} - - {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64} - - {name: shared64-pack, run: source .github/setenv.sh && c4_package shared64} - - name: static64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static64 - - {name: static64-build, run: source .github/setenv.sh && c4_build_test static64} - - {name: static64-run, run: source .github/setenv.sh && c4_run_test static64} - - {name: static64-pack, run: source .github/setenv.sh && c4_package static64} - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - {name: static32-pack, run: source .github/setenv.sh && c4_package static32} - - name: shared32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared32 - - {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32} - - {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32} - - {name: shared32-pack, run: source .github/setenv.sh && c4_package shared32} - - #---------------------------------------------------------------------------- - test_clang_canary: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - - {std: 17, cxx: clang++-10 , bt: Debug , os: ubuntu-18.04, bitlinks: shared64 static32} - - {std: 17, cxx: clang++-10 , bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} - - {std: 11, cxx: clang++-6.0, bt: Debug , os: ubuntu-16.04, bitlinks: shared64 static32} - - {std: 11, cxx: clang++-6.0, bt: Release, os: ubuntu-16.04, bitlinks: shared64 static32} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info} - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} - - {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64} - - {name: shared64-pack, run: source .github/setenv.sh && c4_package shared64} - - name: static64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static64 - - {name: static64-build, run: source .github/setenv.sh && c4_build_test static64} - - {name: static64-run, run: source .github/setenv.sh && c4_run_test static64} - - {name: static64-pack, run: source .github/setenv.sh && c4_package static64} - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - {name: static32-pack, run: source .github/setenv.sh && c4_package static32} - - name: shared32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared32 - - {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32} - - {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32} - - {name: shared32-pack, run: source .github/setenv.sh && c4_package shared32} - - #---------------------------------------------------------------------------- - test_clang_tidy: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - # clang tidy takes a long time, so don't do multiple bits/linktypes - - {std: 11, cxx: clang++-9, bt: Debug , lint: clang-tidy, bitlinks: shared64 static64, os: ubuntu-18.04} - - {std: 11, cxx: clang++-9, bt: Debug , lint: clang-tidy, bitlinks: shared32 static32, os: ubuntu-18.04} - - {std: 11, cxx: clang++-9, bt: ReleaseWithDebInfo, lint: clang-tidy, bitlinks: shared64 static64, os: ubuntu-18.04} - - {std: 11, cxx: clang++-9, bt: ReleaseWithDebInfo, lint: clang-tidy, bitlinks: shared32 static32, os: ubuntu-18.04} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info} - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} - - {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64} - - {name: shared64-pack, run: source .github/setenv.sh && c4_package shared64} - - name: static64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static64 - - {name: static64-build, run: source .github/setenv.sh && c4_build_test static64} - - {name: static64-run, run: source .github/setenv.sh && c4_run_test static64} - - {name: static64-pack, run: source .github/setenv.sh && c4_package static64} - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - {name: static32-pack, run: source .github/setenv.sh && c4_package static32} - - name: shared32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared32 - - {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32} - - {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32} - - {name: shared32-pack, run: source .github/setenv.sh && c4_package shared32} - - #---------------------------------------------------------------------------- - test_gcc_extended: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - # VALGRIND - - {std: 11, cxx: g++-10, bt: Debug , vg: ON, os: ubuntu-18.04} - - {std: 11, cxx: g++-10, bt: Release, vg: ON, os: ubuntu-18.04} - - {std: 14, cxx: g++-10, bt: Debug , vg: ON, os: ubuntu-18.04} - - {std: 14, cxx: g++-10, bt: Release, vg: ON, os: ubuntu-18.04} - - {std: 17, cxx: g++-10, bt: Debug , vg: ON, os: ubuntu-18.04} - - {std: 17, cxx: g++-10, bt: Release, vg: ON, os: ubuntu-18.04} - - {std: 20, cxx: g++-10, bt: Debug , vg: ON, os: ubuntu-18.04} - - {std: 20, cxx: g++-10, bt: Release, vg: ON, os: ubuntu-18.04} - # - - {std: 11, cxx: g++-9, bt: Debug , os: ubuntu-18.04} - - {std: 11, cxx: g++-9, bt: Release, os: ubuntu-18.04} - - {std: 11, cxx: g++-8, bt: Debug , os: ubuntu-18.04} - - {std: 11, cxx: g++-8, bt: Release, os: ubuntu-18.04} - - {std: 11, cxx: g++-7, bt: Debug , os: ubuntu-18.04} - - {std: 11, cxx: g++-7, bt: Release, os: ubuntu-18.04} - - {std: 11, cxx: g++-6, bt: Debug , os: ubuntu-18.04} - - {std: 11, cxx: g++-6, bt: Release, os: ubuntu-18.04} - - {std: 11, cxx: g++-5, bt: Debug , os: ubuntu-18.04} - - {std: 11, cxx: g++-5, bt: Release, os: ubuntu-18.04} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info} - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} - - {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64} - - {name: shared64-pack, run: source .github/setenv.sh && c4_package shared64} - - name: static64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static64 - - {name: static64-build, run: source .github/setenv.sh && c4_build_test static64} - - {name: static64-run, run: source .github/setenv.sh && c4_run_test static64} - - {name: static64-pack, run: source .github/setenv.sh && c4_package static64} - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - {name: static32-pack, run: source .github/setenv.sh && c4_package static32} - - name: shared32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared32 - - {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32} - - {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32} - - {name: shared32-pack, run: source .github/setenv.sh && c4_package shared32} - - #---------------------------------------------------------------------------- - test_clang_extended: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - - {std: 11, cxx: clang++-9 , bt: Debug , vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-9 , bt: Release, vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-8 , bt: Debug , vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-8 , bt: Release, vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-7 , bt: Debug , vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-7 , bt: Release, vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-6.0, bt: Debug , vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-6.0, bt: Release, vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-5.0, bt: Debug , vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-5.0, bt: Release, vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-4.0, bt: Debug , vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-4.0, bt: Release, vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-3.9, bt: Debug , vg: on, os: ubuntu-18.04} - - {std: 11, cxx: clang++-3.9, bt: Release, vg: on, os: ubuntu-18.04} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info} - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} - - {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64} - - {name: shared64-pack, run: source .github/setenv.sh && c4_package shared64} - - name: static64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static64 - - {name: static64-build, run: source .github/setenv.sh && c4_build_test static64} - - {name: static64-run, run: source .github/setenv.sh && c4_run_test static64} - - {name: static64-pack, run: source .github/setenv.sh && c4_package static64} - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - {name: static32-pack, run: source .github/setenv.sh && c4_package static32} - - name: shared32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared32 - - {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32} - - {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32} - - {name: shared32-pack, run: source .github/setenv.sh && c4_package shared32} - - #---------------------------------------------------------------------------- - test_clang_sanitize: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - # these jobs take much longer, so run only one bitlink pair per job to profit from parallelism - - {std: 11, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: shared64, os: ubuntu-18.04} - - {std: 11, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: static64, os: ubuntu-18.04} - - {std: 11, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: shared32, os: ubuntu-18.04} - - {std: 11, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: static32, os: ubuntu-18.04} - - {std: 11, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: shared64, os: ubuntu-18.04} - - {std: 11, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: static64, os: ubuntu-18.04} - - {std: 11, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: shared32, os: ubuntu-18.04} - - {std: 11, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: static32, os: ubuntu-18.04} - - {std: 17, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: shared64, os: ubuntu-18.04} - - {std: 17, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: static64, os: ubuntu-18.04} - - {std: 17, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: shared32, os: ubuntu-18.04} - - {std: 17, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: static32, os: ubuntu-18.04} - - {std: 17, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: shared64, os: ubuntu-18.04} - - {std: 17, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: static64, os: ubuntu-18.04} - - {std: 17, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: shared32, os: ubuntu-18.04} - - {std: 17, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: static32, os: ubuntu-18.04} - - {std: 20, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: shared64, os: ubuntu-18.04} - - {std: 20, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: static64, os: ubuntu-18.04} - - {std: 20, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: shared32, os: ubuntu-18.04} - - {std: 20, cxx: clang++-10, bt: Debug , vg: ON, san: ALL, bitlinks: static32, os: ubuntu-18.04} - - {std: 20, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: shared64, os: ubuntu-18.04} - - {std: 20, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: static64, os: ubuntu-18.04} - - {std: 20, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: shared32, os: ubuntu-18.04} - - {std: 20, cxx: clang++-10, bt: Release, vg: ON, san: ALL, bitlinks: static32, os: ubuntu-18.04} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info} - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} - - {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64} - - {name: shared64-pack, run: source .github/setenv.sh && c4_package shared64} - - name: static64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static64 - - {name: static64-build, run: source .github/setenv.sh && c4_build_test static64} - - {name: static64-run, run: source .github/setenv.sh && c4_run_test static64} - - {name: static64-pack, run: source .github/setenv.sh && c4_package static64} - - name: static32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test static32 - - {name: static32-build, run: source .github/setenv.sh && c4_build_test static32} - - {name: static32-run, run: source .github/setenv.sh && c4_run_test static32} - - {name: static32-pack, run: source .github/setenv.sh && c4_package static32} - - name: shared32-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared32 - - {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32} - - {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32} - - {name: shared32-pack, run: source .github/setenv.sh && c4_package shared32} - -# #---------------------------------------------------------------------------- -# # https://blog.kitware.com/static-checks-with-cmake-cdash-iwyu-clang-tidy-lwyu-cpplint-and-cppcheck/ -# static_analysis: -# continue-on-error: true -# runs-on: ${{matrix.os}} -# strategy: -# fail-fast: false -# matrix: -# include: -# # these jobs take much longer, so run only one bitlink pair per job to profit from parallelism -# - {std: 11, cxx: clang++-10, bt: Debug , bitlinks: shared64, os: ubuntu-18.04} -# - {std: 11, cxx: clang++-10, bt: Release, bitlinks: shared64, os: ubuntu-18.04} -# - {std: 14, cxx: clang++-10, bt: Debug , bitlinks: shared64, os: ubuntu-18.04} -# - {std: 14, cxx: clang++-10, bt: Release, bitlinks: shared64, os: ubuntu-18.04} -# - {std: 17, cxx: clang++-10, bt: Debug , bitlinks: shared64, os: ubuntu-18.04} -# - {std: 17, cxx: clang++-10, bt: Release, bitlinks: shared64, os: ubuntu-18.04} -# - {std: 20, cxx: clang++-10, bt: Debug , bitlinks: shared64, os: ubuntu-18.04} -# - {std: 20, cxx: clang++-10, bt: Release, bitlinks: shared64, os: ubuntu-18.04} -# env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} -# steps: -# - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} -# - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} -# - {name: show info, run: source .github/setenv.sh && c4_show_info} -# - name: shared64-configure--------------------------------------------------- -# run: source .github/setenv.sh && c4_cfg_test shared64 -# - {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64} -# - {name: clang-tidy, run: cmake "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-3.9;-checks=*" ../path/to/source} -# - {name: cppcheck, run: cmake "-DCMAKE_CXX_CPPCHECK=/usr/bin/cppcheck;--std=c++11" ../path/to/source} -# - {name: cpplint, run: cmake "-DCMAKE_CXX_CPPLINT=/usr/local/bin/cpplint;--linelength=179" ..} -# - {name: include-what-you-use, run: cmake "-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=/usr/bin/iwyu;--transitive_includes_only" ..} -# - {name: link-what-you-use, run: cmake -DCMAKE_LINK_WHAT_YOU_USE=TRUE ..} - - #---------------------------------------------------------------------------- - examples: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - - {bt: Debug , os: ubuntu-18.04} - - {bt: Release, os: ubuntu-18.04} - - {bt: Debug , os: windows-2019} - - {bt: Release, os: windows-2019} - - {bt: Debug , os: macos-11.0} - - {bt: Release, os: macos-11.0} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}", - CMANY: ON} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: python3, uses: actions/setup-python@v2, with: {python-version: 3.7}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info } - - {name: add_subdirectory, run: cmany b -t $BT examples/add_subdirectory } - - #---------------------------------------------------------------------------- - test_api: - continue-on-error: true - runs-on: ${{matrix.os}} - strategy: - fail-fast: false - matrix: - include: - - {bt: Release, os: ubuntu-18.04} - - {bt: Release, os: windows-2019} - env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}", - API: ON, CMAKE_FLAGS: "-DRYML_DEV=OFF -DRYML_BUILD_API=ON -DRYML_API_TESTS=ON -DRYML_API_BENCHMARKS=OFF"} - steps: - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info && which swig } - - name: api-shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: api-shared64-python-build, run: source .github/setenv.sh && c4_build_target shared64 ryml-api-python3} - - {name: api-shared64-python-test, run: source .github/setenv.sh && c4_build_target shared64 ryml-api-test-python3} - - #---------------------------------------------------------------------------- - # useful to iterate when fixing the release - # ver=0.0.0-rc1 ; ( set -x ; git tag -d v$ver ; git push origin :v$ver ) ; (set -x ; set -e ; git add -u ; git commit --amend --no-edit ; git tag --annotate --message "v$ver" "v$ver" ; git push -f --tags origin gh_actions ) - - release: - if: contains(github.ref, 'tags/v') - runs-on: ubuntu-latest - #needs: [test_coverage, test_windows, test_macosx, test_gcc_canary, test_clang_canary, test_clang_tidy, test_gcc_extended, test_clang_extended, test_clang_sanitize, test_api] - steps: - - name: Install requirements - run: | - sudo -E pip install git-archive-all - - name: Get version - id: get_version - # https://github.community/t/how-to-get-just-the-tag-name/16241/11 - run: | - echo ::set-output name=SRC_TAG::${GITHUB_REF#refs/tags/} - echo ::set-output name=SRC_VERSION::${GITHUB_REF#refs/tags/v} - echo SRC_TAG=${GITHUB_REF#refs/tags/} - echo SRC_VERSION=${GITHUB_REF#refs/tags/v} - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - name: Create Release - id: create_release - uses: actions/create-release@v1 # https://github.com/marketplace/actions/create-a-release - env: - GITHUB_TOKEN: "${{secrets.GITHUB_TOKEN}}" - SRC_TAG: "${{steps.get_version.outputs.SRC_TAG}}" - SRC_VERSION: "${{steps.get_version.outputs.SRC_VERSION}}" - with: - tag_name: ${{github.ref}} - release_name: Release ${{steps.get_version.outputs.SRC_VERSION}} - draft: true # to create a draft (unpublished) release, false to create a published one. Default: false - prerelease: ${{contains(github.ref, '-rc')}} - body_path: ${{github.workspace}}/changelog/${{steps.get_version.outputs.SRC_VERSION}}.md - - name: Create source packs - id: src_pack - run: | - version=${{steps.get_version.outputs.SRC_VERSION}} - name=ryml-$version - git-archive-all --prefix $name $name.tgz - git-archive-all --prefix $name $name.zip - echo ::set-output name=TGZ::$name.tgz - echo ::set-output name=ZIP::$name.zip - - name: Upload tgz source pack - id: upload_src_tgz_to_release - uses: actions/upload-release-asset@v1.0.1 - env: {GITHUB_TOKEN: "${{secrets.GITHUB_TOKEN}}"} - with: - upload_url: ${{steps.create_release.outputs.upload_url}} - asset_path: ${{steps.src_pack.outputs.TGZ}} - asset_name: ${{steps.src_pack.outputs.TGZ}} - asset_content_type: application/gzip - - name: Upload zip source pack - id: upload_src_zip_to_release - uses: actions/upload-release-asset@v1.0.1 - env: {GITHUB_TOKEN: "${{secrets.GITHUB_TOKEN}}"} - with: - upload_url: ${{steps.create_release.outputs.upload_url}} - asset_path: ${{steps.src_pack.outputs.ZIP}} - asset_name: ${{steps.src_pack.outputs.ZIP}} - asset_content_type: application/zip - - name: Save Release URL for uploading binary artifacts - run: | - echo "UPLOAD_URL: ${{steps.create_release.outputs.upload_url}}" - echo "${{steps.create_release.outputs.upload_url}}" > ./upload_url - - name: Upload Release URL - uses: actions/upload-artifact@v1 - with: - path: ./upload_url - name: upload_url - - #---------------------------------------------------------------------------- - publish: - needs: release - name: publish/${{matrix.config.os}}/${{matrix.config.gen}} - runs-on: ${{matrix.config.os}} - env: {DEV: OFF, BT: Release, OS: "${{matrix.config.os}}", CXX_: "${{matrix.config.cxx}}", GEN: "${{matrix.config.gen}}"} - strategy: - fail-fast: false - matrix: - config: - # name of the artifact | suffix | cpack gen | mime type | os | cxx - - {name: Ubuntu 20.04 deb , sfx: unix64.deb, gen: DEB , mime: vnd.debian.binary-package, os: ubuntu-20.04 } - - {name: Ubuntu 20.04 sh , sfx: unix64.sh , gen: STGZ , mime: x-sh , os: ubuntu-20.04 } - - {name: Ubuntu 18.04 deb , sfx: unix64.deb, gen: DEB , mime: vnd.debian.binary-package, os: ubuntu-18.04 } - - {name: Ubuntu 18.04 sh , sfx: unix64.sh , gen: STGZ , mime: x-sh , os: ubuntu-18.04 } - - {name: Ubuntu 16.04 deb , sfx: unix64.deb, gen: DEB , mime: vnd.debian.binary-package, os: ubuntu-16.04 } - - {name: Ubuntu 16.04 sh , sfx: unix64.sh , gen: STGZ , mime: x-sh , os: ubuntu-16.04 } - - {name: Windows VS2017 zip, sfx: win64.zip , gen: ZIP , mime: zip , os: windows-2016, cxx: vs2017} - - {name: Windows VS2019 zip, sfx: win64.zip , gen: ZIP , mime: zip , os: windows-2019, cxx: vs2019} - - {name: MacOSX sh , sfx: apple64.sh, gen: STGZ , mime: x-sh , os: macos-11.0 , cxx: xcode } - steps: - - name: Get version - id: get_version - # https://github.community/t/how-to-get-just-the-tag-name/16241/11 - run: | - echo ::set-output name=SRC_VERSION::${GITHUB_REF#refs/tags/v} - echo SRC_VERSION=${GITHUB_REF#refs/tags/v} - echo GEN=$GEN - - name: Download upload URL - uses: actions/download-artifact@v1 - with: {name: upload_url, path: ./} - - name: Preprocess - id: preprocess - run: | - upload_url=`cat ./upload_url` - echo ::set-output name=upload_url::$upload_url - # the package has the same name in multiple same-platform+same-sfx - # instances, but the uploaded asset needs to have different names: - sfx=${{matrix.config.sfx}} - case "${{matrix.config.os}}" in - ubuntu*) - sfx=$(echo $sfx | sed "s:unix64:${{matrix.config.os}}:") - ;; - windows*) - sfx=$(echo $sfx | sed "s:win64:win64-${{matrix.config.cxx}}:") - ;; - macos*) - sfx=$(echo $sfx | sed "s:apple64:macosx-${{matrix.config.cxx}}:") - ;; - esac - asset_name=ryml-${{steps.get_version.outputs.SRC_VERSION}}-$sfx - echo ::set-output name=asset_name::$asset_name - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info } - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_target shared64} - - name: shared64-pack - run: | - source .github/setenv.sh && c4_package shared64 $GEN - src=./build/shared64/ryml-${{steps.get_version.outputs.SRC_VERSION}}-${{matrix.config.sfx}} - dst=${{steps.preprocess.outputs.asset_name}} - cp -fav $src $dst - - name: Upload artifact - id: upload_to_release - uses: actions/upload-release-asset@v1.0.1 - env: {GITHUB_TOKEN: "${{secrets.GITHUB_TOKEN}}"} - with: - upload_url: ${{steps.preprocess.outputs.upload_url}} - asset_path: ${{steps.preprocess.outputs.asset_name}} - asset_name: ${{steps.preprocess.outputs.asset_name}} - asset_content_type: application/${{matrix.config.mime}} - #- name: Report artifact URL - # run: echo "artifact uploaded successfully: ${{steps.upload_to_release.outputs.browser_download_url}}" diff --git a/third_party/rapidyaml/rapidyaml/.gitignore b/third_party/rapidyaml/rapidyaml/.gitignore deleted file mode 100644 index 5daef5f26..000000000 --- a/third_party/rapidyaml/rapidyaml/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# text editor files -*.bck -\#* -*~ -.cquery_cached_index/ -.clangd/ -.ccls-cache/ -.cache/ - -# gdb files -.gdbinit -setup.gdb - -# Visual Studio files -.vs/ -.vscode/ -# QtCreator files -CMakeLists.txt.user* -# Eclipse -.project -.cproject -/.settings/ -# KDevelop files -*.kdev4 - -# build files -build/ -install/ -.python-version -compile_commands.json - -# test files -/Testing/ - -# continuous integration files -.ci/.vagrant diff --git a/third_party/rapidyaml/rapidyaml/.gitmodules b/third_party/rapidyaml/rapidyaml/.gitmodules deleted file mode 100644 index b8f0b0ef4..000000000 --- a/third_party/rapidyaml/rapidyaml/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "extern/c4core"] - path = ext/c4core - url = https://github.com/biojppm/c4core diff --git a/third_party/rapidyaml/rapidyaml/.lgtm.yml b/third_party/rapidyaml/rapidyaml/.lgtm.yml deleted file mode 100644 index c1376d236..000000000 --- a/third_party/rapidyaml/rapidyaml/.lgtm.yml +++ /dev/null @@ -1,2 +0,0 @@ -queries: -- exclude: cpp/unsigned-comparison-zero diff --git a/third_party/rapidyaml/rapidyaml/CMakeLists.txt b/third_party/rapidyaml/rapidyaml/CMakeLists.txt deleted file mode 100644 index 40762b546..000000000 --- a/third_party/rapidyaml/rapidyaml/CMakeLists.txt +++ /dev/null @@ -1,105 +0,0 @@ -cmake_minimum_required(VERSION 3.12) -include(./ext/c4core/cmake/c4Project.cmake) -project(ryml - DESCRIPTION "Rapid YAML parsing and emitting" - HOMEPAGE_URL "https://github.com/biojppm/rapidyaml" - LANGUAGES CXX) -c4_project(VERSION 0.1.0 STANDALONE - AUTHOR "Joao Paulo Magalhaes ") - - -#------------------------------------------------------- - -option(RYML_DEFAULT_CALLBACKS "Enable ryml's default implementation of callbacks: allocate(), free(), error()" ON) -option(RYML_BUILD_API "Enable API generation (python, etc)" OFF) -option(RYML_DBG "Enable (very verbose) ryml debug prints." OFF) - - -#------------------------------------------------------- - -c4_require_subproject(c4core INCORPORATE - SUBDIRECTORY ${RYML_EXT_DIR}/c4core) - -c4_add_library(ryml - SOURCES - ryml.hpp - ryml_std.hpp - c4/yml/detail/checks.hpp - c4/yml/detail/parser_dbg.hpp - c4/yml/detail/stack.hpp - c4/yml/common.hpp - c4/yml/common.cpp - c4/yml/emit.def.hpp - c4/yml/emit.hpp - c4/yml/export.hpp - c4/yml/node.hpp - c4/yml/parse.hpp - c4/yml/parse.cpp - c4/yml/preprocess.hpp - c4/yml/preprocess.cpp - c4/yml/std/map.hpp - c4/yml/std/std.hpp - c4/yml/std/string.hpp - c4/yml/std/vector.hpp - c4/yml/tree.hpp - c4/yml/tree.cpp - c4/yml/writer.hpp - c4/yml/yml.hpp - ryml.natvis - SOURCE_ROOT ${RYML_SRC_DIR} - INC_DIRS - $ - $ - LIBS c4core - INCORPORATE c4core - ) - -if(NOT RYML_DEFAULT_CALLBACKS) - target_compile_definitions(ryml PRIVATE RYML_NO_DEFAULT_CALLBACKS) -endif() - -if(RYML_DBG) - target_compile_definitions(ryml PRIVATE RYML_DBG) -endif() - - -#------------------------------------------------------- - -# TODO(sbarzowski) Needed to comment out te commands above. -# This part causes CMake errors for some reason and it doesn't -# seem relevant in our (vendored) use-case. -# -# c4_install_target(ryml) -# c4_install_exports(DEPENDENCIES c4core) -# c4_pack_project() - - -#------------------------------------------------------- -# developer targets - -# extern libraries, used only for testing/benchmarking -if(RYML_BUILD_TESTS OR RYML_BUILD_BENCHMARKS) - set(ed ${CMAKE_CURRENT_BINARY_DIR}/subprojects) # casual ryml extern dir (these projects are not part of ryml and are downloaded and compiled on the fly) - # these are used both for testing and benchmarking - c4_require_subproject(c4fs REMOTE - GIT_REPOSITORY https://github.com/biojppm/c4fs - GIT_TAG master) - c4_require_subproject(libyaml REMOTE - GIT_REPOSITORY https://github.com/yaml/libyaml - GIT_TAG master - OVERRIDE BUILD_TESTING OFF - SET_FOLDER_TARGETS ext yaml) - c4_import_remote_proj(yaml-cpp ${ed}/yaml-cpp REMOTE - GIT_REPOSITORY https://github.com/jbeder/yaml-cpp - # the master branch regularly screws up on windows builds. - # so use fixed pre-validated commit hashes - GIT_TAG 587b24e2eedea1afa21d79419008ca5f7bda3bf4 - OVERRIDE YAML_CPP_BUILD_TESTS OFF YAML_CPP_BUILD_TOOLS OFF YAML_CPP_BUILD_CONTRIB OFF YAML_CPP_BUILD_INSTALL OFF - SET_FOLDER_TARGETS ext yaml-cpp format) - set(ryml_yaml_cpp_inc ${ed}/yaml-cpp/src/include) - if(MSVC) - target_compile_definitions(yaml-cpp PUBLIC -D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING) - endif() -endif() - -c4_add_dev_targets() diff --git a/third_party/rapidyaml/rapidyaml/CONTRIBUTING.md b/third_party/rapidyaml/rapidyaml/CONTRIBUTING.md deleted file mode 100644 index b05cc3476..000000000 --- a/third_party/rapidyaml/rapidyaml/CONTRIBUTING.md +++ /dev/null @@ -1,21 +0,0 @@ -# Contributing - -Thanks for your contribution! - -* Make sure to clone the project with `git clone --recursive` so that - the submodules are initialized correctly. -* To enable both tests and benchmarks, configure ryml with `-DRYML_DEV=ON` - when calling cmake. To enable only tests, use `-DRYML_BUILD_TESTS=ON`; to - enable only benchmarks use `-DRYML_BUILD_BENCHMARKS=ON`. All these flags - are disabled by default. -* Submitted pull requests should target the `dev` branch. (The `master` - branch is the stable branch, and merges from `dev` to `master` are done - only if the tests succeed.) -* Code style for pull requests should respect the existing code style: - ```c++ - if(foo) // no space before parens - { // curly brackets on next line - // no tabs; indent with 4 spaces - bar(); - } - ``` diff --git a/third_party/rapidyaml/rapidyaml/LICENSE.txt b/third_party/rapidyaml/rapidyaml/LICENSE.txt deleted file mode 100644 index 47b6b4394..000000000 --- a/third_party/rapidyaml/rapidyaml/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2018, Joao Paulo Magalhaes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - diff --git a/third_party/rapidyaml/rapidyaml/README.md b/third_party/rapidyaml/rapidyaml/README.md deleted file mode 100644 index e30ccca95..000000000 --- a/third_party/rapidyaml/rapidyaml/README.md +++ /dev/null @@ -1,1259 +0,0 @@ -# Rapid YAML -[![MIT Licensed](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/biojppm/rapidyaml/blob/master/LICENSE.txt) -[![release](https://img.shields.io/github/v/release/biojppm/rapidyaml?color=g&include_prereleases&label=release%20&sort=semver)](https://github.com/biojppm/rapidyaml/releases) -[![API Docs](https://img.shields.io/badge/docs-docsforge-blue)](https://rapidyaml.docsforge.com/) -[![Gitter](https://badges.gitter.im/rapidyaml/community.svg)](https://gitter.im/rapidyaml/community) - -[![ci](https://github.com/biojppm/rapidyaml/workflows/ci/badge.svg?branch=master)](https://github.com/biojppm/rapidyaml/actions?query=workflow%3Aci) -[![Coverage: coveralls](https://coveralls.io/repos/github/biojppm/rapidyaml/badge.svg?branch=master)](https://coveralls.io/github/biojppm/rapidyaml) -[![Coverage: codecov](https://codecov.io/gh/biojppm/rapidyaml/branch/master/graph/badge.svg?branch=master)](https://codecov.io/gh/biojppm/rapidyaml) -[![Total alerts](https://img.shields.io/lgtm/alerts/g/biojppm/rapidyaml.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/biojppm/rapidyaml/alerts/) -[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/biojppm/rapidyaml.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/biojppm/rapidyaml/context:cpp) - - -Or ryml, for short. ryml is a library to parse and emit YAML, and do it fast. - -ryml parses both read-only and in-situ source buffers; the resulting data -nodes hold only views to sub-ranges of the source buffer. No string copies or -duplications are done, and no virtual functions are used. The data tree is a -flat index-based structure stored in a single array. Serialization happens -only at your direct request, after parsing / before emitting. Internally the -data tree representation has no knowledge of types (but of course, every node -can have a YAML type tag). It is easy and fast to read, write and iterate -through the data tree. - -ryml can use custom per-tree memory allocators, and is -exception-agnostic. Errors are reported via a custom error handler callback. -A default error handler implementation using `std::abort()` is provided, but -you can opt out, or provide your exception-throwing callback. - -ryml has respect for your compilation times and therefore it is NOT -header-only. It uses standard cmake build files, so it is easy to compile and -install. - -ryml has no dependencies, not even on the STL (although it does use the -libc). It provides optional headers that let you serialize/deserialize -STL strings and containers (or show you how to do it). - -ryml is written in C++11, and is known to compile with: -* Visual Studio 2015 and later -* clang++ 3.9 and later -* g++ 5 and later - -ryml is [extensively unit-tested in Linux, Windows and -MacOS](https://github.com/biojppm/rapidyaml/actions?query=workflow%3Arun_tests). The -tests include analysing ryml with: - * valgrind - * clang-tidy - * clang sanitizers: - * memory - * address - * undefined behavior - * thread - * [LGTM.com](https://lgtm.com/projects/g/biojppm/rapidyaml) - -ryml is also partially available in Python, with more languages to follow (see -below). - -See also [the changelog](./changelog) and [the roadmap](./ROADMAP.md). - - ------- - -## Table of contents - -* [Is it rapid?](#is-it-rapid) - * [Comparison with yaml-cpp](#comparison-with-yaml-cpp) - * [Performance reading JSON](#performance-reading-json) - * [Performance emitting](#performance-emitting) -* [Installing and using](#installing-and-using) - * [Using ryml as cmake subproject](#using-ryml-as-cmake-subproject) - * [The traditional way: using an installed version](#the-traditional-way-using-an-installed-version) - * [cmake build settings for ryml](#cmake-build-settings-for-ryml) -* [Quick start](#quick-start) - * [Parsing](#parsing) - * [References: anchors and aliases](#references-anchors-and-aliases) - * [Traversing the tree](#traversing-the-tree) - * [Creating a tree](#creating-a-tree) - * [Low-level API](#low-level-api) - * [Custom types](#custom-types) - * [Leaf types](#leaf-types) - * [Container types](#container-types) - * [STL interoperation](#stl-interoperation) - * [Custom formatting for intrinsic types](#custom-formatting-for-intrinsic-types) - * [Custom allocators and error handlers](#custom-allocators-and-error-handlers) - * [Using ryml to parse JSON, and preprocessing functions](#using-ryml-to-parse-json-and-preprocessing-functions) -* [Other languages](#other-languages) - * [Python](#python) -* [YAML standard conformance](#yaml-standard-conformance) -* [Known limitations](#known-limitations) -* [Alternative libraries](#alternative-libraries) -* [License](#license) - ------- - -## Is it rapid? - -You bet! - -(The results presented below are a bit scattered; and they need to be -sistematized.) On a i7-6800K CPU @3.40GHz: - * ryml parses YAML at about ~150MB/s on Linux and ~100MB/s on Windows (vs2017). - * **ryml parses JSON at about ~450MB/s on Linux**, faster than sajson (didn't - try yet on Windows). - * compared against the other existing YAML libraries for C/C++: - * ryml is in general between 2 and 3 times faster than [libyaml](https://github.com/yaml/libyaml) - * ryml is in general between 20 and 70 times faster than - [yaml-cpp](https://github.com/jbeder/yaml-cpp), and in some cases as - much as 100x and [even - 200x](https://github.com/biojppm/c4core/pull/16#issuecomment-700972614) faster. - -[Here's the benchmark](./bm/bm_parse.cpp). Using different -approaches within ryml (in-situ/read-only vs. with/without reuse), a YAML / -JSON buffer is repeatedly parsed, and compared against other libraries. - -### Comparison with yaml-cpp - -The first result set is for Windows, and is using a [appveyor.yml config -file](./bm/cases/appveyor.yml). A comparison of these results is -summarized on the table below: - -| Read rates (MB/s) | ryml | yamlcpp | compared | -|------------------------------|--------|---------|--------------| -| appveyor / vs2017 / Release | 101.5 | 5.3 | 20x / 5.2% | -| appveyor / vs2017 / Debug | 6.4 | 0.0844 | 76x / 1.3% | - - -The next set of results is taken in Linux, comparing g++ 8.2 and clang++ 7.0.1 in -parsing a YAML buffer from a [travis.yml config -file](./bm/cases/travis.yml) or a JSON buffer from a [compile_commands.json -file](./bm/cases/compile_commands.json). You -can [see the full results here](./bm/results/parse.linux.i7_6800K.md). -Summarizing: - -| Read rates (MB/s) | ryml | yamlcpp | compared | -|-----------------------------|--------|---------|------------| -| json / clang++ / Release | 453.5 | 15.1 | 30x / 3% | -| json / g++ / Release | 430.5 | 16.3 | 26x / 4% | -| json / clang++ / Debug | 61.9 | 1.63 | 38x / 3% | -| json / g++ / Debug | 72.6 | 1.53 | 47x / 2% | -| travis / clang++ / Release | 131.6 | 8.08 | 16x / 6% | -| travis / g++ / Release | 176.4 | 8.23 | 21x / 5% | -| travis / clang++ / Debug | 10.2 | 1.08 | 9x / 1% | -| travis / g++ / Debug | 12.5 | 1.01 | 12x / 8% | - -The 450MB/s read rate for JSON puts ryml squarely in the same ballpark -as [RapidJSON](https://github.com/Tencent/rapidjson) and other fast json -readers -([data from here](https://lemire.me/blog/2018/05/03/how-fast-can-you-parse-json/)). -Even parsing full YAML is at ~150MB/s, which is still in that performance -ballpark, albeit at its lower end. This is something to be proud of, as the -YAML specification is much more complex than JSON: [23449 vs 1969 words](https://www.arp242.net/yaml-config.html#its-pretty-complex). - - -### Performance reading JSON - -So how does ryml compare against other JSON readers? Well, it's one of the -fastest! - -The benchmark is the [same as above](./bm/parse.cpp), and it is reading -the [compile_commands.json](./bm/cases/compile_commands.json), The `_ro` -suffix notes parsing a read-only buffer (so buffer copies are performed), -while the `_rw` suffix means that the source buffer can be parsed in -situ. The `_reuse` means the data tree and/or parser are reused on each -benchmark repeat. - -Here's what we get with g++ 8.2: - -``` -|------------------|-------------------------------|------------------------------- -| | Release | Debug -| Benchmark | Iterations Bytes/sec | Iterations Bytes/sec -|------------------|-------------------------------|------------------------------- -| rapidjson_ro | 7941 509.855M/s | 633 43.3632M/s -| rapidjson_rw | 21400 1.32937G/s | 1067 68.171M/s -| sajson_rw | 6808 434.245M/s | 2770 176.478M/s -| sajson_ro | 6726 430.723M/s | 2748 175.613M/s -| jsoncpp_ro | 2871 183.616M/s | 2941 187.937M/s -| nlohmann_json_ro | 1807 115.801M/s | 337 21.5237M/s -| yamlcpp_ro | 261 16.6322M/s | 25 1.58178M/s -| libyaml_ro | 1786 113.909M/s | 560 35.6599M/s -| libyaml_ro_reuse | 1797 114.594M/s | 561 35.8531M/s -| ryml_ro | 6088 388.585M/s | 576 36.8634M/s -| ryml_rw | 6179 393.658M/s | 577 36.8474M/s -| ryml_ro_reuse | 6986 446.248M/s | 1164 74.636M/s -| ryml_rw_reuse | 7157 457.076M/s | 1175 74.8721M/s -|------------------|-------------------------------|------------------------------- -``` - -You can verify that (at least for this test) ryml beats most json parsers at -their own game, with the notable exception -of [rapidjson](https://github.com/Tencent/rapidjson) --- *but this occurs -only in Release mode*. When in Debug -mode, [rapidjson](https://github.com/Tencent/rapidjson) is actually slower -than ryml, and only [sajson](https://github.com/chadaustin/sajson) manages to -be faster. - -More json comparison benchmarks will be added, but seem unlikely to -significantly alter these results. - - -### Performance emitting - -Emitting benchmarks were not created yet, but feedback from some users -reports as much as 25x speedup from yaml-cpp [(eg, -here)](https://github.com/biojppm/rapidyaml/issues/28#issue-553855608). - -If you have data or YAML code for this, please submit a merge request, or -just send us the files! - - ------- - -## Installing and using - -First, clone the repo: -```bash -git clone --recursive https://github.com/biojppm/rapidyaml -``` -Take care to use the `--recursive` flag to force git to clone the -submodules as well. If you omit `--recursive`, after cloning you -will have to do `git submodule init` and ` submodule update` -to ensure the submodules are checked out. - -Next, you can either use ryml as a cmake subdirectory or build and install to -a directory of your choice. Currently [cmake](https://cmake.org/) is required -for using ryml; we recommend a recent cmake version, at least 3.13. - -### Using ryml as cmake subproject - -ryml is a small library, so this is the advised way. -```cmake -# somewhere in your CMakeLists.txt - -# this is the target you wish to link with ryml -add_library(foolib a.cpp b.cpp) - -# make ryml a subproject of your project -add_subdirectory(path/to/rapidyaml ryml) -target_link_libraries(foolib PUBLIC ryml) # that's it! - -add_executable(fooexe main.cpp) -target_link_libraries(fooexe foolib) # brings in ryml -``` -If you're using git, we also suggest you add ryml as git submodule of -your repo. This makes it easy to track any upstream changes in ryml. - -### The traditional way: using an installed version - -You can also use ryml in the customary cmake way, by first building and -installing it, and then consuming it in your project via `find_package()`. - -First, build ryml. For Visual Studio & multi-configuration CMake generators, -this would be: -```bash -cmake -S path/to/rapidyaml -B path/to/ryml/build/dir \ - -DCMAKE_INSTALL_PREFIX=path/to/ryml/install/dir -cmake --build path/to/ryml/build/dir --parallel --config Release -``` -whereas for single configuration CMake generators (Unix Makefiles, etc), this -would be: -```bash -cmake -S path/to/rapidyaml -B path/to/ryml/build/dir \ - -DCMAKE_INSTALL_PREFIX=path/to/ryml/install/dir \ - -DCMAKE_BUILD_TYPE=Release -cmake --build path/to/ryml/build/dir --parallel -``` -(Note the `-S` and `-B` options first appeared in cmake 3.13 and are not -available in earlier cmake versions). Now you can install ryml: -```bash -cmake --build path/to/ryml/build/dir --target install -``` - -This will get ryml installed into the directory -`path/to/ryml/install/dir`, together with cmake export files for ryml, -which `find_package()` will need to successfully import ryml to your project. - -Now to consume this installed ryml version, do the following: -```cmake -# somewhere in your CMakeLists.txt - -# this is the target you wish to link with ryml -add_library(foolib a.cpp b.cpp) - -# instruct cmake to search for ryml -find_package(ryml REQUIRED) -target_link_libraries(foolib PUBLIC ryml::ryml) # NOTE namespace ryml:: - -add_executable(fooexe main.cpp) -target_link_libraries(fooexe foolib) # brings in ryml -``` -Note a significant difference to the subdirectory approach from the previous -section: the installed ryml cmake exports file places the ryml library target in the -`ryml::` namespace. - -Now when building your project, you will need to point cmake to the installed ryml. -To do this, simply add the ryml install directory to your project's `CMAKE_PREFIX_PATH` by doing eg -`-DCMAKE_PREFIX_PATH=path/to/ryml/install/dir` when configuring your project, -or by setting this variable in the cmake GUI if that's what you prefer to use. - -You can also set (via command line or GUI) the variable `ryml_DIR` to the -directory where the exports file `rymlConfig.cmake` was installed (which is -different across platforms); search for this file in the ryml install tree, -and provide the directory where it is located. For example, in Windows with -the example above, this would be `-Dryml_DIR=path/to/ryml/install/dir/cmake`. - - -### cmake build settings for ryml -The following cmake variables can be used to control the build behavior of -ryml: - - * `RYML_DEFAULT_CALLBACKS=ON/OFF`. Enable/disable ryml's default - implementation of error and allocation callbacks. Defaults to `ON`. - * `RYML_STANDALONE=ON/OFF`. ryml uses - [c4core](https://github.com/biojppm/c4core), a C++ library with low-level - multi-platform utilities for C++. When `RYML_STANDALONE=ON`, c4core is - incorporated into ryml as if it is the same library. Defaults to `ON`. - -If you're developing ryml or just debugging problems with ryml itself, the -following variables can be helpful: - * `RYML_DEV=ON/OFF`: a bool variable which enables development targets such as - unit tests, benchmarks, etc. Defaults to `OFF`. - * `RYML_DBG=ON/OFF`: a bool variable which enables verbose prints from - parsing code; can be useful to figure out parsing problems. Defaults to - `OFF`. - - ------- - -## Quick start - -If you're wondering whether ryml's speed comes at a usage cost, you need -not. With ryml, you can have your cake and eat it too: being rapid is -definitely NOT the same as being unpractical! ryml was written with easy AND -efficient usage in mind, and comes with a two level API for accessing and -traversing the data tree. - -The low-level interface is an index-based API available through -the [`ryml::Tree`](src/c4/yml/tree.hpp) class (see examples below). This -class is essentially a contiguous array of `NodeData` elements; these are -linked to parent, children and siblings via indices. - -On top of this index-based API, there is a thin -abstraction [`ryml::NodeRef`](src/c4/yml/node.hpp) which is essentially a -non-owning pointer to a `NodeData` element. It provides convenient methods -for accessing the `NodeData` properties wrapping it via a class allowing for -a more object-oriented use. - - -### Parsing - -A parser takes a source buffer and fills -a [`ryml::Tree`](src/c4/yml/tree.hpp) object: - -```c++ -#include - -// not needed by ryml, just for these examples (and below) -#include -// convenience functions to print a node -void show_keyval(ryml::NodeRef n) -{ - assert(n.has_keyval()); - std::cout << n.key() << ": " << n.val() << "\n"; -} -void show_val(ryml::NodeRef n) -{ - assert(n.has_val()); - std::cout << n.val() << "\n"; -} - -int main() -{ - // ryml can parse in situ (and read-only buffers too): - char src[] = "{foo: 1, bar: [2, 3]}"; - ryml::substr srcview = src_; // a mutable view to the source buffer - // there are also overloads for reusing the tree and parser - ryml::Tree tree = ryml::parse(srcview); - - // get a reference to the "foo" node - ryml::NodeRef node = tree["foo"]; - - show_keyval(node); // "foo: 1" - show_val(node["bar"][0]); // "2" - show_val(node["bar"][1]); // "3" - - // deserializing: - int foo; - node >> foo; // now foo == 1 -} -``` - -It is also possible to parse read-only buffers, but note these will be copied -over to an arena buffer in the tree object, and that buffer copy will be the -one to be parsed: - -```c++ -// "{foo: 1}" is a const char[], so a read-only buffer; it will be -// copied to the tree's arena before parsing -ryml::Tree tree = ryml::parse("{foo: 1}"); -``` - -When parsing, you can reuse the existing trees and parsers. You can also -parse into particular tree nodes, so that you can parse an entire file into a -node which is deep in the hierarchy of an existing tree. To see the various -parse overloads, consult the [c4/yml/parse.hpp header](src/c4/yml/parse.hpp). -The free-standing `parse()` functions (towards the end of the file) are just -convenience wrappers for calling the several `Parser::parse()` overloads. - - -### References: anchors and aliases - -Note that dereferencing is opt-in; after parsing, you have to call -`Tree::resolve()` explicitly if you want resolved references in the -tree. This method will resolve all references and substitute the anchored -values in place of the reference. - -The `Tree::resolve()` method first does a full traversal of the tree to -gather all anchors and references in a separate collection, then it goes -through that collection to locate the names, which it does by obeying the -YAML standard diktat that - - an alias node refers to the most recent node in the serialization having the specified anchor - -So, depending on the number of anchor/alias nodes, this is a potentially -expensive operation, with a best-case linear complexity (from the initial -traversal) and a worst-case quadratic complexity (if every node has an -alias/anchor). This potential cost is the reason for requiring an explicit -call to `Tree::resolve()`. - - -### Traversing the tree - -The data tree is an index-linked array of `NodeData` elements. These are -defined roughly as (browse the [c4/yml/tree.hpp header](src/c4/yml/tree.hpp)): - -```c++ -// (inside namespace c4::yml) - -typedef enum : int // bitflags for marking node features -{ - KEY=1<<0, - VAL=1<<1, - MAP=1<<2, - SEQ=1<<4, - DOC=1<<5, - TAG=..., - REF=..., - ANCHOR=..., // etc -} NodeType_e; -struct NodeType -{ - NodeType_e m_flags; - // ... predicate methods such as - // has_key(), is_map(), is_seq(), etc -}; -struct NodeScalar // this is both for keys and vals -{ - csubstr tag; - csubstr scalar; - csubstr anchor; - // csubstr is a constant substring: - // a non-owning read-only string view - // consisting of a pointer and a length -} -constexpr const size_t NONE = (size_t)-1; -struct NodeData -{ - NodeType type; - NodeScalar key; // data for the key (if applicable) - NodeScalar val; // data for the value - - size_t parent; // NONE when this is the root node - size_t first_child; // NONE if this is a leaf node - size_t last_child; // etc - size_t next_sibling; - size_t prev_sibling; -} -``` - -Please note that you should not rely on this particular structure; the above -definitions are given only to provide an idea on how the tree is organized. -To access and modify node properties, please use the APIs provided through -the `Tree` (low-level) or the `NodeRef` (high-level) classes. - -You may have noticed above the use of a `csubstr` class. This class is -defined in another library, [c4core](https://github.com/biojppm/c4core), -which is imported by ryml (so technically it's not a dependency, is -it?). This is a library I use with my projects consisting of multiplatform -low-level utilities. One of these is `c4::csubstr` (the name comes from -"constant substring") which is a non-owning read-only string view, with many -methods that make it practical to use (I would certainly argue more practical -than `std::string`). In fact, `c4::csubstr` and its writeable counterpart -`c4::substr` are the workhorses of the ryml parsing and serialization code; -you can browse these classes here: -[c4/substr.hpp](https://github.com/biojppm/c4core/blob/master/src/c4/substr.hpp). - -Now, let's parse and traverse a tree. To obtain a `NodeRef` from the tree, -you only need to invoke `operator[]`. This operator can take indices (when -invoked on sequence and map nodes) and also strings (only when invoked on map -nodes): - -```c++ -ryml::Tree tree = ryml::parse("[a, b, {c: 0, d: 1}]"); - -// note: show_val() was defined above - -show_val(tree[0]); // "a" -show_val(tree[1]); // "b" -show_val(tree[2][ 0 ]); // "0" // index-based -show_val(tree[2][ 1 ]); // "1" // index-based -show_val(tree[2]["c"]); // "0" // string-based -show_val(tree[2]["d"]); // "1" // string-based - -// note that trying to obtain the value on a non-value -// node such as a container will fail an assert: -// ERROR, assertion triggered: a container has no value -show_val(tree[2]); -// ERROR: the same -show_val(tree.rootref()); - -// the same for keys: -show_keyval(tree[0]); // ERROR: sequence element has no key -show_keyval(tree[2][0]); // ok -``` -The square bracket operators `Tree::operator[csubstr]` and -`Tree::operator[size_t]` do a lookup on the root node and return a -`NodeRef`. The first overload (valid only for map nodes) looks for a child having the given key, and the -second overload looks for the i-th root's child. If you prefer to stick to -the low level API, you can use `Tree::find_child()` which takes a node on -which the child should be looked for and also that child's key or position -within the parent. - -Please note that since a ryml tree uses indexed linked lists for storing -children, the complexity of `Tree::operator[csubstr]` and -`Tree::operator[size_t]` is linear on the number of root children. If you use -it with a large tree where the root has many children, you may get a -performance hit. To avoid this hit, you can create your own accelerator -structure. For example, before doing a lookup, do a single traverse at the -root level to fill an `std::map` mapping key names to node -indices; with a node index, a lookup (via `Tree::get()`) is O(1), so this way -you can get O(log n) lookup from a key. - -As for `NodeRef`, the difference from `NodeRef::operator[]` -to `Tree::operator[]` is that the latter refers to the root node, whereas -the former can be invoked on any node. But the lookup process is the same for -both and their algorithmic complexity is the same: they are both linear in -the number of direct children; but depending on the data, that number may -be very different from one to another. - -Now, let's address how to mutate the tree via `operator[]`. We should stress -that there is an important difference to the mutability behavior of the STL's -`std::map::operator[]`. Consider when a non-existing key or index is -requested via `operator[]`. Unlike with `std::map`, **this operator does not -modify the tree**. Instead you get a seed-state `NodeRef`, and the tree will -be modified only when this seed-state reference is written to. Thus `NodeRef` -can either point to a valid tree node, or if no such node exists it will be -in seed-state by holding the index or name passed to `operator[]`. To allow -for this, `NodeRef` is a simple structure with a declaration like: - -```c++ -class NodeRef -{ - // a pointer to the tree - Tree * m_tree; - // either the (tree-scoped) index of an existing node or the (node-scoped) index of a seed state - size_t m_node_or_seed_id; - // the key name of a seed state. null when valid - const char* m_seed_name; - -public: - - // this can be used to query whether a node is in seed state - bool valid() - { - return m_node_or_seed_id != NONE - && - m_seed_name == nullptr; - } - - // forward all calls to m_tree. For example: - csubstr val() const { assert(valid()); return m_tree->val(m_node_or_seed_id); } - void set_val(csubstr v) { if(!valid()) {/*create node in tree*/;} m_tree->set_val(m_node_or_seed_id, v); } - - // etc... -}; -``` - -To iterate over children: -```c++ -for(NodeRef c : node.children()) -{ - std::cout << c.key() << "---" << c.val() << "\n"; -} -``` - -To iterate over siblings: -```c++ -for(NodeRef c : node.siblings()) -{ - std::cout << c.key() << "---" << c.val() << "\n"; -} -``` - - -### Creating a tree - -To create a tree programatically: -```c++ -ryml::Tree tree; -NodeRef r = tree.rootref(); - -// Each container node must be explicitly set (either MAP or SEQ): -r |= ryml::MAP; - -r["foo"] = "1"; // ryml works only with strings. -// Note that the tree will be __pointing__ at the -// strings "foo" and "1" used here. You need -// to make sure they have at least the same -// lifetime as the tree. - -// does not change the tree until s is written to. -ryml::NodeRef s = r["seq"]; // here, s is not valid() -s |= ryml::SEQ; // now s is valid() - -s.append_child() = "bar0"; // this child is now __pointing__ at "bar0" -s.append_child() = "bar1"; -s.append_child() = "bar2"; - -// emit to stdout (can also emit to FILE* or ryml::span) -emit(tree); // prints the following: - // foo: 1 - // seq: - // - bar0 - // - bar1 - // - bar2 - -// serializing: using operator<< instead of operator= -// will make the tree serialize the value into a char -// arena inside the tree. This arena can be reserved at will. -int ch3 = 33, ch4 = 44; -s.append_child() << ch3; -s.append_child() << ch4; - -{ - std::string tmp = "child5"; - s.append_child() << tmp; // requires #include - // now tmp can go safely out of scope, as it was - // serialized to the tree's internal string arena - // Note the include highlighted above is required so that ryml - // knows how to turn an std::string into a c4::csubstr/c4::substr. -} - -emit(tree); // now prints the following: - // foo: 1 - // seq: - // - bar0 - // - bar1 - // - bar2 - // - 33 - // - 44 - // - child5 - -// to serialize keys: -r.append_child() << ryml::key(66) << 7; - -emit(tree); // now prints the following: - // foo: 1 - // seq: - // - bar0 - // - bar1 - // - bar2 - // - 33 - // - 44 - // - child5 - // 66: 7 -} -``` - - - - -### Low-level API - -The low-level api is an index-based API accessible from -the [`ryml::Tree`](src/c4/yml/tree.hpp) object. Here are some examples: - -```c++ -void print_keyval(Tree const& t, size_t elm_id) -{ - std::cout << t.get_key(elm_id) - << ": " - << t.get_val(elm_id) << "\n"; -} - -ryml::Tree t = parse("{foo: 1, bar: 2, baz: 3}") - -size_t root_id = t.root_id(); -size_t foo_id = t.first_child(root_id); -size_t bar_id = t.next_sibling(foo_id); -size_t baz_id = t.last_child(root_id); - -assert(baz == t.next_sibling(bar_id)); -assert(bar == t.prev_sibling(baz_id)); - -print_keyval(t, foo_id); // "foo: 1" -print_keyval(t, bar_id); // "bar: 2" -print_keyval(t, baz_id); // "baz: 3" - -// to iterate over the children of a node: -for(size_t i = t.first_child(root_id); - i != ryml::NONE; - i = t.next_sibling(i)) -{ - // ... -} - -// to iterate over the siblings of a node: -for(size_t i = t.first_sibling(foo_id); - i != ryml::NONE; - i = t.next_sibling(i)) -{ - // ... -} -``` - - -### Custom types - -ryml provides code to serialize the basic intrinsic types (integers, floating -points and strings): you can see it in the [the `c4/charconv.hpp` -header](https://github.com/biojppm/c4core/blob/master/src/c4/charconv.hpp). For -types other than these, you need to instruct ryml how to serialize your -type, and here we explain how to do this. - -There are two distinct type categories when serializing to a YAML tree: -leaf types (value or key-value) and container types (sequences or maps). - - -#### Leaf types - -These are types which should serialize to a string, resulting in a leaf node -in the YAML tree. - -For these, overload the `to_chars(c4::substr, T)/from_chars(c4::csubstr, *T)` -functions. - -Here's an example for a 3D vector type: -```c++ -struct vec3 { float x, y, z; }; - -// format v to the given string view + return the number of -// characters written into it. The view size (buf.len) must -// be strictly respected. Return the number of characters -// that need to be written. So if the return value -// is larger than buf.len, ryml will resize the buffer and -// call this again with a larger buffer of the correct sizeXS. -size_t to_chars(c4::substr buf, vec3 v) -{ - // this call to c4::format() is the type-safe equivalent - // of snprintf(buf.str, buf.len, "(%f,%f,%f)", v.x, v.y, v.z) - return c4::format(buf, "({},{},{})", v.x, v.y, v.z); -} - -bool from_chars(c4::csubstr buf, vec3 *v) -{ - // equivalent to sscanf(buf.str, "(%f,%f,%f)", &v->x, &v->y, &v->z) - // --- actually snscanf(buf.str, buf.len, ...) but there's - // no such function in the standard. - size_t ret = c4::unformat(buf, "({},{},{})", v->x, v->y, v->z); - return ret != c4::csubstr::npos; -} -``` -Now you can provide your formats with -For a live example you can look at [the `std::string` serialization code](https://github.com/biojppm/c4core/blob/master/src/c4/std/string.hpp). - - -#### Container types - -These are types requiring child nodes (ie, either sequences or maps). - -For these, overload the `write()/read()` functions. For example, -```c++ -namespace foo { -struct MyStruct; // a container-type struct -{ - int subject; - std::map counts; -}; - -// ... will need these functions to convert to YAML: -void write(c4::yml::NodeRef *n, MyStruct const& v); -void read(c4::yml::NodeRef const& n, MyStruct *v); -} // namespace foo -``` -which could be implemented as: -```c++ -// include the functions for std::string and std::map (not included by default) -#include -#include - -void foo::read(c4::yml::NodeRef const& n, MyStruct *v) -{ - n["subject"] >> v->subject; - n["counts"] >> v->counts; -} - -void foo::write(c4::yml::NodeRef *n, MyStruct const& v) -{ - *n |= c4::yml::MAP; - - NodeRef ch = n->append_child(); - ch.set_key("subject"); - ch.set_val_serialized(v.subject); - - ch = n->append_child(); - ch.set_key("counts"); - write(&ch, v.counts); -} -``` -To harness [C++'s ADL rules](http://en.cppreference.com/w/cpp/language/adl), -it is important to overload these functions in the namespace of the type -you're serializing (or in the c4::yml namespace). Generic -examples can be seen in the (optional) implementations of `std::vector` -or `std::map`, at their respective headers -[`c4/yml/std/vector.hpp`](src/c4/yml/std/vector.hpp) and -[`c4/yml/std/map.hpp`](src/c4/yml/std/map.hpp). - - - -### STL interoperation - -ryml does not use the STL internally, but you can use ryml to serialize and -deserialize STL containers. That is, the use of STL is opt-in: you need to -`#include` the proper ryml header for the container you want to serialize, or -provide an implementation of your own, as above. Having done that, you can -serialize / deserialize your containers with a single step. For example: - -```c++ -#include // include this before any other ryml header -#include -int main() -{ - std::map m({{"foo", 1}, {"bar", 2}}); - ryml::Tree t; - t.rootref() << m; // serialization of the map happens here - - emit(t); - // foo: 1 - // bar: 2 - - t["foo"] << 1111; // serialize an integer into - // the tree's arena, and make - // foo's value point at it - t["bar"] << 2222; // the same, but for bar - - emit(t); - // foo: 1111 - // bar: 2222 - - m.clear(); - t.rootref() >> m; // deserialization of the map happens here - - assert(m["foo"] == 1111); // ok - assert(m["bar"] == 2222); // ok -} -``` -The [``](src/ryml_std.hpp) header includes every std type -implementation available in ryml. But you can include just a specific header -if you are interested only in a particular container; these headers are -located under a specific directory in the ryml source -folder: [c4/yml/std](src/c4/yml/std). You can browse them to learn how to -implement your custom type: for containers, see for example -[the `std::vector` implementation](src/c4/yml/std/vector.hpp), -or [the `std::map` implementation](src/c4/yml/std/map.hpp); for an example -of value nodes, see -[the `std::string` implementation](https://github.com/biojppm/c4core/src/c4/std/string.hpp). -If you'd like to see a particular STL container implemented, feel free to -[submit a pull request or open an issue](https://github.com/biojppm/rapidyaml/issues). - -The need for separate inclusion of ryml's std interoperation headers is dictated -by ryml's design requirement of not forcing clients to use the STL. - -Please take note of the following pitfall when using the std headers: you have to include -the std header before any other headers that use functions from it. For example: -```c++ -// the to_csubstr(std::string const&) overload is not found in the resolution set -#include -#include -int main() -{ - std::string in = R"({"a":"b","c":null,"d":"e"})"; - // COMPILE ERROR: to_csubstr() not found for std::string - std::string yaml = ryml::preprocess_json(c4::to_csubstr(in)); -} -``` -But this works: -```c++ -#include // note the inclusion order changed -#include -int main() -{ - std::string in = R"({"a":"b","c":null,"d":"e"})"; - // OK: - std::string yaml = ryml::preprocess_json(c4::to_csubstr(in)); -} -``` -This constraint also applies to the conversion functions for your types; -just like with the STL's headers, they should be included prior to -ryml's headers. - - -### Custom formatting for intrinsic types - -Sometimes the general formatting from ryml may not be what is required. - -Consider the following: -```c++ -NodeRef r = tree.rootref(); - -bool t = true; -float a = 24.0f; -float b = 2.41f; - -r["t"] << t; -r["a"] << a; -r["b"] << b; -print_keyval(r["t"]); // "t=1" -- true was formatted as an int -print_keyval(r["a"]); // "a=24" -- the decimal was lost with general formatting -print_keyval(r["b"]); // "b=2.41" -- as expected -``` -The behavior above may not be ideal in some cases. There are alternatives for -this situation: -```c++ -// if you want the decimal to remain, you can provide the string yourself: -r["t"] << (t ? "true" : "false"); -std::string sa = ...; // something resulting in "24.0" -r["a"] << c4::to_csubstr(sa); - -print_keyval(r["t"]); // "t=true" -- as expected -print_keyval(r["a"]); // "a=24.0" -- as expected -print_keyval(r["b"]); // "b=2.41" -- as expected -``` -If, understandably, you want to avoid the likely allocation caused -by the `std::to_string()` antipattern (or even worse, the `std::stringstream::str()` -allocation cookie monster), [ryml has you covered](https://github.com/biojppm/c4core/tree/master/src/c4/format.hpp): -```c++ -#include // look for the appropriate formatting functions in this header -//... - -int precision = 2; // print floats with two digits. -r["a"] << c4::fmt::real(val, precision); // OK, result: "24.00" - -// c4::fmt::real() is a lazy marker which will be used by ryml to format the -// float directly in the arena without any extra allocation (other than -// possible arena growth, which would happen just the same for the approach -// above). It calls ftoa() on the arena range. -``` -Again, note that you don't have to use the tree's arena. If you use -`operator=`, the `csubstr` you provide will be directly used instead. - - -### Custom allocators and error handlers - -ryml accepts your own allocators and error handlers. Read through [this -header file](src/c4/yml/common.hpp) to set it up. - -Please note the following about the use of custom allocators with ryml. If -you use static ryml trees or parsers, you need to make sure that their -allocator has the same lifetime. So you can't use ryml's default allocator, -as it is declared in a ryml file, and the standard provides no guarantee on -the relative initialization order, such that the allocator is constructed -before and destroyed after your variables (in fact you are pretty much -guaranteed to see this fail). So please carefully consider your choices, and -ponder whether you really need to use ryml static trees and parsers. If you -do need this, then you will need to declare and use an allocator from a ryml -memory resource that outlives the tree and/or parser. - - -### Using ryml to parse JSON, and preprocessing functions - -Although JSON is generally a subset of YAML, [there is an exception that is -valid JSON, but not valid YAML](https://stackoverflow.com/questions/42124227/why-does-the-yaml-spec-mandate-a-space-after-the-colon): -```yaml -{"a":"b"} # note the missing space after the semicolon -``` -As a result, you will get a parse error if you try to do this: -```c++ -auto tree = ryml::parse("{\"a\":\"b\"}"); -``` -This behavior is intended, and this was chosen to save added complexity in -the parser code. - -However, you can still parse this with ryml if (prior to parsing) you -preprocess the JSON into valid YAML, adding the missing spaces after the -semicolons. ryml provides a freestanding function to do this: -`ryml::preprocess_json()`: - -```c++ -#include -// you can also use in-place overloads -auto yaml = ryml::preprocess_json("{\"a\":\"b\"}"); -// now you have a buffer with valid yaml - note the space: -std::cout << yaml << "\n"; // {"a": "b"} -// ... which you can parse: -ryml::Tree t = ryml::parse(to_substr(yaml)); -std::cout << t["a"] << "\n"; // b -``` - -There is also `ryml::preprocess_rxmap()`, a function to convert non-standard -relaxed maps (ie, keys with implicit true values) into standard YAML maps. - -```c++ -#include -// you can also use in-place overloads -auto yaml = ryml::preprocess_rxmap("{a, b, c, d: [e, f, g]}"); -std::cout << yaml << "\n"; // {a: 1, b: 1, c: 1, d: [e, f, g]} -ryml::Tree t = ryml::parse(to_substr(yaml)); -std::cout << t["a"] << "\n"; // 1 -``` - - ------- - -## Other languages - -One of the aims of ryml is to provide an efficient YAML API for other -languages. There's already a cursory implementation for Python (using only -the low-level API). After ironing out the general approach, other languages -are likely to follow: probably (in order) JavaScript, C#, Java, Ruby, PHP, -Octave and R (all of this is possible because we're -using [SWIG](http://www.swig.org/), which makes it easy to do so). - -### Python - -(Note that this is a work in progress. Additions will be made and things will -be changed.) With that said, here's an example of the Python API: - -```python -import ryml - -# because ryml does not take ownership of the source buffer -# ryml cannot accept strings; only bytes or bytearrays -src = b"{HELLO: a, foo: b, bar: c, baz: d, seq: [0, 1, 2, 3]}" - -def check(tree): - # for now, only the index-based low-level API is implemented - assert tree.size() == 10 - assert tree.root_id() == 0 - assert tree.first_child(0) == 1 - assert tree.next_sibling(1) == 2 - assert tree.first_sibling(5) == 2 - assert tree.last_sibling(1) == 5 - # use bytes objects for queries - assert tree.find_child(0, b"foo") == 1 - assert tree.key(1) == b"foo") - assert tree.val(1) == b"b") - assert tree.find_child(0, b"seq") == 5 - assert tree.is_seq(5) - # to loop over children: - for i, ch in enumerate(ryml.children(tree, 5)): - assert tree.val(ch) == [b"0", b"1", b"2", b"3"][i] - # to loop over siblings: - for i, sib in enumerate(ryml.siblings(tree, 5)): - assert tree.key(sib) == [b"HELLO", b"foo", b"bar", b"baz", b"seq"][i] - # to walk over all elements - visited = [False] * tree.size() - for n, indentation_level in ryml.walk(tree): - # just a dumb emitter - left = " " * indentation_level - if tree.is_keyval(n): - print("{}{}: {}".format(left, tree.key(n), tree.val(n)) - elif tree.is_val(n): - print("- {}".format(left, tree.val(n)) - elif tree.is_keyseq(n): - print("{}{}:".format(left, tree.key(n)) - visited[inode] = True - assert False not in visited - # NOTE about encoding! - k = tree.get_key(5) - print(k) # '' - assert k == b"seq" # ok, as expected - assert k != "seq" # not ok - NOTE THIS! - assert str(k) != "seq" # not ok - assert str(k, "utf8") == "seq" # ok again - -# parse immutable buffer -tree = ryml.parse(src) -check(tree) # OK - -# also works, but requires bytearrays or -# objects offering writeable memory -mutable = bytearray(src) -tree = ryml.parse_in_situ(mutable) -check(tree) # OK -``` - -As expected, the performance results so far are encouraging. In -a [timeit benchmark](api/python/parse_bm.py) compared -against [PyYaml](https://pyyaml.org/) -and [ruamel.yaml](https://yaml.readthedocs.io/en/latest/), ryml parses -quicker by a factor of 30x-50x: - -``` -+-----------------------+-------+----------+---------+----------------+ -| case | iters | time(ms) | avg(ms) | avg_read(MB/s) | -+-----------------------+-------+----------+---------+----------------+ -| parse:RuamelYaml | 88 | 800.483 | 9.096 | 0.234 | -| parse:PyYaml | 88 | 541.370 | 6.152 | 0.346 | -| parse:RymlRo | 3888 | 776.020 | 0.200 | 10.667 | -| parse:RymlRoReuse | 1888 | 381.558 | 0.202 | 10.535 | -| parse:RymlRw | 3888 | 775.121 | 0.199 | 10.679 | -| parse:RymlRwReuse | 3888 | 774.534 | 0.199 | 10.687 | -+-----------------------+-------+----------+---------+----------------+ -``` - -(Note that the results above are somewhat biased towards ryml, because it does -not perform any type conversions: return types are merely `memoryviews` to -the source buffer.) - - ------- - -## YAML standard conformance - -ryml is under active development, but is close to feature complete. The -following YAML core features are well covered in the unit tests: -* mappings -* sequences -* complex keys -* literal blocks -* quoted scalars -* tags -* anchors and references -* UTF8 is expected to mostly work - -Of course, there are many dark corners in YAML, and there certainly can -appear cases which ryml fails to parse. Your [bug reports or pull -requests!](https://github.com/biojppm/rapidyaml/issues) are very welcome. - -See also [the roadmap](./ROADMAP.md) for a list of future work. - - -### Test suite status - -Integration of the >300 cases in the [YAML test -suite](https://github.com/yaml/yaml-test-suite) is ongoing work. Each of -these tests have several subparts: - * in-yaml: mildly, plainly or extremely difficult-to-parse yaml - * in-json: equivalent json (where possible/meaningful) - * out-yaml: equivalent standard yaml - * events: equivalent libyaml events allowing to establish correctness of - the parsed results - -When testing, ryml tries to parse each of the 3 yaml/json parts. If the -parsing suceeds, then the ryml test will emit the parsed tree, then parse the -emitted result and verify that emission is idempotent, ie that the emitted -result is the same as its input without any loss of information. To ensure -correctness, this happens over four levels of parse/emission pairs, resulting -on ~200 checks per test case. - -Please note that in [their own words](http://matrix.yaml.io/), the tests from -the YAML test suite *contain a lot of edge cases that don't play such an -important role in real world examples*. Despite the extreme focus of the test -suite, as of May 2020, ryml only fails to parse ~30 out of the ~1000=~3x300 -cases from the test suite. Out of all other cases, all the ~200 checks per -case are 100% successful for consistency over parse/emit pairs --- but please -note that the events part is not yet read in and used to check for -correctness, and therefore that **even though ryml may suceed in parsing, -there still exists a minority of cases which may not be correct**. Currently, -I would estimate this fraction at somewhere around 5%. These are the suite -cases where ryml fails to parse any of its subparts: -[EXG3](https://github.com/yaml/yaml-test-suite/tree/master/test/EXG3.tml), -[M7A3](https://github.com/yaml/yaml-test-suite/tree/master/test/M7A3.tml), -[735Y](https://github.com/yaml/yaml-test-suite/tree/master/test/735Y.tml), -[82AN](https://github.com/yaml/yaml-test-suite/tree/master/test/82AN.tml), -[9YRD](https://github.com/yaml/yaml-test-suite/tree/master/test/9YRD.tml), -[EX5H](https://github.com/yaml/yaml-test-suite/tree/master/test/EX5H.tml), -[HS5T](https://github.com/yaml/yaml-test-suite/tree/master/test/HS5T.tml), -[7T8X](https://github.com/yaml/yaml-test-suite/tree/master/test/7T8X.tml), -[RZP5](https://github.com/yaml/yaml-test-suite/tree/master/test/RZP5.tml), -[FH7J](https://github.com/yaml/yaml-test-suite/tree/master/test/FH7J.tml), -[PW8X](https://github.com/yaml/yaml-test-suite/tree/master/test/PW8X.tml), -[CN3R](https://github.com/yaml/yaml-test-suite/tree/master/test/CN3R.tml), -[6BCT](https://github.com/yaml/yaml-test-suite/tree/master/test/6BCT.tml), -[G5U8](https://github.com/yaml/yaml-test-suite/tree/master/test/G5U8.tml), -[K858](https://github.com/yaml/yaml-test-suite/tree/master/test/K858.tml), -[NAT4](https://github.com/yaml/yaml-test-suite/tree/master/test/NAT4.tml), -[9MMW](https://github.com/yaml/yaml-test-suite/tree/master/test/9MMW.tml), -[DC7X](https://github.com/yaml/yaml-test-suite/tree/master/test/DC7X.tml), -[L94M](https://github.com/yaml/yaml-test-suite/tree/master/test/L94M.tml), - -Except for the known limitations listed next, all other suite cases are -expected to work. - - ---------- - -## Known limitations - -ryml makes no effort to follow the standard in the following situations: - -* `%YAML` directives have no effect and are ignored. -* `%TAG` directives have no effect and are ignored. All schemas are assumed - to be the default YAML 2002 schema. -* container elements are not accepted as mapping keys. keys must be - simple strings and cannot themselves be mappings or sequences. But mapping - values can be any of the above. [YAML test - suite](https://github.com/yaml/yaml-test-suite) cases: - [4FJ6](https://github.com/yaml/yaml-test-suite/tree/master/test/4FJ6.tml), - [6BFJ](https://github.com/yaml/yaml-test-suite/tree/master/test/6BFJ.tml), - [6PBE](https://github.com/yaml/yaml-test-suite/tree/master/test/6PBE.tml), - [6PBE](https://github.com/yaml/yaml-test-suite/tree/master/test/6PBE.tml), - [KK5P](https://github.com/yaml/yaml-test-suite/tree/master/test/KK5P.tml), - [KZN9](https://github.com/yaml/yaml-test-suite/tree/master/test/KZN9.tml), - [LX3P](https://github.com/yaml/yaml-test-suite/tree/master/test/LX3P.tml), - [M5DY](https://github.com/yaml/yaml-test-suite/tree/master/test/M5DY.tml), - [Q9WF](https://github.com/yaml/yaml-test-suite/tree/master/test/Q9WF.tml), - [SBG9](https://github.com/yaml/yaml-test-suite/tree/master/test/SBG9.tml), - [X38W](https://github.com/yaml/yaml-test-suite/tree/master/test/X38W.tml), - [XW4D](https://github.com/yaml/yaml-test-suite/tree/master/test/XW4D.tml). - - ------- - -## Alternative libraries - -Why this library? Because none of the existing libraries was quite what I -wanted. There are two C/C++ libraries that I know of: - -* [libyaml](https://github.com/yaml/libyaml) -* [yaml-cpp](https://github.com/jbeder/yaml-cpp) - -The standard [libyaml](https://github.com/yaml/libyaml) is a bare C -library. It does not create a representation of the data tree, so it can't -qualify as practical. My initial idea was to wrap parsing and emitting around -libyaml, but to my surprise I found out it makes heavy use of allocations and -string duplications when parsing. I briefly pondered on sending PRs to reduce -these allocation needs, but not having a permanent tree to store the parsed -data was too much of a downside. - -[yaml-cpp](https://github.com/jbeder/yaml-cpp) is full of functionality, but -is heavy on the use of node-pointer-based structures like `std::map`, -allocations, string copies and slow C++ stream serializations. This is -generally a sure way of making your code slower, and strong evidence of this -can be seen in the benchmark results above. - -When performance and low latency are important, using contiguous structures -for better cache behavior and to prevent the library from trampling over the -client's caches, parsing in place and using non-owning strings is of central -importance. Hence this Rapid YAML library which, with minimal compromise, -bridges the gap from efficiency to usability. This library takes inspiration -from [RapidJSON](https://github.com/Tencent/rapidjson) -and [RapidXML](http://rapidxml.sourceforge.net/). - - ------- -## License - -ryml is permissively licensed under the [MIT license](LICENSE.txt). diff --git a/third_party/rapidyaml/rapidyaml/ROADMAP.md b/third_party/rapidyaml/rapidyaml/ROADMAP.md deleted file mode 100644 index 4d5bf8022..000000000 --- a/third_party/rapidyaml/rapidyaml/ROADMAP.md +++ /dev/null @@ -1,33 +0,0 @@ -# Roadmap - -Roughly in order of priority: - - * Conformance of the parser to the YAML standard: - * Increase success rate of YAML test suite parsing (as of May 2020, - ~30/1300 tests are failing) - * Cross-check the suite test correctness with the events specified in - each test. (Currently the tests are only checking for successful - parsing and idempotent emitting). - * Cleanup: - * Review & cleanup API surface. - * turn calls to `C4_ASSERT()` into calls to `RYML_ASSERT()` - * use `c4::MemoryResource` in place of `c4::yml::MemoryResource`, and - remove `c4::yml::MemoryResource` - * same for allocators and error callbacks: Use the facilities from c4core. - * Review `parse()` API: add suffixes `_in_situ` and `_in_arena` to clarify - intent. Ie: - * rename `parse(substr)` to `parse_in_situ(substr)` - * rename `parse(csubstr)` to `parse_in_arena(csubstr)` - * Add emit formatting controls: - * add single-line flow formatter - * add multi-line flow formatters - * indenting - * non indenting - * keep current block formatter - * add customizable linebreak limits (number of columns) to every formatter - * add per node format flags - * (lesser priority) add auto formatter using reasonable heuristics to - switch between other existing formatters - * use `csubstr` instead of `csubstr const&` in return and parameter types, but - quantify the performance effect. - * Investigate possibility of comment-preserving roundtrips diff --git a/third_party/rapidyaml/rapidyaml/api/CMakeLists.txt b/third_party/rapidyaml/rapidyaml/api/CMakeLists.txt deleted file mode 100644 index e44abfc82..000000000 --- a/third_party/rapidyaml/rapidyaml/api/CMakeLists.txt +++ /dev/null @@ -1,168 +0,0 @@ -option(RYML_BUILD_API_PYTHON "Enable Python API" ON) -option(RYML_API_TESTS "Enable API tests" ${RYML_BUILD_TESTS}) -option(RYML_API_BENCHMARK "Enable API tests" ${RYML_BUILD_BENCHMARKS}) - -c4_log("enabling API") - -cmake_policy(PUSH) -cmake_policy(SET CMP0078 NEW) # https://cmake.org/cmake/help/v3.14/policy/CMP0078.html -cmake_policy(SET CMP0086 NEW) # https://cmake.org/cmake/help/v3.14/policy/CMP0086.html - -find_package(SWIG REQUIRED) -c4_log("found swig ${SWIG_VERSION}: ${SWIG_EXECUTABLE}") - -# https://cmake.org/cmake/help/v3.13/module/UseSWIG.html -include(UseSWIG) - -set(RYML_API_DIR ${CMAKE_CURRENT_LIST_DIR}) -set(RYML_SWIG_SRC ${RYML_API_DIR}/ryml.i) - -foreach(f ${RYML_SWIG_SRC}) - set_source_files_properties(${f} PROPERTIES - CPLUSPLUS ON - SWIG_MODULE_NAME ryml - SWIG_FLAGS "-includeall" - #INCLUDE_DIRECTORIES "${RYML_SRC_DIR}" # this needs quotes here! - ) -endforeach() - - -add_custom_target(ryml-api-build) -c4_set_folder_remote_project_targets("api" ryml-api-build) - - -if(RYML_API_TESTS) - add_custom_target(ryml-api-test - COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure ${${_c4_uprefix}CTEST_OPTIONS} -C $ -R "*api*" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - c4_set_folder_remote_project_targets("test" ryml-api-test) -endif() - - -if(RYML_API_BENCHMARKS) - add_custom_target(ryml-api-bm) - c4_set_folder_remote_project_targets("bm" ryml-api-bm) -endif() - - -if(RYML_BUILD_API_PYTHON) - c4_log("enabling python3 API") - find_package(Python3 COMPONENTS Interpreter Development REQUIRED) - c4_log("found python ${Python3_VERSION}: ${Python3_EXECUTABLE}") - # - set(t ryml-api-python3) # the target name - set(g ${CMAKE_CURRENT_BINARY_DIR}/src/python3) # where to put c++ generated srcs - set(r ${CMAKE_CURRENT_BINARY_DIR}/python3) # where to put the py files/libs - # - # alternative 1: roll out the extension using cmake - # - c4_get_transitive_property(ryml SOURCES ryml_srcs) - c4_get_transitive_property(ryml INCLUDE_DIRECTORIES ryml_incs) - swig_add_library(${t} - LANGUAGE python - OUTPUT_DIR ${r} - OUTFILE_DIR ${g} - SOURCES ${RYML_SWIG_SRC} ${ryml_srcs}) - #c4_set_folder_remote_project_targets("api" ${t}) - add_dependencies(ryml-api-build ${t}) - target_include_directories(${t} PUBLIC ${ryml_incs}) - swig_link_libraries(${t} ${Python3_LIBRARIES}) - set_target_properties(${t} PROPERTIES - OUTPUT_NAME "ryml" - SWIG_GENERATED_INCLUDE_DIRECTORIES ${Python3_INCLUDE_DIRS} - ARCHIVE_OUTPUT_DIRECTORY "${r}/lib" - LIBRARY_OUTPUT_DIRECTORY "${r}" - RUNTIME_OUTPUT_DIRECTORY "${r}") - if(WIN32) - target_compile_definitions(${t} PUBLIC __WIN32__) - endif() - #target_link_libraries(${t} PUBLIC ryml) #"${RYML_SRC_DIR};${PROJECT_SOURCE_DIR}/ext/c4core/src") - #target_include_directories(${t} PUBLIC "${RYML_SRC_DIR};${PROJECT_SOURCE_DIR}/ext/c4core/src") - # - # alternative 2: use distutils to create the extension - # - # get the list of generated files and format it as a python string list - #c4_get_transitive_property(ryml SOURCES ryml_srcs) - #c4_get_transitive_property(ryml INCLUDE_DIRS ryml_incs) - #pylist("${ryml_srcs};rymlPYTHON_wrap.cxx" ryml_srcs) - #pylist("${ryml_incs}" ryml_incs) - #function(pylist li out) - # print_var(li) - # set(l) - # foreach(f ${li}) - # set(l "${l}'${f}', ") - # endforeach() - # set(${out} ${l} PARENT_SCOPE) - #endfunction() - #function(create_setup_py src dst) - # set(opt0arg - # ) - # set(opt1arg - # NAME - # VERSION - # AUTHOR - # DESC - # SRC - # ) - # set(optnarg - # PYMODS - # ) - # cmake_parse_arguments("" "${opt0arg}" "${opt1arg}" "${optnarg}" "${ARGN}") - # configure_file("${src}" "${dst}" @ONLY) - #endfunction() - #create_setup_py(${RYML_API_DIR}/python/setup.py ${g}/setup.py - # NAME ryml - # VERSION ${RYML_VERSION} - # AUTHOR "${RYML_AUTHOR}" - # DESC "${RYML_DESC}" - # SRC "${genfiles_str}" - # ) - #add_custom_target(${t}-distutils - # COMMAND ${Python3_EXECUTABLE} setup.py build_ext --inplace - # WORKING_DIRECTORY ${g}) - - set(pydir ${CMAKE_CURRENT_LIST_DIR}/python) - if(RYML_API_TESTS) - add_custom_target(ryml-api-test-python3 - COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure ${${_c4_uprefix}CTEST_OPTIONS} -C $ -R ".*python3.*" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${t} - ) - add_dependencies(ryml-api-test ryml-api-test-python3) - c4_set_folder_remote_project_targets("test" ryml-api-test-python3) - function(add_python_test script) - get_filename_component(script_name ${script} NAME_WE) - set(script ${pydir}/${script}) - set(tn ryml-api-test-python3-${script_name}) - set(cmd ${CMAKE_COMMAND} -E env PYTHONPATH=${r} ${Python3_EXECUTABLE} ${script}) - add_custom_target(${tn} - COMMAND ${cmd} - DEPENDS ${t} - WORKING_DIRECTORY ${pydir}) - c4_set_folder_remote_project_targets("test" ${tn}) - add_test(NAME ${tn}-run - COMMAND ${cmd} - WORKING_DIRECTORY ${pydir}) - endfunction() - add_python_test(parse.py) - endif() - - if(RYML_API_BENCHMARKS) - add_custom_target(ryml-api-bm-python3) - add_dependencies(ryml-api-bm ryml-api-bm-python3) - c4_set_folder_remote_project_targets("bm" ryml-api-bm-python3) - set(script ${pydir}/parse_bm.py) - c4_add_benchmark_cmd(ryml-api-bm-python3-travis - COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${r} ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/../bm/cases/travis.yml ryml) - c4_add_benchmark_cmd(ryml-api-bm-python3-appveyor - COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${r} ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/../bm/cases/appveyor.yml ryml) - c4_add_benchmark_cmd(ryml-api-bm-python3-compile_commands - COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${r} ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/../bm/cases/compile_commands.json ryml) - c4_set_folder_remote_project_targets("bm" ryml-bm-api-python3-travis) - c4_set_folder_remote_project_targets("bm" ryml-bm-api-python3-appveyor) - c4_set_folder_remote_project_targets("bm" ryml-bm-api-python3-compile_commands) - endif() -endif() - - -cmake_policy(POP) diff --git a/third_party/rapidyaml/rapidyaml/api/python/parse.py b/third_party/rapidyaml/rapidyaml/api/python/parse.py deleted file mode 100644 index 6a814003b..000000000 --- a/third_party/rapidyaml/rapidyaml/api/python/parse.py +++ /dev/null @@ -1,414 +0,0 @@ -import ryml -import unittest - - -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -class TestSubstrInterop(unittest.TestCase): - - # ------------------------------------------------ - # str - - # CAN create c4::csubstr from string object - def test11_str2csubstr(self): - s = "asdasd" - m = ryml.as_csubstr(s) - self.assertTrue(ryml._same_ptr(s, m)) - self.assertTrue(ryml._same_mem(s, m)) - self.assertEqual(s, ryml.u(m)) - # - m = ryml.as_csubstr(m) - self.assertTrue(ryml._same_ptr(s, m)) - self.assertTrue(ryml._same_mem(s, m)) - self.assertEqual(s, ryml.u(m)) - - # CANNOT create c4::substr from string object - def test12_str2substr(self): - s = "" - with self.assertRaises(TypeError) as context: - c = ryml.as_substr(s) - self.assertTrue(type(context.exception), TypeError) - - # ------------------------------------------------ - # bytes - - # CAN create c4::csubstr from string object - def test21_bytes2csubstr(self): - s = b"foo21" - m = ryml.as_csubstr(s) - self.assertTrue(ryml._same_ptr(s, m)) - self.assertTrue(ryml._same_mem(s, m)) - self.assertEqual(s, m) - # - m = ryml.as_csubstr(m) - self.assertTrue(ryml._same_ptr(s, m)) - self.assertTrue(ryml._same_mem(s, m)) - self.assertEqual(s, m) - - # CANNOT create c4::csubstr from string object - def test22_bytes2substr(self): - s = b"foo22" - with self.assertRaises(TypeError) as context: - c = ryml.as_substr(s) - self.assertTrue(type(context.exception), TypeError) - - # ------------------------------------------------ - # bytearray - - # CAN create c4::csubstr from string object - def test31_bytes2csubstr(self): - s = bytearray("foo31", "utf8") - m = ryml.as_csubstr(s) - self.assertTrue(ryml._same_ptr(s, m)) - self.assertTrue(ryml._same_mem(s, m)) - self.assertEqual(s, m) - # - m = ryml.as_csubstr(m) - self.assertTrue(ryml._same_ptr(s, m)) - self.assertTrue(ryml._same_mem(s, m)) - self.assertEqual(s, m) - - # CANNOT create c4::csubstr from string object - def test32_bytes2substr(self): - s = bytearray("foo31", "utf8") - m = ryml.as_csubstr(s) - self.assertTrue(ryml._same_ptr(s, m)) - self.assertTrue(ryml._same_mem(s, m)) - self.assertEqual(s, m) - # - m = ryml.as_csubstr(m) - self.assertTrue(ryml._same_ptr(s, m)) - self.assertTrue(ryml._same_mem(s, m)) - self.assertEqual(s, m) - - -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- - -def _addmap(t, node, k=None): - m = t.append_child(node) - if k is None: - t.to_map(m) - else: - t.to_map(m, k) - return m - - -def _addseq(t, node, k=None): - m = t.append_child(node) - if k is None: - t.to_seq(m) - else: - t.to_seq(m, k) - return m - - -def _addleaf(t, node, k, v=None): - ch = t.append_child(node) - if v is None: - t.to_val(ch, k) - else: - t.to_keyval(ch, k, v) - return ch - - -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -def check_tree_mod(ut, t): - # some convenient shorthands - eq = ut.assertEqual - def _leaf(node, k, v=None): - ch = _addleaf(t, node, k, v) - pos = t.child_pos(node, ch) - eq(t.child(node, pos), ch) - if v is not None: - eq(t.find_child(node, k), ch) - eq(t.child(node, pos), t.find_child(node, k)) - return ch - def _seq(node, k): - ch = _addseq(t, node, k) - eq(t.find_child(node, k), ch) - return ch - def _map(node, k): - ch = _addmap(t, node, k) - eq(t.find_child(node, k), ch) - return ch - m = _map(t.root_id(), "check_tree_mod_map") - _leaf(m, "k1", "v1") - _leaf(m, "k2", "v2") - _leaf(m, "k3", "v3") - eq(t.num_children(m), 3) - eq(t.num_siblings(t.first_child(m)), 3) - s = _seq(t.root_id(), "check_tree_mod_seq") - _leaf(s, "v1") - _leaf(s, "v2") - _leaf(s, "v3") - eq(t.num_children(s), 3) - eq(t.num_siblings(t.first_child(m)), 3) - - -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -class SimpleHardcoded: - - yaml = "{HELLO: a, foo: b, bar: c, baz: d, seq: [0, 1, 2, 3]}" - - def check(self, ut, t): - # some convenient shorthands - eq = ut.assertEqual - ne = ut.assertNotEqual - fs = ut.assertFalse - tr = ut.assertTrue - # - eq(t.size(), 10) - tr(t.is_root(0)) - eq(t.num_children(0), 5) - eq(t.find_child(0, b"HELLO"), 1) - eq(t.find_child(0, b"foo"), 2) - eq(t.find_child(0, b"bar"), 3) - eq(t.find_child(0, b"baz"), 4) - eq(t.find_child(0, b"seq"), 5) - eq(t.parent(0), ryml.NONE) - eq(t.parent(1), 0) - eq(t.parent(2), 0) - eq(t.parent(3), 0) - eq(t.parent(4), 0) - eq(t.parent(5), 0) - fs(t.is_root(1)) - fs(t.is_root(2)) - fs(t.is_root(3)) - fs(t.is_root(4)) - fs(t.is_root(5)) - fs(t.has_child(0, b"foozzie")) - fs(t.has_child(0, b"bark")) - fs(t.has_child(0, b"bart")) - fs(t.has_child(0, b"bazk")) - eq(t.next_sibling(0), ryml.NONE) - eq(t.prev_sibling(0), ryml.NONE) - eq(t.prev_sibling(1), ryml.NONE) - eq(t.next_sibling(5), ryml.NONE) - tr(t.has_child(0, b"HELLO")) - tr(t.has_child(0, b"foo")) - tr(t.has_child(0, b"bar")) - tr(t.has_child(0, b"baz")) - eq(t.key(1), b"HELLO") - eq(t.key(2), b"foo") - eq(t.key(3), b"bar") - eq(t.key(4), b"baz") - eq(t.key(5), b"seq") - eq(t.val(1), b"a") - eq(t.val(2), b"b") - eq(t.val(3), b"c") - eq(t.val(4), b"d") - eq(t.val(6), b"0") - eq(t.val(7), b"1") - eq(t.val(8), b"2") - eq(t.val(9), b"3") - tr(t.has_sibling(1, b"bar")) - tr(t.has_sibling(1, b"baz")) - tr(t.has_sibling(2, b"foo")) - tr(t.has_sibling(2, b"baz")) - tr(t.has_sibling(3, b"foo")) - tr(t.has_sibling(3, b"bar")) - for i in (1, 2, 3, 4, 5): - eq(t.find_sibling(i, b"HELLO"), 1) - eq(t.find_sibling(i, b"foo"), 2) - eq(t.find_sibling(i, b"bar"), 3) - eq(t.find_sibling(i, b"baz"), 4) - eq(t.find_sibling(i, b"seq"), 5) - # - num = 0 - for id in ryml.children(t): - num += 1 - eq(id, num) - eq(num, t.num_children(t.root_id())) - eq(num, t.num_siblings(t.first_child(t.root_id()))) - # - num = 0 - for id in ryml.children(t, 1): - num += 1 - eq(num, 0) - # - num = 0 - for id in ryml.siblings(t, 1): - num += 1 - eq(id, num) - eq(num, t.num_children(t.root_id())) - eq(num, t.num_siblings(t.first_child(t.root_id()))) - # - num = 0 - for id in ryml.siblings(t, 3): - num += 1 - eq(id, num) - eq(num, 5) - eq(num, t.num_siblings(t.first_child(t.root_id()))) - # - - for i, ch in enumerate(ryml.children(t, 5)): - eq(t.val(ch), [b"0", b"1", b"2", b"3"][i]) - - sibs = [b"HELLO", b"foo", b"bar", b"baz", b"seq"] - sibs_s = ["HELLO", "foo", "bar", "baz", "seq"] - for i, sib in enumerate(ryml.siblings(t, 5)): - k = t.key(sib) - k_s = str(k, "utf8") - eq(k, sibs[i]) - eq(k_s, sibs_s[i]) - ne(k, sibs_s[i]) - ne(k_s, sibs[i]) - k_s = str(k) - ne(k_s, sibs_s[i]) - ne(k_s, sibs[i]) - - num = 0 - for id in ryml.siblings(t, 0): - num += 1 - eq(num, 1) - # - num = 0 - for id, level in ryml.walk(t): - num += 1 - if t.is_root(id): - eq(id, 0) - eq(level, 0) - if t.is_map(id): - eq(id, 0) - eq(level, 0) - if t.is_seq(id): - eq(id, 5) - eq(level, 1) - if t.is_keyval(id): - tr(id > 0 and id < 5) - if t.is_val(id): - tr(id > 5) - eq(level, 2) - eq(num, t.size()) - # - num = 0 - for id in ryml.walk(t, 5): - num += 1 - eq(num, 5) - # - num = 0 - for id in ryml.walk(t, 9): - num += 1 - eq(num, 1) - - check_tree_mod(ut, t) - - -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -class _TestBase(unittest.TestCase): - - def _setUp(self, case=None): - self.case = case - self.src_as_str = str(case.yaml) - self.src_as_bytes = bytes(case.yaml, "utf8") - self.src_as_bytearray = bytearray(case.yaml, "utf8") - - # ---------------------------------------------------------- - def _test11_str__ro(self): # cannot read string buffers (or can we?) - tree = ryml.parse(self.src_as_str) - self.case.check(self, tree) - - def _test12_str__ro__reuse_tree(self): # cannot read string buffers (or can we?) - t = ryml.Tree() - ryml.parse(self.src_as_str, tree=t) - self.case.check(self, t) - - def _test13_str__rw(self): # cannot mutate string buffers (or can we?) - with self.assertRaises(TypeError) as context: - ryml.parse_in_situ(self.src_as_str) - self.assertTrue(type(context.exception), TypeError) - - # ---------------------------------------------------------- - def _test21_bytes__ro(self): - tree = ryml.parse(self.src_as_bytes) - self.case.check(self, tree) - - def _test22_bytes__ro__reuse_tree(self): - t = ryml.Tree() - r = ryml.parse(self.src_as_bytes, tree=t) - self.assertTrue(r is t) - self.case.check(self, t) - - def _test23_bytes__rw(self): # cannot mutate bytes buffers - with self.assertRaises(TypeError) as context: - ryml.parse_in_situ(self.src_as_bytes) - self.assertTrue(type(context.exception), TypeError) - - # ---------------------------------------------------------- - def _test31_bytearray__ro(self): - tree = ryml.parse(self.src_as_bytearray) - self.case.check(self, tree) - - def _test32_bytearray__ro__reuse_tree(self): - t = ryml.Tree() - r = ryml.parse(self.src_as_bytearray, tree=t) - self.assertTrue(r is t) - self.case.check(self, t) - - def _test33_bytearray__rw(self): # bytearray buffers are mutable - tree = ryml.parse_in_situ(self.src_as_bytearray) - self.case.check(self, tree) - - def _test34_bytearray__rw__reuse_tree(self): # bytearray buffers are mutable - t = ryml.Tree() - r = ryml.parse_in_situ(self.src_as_bytearray, tree=t) - self.assertTrue(r is t) - self.case.check(self, t) - - -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -class TestSimpleHardCoded(_TestBase): - - def setUp(self): - _TestBase._setUp(self, SimpleHardcoded()) - - # ---------------------------------------------------------- - def test11_str__ro(self): - super()._test11_str__ro() - - def test12_str__ro__reuse_tree(self): - self._test12_str__ro__reuse_tree() - - def test13_str__rw(self): - self._test13_str__rw() - - # ---------------------------------------------------------- - def test21_bytes__ro(self): - self._test21_bytes__ro() - - def test22_bytes__ro__reuse_tree(self): - self._test22_bytes__ro__reuse_tree() - - def test23_bytes__rw(self): - self._test23_bytes__rw() - - # ---------------------------------------------------------- - def test31_bytearray__ro(self): - self._test31_bytearray__ro() - - def test32_bytearray__ro__reuse_tree(self): - self._test32_bytearray__ro__reuse_tree() - - def test33_bytearray__rw(self): - self._test33_bytearray__rw() - - def test34_bytearray__rw__reuse_tree(self): - self._test34_bytearray__rw__reuse_tree() - - -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -if __name__ == "__main__": - unittest.main() diff --git a/third_party/rapidyaml/rapidyaml/api/python/parse_bm.py b/third_party/rapidyaml/rapidyaml/api/python/parse_bm.py deleted file mode 100644 index 41a0a5e5d..000000000 --- a/third_party/rapidyaml/rapidyaml/api/python/parse_bm.py +++ /dev/null @@ -1,128 +0,0 @@ -import ryml -import ruamel.yaml -import yaml -import timeit -import time -import prettytable -from collections import OrderedDict as odict - - -class RunResults: - - __slots__ = ('name', 'count', 'time', 'avg', 'MBps', 'timeit') - - def __init__(self, name, time, count, MB, timeit): - self.name = name - self.time = time - self.count = count - self.avg = time / count - self.MBps = MB / self.time / 1000.0 - self.timeit = timeit - - def __str__(self): - fmt = "{}: count={} time={:.3f}ms avg={:.3f}ms MB/s={:.3f}" - fmt = fmt.format(self.name, self.count, self.time, self.avg, self.MBps) - return fmt - - -class BmCase: - - def __init__(self, filename): - with open(filename, "r") as f: - src = f.read() - self.src_as_str = src - self.src_as_bytes = bytes(src, "utf8") - self.src_as_bytearray = bytearray(src, "utf8") - - def run(self, bm_name, cls): - obj = cls() - method = getattr(obj, bm_name) - self.count = 0 - self.MB = 0 - def fn(): - method(self) - self.count += 1 - self.MB += len(self.src_as_str) - t = timeit.Timer(fn) - delta = time.time() - result = t.autorange() - delta = 1000. * (time.time() - delta) - name = bm_name + ":" + cls.__name__ - return RunResults(name, delta, self.count, self.MB, result) - - -class RymlRo: - - def parse(self, case): - r = ryml.parse(case.src_as_bytearray) - - -class RymlRoReuse: - - def __init__(self): - self.tree = ryml.Tree() - - def parse(self, case): - ryml.parse(case.src_as_bytearray, tree=ryml.Tree()) - - - -class RymlInSitu: - - def parse(self, case): - r = ryml.parse_in_situ(case.src_as_bytearray) - - -class RymlInSituReuse: - - def __init__(self): - self.tree = ryml.Tree() - - def parse(self, case): - self.tree.clear() - self.tree.clear_arena() - ryml.parse_in_situ(case.src_as_bytearray, tree=self.tree) - - -class RuamelYaml: - - def parse(self, case): - r = ruamel.yaml.load(case.src_as_str, Loader=ruamel.yaml.Loader) - - -class PyYaml: - - def parse(self, case): - r = yaml.safe_load(case.src_as_str) - - -def run(filename): - case = BmCase(filename) - approaches = (RuamelYaml, - PyYaml, - RymlRo, - RymlRoReuse, - RymlInSitu, - RymlInSituReuse) - benchmarks = ('parse', ) - for bm in benchmarks: - results = odict() - for cls in approaches: - r = case.run(bm, cls) - results[r.name] = r - print(r) - table = prettytable.PrettyTable() - table.field_names = ["case", "count", "time(ms)", "avg(ms)", "avg_read(MB/s)"] - table.align["case"] = "l" - def f(v): return "{:.3f}".format(v) - for v in results.values(): - table.add_row([v.name, v.count, f(v.time), f(v.avg), f(v.MBps)]) - print(table) - - -if __name__ == "__main__": - import sys - if len(sys.argv) < 2: - raise Exception("") - filename = sys.argv[1] - run(filename) diff --git a/third_party/rapidyaml/rapidyaml/api/python/requirements_dev.txt b/third_party/rapidyaml/rapidyaml/api/python/requirements_dev.txt deleted file mode 100644 index cc22dcadd..000000000 --- a/third_party/rapidyaml/rapidyaml/api/python/requirements_dev.txt +++ /dev/null @@ -1,3 +0,0 @@ -ruamel.yaml -pyyaml -prettytable diff --git a/third_party/rapidyaml/rapidyaml/api/python/setup.py b/third_party/rapidyaml/rapidyaml/api/python/setup.py deleted file mode 100644 index e1a0a3d3c..000000000 --- a/third_party/rapidyaml/rapidyaml/api/python/setup.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -from distutils.core import setup, Extension - -_ext = Extension( - '_' + '@_NAME@', - sources=[@_SRC@], - include_dirs=[@_INC_DIRS@], -) - -setup( - name = '@_NAME@', - version = '@_VERSION@', - author = "@_AUTHOR@", - description = """@_DESC@""", - ext_modules = [_ext], - py_modules = ["@_NAME@"], -) diff --git a/third_party/rapidyaml/rapidyaml/api/ryml.i b/third_party/rapidyaml/rapidyaml/api/ryml.i deleted file mode 100644 index 149d01b49..000000000 --- a/third_party/rapidyaml/rapidyaml/api/ryml.i +++ /dev/null @@ -1,536 +0,0 @@ - -%module ryml - - -//----------------------------------------------------------------------------- -// this block will be pasted verbatim in the generated C++ source file - -%{ -// specifies that the resulting C file should be built as a python -// extension, inserting the module init code -#define SWIG_FILE_WITH_INIT - -#include "ryml.hpp" - -namespace c4 { -namespace yml { - -using substr = c4::substr; -using csubstr = c4::csubstr; - -} /* namespace yml */ -} /* namespace c4 */ - -%} - -//----------------------------------------------------------------------------- - - -%apply (const char *STRING, size_t LENGTH) { (const char *str, size_t len) }; -%apply (char *STRING, size_t LENGTH) { (char *str, size_t len) }; - -%typemap(in) c4::substr { -#if defined(SWIGPYTHON) - Py_buffer view; - int ok = PyObject_CheckBuffer($input); - if(ok) - { - ok = (0 == PyObject_GetBuffer($input, &view, PyBUF_SIMPLE|PyBUF_WRITABLE)); - } - if(ok) - { - $1 = c4::substr((char*)view.buf, view.len); - PyBuffer_Release(&view); - } - else - { - PyErr_SetString(PyExc_TypeError, "could not get mutable memory for c4::csubstr - have you passed a str?"); - SWIG_fail; - } -#else -#error no "in" typemap defined for this export language -#endif -}; - -%typemap(in) c4::csubstr { -#if defined(SWIGPYTHON) - Py_buffer view; - view.buf = nullptr; - int ok = PyObject_CheckBuffer($input); - if(ok) - { - ok = (0 == PyObject_GetBuffer($input, &view, PyBUF_CONTIG_RO)); - } - if(ok) - { - $1 = c4::csubstr((const char*)view.buf, view.len); - PyBuffer_Release(&view); - } - else - { - // https://stackoverflow.com/questions/36098984/python-3-3-c-api-and-utf-8-strings - Py_ssize_t sz = 0; - const char *buf = PyUnicode_AsUTF8AndSize($input, &sz); - if(buf || sz == 0) - { - $1 = c4::csubstr(buf, sz); - } - else - { - PyErr_SetString(PyExc_TypeError, "c4::csubstr: could not get readonly memory from python object"); - SWIG_fail; - } - } -#else -#error no "in" typemap defined for this export language -#endif -}; -// Copy the typecheck code for "char *". -%typemap(typecheck) c4::substr = char *; -%typemap(typecheck) c4::csubstr = const char *; - - -%typemap(out) c4::csubstr { -#if defined(SWIGPYTHON) - PyObject *obj = PyMemoryView_FromMemory((char*)$1.str, $1.len, PyBUF_READ); - if( ! obj) - { - PyErr_SetString(PyExc_TypeError, "could not get readonly memory from c4::csubstr - have you passed a str?"); - SWIG_fail; - } - $result = obj; -#else -#error no "out" typemap defined for this export language -#endif -}; - - -%inline %{ - -void parse_csubstr(c4::csubstr s, c4::yml::Tree *t) -{ - c4::yml::parse(s, t); -} - -void parse_substr(c4::substr s, c4::yml::Tree *t) -{ - c4::yml::parse(s, t); -} - - -// force a roundtrip to C++, which triggers a conversion to csubstr and returns it as a memoryview -c4::csubstr _get_as_csubstr(c4::csubstr s) -{ - //printf("_get_as_csubstr: %p[%zu]'%.*s'\n", s.str, s.len, (int)s.len, s.str); - return s; -} - -c4::csubstr _get_as_substr(c4::substr s) -{ - //printf("_get_as_substr: %p[%zu]'%.*s'\n", s.str, s.len, (int)s.len, s.str); - return s; -} - - -// utilities for testing -bool _same_ptr(c4::csubstr l, c4::csubstr r) -{ - return l.str == r.str; -} - -bool _same_mem(c4::csubstr l, c4::csubstr r) -{ - return l.str == r.str && l.len == r.len; -} - - -%} - - -//----------------------------------------------------------------------------- - -%pythoncode %{ - - -def as_csubstr(s): - return _get_as_csubstr(s) - -def as_substr(s): - return _get_as_substr(s) - -def u(memview): - return str(memview, "utf8") - - -def children(tree, node=None): - assert tree is not None - if node is None: node = tree.root_id() - ch = tree.first_child(node) - while ch != NONE: - yield ch - ch = tree.next_sibling(ch) - - -def siblings(tree, node): - assert tree is not None - if node is None: return - ch = tree.first_sibling(node) - while ch != NONE: - yield ch - ch = tree.next_sibling(ch) - - -def walk(tree, node=None, indentation_level=0): - assert tree is not None - if node is None: node = tree.root_id() - yield node, indentation_level - ch = tree.first_child(node) - while ch != NONE: - for gc, il in walk(tree, ch, indentation_level + 1): - yield gc, il - ch = tree.next_sibling(ch) - - -def parse_in_situ(buf, **kwargs): - _check_valid_for_in_situ(buf) - return _call_parse(parse_substr, buf, **kwargs) - - -def parse(buf, **kwargs): - return _call_parse(parse_csubstr, buf, **kwargs) - - -def _call_parse(parse_fn, buf, **kwargs): - tree = kwargs.get("tree", Tree()) - parse_fn(buf, tree) - return tree - - -def _check_valid_for_in_situ(obj): - if type(obj) in (str, bytes): - raise TypeError("cannot parse in situ: " + type(obj).__name__) - -%} - -//----------------------------------------------------------------------------- - -namespace c4 { -namespace yml { - -constexpr const size_t NONE = (size_t)-1; - -typedef enum { - NOTYPE = 0, ///< no type is set - VAL = (1<<0), ///< a leaf node, has a (possibly empty) value - KEY = (1<<1), ///< is member of a map, must have non-empty key - MAP = (1<<2), ///< a map: a parent of keyvals - SEQ = (1<<3), ///< a seq: a parent of vals - DOC = (1<<4), ///< a document - STREAM = (1<<5)|SEQ, ///< a stream: a seq of docs - KEYREF = (1<<6), ///< a *reference: the key references an &anchor - VALREF = (1<<7), ///< a *reference: the val references an &anchor - KEYANCH = (1<<8), ///< the key has an &anchor - VALANCH = (1<<9), ///< the val has an &anchor - KEYTAG = (1<<10), ///< the key has an explicit tag/type - VALTAG = (1<<11), ///< the val has an explicit tag/type -} NodeType_e; - - -struct NodeType -{ - NodeType_e type; - - NodeType(); - NodeType(NodeType_e t); - ~NodeType(); - - const char *type_str(); - static const char* type_str(NodeType_e t); - - void set(NodeType_e t); - void add(NodeType_e t); - void rem(NodeType_e t); - - bool is_stream() const; - bool is_doc() const; - bool is_container() const; - bool is_map() const; - bool is_seq() const; - bool has_val() const; - bool has_key() const; - bool is_val() const; - bool is_keyval() const; - bool has_key_tag() const; - bool has_val_tag() const; - bool has_key_anchor() const; - bool has_val_anchor() const; - bool has_anchor() const; - bool is_key_ref() const; - bool is_val_ref() const; - bool is_ref() const; -}; - - -struct Tree -{ - Tree(); - ~Tree(); - - void reserve(size_t node_capacity); - void reserve_arena(size_t node_capacity); - void clear(); - void clear_arena(); - - size_t size() const; - size_t capacity() const; - size_t slack() const; - - size_t arena_size() const; - size_t arena_capacity() const; - size_t arena_slack() const; - - void resolve(); - -public: - - // getters - - NodeType_e type(size_t node) const; - const char* type_str(size_t node) const; - - c4::csubstr key (size_t node) const; - c4::csubstr key_tag (size_t node) const; - c4::csubstr key_ref (size_t node) const; - c4::csubstr key_anchor(size_t node) const; - c4::yml::NodeScalar keysc(size_t node) const; - - c4::csubstr val (size_t node) const; - c4::csubstr val_tag (size_t node) const; - c4::csubstr val_ref (size_t node) const; - c4::csubstr val_anchor(size_t node) const; - c4::yml::NodeScalar valsc(size_t node) const; - -public: - - // node predicates - - bool is_root(size_t node) const; - bool is_stream(size_t node) const; - bool is_doc(size_t node) const; - bool is_container(size_t node) const; - bool is_map(size_t node) const; - bool is_seq(size_t node) const; - bool has_val(size_t node) const; - bool has_key(size_t node) const; - bool is_val(size_t node) const; - bool is_keyval(size_t node) const; - bool has_key_tag(size_t node) const; - bool has_val_tag(size_t node) const; - bool has_key_anchor(size_t node) const; - bool has_val_anchor(size_t node) const; - bool is_key_ref(size_t node) const; - bool is_val_ref(size_t node) const; - bool is_ref(size_t node) const; - bool is_anchor(size_t node) const; - bool parent_is_seq(size_t node) const; - bool parent_is_map(size_t node) const; - bool empty(size_t node) const; - bool has_anchor(size_t node, c4::csubstr a) const; - -public: - - // hierarchy predicates - - bool has_parent(size_t node) const; - bool has_child(size_t node, c4::csubstr key) const; - //bool has_child(size_t node, size_t ch) const; - bool has_children(size_t node) const; - bool has_sibling(size_t node, c4::csubstr key) const; - //bool has_sibling(size_t node, size_t sib) const; - bool has_siblings(size_t node) const; - bool has_other_siblings(size_t node) const; - -public: - - // hierarchy getters - - size_t root_id() const; - - size_t parent(size_t node) const; - size_t prev_sibling(size_t node) const; - size_t next_sibling(size_t node) const; - size_t num_children(size_t node) const; - size_t child_pos(size_t node, size_t ch) const; - size_t first_child(size_t node) const; - size_t last_child(size_t node) const; - size_t child(size_t node, size_t pos) const; - size_t find_child(size_t node, c4::csubstr key) const; - size_t num_siblings(size_t node) const; - size_t num_other_siblings(size_t node) const; - size_t sibling_pos(size_t node, size_t sib) const; - size_t first_sibling(size_t node) const; - size_t last_sibling(size_t node) const; - size_t sibling(size_t node, size_t pos) const; - size_t find_sibling(size_t node, c4::csubstr key) const; - -public: - - void to_keyval(size_t node, c4::csubstr key, c4::csubstr val, int more_flags=0); - void to_map(size_t node, c4::csubstr key, int more_flags=0); - void to_seq(size_t node, c4::csubstr key, int more_flags=0); - void to_val(size_t node, c4::csubstr val, int more_flags=0); - void to_stream(size_t node, int more_flags=0); - void to_map(size_t node, int more_flags=0); - void to_seq(size_t node, int more_flags=0); - void to_doc(size_t node, int more_flags=0); - - void set_key_tag(size_t node, c4::csubstr tag); - void set_key_anchor(size_t node, c4::csubstr anchor); - void set_val_anchor(size_t node, c4::csubstr anchor); - void set_key_ref (size_t node, c4::csubstr ref ); - void set_val_ref (size_t node, c4::csubstr ref ); - - void set_val_tag(size_t node, c4::csubstr tag); - void rem_key_anchor(size_t node); - void rem_val_anchor(size_t node); - void rem_key_ref (size_t node); - void rem_val_ref (size_t node); - void rem_anchor_ref(size_t node); - -public: - - /** create and insert a new child of "parent". insert after the (to-be) - * sibling "after", which must be a child of "parent". To insert as the - * first child, set after to NONE */ - size_t insert_child(size_t parent, size_t after); - size_t prepend_child(size_t parent); - size_t append_child(size_t parent); - -public: - - //! create and insert a new sibling of n. insert after "after" - size_t insert_sibling(size_t node, size_t after); - size_t prepend_sibling(size_t node); - size_t append_sibling(size_t node); - -public: - - //! remove an entire branch at once: ie remove the children and the node itself - void remove(size_t node); - - //! remove all the node's children, but keep the node itself - void remove_children(size_t node); - -public: - - /** change the node's position in the parent */ - void move(size_t node, size_t after); - - /** change the node's parent and position */ - void move(size_t node, size_t new_parent, size_t after); - /** change the node's parent and position */ - size_t move(Tree * src, size_t node, size_t new_parent, size_t after); - - /** recursively duplicate the node */ - size_t duplicate(size_t node, size_t new_parent, size_t after); - /** recursively duplicate a node from a different tree */ - size_t duplicate(Tree const* src, size_t node, size_t new_parent, size_t after); - - /** recursively duplicate the node's children (but not the node) */ - void duplicate_children(size_t node, size_t parent, size_t after); - /** recursively duplicate the node's children (but not the node), where the node is from a different tree */ - void duplicate_children(Tree const* src, size_t node, size_t parent, size_t after); - - void duplicate_contents(size_t node, size_t where); - - /** duplicate the node's children (but not the node) in a new parent, but - * omit repetitions where a duplicated node has the same key (in maps) or - * value (in seqs). If one of the duplicated children has the same key - * (in maps) or value (in seqs) as one of the parent's children, the one - * that is placed closest to the end will prevail. */ - void duplicate_children_no_rep(size_t node, size_t parent, size_t after); - -}; - -/* -%extend Tree { - - bool has_anchor(size_t node, const char *str, size_t len) const - { - return $self->has_anchor(node, c4::csubstr(str, len)); - } - - bool has_child(size_t node, const char *str, size_t len) const - { - return $self->has_child(node, c4::csubstr(str, len)); - } - - bool has_sibling(size_t node, const char *str, size_t len) const - { - return $self->has_sibling(node, c4::csubstr(str, len)); - } - - size_t find_child(size_t node, const char *str, size_t len) const - { - return $self->find_child(node, c4::csubstr(str, len)); - } - - size_t find_sibling(size_t node, const char *str, size_t len) const - { - return $self->find_sibling(node, c4::csubstr(str, len)); - } - - void to_keyval(size_t node, const char *keystr, size_t keylen, const char *valstr, size_t vallen, int more_flags=0) - { - return $self->to_keyval(node, c4::csubstr(keystr, keylen), c4::csubstr(valstr, vallen), more_flags); - } - - void to_map(size_t node, const char *keystr, size_t keylen, int more_flags=0) - { - return $self->to_map(node, c4::csubstr(keystr, keylen), more_flags); - } - - void to_seq(size_t node, const char *keystr, size_t keylen, int more_flags=0) - { - return $self->to_seq(node, c4::csubstr(keystr, keylen), more_flags); - } - - void to_val(size_t node, const char *valstr, size_t vallen, int more_flags=0) - { - return $self->to_val(node, c4::csubstr(valstr, vallen), more_flags); - } - - void set_key_tag(size_t node, const char *str, size_t len) - { - return $self->set_key_tag(node, c4::csubstr(str, len)); - } - void set_val_tag(size_t node, const char *str, size_t len) - { - return $self->set_val_tag(node, c4::csubstr(str, len)); - } - - void set_key_anchor(size_t node, const char *str, size_t len) - { - return $self->set_key_anchor(node, c4::csubstr(str, len)); - } - void set_val_anchor(size_t node, const char *str, size_t len) - { - return $self->set_val_anchor(node, c4::csubstr(str, len)); - } - - void set_key_ref(size_t node, const char *str, size_t len) - { - return $self->set_key_ref(node, c4::csubstr(str, len)); - } - void set_val_ref(size_t node, const char *str, size_t len) - { - return $self->set_val_ref(node, c4::csubstr(str, len)); - } - -}; -*/ - -} // namespace yml -} // namespace c4 - -//----------------------------------------------------------------------------- diff --git a/third_party/rapidyaml/rapidyaml/bm/CMakeLists.txt b/third_party/rapidyaml/rapidyaml/bm/CMakeLists.txt deleted file mode 100644 index d1e387567..000000000 --- a/third_party/rapidyaml/rapidyaml/bm/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -c4_setup_benchmarking() - -# ----------------------------------------------------------------------------- -# json libs that will be compared with ryml (and the other yaml libs) - -set(_ed ${CMAKE_CURRENT_BINARY_DIR}/ext) # casual ryml extern dir (these projects are not part of ryml and are downloaded and compiled on the fly) - -# jsoncpp needs to be compiled -c4_override(JSONCPP_WITH_TESTS OFF) -c4_override(JSONCPP_WITH_POST_BUILD_UNITTEST OFF) -c4_override(JSONCPP_WITH_WARNING_AS_ERROR OFF) -c4_override(JSONCPP_WITH_STRICT_ISO OFF) -c4_override(JSONCPP_WITH_PKGCONFIG_SUPPORT OFF) -c4_override(JSONCPP_WITH_CMAKE_PACKAGE OFF) -c4_require_subproject(jsoncpp REMOTE - GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp - GIT_TAG master) -c4_set_folder_remote_project_targets(ext/jsoncpp - jsoncpp_lib - examples - readFromStream - readFromString - streamWrite - stringWrite) - -# nlohmannjson needs to be compiled -c4_override(JSON_BuildTests OFF) -c4_override(JSON_Install OFF) -c4_override(JSON_MultipleHeaders OFF) -c4_require_subproject(nlohmann_json REMOTE - GIT_REPOSITORY https://github.com/nlohmann/json - GIT_TAG master) - -# rapidjson is header only -set(rapidjson_dir ${_ed}/rapidjson) -c4_download_remote_proj(rapidjson rapidjson_dir - GIT_REPOSITORY https://github.com/Tencent/rapidjson - GIT_TAG version1.1.0) -set(RYML_RAPIDJSON_INC_DIR ${rapidjson_dir}/include) - -# sajson is header only -set(sajson_dir ${_ed}/sajson) -c4_download_remote_proj(sajson sajson_dir - GIT_REPOSITORY https://github.com/chadaustin/sajson - GIT_TAG 2dcfd350586375f9910f74821d4f07d67ae455ba) -set(RYML_SAJSON_INC_DIR ${sajson_dir}/include) - - -# ----------------------------------------------------------------------------- -function(ryml_add_bm_case target case_file) - c4_dbg("adding benchmark case: ${case_file}") - # case identifier - get_filename_component(case ${case_file} NAME_WE) - # prevent json readers from reading yml data - get_filename_component(ext ${case_file} EXT) - if(NOT ("${ext}" STREQUAL ".json")) - set(filter_json "yml|yaml") - endif() - # that's it! - c4_add_target_benchmark(${target} ${case} - FILTER "${filter_json}" - ARGS ${case_file}) -endfunction() - -c4_add_executable(ryml-bm-parse - SOURCES bm_parse.cpp - LIBS ryml yaml yaml-cpp benchmark jsoncpp_lib nlohmann_json c4fs - INC_DIRS ${RYML_RAPIDJSON_INC_DIR} ${RYML_SAJSON_INC_DIR} - FOLDER bm) -if(RYML_DBG) - target_compile_definitions(ryml-bm-parse PRIVATE RYML_DBG) -endif() - -set(cdir "${CMAKE_CURRENT_LIST_DIR}/cases") -file(GLOB bm_cases RELATIVE "${cdir}" "${cdir}/*.*") -foreach(case_file ${bm_cases}) - ryml_add_bm_case(ryml-bm-parse "${cdir}/${case_file}") -endforeach() diff --git a/third_party/rapidyaml/rapidyaml/bm/bm_parse.cpp b/third_party/rapidyaml/rapidyaml/bm/bm_parse.cpp deleted file mode 100644 index 6d08f157e..000000000 --- a/third_party/rapidyaml/rapidyaml/bm/bm_parse.cpp +++ /dev/null @@ -1,362 +0,0 @@ -#include -#include -#include -#include "../test/libyaml.hpp" - -#include -#include - -#include - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4100) // sajson.h(1313,41): warning C4100: 'input_document_size_in_bytes': unreferenced formal parameter -# pragma warning(disable : 4127) // conditional expression is constant -# pragma warning(disable : 4200) // sajson.h(209,28): warning C4200: nonstandard extension used: zero-sized array in struct/union -# pragma warning(disable : 4242) // sajson.h(2295,1): warning C4242: '=': conversion from 'unsigned int' to 'char', possible loss of data -# pragma warning(disable : 4244) // sajson.h(2295,26): warning C4244: '=': conversion from 'unsigned int' to 'char', possible loss of data -# pragma warning(disable : 4389) // '==': signed/unsigned mismatch -# pragma warning(disable : 4996) // warning C4996: 'Json::Reader': Use CharReader and CharReaderBuilder instead. -#elif defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wunused-parameter" -# pragma clang diagnostic ignored "-Wc99-extensions" -# pragma clang diagnostic ignored "-Wfloat-equal" -# pragma clang diagnostic ignored "-Wshadow" -# pragma clang diagnostic ignored "-Wsign-conversion" -# pragma clang diagnostic ignored "-Wconversion" -# if __clang_major__ >= 8 -# pragma clang diagnostic ignored "-Wimplicit-int-conversion" -# endif -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wshadow" -# pragma GCC diagnostic ignored "-Wunused-parameter" -# pragma GCC diagnostic ignored "-Wunused-but-set-variable" -# pragma GCC diagnostic ignored "-Wfloat-equal" -# pragma GCC diagnostic ignored "-Wpedantic" -# pragma GCC diagnostic ignored "-Wuseless-cast" -# pragma GCC diagnostic ignored "-Wconversion" -# pragma GCC diagnostic ignored "-Wsign-conversion" -# if __GNUC__ >= 8 -# pragma GCC diagnostic ignored "-Wclass-memaccess" // rapidjson/document.h:1952:24 -# endif -#endif -#include -#include -#include -#include -#include -#if defined(_MSC_VER) -# pragma warning(pop) -#elif defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - - -namespace bm = benchmark; - - -// now for our code -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4996) // warning C4996: 'Json::Reader': Use CharReader and CharReaderBuilder instead. -#elif defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -# pragma clang diagnostic ignored "-Wunused-variable" -# pragma clang diagnostic ignored "-Wsign-conversion" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic ignored "-Wsign-conversion" -#endif - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -enum : int { - kClearTree=1, - kClearTreeArena=2, - kResetInPlace=4, - kAll=kClearTree|kClearTreeArena|kResetInPlace, -}; - -struct BmCase -{ - c4::csubstr filename; - std::vector src; - std::vector in_place; - ryml::Parser ryml_parser; - ryml::Tree ryml_tree; - bool is_json; - rapidjson::Document rapidjson_doc; - ryml::Tree libyaml_tree; - - void run(int argc, char **argv) - { - bm::Initialize(&argc, argv); - C4_CHECK(argc == 2); - load(argv[1]); - bm::RunSpecifiedBenchmarks(); - } - - void load(const char* file) - { - filename = c4::to_csubstr(file); - is_json = filename.ends_with(".json"); - std::cout << "-----------------------------------\n"; - std::cout << "running case: " << filename.basename() << "\n"; - std::cout << "file: " << filename << "\n"; - std::cout << "-----------------------------------\n"; - c4::fs::file_get_contents(file, &src); - if(src.back() != '\0') - { - src.push_back('\0'); - } - in_place = src; - C4_ASSERT_MSG(strlen(in_place.data()) == in_place.size()-1, - "len=%zu sz=%zu", - strlen(in_place.data()), in_place.size()); - } - - void prepare(bm::State &st, int what) - { - st.PauseTiming(); - prepare(what); - st.ResumeTiming(); - } - - void prepare(int what) - { - if(what & kClearTree) - { - ryml_tree.clear(); - } - if(what & kClearTreeArena) - { - ryml_tree.clear_arena(); - } - if(what & kResetInPlace) - { - C4_ASSERT(in_place.size() == src.size()); - memcpy(in_place.data(), src.data(), src.size()); - } - } -}; - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - - -/** this is used by the benchmarks. - * - * @note We cannot declare the case as value-static as there is no guarantee - * that the allocator's lifetime starts before and ends after the case's - * lifetime. So use a pointer to control the lifetime. */ -static BmCase * C4_RESTRICT s_bm_case = nullptr; - - -int main(int argc, char** argv) -{ - BmCase fixture; - s_bm_case = &fixture; - s_bm_case->run(argc, argv); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -#define ONLY_FOR_JSON \ - if(!s_bm_case->is_json) { st.SkipWithError("not a json file"); return; } - -void rapidjson_ro(bm::State& st) -{ - const char *src = s_bm_case->src.data(); - for(auto _ : st) - { - ONLY_FOR_JSON; - rapidjson::Document doc; - doc.Parse(src); - } - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void rapidjson_rw(bm::State& st) -{ - char *src = s_bm_case->in_place.data(); - for(auto _ : st) - { - ONLY_FOR_JSON; - s_bm_case->prepare(st, kResetInPlace); - rapidjson::Document doc; - doc.ParseInsitu(src); - } - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void sajson_ro(bm::State& st) -{ - sajson::string src = {s_bm_case->src.data(), s_bm_case->src.size()}; - for(auto _ : st) - { - ONLY_FOR_JSON; - sajson::document document = sajson::parse(sajson::dynamic_allocation(), src); - } - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void sajson_rw(bm::State& st) -{ - sajson::mutable_string_view src = {s_bm_case->in_place.size(), s_bm_case->in_place.data()}; - for(auto _ : st) - { - ONLY_FOR_JSON; - s_bm_case->prepare(st, kResetInPlace); - sajson::document document = sajson::parse(sajson::dynamic_allocation(), src); - } - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void jsoncpp_ro(bm::State& st) -{ - const char *b = &s_bm_case->src.front(), *e = &s_bm_case->src.back(); - for(auto _ : st) - { - ONLY_FOR_JSON; - Json::Value root; - Json::Reader reader; - reader.parse(b, e, root); - } - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void nlohmann_json_ro(bm::State& st) -{ - const char* src = s_bm_case->src.data(); - for(auto _ : st) - { - ONLY_FOR_JSON; - auto root = nlohmann::json::parse(src); - } - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void yamlcpp_ro(bm::State& st) -{ - const char* src = s_bm_case->src.data(); - for(auto _ : st) - { - YAML::Node node = YAML::Load(src); - } - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void libyaml_ro(bm::State& st) -{ - c4::csubstr src = c4::to_csubstr(s_bm_case->src.data()); - for(auto _ : st) - { - c4::yml::LibyamlParser p; - c4::yml::Tree t; - p.parse(&t, src); - } - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void libyaml_ro_reuse(bm::State& st) -{ - c4::csubstr src = c4::to_csubstr(s_bm_case->src.data()); - for(auto _ : st) - { - c4::yml::LibyamlParser libyaml_parser; - s_bm_case->prepare(st, kClearTree|kClearTreeArena); - libyaml_parser.parse(&s_bm_case->libyaml_tree, src); - } - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void ryml_ro(bm::State& st) -{ - size_t sz = 0; - c4::csubstr src = c4::to_csubstr(s_bm_case->src); - for(auto _ : st) - { - ryml::Tree tree = ryml::parse(s_bm_case->filename, src); - sz = tree.size(); - } - st.SetItemsProcessed(st.iterations() * sz); - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void ryml_rw(bm::State& st) -{ - size_t sz = 0; - c4::substr src = c4::to_substr(s_bm_case->in_place); - for(auto _ : st) - { - s_bm_case->prepare(st, kResetInPlace); - ryml::Tree tree = ryml::parse(s_bm_case->filename, src); - sz = tree.size(); - } - st.SetItemsProcessed(st.iterations() * sz); - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void ryml_ro_reuse(bm::State& st) -{ - size_t sz = 0; - c4::csubstr src = c4::to_csubstr(s_bm_case->src); - for(auto _ : st) - { - s_bm_case->prepare(st, kClearTree|kClearTreeArena); - s_bm_case->ryml_parser.parse(s_bm_case->filename, src, &s_bm_case->ryml_tree); - sz = s_bm_case->ryml_tree.size(); - } - st.SetItemsProcessed(st.iterations() * sz); - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -void ryml_rw_reuse(bm::State& st) -{ - size_t sz = 0; - c4::substr src = c4::to_substr(s_bm_case->in_place); - for(auto _ : st) - { - s_bm_case->prepare(st, kResetInPlace|kClearTree|kClearTreeArena); - s_bm_case->ryml_parser.parse(s_bm_case->filename, src, &s_bm_case->ryml_tree); - sz = s_bm_case->ryml_tree.size(); - } - st.SetItemsProcessed(st.iterations() * sz); - st.SetBytesProcessed(st.iterations() * s_bm_case->src.size()); -} - -BENCHMARK(rapidjson_ro); -BENCHMARK(rapidjson_rw); -BENCHMARK(sajson_rw); -BENCHMARK(sajson_ro); -BENCHMARK(jsoncpp_ro); -BENCHMARK(nlohmann_json_ro); -BENCHMARK(yamlcpp_ro); -BENCHMARK(libyaml_ro); -BENCHMARK(libyaml_ro_reuse); -BENCHMARK(ryml_ro); -BENCHMARK(ryml_rw); -BENCHMARK(ryml_ro_reuse); -BENCHMARK(ryml_rw_reuse); - -#if defined(_MSC_VER) -# pragma warning(pop) -#elif defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif diff --git a/third_party/rapidyaml/rapidyaml/bm/cases/appveyor.yml b/third_party/rapidyaml/rapidyaml/bm/cases/appveyor.yml deleted file mode 100644 index 1377ae0da..000000000 --- a/third_party/rapidyaml/rapidyaml/bm/cases/appveyor.yml +++ /dev/null @@ -1,90 +0,0 @@ -version: '{build}' - -image: Visual Studio 2017 - -environment: - matrix: - - - compiler: msvc-15-seh - generator: "Visual Studio 15 2017" - configuration: Debug - - - compiler: msvc-15-seh - generator: "Visual Studio 15 2017 Win64" - configuration: Debug - - - compiler: msvc-15-seh - generator: "Visual Studio 15 2017" - configuration: Release - - - compiler: msvc-15-seh - generator: "Visual Studio 15 2017 Win64" - configuration: Release - - - - compiler: msvc-14-seh - generator: "Visual Studio 14 2015" - configuration: Debug - - - compiler: msvc-14-seh - generator: "Visual Studio 14 2015 Win64" - configuration: Debug - - - compiler: msvc-14-seh - generator: "Visual Studio 14 2015" - configuration: Release - - - compiler: msvc-14-seh - generator: "Visual Studio 14 2015 Win64" - configuration: Release - - - - #- compiler: gcc-5.3.0-posix - # generator: "MinGW Makefiles" - # cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin' - # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - # configuration: Quicktest - # externconfig: Debug - # cmkargs: "-DC4STL_PEDANTIC=ON -DC4STL_WERROR=ON" - -matrix: - fast_finish: true - -install: - - git submodule update --init --recursive - # git bash conflicts with MinGW makefiles - - if "%generator%"=="MinGW Makefiles" (set "PATH=%PATH:C:\Program Files\Git\usr\bin;=%") - - if not "%cxx_path%"=="" (set "PATH=%PATH%;%cxx_path%") - -build_script: - - md _build -Force - - cd _build - -test_script: - - echo %configuration% - - cmake -G "%generator%" "-DCMAKE_BUILD_TYPE=%configuration%" -DRYML_DEV=ON .. - - dir - - dir test - - cmake --build . --config %configuration% --target ryml-test - #- ctest -c %configuration% --timeout 300 --output-on-failure - -artifacts: - - path: '_build/CMakeFiles/*.log' - name: logs - - path: '_build/Testing/**/*.xml' - name: test_results - -skip_commits: - files: - - .gitignore - - .travis* - - .ci/travis* - - .ci/dev_* - - .ci/show_* - - .ci/vagrant* - - .ci/Vagrant* - - bm/html/* - - doc/* - - LICENSE.txt - - README.* diff --git a/third_party/rapidyaml/rapidyaml/bm/cases/travis.yml b/third_party/rapidyaml/rapidyaml/bm/cases/travis.yml deleted file mode 100644 index 34933e6b8..000000000 --- a/third_party/rapidyaml/rapidyaml/bm/cases/travis.yml +++ /dev/null @@ -1,107 +0,0 @@ -sudo: required -dist: trusty -language: cpp -addons: - apt: - sources: - - ubuntu-toolchain-r-test -# - llvm-toolchain-trusty - -# we're not using combination parameters here to ensure that the builds -# run in the order we want. (We want to perform the fastest tests first so -# failed tests appear as early as possible). -env: - global: - - PATH=/usr/local/bin:$PATH - -# NOTE: The compiler setting is unused. It simply makes the display on -# travis-ci.org more readable. -# WARNING: do not use the name CXX. Travis will ignore the value here. -matrix: - - include: - # - # ----------- Coverage (covers all tests, slow) ------------------------- - # - - env: CXX_=g++-7 A=64 BT=Coverage - - env: CXX_=g++-7 A=32 BT=Coverage - # - # ----------- other tests ----------------------------------------------- - # - #- env: CXX_=clang++-7 A=32 BT=Debug SAN=ALL VG=ON - #- env: CXX_=clang++-7 A=64 BT=Debug SAN=ALL VG=ON - #- env: CXX_=clang++-7 A=32 BT=Release SAN=ALL VG=ON - #- env: CXX_=clang++-7 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=g++-7 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=g++-7 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=g++-7 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=g++-7 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=clang++-6.0 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-6.0 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-6.0 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=clang++-6.0 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=clang++-5.0 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-5.0 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-5.0 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=clang++-5.0 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=clang++-4.0 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-4.0 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-4.0 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=clang++-4.0 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=clang++-3.9 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-3.9 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-3.9 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=clang++-3.9 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=g++-6 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=g++-6 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=g++-6 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=g++-6 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=clang++-3.8 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-3.8 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-3.8 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=clang++-3.8 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=g++-5 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=g++-5 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=g++-5 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=g++-5 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=clang++-3.7 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-3.7 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-3.7 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=clang++-3.7 A=64 BT=Release SAN=ALL VG=ON - - #- env: CXX_=g++-4.9 A=32 BT=Debug SAN=ALL VG=ON - #- env: CXX_=g++-4.9 A=64 BT=Debug SAN=ALL VG=ON - #- env: CXX_=g++-4.9 A=32 BT=Release SAN=ALL VG=ON - #- env: CXX_=g++-4.9 A=64 BT=Release SAN=ALL VG=ON - - - env: CXX_=clang++-3.6 A=32 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-3.6 A=64 BT=Debug SAN=ALL VG=ON - - env: CXX_=clang++-3.6 A=32 BT=Release SAN=ALL VG=ON - - env: CXX_=clang++-3.6 A=64 BT=Release SAN=ALL VG=ON - - # ----------- clang-tidy - # - - env: CXX_=clang++-6.0 A=32 BT=Debug LINT=clang-tidy - - env: CXX_=clang++-6.0 A=64 BT=Debug LINT=clang-tidy - - env: CXX_=clang++-6.0 A=32 BT=Release LINT=clang-tidy - - env: CXX_=clang++-6.0 A=64 BT=Release LINT=clang-tidy - # - -install: - - bash -x .ci/travis-install.sh - -script: - - bash -x .ci/travis-test.sh - -after_success: - - echo "Success!" - - bash -x .ci/travis-coverage.sh diff --git a/third_party/rapidyaml/rapidyaml/bm/results/parse.linux.i7_6800K.md b/third_party/rapidyaml/rapidyaml/bm/results/parse.linux.i7_6800K.md deleted file mode 100644 index 238fee0d6..000000000 --- a/third_party/rapidyaml/rapidyaml/bm/results/parse.linux.i7_6800K.md +++ /dev/null @@ -1,90 +0,0 @@ - -## CPU info -``` -i7-6800K CPU @ 3.40GHz -CPU Caches: - L1 Data 32K (x6) - L1 Instruction 32K (x6) - L2 Unified 256K (x6) - L3 Unified 15360K (x1) -Load Average: 0.99, 0.49, 0.29 -``` - - -## JSON file (linux) - -``` ----------------------------------------------------------------------------------------------------- -Case Benchmark Compilation Time CPU Iterations UserCounters... ----------------------------------------------------------------------------------------------------- -json yamlcpp clangxx7.0-Release 2951978 ns 2949570 ns 237 bytes_per_second=15.1398M/s -json ryml_ro clangxx7.0-Release 132882 ns 132821 ns 5273 bytes_per_second=336.21M/s items_per_second=2.17586M/s -json ryml_rw clangxx7.0-Release 132670 ns 132613 ns 5303 bytes_per_second=336.738M/s items_per_second=2.17928M/s -json ryml_ro_reuse clangxx7.0-Release 115183 ns 115123 ns 6215 bytes_per_second=387.898M/s items_per_second=2.51037M/s -json ryml_rw_reuse clangxx7.0-Release 98509 ns 98464 ns 7098 bytes_per_second=453.526M/s items_per_second=2.9351M/s ----------------------------------------------------------------------------------------------------- -json yamlcpp gxx8.2-Release 2744383 ns 2741505 ns 259 bytes_per_second=16.2888M/s -json ryml_ro gxx8.2-Release 115434 ns 115369 ns 5912 bytes_per_second=387.068M/s items_per_second=2.505M/s -json ryml_rw gxx8.2-Release 114051 ns 113990 ns 6056 bytes_per_second=391.752M/s items_per_second=2.53531M/s -json ryml_ro_reuse gxx8.2-Release 105970 ns 105914 ns 6596 bytes_per_second=421.625M/s items_per_second=2.72864M/s -json ryml_rw_reuse gxx8.2-Release 103779 ns 103732 ns 6742 bytes_per_second=430.494M/s items_per_second=2.78604M/s ----------------------------------------------------------------------------------------------------- -json yamlcpp clangxx7.0-Debug 27435004 ns 27415168 ns 26 bytes_per_second=1.62887M/s -json ryml_ro clangxx7.0-Debug 1655051 ns 1653997 ns 424 bytes_per_second=26.9987M/s items_per_second=174.728k/s -json ryml_rw clangxx7.0-Debug 1649918 ns 1648922 ns 424 bytes_per_second=27.0818M/s items_per_second=175.266k/s -json ryml_ro_reuse clangxx7.0-Debug 724446 ns 724002 ns 961 bytes_per_second=61.6791M/s items_per_second=399.17k/s -json ryml_rw_reuse clangxx7.0-Debug 721836 ns 721423 ns 970 bytes_per_second=61.8996M/s items_per_second=400.597k/s ----------------------------------------------------------------------------------------------------- -json yamlcpp gxx8.2-Debug 29133193 ns 29113788 ns 24 bytes_per_second=1.53384M/s -json ryml_ro gxx8.2-Debug 1199038 ns 1198311 ns 578 bytes_per_second=37.2656M/s items_per_second=241.173k/s -json ryml_rw gxx8.2-Debug 1194125 ns 1193474 ns 585 bytes_per_second=37.4166M/s items_per_second=242.15k/s -json ryml_ro_reuse gxx8.2-Debug 613111 ns 612730 ns 1130 bytes_per_second=72.8801M/s items_per_second=471.66k/s -json ryml_rw_reuse gxx8.2-Debug 615212 ns 614905 ns 1124 bytes_per_second=72.6223M/s items_per_second=469.991k/s -``` - - -## YAML file (linux) - -``` ----------------------------------------------------------------------------------------------------- -Case Benchmark Compilation Time CPU Iterations UserCounters... ----------------------------------------------------------------------------------------------------- -travis yamlcpp clangxx7.0-Release 480382 ns 480037 ns 1460 bytes_per_second=8.07978M/s -travis ryml_ro clangxx7.0-Release 34300 ns 34285 ns 20435 bytes_per_second=113.127M/s items_per_second=3.2667M/s -travis ryml_rw clangxx7.0-Release 34299 ns 34282 ns 20559 bytes_per_second=113.136M/s items_per_second=3.26698M/s -travis ryml_ro_reuse clangxx7.0-Release 29431 ns 29419 ns 23805 bytes_per_second=131.838M/s items_per_second=3.80702M/s -travis ryml_rw_reuse clangxx7.0-Release 29490 ns 29478 ns 23849 bytes_per_second=131.577M/s items_per_second=3.79948M/s ----------------------------------------------------------------------------------------------------- -travis yamlcpp gxx8.2-Release 471533 ns 471181 ns 1447 bytes_per_second=8.23164M/s -travis ryml_ro gxx8.2-Release 25020 ns 25009 ns 27616 bytes_per_second=155.086M/s items_per_second=4.47835M/s -travis ryml_rw gxx8.2-Release 24851 ns 24839 ns 27953 bytes_per_second=156.151M/s items_per_second=4.50908M/s -travis ryml_ro_reuse gxx8.2-Release 22101 ns 22092 ns 31662 bytes_per_second=175.569M/s items_per_second=5.0698M/s -travis ryml_rw_reuse gxx8.2-Release 21995 ns 21986 ns 31771 bytes_per_second=176.413M/s items_per_second=5.09417M/s ----------------------------------------------------------------------------------------------------- -travis yamlcpp clangxx7.0-Debug 3687829 ns 3684240 ns 190 bytes_per_second=1078.02k/s -travis ryml_ro clangxx7.0-Debug 470504 ns 470249 ns 1492 bytes_per_second=8.24795M/s items_per_second=238.171k/s -travis ryml_rw clangxx7.0-Debug 468722 ns 468495 ns 1494 bytes_per_second=8.27884M/s items_per_second=239.063k/s -travis ryml_ro_reuse clangxx7.0-Debug 383510 ns 383335 ns 1826 bytes_per_second=10.118M/s items_per_second=292.172k/s -travis ryml_rw_reuse clangxx7.0-Debug 382344 ns 382179 ns 1820 bytes_per_second=10.1486M/s items_per_second=293.057k/s ----------------------------------------------------------------------------------------------------- -travis yamlcpp gxx8.2-Debug 3917888 ns 3913856 ns 180 bytes_per_second=1014.77k/s -travis ryml_ro gxx8.2-Debug 367717 ns 367522 ns 1904 bytes_per_second=10.5534M/s items_per_second=304.743k/s -travis ryml_rw gxx8.2-Debug 367291 ns 367101 ns 1908 bytes_per_second=10.5655M/s items_per_second=305.093k/s -travis ryml_ro_reuse gxx8.2-Debug 311178 ns 311031 ns 2251 bytes_per_second=12.4701M/s items_per_second=360.093k/s -travis ryml_rw_reuse gxx8.2-Debug 311510 ns 311362 ns 2248 bytes_per_second=12.4569M/s items_per_second=359.71k/s ----------------------------------------------------------------------------------------------------- -``` - - -## YAML file (windows) - -``` ----------------------------------------------------------------------------------------------------- -Case Benchmark Compilation Time CPU Iterations UserCounters... ----------------------------------------------------------------------------------------------------- -appveyor yamlcpp vs2017-Debug 25423992 ns 25669643 ns 28 bytes_per_second=84.4185k/s -appveyor ryml_rw_reuse vs2017-Debug 328672 ns 329641 ns 2133 bytes_per_second=6.41971M/s items_per_second=218.419k/s -appveyor yamlcpp vs2017-Release 394764 ns 399013 ns 1723 bytes_per_second=5.30359M/s -appveyor ryml_rw_reuse vs2017-Release 20737 ns 20856 ns 34462 bytes_per_second=101.466M/s items_per_second=3.45219M/s ----------------------------------------------------------------------------------------------------- -``` diff --git a/third_party/rapidyaml/rapidyaml/changelog/0.1.0.md b/third_party/rapidyaml/rapidyaml/changelog/0.1.0.md deleted file mode 100644 index b2ea04861..000000000 --- a/third_party/rapidyaml/rapidyaml/changelog/0.1.0.md +++ /dev/null @@ -1,44 +0,0 @@ -This is the first ryml release. Future releases will have a more organized changelog; for now, only recent major changes are listed. - -Please be aware that there are still some anticipated breaking changes in the API before releasing the 1.0 major version. These are highlighted in [the repo ROADMAP](https://github.com/biojppm/rapidyaml/blob/v0.1.0/ROADMAP.md). - -* 2020/October - * [MR#89](https://github.com/biojppm/rapidyaml/pull/89): - * fix python API generation in windows - * use github actions for testing and releasing - * [MR#88](https://github.com/biojppm/rapidyaml/pull/88): [fix MacOS compilation and installs](https://github.com/biojppm/rapidyaml/issues/75). This is a fix from [c4core](https://github.com/biojppm/cmake/issues/1). - * [MR#88](https://github.com/biojppm/rapidyaml/pull/88): [fix boolean handling](https://github.com/biojppm/rapidyaml/issues/74). This is a fix from [c4core](https://github.com/biojppm/c4core/pull/18/). `true` and `false` are now parsed correctly into `bool` variables: - ```c++ - auto tree = parse("{foo: true, bar: false}"); - ``` - Emitting `bool` variables still defaults to `0`/`1`, like the default behaviour in the STL. To explicitly request `true`/`false` use `c4::fmt::boolalpha()`: - ```c++ - node << var; // "1" or "0" - node << c4::fmt::boolalpha(var); // "true" or "false" - ``` -* 2020/September - * [***Breaking change***] [MR#85](https://github.com/biojppm/rapidyaml/pull/85) null values in YAML are now parsed to null strings instead of YAML null token "~": - ```c++ - auto tree = parse("{foo: , bar: ''}"); - // previous: - assert(tree["foo"].val() == "~"); - assert(tree["bar"].val() == ""); - // now: - assert(tree["foo"].val() == nullptr); // notice that this is now null - assert(tree["bar"].val() == ""); - ``` - * [MR#85](https://github.com/biojppm/rapidyaml/pull/85) Commas after tags are now allowed: - ```yaml - {foo: !!str, bar: ''} # now the comma does not cause an error - ``` - * [MR#81](https://github.com/biojppm/rapidyaml/pull/81): Always compile with extra pedantic warnings. -* 2020/May - * [***Breaking change***] the error callback now receives a source location object: - ```c++ - // previous - using pfn_error = void (*)(const char* msg, size_t msg_len, void *user_data); - // now: - using pfn_error = void (*)(const char* msg, size_t msg_len, Location location, void *user_data); - ``` - * Parser fixes to improve test suite success: [MR#73](https://github.com/biojppm/rapidyaml/pull/73), [MR#71](https://github.com/biojppm/rapidyaml/pull/71), [MR#68](https://github.com/biojppm/rapidyaml/pull/68), [MR#67](https://github.com/biojppm/rapidyaml/pull/67), [MR#66](https://github.com/biojppm/rapidyaml/pull/66) - * Fix compilation as DLL on windows [MR#69](https://github.com/biojppm/rapidyaml/pull/69) diff --git a/third_party/rapidyaml/rapidyaml/examples/add_subdirectory/CMakeLists.txt b/third_party/rapidyaml/rapidyaml/examples/add_subdirectory/CMakeLists.txt deleted file mode 100644 index 1509f4641..000000000 --- a/third_party/rapidyaml/rapidyaml/examples/add_subdirectory/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 3.12) -project(ryml-consumer LANGUAGES CXX) - -set(CMAKE_CXX_STANDARD 17) - -add_subdirectory(../../ foobar-ryml) - -include(./check.cmake) # run some checks (used in CI tests) - -add_executable(ryml-consumer main.cpp) -target_link_libraries(ryml-consumer ryml) -add_custom_command(TARGET ryml-consumer POST_BUILD - COMMAND $ - COMMENT "running test: $") diff --git a/third_party/rapidyaml/rapidyaml/examples/add_subdirectory/check.cmake b/third_party/rapidyaml/rapidyaml/examples/add_subdirectory/check.cmake deleted file mode 100644 index a3f477370..000000000 --- a/third_party/rapidyaml/rapidyaml/examples/add_subdirectory/check.cmake +++ /dev/null @@ -1,10 +0,0 @@ -if(NOT TARGET ryml) - message(FATAL_ERROR "could not find target ryml") -endif() -if(NOT CMAKE_CXX_STANDARD EQUAL 17) - message(FATAL_ERROR "CXX standard was changed by ryml") -endif() -get_target_property(ryml_cxx_std ryml CXX_STANDARD) -if(NOT ryml_cxx_std EQUAL 17) - message(FATAL_ERROR "ryml did not inherit the cxx standard: expected 17, got ${ryml_cxx_std}") -endif() diff --git a/third_party/rapidyaml/rapidyaml/examples/add_subdirectory/main.cpp b/third_party/rapidyaml/rapidyaml/examples/add_subdirectory/main.cpp deleted file mode 100644 index bcaf6cb68..000000000 --- a/third_party/rapidyaml/rapidyaml/examples/add_subdirectory/main.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include -#include - -#if C4_CPP < 17 -#error "must be C++17" -#endif - - -template -void err(c4::csubstr fmt, Args const& ...args) -{ - throw std::runtime_error(c4::formatrs(fmt, args...)); -} - - -void check(ryml::Tree const& t, c4::csubstr key, c4::csubstr expected) -{ - c4::csubstr actual = t[key].val(); - if(actual != expected) - { - err("expected t[{}]='{}', got '{}'", key, expected, actual); - } -} - - -int main() -{ - auto tree = ryml::parse("{foo: 0, bar: 1}"); - check(tree, "foo", "0"); - check(tree, "bar", "1"); - return 0; -} diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/.old/log.hpp b/third_party/rapidyaml/rapidyaml/ext/c4core/.github/.old/log.hpp deleted file mode 100644 index 278cf91b9..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/.old/log.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _C4_LOG_HPP_ -#define _C4_LOG_HPP_ - -// FIXME - these are just dumb placeholders -#define C4_LOGF_ERR(...) fprintf(stderr, __VA_ARGS__) -#define C4_LOGF_WARN(...) fprintf(stderr, __VA_ARGS__) -#define C4_LOGP(msg, ...) printf(msg) - -#endif /* _C4_LOG_HPP_ */ diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/.old/util.hpp b/third_party/rapidyaml/rapidyaml/ext/c4core/.github/.old/util.hpp deleted file mode 100644 index dbb328d94..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/.old/util.hpp +++ /dev/null @@ -1,4091 +0,0 @@ -#ifndef _C4_UTIL_HPP_ -#define _C4_UTIL_HPP_ - -//------------------------------------------------------------ -//------------------------------------------------------------ -//------------------------------------------------------------ -// CONFIG - -//#define C4_DEBUG -//#define C4_USE_XASSERT -//#define C4_NO_ALLOC_DEFAULTS -//#define C4_REDEFINE_CPPNEW -//#define C4_LOG_THREAD_SAFE -#ifndef C4_LOG_MAX_CHANNELS -# define C4_LOG_MAX_CHANNELS 32 -#endif -#ifndef C4_LOG_BUFFER_INITIAL_SIZE -# define C4_LOG_BUFFER_INITIAL_SIZE 128 -#endif -#ifndef C4_LOG_BUFFER_REF_SIZE -# define C4_LOG_BUFFER_REF_SIZE 256 -#endif - -//------------------------------------------------------------ -//------------------------------------------------------------ -//------------------------------------------------------------ -// INCLUDES - -#include -#include // put uint32_t et al into the :: namespace -#include -#include -#include - -#include -#include -#include - -#include - -#include "c4/preprocessor.hpp" -#include "c4/platform.hpp" -#include "c4/cpu.hpp" - -#include "c4/windows.hpp" - -#if !defined(C4_WIN) && !defined(C4_POSIX) -# include -#elif defined(C4_POSIX) -# include -#endif - -#ifdef C4_LOG_THREAD_SAFE -# include -# include -#endif - -#if !defined(C4_NO_ALLOC_DEFAULTS) && defined(C4_POSIX) -# include -#endif - -#include - -#include "c4/language.hpp" - - -//------------------------------------------------------------ -//------------------------------------------------------------ -//------------------------------------------------------------ -// error reporting - -#define C4_STATIC_ASSERT(cond) static_assert(cond, "static assert failed") -#define C4_STATIC_ASSERT_MSG(cond, msg) static_assert(cond, msg) - -C4_BEGIN_NAMESPACE(c4) - -using error_callback_type = void (*)(); - -/** Defaults to abort() */ -inline error_callback_type& get_error_callback() -{ - static error_callback_type cb = &::abort; - return cb; -} -/** Set the function which is called when an error occurs. */ -inline void set_error_callback(error_callback_type cb) -{ - get_error_callback() = cb; -} - -void report_error(const char *file, int line, const char *func, const char *fmt, ...); -C4_END_NAMESPACE(c4) - -/** Raise an error, and report a printf-formatted message. - * If an error callback was set, it will be called. - * @see set_error_callback() */ -#define C4_ERROR(msg, ...) \ - c4::report_error(__FILE__, __LINE__, C4_PRETTY_FUNC, msg, ## __VA_ARGS__) - -/** Report a warning with a printf-formatted message. */ -#define C4_WARNING(msg, ...) \ - { \ - C4_LOG_WARN("\n%s:%d: WARNING: " msg \ - "\n%s:%d: WARNING: %s\n", \ - __FILE__, __LINE__, ## __VA_ARGS__, \ - __FILE__, __LINE__, C4_PRETTY_FUNC); \ - } - -// error checking - always turned on -/** Check that a condition is true, or raise an error when not true. */ -#define C4_CHECK(cond) \ - if(C4_UNLIKELY(!(cond))) \ - { \ - C4_ERROR("check failed: " #cond); \ - } - -/** like C4_CHECK(), and additionally log a printf-style message. - * @see C4_CHECK */ -#define C4_CHECK_MSG(cond, fmt, ...) \ - if(C4_UNLIKELY(!(cond))) \ - { \ - C4_ERROR("check failed: " #cond "\n" fmt, ## __VA_ARGS__); \ - } - -// assertions - only in debug builds -#ifdef NDEBUG // turn off assertions -# define C4_ASSERT(cond) -# define C4_ASSERT_MSG(cond, fmt, ...) -#else -# define C4_ASSERT(cond) C4_CHECK(cond) -# define C4_ASSERT_MSG(cond, fmt, ...) C4_CHECK_MSG(cond, fmt, ## __VA_ARGS__) -#endif - -// Extreme assertion: can be switched off independently of the regular assertion. -// Use eg for bounds checking in hot code. -#ifdef C4_USE_XASSERT -# define C4_XASSERT(cond) C4_CHECK(cond) -# define C4_XASSERT_MSG(cond, fmt, ...) C4_CHECK_MSG(cond, fmt, ## __VA_ARGS__) -#else -# define C4_XASSERT(cond) -# define C4_XASSERT_MSG(cond, fmt, ...) -#endif - -// Common error conditions -#define C4_NOT_IMPLEMENTED() C4_ERROR("NOT IMPLEMENTED") -#define C4_NOT_IMPLEMENTED_MSG(msg, ...) C4_ERROR("NOT IMPLEMENTED: " msg, ## __VA_ARGS__) - -#define C4_NEVER_REACH() C4_UNREACHABLE(); C4_ERROR("never reach this point") -#define C4_NEVER_REACH_MSG(msg, ...) C4_UNREACHABLE(); C4_ERROR("never reach this point: " msg, ## __VA_ARGS__) - -//------------------------------------------------------------ -//------------------------------------------------------------ -//------------------------------------------------------------ -// TIMING - -C4_BEGIN_NAMESPACE(c4) - -/** converts automatically from/to microseconds. */ -class Time -{ -public: - - C4_ALWAYS_INLINE Time() : m_microsecs(0) {} - C4_ALWAYS_INLINE Time(double microsecs) : m_microsecs(microsecs) {} - - C4_ALWAYS_INLINE operator double () const { return m_microsecs; } - - C4_ALWAYS_INLINE void operator= (double t) { m_microsecs = t; } - - C4_ALWAYS_INLINE void m(double minutes) { m_microsecs = minutes * 60.e6; } - C4_ALWAYS_INLINE double m() const { return m_microsecs / 60.e6; } - - C4_ALWAYS_INLINE void s(double seconds) { m_microsecs = seconds * 1.e6; } - C4_ALWAYS_INLINE double s() const { return m_microsecs * 1.e-6; } - - C4_ALWAYS_INLINE void ms(double miliseconds) { m_microsecs = miliseconds * 1.e3; } - C4_ALWAYS_INLINE double ms() const { return m_microsecs * 1.e-3; } - - C4_ALWAYS_INLINE void us(double microseconds) { m_microsecs = microseconds; } - C4_ALWAYS_INLINE double us() const { return m_microsecs; } - - C4_ALWAYS_INLINE void ns(double nanoseconds) { m_microsecs = nanoseconds * 1.e-3; } - C4_ALWAYS_INLINE double ns() const { return m_microsecs * 1.e3; } - -private: - - double m_microsecs; - -}; - -C4_BEGIN_NAMESPACE(time_suffixes) -Time operator"" _s(long double seconds) { Time t; t.s((double)seconds); return t; } -Time operator"" _ms(long double milliseconds) { Time t; t.ms((double)milliseconds); return t; } -Time operator"" _us(long double microseconds) { Time t; t.us((double)microseconds); return t; } -Time operator"" _ns(long double nanoseconds) { Time t; t.ns((double)nanoseconds); return t; } -C4_END_NAMESPACE(time_suffixes) - -/** a general-use time stamp in microseconds (usecs). - * Although this is timed precisely, there may be some issues. - * Eg, concurrent or heavy use may cause penalties. - * @see https://www.strchr.com/performance_measurements_with_rdtsc - * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ee417693(v=vs.85).aspx */ -inline double currtime() -{ -#ifdef C4_WIN - static bool gotfreq = false; - static double ifreq = 0.; - if(C4_UNLIKELY(!gotfreq)) - { - static LARGE_INTEGER freq = {}; - QueryPerformanceFrequency(&freq); - ifreq = 1.e9 / double(freq.QuadPart); - gotfreq = true; - } - LARGE_INTEGER ts; - QueryPerformanceCounter(&ts); - double usecs = ts.QuadPart * ifreq; - return usecs; -#elif defined(C4_POSIX) - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC_RAW, &ts); - double usecs = 1.e6 * double(ts.tv_sec) + 1.e-3 * double(ts.tv_nsec); - return usecs; -#else - std::chrono::time_point< hrc_type, usec_type > tp = std::chrono::high_resolution_clock::now(); - double nsecs = tp.time_since_epoch().count(); - return 1.e-3 * nsecs; -#endif -} - -/** execution time */ -inline double exetime() -{ - static const double atstart = currtime(); - double now = currtime() - atstart; - return now; -} - -/** do a spin loop for at least the given time */ -inline void busy_wait(double microsecs) -{ - double start = currtime(); - while(currtime() - start < microsecs) - { - C4_KEEP_EMPTY_LOOP; - } -} - -C4_END_NAMESPACE(c4) - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// Some memory utilities. - -C4_BEGIN_NAMESPACE(c4) - -C4_ALWAYS_INLINE void zero_mem(void* mem, size_t num_bytes) -{ - ::memset(mem, 0, num_bytes); -} -template< class T > -C4_ALWAYS_INLINE void zero_mem(T* mem, size_t num_elms) -{ - ::memset(mem, 0, sizeof(T) * num_elms); -} -template< class T > -C4_ALWAYS_INLINE void zero_mem(T* mem) -{ - ::memset(mem, 0, sizeof(T)); -} - - -inline bool mem_overlaps(void const* a, void const* b, size_t sza, size_t szb) -{ - if(a < b) - { - if(size_t(a) + sza > size_t(b)) return true; - } - else if(a > b) - { - if(size_t(b) + szb > size_t(a)) return true; - } - else if(a == b) - { - if(sza != 0 && szb != 0) return true; - } - return false; -} - -/** Fills 'dest' with the first 'pattern_size' bytes at 'pattern', 'num_times'. */ -inline void mem_repeat(void* dest, void const* pattern, size_t pattern_size, size_t num_times) -{ - if(C4_UNLIKELY(num_times == 0)) return; - C4_ASSERT(!mem_overlaps(dest, pattern, num_times*pattern_size, pattern_size)); - char *begin = (char*)dest; - char *end = begin + num_times * pattern_size; - // copy the pattern once - ::memcpy(begin, pattern, pattern_size); - // now copy from dest to itself, doubling up every time - size_t n = pattern_size; - while(begin + 2*n < end) - { - ::memcpy(begin + n, begin, n); - n <<= 1; // double n - } - // copy the missing part - if(begin + n < end) - { - ::memcpy(begin + n, begin, end - (begin + n)); - } -} - -C4_END_NAMESPACE(c4) - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// some traits and type utility classes/macros. - -C4_BEGIN_NAMESPACE(c4) - -/** use this macro to enable a function overload based on a compile-time condition. -@code -// define an overload for a non-pod type -template< class T, C4_REQUIRE_R(std::is_pod< T >::value) > -void foo() { std::cout << "pod type\n"; } - -// define an overload for a non-pod type -template< class T, C4_REQUIRE_R(!std::is_pod< T >::value) > -void foo() { std::cout << "nonpod type\n"; } - -struct non_pod -{ - non_pod() : name("asdfkjhasdkjh") {} - const char *name; -}; - -int main() -{ - foo< float >(); // prints "pod type" - foo< non_pod >(); // prints "nonpod type" -} -@endcode */ -#define C4_REQUIRE_T(cond) typename std::enable_if< cond, bool >::type* = nullptr - -/** enable_if for a return type */ -#define C4_REQUIRE_R(cond, type_) typename std::enable_if< cond, type_ >::type - -//----------------------------------------------------------------------------- -/** declare a traits class telling whether a type provides a member typedef */ -#define C4_DEFINE_HAS_TYPEDEF(member_typedef) \ -template< typename T > \ -struct has_##stype \ -{ \ -private: \ - \ - typedef char yes; \ - typedef struct { char array[2]; } no; \ - \ - template< typename C > \ - static yes _test(typename C::member_typedef*); \ - \ - template< typename C > \ - static no _test(...); \ - \ -public: \ - \ - enum { value = (sizeof(_test< T >(0)) == sizeof(yes)) }; \ - \ -} - -//----------------------------------------------------------------------------- -/** declare a traits class telling whether a type provides a method */ -#define C4_DEFINE_HAS_METHOD(ret_type, method_name, const_qualifier, ...) \ -template< typename T > \ -struct has_##method_name##_method \ -{ \ -private: \ - \ - typedef char &yes; \ - typedef struct { char array[2]; } &no; \ - \ - template< typename C > \ - static yes _test \ - ( \ - C const_qualifier* v, \ - typename std::enable_if \ - < \ - std::is_same< decltype(v->method_name(__VA_ARGS__)), ret_type >::value \ - , \ - void /* this is defined only if the bool above is true. */ \ - /* so when it fails, SFINAE is triggered */ \ - > \ - ::type* \ - ); \ - \ - template< typename C > \ - static no _test(...); \ - \ -public: \ - \ - enum { value = (sizeof(_test< T >((typename std::remove_reference< T >::type*)0, 0)) == sizeof(yes)) }; \ - \ -}; - -//-------------------------------------------------- - -/** whether a value should be used in place of a const-reference in argument passing. */ -template< class T > -struct cref_uses_val -{ - enum { value = ( - std::is_scalar< T >::value - || - (std::is_pod< T >::value && sizeof(T) <= sizeof(size_t))) }; -}; -/** override the default behaviour for c4::fastcref< T > - @see fastcref */ -#define C4_CREF_USES_VAL(T) \ -template<> \ -struct cref_uses_val< T > \ -{ \ - enum { value = true }; \ -}; - -/** Whether to use pass-by-value or pass-by-const-reference in a function argument - * or return type. */ -template< class T > -using fastcref = typename std::conditional< c4::cref_uses_val< T >::value, T, T const& >::type; - -//-------------------------------------------------- - -/** Just what its name says. Useful sometimes as a default empty policy class. */ -struct EmptyStruct -{ - template< class... T > EmptyStruct(T && ...){} -}; - -/** Just what its name says. Useful sometimes as a default policy class to - * be inherited from. */ -struct EmptyStructVirtual -{ - virtual ~EmptyStructVirtual() = default; - template< class... T > EmptyStructVirtual(T && ...){} -}; - - -//-------------------------------------------------- -// Utilities to make a class obey size restrictions (eg, min size or size multiple of). -// DirectX usually makes this restriction with uniform buffers. -// This is also useful for padding to prevent false-sharing. - -/** force the following class to be tightly packed. - * @see http://stackoverflow.com/questions/21092415/force-c-structure-to-pack-tightly */ -#pragma pack(push, 1) -/** pad a class with more bytes at the end. */ -template< class T, size_t BytesToPadAtEnd > -struct Padded : public T -{ - using T::T; -public: - char ___c4padspace___[BytesToPadAtEnd]; -}; -#pragma pack(pop) -/** When the padding argument is 0, we cannot declare the char[] array. */ -template< class T > -struct Padded< T, 0 > : public T -{ - using T::T; -}; - -/** how many bytes must be added to size such that the result is at least minsize? */ -constexpr inline size_t min_remainder(size_t size, size_t minsize) -{ - return size < minsize ? minsize-size : 0; -} - -/** how many bytes must be added to size such that the result is a multiple of multipleOf? */ -constexpr inline size_t mult_remainder(size_t size, size_t multipleof) -{ - return (((size % multipleof) != 0) ? (multipleof-(size % multipleof)) : 0); -} - -/** make T have a size which is at least Min bytes */ -template< class T, size_t Min > -using MinSized = Padded< T, min_remainder(sizeof(T), Min) >; - -/** make T have a size which is a multiple of Mult bytes */ -template< class T, size_t Mult > -using MultSized = Padded< T, mult_remainder(sizeof(T), Mult) >; - -/** make T have a size which is simultaneously: - * -bigger or equal than Min - * -a multiple of Mult */ -template< class T, size_t Min, size_t Mult > -using MinMultSized = MultSized< MinSized< T, Min >, Mult >; - -/** make T be suitable for use as a uniform buffer. (at least with DirectX). */ -template< class T > -using UbufSized = MinMultSized< T, 64, 16 >; - -//----------------------------------------------------------------------------- -// construct - -#define _C4REQUIRE(cond) \ -C4_ALWAYS_INLINE typename std::enable_if< cond, void >::type - - -/** default-construct an object, trivial version */ -template< class U > _C4REQUIRE(std::is_trivially_default_constructible< U >::value) -construct(U* ptr) noexcept -{ - memset(ptr, 0, sizeof(U)); -} -/** default-construct an object, non-trivial version */ -template< class U > _C4REQUIRE( ! std::is_trivially_default_constructible< U >::value) -construct(U* ptr) noexcept -{ - new (ptr) U(); -} - -/** default-construct n objects, trivial version */ -template< class U, class I > _C4REQUIRE(std::is_trivially_default_constructible< U >::value) -construct_n(U* ptr, I n) noexcept -{ - memset(ptr, 0, n * sizeof(U)); -} -/** default-construct n objects, non-trivial version */ -template< class U, class I > _C4REQUIRE( ! std::is_trivially_default_constructible< U >::value) -construct_n(U* ptr, I n) noexcept -{ - for(I i = 0; i < n; ++i) - { - new (ptr+i) U(); - } -} - -template< class U, class ...Args > -inline void construct(U* ptr, Args&&... args) -{ - new ((void*)ptr) U(std::forward< Args >(args)...); -} -template< class U, class I, class ...Args > -inline void construct_n(U* ptr, I n, Args&&... args) -{ - for(I i = 0; i < n; ++i) - { - new ((void*)(ptr + i)) U(std::forward< Args >(args)...); - } -} - -//----------------------------------------------------------------------------- -// copy-construct - -template< class U > _C4REQUIRE(std::is_trivially_copy_constructible< U >::value) -copy_construct(U* dst, U const* src) noexcept -{ - memcpy(dst, src, sizeof(U)); -} -template< class U > _C4REQUIRE( ! std::is_trivially_copy_constructible< U >::value) -copy_construct(U* dst, U const* src) -{ - new (dst) U(*src); -} -template< class U, class I > _C4REQUIRE(std::is_trivially_copy_constructible< U >::value) -copy_construct_n(U* dst, U const* src, I n) noexcept -{ - memcpy(dst, src, n * sizeof(U)); -} -template< class U, class I > _C4REQUIRE( ! std::is_trivially_copy_constructible< U >::value) -copy_construct_n(U* dst, U const* src, I n) -{ - for(I i = 0; i < n; ++i) - { - new (dst + i) U(*(src + i)); - } -} - -template< class U > _C4REQUIRE(std::is_scalar< U >::value) -copy_construct(U* dst, U src) noexcept // pass by value for scalar types -{ - *dst = src; -} -template< class U > _C4REQUIRE( ! std::is_scalar< U >::value) -copy_construct(U* dst, U const& src) // pass by reference for non-scalar types -{ - new (dst) U(src); -} -template< class U, class I > _C4REQUIRE(std::is_scalar< U >::value) -copy_construct_n(U* dst, U src, I n) noexcept // pass by value for scalar types -{ - for(I i = 0; i < n; ++i) - { - dst[i] = src; - } -} -template< class U, class I > _C4REQUIRE( ! std::is_scalar< U >::value) -copy_construct_n(U* dst, U const& src, I n) // pass by reference for non-scalar types -{ - for(I i = 0; i < n; ++i) - { - new (dst + i) U(src); - } -} - -template< class U, size_t N > -C4_ALWAYS_INLINE void copy_construct(U (&dst)[N], U const (&src)[N]) noexcept -{ - copy_construct_n(dst, src, N); -} - -//----------------------------------------------------------------------------- -// copy-assign - -template< class U > _C4REQUIRE(std::is_trivially_copy_assignable< U >::value) -copy_assign(U* dst, U const* src) noexcept -{ - memcpy(dst, src, sizeof(U)); -} -template< class U > _C4REQUIRE( ! std::is_trivially_copy_assignable< U >::value) -copy_assign(U* dst, U const* src) noexcept -{ - *dst = *src; -} -template< class U, class I > _C4REQUIRE(std::is_trivially_copy_assignable< U >::value) -copy_assign_n(U* dst, U const* src, I n) noexcept -{ - memcpy(dst, src, n * sizeof(U)); -} -template< class U, class I > _C4REQUIRE( ! std::is_trivially_copy_assignable< U >::value) -copy_assign_n(U* dst, U const* src, I n) noexcept -{ - for(I i = 0; i < n; ++i) - { - dst[i] = src[i]; - } -} - -template< class U > _C4REQUIRE(std::is_scalar< U >::value) -copy_assign(U* dst, U src) noexcept // pass by value for scalar types -{ - *dst = src; -} -template< class U > _C4REQUIRE( ! std::is_scalar< U >::value) -copy_assign(U* dst, U const& src) noexcept // pass by reference for non-scalar types -{ - *dst = src; -} -template< class U, class I > _C4REQUIRE(std::is_scalar< U >::value) -copy_assign_n(U* dst, U src, I n) noexcept // pass by value for scalar types -{ - for(I i = 0; i < n; ++i) - { - dst[i] = src; - } -} -template< class U, class I > _C4REQUIRE( ! std::is_scalar< U >::value) -copy_assign_n(U* dst, U const& src, I n) noexcept // pass by reference for non-scalar types -{ - for(I i = 0; i < n; ++i) - { - dst[i] = src; - } -} - -template< class U, size_t N > -C4_ALWAYS_INLINE void copy_assign(U (&dst)[N], U const (&src)[N]) noexcept -{ - copy_assign_n(dst, src, N); -} - -//----------------------------------------------------------------------------- -// move-construct - -template< class U > _C4REQUIRE(std::is_trivially_move_constructible< U >::value) -move_construct(U* dst, U* src) noexcept -{ - memcpy(dst, src, sizeof(U)); -} -template< class U > _C4REQUIRE( ! std::is_trivially_move_constructible< U >::value) -move_construct(U* dst, U* src) noexcept -{ - new (dst) U(std::move(*src)); -} -template< class U, class I > _C4REQUIRE(std::is_trivially_move_constructible< U >::value) -move_construct_n(U* dst, U* src, I n) noexcept -{ - memcpy(dst, src, n * sizeof(U)); -} -template< class U, class I > _C4REQUIRE( ! std::is_trivially_move_constructible< U >::value) -move_construct_n(U* dst, U* src, I n) noexcept -{ - for(I i = 0; i < n; ++i) - { - new (dst + i) U(std::move(src[i])); - } -} - -//----------------------------------------------------------------------------- -// move-assign - -template< class U > _C4REQUIRE(std::is_trivially_move_assignable< U >::value) -move_assign(U* dst, U* src) noexcept -{ - memcpy(dst, src, sizeof(U)); -} -template< class U > _C4REQUIRE( ! std::is_trivially_move_assignable< U >::value) -move_assign(U* dst, U* src) noexcept -{ - *dst = std::move(*src); -} -template< class U, class I > _C4REQUIRE(std::is_trivially_move_assignable< U >::value) -move_assign_n(U* dst, U* src, I n) noexcept -{ - memcpy(dst, src, n * sizeof(U)); -} -template< class U, class I > _C4REQUIRE( ! std::is_trivially_move_assignable< U >::value) -move_assign_n(U* dst, U* src, I n) noexcept -{ - for(I i = 0; i < n; ++i) - { - *(dst + i) = std::move(*(src + i)); - } -} - -//----------------------------------------------------------------------------- -// destroy - -template< class U > _C4REQUIRE(std::is_trivially_destructible< U >::value) -destroy(U* ptr) noexcept -{ - C4_UNUSED(ptr); // nothing to do -} -template< class U > _C4REQUIRE( ! std::is_trivially_destructible< U >::value) -destroy(U* ptr) noexcept -{ - ptr->~U(); -} -template< class U, class I > _C4REQUIRE(std::is_trivially_destructible< U >::value) -destroy_n(U* ptr, I n) noexcept -{ - C4_UNUSED(ptr); - C4_UNUSED(n); // nothing to do -} -template< class U, class I > _C4REQUIRE( ! std::is_trivially_destructible< U >::value) -destroy_n(U* ptr, I n) noexcept -{ - for(I i = 0; i < n; ++i) - { - ptr[i].~U(); - } -} - -#undef _C4REQUIRE - -C4_END_NAMESPACE(c4) - - -//------------------------------------------------------------ -//------------------------------------------------------------ -//------------------------------------------------------------ -// MEMORY ALLOCATION - -C4_BEGIN_NAMESPACE(c4) - -// c-style allocation --------------------------------------------------------- - -// this API provides unaligned as well as aligned allocation functions. -// These functions forward the call to a modifiable function. - -// aligned allocation. Thread-safe. -void* aalloc(size_t sz, size_t alignment); -void afree(void* ptr); -void* arealloc(void* ptr, size_t oldsz, size_t newsz, size_t alignment); - -// classic, unaligned allocation. Thread-safe. -void* alloc(size_t sz); -void free(void* ptr); -void* realloc(void* ptr, size_t oldsz, size_t newsz); - -// allocation setup facilities -using aalloc_type = void* (*)(size_t size, size_t alignment); -using afree_type = void (*)(void *ptr); -using arealloc_type = void* (*)(void *ptr, size_t oldsz, size_t newsz, size_t alignment); - -using alloc_type = void* (*)(size_t size); -using free_type = void (*)(void *ptr); -using realloc_type = void* (*)(void *ptr, size_t oldsz, size_t newsz); - -// set the function to be called -void set_aalloc(aalloc_type fn); -void set_afree(afree_type fn); -void set_arealloc(arealloc_type fn); - -void set_alloc(alloc_type fn); -void set_free(free_type fn); -void set_realloc(realloc_type fn); - -// get the function which will be called -alloc_type get_alloc(); -free_type get_free(); -realloc_type get_realloc(); - -aalloc_type get_aalloc(); -free_type get_afree(); -arealloc_type get_arealloc(); - -// c++-style allocation ------------------------------------------------------- - -/** C++17-style memory_resource. See http://en.cppreference.com/w/cpp/experimental/memory_resource */ -struct MemoryResource -{ - const char *name = nullptr; - virtual ~MemoryResource() {} - - void* allocate(size_t sz, size_t alignment = alignof(max_align_t)) - { - void *mem = this->do_allocate(sz, alignment); - C4_CHECK_MSG(mem != nullptr, "could not allocate %lu bytes", sz); - return mem; - } - void* reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment = alignof(max_align_t)) - { - void *mem = this->do_reallocate(ptr, oldsz, newsz, alignment); - C4_CHECK_MSG(mem != nullptr, "could not reallocate from %lu to %lu bytes", oldsz, newsz); - return mem; - } - void deallocate(void* ptr, size_t sz, size_t alignment = alignof(max_align_t)) - { - this->do_deallocate(ptr, sz, alignment); - } - -protected: - - virtual void* do_allocate(size_t sz, size_t alignment) = 0; - virtual void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) = 0; - virtual void do_deallocate(void* ptr, size_t sz, size_t alignment) = 0; - -}; - -/** A c4::aalloc-based memory resource. Thread-safe if the implementation called by - * c4::aalloc() is safe. */ -struct MemoryResourceMalloc : public MemoryResource -{ - - MemoryResourceMalloc() { name = "malloc"; } - virtual ~MemoryResourceMalloc() {} - -protected: - - virtual void* do_allocate(size_t sz, size_t alignment) override - { - return c4::aalloc(sz, alignment); - } - - virtual void do_deallocate(void* ptr, size_t sz, size_t alignment) override - { - C4_UNUSED(sz); - C4_UNUSED(alignment); - c4::afree(ptr); - } - - virtual void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override - { - return c4::arealloc(ptr, oldsz, newsz, alignment); - } - -}; - - -C4_ALWAYS_INLINE MemoryResource* get_memory_resource_malloc() -{ - static MemoryResourceMalloc mr; - return &mr; -} - -C4_BEGIN_NAMESPACE(detail) -C4_ALWAYS_INLINE MemoryResource* & get_memory_resource() -{ - static MemoryResource* mr = get_memory_resource_malloc(); - return mr; -} -C4_END_NAMESPACE(detail) - -MemoryResource* get_memory_resource() -{ - return detail::get_memory_resource(); -} -void set_memory_resource(MemoryResource* mr) -{ - C4_ASSERT(mr != nullptr); - detail::get_memory_resource() = mr; -} - - -struct AllocationCounts -{ - size_t curr_allocs = 0; - size_t curr_size = 0; - size_t max_allocs = 0; - size_t max_size = 0; - size_t total_allocs = 0; - size_t sum_size = 0; - - void clear_counts() - { - zero_mem(this); - } - - void add_counts(void* ptr, size_t sz) - { - if(ptr == nullptr) return; - ++curr_allocs; - curr_size += sz; - max_allocs = curr_allocs > max_allocs ? curr_allocs : max_allocs; - max_size = curr_size > max_size ? curr_size : max_size; - ++total_allocs; - sum_size += sz; - } - void rem_counts(void *ptr, size_t sz) - { - if(ptr == nullptr) return; - --curr_allocs; - curr_size -= sz; - } - - AllocationCounts operator- (AllocationCounts const& that) - { - AllocationCounts r(*this); - r.curr_allocs -= that.curr_allocs; - r.curr_size -= that.curr_size; - r.max_allocs = max_allocs > that.max_allocs ? max_allocs : that.max_allocs; - r.max_size = max_size > that.max_size ? max_size : that.max_size; - r.total_allocs -= that.total_allocs; - r.sum_size -= that.sum_size; - return r; - } - AllocationCounts operator+ (AllocationCounts const& that) - { - AllocationCounts r(*this); - r.curr_allocs += that.curr_allocs; - r.curr_size += that.curr_size; - r.max_allocs += max_allocs > that.max_allocs ? max_allocs : that.max_allocs; - r.max_size += max_size > that.max_size ? max_size : that.max_size; - r.total_allocs += that.total_allocs; - r.sum_size += that.sum_size; - return r; - } - -}; - - -/** a MemoryResource which latches onto another MemoryResource - * and counts allocations and sizes. */ -class MemoryResourceCounts : public MemoryResource -{ -public: - - MemoryResourceCounts() : m_resource(get_memory_resource()) { name = m_resource->name; } - MemoryResourceCounts(MemoryResource *res) : m_resource(res) { name = m_resource->name; } - -protected: - - MemoryResource *m_resource; - -public: - - AllocationCounts counts; - -protected: - - virtual void* do_allocate(size_t sz, size_t alignment) override - { - void *ptr = m_resource->allocate(sz, alignment); - counts.add_counts(ptr, sz); - return ptr; - } - - virtual void do_deallocate(void* ptr, size_t sz, size_t alignment) override - { - counts.rem_counts(ptr, sz); - m_resource->deallocate(ptr, sz, alignment); - } - - virtual void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override - { - counts.rem_counts(ptr, oldsz); - void* nptr = m_resource->reallocate(ptr, oldsz, newsz, alignment); - counts.add_counts(nptr, newsz); - return nptr; - } - -}; - -struct AllocatorBase -{ -protected: - - MemoryResource *m_resource; - - AllocatorBase() : m_resource(get_memory_resource()) {} - AllocatorBase(MemoryResource* mem) noexcept : m_resource(mem) {} - -public: - - MemoryResource* resource() const { return m_resource; } - - /** for construct: - * @see http://en.cppreference.com/w/cpp/experimental/polymorphic_allocator/construct */ - -/** SFINAE: enable the function with a void return type when a condition is verified */ -#define _c4_void_if(cond) C4_ALWAYS_INLINE typename std::enable_if< cond, void >::type -/** @see http://en.cppreference.com/w/cpp/memory/uses_allocator */ -#define _c4_uses_allocator(U) std::uses_allocator< U, MemoryResource* >::value -/** @see http://en.cppreference.com/w/cpp/types/is_constructible */ -#define _c4_is_constructible(...) std::is_constructible< __VA_ARGS__ >::value - - // 1. types with no allocators - template< class U, class... Args > - _c4_void_if( ! _c4_uses_allocator(U) && _c4_is_constructible(U, Args...) ) - construct(U* ptr, Args&&... args) - { - c4::construct(ptr, std::forward< Args >(args)...); - } - template< class U, class I, class... Args > - _c4_void_if( ! _c4_uses_allocator(U) && _c4_is_constructible(U, Args...) ) - construct_n(U* ptr, I n, Args&&... args) - { - c4::construct_n(ptr, n, std::forward< Args >(args)...); - } - - // 2. types using allocators (ie, containers) - - // 2.1. can construct(std::allocator_arg_t, MemoryResource*, Args...) - template< class U, class... Args > - _c4_void_if(_c4_uses_allocator(U) && _c4_is_constructible(U, std::allocator_arg_t, MemoryResource*, Args...)) - construct(U* ptr, Args&&... args) - { - c4::construct(ptr, std::allocator_arg, m_resource, std::forward< Args >(args)...); - } - template< class U, class I, class... Args > - _c4_void_if(_c4_uses_allocator(U) && _c4_is_constructible(U, std::allocator_arg_t, MemoryResource*, Args...)) - construct_n(U* ptr, I n, Args&&... args) - { - c4::construct_n(ptr, n, std::allocator_arg, m_resource, std::forward< Args >(args)...); - } - - // 2.2. can construct(Args..., MemoryResource*) - template< class U, class... Args > - _c4_void_if(_c4_uses_allocator(U) && _c4_is_constructible(U, Args..., MemoryResource*)) - construct(U* ptr, Args&&... args) - { - c4::construct(ptr, std::forward< Args >(args)..., m_resource); - } - template< class U, class I, class... Args > - _c4_void_if(_c4_uses_allocator(U) && _c4_is_constructible(U, Args..., MemoryResource*)) - construct_n(U* ptr, I n, Args&&... args) - { - c4::construct_n(ptr, n, std::forward< Args >(args)..., m_resource); - } - - template< class U > - static C4_ALWAYS_INLINE void destroy(U* ptr) - { - c4::destroy(ptr); - } - template< class U, class I > - static C4_ALWAYS_INLINE void destroy_n(U* ptr, I n) - { - c4::destroy_n(ptr, n); - } - -#undef _c4_void_if -#undef _c4_is_constructible -#undef _c4_uses_allocator - -}; - - -/** A polymorphic allocator, acting as a proxy to a memory resource */ -template< class T > -class Allocator : public AllocatorBase -{ -public: - - template< class U > using rebind = Allocator< U >; - template< class U > Allocator< U > rebound() { return Allocator< U >(*this); } - - Allocator() : AllocatorBase() {} - Allocator(MemoryResource *r) : AllocatorBase(r) {} - template< class U > Allocator(Allocator const& that) : AllocatorBase(that.m_resource) {} - - Allocator(Allocator const&) = default; - Allocator(Allocator &&) = default; - - Allocator& operator= (Allocator const&) = delete; // WTF? why? @see http://en.cppreference.com/w/cpp/memory/polymorphic_allocator - Allocator& operator= (Allocator &&) = default; - - /** returns a default-constructed polymorphic allocator object - * @see http://en.cppreference.com/w/cpp/memory/polymorphic_allocator/select_on_container_copy_construction */ - Allocator select_on_container_copy_construct() const { return Allocator(*this); } - - T* allocate(size_t num_objs, size_t alignment = alignof(T)) - { - C4_ASSERT(m_resource != nullptr); - void* vmem = m_resource->allocate(num_objs * sizeof(T), alignment); - T* mem = static_cast< T* >(vmem); - return mem; - } - - void deallocate(T * ptr, size_t num_objs, size_t alignment = alignof(T)) - { - C4_ASSERT(m_resource != nullptr); - m_resource->deallocate(ptr, num_objs * sizeof(T), alignment); - } - - T* reallocate(T* ptr, size_t oldnum, size_t newnum, size_t alignment = alignof(T)) - { - C4_ASSERT(m_resource != nullptr); - void* vmem = m_resource->reallocate(ptr, oldnum * sizeof(T), newnum * sizeof(T), alignment); - T* mem = static_cast< T* >(vmem); - return mem; - } - -}; - - -template< class T, size_t N = 16, size_t Alignment = alignof(T) > -class SmallAllocator : public AllocatorBase -{ - - union { - alignas(Alignment) char _m_arr[N * sizeof(T)]; - alignas(Alignment) T m_arr[N]; - }; - -public: - - template< class U > using rebind = SmallAllocator< U >; - template< class U > SmallAllocator< U > rebound() { return SmallAllocator< U >(*this); } - - SmallAllocator() : AllocatorBase() {} - SmallAllocator(MemoryResource *r) : AllocatorBase(r) {} - template< class U > SmallAllocator(SmallAllocator const& that) : AllocatorBase(that.m_resource) {} - - SmallAllocator(SmallAllocator const&) = default; - SmallAllocator(SmallAllocator &&) = default; - - SmallAllocator& operator= (SmallAllocator const&) = delete; // WTF? why? @see http://en.cppreference.com/w/cpp/memory/polymorphic_allocator - SmallAllocator& operator= (SmallAllocator &&) = default; - - /** returns a default-constructed polymorphic allocator object - * @see http://en.cppreference.com/w/cpp/memory/polymorphic_allocator/select_on_container_copy_construction */ - SmallAllocator select_on_container_copy_construct() const { return SmallAllocator(*this); } - - T* allocate(size_t num_objs, size_t alignment = alignof(T)) - { - C4_ASSERT(m_resource != nullptr); - if(num_objs <= N) - { - return m_arr; - } - void* vmem = m_resource->allocate(num_objs * sizeof(T), alignment); - T* mem = static_cast< T* >(vmem); - return mem; - } - - void deallocate(T * ptr, size_t num_objs, size_t alignment = alignof(T)) - { - if(ptr == &m_arr[0]) - { - return; - } - C4_ASSERT(m_resource != nullptr); - m_resource->deallocate(ptr, num_objs * sizeof(T), alignment); - } - - T* reallocate(T* ptr, size_t oldnum, size_t newnum, size_t alignment = alignof(T)) - { - C4_ASSERT(m_resource != nullptr); - if(oldnum <= N && newnum <= N) - { - return m_arr; - } - else if(oldnum <= N && newnum > N) - { - return allocate(newnum, alignment); - } - else if(oldnum > N && newnum <= N) - { - deallocate(ptr, oldnum, alignment); - return m_arr; - } - void* vmem = m_resource->reallocate(ptr, oldnum * sizeof(T), newnum * sizeof(T), alignment); - T* mem = static_cast< T* >(vmem); - return mem; - } - -private: - - MemoryResource* m_resource; - -}; - -C4_END_NAMESPACE(c4) - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// Storage facilities. - - -C4_BEGIN_NAMESPACE(c4) - -//----------------------------------------------------------------------------- -#define _c4_DEFINE_ARRAY_TYPES(T, I) \ -\ - using value_type = T;\ - using size_type = I;\ -\ - using pointer = T*;\ - using const_pointer = T const*;\ -\ - using reference = T&;\ - using const_reference = T const&;\ -\ - using iterator = T*;\ - using const_iterator = T const*;\ -\ - using difference_type = ptrdiff_t; - -//----------------------------------------------------------------------------- -template< class T, class I = uint32_t > -class array_view -{ -protected: - - T *m_ptr; - I m_size; - -public: - - _c4_DEFINE_ARRAY_TYPES(T, I); - - C4_ALWAYS_INLINE operator array_view< const T, I > () const { return array_view< const T, I >((T const*)m_ptr, m_size); } - - array_view(array_view const&) = default; - array_view(array_view &&) = default; - - array_view& operator= (array_view const&) = default; - array_view& operator= (array_view &&) = default; - -public: - - C4_ALWAYS_INLINE array_view() : m_ptr{}, m_size{0} {} - C4_ALWAYS_INLINE array_view(T *p, I sz) : m_ptr{p}, m_size{sz} {} - template< size_t N > - C4_ALWAYS_INLINE array_view(T (&arr)[N]) : m_ptr{arr}, m_size{N} {} - - C4_ALWAYS_INLINE constexpr I type_size() const { return sizeof(T); } - C4_ALWAYS_INLINE I byte_size() const { return m_size*sizeof(T); } - - C4_ALWAYS_INLINE bool empty() const noexcept { return m_size == 0; } - C4_ALWAYS_INLINE I size() const noexcept { return m_size; } - C4_ALWAYS_INLINE I capacity() const noexcept { return m_size; } - - C4_ALWAYS_INLINE T * data() noexcept { return m_ptr; } - C4_ALWAYS_INLINE T const* data() const noexcept { return m_ptr; } - - C4_ALWAYS_INLINE iterator begin() noexcept { return m_ptr; } - C4_ALWAYS_INLINE const_iterator begin() const noexcept { return m_ptr; } - C4_ALWAYS_INLINE const_iterator cbegin() const noexcept { return m_ptr; } - - C4_ALWAYS_INLINE iterator end() noexcept { return m_ptr + m_size; } - C4_ALWAYS_INLINE const_iterator end() const noexcept { return m_ptr + m_size; } - C4_ALWAYS_INLINE const_iterator cend() const noexcept { return m_ptr + m_size; } - - C4_ALWAYS_INLINE T& front() noexcept { C4_XASSERT(!empty()); return m_ptr[0]; } - C4_ALWAYS_INLINE fastcref front() const noexcept { C4_XASSERT(!empty()); return m_ptr[0]; } - - C4_ALWAYS_INLINE T& back() noexcept { C4_XASSERT(!empty()); return m_ptr[m_size - 1]; } - C4_ALWAYS_INLINE fastcref back() const noexcept { C4_XASSERT(!empty()); return m_ptr[m_size - 1]; } - - C4_ALWAYS_INLINE T& operator[] (I i) noexcept { C4_XASSERT(i >= 0 && i < m_size); return m_ptr[i]; } - C4_ALWAYS_INLINE fastcref operator[] (I i) const noexcept { C4_XASSERT(i >= 0 && i < m_size); return m_ptr[i]; } - - C4_ALWAYS_INLINE void clear() noexcept { m_size = 0; } - - C4_ALWAYS_INLINE void ltrim(I n) noexcept { C4_XASSERT(n >= 0 && n < m_size); m_ptr += n; } - C4_ALWAYS_INLINE void rtrim(I n) noexcept { C4_XASSERT(n >= 0 && n < m_size); m_size -= n; } - - array_view view(I first = 0) const noexcept - { - C4_ASSERT(first >= 0 && first < m_size); - return array_view(m_ptr + first, m_size - first); - } - array_view view(I first, I num) const noexcept - { - C4_ASSERT(first >= 0 && first < m_size); - C4_ASSERT(first + num >= 0 && first + num < m_size); - return array_view(m_ptr + first, num); - } - -}; - -C4_BEGIN_NAMESPACE(stg) // stg==SToraGe - -struct growth_default; - -//----------------------------------------------------------------------------- -/** a tag type for specifying the initial capacity of allocatable contiguous storage */ -struct with_capacity_t {}; -/** a tag type for initializing the containers with variadic arguments a la - * initializer_list, minus the initializer_list problems. - * @see */ -struct aggregate_t {}; - -//----------------------------------------------------------------------------- -// Raw storage classes - -/** @defgroup raw_storage_classes Raw storage classes - * - * These classes are a building block for the several flavours of - * contiguous containers. They offer a convenient way to hold a - * number of (almost-)contiguous objects (via the index-based [] operator). - * - * - The memory used by these objects is NOT automatically allocated or\n - * freed. Use the protected methods _raw_reserve(I n), _raw_trim(I n) - * - The elements in the raw storage are NOT automatically constructed\n - * or destroyed. - */ - -//----------------------------------------------------------------------------- -/** Type traits for raw storage classes. - * @ingroup raw_storage_classes */ -template< class T > -struct raw_storage_traits -{ - using storage_type = T; - using value_type = typename T::value_type; - using size_type = typename T::size_type; - - constexpr static const bool fixed = false; - constexpr static const bool contiguous = false; -} - -#define C4_DEFINE_STORAGE_TRAITS(type, is_fixed, is_contiguous, ...) \ - template< __VA_ARGS__ > \ - struct raw_storage_traits< type > \ - { \ - using storage_type = T; \ - using value_type = typename T::value_type; \ - using size_type = typename T::size_type; \ - \ - constexpr static const bool fixed = is_fixed; \ - constexpr static const bool contiguous = is_contiguous; \ - } - -//----------------------------------------------------------------------------- -/** Utility class which uses SFINAE to dispatch construction/destruction - * to the appropriate functions. This class is meant to be used by container - * implementations to aid in object management. - * @ingroup raw_storage_classes */ -template< class T > -struct raw_storage_util : public raw_storage_traits< T > -{ - using raw_storage_traits< T >::contiguous; - -#define _c4require(what) C4_ALWAYS_INLINE static typename std::enable_if< what, void >::type - - template< class ...Args > - _c4require(contiguous) construct(T& dest, I first, I n, Args&&... args) - { - dest.m_allocator.construct_n(dest.data() + first, n, std::forward< Args >(args)...); - } - template< class ...Args > - _c4require( ! contiguous) construct(T& dest, I first, I n, Args&&... args) - { - dest._raw_construct(first, n, std::forward< Args >(args)...); - } - - _c4require(contiguous) destroy(T& dest, I first, I n) - { - dest.m_allocator.destroy_n(dest.data() + first, n); - } - _c4require( ! contiguous) destroy(T& dest, I first, I n) - { - dest._raw_destroy(first, n); - } - - _c4require(contiguous) move_construct(T& dest, T const& src, I first, I n) - { - c4::move_construct_n(dest.data() + first, src.data() + first, n); - } - _c4require( ! contiguous) move_construct(T& dest, T const& src, I first, I n) - { - dest._raw_move_construct(src, first, n); - } - - _c4require(contiguous) copy_construct(T& dest, T const& src, I first, I n) - { - c4::copy_construct_n(dest.data() + first, src.data() + first, n); - } - _c4require( ! contiguous) copy_construct(T& dest, T const& src, I first, I n) - { - dest._raw_copy_construct(src, first, n); - } - - _c4require(contiguous) move_assign(T& dest, T const& src, I first, I n) - { - c4::move_assign_n(dest.data() + first, src.data() + first, n); - } - _c4require( ! contiguous) move_assign(T& dest, T const& src, I first, I n) - { - dest._raw_move_assign(src, first, n); - } - - _c4require(contiguous) copy_assign(T& dest, T const& src, I first, I n) - { - c4::copy_assign_n(dest.data() + first, src.data() + first, n); - } - _c4require( ! contiguous) copy_assign(T& dest, T const& src, I first, I n) - { - dest._raw_copy_assign(src, first, n); - } - - -#undef _c4require -}; - -//----------------------------------------------------------------------------- -/** @ingroup raw_storage_classes */ -template< class T, size_t N, class I = uint32_t, I Alignment = alignof(T) > -struct raw_fixed -{ - - union { - alignas(Alignment) char _m_buf[N * sizeof(T)]; - alignas(Alignment) T m_ptr[N]; - }; - - _c4_DEFINE_ARRAY_TYPES(T, I); - - C4_ALWAYS_INLINE T& operator[] (I i) { return m_ptr[i]; } - C4_ALWAYS_INLINE constexpr fastcref operator[] (I i) const { return m_ptr[i]; } - - C4_ALWAYS_INLINE T * data() noexcept { return m_ptr; } - C4_ALWAYS_INLINE T const* data() const noexcept { return m_ptr; } - - C4_ALWAYS_INLINE constexpr I max_capacity() const noexcept { return N; } - C4_ALWAYS_INLINE constexpr I capacity() const noexcept { return N; } - C4_ALWAYS_INLINE constexpr I next_capacity(I cap) const noexcept { return N; } - - void _raw_reserve(I n) { C4_XASSERT(n <= N); } - void _raw_trim(I n) { C4_XASSERT(n <= N); } -}; - -C4_DEFINE_STORAGE_TRAITS(raw_fixed< T, N, I, Alignment >, - true, // fixed - true, // contiguous - class T, size_t N, class I, I Alignment); - -//----------------------------------------------------------------------------- - -/** raw storage variable size: allocatable, contiguous - * @ingroup raw_storage_classes */ -template -< - class T, - class I = uint32_t, - I Alignment = alignof(T), - class Alloc = Allocator< T >, - class GrowthType = growth_default -> -struct raw -{ - - T* m_ptr; - I m_capacity; - Alloc m_allocator; - - _c4_DEFINE_ARRAY_TYPES(T, I); - - using allocator_type = Alloc; - - raw() : m_ptr(nullptr), m_capacity(0), m_allocator() {} - raw(Alloc const& a) : m_ptr(nullptr), m_capacity(0), m_allocator(a) {} - ~raw() - { - C4_ASSERT_MSG(m_ptr == nullptr, "the container using this did not free the storage"); - } - - /** @todo implement this */ - raw(raw const& that) = delete; - raw(raw && that) = default; - - /** @todo implement this */ - raw& operator=(raw const& that) = delete; - raw& operator=(raw && that) = default; - - C4_ALWAYS_INLINE T& operator[] (I i) { return m_ptr[i]; } - C4_ALWAYS_INLINE constexpr fastcref operator[] (I i) const { return m_ptr[i]; } - - C4_ALWAYS_INLINE T * data() noexcept { return m_ptr; } - C4_ALWAYS_INLINE T const* data() const noexcept { return m_ptr; } - - C4_ALWAYS_INLINE I max_capacity() const noexcept { return std::numeric_limits< I >::max() - 1; } - C4_ALWAYS_INLINE I capacity() const noexcept { return m_capacity; } - C4_ALWAYS_INLINE I next_capacity(I desired) const - { - return GrowthType::next_size(m_capacity, desired); - } - - void _raw_reserve(I cap) - { - - } - - void _raw_trim(I cap) - { - - } -}; - -C4_DEFINE_STORAGE_TRAITS(raw< T, I, Alignment, Alloc, GrowthType >, - false, // fixed - true, // contiguous - class T, class I, I Alignment, class Alloc, class GrowthType); - - -//----------------------------------------------------------------------------- -/** raw storage: allocatable and paged. This is NOT a contiguous storage structure. - * However, it does behave as such, offering the [] operator with contiguous - * range indices. This is useful for minimizing allocations and data copies in - * dynamic array-based containers as flat_list. - * - * @ingroup raw_storage_classes - * @todo add a raw structure with a runtime-determined page size */ -template -< - class T, - size_t PageSize, //< The page size. Must be a power of two. - class I = uint32_t, - I Alignment = alignof(T), - class Alloc = Allocator< T > -> -struct raw_paged -{ - static_assert(PageSize > 1, "PageSize must be > 1") - static_assert(PageSize & (PageSize - 1) == 0, "PageSize must be a power of two") - - //! id mask: all the bits up to PageSize. Use to extract the position of an index within a page. - constexpr static const I _raw_idmask = (I)PageSize - 1; - - //! page mask: bits complementary to PageSize. Use to extract the page of an index. - constexpr static const I _raw_pgmask = ~ ((I)PageSize - 1); //< all the bits - - T **m_pages; //< array containing the pages - I m_num_pages; //< number of current pages in the array - Alloc m_allocator; - -public: - - _c4_DEFINE_ARRAY_TYPES(T, I); - using allocator_type = Alloc; - - raw_paged() : m_pages(nullptr), m_num_pages(0), m_allocator() {} - raw_paged(Alloc const& a) : m_pages(nullptr), m_num_pages(0), m_allocator(a) {} - - raw_paged(raw_paged const& that) = delete; - raw_paged(raw_paged && that) = default; - raw_paged& operator=(raw_paged const& that) = delete; - raw_paged& operator=(raw_paged && that) = default; - - C4_ALWAYS_INLINE T& operator[] (I i) - { - C4_XASSERT(i < capacity()); - I pg = i & _raw_pgmask; - I id = i & _raw_idmask; - C4_XASSERT(pg < m_num_pages); - C4_XASSERT(id < PageSize); - return m_pages[pg][id]; - } - C4_ALWAYS_INLINE constexpr fastcref operator[] (I i) const - { - C4_XASSERT(i < capacity()); - I pg = i & _raw_pgmask; - I id = i & _raw_id; - C4_XASSERT(pg < m_num_pages); - C4_XASSERT(id < PageSize); - return m_pages[pg][id]; - } - - C4_ALWAYS_INLINE I max_capacity() const noexcept { return std::numeric_limits< I >::max() - 1; } - C4_ALWAYS_INLINE I capacity() const noexcept { return m_num_pages * PageSize; } - C4_ALWAYS_INLINE I next_capacity(I desired) const - { - I cap = capacity(); - if(desired < cap) return cap; - I np = desired / PageSize; - I cap = np * PageSize; - return cap; - } - -protected: - - void _raw_reserve(I cap) - { - if(cap <= capacity()) return; - I np = cap / PageSize; - C4_XASSERT(np * PageSize >= capacity()); - if(np > m_num_pages) - { - auto at = m_allocator.rebound< T* >(); - m_pages = at.reallocate(m_pages, m_num_pages, np); - for(I i = m_num_pages; i < np; ++i) - { - m_pages[i] = m_allocator.allocate(PageSize, Alignment); - } - } - m_num_pages = np; - } - void _raw_trim(I to) - { - if(m_pages == nullptr) return; - I np = to / PageSize; - if(np >= m_num_pages) return; - for(I i = np; i < m_num_pages; ++i) - { - m_allocator.deallocate(m_pages[i], PageSize, Alignment); - } - auto at = m_allocator.rebound< T* >(); - if(to == 0) - { - at.deallocate(m_pages, m_num_pages); - m_pages = nullptr; - } - else - { - m_pages = at.reallocate(m_pages, m_num_pages, np); - } - m_num_pages = np; - } - void _raw_copy(raw_paged const& that, I first, I num) - { - C4_NOT_IMPLEMENTED(); - } -}; - - -C4_DEFINE_STORAGE_TRAITS(raw_paged< T, I, PageSize, Alignment, Alloc >, - false, // fixed - false, // contiguous - true, // paged - class T, class I, I PageSize, I Alignment, class Alloc); - -//----------------------------------------------------------------------------- -/* CRTP bases for contiguous storage. - * These serve as a development scaffold until the implementation is validated - * and stable. Afterwards, the member functions in these base classes - * should be copied and adapted into each of the contiguous storage classes. */ - - -#define _c4this static_cast< S* >(this) -#define _c4cthis static_cast< S const* >(this) - -/** CRTP base for non-resizeable contiguous storage */ -template< class T, class I, class S > -struct contiguous_base -{ -protected: - - // prevent construction/destruction of an object of this type unless through derived types - - contiguous_base() {} - ~contiguous_base() {} - -public: - - _c4_DEFINE_ARRAY_TYPES(T, I); - - using view_type = array_view< T, I >; - using const_view_type = array_view< const T, I >; - - C4_ALWAYS_INLINE constexpr I type_size() const { return sizeof(T); } - C4_ALWAYS_INLINE I byte_size() const { return _c4this->size() * sizeof(T); } - -public: - - C4_ALWAYS_INLINE operator view_type () { return view_type(_c4this->m_ptr, _c4this->size()); } - C4_ALWAYS_INLINE operator const_view_type () const { return const_view_type(_c4this->m_ptr, _c4this->size()); } - - view_type view(I first = 0) - { - C4_ASSERT(first >= 0 && first < _c4this->size()); - return view_type(_c4this->m_ptr + first, _c4this->size() - first); - } - const_view_type view(I first = 0) const - { - C4_ASSERT(first >= 0 && first < _c4this->size()); - return view_type(_c4this->m_ptr + first, _c4this->size() - first); - } - view_type view(I first, I num) - { - C4_ASSERT(first >= 0 && first < _c4this->size()); - C4_ASSERT(first + num >= 0 && first + num < _c4this->size()); - return view_type(_c4this->m_ptr + first, num); - } - const_view_type view(I first, I num) const - { - C4_ASSERT(first >= 0 && first < _c4this->size()); - C4_ASSERT(first + num >= 0 && first + num < _c4this->size()); - return view_type(_c4this->m_ptr + first, num); - } - - void fill(T const& v) - { - C4_ASSERT(_c4this->m_size > 0); - copy_assign_n(_c4this->m_ptr, v, _c4this->m_size); - } - - void assign(T const* v, I sz) - { - if(v == _c4this->m_ptr && sz == _c4this->size()) return; - _c4this->resize(sz); // resize() for fixed-size storage just asserts whether the size is the same - copy_assign_n(_c4this->m_ptr, v, sz); - } - - void assign(array_view< T, I > v) - { - assign(v.data(), v.size()); - } - - void assign(aggregate_t, std::initializer_list< T > il) - { - assign(il.begin(), il.size()); - } - - C4_ALWAYS_INLINE bool is_valid_iterator(const_iterator it) const noexcept - { - return it >= _c4cthis->m_ptr && it <= _c4cthis->m_ptr + _c4cthis->size(); - } - C4_ALWAYS_INLINE bool is_valid_index(I i) const noexcept - { - return i >= 0 && i < _c4cthis->size(); - } - -}; - - -/** CRTP base for resizeable contiguous storage */ -template< class T, class I, class S > -struct contiguous_base_rs : public contiguous_base< T, I, S > -{ - using contiguous_base< T, I, S >::is_valid_iterator; - -protected: - - // prevent construction/destruction of an object of this type unless through derived types - - contiguous_base_rs() {} - ~contiguous_base_rs() {} - -public: - - _c4_DEFINE_ARRAY_TYPES(T, I); - -public: - - // emplace - template< class... Args > - iterator emplace(const_iterator pos, Args&&... args) - { - C4_XASSERT(pos >= _c4this->m_ptr && pos <= _c4this->m_ptr + _c4this->m_size); - I ipos = I(pos - _c4this->m_ptr); - _c4this->_growto(_c4this->m_size + 1, pos); - pos = _c4this->m_ptr + ipos; - _c4this->_construct(pos, std::forward< Args >(args)...); - ++_c4this->m_size; - return (iterator)pos; - } - template< class... Args > - void emplace_back(Args&& ...a) - { - _c4this->_growto(_c4this->m_size + 1); - _c4this->_construct(_c4this->m_ptr + _c4this->m_size, std::forward< Args >(a)...); - ++_c4this->m_size; - } - template< class... Args > - void emplace_front(Args&& ...a) - { - _c4this->_growto(_c4this->m_size + 1); - _c4this->_construct(_c4this->m_ptr, std::forward< Args >(a)...); - ++_c4this->m_size; - } - - // push - - void push_back(T const& val) - { - _c4this->_growto(_c4this->m_size + 1); - _c4this->_construct(_c4this->m_ptr + _c4this->m_size, val); - ++_c4this->m_size; - } - void push_back(T && val) - { - _c4this->_growto(_c4this->m_size + 1); - _c4this->_construct(_c4this->m_ptr + _c4this->m_size, std::move(val)); - ++_c4this->m_size; - } - - void push_front(T const& val) - { - _c4this->_growto(_c4this->m_size + 1, _c4this->m_ptr); - _c4this->_construct(_c4this->m_ptr, val); - ++_c4this->m_size; - } - void push_front(T && val) - { - _c4this->_growto(_c4this->m_size + 1, _c4this->m_ptr); - _c4this->_construct(_c4this->m_ptr, std::move(val)); - ++_c4this->m_size; - } - - // pop - - void pop_back() - { - C4_XASSERT(_c4this->m_size > 0); - _c4this->_growto(_c4this->m_size - 1); - --_c4this->m_size; - } - void pop_front() - { - C4_XASSERT(_c4this->m_size > 0); - _c4this->_growto(_c4this->m_size - 1, _c4this->m_ptr); - --_c4this->m_size; - } - - // insert - - iterator insert(const_iterator pos, T const& value) - { - C4_XASSERT(is_valid_iterator(pos)); - I ipos = I(pos - _c4this->m_ptr); - _c4this->_growto(_c4this->m_size + 1, pos); - pos = _c4this->m_ptr + ipos; - _c4this->_construct(pos, value); - ++_c4this->m_size; - return (iterator)pos; - } - iterator insert(const_iterator pos, T&& value) - { - C4_XASSERT(is_valid_iterator(pos)); - I ipos = I(pos - _c4this->m_ptr); - _c4this->_growto(_c4this->m_size + 1, pos); - pos = _c4this->m_ptr + ipos; - _c4this->_construct(pos, std::move(value)); - ++_c4this->m_size; - return (iterator)pos; - } - iterator insert(const_iterator pos, I count, T const& value) - { - C4_XASSERT(is_valid_iterator(pos)); - I ipos = I(pos - _c4this->m_ptr); - _c4this->_growto(_c4this->m_size + count, pos); - pos = _c4this->m_ptr + ipos; - _c4this->_construct_n(pos, value, count); - _c4this->m_size += count; - return (iterator)pos; - } - template< class InputIt > - iterator insert(const_iterator pos, InputIt first, InputIt last) - { - C4_XASSERT(is_valid_iterator(pos)); - I ipos = I(pos - _c4this->m_ptr); - I count = (I)std::distance(first, last); - _c4this->_growto(_c4this->m_size + count, pos); - pos = _c4this->m_ptr + ipos; - for(I i = 0; first != last; ++first, ++i) - { - _c4this->_construct(pos + i, first); - } - _c4this->m_size += count; - return (iterator)pos; - } - iterator insert(const_iterator pos, aggregate_t, std::initializer_list ilist) - { - C4_XASSERT(is_valid_iterator(pos)); - I ipos = I(pos - _c4this->m_ptr); - _c4this->_growto(_c4this->m_size + ilist.size(), pos); - pos = _c4this->m_ptr + ipos; - I i = 0; - for(auto const& v : ilist) - { - _c4this->_construct((pos++) + i, v); - } - pos = _c4this->m_ptr + ipos; - _c4this->m_size += ilist.size(); - return (iterator)pos; - } - - /** removes the element at pos */ - iterator erase(const_iterator pos) - { - C4_XASSERT(is_valid_iterator(pos) && _c4this->size() > 0); - I ipos = I(pos - _c4this->m_ptr); - _c4this->_grow_to(_c4this->size() - 1, pos); - pos = _c4this->m_ptr + ipos; - --_c4this->m_size; - return (iterator)pos; - } - /** removes the elements in the range [first; last). */ - iterator erase(const_iterator first, const_iterator last) - { - I dist = (I)std::distance(first, last); - if(!dist) return (iterator)first; - C4_XASSERT(is_valid_iterator(first) && _c4this->size() >= dist); - I ipos = I(first - _c4this->m_ptr); - _c4this->_grow_to(_c4this->size() - dist, first); - first = _c4this->m_ptr + ipos; - _c4this->m_size -= dist; - return (iterator)first; - } - -}; - -#undef _c4this -#undef _c4cthis - -//----------------------------------------------------------------------------- -/** contiguous storage, fixed size+capacity (cannot resize down) */ -template< class T, size_t N, class I = uint32_t, I Alignment = alignof(T) > -class contiguous_fixed_size : public contiguous_base< T, I, contiguous_fixed_size< T, N, I, Alignment > > -{ - C4_STATIC_ASSERT(N <= std::numeric_limits< I >::max()); - - friend struct contiguous_base< T, I, contiguous_fixed_size< T, N, I, Alignment > >; - using base_type = contiguous_base< T, I, contiguous_fixed_size< T, N, I, Alignment > >; - -protected: - - alignas(Alignment) T m_ptr[N]; - -public: - - _c4_DEFINE_ARRAY_TYPES(T, I); - - enum { alignment = Alignment }; - -public: - - C4_ALWAYS_INLINE operator array_view< T, I > () { return array_view< T, I >(m_ptr, N); } - C4_ALWAYS_INLINE operator array_view< const T, I > () const { return array_view< const T, I >(m_ptr, N); } - -public: - - contiguous_fixed_size() {} - contiguous_fixed_size(array_view< T, I > const& v) { assign(v); } - contiguous_fixed_size(array_view< T, I > && v) { assign(std::move(v)); } - //contiguous_fixed_size(std::initializer_list< T > il) { assign(il); } - - // provided for compatibility with other contiguous storages - contiguous_fixed_size(I sz) { C4_ASSERT(sz == N); } - contiguous_fixed_size(I sz, with_capacity_t, I cap) { C4_ASSERT(sz == N && cap == N); } - - C4_ALWAYS_INLINE constexpr bool empty() const { return false; } - C4_ALWAYS_INLINE constexpr I size() const { return N; } - C4_ALWAYS_INLINE constexpr I max_size() const { return N; } - C4_ALWAYS_INLINE constexpr I capacity() const { return N; } - - C4_ALWAYS_INLINE iterator begin() { return m_ptr; } - C4_ALWAYS_INLINE constexpr const_iterator begin() const { return m_ptr; } - C4_ALWAYS_INLINE constexpr const_iterator cbegin() const { return m_ptr; } - - C4_ALWAYS_INLINE iterator end() { return m_ptr + I(N); } - C4_ALWAYS_INLINE constexpr const_iterator end() const { return m_ptr + I(N); } - C4_ALWAYS_INLINE constexpr const_iterator cend() const { return m_ptr + I(N); } - - C4_ALWAYS_INLINE T& front() { return m_ptr[0]; } - C4_ALWAYS_INLINE constexpr fastcref front() const { return m_ptr[0]; } - - C4_ALWAYS_INLINE T& back() { return m_ptr[I(N) - 1]; } - C4_ALWAYS_INLINE constexpr fastcref back() const { return m_ptr[I(N) - 1]; } - - C4_ALWAYS_INLINE T * data() { return m_ptr; } - C4_ALWAYS_INLINE constexpr T const* data() const { return m_ptr; } - - C4_ALWAYS_INLINE T& operator[] (I i) { C4_XASSERT(i >= 0 && i < N); return m_ptr[i]; } - C4_ALWAYS_INLINE fastcref operator[] (I i) const { C4_XASSERT(i >= 0 && i < N); return m_ptr[i]; } - -private: - - // these functions are provided for compatibility with the scaffold CRTP - - C4_ALWAYS_INLINE void reserve(I cap) { C4_ASSERT(cap == I(N)); } - C4_ALWAYS_INLINE void shrink_to_fit() {} - C4_ALWAYS_INLINE void resize(I sz) { C4_ASSERT(sz == I(N)); } - C4_ALWAYS_INLINE void clear() { C4_NEVER_REACH(); } - - template< class U, class... Args > - C4_ALWAYS_INLINE static void _construct(U *ptr, Args&&... args) - { - ::c4::construct(ptr, std::forward< Args >(args)...); - } - -}; - -//----------------------------------------------------------------------------- -/** contiguous storage, variable size, fixed capacity. */ -template< class T, size_t N, class I = uint32_t, I Alignment = alignof(T) > -class contiguous_fixed_capacity : public contiguous_base_rs< T, I, contiguous_fixed_capacity< T, N, I, Alignment > > -{ - C4_STATIC_ASSERT(N <= std::numeric_limits< I >::max()); - - friend struct contiguous_base< T, I, contiguous_fixed_capacity< T, N, I, Alignment > >; - friend struct contiguous_base_rs< T, I, contiguous_fixed_capacity< T, N, I, Alignment > >; - using base_type = contiguous_base_rs< T, I, contiguous_fixed_capacity< T, N, I, Alignment > >; - -protected: - - union { - alignas(Alignment) char _m_buf[N * sizeof(T)]; - alignas(Alignment) T m_ptr[N]; - }; - - I m_size; - -public: - - _c4_DEFINE_ARRAY_TYPES(T, I); - - enum { alignment = Alignment }; - -public: - - contiguous_fixed_capacity() : m_size{0} {} - contiguous_fixed_capacity(I sz) : contiguous_fixed_capacity() { resize(sz); } - - // provided for compatibility - contiguous_fixed_capacity(with_capacity_t, I cap) : contiguous_fixed_capacity() { C4_ASSERT_MSG(cap == N, "capacity: asked %u, should be %u", (uint32_t)cap, (uint32_t)N); } - contiguous_fixed_capacity(I sz, with_capacity_t, I cap) : contiguous_fixed_capacity() { C4_ASSERT_MSG(cap == N, "capacity: asked %u, should be %u", (uint32_t)cap, (uint32_t)N); resize(sz); } - - contiguous_fixed_capacity(aggregate_t, std::initializer_list< T > il) { assign(aggregate_t{}, il); } - - C4_ALWAYS_INLINE bool empty() const { return m_size == 0; } - C4_ALWAYS_INLINE I size() const { return m_size; } - C4_ALWAYS_INLINE constexpr I max_size() const { return N; } - C4_ALWAYS_INLINE constexpr I capacity() const { return N; } - - C4_ALWAYS_INLINE T * data() { return m_ptr; } - C4_ALWAYS_INLINE constexpr T const* data() const { return m_ptr; } - - C4_ALWAYS_INLINE iterator begin() { return m_ptr; } - C4_ALWAYS_INLINE constexpr const_iterator begin() const { return m_ptr; } - C4_ALWAYS_INLINE constexpr const_iterator cbegin() const { return m_ptr; } - - C4_ALWAYS_INLINE iterator end() { return m_ptr + m_size; } - C4_ALWAYS_INLINE const_iterator end() const { return m_ptr + m_size; } - C4_ALWAYS_INLINE const_iterator cend() const { return m_ptr + m_size; } - - C4_ALWAYS_INLINE T& front() { C4_XASSERT(!empty()); return m_ptr[0]; } - C4_ALWAYS_INLINE fastcref front() const { C4_XASSERT(!empty()); return m_ptr[0]; } - - C4_ALWAYS_INLINE T& back() { C4_XASSERT(!empty()); return m_ptr[m_size - 1]; } - C4_ALWAYS_INLINE fastcref back() const { C4_XASSERT(!empty()); return m_ptr[m_size - 1]; } - - C4_ALWAYS_INLINE T& operator[] (I i) { C4_XASSERT(i >= 0 && i < m_size); return m_ptr[i]; } - C4_ALWAYS_INLINE fastcref operator[] (I i) const { C4_XASSERT(i >= 0 && i < m_size); return m_ptr[i]; } - - C4_ALWAYS_INLINE void resize(I sz) { C4_ASSERT(sz >= 0 && sz <= N); m_size = sz; } - C4_ALWAYS_INLINE void clear() { m_size = 0; } - -protected: - - // these functions are provided for compatibility with the scaffold CRTP - - C4_ALWAYS_INLINE void reserve(I cap) { C4_ASSERT(cap == N); } - C4_ALWAYS_INLINE void shrink_to_fit() {} - - template< class U, class... Args > - C4_ALWAYS_INLINE static void _construct(U *ptr, Args&&... args) - { - ::c4::construct(ptr, std::forward< Args >(args)...); - } - - void _growto(I sz) - { - C4_ASSERT(sz <= N); - } - void _growto(I sz, const_iterator before_this) - { - C4_ASSERT(sz <= N); - C4_NOT_IMPLEMENTED(); - } -}; - - -//----------------------------------------------------------------------------- -/** contiguous storage, allocatable */ -template -< - class T, - class I = uint32_t, - I Alignment = alignof(T), - class Alloc = c4::Allocator< T >, - class GrowthType = growth_default -> -struct contiguous : public contiguous_base_rs< T, I, contiguous< T, I, Alignment, Alloc, GrowthType > > -{ - friend struct contiguous_base< T, I, contiguous< T, I, Alignment, Alloc, GrowthType > >; - friend struct contiguous_base_rs< T, I, contiguous< T, I, Alignment, Alloc, GrowthType > >; - using base_type = contiguous_base_rs< T, I, contiguous< T, I, Alignment, Alloc, GrowthType > >; -protected: - - T* m_ptr; - I m_size; - I m_capacity; - Alloc m_allocator; - -public: - - _c4_DEFINE_ARRAY_TYPES(T, I); - - enum { alignment = Alignment }; - using allocator_type = Alloc; - using growth_type = GrowthType; - - C4_ALWAYS_INLINE operator array_view< T, I > () { return array_view< T, I >(m_ptr, m_size); } - C4_ALWAYS_INLINE operator array_view< const T, I > () const { return array_view< const T, I >(m_ptr, m_size); } - -public: - - allocator_type get_allocator() const { return m_allocator; } - - C4_ALWAYS_INLINE bool empty() const { return m_size == 0; } - C4_ALWAYS_INLINE I size() const { return m_size; } - C4_ALWAYS_INLINE I max_size() const { return allocator_type::max_size(); } - C4_ALWAYS_INLINE I capacity() const { return m_capacity; } - - C4_ALWAYS_INLINE T * data() { return m_ptr; } - C4_ALWAYS_INLINE T const* data() const { return m_ptr; } - - C4_ALWAYS_INLINE iterator begin() { return m_ptr; } - C4_ALWAYS_INLINE const_iterator begin() const { return m_ptr; } - C4_ALWAYS_INLINE const_iterator cbegin() const { return m_ptr; } - - C4_ALWAYS_INLINE iterator end() { return m_ptr + m_size; } - C4_ALWAYS_INLINE const_iterator end() const { return m_ptr + m_size; } - C4_ALWAYS_INLINE const_iterator cend() const { return m_ptr + m_size; } - - C4_ALWAYS_INLINE T& front() { C4_XASSERT(!empty()); return *m_ptr; } - C4_ALWAYS_INLINE fastcref front() const { C4_XASSERT(!empty()); return *m_ptr; } - - C4_ALWAYS_INLINE T& back() { C4_XASSERT(!empty()); return *(m_ptr + (m_size - 1)); } - C4_ALWAYS_INLINE fastcref back() const { C4_XASSERT(!empty()); return *(m_ptr + (m_size - 1)); } - - C4_ALWAYS_INLINE T& operator[] (I i) { C4_XASSERT(i >= 0 && i < m_size); return m_ptr[i]; } - C4_ALWAYS_INLINE fastcref operator[] (I i) const { C4_XASSERT(i >= 0 && i < m_size); return m_ptr[i]; } - - contiguous() : m_ptr(nullptr), m_size(0), m_capacity(0), m_allocator( ) {} - contiguous(allocator_type const& a) : m_ptr(nullptr), m_size(0), m_capacity(0), m_allocator(a) {} - - contiguous(I sz) : contiguous( ) { resize(sz); } - contiguous(I sz, allocator_type const& a) : contiguous(a) { resize(sz); } - - contiguous(with_capacity_t, I cap) : contiguous( ) { reserve(cap); } - contiguous(with_capacity_t, I cap, allocator_type const& a) : contiguous(a) { reserve(cap); } - - contiguous(I sz, with_capacity_t, I cap) : contiguous( ) { reserve(cap); resize(sz); } - contiguous(I sz, with_capacity_t, I cap, allocator_type const& a) : contiguous(a) { reserve(cap); resize(sz); } - - contiguous(contiguous const& that) : contiguous(that.m_allocator) { assign(that); } - contiguous(contiguous && that) : contiguous(that.m_allocator) { assign(std::move(that)); } - - contiguous& operator= (contiguous const& that) { assign(that); return *this; } - contiguous& operator= (contiguous && that) { assign(std::move(that)); return *this; } - - ~contiguous() - { - _free(); - } - - void clear() - { - resize(0); - } - - using base_type::assign; - void assign(contiguous const& that) - { - if(&that == this) return; - if(that.m_size == 0) - { - clear(); - } - else if(that.m_size > 0) - { - if(that.m_size == m_size) - { - copy_assign_n(m_ptr, that.m_ptr, that.m_size); - } - else if(that.m_size < m_size) - { - copy_assign_n(m_ptr, that.m_ptr, that.m_size); - m_allocator.destroy_n(m_ptr+that.m_size, m_size - that.m_size); - } - else if(that.m_size > m_size) - { - reserve(that.m_size); - copy_assign_n(m_ptr, that.m_ptr, m_size); - copy_construct_n(m_ptr+m_size, that.m_ptr, that.m_size - m_size); - } - m_size = that.m_size; - } - } - void assign(contiguous && that) - { - if(&that == this) return; - C4_ASSERT(m_ptr != that.m_ptr); - clear(); - m_allocator.deallocate(m_ptr, m_capacity, Alignment); - m_ptr = that.m_ptr; - m_size = that.m_size; - m_capacity = that.m_capacity; - that.m_ptr = nullptr; - that.m_size = 0; - that.m_capacity = 0; - } - - void resize(I sz) - { - if(sz == m_size) return; - if(sz > m_capacity) - { - reserve(sz); - } - if(sz > m_size) - { - m_allocator.construct_n(m_ptr + m_size, sz - m_size); - } - else if(sz < m_size) - { - m_allocator.destroy_n(m_ptr + sz, m_size - sz); - } - m_size = sz; - } - void resize(I sz, fastcref value) - { - if(sz == m_size) return; - if(sz > m_capacity) - { - reserve(sz); - } - if(sz > m_size) - { - m_allocator.construct_n(m_ptr + m_size, sz - m_size, value); - } - else if(sz < m_size) - { - m_allocator.destroy_n(m_ptr + sz, m_size - sz); - } - m_size = sz; - } - void reserve(I cap) - { - _reserve(m_size, cap, m_ptr + m_size); - } - void shrink_to_fit() - { - if(m_size == m_capacity) return; - if(m_size == 0) - { - _free(); - } - else - { - T *tmp = m_allocator.allocate(m_size, Alignment); - if(m_ptr) - { - move_construct_n(tmp, m_ptr, m_size); - m_allocator.deallocate(m_ptr, m_capacity, Alignment); - } - m_ptr = tmp; - m_capacity = m_size; - } - } - -protected: - - void _growto(I sz) - { - C4_XASSERT(m_size <= m_capacity); - if(sz > m_capacity) - { - size_t next = growth_type::next_size(m_capacity, sz); - C4_XASSERT(next < size_t(std::numeric_limits< I >::max())); - _reserve(sz, (I)next, m_ptr + m_capacity); - } - if(sz < m_size) - { - C4_NOT_IMPLEMENTED(); - } - } - void _growto(I sz, const_iterator before_this) - { - C4_XASSERT(m_size <= m_capacity); - if(sz > m_capacity) - { - size_t next = growth_type::next_size(m_capacity, sz); - C4_XASSERT(next < size_t(std::numeric_limits< I >::max())); - _reserve(sz, (I)next, before_this); - } - else - { - if(sz > m_size) - { - I num_after = m_ptr+m_size - before_this; - for(I i = 0; i < num_after; ++i) - { - T* curr = m_ptr + m_size - i; - move_construct(curr, curr-1); - } - } - else if(sz < m_size) - { - C4_NOT_IMPLEMENTED(); - } - } - } - void _reserve(I sz, I cap, const_iterator before_this) - { - if(cap <= m_capacity) return; - T *tmp = m_allocator.allocate(cap, Alignment); - if(m_ptr) - { - if(sz >= m_size) // add more before_this - { - I num_more = sz - m_size; // to construct (later) - I num_before = before_this - m_ptr; // to move before - I num_after = m_ptr+m_size - before_this; // to move after - move_construct_n(tmp, m_ptr, num_before); - move_construct_n(tmp + num_before + num_more, m_ptr + num_before, num_after); - } - else // remove some before_this - { - I num_less = m_size - sz; // to remove - I num_before = before_this-num_less - m_ptr; // to move before - I num_after = m_ptr+m_size - before_this; // to move after - m_allocator.destroy_n(m_ptr + num_before, num_less); - move_construct_n(tmp, m_ptr, num_before); - move_construct_n(tmp + num_before, m_ptr + num_before + num_less, num_after); - } - m_allocator.deallocate(m_ptr, m_capacity, Alignment); - } - m_ptr = tmp; - m_capacity = cap; - } - - void _free() - { - m_allocator.destroy_n(m_ptr, m_size); - m_allocator.deallocate(m_ptr, m_capacity, Alignment); - m_size = 0; - m_ptr = nullptr; - m_capacity = 0; - } - - - template< class U, class... Args > - C4_ALWAYS_INLINE void _construct(U *ptr, Args&&... args) - { - m_allocator.construct(ptr, std::forward< Args >(args)...); - } - - template< class U, class... Args > - C4_ALWAYS_INLINE void _construct_n(U *ptr, Args&&... args) - { - m_allocator.construct_n(ptr, std::forward< Args >(args)...); - } -}; - - -//----------------------------------------------------------------------------- - -/** @todo add search algorithm transparency (binary/ternary/golden)*/ -template -< - class T, - class Compare = std::less< T >, - class Storage = c4::stg::contiguous< T > -> -class contiguous_sorted : protected Storage -{ -public: - - using value_type = T; - using size_type = typename Storage::size_type; - using iterator = typename Storage::iterator; - using const_iterator = typename Storage::const_iterator; - using reference = value_type&; - using const_reference = value_type const&; - using pointer = value_type*; - using const_pointer = value_type const*; - -public: - - contiguous_sorted() : m_valid(true) {} - contiguous_sorted(aggregate_t, std::initializer_list< T > il) { Storage::assign(aggregate_t{}, il); } - - using Storage::empty; - using Storage::size; - using Storage::capacity; - using Storage::reserve; - using Storage::shrink_to_fit; - - using Storage::type_size; - using Storage::byte_size; - - using Storage::begin; - using Storage::end; - using Storage::data; - - using Storage::front; - using Storage::back; - - using Storage::operator[]; - - bool valid() const { return m_valid; } - - template< class L > - iterator find(L const& v) - { - C4_STATIC_ASSERT(m_valid); - auto it = lower_bound< L >(v); - if(it == end()) return it; - if( ! m_compare(*it, v) && ! m_compare(v, *it)) return it; - return end(); - } - iterator find(T const& v) - { - C4_STATIC_ASSERT(m_valid); - auto it = lower_bound(v); - if(it == end()) return it; - if( ! m_compare(*it, v) && ! m_compare(v, *it)) return it; - return end(); - } - - template< class L > - const_iterator find(L const& v) const - { - C4_STATIC_ASSERT(m_valid); - auto it = lower_bound< L >(v); - if(it == end()) return it; - if( ! m_compare(*it, v) && ! m_compare(v, *it)) return it; - return end(); - } - const_iterator find(T const& v) const - { - C4_STATIC_ASSERT(m_valid); - auto it = lower_bound(v); - if(it == end()) return it; - if( ! m_compare(*it, v) && ! m_compare(v, *it)) return it; - return end(); - } - - // insert into the proper place. order remains valid. - - iterator insert(T const& v) - { - if(empty()) - { - Storage::push_back(v); - return end() - 1; - } - if( ! m_valid) fix(); - auto lb = lower_bound(v); - auto it = Storage::insert(lb, v); - return it; - } - iterator insert(T && v) - { - if(empty()) - { - Storage::push_back(std::move(v)); - return end() - 1; - } - if( ! m_valid) fix(); - auto lb = lower_bound(v); - auto it = Storage::insert(lb, std::move(v)); - return it; - } - template< class... Args > - C4_ALWAYS_INLINE iterator emplace(Args&&... args) - { - if(empty()) - { - Storage::emplace_back(std::forward< Args >(args)...); - return end() - 1; - } - if( ! m_valid) fix(); - auto lb = lower_bound(v); - auto it = Storage::emplace(lb, std::forward< Args >(args)...); - return it; - } - - // insert at the end. order continues valid if and only if the value is not less than back() - - iterator push_back_nosort(T const& v) - { - if( ! empty()) - { - m_valid = m_compare(v, back()); - } - this->push_back(v); - return end() - 1; - } - iterator push_back_nosort(T && v) - { - if( ! empty()) - { - m_valid = m_compare(v, back()); - } - this->push_back(std::move(v)); - return end() - 1; - } - template< class... Args > - C4_ALWAYS_INLINE iterator emplace_back_nosort(Args&&... args) - { - return this->push_back_nosort(std::move(T(std::forward< Args >(args)...))); - } - - // insert before the given position. Order continues valid if and only if the value is not less than pos->first - - iterator insert_nosort(const_iterator pos, T const& v) - { - C4_XASSERT(this->is_valid_iterator(pos)); - if( ! empty() && pos != end()) - { - m_valid = m_compare(v, *pos); - } - size_type i = (size_type)(pos - begin()); - Storage::insert(pos, v); - return begin() + i; - } - iterator insert_nosort(const_iterator pos, T && v) - { - C4_XASSERT(this->is_valid_iterator(pos)); - if( ! empty() && pos != end()) - { - m_valid = m_compare(v, *pos); - } - size_type i = (size_type)(pos - begin()); - Storage::insert(pos, std::move(v)); - return begin() + i; - } - template< class... Args > - C4_ALWAYS_INLINE iterator emplace_nosort(const_iterator pos, Args&&... args) - { - return insert_nosort(pos, std::move(T(std::forward< Args >(args)...))); - } - - bool fix() - { - if(m_valid) return false; - std::sort(begin(), end(), m_compare); - m_valid = true; - return true; - } - - - void assign(T const* mem, size_type sz) - { - Storage::assign(mem, sz); - m_valid = _check(); // O(N) pass - fix(); // O(N log N) pass - } - void assign_nosort(T const* mem, size_type sz) - { - Storage::assign(mem, sz); - m_valid = _check(); // O(N) pass - } - void assign_nocheck(T const* mem, size_type sz) - { - Storage::assign(mem, sz); - } - void assign(aggregate_t a, std::initializer_list< T > il) - { - Storage::assign(a, il); - m_valid = _check(); // O(N) pass - fix(); // O(N log N) pass - } - void assign_nosort(aggregate_t a, std::initializer_list< T > il) - { - Storage::assign(a, il); - m_valid = _check(); // O(N) pass - } - void assign_nocheck(aggregate_t a, std::initializer_list< T > il) - { - Storage::assign(a, il); - } - - /** Returns an iterator pointing to the first element that is _NOT LESS THAN_ key.*/ - template< class U > - C4_ALWAYS_INLINE const_iterator lower_bound(U const& v) const { return std::lower_bound(begin(), end(), v, m_compare); } - /** Returns an iterator pointing to the first element that is _NOT LESS THAN_ key.*/ - C4_ALWAYS_INLINE const_iterator lower_bound(T const& v) const { return std::lower_bound(begin(), end(), v, m_compare); } - - /** Returns an iterator pointing to the first element that is _NOT LESS THAN_ key.*/ - template< class U > - C4_ALWAYS_INLINE iterator lower_bound(U const& v) { return std::lower_bound(begin(), end(), v, m_compare); } - /** Returns an iterator pointing to the first element that is _NOT LESS THAN_ key.*/ - C4_ALWAYS_INLINE iterator lower_bound(T const& v) { return std::lower_bound(begin(), end(), v, m_compare); } - - /** Returns an iterator pointing to the first element that is _NOT MORE THAN_ key.*/ - template< class U > - C4_ALWAYS_INLINE const_iterator upper_bound(U const& v) const { return std::upper_bound(begin(), end(), v, m_compare); } - /** Returns an iterator pointing to the first element that is _NOT MORE THAN_ key.*/ - C4_ALWAYS_INLINE const_iterator upper_bound(T const& v) const { return std::upper_bound(begin(), end(), v, m_compare); } - - /** Returns an iterator pointing to the first element that is _NOT MORE THAN_ key.*/ - template< class U > - C4_ALWAYS_INLINE iterator upper_bound(U const& v) { return std::upper_bound(begin(), end(), v, m_compare); } - /** Returns an iterator pointing to the first element that is _NOT MORE THAN_ key.*/ - C4_ALWAYS_INLINE iterator upper_bound(T const& v) { return std::upper_bound(begin(), end(), v, m_compare); } - -protected: - - bool _check() const - { - for(auto itm1 = begin(), it = itm1+1, e = end(); it < e; ++itm1, ++it) - { - if( ! m_compare(itm1, it)) - { - return false; - } - } - return true; - } - -private: - - Compare m_compare; - bool m_valid; - -}; - -//----------------------------------------------------------------------------- - -// Capacity growth policies - -/** Grow by the least possible amount. */ -struct growth_least -{ - static size_t next_size(size_t curr, size_t at_least) noexcept - { - if(at_least <= curr) return curr; - return at_least; - } -}; -/** Grow to the double of the current size if it is bigger than at_least; - * if not, then just to at_least. */ -struct growth_pot -{ - static size_t next_size(size_t curr, size_t at_least) noexcept - { - if(at_least <= curr) return curr; - size_t nxt = (curr << 1); - return nxt > at_least ? nxt : at_least; - } -}; -/** Grow by the Fibonacci ratio if the result is bigger than at_least; - * if not, then just to at_least. */ -struct growth_phi -{ - static size_t next_size(size_t curr, size_t at_least) noexcept - { - if(at_least <= curr) return curr; - size_t nxt = size_t(float(curr) * 1.618f); - nxt = nxt > 0 ? nxt : 1; - return nxt > at_least ? nxt : at_least; - } -}; -/** grow another growth policy in fixed chunk sizes. Useful for SIMD buffers. */ -template< class Growth, size_t PowerOfTwoChunkSize > -struct growth_by_chunks -{ - C4_STATIC_ASSERT(PowerOfTwoChunkSize > 1); - C4_STATIC_ASSERT_MSG((PowerOfTwoChunkSize & (PowerOfTwoChunkSize - 1)) == 0, "chunk size must be a power of two"); - - constexpr static const size_t chunk_size = PowerOfTwoChunkSize; - - static size_t next_size(size_t curr, size_t at_least) noexcept - { - size_t next = Growth::next_size(curr, at_least); - size_t rem = (next & (PowerOfTwoChunkSize-1)); - next += rem ? PowerOfTwoChunkSize - rem : 0; - C4_ASSERT((next % PowerOfTwoChunkSize) == 0); - return next; - } -}; -/** first, powers of 2, then Fibonacci ratio */ -struct growth_default -{ - static size_t next_size(size_t curr, size_t at_least) noexcept - { - if(at_least <= 1024) - return growth_pot::next_size(curr, at_least); - else - return growth_phi::next_size(curr, at_least); - } -}; - -C4_END_NAMESPACE(stg) - -//----------------------------------------------------------------------------- -using stg::with_capacity_t; -constexpr const stg::with_capacity_t with_capacity; - -using stg::aggregate_t; -constexpr const stg::aggregate_t aggregate; - -template< class T, size_t N, class I = uint32_t > -using array = c4::stg::contiguous_fixed_size< T, N, I, alignof(T) >; - -template< class T, size_t N, class I = uint32_t > -using static_vector = c4::stg::contiguous_fixed_capacity< T, N, I, alignof(T) >; - -template< class T, class I = uint32_t > -using vector = c4::stg::contiguous< T, I, alignof(T), c4::Allocator< T >, c4::stg::growth_default >; - -template< class T, size_t N = 16, class I = uint8_t > -using small_vector = c4::stg::contiguous< T, I, alignof(T), c4::SmallAllocator< T, N, alignof(T) >, c4::stg::growth_default >; - -template< class T, class Compare = std::less< T >, class Storage = vector< T > > -using sorted_vector = c4::stg::contiguous_sorted< T, Compare, Storage >; - -//----------------------------------------------------------------------------- - -template< class K, class T, class Compare = std::less< K > > -struct flat_map_compare -{ - using value_type = std::pair; - - Compare comp; - - flat_map_compare() : comp() {} - flat_map_compare(Compare const& c) : comp(c) {} - - // compare value vs value - C4_ALWAYS_INLINE bool operator() (value_type const& l, value_type const& r) const { return comp(l.first, r.first); } - - // compare key vs value - template< class L > - C4_ALWAYS_INLINE bool operator() (L const& k, value_type const& v) const { return comp(k, v.first); } - C4_ALWAYS_INLINE bool operator() (K const& k, value_type const& v) const { return comp(k, v.first); } - - // compare value vs key - template< class L > - C4_ALWAYS_INLINE bool operator() (value_type const& v, L const& k) const { return comp(v.first, k); } - C4_ALWAYS_INLINE bool operator() (value_type const& v, K const& k) const { return comp(v.first, k); } -}; - -//----------------------------------------------------------------------------- -/** A map based on a sorted array. Lookup is O(log N) BUT insertion/removal are O(N). - * This associative container is good for any of the following scenarios: - * -frequent lookups with infrequent modifications. - * -OR small sizes. Depending on the size, the array's better cache - * properties compensate the more expensive linear modification time. - * Of course, YMMV. */ -template -< - class K, - class T, - class Compare = std::less< K >, - class Storage = c4::stg::contiguous< std::pair< K, T > > -> -class flat_map : protected stg::contiguous_sorted< std::pair< K, T >, flat_map_compare< K, T, Compare >, Storage > -{ - C4_STATIC_ASSERT((std::is_same< std::pair< K, T >, typename Storage::value_type >::value == true)); - using base_type = stg::contiguous_sorted< std::pair< K, T >, flat_map_compare< K, T, Compare >, Storage >; - -public: - - using key_type = K; - using mapped_type = T; - using size_type = typename Storage::size_type; - using allocator_type = typename Storage::allocator_type; - using value_type = typename Storage::value_type; - using iterator = typename Storage::iterator; - using const_iterator = typename Storage::const_iterator; - -public: - - using base_type::base_type; - - using base_type::empty; - using base_type::size; - using base_type::capacity; - using base_type::reserve; - using base_type::shrink_to_fit; - - using base_type::type_size; - using base_type::byte_size; - - using base_type::data; - - using base_type::begin; - using base_type::end; - - using base_type::front; - using base_type::back; - - using base_type::valid; - using base_type::find; - - using base_type::lower_bound; - using base_type::upper_bound; - - using base_type::clear; - - using base_type::insert; - using base_type::emplace; - - using base_type::push_back_nosort; - using base_type::emplace_back_nosort; - - using base_type::insert_nosort; - using base_type::emplace_nosort; - - using base_type::fix; - - using base_type::assign; - using base_type::assign_nosort; - using base_type::assign_nocheck; - - template< class L > - T& operator[] (L const& key) - { - iterator it = this->template lower_bound< L >(key); - if(it == this->end() || it->first != key) - { - it = this->emplace_nosort(it, key, std::move(T())); - } - C4_XASSERT(it->first == key); - return it->second; - } - T& operator[] (K const& key) - { - auto it = this->lower_bound(key); - if(it == this->end() || it->first != key) - { - it = this->emplace_nosort(it, key, std::move(T())); - } - C4_XASSERT(it->first == key); - return it->second; - } - - template< class L > - fastcref< T > operator[] (L const& key) const - { - auto it = this->template find< L >(key); - C4_XASSERT(it != this->end()); - C4_XASSERT(it->first == key); - return it->second; - } - fastcref< T > operator[] (K const& key) const - { - auto it = this->find(key); - C4_XASSERT(it != this->end()); - C4_XASSERT(it->first == key); - return it->second; - } - -}; - -//----------------------------------------------------------------------------- - -template< class T, class I > -struct flat_forward_list_node -{ - using value_type = T; - using size_type = I; - T val; - I next; -}; -template< class T, class I > -struct flat_list_node -{ - using value_type = T; - using size_type = I; - T val; - I prev; - I next; -}; - -//----------------------------------------------------------------------------- - -template< class T, class I = uint32_t, class RawStorage = stg::raw< flat_forward_list_node, I > > -struct flat_forward_list -{ - C4_STATIC_ASSERT((std::is_same< I, typename RawStorage::size_type >::value)); - C4_STATIC_ASSERT((std::is_same< flat_forward_list_node, typename RawStorage::value_type >::value)); -public: - - using node_type = flat_forward_list_node< T, I >; - using value_type = T; - using size_type = I; - using storage_type = RawStorage; - -public: - - flat_forward_list() : m_storage(), m_size(0), m_head(0), m_tail(0), m_fhead(0) - { - } - - I size() const { return m_size; } - I capacity() const { return m_storage.capacity(); } - - bool empty() const { return m_size == 0; } - bool full() const { return m_fhead == m_storage.capacity(); } - - void push_front(T const& val) - { - auto *n = _push_front(); - n->val = val; - } - void push_front(T && val) - { - auto *n = _push_front(); - n->val = std::move(val); - } - template< class... Args > - void emplace_front(Args&&... args) - { - auto *n = _push_front(); - construct(&n->val, std::forward< Args >(args)...); - } - void pop_front() - { - C4_XASSERT(m_size > 0); - auto *c = n(m_head); - m_head = c->next; - c->val.~T(); - --m_size; - C4_NOT_IMPLEMENTED(); - } - - void push_back(T const& val) - { - auto *c = _push_back(); - c->val = val; - } - void push_back(T && val) - { - auto *c = _push_back(); - c->val = std::move(val); - } - template< class... Args > - void emplace_back(Args&&... args) - { - auto *c = _push_back(); - construct(&c->val, std::forward< Args >(args)...); - } - void pop_back() - { - C4_XASSERT(m_size > 1); - C4_NOT_IMPLEMENTED(); - } - - void clear() - { - if(m_size > 0) - { - n(m_tail)->next = m_fhead; - m_fhead = m_head; - m_head = 0; - m_tail = 0; - } - m_size = 0; - } - - /** reorders the elements in memory in order of appearance on the list */ - void sort() - { - node_type *d = m_storage.data(); - I curr = m_head; - for(I i = 0; i < m_size; ++i) - { - while(curr < i) - { - curr = d[curr].next; - } - std::swap(d[i], d[curr]); - std::swap(d[i].next, curr); - } - I cap = m_storage.capacity(); - for(I i = 0; i < cap; ++i) - { - d[i].next = i+1; - } - m_head = 0; - m_tail = 0; - if(m_size > 0) - { - d[m_size-1].next = cap; - m_tail = m_size - 1; - } - m_fhead = m_storage.capacity(); - m_fhead = m_size < m_fhead ? m_size : m_fhead; - } - -protected: - - C4_ALWAYS_INLINE node_type * n(I i) { C4_XASSERT(i >= 0 && i <= m_storage.capacity()); return m_storage.data() + i; } - C4_ALWAYS_INLINE node_type const* n(I i) const { C4_XASSERT(i >= 0 && i <= m_storage.capacity()); return m_storage.data() + i; } - - node_type* _push_back() - { - if(C4_UNLIKELY(full())) - { - _growto(m_size + 1); - } - node_type* d = m_storage.data(); - node_type* c = d + m_fhead; - I fhead = c->next; - c->next = m_storage.capacity(); - if(C4_LIKELY(m_size > 0)) - { - d[m_tail].next = m_fhead; - } - m_tail = m_fhead; - m_fhead = fhead; - ++m_size; - return c; - } - node_type* _push_front() - { - if(C4_UNLIKELY(full())) - { - _growto(m_size + 1); - } - node_type* d = m_storage.data(); - node_type* c = d + m_fhead; - I fhead = c->next; - if(C4_LIKELY(m_size > 0)) - { - c->next = m_head; - } - else - { - c->next = m_storage.capacity(); - m_tail = m_fhead; - } - m_head = m_fhead; - m_fhead = fhead; - ++m_size; - return c; - } - node_type* _insert_after(I after_this) - { - C4_XASSERT(!empty()); - C4_XASSERT(after_this >= 0 && after_this < m_storage.capacity()); - if(C4_UNLIKELY(full())) - { - _growto(m_size + 1); - } - node_type* d = m_storage.data(); - node_type* c = d + m_fhead; - I next_fhead = c->next; - c->next = d[after_this].next; - d[after_this].next = m_fhead; - m_tail = (after_this == m_tail) ? m_fhead : m_tail; - m_fhead = next_fhead; - ++m_size; - return c; - } - - void _growto(I cap) - { - if(cap <= m_storage.capacity()) return; - C4_CHECK_MSG(cap <= m_storage.max_capacity(), "asked %lu, max is %lu", (uint64_t)cap, (uint64_t)m_storage.max_capacity()); - I next_cap = m_storage.next_capacity(cap); - C4_CHECK_MSG(next_cap >= cap, "could not allocate storage for more elements. next=%lu cap=%lu", (uint64_t)next_cap, (uint64_t)cap); - _sort_into(m_storage.alloc(next_cap), next_cap); - C4_ASSERT(m_fhead != m_storage.capacity()); - } - - /** swaps the list into another array, pasting in list order */ - void _sort_into(node_type* dst, I next_cap) - { - if(m_size != 0) - { - node_type * src = m_storage.data(); - node_type * sc = src + m_head; - node_type * e = src + m_storage.capacity(); - node_type * dc = dst; - I curr = 0; - while(sc != e) - { - move_construct(&dc->val, &sc->val); - sc = src + sc->next; - dc->next = 1 + curr++; - ++dc; - } - } - m_head = 0; - m_tail = 0; - if(m_size > 0) - { - m_tail = m_size - 1; - dst[m_tail].next = next_cap; - } - m_fhead = m_size; - m_storage.reset(dst, next_cap); - for(I i = m_fhead; i < next_cap; ++i) - { - (dst + i)->next = i+1; - } - } - -protected: - - RawStorage m_storage; - I m_size; - I m_head; - I m_tail; - I m_fhead; // free head: first free element - -protected: - - template< class U > - friend class iterator_impl; - - template< class U > - class iterator_impl - { - flat_forward_list *list; - I node; - - C4_ALWAYS_INLINE bool _valid() const { return list != nullptr && list->_valid_node(node); } - - public: - - using value_type = typename U::value_type; - using size_type = typename U::size_type; - - iterator_impl(flat_forward_list *li, I n) : list(li), node(n) {} - - value_type& operator* () { return list->n(node)->val; } - value_type* operator-> () { return &list->n(node)->val; } - - iterator_impl& operator++ () { C4_XASSERT(_valid()); node = list->n(node)->next; return *this; } - iterator_impl& operator++ (int) { C4_XASSERT(_valid()); iterator_impl it = *this; node = list->n(node).next; return it; } - - bool operator== (iterator_impl const& that) const { return list == that.list && node == that.node; } - bool operator!= (iterator_impl const& that) const { return list != that.list || node != that.node; } - - }; - -public: - - using iterator = iterator_impl< node_type >; - using const_iterator = iterator_impl< const node_type >; - - C4_ALWAYS_INLINE bool _valid_node(I node) - { - node_type const* c = n(node); - return c >= m_storage.data() && c < m_storage.data() + m_storage.capacity(); - } - - C4_ALWAYS_INLINE iterator begin() { return iterator(this, m_head); } - C4_ALWAYS_INLINE iterator end () { return iterator(this, m_storage.capacity()); } - - C4_ALWAYS_INLINE const_iterator begin() const { return iterator(this, m_head); } - C4_ALWAYS_INLINE const_iterator end () const { return iterator(this, m_storage.capacity()); } - -}; - -C4_END_NAMESPACE(c4) - -//------------------------------------------------------------ -//------------------------------------------------------------ -//------------------------------------------------------------ -// THREAD UTILS - -#ifdef C4_LOG_THREAD_SAFE - -C4_BEGIN_NAMESPACE(c4) - -uint32_t thread_number() -{ - static std::mutex mtx; - { - std::lock_guard< std::mutex > lock(mtx); - static flat_map< std::thread::id, uint32_t > ids; - static uint32_t count = 0; - - auto id = std::this_thread::get_id(); - auto it = ids.find(id); - if(it == ids.end()) - { - it = ids.emplace(id, count++); - } - - return it->second; - } -} - -/** A simple class for implementing thread local vars. - * @warning It is inefficient for heavy use. */ -template< class T > -class ThreadLocal : private c4::flat_map< std::thread::id, T > -{ - typedef c4::flat_map< std::thread::id, T > map_type; -public: - - using map_type::map_type; - - C4_ALWAYS_INLINE operator T& () { return get(); } - C4_ALWAYS_INLINE T& get() - { - std::lock_guard< std::mutex > lock(m_mtx); - T& obj = (*this)[std::this_thread::get_id()]; - return obj; - } - -private: - - std::mutex m_mtx; - -}; - -#if 0 -# define C4_THREAD_LOCAL(type) c4::ThreadLocal< type > -#else -# define C4_THREAD_LOCAL(type) thread_local type -#endif - -C4_END_NAMESPACE(c4) - -#endif // C4_LOG_THREAD_SAFE - -//------------------------------------------------------------ -//------------------------------------------------------------ -//------------------------------------------------------------ -// LOGGING - -C4_BEGIN_NAMESPACE(c4) - -// a stringstream output buffer used by the logger -template< class I = uint16_t > -struct LogBuffer -{ - typedef I index_type; - - vector< char, I > buf; - I pos; - - LogBuffer() : buf(C4_LOG_BUFFER_INITIAL_SIZE), pos(0) {} - - // string to read from - C4_ALWAYS_INLINE const char* rd() const { return buf.data(); } - // string to write into - C4_ALWAYS_INLINE char* wt() { return buf.data() + pos; } - // remaining size - C4_ALWAYS_INLINE I rem() - { - C4_XASSERT(pos <= buf.size()); - return buf.size() - pos; - } - - void clear() - { - pos = 0; - buf[0] = '\0'; - } - void growto(uint16_t sz) // grow by the max of sz and the golden ratio - { - float n = 1.618f * float(buf.size()); - assert(size_t(n) < max_idx); - auto next = I(n); - next = next > sz ? next : sz; - buf.resize(next); - } - void write(const char *cstr) - { - write(cstr, strlen(cstr)); - } - void write(const char *str, size_t sz) - { - assert(sz <= max_idx); - assert(sz + size_t(pos + 1) < max_idx); - if(sz+1 > rem()) growto(pos + sz + 1); - ::strncpy(wt(), str, sz); - pos += sz; - buf[pos] = '\0'; - } - void printf(const char *fmt, ...) - { - va_list args; - va_start(args, fmt); - int inum = ::vsnprintf(wt(), rem(), fmt, args); - I num = abs(inum); // silently skip output errors - assert(num < max_idx); - if(num >= rem()) // not enough space? - { - va_start(args, fmt); - growto(pos + num + 1); - assert(size_t(pos) + size_t(num) + 1 < max_idx); - inum = ::vsnprintf(wt(), rem(), fmt, args); - num = abs(inum); - assert(num < max_idx); - } - assert(size_t(pos) + size_t(num) < max_idx); - pos += num; - buf[pos] = '\0'; - va_end(args); - } - void vprintf(const char *fmt, va_list args) - { - va_list args2; - va_copy(args2, args); - int inum = ::vsnprintf(wt(), rem(), fmt, args); - I num = abs(inum); // silently skip output errors - assert(num < max_idx); - if(num >= rem()) // not enough space? - { - assert(num < max_idx); - assert(size_t(pos) + size_t(num) + 1 < max_idx); - growto(buf.size() + num + 1); - inum = ::vsnprintf(wt(), rem(), fmt, args2); - num = abs(inum); - } - assert(size_t(pos) + size_t(num) + 1 < max_idx); - pos += num; - buf[pos] = '\0'; - va_end(args2); - } - - constexpr static const size_t max_idx = std::numeric_limits< I >::max(); -}; - -//----------------------------------------------------------------------------- -class Log -{ -public: - - typedef enum { - ALWAYS = -10, - ERR = -2, - WARN = -1, - INFO = 0, - DEBUG = 1, - TRACE1 = 2, - TRACE2 = 3, - TRACE3 = 4, - } Level_e; - - typedef enum { - SHOW_TIMESTAMP = 1 << 0, - TO_TERM = 1 << 1, - TO_FILE = 1 << 2, - TO_STR = 1 << 3, - DEFAULT_MODE = SHOW_TIMESTAMP|TO_TERM, - } Mode_e; - - struct Channel - { - uint8_t level; - uint8_t name_len; - char name[30]; - - Channel() : level{INFO}, name_len{0}, name{0} {} - Channel(const char *str, Level_e lev) - { - level = lev; - name_len = strlen(str); - if(name_len > (sizeof(name) - 1)) abort(); - if(name_len > 0) - { - snprintf(name, sizeof(name), "%s", str); - } - else - { - name[name_len] = '\0'; - } - } - inline bool cmp(const char *str) const - { - if(name_len == 0) return str[0] == '\0'; - return strncmp(name, str, name_len) == 0; - } - C4_ALWAYS_INLINE bool skip(Level_e lev) const - { - return lev > level && lev != ALWAYS; - } - }; - - static uint8_t& _mode() { static uint8_t m = DEFAULT_MODE; return m; } - static uint8_t mode() { return _mode(); } - static void mode(uint8_t mode_flags) { _mode() = mode_flags; } - - static FILE*& _file() { static FILE *f = nullptr; return f; } - static FILE* file() { return _file(); } - static void file(FILE* f) { _file() = f; } - - static LogBuffer< size_t >& strbuf() { static LogBuffer< size_t > b; return b; } -#ifdef C4_LOG_THREAD_SAFE - static std::mutex& strbuf_mtx() { static std::mutex m; return m; } -#endif - - class StrReader - { -#ifdef C4_LOG_THREAD_SAFE - std::lock_guard< std::mutex > l; - const char* s; - public: - C4_ALWAYS_INLINE operator const char* () const { return s; } - StrReader(std::mutex &m, const char* s_) : l(m, std::adopt_lock_t{}), s(s_) {} -#else - const char* s; - public: - C4_ALWAYS_INLINE operator const char* () const { return s; } - StrReader(const char* s_) : s(s_) {} -#endif - }; - - static StrReader&& str() - { -#ifdef C4_LOG_THREAD_SAFE - auto& m = strbuf_mtx(); - m.lock(); -abort(); - return std::move(StrReader(m, (mode() & TO_STR) ? strbuf().rd() : "")); -#else - return std::move(StrReader((mode() & TO_STR) ? strbuf().rd() : "")); -#endif - } - - static void str_clear() - { - if(mode() & TO_STR) - { -#ifdef C4_LOG_THREAD_SAFE - std::lock_guard< std::mutex > lock(strbuf_mtx()); -#endif - strbuf().clear(); - } - } - - /** return the buffer for this thread */ - static LogBuffer< uint16_t >& buf() - { - // using static vars here saves us the need to declare them - // in a source file, allowing to use this as a drop-in header. -#ifndef C4_LOG_THREAD_SAFE - static LogBuffer< uint16_t > b; - return b; -#else // C4_LOG_THREAD_SAFE - // using a thread-local buffer saves us from locking when formatting - static C4_THREAD_LOCAL(LogBuffer< uint16_t >) s_buffer; - return s_buffer; -#endif // C4_LOG_THREAD_SAFE - } - static Channel* main_channel() - { - return &_channels()[0]; - } - static Channel* channel(uint8_t i) - { - assert(i < _channels().size()); - return &_channels()[i]; - } - static Channel* channel(const char *name) - { - for(auto &ch : _channels()) - { - if(ch.cmp(name)) - { - return &ch; - } - } - return nullptr; - } - static Channel* add_channel(const char *name, Level_e lev = INFO) - { - auto& chs = _channels(); - assert(chs.size() < C4_LOG_MAX_CHANNELS); - assert(channel(name) == nullptr); - chs.emplace_back(name, lev); - return &chs.back(); - } - -private: - - static inline c4::vector< Channel >& _channels() - { - static c4::vector< Channel > s_channels(1, c4::with_capacity, C4_LOG_MAX_CHANNELS); - return s_channels; - } - -public: - - /** set the level of all channels */ - static void level(Level_e l) - { - for(auto &ch : _channels()) - { - ch.level = l; - } - } - - template< class I > - static void _print_prefix(Channel const& ch, LogBuffer< I > &buf) - { - uint8_t md = mode(); - if((md & SHOW_TIMESTAMP) && (ch.name_len > 0)) - { - buf.printf("%lfms[%s]: ", exetime()/1.e3, ch.name); - } - else if((md & SHOW_TIMESTAMP)) - { - buf.printf("%lfms: ", exetime()/1.e3, ch.name); - } - else if((ch.name_len > 0)) - { - buf.printf("[%s]: ", ch.name); - } - } - - /** print formatted output to the main channel, at INFO level */ - static void printf(const char *fmt, ...) - { - Channel &ch = *main_channel(); - if(ch.skip(INFO)) return; - va_list args; - va_start(args, fmt); - auto& b = buf(); - _print_prefix(ch, b); - b.vprintf(fmt, args); - pump(b.rd(), b.pos); - b.clear(); - } - /** print formatted output to the main channel, at the given level */ - static void printfl(Level_e level, const char *fmt, ...) - { - Channel &ch = *main_channel(); - if(ch.skip(level)) return; - va_list args; - va_start(args, fmt); - auto& b = buf(); - _print_prefix(ch, b); - b.vprintf(fmt, args); - pump(b.rd(), b.pos); - b.clear(); - } - /** print formatted output to the given channel at the given level */ - static void printfcl(Channel *ch, Level_e level, const char *fmt, ...) - { - if(ch->skip(level)) return; - va_list args; - va_start(args, fmt); - auto& b = buf(); - _print_prefix(*ch, b); - b.vprintf(fmt, args); - pump(b.rd(), b.pos); - b.clear(); - } - - /** directly print a string to the main channel at INFO level */ - static void write(const char *s) { write(s, strlen(s)); } - /** directly print a string with specified size to the main channel at INFO level */ - static void write(const char *s, size_t sz) - { - Channel &ch = *main_channel(); - if(ch.skip(INFO)) return; - auto& b = buf(); - _print_prefix(ch, b); - b.write(s, sz); - pump(b.rd(), sz); - b.clear(); - } - /** directly print a string to the main channel at the given level */ - static void writel(Level_e level, const char *s) { writel(level, s, strlen(s)); } - /** directly print a string with specified size to the main channel at the given level */ - static void writel(Level_e level, const char *s, size_t sz) - { - Channel &ch = *main_channel(); - if(ch.skip(level)) return; - auto& b = buf(); - _print_prefix(ch, b); - b.write(s, sz); - pump(b.rd(), sz); - b.clear(); - } - /** directly print a string to the given channel at the given level */ - static void writecl(Channel *ch, Level_e level, const char *s) { writel(level, s, strlen(s)); } - /** directly print a string with specified size to the given channel at the given level */ - static void writecl(Channel *ch, Level_e level, const char *s, size_t sz) - { - if(ch->skip(level)) return; - auto& b = buf(); - _print_prefix(*ch, b); - b.write(s, sz); - pump(b.rd(), sz); - b.clear(); - } - - static void pump(const char *str, size_t sz) - { - uint8_t md = mode(); - if(md & TO_TERM) - { -#ifndef _MSC_VER - ::printf("%.*s", (int)sz, str); -#else - if( ! IsDebuggerPresent()) - { - ::printf("%.*s", (int)sz, str); - } - else - { - OutputDebugStrA(str); - } -#endif - } - if(md & TO_FILE) - { - if(file() == nullptr) abort(); - fprintf(file(), "%.*s", (int)sz, str); - } - if(md & TO_STR) - { -#ifdef C4_LOG_THREAD_SAFE - std::lock_guard< std::mutex > lock(strbuf_mtx()); -#endif - strbuf().write(str, sz); - } - } - - static void flush() - { - uint8_t md = mode(); - if(md & TO_TERM) - { -#ifndef _MSC_VER - fflush(stdout); -#else - if( ! IsDebuggerPresent()) - { - fflush(stdout); - } -#endif - } - if(md & TO_FILE) - { - fflush(file()); - } - } - - /** A proxy object which buffers prints to a log buffer. - * It accumulates << calls and outputs once after the last call. - * The buffer is set to NULL when the channel's log level - * is incompatible with the given log level. */ - struct Proxy - { - Channel const& channel; - Level_e level; - LogBuffer< uint16_t >* buf; - Proxy(Channel const* ch, Level_e lev) : channel(*ch), level(lev), buf(nullptr) - { - if(C4_LIKELY(channel.skip(level))) return; - buf = &Log::buf(); - Log::_print_prefix(channel, *buf); - } - ~Proxy() - { - if(C4_LIKELY(!buf)) return; - Log::pump(buf->rd(), buf->pos); - buf->clear(); - } - template< typename T > - void printf(const char *fmt, T const& var) const - { - if(C4_LIKELY(!buf)) return; - buf->printf(fmt, var); - if(buf->pos > C4_LOG_BUFFER_REF_SIZE) - { - Log::pump(buf->rd(), buf->pos); - buf->clear(); - } - } - }; - Proxy operator() (Channel const *ch, Level_e lev) { return Proxy(ch, lev); } - Proxy operator() (Channel const *ch) { return Proxy(ch, INFO); } - Proxy operator() (Level_e lev) { return Proxy(&_channels()[0], INFO); } - - /** create a temporary proxy object to handle all the calls to <<. - * It will accumulate the calls and output once after the last call. */ - template< class T > - Proxy operator<< (T const& v) - { - Proxy s(main_channel(), INFO); - s << v; - return s; - } -}; - -using LogProxy = const Log::Proxy; - -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, void * var) { ss.printf("%p", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, double var) { ss.printf("%lg", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, float var) { ss.printf("%g", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, char var) { ss.printf("%c", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, int64_t var) { ss.printf("%lld", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, uint64_t var) { ss.printf("%llu", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, int32_t var) { ss.printf("%d", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, uint32_t var) { ss.printf("%u", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, int16_t var) { ss.printf("%hd", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, uint16_t var) { ss.printf("%hu", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, int8_t var) { ss.printf("%hhd", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, uint8_t var) { ss.printf("%hhu", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, char *var) { ss.printf("%s", var); return ss; } -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, const char *var) { ss.printf("%s", var); return ss; } -//C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, std::string const& var) { ss.printf(var.c_str(), var.size()); return ss; } -template< size_t N > -C4_ALWAYS_INLINE LogProxy& operator<< (LogProxy& ss, const char (&var)[N]) { ss.printf("%.*s", (int)(N-1), &var[0]); return ss; } - -#define c4_log c4::Log() - -#define C4_LOG(fmt, ...) C4_LOG_INFO(fmt, ## __VA_ARGS__) -#define C4_LOG_ERR(fmt, ...) c4_log.printfl(c4::Log::ERR, fmt, ## __VA_ARGS__) -#define C4_LOG_WARN(fmt, ...) c4_log.printfl(c4::Log::WARN, fmt, ## __VA_ARGS__) -#define C4_LOG_INFO(fmt, ...) c4_log.printfl(c4::Log::INFO, fmt, ## __VA_ARGS__) -#define C4_LOG_DEBUG(fmt, ...) c4_log.printfl(c4::Log::DEBUG, fmt, ## __VA_ARGS__) -#define C4_LOG_TRACE1(fmt, ...) c4_log.printfl(c4::Log::TRACE1, fmt, ## __VA_ARGS__) -#define C4_LOG_TRACE2(fmt, ...) c4_log.printfl(c4::Log::TRACE2, fmt, ## __VA_ARGS__) -#define C4_LOG_TRACE3(fmt, ...) c4_log.printfl(c4::Log::TRACE3, fmt, ## __VA_ARGS__) - -#define C4_LOGC(channel, fmt, ...) C4_LOGC_INFO(channel, fmt, ## __VA_ARGS__) -#define C4_LOGC_ERR(channel, fmt, ...) c4_log.printfcl(channel, c4::Log::ERR, fmt, ## __VA_ARGS__) -#define C4_LOGC_WARN(channel, fmt, ...) c4_log.printfcl(channel, c4::Log::WARN, fmt, ## __VA_ARGS__) -#define C4_LOGC_INFO(channel, fmt, ...) c4_log.printfcl(channel, c4::Log::INFO, fmt, ## __VA_ARGS__) -#define C4_LOGC_DEBUG(channel, fmt, ...) c4_log.printfcl(channel, c4::Log::DEBUG, fmt, ## __VA_ARGS__) -#define C4_LOGC_TRACE1(channel, fmt, ...) c4_log.printfcl(channel, c4::Log::TRACE1, fmt, ## __VA_ARGS__) -#define C4_LOGC_TRACE2(channel, fmt, ...) c4_log.printfcl(channel, c4::Log::TRACE2, fmt, ## __VA_ARGS__) -#define C4_LOGC_TRACE3(channel, fmt, ...) c4_log.printfcl(channel, 4::Log::TRACE3, fmt, ## __VA_ARGS__) - - -C4_END_NAMESPACE(c4) - -//------------------------------------------------------------ -//------------------------------------------------------------ -//------------------------------------------------------------ -// ERROR REPORTING: implementation - -C4_BEGIN_NAMESPACE(c4) - -/** Raise an error, and report a printf-formatted message. - * If an error callback was set, it will be called. - * @see set_error_callback() */ -inline void report_error(const char *file, int line, const char *func, const char *fmt, ...) -{ - char msg[256]; - va_list args; - va_start(args, fmt); - int num = vsnprintf(msg, sizeof(msg), fmt, args); - if(num > 0) - { - C4_LOG_ERR("\n%s:%d: ERROR: %s\n", file, line, msg); - } - C4_LOG_ERR("\n%s:%d: ERROR: %s\n", file, line, func); - C4_LOG_ERR("\n%s:%d: ERROR: ABORTING...\n", file, line); - c4_log.flush(); - auto fn = get_error_callback(); - if(fn) - { - fn(); - } -} - -C4_END_NAMESPACE(c4) - -//------------------------------------------------------------ -//------------------------------------------------------------ -//------------------------------------------------------------ -// ALLOCATIONS - implementation - -C4_BEGIN_NAMESPACE(c4) - -C4_BEGIN_NAMESPACE(detail) -#ifndef C4_NO_ALLOC_DEFAULTS -inline void free_impl(void *ptr) -{ - ::free(ptr); -} -inline void afree_impl(void *ptr) -{ -#if defined(C4_WIN) || defined(C4_XBOX) - ::_aligned_free(ptr); -#else - ::free(ptr); -#endif -} -inline void* alloc_impl(size_t size) -{ - void* mem = ::malloc(size); - C4_CHECK(mem != nullptr || size == 0); - return mem; -} -inline void* aalloc_impl(size_t size, size_t alignment) -{ - void *mem; -#if defined(C4_WIN) || defined(C4_XBOX) - mem = ::_aligned_malloc(size, alignment); - C4_CHECK(mem != nullptr || size == 0); -#elif defined(C4_POSIX) - // NOTE: alignment needs to be sized in multiples of sizeof(void*) - size_t amult = alignment; - if(C4_UNLIKELY(alignment < sizeof(void*))) - { - amult = sizeof(void*); - } - int ret = ::posix_memalign(&mem, amult, size); - if(C4_UNLIKELY(ret)) - { - if(ret == EINVAL) - { - C4_ERROR("The alignment argument %lu was not a power of two, " - "or was not a multiple of sizeof(void*)", - (uint64_t)alignment); - } - else if(ret == ENOMEM) - { - C4_ERROR("There was insufficient memory to fulfill the " - "allocation request of %lu bytes (alignment=%lu)", - (uint64_t)size, (uint64_t)size); - } - if(mem) - { - afree(mem); - } - return nullptr; - } -#else - C4_NOT_IMPLEMENTED_MSG("need to implement an aligned allocation for this platform"); -#endif - C4_ASSERT_MSG((size_t(mem) & (alignment-1)) == 0, "address %p is not aligned to %lu boundary", mem, (uint64_t)alignment); - return mem; -} -inline void* realloc_impl(void* ptr, size_t oldsz, size_t newsz) -{ - C4_UNUSED(oldsz); - void *nptr = ::realloc(ptr, newsz); - return nptr; -} -inline void* arealloc_impl(void* ptr, size_t oldsz, size_t newsz, size_t alignment) -{ - /** @todo make this more efficient - * @see http://stackoverflow.com/a/9078627/5875572 - * @see look for qReallocAligned() in http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/global/qmalloc.cpp - */ - void *tmp = aalloc(newsz, alignment); - size_t min = newsz < oldsz ? newsz : oldsz; - ::memcpy(tmp, ptr, min); - afree(ptr); - return tmp; -} - -#endif // C4_NO_ALLOC_DEFAULTS - -C4_ALWAYS_INLINE alloc_type& get_alloc() -{ -#ifndef C4_NO_ALLOC_DEFAULTS - static alloc_type fn = &alloc_impl; -#else - static alloc_type fn = nullptr; -#endif - return fn; -} -C4_ALWAYS_INLINE aalloc_type& get_aalloc() -{ -#ifndef C4_NO_ALLOC_DEFAULTS - static aalloc_type fn = &aalloc_impl; -#else - static aalloc_type fn = nullptr; -#endif - return fn; -} - -C4_ALWAYS_INLINE free_type& get_free() -{ -#ifndef C4_NO_ALLOC_DEFAULTS - static free_type fn = &free_impl; -#else - static free_type fn = nullptr; -#endif - return fn; -} - -C4_ALWAYS_INLINE free_type& get_afree() -{ -#ifndef C4_NO_ALLOC_DEFAULTS - static free_type fn = &afree_impl; -#else - static free_type fn = nullptr; -#endif - return fn; -} - -C4_ALWAYS_INLINE realloc_type& get_realloc() -{ -#ifndef C4_NO_ALLOC_DEFAULTS - static realloc_type fn = &realloc_impl; -#else - static realloc_type fn = nullptr; -#endif - return fn; -} -C4_ALWAYS_INLINE arealloc_type& get_arealloc() -{ -#ifndef C4_NO_ALLOC_DEFAULTS - static arealloc_type fn = &arealloc_impl; -#else - static arealloc_type fn = nullptr; -#endif - return fn; -} - -C4_END_NAMESPACE(detail) - - -C4_ALWAYS_INLINE alloc_type get_alloc() -{ - return detail::get_alloc(); -} -C4_ALWAYS_INLINE void set_alloc(alloc_type fn) -{ - detail::get_alloc() = fn; -} - -C4_ALWAYS_INLINE aalloc_type get_aalloc() -{ - return detail::get_aalloc(); -} -C4_ALWAYS_INLINE void set_aalloc(aalloc_type fn) -{ - detail::get_aalloc() = fn; -} - -C4_ALWAYS_INLINE free_type get_free() -{ - return detail::get_free(); -} -C4_ALWAYS_INLINE void set_free(free_type fn) -{ - detail::get_free() = fn; -} - -C4_ALWAYS_INLINE free_type get_afree() -{ - return detail::get_afree(); -} -C4_ALWAYS_INLINE void set_afree(free_type fn) -{ - detail::get_afree() = fn; -} - -C4_ALWAYS_INLINE realloc_type get_realloc() -{ - return detail::get_realloc(); -} -C4_ALWAYS_INLINE void set_realloc(realloc_type fn) -{ - detail::get_realloc() = fn; -} - -C4_ALWAYS_INLINE arealloc_type get_arealloc() -{ - return detail::get_arealloc(); -} -C4_ALWAYS_INLINE void set_arealloc(arealloc_type fn) -{ - detail::get_arealloc() = fn; -} - - -inline void* alloc(size_t sz) -{ - C4_ASSERT_MSG(c4::get_alloc() != nullptr, "did you forget to call set_alloc()?"); - auto fn = c4::get_alloc(); - void* ptr = fn(sz); - return ptr; -} -inline void* aalloc(size_t sz, size_t alignment) -{ - C4_ASSERT_MSG(c4::get_aalloc() != nullptr, "did you forget to call set_aalloc()?"); - auto fn = c4::get_aalloc(); - void* ptr = fn(sz, alignment); - return ptr; -} -inline void free(void* ptr) -{ - C4_ASSERT_MSG(c4::get_free() != nullptr, "did you forget to call set_free()?"); - auto fn = c4::get_free(); - fn(ptr); -} -inline void afree(void* ptr) -{ - C4_ASSERT_MSG(c4::get_afree() != nullptr, "did you forget to call set_afree()?"); - auto fn = c4::get_afree(); - fn(ptr); -} - -inline void* realloc(void *ptr, size_t oldsz, size_t newsz) -{ - C4_ASSERT_MSG(c4::get_realloc() != nullptr, "did you forget to call set_realloc()?"); - auto fn = c4::get_realloc(); - void* nptr = fn(ptr, oldsz, newsz); - return nptr; -} -inline void* arealloc(void *ptr, size_t oldsz, size_t newsz, size_t alignment) -{ - C4_ASSERT_MSG(c4::get_arealloc() != nullptr, "did you forget to call set_arealloc()?"); - auto fn = c4::get_arealloc(); - void* nptr = fn(ptr, oldsz, newsz, alignment); - return nptr; -} - -C4_END_NAMESPACE(c4) - -#ifdef C4_REDEFINE_CPPNEW -#include -void* operator new(size_t size) -{ - return ::c4::alloc(size); -} -void operator delete(void *p) noexcept -{ - ::c4::free(p); -} -void operator delete(void *p, size_t) -{ - ::c4::free(p); -} -void* operator new[](size_t size) -{ - return operator new(size); -} -void operator delete[](void *p) noexcept -{ - operator delete(p); -} -void operator delete[](void *p, size_t) -{ - operator delete(p); -} -void* operator new(size_t size, std::nothrow_t) -{ - return operator new(size); -} -void operator delete(void *p, std::nothrow_t) -{ - operator delete(p); -} -void operator delete(void *p, size_t, std::nothrow_t) -{ - operator delete(p); -} -void* operator new[](size_t size, std::nothrow_t) -{ - return operator new(size); -} -void operator delete[](void *p, std::nothrow_t) -{ - operator delete(p); -} -void operator delete[](void *p, size_t, std::nothrow_t) -{ - operator delete(p); -} -#endif // C4_REDEFINE_CPPNEW - - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#endif //_C4_UTIL_HPP_ diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/.travis.yml.old b/third_party/rapidyaml/rapidyaml/ext/c4core/.github/.travis.yml.old deleted file mode 100644 index 94d1b5adc..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/.travis.yml.old +++ /dev/null @@ -1,108 +0,0 @@ -sudo: required -dist: bionic -language: cpp -env: - global: - # cmake is installed into /usr/bin - - PATH=/usr/bin:/usr/local/bin:$PATH - -# we're not using combination parameters here to ensure that the builds -# run in the order we want. (We want to perform the fastest tests first so -# failed tests appear as early as possible). - -# NOTE: The compiler setting is unused. It simply makes the display on -# travis-ci.org more readable. -# WARNING: do not use the name CXX. Travis will ignore the value here. -matrix: - - include: - # every entry does both 64 and 32 bit - # SAN := sanitizers - # VG := valgrind - - # coverage: in bionic, lcov is incompatible with g++8 and later - - env: CXX_=g++-7 BT=Coverage STD=11 - - env: CXX_=g++-7 BT=Coverage STD=14 - - env: CXX_=g++-7 BT=Coverage STD=17 - - - env: CXX_=g++-10 BT=Debug STD=11 VG=ON - - env: CXX_=g++-10 BT=Release STD=11 VG=ON - - env: CXX_=g++-10 BT=Debug STD=14 VG=ON - - env: CXX_=g++-10 BT=Release STD=14 VG=ON - - env: CXX_=g++-10 BT=Debug STD=17 VG=ON - - env: CXX_=g++-10 BT=Release STD=17 VG=ON - - env: CXX_=g++-10 BT=Debug STD=20 VG=ON - - env: CXX_=g++-10 BT=Release STD=20 VG=ON - - - env: CXX_=clang++-10 BT=Debug STD=11 SAN=ALL VG=ON - - env: CXX_=clang++-10 BT=Release STD=11 SAN=ALL VG=ON - - env: CXX_=clang++-10 BT=Debug STD=14 SAN=ALL VG=ON - - env: CXX_=clang++-10 BT=Release STD=14 SAN=ALL VG=ON - - env: CXX_=clang++-10 BT=Debug STD=17 SAN=ALL VG=ON - - env: CXX_=clang++-10 BT=Release STD=17 SAN=ALL VG=ON - - env: CXX_=clang++-10 BT=Debug STD=20 SAN=ALL VG=ON - - env: CXX_=clang++-10 BT=Release STD=20 SAN=ALL VG=ON - - - env: CXX_=g++-9 BT=Debug - - env: CXX_=g++-9 BT=Release - - env: CXX_=clang++-9 BT=Debug - - env: CXX_=clang++-9 BT=Release - - - env: CXX_=g++-8 BT=Debug - - env: CXX_=g++-8 BT=Release - - env: CXX_=clang++-8 BT=Debug - - env: CXX_=clang++-8 BT=Release - - - env: CXX_=g++-7 BT=Debug - - env: CXX_=g++-7 BT=Release - - env: CXX_=clang++-7 BT=Debug - - env: CXX_=clang++-7 BT=Release - - - env: CXX_=g++-6 BT=Debug - - env: CXX_=g++-6 BT=Release - - env: CXX_=clang++-6.0 BT=Debug - - env: CXX_=clang++-6.0 BT=Release - - - env: CXX_=g++-5 BT=Debug - - env: CXX_=g++-5 BT=Release - - env: CXX_=clang++-5.0 BT=Debug - - env: CXX_=clang++-5.0 BT=Release - - # gcc 4.9 is not available in 18.04 -- https://stackoverflow.com/questions/48398475/ - #- env: CXX_=g++-4.9 BT=Debug - #- env: CXX_=g++-4.9 BT=Release - - env: CXX_=clang++-4.0 BT=Debug - - env: CXX_=clang++-4.0 BT=Release - - - env: CXX_=clang++-3.9 BT=Debug - - env: CXX_=clang++-3.9 BT=Release - - # ----------- clang-tidy - # - - env: CXX_=clang++-9 BT=Debug LINT=clang-tidy - - env: CXX_=clang++-9 BT=Release LINT=clang-tidy - -install: - - bash -x .ci/travis-install.sh - -script: - - source .ci/travis-setenv.sh - - - c4core_cfg_test 64 dynamic - - c4core_run_test 64 dynamic - - - c4core_cfg_test 64 static - - c4core_run_test 64 static - - - c4core_cfg_test 32 static - - c4core_run_test 32 static - - - echo "Success!" - -after_success: - - source .ci/travis-setenv.sh - # coveralls only accepts one submission per job - #- c4core_submit_coverage 32 static coveralls - - c4core_submit_coverage 64 static coveralls - - c4core_submit_coverage 32 static codecov - - c4core_submit_coverage 64 static codecov diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/appveyor.yml.old b/third_party/rapidyaml/rapidyaml/ext/c4core/.github/appveyor.yml.old deleted file mode 100644 index 802f3de59..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/appveyor.yml.old +++ /dev/null @@ -1,82 +0,0 @@ -version: '{build}' - -image: Visual Studio 2019 - -environment: - matrix: - - - {GEN: Visual Studio 16 2019, ARCH: -A x64, CFG: Debug, compiler: msvc-16-seh} - - {GEN: Visual Studio 16 2019, ARCH: -A Win32, CFG: Debug, compiler: msvc-16-seh} - - {GEN: Visual Studio 16 2019, ARCH: -A x64, CFG: Release, compiler: msvc-16-seh} - - {GEN: Visual Studio 16 2019, ARCH: -A Win32, CFG: Release, compiler: msvc-16-seh} - - {GEN: Visual Studio 16 2019, ARCH: -A x64, STD: -D C4_CXX_STANDARD=20, CFG: Debug, compiler: msvc-16-seh} - - {GEN: Visual Studio 16 2019, ARCH: -A x64, STD: -D C4_CXX_STANDARD=17, CFG: Debug, compiler: msvc-16-seh} - - {GEN: Visual Studio 16 2019, ARCH: -A x64, STD: -D C4_CXX_STANDARD=14, CFG: Debug, compiler: msvc-16-seh} - - - {GEN: Visual Studio 15 2017 Win64, CFG: Debug, APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017, compiler: msvc-15-seh} - - {GEN: Visual Studio 15 2017, CFG: Debug, APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017, compiler: msvc-15-seh} - - {GEN: Visual Studio 15 2017 Win64, CFG: Release, APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017, compiler: msvc-15-seh} - - {GEN: Visual Studio 15 2017, CFG: Release, APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017, compiler: msvc-15-seh} - - #- compiler: gcc-5.3.0-posix - # GEN: "MinGW Makefiles" - # cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin' - # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - # CFG: Quicktest - # externconfig: Debug - - -matrix: - fast_finish: true - -install: - - git submodule update --init --recursive - # git bash conflicts with MinGW makefiles - - set "PATH=%PATH:C:\Program Files\Git\usr\bin;=%" - - if not "%cxx_path%"=="" (set "PATH=%PATH%;%cxx_path%") - - cmake --version - -build_script: - - echo %GEN% - - echo %ARCH% - - echo %CFG% - - echo %STD% - - set NUM_JOBS=3 - - set PROJ_DIR=%cd% - - set BUILD_DIR=%PROJ_DIR%\build - - set INSTALL_DIR=%PROJ_DIR%\install - - set C4_EXTERN_DIR=%BUILD_DIR%\extern - - md %BUILD_DIR% - - md %BUILD_DIR%\static %BUILD_DIR%\shared %BUILD_DIR%\extern - - cmake -S %PROJ_DIR% -B %BUILD_DIR%\static %STD% -DC4CORE_DEV=ON -G "%GEN%" %ARCH% "-DCMAKE_BUILD_TYPE=%CFG%" "-DCMAKE_INSTALL_PREFIX=%INSTALL_DIR%\static" -DBUILD_SHARED_LIBS=OFF - - cmake -S %PROJ_DIR% -B %BUILD_DIR%\shared %STD% -DC4CORE_DEV=ON -G "%GEN%" %ARCH% "-DCMAKE_BUILD_TYPE=%CFG%" "-DCMAKE_INSTALL_PREFIX=%INSTALL_DIR%\shared" -DBUILD_SHARED_LIBS=ON - - cmake --build %BUILD_DIR%\static --config %configuration% --target test-build --parallel %NUM_JOBS% - - cmake --build %BUILD_DIR%\shared --config %configuration% --target test-build --parallel %NUM_JOBS% - -test_script: - - cmake --build %BUILD_DIR%\static --config %configuration% --target test - - cmake --build %BUILD_DIR%\shared --config %configuration% --target test - -#artifacts: -# - path: '_build/CMakeFiles/*.log' -# name: logs -# - path: '_build/Testing/**/*.xml' -# name: test_results - -skip_commits: - files: - - .gitignore - - .travis* - - .ci/travis* - - .ci/dev_* - - .ci/show_* - - .ci/vagrant* - - .ci/Vagrant* - - bm/html/* - - doc/* - - img/* - - CHANGELOG.md - - CONTRIBUTING.md - - LICENSE.txt - - README.* - - ROADMAP.* diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/reqs.sh b/third_party/rapidyaml/rapidyaml/ext/c4core/.github/reqs.sh deleted file mode 100644 index 84d122d58..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/reqs.sh +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env bash - -# input environment variables: -# OS: the operating system -# CXX_: the compiler version. eg, g++-9 or clang++-6.0 -# BT: the build type -# VG: whether to install valgrind -# ARM: whether to arm cross-compiler and emulator -# GITHUB_WORKFLOW: when run from github - - -#------------------------------------------------------------------------------- - -function c4_install_test_requirements() -{ - # this is only for ubuntu ------------------ - os=$1 - case "$os" in - ubuntu*) ;; - win*) - if [ "$API" == "ON" ] ; then - choco install swig - which swig - fi - return 0 - ;; - *) - return 0 - ;; - esac - - # gather all the requirements ------------------ - - APT_PKG="" - PIP_PKG="" - - if [ "$GITHUB_WORKFLOW" != "" ] ; then - sudo dpkg --add-architecture i386 - else - # travis requires build-essential + cmake - _add_apt build-essential - _add_apt cmake - fi - - _add_apt linux-libc-dev:i386 - _add_apt libc6:i386 - _add_apt libc6-dev:i386 - _add_apt libc6-dbg:i386 - - _c4_gather_compilers "$CXX_" - - #_add_apt iwyu - #_add_apt cppcheck - #_add_pip cpplint - if [ "$VG" == "ON" ] ; then - _add_apt valgrind - fi - - if [ "$BT" == "Coverage" ]; then - _add_apt lcov - _add_apt libffi-dev - _add_apt libssl-dev - _add_pip requests[security] - _add_pip pyopenssl - _add_pip ndg-httpsclient - _add_pip pyasn1 - _add_pip cpp-coveralls - fi - - if [ "$PIP_PKG" != "" ]; then - _add_apt python3-setuptools - _add_apt python3-pip - fi - - case "$CXX_" in - arm*) - _add_apt gcc-arm-embedded - _add_apt g++-arm-linux-gnueabihf - _add_apt qemu - # this is going to be deprecated: - # https://askubuntu.com/questions/1243252/how-to-install-arm-none-eabi-gdb-on-ubuntu-20-04-lts-focal-fossa - sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa - ;; - esac - - wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - - sudo -E apt-add-repository --yes 'deb https://apt.kitware.com/ubuntu/ bionic main' - sudo -E add-apt-repository --yes ppa:ubuntu-toolchain-r/test - - echo "apt packages: $APT_PKG" - echo "pip packages: $PIP_PKG" - - # now install the requirements ------------------ - - if [ "$APT_PKG" != "" ] ; then - #sudo -E apt-get clean - sudo -E apt-get update - sudo -E apt-get install -y --force-yes $APT_PKG - fi - - if [ "$PIP_PKG" != "" ]; then - sudo pip3 install $PIP_PKG - fi - - echo 'INSTALL COMPLETE!' -} - - -#------------------------------------------------------------------------------- - -function _c4_gather_compilers() -{ - cxx=$1 - case $cxx in - g++-10 ) _c4_addgcc 10 ;; - g++-9 ) _c4_addgcc 9 ;; - g++-8 ) _c4_addgcc 8 ;; - g++-7 ) _c4_addgcc 7 ;; - g++-6 ) _c4_addgcc 6 ;; - g++-5 ) _c4_addgcc 5 ;; - #g++-4.9 ) _c4_addgcc 4.9 ;; # https://askubuntu.com/questions/1036108/install-gcc-4-9-at-ubuntu-18-04 - clang++-10 ) _c4_addclang 10 ;; - clang++-9 ) _c4_addclang 9 ;; - clang++-8 ) _c4_addclang 8 ;; - clang++-7 ) _c4_addclang 7 ;; - clang++-6.0) _c4_addclang 6.0 ;; - clang++-5.0) _c4_addclang 5.0 ;; - clang++-4.0) _c4_addclang 4.0 ;; - clang++-3.9) _c4_addclang 3.9 ;; - all) - all="g++-10 g++-9 g++-8 g++-7 g++-6 g++-5 g++-4.9 clang++-10 clang++-9 clang++-8 clang++-7 clang++-6.0 clang++-5.0 clang++-4.0 clang++-3.9" - echo "installing all compilers: $all" - for cxx in $all ; do - _c4_gather_compilers $cxx - done - ;; - "") - # use default compiler - ;; - arm*) - ;; - *) - echo "unknown compiler: $cxx" - exit 1 - ;; - esac -} - -# add a gcc compiler -function _c4_addgcc() -{ - version=$1 - _add_apt g++-$version - _add_apt g++-$version-multilib -} - -# add a clang compiler -function _c4_addclang() -{ - version=$1 - case $version in - # in 18.04, clang9 and later require PPAs - 9 | 10 ) _add_apt clang-$version "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-$version main" ;; - * ) _add_apt clang-$version ;; - esac - _add_apt g++-multilib # this is required for 32 bit https://askubuntu.com/questions/1057341/unable-to-find-stl-headers-in-ubuntu-18-04 - _add_apt clang-tidy-$version - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key 2>/dev/null | sudo apt-key add - -} - - -#------------------------------------------------------------------------------- - -# add a pip package to the list -function _add_pip() -{ - pkgs=$* - PIP_PKG="$PIP_PKG $pkgs" - echo "adding to pip packages: $pkgs" -} - -# add a debian package to the list -function _add_apt() -{ - pkgs=$1 - sourceslist=$2 - APT_PKG="$APT_PKG $pkgs" - echo "adding to apt packages: $pkgs" - _add_src "$sourceslist" "# for packages: $pkgs" - #echo "APT_PKG=$APT_PKG" -} - -# add an apt source -function _add_src() -{ - sourceslist=$1 - comment=$2 - if [ ! -z "$sourceslist" ] ; then - echo "adding apt source: $sourceslist" - sudo bash -c "cat >> /etc/apt/sources.list < $coverage_service" - cmake --build $build_dir --config $BT --target ${PROJ_PFX_TARGET}coverage-submit-$coverage_service -} - -# WIP -function c4_run_static_analysis() -{ - if _c4skipbitlink "$1" ; then return 0 ; fi - id=$1 - linktype=$(_c4linktype $id) - build_dir=`pwd`/build/$id - # https://blog.kitware.com/static-checks-with-cmake-cdash-iwyu-clang-tidy-lwyu-cpplint-and-cppcheck/ - pushd $PROJ_DIR -} - -function c4_cfg_test() -{ - if _c4skipbitlink "$1" ; then return 0 ; fi - id=$1 - # - build_dir=`pwd`/build/$id - install_dir=`pwd`/install/$id - mkdir -p $build_dir - mkdir -p $install_dir - # - if [ "$TOOLCHAIN" != "" ] ; then - toolchain_file=`pwd`/$TOOLCHAIN - if [ ! -f "$toolchain_file" ] ; then - echo "ERROR: toolchain not found: $toolchain_file" - exit 1 - fi - _addcmkflags -DCMAKE_TOOLCHAIN_FILE=$toolchain_file - else - bits=$(_c4bits $id) - linktype=$(_c4linktype $id) - case "$linktype" in - static) _addcmkflags -DBUILD_SHARED_LIBS=OFF ;; - shared) _addcmkflags -DBUILD_SHARED_LIBS=ON ;; - *) - echo "ERROR: unknown linktype: $linktype" - exit 1 - ;; - esac - fi - if [ "$STD" != "" ] ; then - _addcmkflags -DC4_CXX_STANDARD=$STD - _addprojflags CXX_STANDARD=$STD - fi - # - if [ "$DEV" != "OFF" ] ; then - _addprojflags DEV=ON - fi - case "$LINT" in - all ) _addprojflags LINT=ON LINT_TESTS=ON LINT_CLANG_TIDY=ON LINT_PVS_STUDIO=ON ;; - clang-tidy) _addprojflags LINT=ON LINT_TESTS=ON LINT_CLANG_TIDY=ON LINT_PVS_STUDIO=OFF ;; - pvs-studio) _addprojflags LINT=ON LINT_TESTS=ON LINT_CLANG_TIDY=OFF LINT_PVS_STUDIO=ON ;; - * ) _addprojflags LINT=OFF ;; - esac - case "$SAN" in - ALL) _addprojflags SANITIZE=ON ;; - A ) _addprojflags SANITIZE=ON ASAN=ON TSAN=OFF MSAN=OFF UBSAN=OFF ;; - T ) _addprojflags SANITIZE=ON ASAN=OFF TSAN=ON MSAN=OFF UBSAN=OFF ;; - M ) _addprojflags SANITIZE=ON ASAN=OFF TSAN=OFF MSAN=ON UBSAN=OFF ;; - UB ) _addprojflags SANITIZE=ON ASAN=OFF TSAN=OFF MSAN=OFF UBSAN=ON ;; - * ) _addprojflags SANITIZE=OFF ;; - esac - case "$SAN_ONLY" in - ON) _addprojflags SANITIZE_ONLY=ON ;; - * ) _addprojflags SANITIZE_ONLY=OFF ;; - esac - case "$VG" in - ON) _addprojflags VALGRIND=ON VALGRIND_SGCHECK=OFF ;; # FIXME SGCHECK should be ON - * ) _addprojflags VALGRIND=OFF VALGRIND_SGCHECK=OFF ;; - esac - case "$BM" in - ON) _addprojflags BUILD_BENCHMARKS=ON ;; - * ) _addprojflags BUILD_BENCHMARKS=OFF ;; - esac - if [ "$BT" == "Coverage" ] ; then - # the coverage repo tokens can be set in the travis environment: - # export CODECOV_TOKEN=....... - # export COVERALLS_REPO_TOKEN=....... - _addprojflags COVERAGE_CODECOV=ON COVERAGE_CODECOV_SILENT=ON - _addprojflags COVERAGE_COVERALLS=ON COVERAGE_COVERALLS_SILENT=ON - fi - _addcmkflags -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - if [ ! -z "$CMAKE_FLAGS" ] ; then - _addcmkflags $CMAKE_FLAGS - fi - - echo "building with additional cmake flags: $CMFLAGS" - - export C4_EXTERN_DIR=`pwd`/build/extern - mkdir -p $C4_EXTERN_DIR - - cmake --version - pwd - - # - # bash quote handling is a fiasco, and I could not find a way of storing - # quoted strings in variables and then expand the variables with correct quotes - # so we have to do this precious jewell of chicanery: - case "$CXX_" in - vs2019) - g='Visual Studio 16 2019' - case "$bits" in - 64) a=x64 ;; - 32) a=Win32 ;; - esac - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT -G "$g" -A $a $CMFLAGS - ;; - vs2017) - case "$bits" in - 64) g="Visual Studio 15 2017 Win64" ;; - 32) g="Visual Studio 15 2017" ;; - esac - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT -G "$g" $CMFLAGS - ;; - xcode) - g=Xcode - case "$bits" in - 64) a="x86_64" ;; - 32) a="i386" - exit 1 # i386 is deprecated in xcode - ;; - esac - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT -G "$g" -DCMAKE_OSX_ARCHITECTURES=$a $CMFLAGS - ;; - arm*|"") # make sure arm* comes before *g++ or *gcc* - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT $CMFLAGS - ;; - *g++*|*gcc*|*clang*) - export CC_=$(echo "$CXX_" | sed 's:clang++:clang:g' | sed 's:g++:gcc:g') - _c4_choose_clang_tidy $CXX_ - cmake -S $PROJ_DIR -B $build_dir -DCMAKE_INSTALL_PREFIX="$install_dir" \ - -DCMAKE_BUILD_TYPE=$BT $CMFLAGS \ - -DCMAKE_C_COMPILER=$CC_ -DCMAKE_CXX_COMPILER=$CXX_ \ - -DCMAKE_C_FLAGS="-std=c99 -m$bits" -DCMAKE_CXX_FLAGS="-m$bits" - cmake --build $build_dir --target help | sed 1d | sort - ;; - *) - echo "unknown compiler" - exit 1 - ;; - esac -} - -function _c4_choose_clang_tidy() -{ - cxx=$1 - # only for clang compilers. - case $cxx in - clang*) - # try with version first - clang_tidy_ver=$(echo $cxx | sed "s:++:-tidy:") - clang_tidy=$(echo $cxx | sed "s:++.*:-tidy:") - for n in $clang_tidy_ver $clang_tidy ; do - exe=$(which $n) - echo "searching for $n: $exe" - if [ -z "$exe" ] ; then - echo "could not find $clang_tidy" - else - _addcmkflags "-DCLANG_TIDY=$exe" - return 0 - fi - done - echo "error: could not find clang-tidy for $cxx" - exit 1 - ;; - esac -} - -# add cmake flags without project prefix -function _addcmkflags() -{ - for f in $* ; do - CMFLAGS="$CMFLAGS ${f}" - done -} - -# add cmake flags with project prefix -function _addprojflags() -{ - for f in $* ; do - CMFLAGS="$CMFLAGS -D${PROJ_PFX_CMAKE}${f}" - done -} - -function _c4_parallel_build_flags() -{ - case "$CXX_" in - vs2019|vs2017|vs2015) - # https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2019 - # https://stackoverflow.com/questions/2619198/how-to-get-number-of-cores-in-win32 - if [ -z "$NUM_JOBS_BUILD" ] ; then - echo "/maxcpucount:$NUMBER_OF_PROCESSORS" - else - echo "/maxcpucount:$NUM_JOBS_BUILD" - fi - ;; - xcode) - # https://stackoverflow.com/questions/5417835/how-to-modify-the-number-of-parallel-compilation-with-xcode - # https://gist.github.com/nlutsenko/ee245fbd239087d22137 - if [ -z "$NUM_JOBS_BUILD" ] ; then - echo "-IDEBuildOperationMaxNumberOfConcurrentCompileTasks=$(sysctl -n hw.ncpu)" - else - echo "-IDEBuildOperationMaxNumberOfConcurrentCompileTasks=$NUM_JOBS_BUILD" - fi - ;; - *g++*|*gcc*|*clang*) - if [ -z "$NUM_JOBS_BUILD" ] ; then - echo "-j $(nproc)" - else - echo "-j $NUM_JOBS_BUILD" - fi - ;; - "") # allow empty compiler - ;; - *) - echo "unknown compiler" - exit 1 - ;; - esac -} - -function _c4_generator_build_flags() -{ - case "$CXX_" in - vs2019|vs2017|vs2015) - ;; - xcode) - # WTF??? - # https://github.com/biojppm/rapidyaml/pull/97/checks?check_run_id=1504677928#step:7:964 - # https://stackoverflow.com/questions/51153525/xcode-10-unable-to-attach-db-error - echo "-UseModernBuildSystem=NO" - ;; - *g++*|*gcc*|*clang*) - ;; - "") # allow empty compiler - ;; - *) - echo "unknown compiler" - exit 1 - ;; - esac -} diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/vagrant/Vagrantfile b/third_party/rapidyaml/rapidyaml/ext/c4core/.github/vagrant/Vagrantfile deleted file mode 100644 index 1a9031c34..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/vagrant/Vagrantfile +++ /dev/null @@ -1,80 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# 1) download and install vagrant: https://www.vagrantup.com/downloads.html -# (do not install ubuntu's 14.04 16.04 version, see https://stackoverflow.com/questions/22717428/vagrant-error-failed-to-mount-folders-in-linux-guest ): -# 2) vagrant plugin install vagrant-vbguest -# 3) vagrant up --provider virtualbox -# 4) vagrant ssh - -# All Vagrant configuration is done below. The "2" in Vagrant.configure -# configures the configuration version (we support older styles for -# backwards compatibility). Please don't change it unless you know what -# you're doing. -Vagrant.configure(2) do |config| - # The most common configuration options are documented and commented below. - # For a complete reference, please see the online documentation at - # https://docs.vagrantup.com. - - # Every Vagrant development environment requires a box. You can search for - # boxes at https://atlas.hashicorp.com/search. - config.vm.box = "generic/ubuntu1804" - - # Disable automatic box update checking. If you disable this, then - # boxes will only be checked for updates when the user runs - # `vagrant box outdated`. This is not recommended. - # config.vm.box_check_update = false - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - # config.vm.network "forwarded_port", guest: 80, host: 8080 - - #config.ssh.username = 'travis' - #config.ssh.password = 'travis' - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - # config.vm.network "private_network", ip: "192.168.33.10" - - # Create a public network, which generally matched to bridged network. - # Bridged networks make the machine appear as another physical device on - # your network. - # config.vm.network "public_network" - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - config.vm.synced_folder "../..", "/vagrant" - - #config.vm.synced_folder '.', '/vagrant', disabled: true - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider "virtualbox" do |vb| - # # Display the VirtualBox GUI when booting the machine - # vb.gui = true - # - # # Customize the amount of memory on the VM: - # vb.memory = "1024" - # end - # - # View the documentation for the provider you are using for more - # information on available options. - - # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies - # such as FTP and Heroku are also available. See the documentation at - # https://docs.vagrantup.com/v2/push/atlas.html for more information. - # config.push.define "atlas" do |push| - # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME" - # end - - # Enable provisioning with a shell script. Additional provisioners such as - # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the - # documentation for more information about their specific syntax and use. - #config.vm.provision "shell", path: "travis-install.sh" - -end diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/vagrant/macos/Vagrantfile b/third_party/rapidyaml/rapidyaml/ext/c4core/.github/vagrant/macos/Vagrantfile deleted file mode 100644 index 62806c970..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/vagrant/macos/Vagrantfile +++ /dev/null @@ -1,71 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# All Vagrant configuration is done below. The "2" in Vagrant.configure -# configures the configuration version (we support older styles for -# backwards compatibility). Please don't change it unless you know what -# you're doing. -Vagrant.configure("2") do |config| - # The most common configuration options are documented and commented below. - # For a complete reference, please see the online documentation at - # https://docs.vagrantup.com. - - # Every Vagrant development environment requires a box. You can search for - # boxes at https://vagrantcloud.com/search. - config.vm.box = "ramsey/macos-catalina" - config.vm.box_version = "1.0.0" - - # Disable automatic box update checking. If you disable this, then - # boxes will only be checked for updates when the user runs - # `vagrant box outdated`. This is not recommended. - # config.vm.box_check_update = false - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - # NOTE: This will enable public access to the opened port - # config.vm.network "forwarded_port", guest: 80, host: 8080 - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine and only allow access - # via 127.0.0.1 to disable public access - # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - # config.vm.network "private_network", ip: "192.168.33.10" - - # Create a public network, which generally matched to bridged network. - # Bridged networks make the machine appear as another physical device on - # your network. - # config.vm.network "public_network" - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - # config.vm.synced_folder "../data", "/vagrant_data" - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider "virtualbox" do |vb| - # # Display the VirtualBox GUI when booting the machine - # vb.gui = true - # - # # Customize the amount of memory on the VM: - # vb.memory = "1024" - # end - # - # View the documentation for the provider you are using for more - # information on available options. - - # Enable provisioning with a shell script. Additional provisioners such as - # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the - # documentation for more information about their specific syntax and use. - # config.vm.provision "shell", inline: <<-SHELL - # apt-get update - # apt-get install -y apache2 - # SHELL -end diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/vagrant/vagrant-provision.sh b/third_party/rapidyaml/rapidyaml/ext/c4core/.github/vagrant/vagrant-provision.sh deleted file mode 100755 index 75384253e..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.github/vagrant/vagrant-provision.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -set -x - -# https://askubuntu.com/questions/735201/installing-clang-3-8-on-ubuntu-14-04-3 -wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add - - -done=$(grep C4STL /etc/apt/sources.list) -if [ -z "$done" ] ; then - cat >> /etc/apt/sources.list < ./upload_url - - name: Upload Release URL - uses: actions/upload-artifact@v1 - with: - path: ./upload_url - name: upload_url - - #---------------------------------------------------------------------------- - publish: - needs: release - name: publish/${{matrix.config.os}}/${{matrix.config.gen}} - runs-on: ${{matrix.config.os}} - env: {DEV: OFF, BT: Release, OS: "${{matrix.config.os}}", CXX_: "${{matrix.config.cxx}}", GEN: "${{matrix.config.gen}}"} - strategy: - fail-fast: false - matrix: - config: - # name of the artifact | suffix | cpack gen | mime type | os | cxx - - {name: Ubuntu 20.04 deb , sfx: unix64.deb, gen: DEB , mime: vnd.debian.binary-package, os: ubuntu-20.04 } - - {name: Ubuntu 20.04 sh , sfx: unix64.sh , gen: STGZ , mime: x-sh , os: ubuntu-20.04 } - - {name: Ubuntu 18.04 deb , sfx: unix64.deb, gen: DEB , mime: vnd.debian.binary-package, os: ubuntu-18.04 } - - {name: Ubuntu 18.04 sh , sfx: unix64.sh , gen: STGZ , mime: x-sh , os: ubuntu-18.04 } - - {name: Ubuntu 16.04 deb , sfx: unix64.deb, gen: DEB , mime: vnd.debian.binary-package, os: ubuntu-16.04 } - - {name: Ubuntu 16.04 sh , sfx: unix64.sh , gen: STGZ , mime: x-sh , os: ubuntu-16.04 } - - {name: Windows VS2017 zip, sfx: win64.zip , gen: ZIP , mime: zip , os: windows-2016, cxx: vs2017} - - {name: Windows VS2019 zip, sfx: win64.zip , gen: ZIP , mime: zip , os: windows-2019, cxx: vs2019} - - {name: MacOSX sh , sfx: apple64.sh, gen: STGZ , mime: x-sh , os: macos-11.0 , cxx: xcode } - steps: - - name: Get version - id: get_version - # https://github.community/t/how-to-get-just-the-tag-name/16241/11 - run: | - echo ::set-output name=SRC_VERSION::${GITHUB_REF#refs/tags/v} - echo SRC_VERSION=${GITHUB_REF#refs/tags/v} - echo GEN=$GEN - - name: Download upload URL - uses: actions/download-artifact@v1 - with: {name: upload_url, path: ./} - - name: Preprocess - id: preprocess - run: | - upload_url=`cat ./upload_url` - echo ::set-output name=upload_url::$upload_url - # the package has the same name in multiple same-platform+same-sfx - # instances, but the uploaded asset needs to have different names: - sfx=${{matrix.config.sfx}} - case "${{matrix.config.os}}" in - ubuntu*) - sfx=$(echo $sfx | sed "s:unix64:${{matrix.config.os}}:") - ;; - windows*) - sfx=$(echo $sfx | sed "s:win64:win64-${{matrix.config.cxx}}:") - ;; - macos*) - sfx=$(echo $sfx | sed "s:apple64:macosx-${{matrix.config.cxx}}:") - ;; - esac - asset_name=${PROJ_PFX_TARGET}${{steps.get_version.outputs.SRC_VERSION}}-$sfx - echo ::set-output name=asset_name::$asset_name - - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - - {name: install requirements, run: source .github/reqs.sh && c4_install_test_requirements $OS} - - {name: show info, run: source .github/setenv.sh && c4_show_info } - - name: shared64-configure--------------------------------------------------- - run: source .github/setenv.sh && c4_cfg_test shared64 - - {name: shared64-build, run: source .github/setenv.sh && c4_build_target shared64} - - name: shared64-pack - run: | - source .github/setenv.sh && c4_package shared64 $GEN - src=./build/shared64/${PROJ_PFX_TARGET}${{steps.get_version.outputs.SRC_VERSION}}-${{matrix.config.sfx}} - dst=${{steps.preprocess.outputs.asset_name}} - cp -fav $src $dst - - name: Upload artifact - id: upload_to_release - uses: actions/upload-release-asset@v1.0.1 - env: {GITHUB_TOKEN: "${{secrets.GITHUB_TOKEN}}"} - with: - upload_url: ${{steps.preprocess.outputs.upload_url}} - asset_path: ${{steps.preprocess.outputs.asset_name}} - asset_name: ${{steps.preprocess.outputs.asset_name}} - asset_content_type: application/${{matrix.config.mime}} - #- name: Report artifact URL - # run: echo "artifact uploaded successfully: ${{steps.upload_to_release.outputs.browser_download_url}}" diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.gitignore b/third_party/rapidyaml/rapidyaml/ext/c4core/.gitignore deleted file mode 100644 index 72492ffa6..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.gitignore +++ /dev/null @@ -1,31 +0,0 @@ -# text editor files -*.bck -\#* -*~ -.ccls-cache/ -.clangd/ -.cache/ -.cquery_cached_index/ - -# Visual Studio files -.vs/ -.vscode/ -# QtCreator files -CMakeLists.txt.user -# Eclipse -.project -.cproject -/.settings/ - -# build files -build/ -install/ -.python-version -compile_commands.json - -# test files -/Testing/ - -# continuous integration files -.github/vagrant/.vagrant -.github/vagrant/macos/.vagrant diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/.gitmodules b/third_party/rapidyaml/rapidyaml/ext/c4core/.gitmodules deleted file mode 100644 index 77f89eae3..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule "cmake"] - path = cmake - url = https://github.com/biojppm/cmake -[submodule "extern/debugbreak"] - path = src/c4/ext/debugbreak - url = https://github.com/biojppm/debugbreak -[submodule "src/c4/ext/fast_float"] - path = src/c4/ext/fast_float - url = https://github.com/fastfloat/fast_float diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/CMakeLists.txt b/third_party/rapidyaml/rapidyaml/ext/c4core/CMakeLists.txt deleted file mode 100644 index 2dd1a7481..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/CMakeLists.txt +++ /dev/null @@ -1,87 +0,0 @@ -cmake_minimum_required(VERSION 3.12 FATAL_ERROR) -include(./cmake/c4Project.cmake) -project(c4core - DESCRIPTION "Multiplatform low-level C++ utilities" - HOMEPAGE_URL "https://github.com/biojppm/c4core" - LANGUAGES CXX) -c4_project(VERSION 0.0.1 - AUTHOR "Joao Paulo Magalhaes ") - -c4_add_library(c4core - INC_DIRS - $ $ - SOURCE_ROOT ${C4CORE_SRC_DIR} - SOURCES - c4/allocator.hpp - c4/base64.hpp - c4/base64.cpp - c4/blob.hpp - c4/bitmask.hpp - c4/charconv.hpp - c4/c4_pop.hpp - c4/c4_push.hpp - c4/char_traits.cpp - c4/char_traits.hpp - c4/common.hpp - c4/compiler.hpp - c4/config.hpp - c4/cpu.hpp - c4/ctor_dtor.hpp - c4/enum.hpp - c4/error.cpp - c4/error.hpp - c4/export.hpp - c4/format.hpp - c4/format.cpp - c4/hash.hpp - c4/language.hpp - c4/language.cpp - c4/memory_resource.cpp - c4/memory_resource.hpp - c4/memory_util.cpp - c4/memory_util.hpp - c4/platform.hpp - c4/preprocessor.hpp - c4/restrict.hpp - c4/span.hpp - c4/std/std.hpp - c4/std/string.hpp - c4/std/tuple.hpp - c4/std/vector.hpp - c4/substr.hpp - c4/substr_fwd.hpp - c4/szconv.hpp - c4/time.hpp - c4/time.cpp - c4/type_name.hpp - c4/types.hpp - c4/unrestrict.hpp - c4/windows.hpp - c4/windows_pop.hpp - c4/windows_push.hpp - c4/c4core.natvis - # - c4/ext/debugbreak/debugbreak.h - c4/ext/rng/rng.hpp - c4/ext/sg14/inplace_function.h - c4/ext/fast_float.hpp - c4/ext/fast_float/include/fast_float/ascii_number.h - c4/ext/fast_float/include/fast_float/decimal_to_binary.h - c4/ext/fast_float/include/fast_float/fast_float.h - c4/ext/fast_float/include/fast_float/fast_table.h - c4/ext/fast_float/include/fast_float/float_common.h - c4/ext/fast_float/include/fast_float/parse_number.h - c4/ext/fast_float/include/fast_float/simple_decimal_conversion.h -) - - -#------------------------------------------------------- - -c4_install_target(c4core) -c4_install_exports() -c4_pack_project() - -c4_add_dev_targets() - -c4_set_default_pack_properties(TYPE LIBRARY) -include(CPack) diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/LICENSE.txt b/third_party/rapidyaml/rapidyaml/ext/c4core/LICENSE.txt deleted file mode 100644 index 47b6b4394..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2018, Joao Paulo Magalhaes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/README.md b/third_party/rapidyaml/rapidyaml/ext/c4core/README.md deleted file mode 100644 index 46f03425b..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/README.md +++ /dev/null @@ -1,212 +0,0 @@ -# c4core - C++ core utilities - -[![MIT Licensed](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/biojppm/c4core/blob/master/LICENSE.txt) -[![ci](https://github.com/biojppm/c4core/workflows/ci/badge.svg)](https://github.com/biojppm/c4core/actions?query=ci) -[![Coverage: coveralls](https://coveralls.io/repos/github/biojppm/c4core/badge.svg)](https://coveralls.io/github/biojppm/c4core) -[![Coverage: codecov](https://codecov.io/gh/biojppm/c4core/branch/master/graph/badge.svg)](https://codecov.io/gh/biojppm/c4core) -[![LGTM alerts](https://img.shields.io/lgtm/alerts/g/biojppm/c4core.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/biojppm/c4core/alerts/) -[![LGTM grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/biojppm/c4core.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/biojppm/c4core/context:cpp) - - -c4core is a library of low-level C++ utilities, written with low-latency -projects in mind. - -Some of the utilities provided by c4core have already equivalent -functionality in the C++ standard, but they are provided as the existing C++ -equivalent may be insufficient (eg, std::string_view), inefficient (eg, -std::string), heavy (eg streams), or plainly unusable on some -platforms/projects, (eg exceptions); some other utilities have equivalent -under consideration for C++ standardisation; and yet some other utilities -have (to my knowledge) no equivalent under consideration. Be that as it may, -I've been using these utilities in this or similar forms for some years now, -and I've found them incredibly useful in my projects. I'm packing these as a -separate library, as all of my projects use it. - - -## Obtaining c4core - -c4core uses git submodules. It is best to clone c4core with the `--recursive` -option: - -```bash -# using --recursive makes sure git submodules are also cloned at the same time -git clone --recursive https://github.com/biojppm/c4core -``` - -If you ommit the `--recursive` option, then after cloning you will have to -make git checkout the current version of the submodules, using `git submodule -init` followed by `git submodule update`. - - -## Using c4core in your project - -c4core is built with cmake, and assumes you also use cmake. Although c4core -is NOT header-only, and currently has no install target, you can very easily -use c4core in your project by using -`add_subdirectory(${path_to_c4core_root})` in your CMakeLists.txt; this will -add c4core as a subproject of your project. Doing this is not intrusive to -your cmake project because c4core is fast to build (typically under 10s), and -it also prefixes every cmake variable with `C4CORE_`. But more importantly -this will enable you to compile c4core with the exact same compile settings -used by your project. - -Here's a very quick complete example of setting up your project to use -c4core: - -```cmake -project(foo) - -add_subdirectory(c4core) - -add_library(foo foo.cpp) -target_link_libraries(foo PUBLIC c4core) # that's it! -``` - -Note above that the call to `target_link_libraries()` is using PUBLIC -linking. This is required to make sure the include directories from `c4core` -are transitively used. - - -## Quick tour - -All of the utilities in this library are under the namespace `c4`; any -exposed macros use the prefix `C4_`: eg `C4_ASSERT()`. - -### Multi-platform / multi-compiler utilities - -```c++ -// TODO: elaborate on the topics: -#include - -C4_LIKELY()/C4_UNLIKELY() - -C4_RESTRICT, $, c$, $$, c$$ -#include -#include - -#include -#include - -C4_UNREACHABLE() - -c4::type_name() -``` - -### Runtime assertions and error handling - -```c++ -// TODO: elaborate on the topics: - -error callback - -C4_ASSERT() -C4_XASSERT() -C4_CHECK() - -C4_ERROR() -C4_NOT_IMPLEMENTED() -``` - -### Memory allocation - -```c++ -// TODO: elaborate on the topics: - -c4::aalloc(), c4::afree() // aligned allocation - -c4::MemoryResource // global and scope - -c4::Allocator -``` - -### Mass initialization/construction/destruction - -```c++ -// TODO: elaborate on the topics: - -c4::construct()/c4::construct_n() - -c4::destroy()/c4::destroy_n() - -c4::copy_construct()/c4::copy_construct_n() - -c4::copy_assign()/c4::copy_assign_n() - -c4::move_construct()/c4::move_construct_n() - -c4::move_assign()/c4::move_assign_n() - -c4::make_room()/c4::destroy_room() -``` - - -### Writeable string views: c4::substr and c4::csubstr - -Here: [`#include `](src/c4/substr.hpp) - - -### Value <-> character interoperation - -Here: [`#include `](src/c4/charconv.hpp) - -```c++ -// TODO: elaborate on the topics: - -c4::utoa(), c4::atou() -c4::itoa(), c4::atoi() -c4::ftoa(), c4::atof() -c4::dtoa(), c4::atod() - -c4::to_chars(), c4::from_chars() -c4::to_chars_sub() -c4::to_chars_first() -``` - -### String formatting and parsing - -* [`#include `](src/c4/format.hpp) - -```c++ -// TODO: elaborate on the topics: - -c4::cat(), c4::uncat() - -c4::catsep(), c4::uncatsep() - -c4::format(), c4::unformat() - -// formatting: -c4::raw, c4::craw -``` - -### `c4::span` and `c4::blob` - -* [`#include `](src/c4/span.hpp) -* [`#include `](src/c4/blob.hpp) - - -### Enums and enum symbols - -[`#include `](src/c4/enum.hpp) - -```c++ -// TODO: elaborate on the topics: - -c4::e2str(), c4::str2e() -``` - -### Bitmasks and bitmask symbols - -[`#include `](src/c4/bitmask.hpp) - -```c++ -// TODO: elaborate on the topics: - -c4::bm2str(), c4::str2bm() -``` - -### Base64 encoding / decoding - -[`#include `](src/c4/base64.hpp) - -### Fuzzy float comparison diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/ROADMAP.md b/third_party/rapidyaml/rapidyaml/ext/c4core/ROADMAP.md deleted file mode 100644 index 9857514e4..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/ROADMAP.md +++ /dev/null @@ -1,23 +0,0 @@ -# ROADMAP - -## New features - -These changes will provide new features, and client code can be kept -unchanged. - - -## API changes - -These changes will require client code to be updated. - -* [breaking] drop use of C-style sprintf() formats in error messages and - assertions. Change the implementation to use c4::format() - ```c++ - C4_ASSERT_MSG(sz > s.size(), "sz=%zu s.size()=%zu", sz, s.size()); - // ... the above changes to: - C4_ASSERT_MSG(sz > s.size(), "sz={} s.size()={}", sz, s.size()); - ``` - -## Implementation changes - -* drop calls to sprintf() in charconv.hpp. diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/CMakeLists.txt b/third_party/rapidyaml/rapidyaml/ext/c4core/bm/CMakeLists.txt deleted file mode 100644 index bda29c6ad..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -c4_setup_benchmarking() - -#---------------------------------------------- - -# libraries to compare - -c4_require_subproject(fp - REMOTE - GIT_REPOSITORY https://github.com/jk-jeon/fp - GIT_TAG master) - -# ryu requires too much code; use an include for clarity -include(./ryu.cmake) - - -#---------------------------------------------- - -c4_add_executable(c4core-bm-format - SOURCES bm_format.cpp - LIBS c4core benchmark - FOLDER bm) - -c4_add_target_benchmark(c4core-bm-format cat FILTER "^cat_.*") -c4_add_target_benchmark(c4core-bm-format catsep FILTER "^catsep_.*") -c4_add_target_benchmark(c4core-bm-format format FILTER "^format_.*") - - -#---------------------------------------------- - -c4_add_executable(c4core-bm-charconv - SOURCES bm_charconv.cpp - LIBS c4core benchmark ryu_c4 - INC_DIRS ${C4CORE_SRC_DIR}/c4/ext/fast_float/include - FOLDER bm) - -get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES) -if(cxx_std_17 IN_LIST known_features) - target_link_libraries(c4core-bm-charconv PRIVATE jkj_fp) -endif() - - -function(c4core_charconv_benchmark pfx) - foreach(case ${ARGN}) - c4_add_target_benchmark(c4core-bm-charconv ${pfx}-${case} FILTER "^${pfx}.*<${case}.*") - endforeach() -endfunction() - -c4core_charconv_benchmark(xtoa uint8 int8 uint16 int16 uint32 int32 uint64 int64 float double) -c4core_charconv_benchmark(atox uint8 int8 uint16 int16 uint32 int32 uint64 int64 float double) - - -#---------------------------------------------- - -option(C4CORE_BM_FLOAT_CMP "compare between alternative implementations for reading/writing floats" ON) -if(C4CORE_BM_FLOAT_CMP) - add_subdirectory(float) -endif() diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/bm.yml b/third_party/rapidyaml/rapidyaml/ext/c4core/bm/bm.yml deleted file mode 100644 index 39a3010ca..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/bm.yml +++ /dev/null @@ -1,17 +0,0 @@ - -prefix: c4core-bm - -# TODO https://stackoverflow.com/questions/12360547/tool-for-retrieving-the-list-of-functions-and-methods-in-a-c-code-base - -bm: - format-cat: - desc: compares stringification of a sequence of heterogeneous general types - src: bm_format.hpp - charconv-atox: - desc: read string to arithmetic value - src: bm_charconv.cpp - template_types: [uint8, int8, uint16, int16, uint32, int32, uint64, int64, float, double] - charconv-xtoa: - desc: write arithmetic value to string - src: bm_charconv.cpp - template_types: [uint8, int8, uint16, int16, uint32, int32, uint64, int64, float, double] diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/bm_charconv.cpp b/third_party/rapidyaml/rapidyaml/ext/c4core/bm/bm_charconv.cpp deleted file mode 100644 index fd3b2de40..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/bm_charconv.cpp +++ /dev/null @@ -1,1193 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -double getmax(std::vector const& v) -{ - return *(std::max_element(std::begin(v), std::end(v))); -} -double getmin(std::vector const& v) -{ - return *(std::min_element(std::begin(v), std::end(v))); -} -double getrange(std::vector const& v) -{ - auto min_max = std::minmax_element(std::begin(v), std::end(v)); - return *min_max.second - *min_max.first; -} - -#define _c4bm_stats \ - /*->Repetitions(20)*/ \ - ->DisplayAggregatesOnly(true) \ - ->ComputeStatistics("range", &getrange) \ - ->ComputeStatistics("max", &getmax) \ - ->ComputeStatistics("min", &getmin) - -#define C4BM_TEMPLATE(fn, ...) BENCHMARK_TEMPLATE(fn, __VA_ARGS__) _c4bm_stats - - -// benchmarks depending on c++17 features are disabled using the -// preprocessor. google benchmark has state.SkipWithError() but it -// makes the program return a nonzero exit code when it finishes. So -// we resort to the preprocessor to conditionally disable these -// benchmarks -#if C4_CPP >= 17 && defined(__cpp_lib_to_chars) -#define C4BM_TEMPLATE_CPP17(fn, ...) BENCHMARK_TEMPLATE(fn, __VA_ARGS__) _c4bm_stats -#else -#define C4BM_TEMPLATE_CPP17(fn, ...) void shutup_extra_semicolon() -#endif - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdouble-promotion" -# pragma clang diagnostic ignored "-Wdeprecated" -# pragma clang diagnostic ignored "-Wsign-conversion" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdouble-promotion" -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -# pragma GCC diagnostic ignored "-Wsign-conversion" -#endif - -#include -#include -#include -#include -#if C4_CPP >= 17 -#include -#include -#endif - - -namespace bm = benchmark; - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// utilities for use in the benchmarks below - - -// facilities to deuglify SFINAE -#define C4FOR(ty, condition) \ - template \ - typename std::enable_if::type -#define C4FOR2(ty1, ty2, condition) \ - template \ - typename std::enable_if::type - -#define isint(ty) std::is_integral::value -#define isiint(ty) std::is_integral::value && !std::is_unsigned::value -#define isuint(ty) std::is_integral::value && std::is_unsigned::value -#define isreal(ty) std::is_floating_point::value -#define isfloat(ty) std::is_same::value -#define isdouble(ty) std::is_same::value - - -/** convenience wrapper to avoid boilerplate code */ -template -void report(bm::State &st) -{ - st.SetBytesProcessed(static_cast(st.iterations() * sizeof(T))); - st.SetItemsProcessed(static_cast(st.iterations())); -} - - -/** generate in place a random sequence of values: integral version*/ -C4FOR(T, isint) -generate_n(T *begin, T *end) -{ - c4::rng::pcg rng; - // do not use T in the distribution: - // N4659 29.6.1.1 [rand.req.genl]/1e requires one of short, int, long, long long, unsigned short, unsigned int, unsigned long, or unsigned long long - std::uniform_int_distribution idist; - std::generate(begin, end, [&](){ return (T) idist(rng); }); -} - - -/** generate in place a random sequence of values: real-number version*/ -C4FOR(T, isreal) -generate_n(T *begin, T *end) -{ - c4::rng::pcg rng; - // make sure we also have some integral numbers in the real sequence - T *rstart = begin + (std::distance(begin, end) / 20); // 5% integral numbers - std::uniform_int_distribution idist; - std::uniform_real_distribution rdist; - std::generate(begin , rstart, [&](){ return idist(rng); }); - std::generate(rstart, end, [&](){ return rdist(rng); }); -} - - -constexpr const size_t kNumValues = 16384; - - -/** a ring buffer with input values for xtoa benchmarks */ -template -struct random_values -{ - std::vector v; - size_t curr; - T next() { T f = v[curr]; curr = (curr + 1) % v.size(); return f; } - - random_values(size_t sz=kNumValues) : v(sz), curr(0) - { - generate_n(&v.front(), &v.back()); - } -}; - - -/** a ring buffer with input strings for atox benchmarks */ -struct random_strings -{ - std::vector v; - size_t curr; - c4::csubstr next() { c4::csubstr f = c4::to_csubstr(v[curr]); curr = (curr + 1) % v.size(); return f; } - std::string const& next_s() { std::string const& f = v[curr]; curr = (curr + 1) % v.size(); return f; } - - random_strings(size_t sz=kNumValues) : v(sz), curr(0) {} - - template - void init_as() - { - random_values tmp(v.size()); - generate_n(&tmp.v.front(), &tmp.v.back()); - for(size_t i = 0; i < v.size(); ++i) - { - c4::catrs(&v[i], tmp.v[i]); - } - } - - template - void init_as_hex() - { - random_values tmp(v.size()); - generate_n(&tmp.v.front(), &tmp.v.back()); - for(size_t i = 0; i < v.size(); ++i) - { - c4::catrs(&v[i], c4::fmt::hex(tmp.v[i])); - } - } - template - void init_as_oct() - { - random_values tmp(v.size()); - generate_n(&tmp.v.front(), &tmp.v.back()); - for(size_t i = 0; i < v.size(); ++i) - { - c4::catrs(&v[i], c4::fmt::oct(tmp.v[i])); - } - } - template - void init_as_bin() - { - random_values tmp(v.size()); - generate_n(&tmp.v.front(), &tmp.v.back()); - for(size_t i = 0; i < v.size(); ++i) - { - c4::catrs(&v[i], c4::fmt::bin(tmp.v[i])); - } - } - -}; - -template -random_strings mkstrings() -{ - random_strings rs; - rs.init_as(); - return rs; -} - - -/** a character buffer, easily convertible to c4::substr */ -template -struct sbuf -{ - char buf_[Dim]; - c4::substr buf; - sbuf() : buf_(), buf(buf_) {} - inline operator c4::substr& () { return buf; } - char* begin() { return buf.begin(); } - char* end() { return buf.end(); } -}; - -using string_buffer = sbuf<>; - - -// some of the benchmarks do not need to be templates, -// but it helps in the naming scheme. - -// xtoa means to string -// atox means string to - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -C4FOR(T, isint) -atox_c4_read_dec(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; - for(auto _ : st) - { - c4::read_dec(strings.next(), &val); - } - report(st); -} - -C4FOR(T, isint) -atox_c4_read_hex(bm::State& st) -{ - random_strings strings; - strings.init_as_hex(); - T val; - for(auto _ : st) - { - c4::read_hex(strings.next(), &val); - } - report(st); -} - -C4FOR(T, isint) -atox_c4_read_oct(bm::State& st) -{ - random_strings strings; - strings.init_as_oct(); - T val; - for(auto _ : st) - { - c4::read_oct(strings.next(), &val); - } - report(st); -} - -C4FOR(T, isint) -atox_c4_read_bin(bm::State& st) -{ - random_strings strings; - strings.init_as_bin(); - T val; - for(auto _ : st) - { - c4::read_bin(strings.next(), &val); - } - report(st); -} - -C4FOR(T, isiint) -xtoa_c4_itoa(bm::State& st) -{ - string_buffer buf; - T i = -10; - for(auto _ : st) - { - c4::itoa(buf, ++i); - } - report(st); -} - -C4FOR(T, isuint) -xtoa_c4_utoa(bm::State& st) -{ - string_buffer buf; - T i = 0; - for(auto _ : st) - { - ++i; - c4::utoa(buf, ++i); - } - report(st); -} - -C4FOR(T, isfloat) -xtoa_c4_ftoa(bm::State& st) -{ - string_buffer buf; - random_values values; - for(auto _ : st) - { - c4::ftoa(buf, values.next()); - } - report(st); -} - -C4FOR(T, isdouble) -xtoa_c4_dtoa(bm::State& st) -{ - string_buffer buf; - random_values values; - for(auto _ : st) - { - c4::dtoa(buf, values.next()); - } - report(st); -} - -template -void xtoa_c4_xtoa(bm::State& st) -{ - string_buffer buf; - random_values values; - for(auto _ : st) - { - c4::xtoa(buf, values.next()); - } - report(st); -} - - -//----------------------------------------------------------------------------- - -C4FOR(T, isiint) -atox_c4_atoi(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - c4::atoi(strings.next(), &val); - } - report(st); -} - -C4FOR(T, isuint) -atox_c4_atou(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - c4::atou(strings.next(), &val); - } - report(st); -} - -C4FOR(T, isfloat) -atox_c4_atof(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - c4::atof(strings.next(), &val); - } - report(st); -} - -C4FOR(T, isdouble) -atox_c4_atod(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - c4::atod(strings.next(), &val); - } - report(st); -} - -template -void atox_c4_atox(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - c4::atox(strings.next(), &val); - } - report(st); -} - - -//----------------------------------------------------------------------------- - -C4FOR(T, isint) -atox_std_atoi(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - val = (T) std::atoi(strings.next().data()); - } - report(st); -} - -C4FOR(T, isint) -atox_std_atol(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - val = (T) std::atol(strings.next().data()); - } - report(st); -} - -C4FOR(T, isreal) -atox_std_atof(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - val = (T) std::atof(strings.next().data()); - } - report(st); -} - - -//----------------------------------------------------------------------------- - -C4FOR(T, isint) -atox_std_strtol(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - auto s = strings.next(); - val = (T) std::strtol(s.begin(), nullptr, 10); - } - report(st); -} - -C4FOR(T, isint) -atox_std_strtoll(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - auto s = strings.next(); - val = (T) std::strtoll(s.begin(), nullptr, 10); - } - report(st); -} - -C4FOR(T, isint) -atox_std_strtoul(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - auto s = strings.next(); - val = (T) std::strtoul(s.begin(), nullptr, 10); - } - report(st); -} - -C4FOR(T, isint) -atox_std_strtoull(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - auto s = strings.next(); - val = (T) std::strtoull(s.begin(), nullptr, 10); - } - report(st); -} - -C4FOR(T, isreal) -atox_std_strtof(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - auto s = strings.next(); - val = (T) std::strtof(s.begin(), nullptr); - } - report(st); -} - -C4FOR(T, isreal) -atox_std_strtod(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - auto s = strings.next(); - val = (T) std::strtod(s.begin(), nullptr); - } - report(st); -} - -C4FOR(T, isreal) -atox_std_stof(bm::State &st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - val = std::stof(strings.next_s()); - } - report(st); -} - -C4FOR(T, isreal) -atox_std_stod(bm::State &st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - val = std::stod(strings.next_s()); - } - report(st); -} - - -//----------------------------------------------------------------------------- - -C4FOR(T, isfloat) -atox_ryu_s2f(bm::State &st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - std::string const& s = strings.next_s(); - s2f_n(s.data(), (int) s.size(), &val); - } - report(st); -} - -C4FOR(T, isdouble) -atox_ryu_s2d(bm::State &st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - std::string const& s = strings.next_s(); - s2d_n(s.data(), (int) s.size(), &val); - } - report(st); -} - -C4FOR(T, isfloat) -xtoa_ryu_f2s(bm::State &st) -{ - string_buffer buf; - random_values values; - for(auto _ : st) - { - f2s_buffered_n(values.next(), buf.buf.str); - } - report(st); -} - -C4FOR(T, isdouble) -xtoa_ryu_d2s(bm::State &st) -{ - string_buffer buf; - random_values values; - for(auto _ : st) - { - d2s_buffered_n(values.next(), buf.buf.str); - } - report(st); -} - - -//----------------------------------------------------------------------------- - -// fp is still experimental and undocumented; -// some assertions are firing in debug builds -// so we make these benchmarks available only with NDEBUG -#if !defined(NDEBUG) || (C4_CPP < 17) -#define C4BM_FP_BENCHMARK(name, ...) void shutup_extra_semicolon() -#else -#define C4BM_FP_BENCHMARK(name, ...) C4BM_TEMPLATE(name, __VA_ARGS__) - -C4FOR(T, isreal) -atox_fp_from_chars_limited(bm::State &st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - std::string const& s = strings.next_s(); - val = jkj::fp::from_chars_limited(s.data(), s.data()+s.size()).to_float(); - } - report(st); -} - -C4FOR(T, isreal) -atox_fp_from_chars_unlimited(bm::State &st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - std::string const& s = strings.next_s(); - val = jkj::fp::from_chars_unlimited(s.data(), s.data()+s.size()).to_float(); - } - report(st); -} -#endif - - -//----------------------------------------------------------------------------- - -template -void atox_fast_float(bm::State &st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - std::string const& s = strings.next_s(); - fast_float::from_chars(s.data(), s.data()+s.size(), val); - } - report(st); -} - - -//----------------------------------------------------------------------------- - -template struct fmtspec; -template<> struct fmtspec< uint8_t> { static const char w[], r[]; }; -template<> struct fmtspec< int8_t> { static const char w[], r[]; }; -template<> struct fmtspec { static const char w[], r[]; }; -template<> struct fmtspec< int16_t> { static const char w[], r[]; }; -template<> struct fmtspec { static const char w[], r[]; }; -template<> struct fmtspec< int32_t> { static const char w[], r[]; }; -template<> struct fmtspec { static const char w[], r[]; }; -template<> struct fmtspec< int64_t> { static const char w[], r[]; }; -template<> struct fmtspec< float > { static const char w[], r[]; }; -template<> struct fmtspec< double > { static const char w[], r[]; }; - -constexpr const char fmtspec< uint8_t>::w[] = "%" PRIu8 ; -constexpr const char fmtspec< int8_t>::w[] = "%" PRIi8 ; -constexpr const char fmtspec::w[] = "%" PRIu16; -constexpr const char fmtspec< int16_t>::w[] = "%" PRIi16; -constexpr const char fmtspec::w[] = "%" PRIu32; -constexpr const char fmtspec< int32_t>::w[] = "%" PRIi32; -constexpr const char fmtspec::w[] = "%" PRIu64; -constexpr const char fmtspec< int64_t>::w[] = "%" PRIi64; -constexpr const char fmtspec< float >::w[] = "%g" ; -constexpr const char fmtspec< double >::w[] = "%lg" ; - -constexpr const char fmtspec< uint8_t>::r[] = "%" SCNu8 ; -constexpr const char fmtspec< int8_t>::r[] = "%" SCNi8 ; -constexpr const char fmtspec::r[] = "%" SCNu16; -constexpr const char fmtspec< int16_t>::r[] = "%" SCNi16; -constexpr const char fmtspec::r[] = "%" SCNu32; -constexpr const char fmtspec< int32_t>::r[] = "%" SCNi32; -constexpr const char fmtspec::r[] = "%" SCNu64; -constexpr const char fmtspec< int64_t>::r[] = "%" SCNi64; -constexpr const char fmtspec< float >::r[] = "%g" ; -constexpr const char fmtspec< double >::r[] = "%lg" ; - -C4FOR(T, isint) -xtoa_sprintf(bm::State& st) -{ - string_buffer buf; - T i = 0; - for(auto _ : st) - { - ++i; - ::snprintf(buf.buf.str, buf.buf.len, fmtspec::w, i); - } - report(st); -} - -C4FOR(T, isreal) -xtoa_sprintf(bm::State& st) -{ - string_buffer buf; - random_values values; - for(auto _ : st) - { - ::snprintf(buf.buf.str, buf.buf.len, fmtspec::w, values.next()); - } - report(st); -} - -template -void atox_scanf(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - ::sscanf(strings.next().str, fmtspec::r, &val); - } - report(st); -} - - -//----------------------------------------------------------------------------- - -C4FOR(T, isint) -xtoa_sstream(bm::State& st) -{ - T i = 0; - std::string out; C4_UNUSED(out); - for(auto _ : st) - { - std::stringstream ss; - ss << ++i; - out = ss.str(); - } - report(st); -} - -C4FOR(T, isreal) -xtoa_sstream(bm::State& st) -{ - random_values values; - std::string out; C4_UNUSED(out); - for(auto _ : st) - { - std::stringstream ss; - ss << values.next(); - out = ss.str(); - } - report(st); -} - -C4FOR(T, isint) -xtoa_sstream_reuse(bm::State& st) -{ - std::stringstream ss; - std::string out; C4_UNUSED(out); - T i = 0; - for(auto _ : st) - { - ss.clear(); - ss.str(""); - ss << ++i; - } - report(st); -} - -C4FOR(T, isreal) -xtoa_sstream_reuse(bm::State& st) -{ - random_values values; - std::stringstream ss; - std::string out; C4_UNUSED(out); - for(auto _ : st) - { - ss.clear(); - ss.str(""); - ss << values.next(); - } - report(st); -} - -template -void atox_sstream(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - std::stringstream ss(strings.next_s()); - ss >> val; - } - report(st); -} - -template -void atox_sstream_reuse(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - std::stringstream ss; - for(auto _ : st) - { - ss.clear(); - ss.str(strings.next_s()); - ss >> val; - } - report(st); -} - - -//----------------------------------------------------------------------------- - -C4FOR(T, isint) -xtoa_std_to_string(bm::State& st) -{ - T i = 0; - for(auto _ : st) - { - std::string out = std::to_string(++i); - C4_UNUSED(out); - } - report(st); -} - -C4FOR(T, isreal) -xtoa_std_to_string(bm::State& st) -{ - random_values values; - for(auto _ : st) - { - std::string out = std::to_string(values.next()); - C4_UNUSED(out); - } - report(st); -} - - -//----------------------------------------------------------------------------- - -C4FOR(T, isint) -xtoa_c4_to_chars(bm::State& st) -{ - string_buffer buf; - T i = 0; - for(auto _ : st) - { - c4::to_chars(buf, ++i); - } - report(st); -} - -C4FOR(T, isreal) -xtoa_c4_to_chars(bm::State& st) -{ - string_buffer buf; - random_values values; - for(auto _ : st) - { - c4::to_chars(buf, values.next()); - } - report(st); -} - -template -void atox_c4_from_chars(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; - for(auto _ : st) - { - c4::from_chars(strings.next(), &val); - } - report(st); -} - -#if (C4_CPP >= 17) && defined(__cpp_lib_to_chars) -C4FOR(T, isint) -xtoa_std_to_chars(bm::State& st) -{ - string_buffer buf; - T i = 0; - for(auto _ : st) - { - std::to_chars(buf.begin(), buf.end(), ++i); - } - report(st); -} - -C4FOR(T, isreal) -xtoa_std_to_chars(bm::State& st) -{ - string_buffer buf; - random_values values; - for(auto _ : st) - { - std::to_chars(buf.begin(), buf.end(), values.next()); - } - report(st); -} - -template -void atox_std_from_chars(bm::State& st) -{ - random_strings strings = mkstrings(); - T val; C4_UNUSED(val); - for(auto _ : st) - { - std::string const& s = strings.next_s(); - std::from_chars(s.data(), s.data()+s.size(), val); - } - report(st); -} -#endif - - -//----------------------------------------------------------------------------- - -C4BM_TEMPLATE(xtoa_c4_utoa, uint8_t); -C4BM_TEMPLATE(xtoa_c4_xtoa, uint8_t); -C4BM_TEMPLATE(xtoa_c4_to_chars, uint8_t); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, uint8_t); -C4BM_TEMPLATE(xtoa_std_to_string, uint8_t); -C4BM_TEMPLATE(xtoa_sprintf, uint8_t); -C4BM_TEMPLATE(xtoa_sstream_reuse, uint8_t); -C4BM_TEMPLATE(xtoa_sstream, uint8_t); - -C4BM_TEMPLATE(xtoa_c4_itoa, int8_t); -C4BM_TEMPLATE(xtoa_c4_xtoa, int8_t); -C4BM_TEMPLATE(xtoa_c4_to_chars, int8_t); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, int8_t); -C4BM_TEMPLATE(xtoa_std_to_string, int8_t); -C4BM_TEMPLATE(xtoa_sprintf, int8_t); -C4BM_TEMPLATE(xtoa_sstream_reuse, int8_t); -C4BM_TEMPLATE(xtoa_sstream, int8_t); - -C4BM_TEMPLATE(xtoa_c4_utoa, uint16_t); -C4BM_TEMPLATE(xtoa_c4_xtoa, uint16_t); -C4BM_TEMPLATE(xtoa_c4_to_chars, uint16_t); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, uint16_t); -C4BM_TEMPLATE(xtoa_std_to_string, uint16_t); -C4BM_TEMPLATE(xtoa_sprintf, uint16_t); -C4BM_TEMPLATE(xtoa_sstream_reuse, uint16_t); -C4BM_TEMPLATE(xtoa_sstream, uint16_t); - -C4BM_TEMPLATE(xtoa_c4_itoa, int16_t); -C4BM_TEMPLATE(xtoa_c4_xtoa, int16_t); -C4BM_TEMPLATE(xtoa_c4_to_chars, int16_t); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, int16_t); -C4BM_TEMPLATE(xtoa_std_to_string, int16_t); -C4BM_TEMPLATE(xtoa_sprintf, int16_t); -C4BM_TEMPLATE(xtoa_sstream_reuse, int16_t); -C4BM_TEMPLATE(xtoa_sstream, int16_t); - -C4BM_TEMPLATE(xtoa_c4_utoa, uint32_t); -C4BM_TEMPLATE(xtoa_c4_xtoa, uint32_t); -C4BM_TEMPLATE(xtoa_c4_to_chars, uint32_t); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, uint32_t); -C4BM_TEMPLATE(xtoa_std_to_string, uint32_t); -C4BM_TEMPLATE(xtoa_sprintf, uint32_t); -C4BM_TEMPLATE(xtoa_sstream_reuse, uint32_t); -C4BM_TEMPLATE(xtoa_sstream, uint32_t); - -C4BM_TEMPLATE(xtoa_c4_itoa, int32_t); -C4BM_TEMPLATE(xtoa_c4_xtoa, int32_t); -C4BM_TEMPLATE(xtoa_c4_to_chars, int32_t); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, int32_t); -C4BM_TEMPLATE(xtoa_std_to_string, int32_t); -C4BM_TEMPLATE(xtoa_sprintf, int32_t); -C4BM_TEMPLATE(xtoa_sstream_reuse, int32_t); -C4BM_TEMPLATE(xtoa_sstream, int32_t); - -C4BM_TEMPLATE(xtoa_c4_utoa, uint64_t); -C4BM_TEMPLATE(xtoa_c4_xtoa, uint64_t); -C4BM_TEMPLATE(xtoa_c4_to_chars, uint64_t); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, uint64_t); -C4BM_TEMPLATE(xtoa_std_to_string, uint64_t); -C4BM_TEMPLATE(xtoa_sprintf, uint64_t); -C4BM_TEMPLATE(xtoa_sstream_reuse, uint64_t); -C4BM_TEMPLATE(xtoa_sstream, uint64_t); - -C4BM_TEMPLATE(xtoa_c4_itoa, int64_t); -C4BM_TEMPLATE(xtoa_c4_xtoa, int64_t); -C4BM_TEMPLATE(xtoa_c4_to_chars, int64_t); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, int64_t); -C4BM_TEMPLATE(xtoa_std_to_string, int64_t); -C4BM_TEMPLATE(xtoa_sprintf, int64_t); -C4BM_TEMPLATE(xtoa_sstream_reuse, int64_t); -C4BM_TEMPLATE(xtoa_sstream, int64_t); - -C4BM_TEMPLATE(xtoa_c4_ftoa, float); -C4BM_TEMPLATE(xtoa_c4_xtoa, float); -C4BM_TEMPLATE(xtoa_c4_to_chars, float); -C4BM_TEMPLATE(xtoa_ryu_f2s, float); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, float); -C4BM_TEMPLATE(xtoa_std_to_string, float); -C4BM_TEMPLATE(xtoa_sprintf, float); -C4BM_TEMPLATE(xtoa_sstream_reuse, float); -C4BM_TEMPLATE(xtoa_sstream, float); - -C4BM_TEMPLATE(xtoa_c4_dtoa, double); -C4BM_TEMPLATE(xtoa_c4_xtoa, double); -C4BM_TEMPLATE(xtoa_c4_to_chars, double); -C4BM_TEMPLATE(xtoa_ryu_d2s, double); -C4BM_TEMPLATE_CPP17(xtoa_std_to_chars, double); -C4BM_TEMPLATE(xtoa_std_to_string, double); -C4BM_TEMPLATE(xtoa_sprintf, double); -C4BM_TEMPLATE(xtoa_sstream_reuse, double); -C4BM_TEMPLATE(xtoa_sstream, double); - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -C4BM_TEMPLATE(atox_c4_read_dec, uint8_t); -C4BM_TEMPLATE(atox_c4_read_hex, uint8_t); -C4BM_TEMPLATE(atox_c4_read_oct, uint8_t); -C4BM_TEMPLATE(atox_c4_read_bin, uint8_t); -C4BM_TEMPLATE(atox_c4_atou, uint8_t); -C4BM_TEMPLATE(atox_c4_atox, uint8_t); -C4BM_TEMPLATE(atox_c4_from_chars, uint8_t); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, uint8_t); -C4BM_TEMPLATE(atox_std_atoi, uint8_t); -C4BM_TEMPLATE(atox_std_strtoul, uint8_t); -C4BM_TEMPLATE(atox_scanf, uint8_t); -C4BM_TEMPLATE(atox_sstream, uint8_t); -C4BM_TEMPLATE(atox_sstream_reuse, uint8_t); - -C4BM_TEMPLATE(atox_c4_read_dec, int8_t); -C4BM_TEMPLATE(atox_c4_read_hex, int8_t); -C4BM_TEMPLATE(atox_c4_read_oct, int8_t); -C4BM_TEMPLATE(atox_c4_read_bin, int8_t); -C4BM_TEMPLATE(atox_c4_atoi, int8_t); -C4BM_TEMPLATE(atox_c4_atox, int8_t); -C4BM_TEMPLATE(atox_c4_from_chars, int8_t); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, int8_t); -C4BM_TEMPLATE(atox_std_atoi, int8_t); -C4BM_TEMPLATE(atox_std_strtol, int8_t); -C4BM_TEMPLATE(atox_scanf, int8_t); -C4BM_TEMPLATE(atox_sstream, int8_t); -C4BM_TEMPLATE(atox_sstream_reuse, int8_t); - -C4BM_TEMPLATE(atox_c4_read_dec, uint16_t); -C4BM_TEMPLATE(atox_c4_read_hex, uint16_t); -C4BM_TEMPLATE(atox_c4_read_oct, uint16_t); -C4BM_TEMPLATE(atox_c4_read_bin, uint16_t); -C4BM_TEMPLATE(atox_c4_atou, uint16_t); -C4BM_TEMPLATE(atox_c4_atox, uint16_t); -C4BM_TEMPLATE(atox_c4_from_chars, uint16_t); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, uint16_t); -C4BM_TEMPLATE(atox_std_atoi, uint16_t); -C4BM_TEMPLATE(atox_std_strtoul, uint16_t); -C4BM_TEMPLATE(atox_scanf, uint16_t); -C4BM_TEMPLATE(atox_sstream, uint16_t); -C4BM_TEMPLATE(atox_sstream_reuse, uint16_t); - -C4BM_TEMPLATE(atox_c4_read_dec, int16_t); -C4BM_TEMPLATE(atox_c4_read_hex, int16_t); -C4BM_TEMPLATE(atox_c4_read_oct, int16_t); -C4BM_TEMPLATE(atox_c4_read_bin, int16_t); -C4BM_TEMPLATE(atox_c4_atoi, int16_t); -C4BM_TEMPLATE(atox_c4_atox, int16_t); -C4BM_TEMPLATE(atox_c4_from_chars, int16_t); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, int16_t); -C4BM_TEMPLATE(atox_std_atoi, int16_t); -C4BM_TEMPLATE(atox_std_strtol, int16_t); -C4BM_TEMPLATE(atox_scanf, int16_t); -C4BM_TEMPLATE(atox_sstream, int16_t); -C4BM_TEMPLATE(atox_sstream_reuse, int16_t); - -C4BM_TEMPLATE(atox_c4_read_dec, uint32_t); -C4BM_TEMPLATE(atox_c4_read_hex, uint32_t); -C4BM_TEMPLATE(atox_c4_read_oct, uint32_t); -C4BM_TEMPLATE(atox_c4_read_bin, uint32_t); -C4BM_TEMPLATE(atox_c4_atou, uint32_t); -C4BM_TEMPLATE(atox_c4_atox, uint32_t); -C4BM_TEMPLATE(atox_c4_from_chars, uint32_t); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, uint32_t); -C4BM_TEMPLATE(atox_std_atoi, uint32_t); -C4BM_TEMPLATE(atox_std_strtoul, uint32_t); -C4BM_TEMPLATE(atox_scanf, uint32_t); -C4BM_TEMPLATE(atox_sstream, uint32_t); -C4BM_TEMPLATE(atox_sstream_reuse, uint32_t); - -C4BM_TEMPLATE(atox_c4_read_dec, int32_t); -C4BM_TEMPLATE(atox_c4_read_hex, int32_t); -C4BM_TEMPLATE(atox_c4_read_oct, int32_t); -C4BM_TEMPLATE(atox_c4_read_bin, int32_t); -C4BM_TEMPLATE(atox_c4_atoi, int32_t); -C4BM_TEMPLATE(atox_c4_atox, int32_t); -C4BM_TEMPLATE(atox_c4_from_chars, int32_t); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, int32_t); -C4BM_TEMPLATE(atox_std_atoi, int32_t); -C4BM_TEMPLATE(atox_std_strtol, int32_t); -C4BM_TEMPLATE(atox_scanf, int32_t); -C4BM_TEMPLATE(atox_sstream, int32_t); -C4BM_TEMPLATE(atox_sstream_reuse, int32_t); - -C4BM_TEMPLATE(atox_c4_read_dec, uint64_t); -C4BM_TEMPLATE(atox_c4_read_hex, uint64_t); -C4BM_TEMPLATE(atox_c4_read_oct, uint64_t); -C4BM_TEMPLATE(atox_c4_read_bin, uint64_t); -C4BM_TEMPLATE(atox_c4_atou, uint64_t); -C4BM_TEMPLATE(atox_c4_atox, uint64_t); -C4BM_TEMPLATE(atox_c4_from_chars, uint64_t); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, uint64_t); -C4BM_TEMPLATE(atox_std_atol, uint64_t); -C4BM_TEMPLATE(atox_std_strtoull, uint64_t); -C4BM_TEMPLATE(atox_scanf, uint64_t); -C4BM_TEMPLATE(atox_sstream, uint64_t); -C4BM_TEMPLATE(atox_sstream_reuse, uint64_t); - -C4BM_TEMPLATE(atox_c4_read_dec, int64_t); -C4BM_TEMPLATE(atox_c4_read_hex, int64_t); -C4BM_TEMPLATE(atox_c4_read_oct, int64_t); -C4BM_TEMPLATE(atox_c4_read_bin, int64_t); -C4BM_TEMPLATE(atox_c4_atoi, int64_t); -C4BM_TEMPLATE(atox_c4_atox, int64_t); -C4BM_TEMPLATE(atox_c4_from_chars, int64_t); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, int64_t); -C4BM_TEMPLATE(atox_std_atol, int64_t); -C4BM_TEMPLATE(atox_std_strtoll, int64_t); -C4BM_TEMPLATE(atox_scanf, int64_t); -C4BM_TEMPLATE(atox_sstream, int64_t); -C4BM_TEMPLATE(atox_sstream_reuse, int64_t); - -C4BM_TEMPLATE(atox_c4_atof, float); -C4BM_TEMPLATE(atox_c4_atox, float); -C4BM_TEMPLATE(atox_c4_from_chars, float); -C4BM_TEMPLATE(atox_ryu_s2f, float); -C4BM_TEMPLATE(atox_fast_float, float); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, float); -C4BM_FP_BENCHMARK(atox_fp_from_chars_limited, float); -C4BM_FP_BENCHMARK(atox_fp_from_chars_unlimited, float); -C4BM_TEMPLATE(atox_std_atof, float); -C4BM_TEMPLATE(atox_std_strtof, float); -C4BM_TEMPLATE(atox_std_stof, float); -C4BM_TEMPLATE(atox_scanf, float); -C4BM_TEMPLATE(atox_sstream, float); -C4BM_TEMPLATE(atox_sstream_reuse, float); - -C4BM_TEMPLATE(atox_c4_atod, double); -C4BM_TEMPLATE(atox_c4_atox, double); -C4BM_TEMPLATE(atox_c4_from_chars, double); -C4BM_TEMPLATE(atox_ryu_s2d, double); -C4BM_TEMPLATE(atox_fast_float, double); -C4BM_TEMPLATE_CPP17(atox_std_from_chars, double); -C4BM_FP_BENCHMARK(atox_fp_from_chars_limited, double); -C4BM_FP_BENCHMARK(atox_fp_from_chars_unlimited, double); -C4BM_TEMPLATE(atox_std_atof, double); -C4BM_TEMPLATE(atox_std_strtod, double); -C4BM_TEMPLATE(atox_std_stod, double); -C4BM_TEMPLATE(atox_scanf, double); -C4BM_TEMPLATE(atox_sstream, double); -C4BM_TEMPLATE(atox_sstream_reuse, double); - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -int main(int argc, char *argv[]) -{ - bm::Initialize(&argc, argv); - bm::RunSpecifiedBenchmarks(); - return 0; -} - -#ifdef __clang__ -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - -#include diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/bm_format.cpp b/third_party/rapidyaml/rapidyaml/ext/c4core/bm/bm_format.cpp deleted file mode 100644 index c74f793b3..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/bm_format.cpp +++ /dev/null @@ -1,410 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace bm = benchmark; - -double getmax(std::vector const& v) -{ - return *(std::max_element(std::begin(v), std::end(v))); -} -double getmin(std::vector const& v) -{ - return *(std::min_element(std::begin(v), std::end(v))); -} -double getrange(std::vector const& v) -{ - auto min_max = std::minmax_element(std::begin(v), std::end(v)); - return *min_max.second - *min_max.first; -} - -#define _c4bm_stats \ - /*->Repetitions(20)*/ \ - ->DisplayAggregatesOnly(true) \ - ->ComputeStatistics("range", &getrange) \ - ->ComputeStatistics("max", &getmax) \ - ->ComputeStatistics("min", &getmin) - -#define C4BM(fn) BENCHMARK(fn) _c4bm_stats - -/** convenience wrapper to avoid boilerplate code */ -void report(bm::State &st, size_t sz) -{ - st.SetBytesProcessed(static_cast(st.iterations() * sz)); - st.SetItemsProcessed(static_cast(st.iterations())); -} - - -#define _c4argbundle_fmt "hello here you have some numbers: "\ - "1={}, 2={}, 3={}, 4={}, 5={}, 6={}, 7={}, 8={}, 9={}, size_t(283482349)={}, "\ - "\" \"=\"{}\", \"haha\"=\"{}\", std::string(\"hehe\")=\"{}\", "\ - "str=\"{}\"" - -#define _c4argbundle_fmt_printf "hello here you have some numbers: "\ - "1=%d, 2=%d, 3=%d, 4=%d, 5=%d, 6=%d, 7=%d, 8=%d, 9=%d, size_t(283482349)=%zu, "\ - "\" \"=\"%s\", \"haha\"=\"%s\", std::string(\"hehe\")=\"%s\", "\ - "str=\"%s\"" - -#define _c4argbundle \ - 1, 2, 3, 4, 5, 6, 7, 8, 9, size_t(283482349),\ - " ", "haha", std::string("hehe"),\ - std::string("asdlklkasdlkjasd asdlkjasdlkjasdlkjasdoiasdlkjasldkj") - -#define _c4argbundle_printf \ - 1, 2, 3, 4, 5, 6, 7, 8, 9, size_t(283482349),\ - " ", "haha", std::string("hehe").c_str(),\ - std::string("asdlklkasdlkjasd asdlkjasdlkjasdlkjasdoiasdlkjasldkj").c_str() - -#define _c4argbundle_lshift \ - 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << size_t(283482349)\ - << " " << "haha" << std::string("hehe")\ - << std::string("asdlklkasdlkjasd asdlkjasdlkjasdlkjasdoiasdlkjasldkj") - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -void cat_c4cat_substr(bm::State &st) -{ - char buf_[256]; - c4::substr buf(buf_); - size_t sz = 0; - for(auto _ : st) - { - sz = cat(buf, _c4argbundle); - } - report(st, sz); -} - -void catsep_c4cat_substr(bm::State &st) -{ - char buf_[256]; - c4::substr buf(buf_); - size_t sz = 0; - for(auto _ : st) - { - sz = catsep(buf, _c4argbundle); - } - report(st, sz); -} - -void cat_c4catrs_reuse(bm::State &st) -{ - std::string buf; - size_t sz = 0; - for(auto _ : st) - { - c4::catrs(&buf, _c4argbundle); - sz = buf.size(); - } - report(st, sz); -} - -void catsep_c4catrs_reuse(bm::State &st) -{ - std::string buf; - size_t sz = 0; - for(auto _ : st) - { - c4::catseprs(&buf, _c4argbundle); - sz = buf.size(); - } - report(st, sz); -} - -void cat_c4catrs_no_reuse(bm::State &st) -{ - size_t sz = 0; - for(auto _ : st) - { - auto buf = c4::catrs(_c4argbundle); - sz = buf.size(); - } - report(st, sz); -} - -void catsep_c4catrs_no_reuse(bm::State &st) -{ - size_t sz = 0; - for(auto _ : st) - { - auto buf = c4::catseprs(_c4argbundle); - sz = buf.size(); - } - report(st, sz); -} - -//----------------------------------------------------------------------------- -void cat_std_stringstream_impl(std::stringstream &) -{ -} -void catsep_std_stringstream_impl(std::stringstream &) -{ -} - -template -void cat_std_stringstream_impl(std::stringstream &ss, Arg const& a, Args const& ...args) -{ - ss << a; - cat_std_stringstream_impl(ss, args...); -} - -template -void catsep_std_stringstream_impl(std::stringstream &ss, Arg const& a, Args const& ...args) -{ - ss << ' ' << a; - cat_std_stringstream_impl(ss, args...); -} - -void cat_stdsstream_reuse(bm::State &st) -{ - size_t sz = 0; - std::stringstream ss; - for(auto _ : st) - { - ss.clear(); - ss.str(""); - cat_std_stringstream_impl(ss, _c4argbundle); - sz = ss.str().size(); - } - report(st, sz); -} - -void catsep_stdsstream_reuse(bm::State &st) -{ - size_t sz = 0; - std::stringstream ss; - for(auto _ : st) - { - ss.clear(); - ss.str(""); - catsep_std_stringstream_impl(ss, _c4argbundle); - sz = ss.str().size(); - } - report(st, sz); -} - -void cat_stdsstream_no_reuse(bm::State &st) -{ - size_t sz = 0; - for(auto _ : st) - { - std::stringstream ss; - cat_std_stringstream_impl(ss, _c4argbundle); - sz = ss.str().size(); - } - report(st, sz); -} - -void catsep_stdsstream_no_reuse(bm::State &st) -{ - size_t sz = 0; - for(auto _ : st) - { - std::stringstream ss; - catsep_std_stringstream_impl(ss, _c4argbundle); - sz = ss.str().size(); - } - report(st, sz); -} - - -//----------------------------------------------------------------------------- - -template -C4_ALWAYS_INLINE typename std::enable_if::value, std::string>::type -std_to_string(T const& a) -{ - return std::to_string(a); -} - -template -C4_ALWAYS_INLINE typename std::enable_if::value, std::string const&>::type -std_to_string(std::string const& a) -{ - return a; -} - -template -C4_ALWAYS_INLINE typename std::enable_if< ! std::is_arithmetic::value, std::string>::type -std_to_string(T const& a) -{ - return std::string(a); -} - -C4_ALWAYS_INLINE void cat_std_string_impl(std::string *) -{ -} - -C4_ALWAYS_INLINE void catsep_std_string_impl(std::string *) -{ -} - -template -void cat_std_string_impl(std::string *s, Arg const& a, Args const& ...args) -{ - *s += std_to_string(a); - cat_std_string_impl(s, args...); -} - -template -void catsep_std_string_impl(std::string *s, Arg const& a, Args const& ...args) -{ - *s += ' '; - *s += std_to_string(a); - cat_std_string_impl(s, args...); -} - -void cat_std_to_string_reuse(bm::State &st) -{ - size_t sz = 0; - std::string s; - for(auto _ : st) - { - s.clear(); - cat_std_string_impl(&s, _c4argbundle); - sz = s.size(); - } - report(st, sz); -} - -void catsep_std_to_string_reuse(bm::State &st) -{ - size_t sz = 0; - std::string s; - for(auto _ : st) - { - s.clear(); - catsep_std_string_impl(&s, _c4argbundle); - sz = s.size(); - } - report(st, sz); -} - -void cat_std_to_string_no_reuse(bm::State &st) -{ - size_t sz = 0; - for(auto _ : st) - { - std::string s; - cat_std_string_impl(&s, _c4argbundle); - sz = s.size(); - } - report(st, sz); -} - -void catsep_std_to_string_no_reuse(bm::State &st) -{ - size_t sz = 0; - for(auto _ : st) - { - std::string s; - catsep_std_string_impl(&s, _c4argbundle); - sz = s.size(); - } - report(st, sz); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -void format_c4_format(bm::State &st) -{ - char buf_[512]; - c4::substr buf(buf_); - size_t sz = 0; - for(auto _ : st) - { - sz = format(buf, _c4argbundle_fmt, _c4argbundle); - } - report(st, sz); -} - -void format_c4_formatrs_reuse(bm::State &st) -{ - std::string buf; - size_t sz = 0; - for(auto _ : st) - { - c4::formatrs(&buf, _c4argbundle_fmt, _c4argbundle); - sz = buf.size(); - } - report(st, sz); -} - -void format_c4_formatrs_no_reuse(bm::State &st) -{ - size_t sz = 0; - for(auto _ : st) - { - auto buf = c4::formatrs(_c4argbundle_fmt, _c4argbundle); - sz = buf.size(); - } - report(st, sz); -} - -void format_snprintf(bm::State &st) -{ - char buf_[512]; - c4::substr buf(buf_); - size_t sz = 0; - for(auto _ : st) - { - sz = (size_t) snprintf(buf.str, buf.len, _c4argbundle_fmt_printf, _c4argbundle_printf); - } - report(st, sz); -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -C4BM(cat_c4cat_substr); -C4BM(cat_c4catrs_reuse); -C4BM(cat_c4catrs_no_reuse); -C4BM(cat_std_to_string_reuse); -C4BM(cat_std_to_string_no_reuse); -C4BM(cat_stdsstream_reuse); -C4BM(cat_stdsstream_no_reuse); - - -C4BM(catsep_c4cat_substr); -C4BM(catsep_c4catrs_reuse); -C4BM(catsep_c4catrs_no_reuse); -C4BM(catsep_std_to_string_reuse); -C4BM(catsep_std_to_string_no_reuse); -C4BM(catsep_stdsstream_reuse); -C4BM(catsep_stdsstream_no_reuse); - - -C4BM(format_c4_format); -C4BM(format_c4_formatrs_reuse); -C4BM(format_c4_formatrs_no_reuse); -C4BM(format_snprintf); - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -int main(int argc, char *argv[]) -{ - bm::Initialize(&argc, argv); - bm::RunSpecifiedBenchmarks(); - return 0; -} - - -#include - - diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/float/CMakeLists.txt b/third_party/rapidyaml/rapidyaml/ext/c4core/bm/float/CMakeLists.txt deleted file mode 100644 index 83d569b80..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/float/CMakeLists.txt +++ /dev/null @@ -1,77 +0,0 @@ -find_package(Python COMPONENTS Interpreter) - -# this benchmark compares the binaries from several float libraries - -function(c4core_bm_readfloat name define) - set(target c4core-bm-readfloat-${name}) - c4_add_executable(${target} - SOURCES read.cpp - LIBS ${ARGN} - FOLDER bm/float) - use_static_libc(${target}) - if(NOT "${define}" STREQUAL "") - target_compile_definitions(${target} PUBLIC ${define}=1) - endif() - target_include_directories(${target} PUBLIC ${C4CORE_SRC_DIR}) - if(NOT TARGET c4core-bm-readfloat) - add_custom_target(c4core-bm-readfloat) - endif() - add_dependencies(c4core-bm-readfloat ${target}) - _c4_set_target_folder(c4core-bm-readfloat bm) - set(measure ${CMAKE_CURRENT_LIST_DIR}/measure.py) - target_sources(${target} PRIVATE ${measure}) - if(UNIX) - set(unix --unix) # $<$:--unix> - endif() - add_custom_command(TARGET ${target} PRE_BUILD - COMMAND ${Python_EXECUTABLE} ${measure} start ${target} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - add_custom_command(TARGET ${target} POST_BUILD - COMMAND ${Python_EXECUTABLE} ${measure} finish ${unix} ${target} $ - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) -endfunction() - - -function(use_static_libc target) - if(MSVC) - # https://cmake.org/cmake/help/v3.15/prop_tgt/MSVC_RUNTIME_LIBRARY.html - set_property(TARGET ${target} PROPERTY - MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") - else() - # https://stackoverflow.com/questions/38694058/cmake-linking-statically-against-libgcc-and-libstdc-into-a-shared-library - # see also: - # https://github.com/fastfloat/fast_float/pull/41#issuecomment-733346131 - target_link_libraries(${target} PUBLIC -static -static-libgcc -static-libstdc++) - endif() -endfunction() - - -c4core_bm_readfloat(baseline "") -c4core_bm_readfloat(std_atof C4FLOAT_STD_ATOF) -c4core_bm_readfloat(sscanf_f C4FLOAT_SSCANF_F) -c4core_bm_readfloat(sscanf_d C4FLOAT_SSCANF_D) -c4core_bm_readfloat(iostream_f C4FLOAT_IOSTREAM_F) -c4core_bm_readfloat(iostream_d C4FLOAT_IOSTREAM_D) -c4core_bm_readfloat(fast_float_f C4FLOAT_FASTFLOAT_F) -c4core_bm_readfloat(fast_float_d C4FLOAT_FASTFLOAT_D) -c4core_bm_readfloat(ryu_f C4FLOAT_RYU_F ryu_c4) -c4core_bm_readfloat(ryu_d C4FLOAT_RYU_D ryu_c4) - -get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES) -if(cxx_std_17 IN_LIST known_features) - c4core_bm_readfloat(fast_fp_f_limited C4FLOAT_FP_F_LIMITED jkj_fp) - c4core_bm_readfloat(fast_fp_d_limited C4FLOAT_FP_D_LIMITED jkj_fp) - c4core_bm_readfloat(fast_fp_f_unlimited C4FLOAT_FP_F_UNLIMITED jkj_fp) - c4core_bm_readfloat(fast_fp_d_unlimited C4FLOAT_FP_D_UNLIMITED jkj_fp) - target_compile_features(c4core-bm-readfloat-fast_fp_f_limited PRIVATE cxx_std_17) - target_compile_features(c4core-bm-readfloat-fast_fp_d_limited PRIVATE cxx_std_17) - target_compile_features(c4core-bm-readfloat-fast_fp_f_unlimited PRIVATE cxx_std_17) - target_compile_features(c4core-bm-readfloat-fast_fp_d_unlimited PRIVATE cxx_std_17) - # incredible - 3 years of C++17 and from_chars()/to_chars() is not available - if(NOT ((CMAKE_CXX_COMPILER_ID STREQUAL GNU) OR (CMAKE_CXX_COMPILER_ID STREQUAL Clang))) - c4core_bm_readfloat(std_from_chars_f C4FLOAT_STD_FROM_CHARS_F) - c4core_bm_readfloat(std_from_chars_d C4FLOAT_STD_FROM_CHARS_D) - target_compile_features(c4core-bm-readfloat-std_from_chars_f PRIVATE cxx_std_17) - target_compile_features(c4core-bm-readfloat-std_from_chars_d PRIVATE cxx_std_17) - endif() -endif() diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/float/measure.py b/third_party/rapidyaml/rapidyaml/ext/c4core/bm/float/measure.py deleted file mode 100644 index 253d03a45..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/float/measure.py +++ /dev/null @@ -1,65 +0,0 @@ -import time -import argparse -import os -import subprocess -import shlex -from ruamel import yaml - - -def runcmd(cmd, *cmd_args, **subprocess_args): - cmd = shlex.split(cmd) + list(cmd_args) - #print(" ".join([f"'{a}'" for a in cmd]), flush=True) - proc = subprocess.run(cmd, **subprocess_args) - return proc - - -def getoutput(cmd, *cmd_args, **subprocess_args): - proc = runcmd(cmd, *cmd_args, **subprocess_args, check=True, - stdout=subprocess.PIPE) - return proc.stdout.decode("utf8") - - -def start_build(args): - ts = time.time() - with open(args.out, "w") as f: - f.write(str(ts)) - - -def finish_build(args): - ts = time.time() - with open(args.out, "r") as f: - start = float(f.read()) - duration = ts - start - results = { - 'compile': f"{duration:.3f}s", - 'file_size': f"{os.path.getsize(args.exe)}B" - } - s = yaml.dump({args.target: results}) - print(s, flush=True, end="") - ## too much output: - #if args.unix: - # # https://stackoverflow.com/questions/35485 - # results['size'] = getoutput('size', args.exe) - # #results['symbols'] = getoutput('nm -t d -l -S --size-sort', args.exe) - s = yaml.dump({args.target: results}) - with open(args.out, "w") as f: - f.write(s) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers() - # - sp = subparsers.add_parser("start") - sp.set_defaults(func=start_build) - sp.add_argument('target', type=str, help='the target name') - # - sp = subparsers.add_parser("finish") - sp.set_defaults(func=finish_build) - sp.add_argument('target', type=str, help='the target name') - sp.add_argument('exe', type=str, help='the executable file') - sp.add_argument('-u', '--unix', action="store_true", help='use unix style size reporters') - # - args = parser.parse_args() - args.out = f"{args.target}.dat" - args.func(args) diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/float/read.cpp b/third_party/rapidyaml/rapidyaml/ext/c4core/bm/float/read.cpp deleted file mode 100644 index 5401ff1bb..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/float/read.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include - - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4430) -# pragma warning(disable : 4305) -# pragma warning(disable : 4309) -# pragma warning(disable : 4838) -# pragma warning(disable : 4996) -#elif defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wsign-conversion" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsign-conversion" -#endif - - -#if C4FLOAT_STD_ATOF -#include -double doit(const char *s) { return atof(s); } -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_SSCANF_F -float doit(const char *s) { float val; sscanf(s, "%f", &val); return val; } -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_SSCANF_D -double doit(const char *s) { double val; sscanf(s, "%lf", &val); return val; } -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_IOSTREAM_F -#include -float doit(const char *s) { std::stringstream ss; ss << s; float val; ss >> val; return val; } -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_IOSTREAM_D -#include -double doit(const char *s) { std::stringstream ss; ss << s; double val; ss >> val; return val; } -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_IOSTREAM_D -#include -double doit(const char *s) { std::stringstream ss; ss << s; double val; ss >> val; return val; } -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_FP_F_LIMITED -#include -float doit(const char *s) -{ - auto result = jkj::fp::from_chars_limited(s, s+strlen(s)); - return result.to_float(); -} -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_FP_D_LIMITED -#include -double doit(const char *s) -{ - auto result = jkj::fp::from_chars_limited(s, s+strlen(s)); - return result.to_float(); -} -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_FP_F_UNLIMITED -#include -float doit(const char *s) -{ - auto result = jkj::fp::from_chars_unlimited(s, s+strlen(s)); - return result.to_float(); -} -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_FP_D_UNLIMITED -#include -double doit(const char *s) -{ - auto result = jkj::fp::from_chars_unlimited(s, s+strlen(s)); - return result.to_float(); -} -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_FASTFLOAT_F -#include -#include -float doit(const char *s) -{ - float result; - fast_float::from_chars(s, s+strlen(s), result); - return result; -} -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_FASTFLOAT_D -#include -#include -double doit(const char *s) -{ - double result; - fast_float::from_chars(s, s+strlen(s), result); - return result; -} -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_STD_FROM_CHARS_F -#include -#include -float doit(const char *s) -{ - float result; - std::from_chars(s, s+strlen(s), result); - return result; -} -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_STD_FROM_CHARS_D -#include -#include -double doit(const char *s) -{ - double result; - std::from_chars(s, s+strlen(s), result); - return result; -} -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_RYU_F -#include -float doit(const char *s) -{ - float result; - s2f(s, &result); - return result; -} -#define C4_TO_REAL(s) doit(s) - -#elif C4FLOAT_RYU_D -#include -double doit(const char *s) -{ - double result; - s2d(s, &result); - return result; -} -#define C4_TO_REAL(s) doit(s) - -#else -#define C4_TO_REAL(s) 0 -#endif - -int main() -{ - #define BUFSIZE 128 - char buf[BUFSIZE]; - while(fgets(buf, BUFSIZE, stdin)) - { - fputs(buf, stdout); - (void) C4_TO_REAL(buf); - } -} - - -#ifdef _MSC_VER -# pragma warning(pop) -#elif defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/ryu.cmake b/third_party/rapidyaml/rapidyaml/ext/c4core/bm/ryu.cmake deleted file mode 100644 index e847b9d43..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/bm/ryu.cmake +++ /dev/null @@ -1,33 +0,0 @@ -# ryu does not have a cmakelists -enable_language(C) -c4_download_remote_proj(ryu RYU_DIR - GIT_REPOSITORY https://github.com/ulfjack/ryu - GIT_TAG master) -set(RYU_HDR - ${RYU_DIR}/ryu/common.h - ${RYU_DIR}/ryu/d2fixed_full_table.h - ${RYU_DIR}/ryu/d2s_full_table.h - ${RYU_DIR}/ryu/d2s_intrinsics.h - ${RYU_DIR}/ryu/d2s_small_table.h - ${RYU_DIR}/ryu/digit_table.h - ${RYU_DIR}/ryu/f2s_full_table.h - ${RYU_DIR}/ryu/f2s_intrinsics.h - ${RYU_DIR}/ryu/ryu.h - ${RYU_DIR}/ryu/ryu_parse.h -) -set(RYU_SRC - ${RYU_DIR}/ryu/d2fixed.c - ${RYU_DIR}/ryu/d2s.c - ${RYU_DIR}/ryu/f2s.c - ${RYU_DIR}/ryu/s2d.c - ${RYU_DIR}/ryu/s2f.c -) -add_library(ryu_c4 ${RYU_SRC} ${RYU_HDR}) -target_include_directories(ryu_c4 PUBLIC $) -set_target_properties(ryu_c4 PROPERTIES LINKER_LANGUAGE CXX) -if(CMAKE_CXX_COMPILER_ID STREQUAL GNU) - target_compile_options(ryu_c4 PRIVATE -Wno-sign-conversion) -elseif(CMAKE_CXX_COMPILER_ID STREQUAL GNU) - target_compile_options(ryu_c4 -Wno-deprecated) -endif() -_c4_set_target_folder(ryu_c4 ext) diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/cmake/ConfigurationTypes.cmake b/third_party/rapidyaml/rapidyaml/ext/c4core/cmake/ConfigurationTypes.cmake deleted file mode 100644 index 45395ad1b..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/cmake/ConfigurationTypes.cmake +++ /dev/null @@ -1,120 +0,0 @@ - - -# this function works both with multiconfig and single-config generators. -function(set_default_build_type which) - # CMAKE_CONFIGURATION_TYPES is available only for multiconfig generators. - # so set the build type only if CMAKE_CONFIGURATION_TYPES does not exist. - if(NOT CMAKE_CONFIGURATION_TYPES) # not a multiconfig generator? - if(NOT CMAKE_BUILD_TYPE) - if(NOT which) - set(which RelWithDebInfo) - endif() - message("Defaulting to ${which} build.") - set(CMAKE_BUILD_TYPE ${which} CACHE STRING "") - endif() - endif() -endfunction() - - -# https://stackoverflow.com/questions/31546278/where-to-set-cmake-configuration-types-in-a-project-with-subprojects -function(setup_configuration_types) - set(options0arg - ) - set(options1arg - DEFAULT - ) - set(optionsnarg - TYPES - ) - cmake_parse_arguments("" "${options0arg}" "${options1arg}" "${optionsnarg}" ${ARGN}) - - if(NOT TYPES) - set(TYPES Release Debug RelWithDebInfo MinSizeRel) - endif() - - # make it safe to call repeatedly - if(NOT _setup_configuration_types_done) - set(_setup_configuration_types_done 1 CACHE INTERNAL "") - - # No reason to set CMAKE_CONFIGURATION_TYPES if it's not a multiconfig generator - # Also no reason mess with CMAKE_BUILD_TYPE if it's a multiconfig generator. - - if(CMAKE_CONFIGURATION_TYPES) # multiconfig generator? - set(CMAKE_CONFIGURATION_TYPES "${TYPES}" CACHE STRING "") - else() # single-config generator - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build") - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${TYPES}") - # set the valid options for cmake-gui drop-down list - endif() - endif() -endfunction() - - -# https://stackoverflow.com/questions/31546278/where-to-set-cmake-configuration-types-in-a-project-with-subprojects -function(add_configuration_type name) - set(flag_vars - C_FLAGS - CXX_FLAGS - SHARED_LINKER_FLAGS - STATIC_LINKER_FLAGS - MODULE_LINKER_FLAGS - EXE_LINKER_FLAGS - RC_FLAGS - ) - - set(options0arg - PREPEND # when defaulting to a config, prepend to it instead of appending to it - SET_MAIN_FLAGS # eg, set CMAKE_CXX_FLAGS from CMAKE_CXX_FLAGS_${name} - ) - set(options1arg - DEFAULT_FROM # take the initial value of the flags from this config - ) - set(optionsnarg - C_FLAGS - CXX_FLAGS - SHARED_LINKER_FLAGS - STATIC_LINKER_FLAGS - MODULE_LINKER_FLAGS - EXE_LINKER_FLAGS - RC_FLAGS - ) - cmake_parse_arguments(_act "${options0arg}" "${options1arg}" "${optionsnarg}" ${ARGN}) - - string(TOUPPER ${name} UNAME) - - # make it safe to call repeatedly - if(NOT _add_configuration_type_${name}) - set(_add_configuration_type_${name} 1 CACHE INTERNAL "") - - setup_configuration_types() - - if(CMAKE_CONFIGURATION_TYPES) # multiconfig generator? - set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES};${name}" CACHE STRING "" FORCE) - else() # single-config generator - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${CMAKE_BUILD_TYPES};${name}" FORCE) - # set the valid options for cmake-gui drop-down list - endif() - - # now set up the configuration - message(STATUS "config: CMAKE_${f}_${UNAME} --- ${val}") - foreach(f ${flag_vars}) - set(val ${_act_${f}}) - message(STATUS "config: ${name}: ${f} --- ${val}") - if(_act_DEFAULT_FROM) - if(_act_PREPEND) - set(val "${val} ${CMAKE_${f}_${_act_DEFAULT_FROM}}") - else() - set(val "${CMAKE_${f}_${_act_DEFAULT_FROM}} ${val}") - endif() - endif() - message(STATUS "config: CMAKE_${f}_${UNAME} --- ${val}") - set(CMAKE_${f}_${UNAME} "${val}" CACHE STRING "" FORCE) - mark_as_advanced(CMAKE_${f}_${UNAME}) - if(_act_SET_MAIN_FLAGS) - set(CMAKE_${f} "${CMAKE_${f}_${UNAME}}" CACHE STRING "" FORCE) - endif() - endforeach() - endif() - -endfunction() diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/cmake/CreateSourceGroup.cmake b/third_party/rapidyaml/rapidyaml/ext/c4core/cmake/CreateSourceGroup.cmake deleted file mode 100644 index 2250c8f25..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/cmake/CreateSourceGroup.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# create hierarchical source groups based on a dir tree -# -# EXAMPLE USAGE: -# -# create_source_group("src" "${SRC_ROOT}" "${SRC_LIST}") -# -# Visual Studio usually has the equivalent to this: -# -# create_source_group("Header Files" ${PROJ_SRC_DIR} "${PROJ_HEADERS}") -# create_source_group("Source Files" ${PROJ_SRC_DIR} "${PROJ_SOURCES}") -# -# TODO: this was taken from a stack overflow answer. Need to find it -# and add a link here. - -macro(create_source_group GroupPrefix RootDir ProjectSources) - set(DirSources ${ProjectSources}) - foreach(Source ${DirSources}) - #message(STATUS "s=${Source}") - string(REGEX REPLACE "${RootDir}" "" RelativePath "${Source}") - #message(STATUS " ${RelativePath}") - string(REGEX REPLACE "[\\\\/][^\\\\/]*$" "" RelativePath "${RelativePath}") - #message(STATUS " ${RelativePath}") - string(REGEX REPLACE "^[\\\\/]" "" RelativePath "${RelativePath}") - #message(STATUS " ${RelativePath}") - string(REGEX REPLACE "/" "\\\\\\\\" RelativePath "${RelativePath}") - #message(STATUS " ${RelativePath}") - source_group("${GroupPrefix}\\${RelativePath}" FILES ${Source}) - #message(STATUS " ${Source}") - endforeach(Source) -endmacro(create_source_group) diff --git a/third_party/rapidyaml/rapidyaml/ext/c4core/cmake/Doxyfile.full.in b/third_party/rapidyaml/rapidyaml/ext/c4core/cmake/Doxyfile.full.in deleted file mode 100644 index f444cb742..000000000 --- a/third_party/rapidyaml/rapidyaml/ext/c4core/cmake/Doxyfile.full.in +++ /dev/null @@ -1,2566 +0,0 @@ -# Doxyfile 1.8.15 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the configuration -# file that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# https://www.gnu.org/software/libiconv/ for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = @_PROJ@ - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = @_VERSION@ - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = @_PROJ_BRIEF@ - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = @_OUTPUT_DIR@ - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = YES - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all generated output in the proper direction. -# Possible values are: None, LTR, RTL and Context. -# The default value is: None. - -OUTPUT_TEXT_DIRECTION = None - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = YES - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = @_STRIP_FROM_PATH@ - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = @_STRIP_FROM_INC_PATH@ - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = YES - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = YES - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines (in the resulting output). You can put ^^ in the value part of an -# alias to insert a newline as if a physical newline was in the original file. -# When you need a literal { or } or , in the value part of an alias you have to -# escape them by means of a backslash (\), this can lead to conflicts with the -# commands \{ and \} for these it is advised to use the version @{ and @} or use -# a double escape (\\{ and \\}) - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice -# sources only. Doxygen will then generate output that is more tailored for that -# language. For instance, namespaces will be presented as modules, types will be -# separated into more groups, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_SLICE = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, -# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: -# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser -# tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is -# Fortran), use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See https://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up -# to that level are automatically included in the table of contents, even if -# they do not have an id attribute. -# Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 0. -# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. - -TOC_INCLUDE_HEADINGS = 4 - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = YES - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = YES - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = YES - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = YES - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = YES - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = YES - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = YES - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if ... \endif and \cond -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. If -# EXTRACT_ALL is set to YES then this flag will automatically be disabled. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = @_INPUT@ - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: https://www.gnu.org/software/libiconv/) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.idl \ - *.ddl \ - *.odl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.cs \ - *.d \ - *.php \ - *.php4 \ - *.php5 \ - *.phtml \ - *.inc \ - *.m \ - *.markdown \ - *.md \ - *.mm \ - *.dox \ - *.py \ - *.pyw \ - *.f90 \ - *.f95 \ - *.f03 \ - *.f08 \ - *.f \ - *.for \ - *.tcl \ - *.vhd \ - *.vhdl \ - *.ucf \ - *.qsf \ - *.ice \ - @_FILE_PATTERNS@ - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = @_EXCLUDE@ - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = @_EXCLUDE_PATTERNS@ - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = @_EXCLUDE_SYMBOLS@ - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = @_EXAMPLE_PATH@ - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = YES - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# -# -# where is the value of the INPUT_FILTER tag, and is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = YES - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = NO - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# entity all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see https://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = YES - -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the -# cost of reduced performance. This can be particularly helpful with template -# rich C++ code for which doxygen's built-in parser lacks the necessary type -# information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = YES - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - -# If clang assisted parsing is enabled you can provide the clang parser with the -# path to the compilation database (see: -# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files -# were built. This is equivalent to specifying the "-p" option to a clang tool, -# such as clang-check. These options will then be passed to the parser. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. - -CLANG_DATABASE_PATH = @_CLANG_DATABASE_PATH@ - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = YES - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# https://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML -# documentation will contain a main index with vertical navigation menus that -# are dynamically created via Javascript. If disabled, the navigation index will -# consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have Javascript, -# like the Qt help browser. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_MENUS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: https://developer.apple.com/xcode/), introduced with OSX -# 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy -# genXcode/_index.html for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. -# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use + S -# (what the is depends on the OS and browser, but it is typically -# , /