diff --git a/.gitignore b/.gitignore index 786c3787..b54ffd00 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,11 @@ log/ logs/ temp/ picker_out* +output/ dependence/xcomm +dependence/fmt/ +dependence/slang/ +dependence/yaml-cpp/ AppDir/ app_image_build/ @@ -66,3 +70,4 @@ Testing # Local verible installs/archives verible-*/ verible-*.tar.gz + diff --git a/CMakeLists.txt b/CMakeLists.txt index 74263ebe..ce065272 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,10 +58,12 @@ else() message(FATAL_ERROR "dependence/slang is missing. Run 'make init' first to fetch slang and fmt.") endif() -# third -# add_subdirectory(third/type_safe) -# add_subdirectory(third/cppast) -add_subdirectory(third/yaml-cpp) +# YAML parser +if(EXISTS "${PROJECT_SOURCE_DIR}/dependence/yaml-cpp/CMakeLists.txt") + add_subdirectory(dependence/yaml-cpp) +else() + message(FATAL_ERROR "dependence/yaml-cpp is missing. Run 'make init' first to fetch yaml-cpp.") +endif() LINK_LIBRARIES(yaml-cpp) # source diff --git a/Makefile b/Makefile index f1ef8b88..5792538c 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,11 @@ -SHELL := /bin/bash +SHELL := bash .SHELLFLAGS := -eu -o pipefail -c .PHONY: all init build install appimage test test_all test_vpi_all test_mem_direct_all \ test_all_java test_all_scala clean wheel wheel_install tests smoke_tests unit_tests +include example/example.mk + export NPROC := $(shell (nproc 2>/dev/null || sysctl -n hw.ncpu) 2>/dev/null) export BUILD_XSPCOMM_SWIG ?= python @@ -45,44 +47,33 @@ test: build ./build/bin/picker exports -h test_all: - rm -rf picker_out_* - ./example/Adder/release-verilator.sh --lang python - ./example/RandomGenerator/release-verilator.sh --lang python - ./example/AdderMultiInstance/release-verilator.sh --lang python - ./example/Cache/release-verilator.sh --lang python + rm -rf output + @for example in $(EXAMPLE_TEST_ALL); do \ + $(MAKE) test_$$example EXAMPLE_LANG=python ARGS="$(ARGS)" || exit $$?; \ + done test_vpi_all: - bash example/InternalSignals/release-verilator.sh --lang cpp - bash example/InternalSignals/release-verilator.sh --lang golang - bash example/InternalSignals/release-verilator.sh --lang java - bash example/InternalSignals/release-verilator.sh --lang lua - bash example/InternalSignals/release-verilator.sh --lang python - bash example/InternalSignals/release-verilator.sh --lang scala + @for lang in cpp golang java lua python scala; do \ + $(MAKE) test_InternalSignals EXAMPLE_LANG=$$lang ARGS="$(ARGS)" || exit $$?; \ + done test_mem_direct_all: - bash example/CacheSignalCFG/release-verilator.sh --lang cpp - bash example/CacheSignalCFG/release-verilator.sh --lang golang - bash example/CacheSignalCFG/release-verilator.sh --lang java - bash example/CacheSignalCFG/release-verilator.sh --lang lua - bash example/CacheSignalCFG/release-verilator.sh --lang python - bash example/CacheSignalCFG/release-verilator.sh --lang scala + @for lang in cpp golang java lua python scala; do \ + $(MAKE) test_CacheSignalCFG EXAMPLE_LANG=$$lang ARGS="$(ARGS)" || exit $$?; \ + done test_all_java: - bash example/Adder/release-verilator.sh --lang java - bash example/RandomGenerator/release-verilator.sh --lang java - bash example/DualPortStackCb/release-verilator.sh --lang java - bash example/InternalSignals/release-verilator.sh --lang java - bash example/CacheSignalCFG/release-verilator.sh --lang java + @for example in $(EXAMPLE_TEST_ALL_JAVA); do \ + $(MAKE) test_$$example EXAMPLE_LANG=java ARGS="$(ARGS)" || exit $$?; \ + done test_all_scala: - bash example/Adder/release-verilator.sh --lang scala - bash example/RandomGenerator/release-verilator.sh --lang scala - bash example/DualPortStackCb/release-verilator.sh --lang scala - bash example/InternalSignals/release-verilator.sh --lang scala - bash example/CacheSignalCFG/release-verilator.sh --lang scala + @for example in $(EXAMPLE_TEST_ALL_SCALA); do \ + $(MAKE) test_$$example EXAMPLE_LANG=scala ARGS="$(ARGS)" || exit $$?; \ + done clean: - rm -rf temp build dist picker_out* app_image_build AppDir + rm -rf temp build dist output app_image_build AppDir picker_out* picker_e203_ifu_ift2icb wheel: init cd dependence/xcomm && $(MAKE) wheel diff --git a/example/Adder/release-uvm.sh b/example/Adder/release-uvm.sh index 1fdd8f5c..e66a0a59 100755 --- a/example/Adder/release-uvm.sh +++ b/example/Adder/release-uvm.sh @@ -1,6 +1,9 @@ #!/bin/bash -rm -rf picker_out_adder/ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/Adder" + +rm -rf "$OUT_DIR" ./build/bin/picker pack --from-rtl example/Adder/Adder.v -n Adder -d -e @@ -10,6 +13,6 @@ rm -rf uvmpy/example.py cp example/Adder/example.py uvmpy/ cp example/Adder/example-uvm.sv uvmpy/ -mv uvmpy picker_out_adder +mv uvmpy "$OUT_DIR" -cd picker_out_adder && make +cd "$OUT_DIR" && make diff --git a/example/Adder/release-vcs.sh b/example/Adder/release-vcs.sh index 12efac93..cea264dd 100755 --- a/example/Adder/release-vcs.sh +++ b/example/Adder/release-vcs.sh @@ -1,43 +1,39 @@ #!/bin/bash +set -e -rm -rf picker_out_adder/ -./build/bin/picker export example/Adder/Adder.v --autobuild false --sim vcs -w Adder.fsdb --sname Adder --tdir picker_out_adder/ --sdir template $@ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="$(realpath -m "${OUT_ROOT}/Adder")" + +rm -rf "$OUT_DIR" +./build/bin/picker export example/Adder/Adder.v --autobuild true --sim vcs -w Adder.fsdb --sname Adder --tdir "$OUT_DIR" --sdir template --coverage "$@" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then - cp example/Adder/example.py picker_out_adder/ -elif [[ $@ == *"java"* ]]; then - cp example/Adder/example.java picker_out_adder/Adder/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/Adder/example.scala picker_out_adder/Adder/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/Adder/example.go picker_out_adder/Adder/golang/ +if [[ $* == *"python"* ]]; then + cp example/Adder/example.py "$OUT_DIR" +elif [[ $* == *"java"* ]]; then + cp example/Adder/example.java "$OUT_DIR" +elif [[ $* == *"scala"* ]]; then + cp example/Adder/example.scala "$OUT_DIR" +elif [[ $* == *"golang"* ]]; then + cp example/Adder/example.go "$OUT_DIR" +elif [[ $* == *"lua"* ]]; then + cp example/Adder/example.lua "$OUT_DIR" else - cp example/Adder/example.cpp picker_out_adder/Adder/cpp/ -fi - -# go to the Adder directory and make all -cd picker_out_adder/Adder && make EXAMPLE=ON - -# go back to the root directory -cd ../ - -if [[ $@ != *"cpp"* ]]; then - echo "'cannot allocate memory in static TLS block'error for VCS is expected, please ignore it" -fi - -if [[ $@ == *"python"* ]]; then - LD_PRELOAD=./Adder/libUTAdder.so python3 example.py -fi - -if [[ $@ == *"scala"* ]]; then - LD_PRELOAD=./Adder/libUTAdder.so scala -cp ./Adder/UT_Adder-scala.jar:./Adder/xspcomm-scala.jar -ea com.ut.example + cp example/Adder/example.cpp "$OUT_DIR" fi -if [[ $@ == *"java"* ]]; then - LD_PRELOAD=./Adder/libUTAdder.so java -cp ./Adder/UT_Adder-java.jar:./Adder/xspcomm-java.jar -ea com.ut.example -fi - -if [[ $@ == *"golang"* ]]; then - LD_PRELOAD=./Adder/golang/src/UT_Adder/libUTAdder.so GO111MODULE=off GOPATH="`pwd`/Adder/golang" go build example.go - LD_PRELOAD=./Adder/golang/src/UT_Adder/libUTAdder.so GO111MODULE=off GOPATH="`pwd`/Adder/golang" ./example +cd "$OUT_DIR" + +if [[ $* == *"python"* ]]; then + python3 example.py +elif [[ $* == *"java"* ]]; then + java -cp ./UT_Adder-java.jar:./xspcomm-java.jar -ea com.ut.example +elif [[ $* == *"scala"* ]]; then + scala -cp ./UT_Adder-scala.jar:./xspcomm-scala.jar -ea com.ut.example +elif [[ $* == *"golang"* ]]; then + GO111MODULE=off GOPATH="$(pwd)/golang" go build example.go + ./example +elif [[ $* == *"lua"* ]]; then + LUA_PATH="./xspcomm/?.lua" lua example.lua +else + ./UTAdder_example fi diff --git a/example/Adder/release-verilator.sh b/example/Adder/release-verilator.sh index 220d5426..1795cced 100755 --- a/example/Adder/release-verilator.sh +++ b/example/Adder/release-verilator.sh @@ -1,20 +1,23 @@ #!/bin/bash -rm -rf picker_out_adder/ -./build/bin/picker export example/Adder/Adder.v --autobuild false -w Adder.fst --sname Adder --tdir picker_out_adder/Adder --sdir template $@ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/Adder" + +rm -rf "$OUT_DIR" +./build/bin/picker export example/Adder/Adder.v --autobuild false -w Adder.fst --sname Adder --tdir "$OUT_DIR" --sdir template "$@" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then - cp example/Adder/example.py picker_out_adder/Adder/python/ -elif [[ $@ == *"java"* ]]; then - cp example/Adder/example.java picker_out_adder/Adder/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/Adder/example.scala picker_out_adder/Adder/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/Adder/example.go picker_out_adder/Adder/golang/ -elif [[ $@ == *"lua"* ]]; then - cp example/Adder/example.lua picker_out_adder/Adder/lua/ +if [[ $* == *"python"* ]]; then + cp example/Adder/example.py "$OUT_DIR/python/" +elif [[ $* == *"java"* ]]; then + cp example/Adder/example.java "$OUT_DIR/java/" +elif [[ $* == *"scala"* ]]; then + cp example/Adder/example.scala "$OUT_DIR/scala/" +elif [[ $* == *"golang"* ]]; then + cp example/Adder/example.go "$OUT_DIR/golang/" +elif [[ $* == *"lua"* ]]; then + cp example/Adder/example.lua "$OUT_DIR/lua/" else - cp example/Adder/example.cpp picker_out_adder/Adder/cpp/ + cp example/Adder/example.cpp "$OUT_DIR/cpp/" fi -cd picker_out_adder/Adder && make EXAMPLE=ON +cd "$OUT_DIR" && make EXAMPLE=ON diff --git a/example/AdderMultiInstance/release-verilator.sh b/example/AdderMultiInstance/release-verilator.sh index 32c364b2..8707f59c 100755 --- a/example/AdderMultiInstance/release-verilator.sh +++ b/example/AdderMultiInstance/release-verilator.sh @@ -1,13 +1,16 @@ #!/bin/bash -rm -rf picker_out_adder/ -./build/bin/picker export example/AdderMultiInstance/Adder.v --autobuild false -w Adder.fst --sname Adder --tdir picker_out_adder --sdir template $@ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/AdderMultiInstance" + +rm -rf "$OUT_DIR" +./build/bin/picker export example/AdderMultiInstance/Adder.v --autobuild false -w Adder.fst --sname Adder --tdir "$OUT_DIR" --sdir template "$@" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then - cp example/AdderMultiInstance/example.py picker_out_adder/python/ +if [[ $* == *"python"* ]]; then + cp example/AdderMultiInstance/example.py "$OUT_DIR/python/" else echo "Only example.py find! Use --lang python" exit -1 fi -cd picker_out_adder && make EXAMPLE=ON +cd "$OUT_DIR" && make EXAMPLE=ON diff --git a/example/Cache/release-verilator.sh b/example/Cache/release-verilator.sh index 99cc8d96..b365a48d 100755 --- a/example/Cache/release-verilator.sh +++ b/example/Cache/release-verilator.sh @@ -2,8 +2,11 @@ # This script is used to release the XDummyCache library. +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/Cache" + # run cache codegen -rm -rf picker_out/Cache -./build/bin/picker export --autobuild true example/Cache/Cache.v --fs example/Cache/Test.v -w cache.vcd --sim verilator --tdir ./picker_out/ $@ +rm -rf "$OUT_DIR" +./build/bin/picker export --autobuild true example/Cache/Cache.v --fs example/Cache/Test.v -w cache.vcd --sim verilator --tdir "${OUT_ROOT}/" "$@" # --autobuild true: auto build and test diff --git a/example/CacheSignalCFG/release-vcs.sh b/example/CacheSignalCFG/release-vcs.sh index 3fbc9104..33508db4 100755 --- a/example/CacheSignalCFG/release-vcs.sh +++ b/example/CacheSignalCFG/release-vcs.sh @@ -1,11 +1,39 @@ #!/bin/bash +set -e -rm -rf picker_out_Cache/ -./build/bin/picker export example/Cache/Cache.v --autobuild true --sim vcs -w Cache.fsdb --sname Cache --tdir picker_out_Cache --sdir template $@ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="$(realpath -m "${OUT_ROOT}/CacheSignalCFG")" -cd picker_out_Cache && make EXAMPLE=ON +rm -rf "$OUT_DIR" +./build/bin/picker export example/Cache/Cache.v --autobuild true --sim vcs -w Cache.fsdb --sname Cache --tdir "$OUT_DIR" --sdir template "$@" -if [[ $@ == *"python"* ]]; then - echo "'cannot allocate memory in static TLS block'error for VCS is expected, please ignore it" - LD_PRELOAD=./libUTCache.so python3 example.py +if [[ $* == *"python"* ]]; then + cp example/CacheSignalCFG/example.py "$OUT_DIR" +elif [[ $* == *"java"* ]]; then + cp example/CacheSignalCFG/example.java "$OUT_DIR" +elif [[ $* == *"scala"* ]]; then + cp example/CacheSignalCFG/example.scala "$OUT_DIR" +elif [[ $* == *"golang"* ]]; then + cp example/CacheSignalCFG/example.go "$OUT_DIR" +elif [[ $* == *"lua"* ]]; then + cp example/CacheSignalCFG/example.lua "$OUT_DIR" +else + cp example/CacheSignalCFG/example.cpp "$OUT_DIR" +fi + +cd "$OUT_DIR" + +if [[ $* == *"python"* ]]; then + python3 example.py +elif [[ $* == *"java"* ]]; then + java -cp ./UT_Cache-java.jar:./xspcomm-java.jar -ea com.ut.example +elif [[ $* == *"scala"* ]]; then + scala -cp ./UT_Cache-scala.jar:./xspcomm-scala.jar -ea com.ut.example +elif [[ $* == *"golang"* ]]; then + GO111MODULE=off GOPATH="$(pwd)/golang" go build example.go + ./example +elif [[ $* == *"lua"* ]]; then + LUA_PATH="./xspcomm/?.lua" lua example.lua +else + ./UTCache_example fi diff --git a/example/CacheSignalCFG/release-verilator.sh b/example/CacheSignalCFG/release-verilator.sh index db3cb168..a05dab22 100755 --- a/example/CacheSignalCFG/release-verilator.sh +++ b/example/CacheSignalCFG/release-verilator.sh @@ -2,30 +2,33 @@ # This script is used to release the XDummyCache library. +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/CacheSignalCFG" + # run cache codegen -rm -rf picker_out/CacheCFG +rm -rf "$OUT_DIR" # Use file list and explicit sname to locate top module in list ./build/bin/picker export --autobuild false --rw mem_direct \ --sname Cache \ - --tname CacheCFG \ + --tname CacheSignalCFG \ --fs example/CacheSignalCFG/Cache.txt \ - -w cache.vcd --sim verilator --tdir ./picker_out/ $@ + -w cache.vcd --sim verilator --tdir "${OUT_ROOT}/" "$@" -if [[ $@ == *"python"* ]]; then - cp example/CacheSignalCFG/example.py picker_out/CacheCFG/python/ -elif [[ $@ == *"java"* ]]; then - cp example/CacheSignalCFG/example.java picker_out/CacheCFG/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/CacheSignalCFG/example.scala picker_out/CacheCFG/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/CacheSignalCFG/example.go picker_out/CacheCFG/golang/ -elif [[ $@ == *"lua"* ]]; then - cp example/CacheSignalCFG/example.lua picker_out/CacheCFG/lua/ +if [[ $* == *"python"* ]]; then + cp example/CacheSignalCFG/example.py "$OUT_DIR/python/" +elif [[ $* == *"java"* ]]; then + cp example/CacheSignalCFG/example.java "$OUT_DIR/java/" +elif [[ $* == *"scala"* ]]; then + cp example/CacheSignalCFG/example.scala "$OUT_DIR/scala/" +elif [[ $* == *"golang"* ]]; then + cp example/CacheSignalCFG/example.go "$OUT_DIR/golang/" +elif [[ $* == *"lua"* ]]; then + cp example/CacheSignalCFG/example.lua "$OUT_DIR/lua/" else - cp example/CacheSignalCFG/example.cpp picker_out/CacheCFG/cpp/ + cp example/CacheSignalCFG/example.cpp "$OUT_DIR/cpp/" fi -cd picker_out/CacheCFG && make EXAMPLE=ON +cd "$OUT_DIR" && make EXAMPLE=ON # --autobuild true: auto build and test diff --git a/example/DualPortStackCb/release-uvs.sh b/example/DualPortStackCb/release-uvs.sh index f4c9a93f..e097390c 100755 --- a/example/DualPortStackCb/release-uvs.sh +++ b/example/DualPortStackCb/release-uvs.sh @@ -1,29 +1,30 @@ #!/bin/bash -rm -rf picker_out_dps/ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/DualPortStackCb" -./build/bin/picker export example/DualPortStackCb/dual_port_stack.v --sim uvs --autobuild false -w DualPortStackCb.usdb $@ --tdir picker_out_dps +rm -rf "$OUT_DIR" +./build/bin/picker export example/DualPortStackCb/dual_port_stack.v --sim uvs --autobuild false -w DualPortStackCb.usdb "$@" --tdir "$OUT_DIR" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then +if [[ $* == *"python"* ]]; then if [[ "$async" != "" ]]; then - cp example/DualPortStackCb/example_async.py picker_out_dps/python/example.py + cp example/DualPortStackCb/example_async.py "$OUT_DIR/python/example.py" else - cp example/DualPortStackCb/example.py picker_out_dps/python/ + cp example/DualPortStackCb/example.py "$OUT_DIR/python/" fi -elif [[ $@ == *"java"* ]]; then - cp example/DualPortStackCb/example.java picker_out_dps/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/DualPortStackCb/example.scala picker_out_dps/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/DualPortStackCb/example.go picker_out_dps/golang/ +elif [[ $* == *"java"* ]]; then + cp example/DualPortStackCb/example.java "$OUT_DIR/java/" +elif [[ $* == *"scala"* ]]; then + cp example/DualPortStackCb/example.scala "$OUT_DIR/scala/" +elif [[ $* == *"golang"* ]]; then + cp example/DualPortStackCb/example.go "$OUT_DIR/golang/" else - cp example/DualPortStackCb/example.cpp picker_out_dps/cpp/ + cp example/DualPortStackCb/example.cpp "$OUT_DIR/cpp/" fi -cd picker_out_dps && make EXAMPLE=ON VERBOSE=ON CFLAGS=-g +cd "$OUT_DIR" && make EXAMPLE=ON VERBOSE=ON CFLAGS=-g if [[ $@ == *"python"* ]]; then echo "'cannot allocate memory in static TLS block'error for UVS is expected, please ignore it" LD_PRELOAD=./UT_dual_port_stack/libUTdual_port_stack.so python3 example.py fi - diff --git a/example/DualPortStackCb/release-verilator.sh b/example/DualPortStackCb/release-verilator.sh index ddbfaeff..c88f8b0c 100755 --- a/example/DualPortStackCb/release-verilator.sh +++ b/example/DualPortStackCb/release-verilator.sh @@ -1,23 +1,25 @@ #!/bin/bash -rm -rf picker_out_dps/ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/DualPortStackCb" -./build/bin/picker export example/DualPortStackCb/dual_port_stack.v --autobuild false -w DualPortStackCb.fst $@ --tdir picker_out_dps +rm -rf "$OUT_DIR" +./build/bin/picker export example/DualPortStackCb/dual_port_stack.v --autobuild false -w DualPortStackCb.fst "$@" --tdir "$OUT_DIR" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then +if [[ $* == *"python"* ]]; then if [[ "$async" != "" ]]; then - cp example/DualPortStackCb/example_async.py picker_out_dps/python/example.py + cp example/DualPortStackCb/example_async.py "$OUT_DIR/python/example.py" else - cp example/DualPortStackCb/example.py picker_out_dps/python/ + cp example/DualPortStackCb/example.py "$OUT_DIR/python/" fi -elif [[ $@ == *"java"* ]]; then - cp example/DualPortStackCb/example.java picker_out_dps/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/DualPortStackCb/example.scala picker_out_dps/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/DualPortStackCb/example.go picker_out_dps/golang/ +elif [[ $* == *"java"* ]]; then + cp example/DualPortStackCb/example.java "$OUT_DIR/java/" +elif [[ $* == *"scala"* ]]; then + cp example/DualPortStackCb/example.scala "$OUT_DIR/scala/" +elif [[ $* == *"golang"* ]]; then + cp example/DualPortStackCb/example.go "$OUT_DIR/golang/" else - cp example/DualPortStackCb/example.cpp picker_out_dps/cpp/ + cp example/DualPortStackCb/example.cpp "$OUT_DIR/cpp/" fi -cd picker_out_dps && make EXAMPLE=ON +cd "$OUT_DIR" && make EXAMPLE=ON diff --git a/example/GSim/NutShell/release-gsim.sh b/example/GSim/NutShell/release-gsim.sh index e68e8af1..f5ba20dc 100644 --- a/example/GSim/NutShell/release-gsim.sh +++ b/example/GSim/NutShell/release-gsim.sh @@ -8,25 +8,28 @@ then exit fi -rm -rf picker_out_GSIM/ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/NutShell" + +rm -rf "$OUT_DIR" if [ ! -f example/GSim/NutShell/SimTop-nutshell.fir ]; then tar -xf example/GSim/NutShell/SimTop-nutshell.tar.bz2 -C example/GSim/NutShell/ fi -./build/bin/picker export example/GSim/NutShell/SimTop-nutshell.fir --rw mem_direct --autobuild false --sim gsim --tdir picker_out_GSIM/NutShell $@ +./build/bin/picker export example/GSim/NutShell/SimTop-nutshell.fir --rw mem_direct --autobuild false --sim gsim --tdir "$OUT_DIR" "$@" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then - cp example/GSim/NutShell/example.py picker_out_GSIM/NutShell/python/ - cp example/GSim/NutShell/microbench-NutShell.bin picker_out_GSIM/NutShell/ -elif [[ $@ == *"java"* ]]; then - cp example/GSim/NutShell/example.java picker_out_GSIM/NutShell/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/GSim/NutShell/example.scala picker_out_GSIM/NutShell/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/GSim/NutShell/example.go picker_out_GSIM/NutShell/golang/ -elif [[ $@ == *"lua"* ]]; then - cp example/GSim/NutShell/example.lua picker_out_GSIM/NutShell/lua/ -elif [[ $@ == *"cpp"* ]]; then - cp example/GSim/NutShell/example.cpp picker_out_GSIM/NutShell/cpp/ +if [[ $* == *"python"* ]]; then + cp example/GSim/NutShell/example.py "$OUT_DIR/python/" + cp example/GSim/NutShell/microbench-NutShell.bin "$OUT_DIR/" +elif [[ $* == *"java"* ]]; then + cp example/GSim/NutShell/example.java "$OUT_DIR/java/" +elif [[ $* == *"scala"* ]]; then + cp example/GSim/NutShell/example.scala "$OUT_DIR/scala/" +elif [[ $* == *"golang"* ]]; then + cp example/GSim/NutShell/example.go "$OUT_DIR/golang/" +elif [[ $* == *"lua"* ]]; then + cp example/GSim/NutShell/example.lua "$OUT_DIR/lua/" +elif [[ $* == *"cpp"* ]]; then + cp example/GSim/NutShell/example.cpp "$OUT_DIR/cpp/" else echo "No example file copied, use default config." fi @@ -38,4 +41,4 @@ if [ -z $CC ] && [ -z $CXX ]; then else echo "Using CC=$CC and CXX=$CXX" fi -cd picker_out_GSIM/NutShell && make EXAMPLE=ON +cd "$OUT_DIR" && make EXAMPLE=ON diff --git a/example/InternalSignals/release-verilator.sh b/example/InternalSignals/release-verilator.sh index 5899a4a6..dbc41086 100755 --- a/example/InternalSignals/release-verilator.sh +++ b/example/InternalSignals/release-verilator.sh @@ -2,9 +2,12 @@ # This script is used to release the XDummyCache library. +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/InternalSignals" + # run cache codegen -rm -rf ./picker_out -./build/bin/picker export example/InternalSignals/vpi.v --autobuild false --sdir ./template --vpi --sname vpi --tdir ./picker_out/InternalSignals --sim verilator $@ +rm -rf "$OUT_DIR" +./build/bin/picker export example/InternalSignals/vpi.v --autobuild false --sdir ./template --vpi --sname vpi --tdir "$OUT_DIR" --sim verilator "$@" if [ $? -ne 0 ]; then echo "codegen failed" @@ -12,19 +15,18 @@ if [ $? -ne 0 ]; then fi # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then - cp example/InternalSignals/example.py picker_out/InternalSignals/python/ -elif [[ $@ == *"java"* ]]; then - cp example/InternalSignals/example.java picker_out/InternalSignals/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/InternalSignals/example.scala picker_out/InternalSignals/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/InternalSignals/example.go picker_out/InternalSignals/golang/ -elif [[ $@ == *"lua"* ]]; then - cp example/InternalSignals/example.lua picker_out/InternalSignals/lua/ +if [[ $* == *"python"* ]]; then + cp example/InternalSignals/example.py "$OUT_DIR/python/" +elif [[ $* == *"java"* ]]; then + cp example/InternalSignals/example.java "$OUT_DIR/java/" +elif [[ $* == *"scala"* ]]; then + cp example/InternalSignals/example.scala "$OUT_DIR/scala/" +elif [[ $* == *"golang"* ]]; then + cp example/InternalSignals/example.go "$OUT_DIR/golang/" +elif [[ $* == *"lua"* ]]; then + cp example/InternalSignals/example.lua "$OUT_DIR/lua/" else - cp example/InternalSignals/example.cpp picker_out/InternalSignals/cpp/ + cp example/InternalSignals/example.cpp "$OUT_DIR/cpp/" fi -cd picker_out/InternalSignals && make EXAMPLE=ON - +cd "$OUT_DIR" && make EXAMPLE=ON diff --git a/example/MultiClock/release-verilator.sh b/example/MultiClock/release-verilator.sh index aa5b16da..22c5cd0c 100755 --- a/example/MultiClock/release-verilator.sh +++ b/example/MultiClock/release-verilator.sh @@ -1,13 +1,16 @@ #!/bin/bash -rm -rf picker_out/ -./build/bin/picker export example/MultiClock/multi_clock.v --autobuild false -w mc.fst --tdir picker_out/MultiClock --sdir template $@ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/MultiClock" + +rm -rf "$OUT_DIR" +./build/bin/picker export example/MultiClock/multi_clock.v --autobuild false -w mc.fst --tdir "$OUT_DIR" --sdir template "$@" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then - cp example/MultiClock/example.py picker_out/MultiClock/python/ +if [[ $* == *"python"* ]]; then + cp example/MultiClock/example.py "$OUT_DIR/python/" else echo "This example only supports python now, please use --lang python" exit fi -cd picker_out/MultiClock && make EXAMPLE=ON +cd "$OUT_DIR" && make EXAMPLE=ON diff --git a/example/Pack/release-pack.sh b/example/Pack/release-pack.sh index 3be09a3d..edfc3669 100644 --- a/example/Pack/release-pack.sh +++ b/example/Pack/release-pack.sh @@ -2,7 +2,7 @@ set -e ROOT=$(pwd) -PACK_OUT="$ROOT/picker_out_pack" +PACK_OUT="${OUT_ROOT:-$ROOT/output}/Pack" prepare() { rm -rf "$PACK_OUT" diff --git a/example/RandomGenerator/example.py b/example/RandomGenerator/example.py index ddd2f200..b283278a 100644 --- a/example/RandomGenerator/example.py +++ b/example/RandomGenerator/example.py @@ -8,13 +8,15 @@ import random + class LSRF_16: def __init__(self, seed): self.state = seed & ((1 << 16) - 1) def step(self): new_bit = (self.state >> 15) ^ (self.state >> 14) & 1 - self.state = ((self.state << 1) | new_bit ) & ((1 << 16) - 1) + self.state = ((self.state << 1) | new_bit) & ((1 << 16) - 1) + if __name__ == "__main__": dut = DUTRandomGenerator() @@ -24,18 +26,22 @@ def step(self): dut.seed.value = seed ref = LSRF_16(seed) - + # reset dut.reset.value = 1 dut.Step(1) dut.reset.value = 0 dut.Step(1) - for i in range(65536): + for i in range(50): + if i % 10 == 0: + dut.FlushWaveform() + dut.SetWaveform(f"dut{i}.fsdb") print(f"Cycle {i}, DUT: {dut.random_number.value:x}, REF: {ref.state:x}") assert dut.random_number.value == ref.state, "Mismatch" dut.Step(1) ref.step() print("Test Passed, destroy UT_RandomGenerator") - dut.Finish() \ No newline at end of file + dut.Finish() + diff --git a/example/RandomGenerator/release-uvm.sh b/example/RandomGenerator/release-uvm.sh index ebf6bc67..a10d5f12 100755 --- a/example/RandomGenerator/release-uvm.sh +++ b/example/RandomGenerator/release-uvm.sh @@ -1,6 +1,9 @@ #!/bin/bash -rm -rf picker_out_rmg/ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/RandomGenerator" + +rm -rf "$OUT_DIR" ./build/bin/picker pack --from-rtl example/RandomGenerator/RandomGenerator.v -d -e @@ -11,6 +14,6 @@ cp example/RandomGenerator/example.py uvmpy/ cp example/RandomGenerator/example-uvm.sv uvmpy/ cp example/RandomGenerator/RandomGenerator.v uvmpy/ -mv uvmpy picker_out_rmg +mv uvmpy "$OUT_DIR" -cd picker_out_rmg && make +cd "$OUT_DIR" && make diff --git a/example/RandomGenerator/release-vcs.sh b/example/RandomGenerator/release-vcs.sh index 6d2b2870..2f946187 100755 --- a/example/RandomGenerator/release-vcs.sh +++ b/example/RandomGenerator/release-vcs.sh @@ -1,23 +1,39 @@ #!/bin/bash +set -e -rm -rf picker_out_RandomGenerator/ -./build/bin/picker export example/RandomGenerator/RandomGenerator.v --autobuild false --sim vcs -w RandomGenerator.fsdb --sname RandomGenerator --tdir picker_out_RandomGenerator --sdir template $@ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="$(realpath -m "${OUT_ROOT}/RandomGenerator")" + +rm -rf "$OUT_DIR" +./build/bin/picker export example/RandomGenerator/RandomGenerator.v --autobuild true --sim vcs -w RandomGenerator.fsdb --sname RandomGenerator --tdir "$OUT_DIR" --sdir template --coverage "$@" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then - cp example/RandomGenerator/example.py picker_out_RandomGenerator/python/ -elif [[ $@ == *"java"* ]]; then - cp example/RandomGenerator/example.java picker_out_RandomGenerator/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/RandomGenerator/example.scala picker_out_RandomGenerator/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/RandomGenerator/example.go picker_out_RandomGenerator/golang/ +if [[ $* == *"python"* ]]; then + cp example/RandomGenerator/example.py "$OUT_DIR" +elif [[ $* == *"java"* ]]; then + cp example/RandomGenerator/example.java "$OUT_DIR" +elif [[ $* == *"scala"* ]]; then + cp example/RandomGenerator/example.scala "$OUT_DIR" +elif [[ $* == *"golang"* ]]; then + cp example/RandomGenerator/example.go "$OUT_DIR" +elif [[ $* == *"lua"* ]]; then + cp example/RandomGenerator/example.lua "$OUT_DIR" else - cp example/RandomGenerator/example.cpp picker_out_RandomGenerator/cpp/ + cp example/RandomGenerator/example.cpp "$OUT_DIR" fi -cd picker_out_RandomGenerator && make EXAMPLE=ON +cd "$OUT_DIR" -if [[ $@ == *"python"* ]]; then - echo "'cannot allocate memory in static TLS block'error for VCS is expected, please ignore it" - LD_PRELOAD=./libUTRandomGenerator.so python3 example.py +if [[ $* == *"python"* ]]; then + python3 example.py +elif [[ $* == *"java"* ]]; then + java -cp ./UT_RandomGenerator-java.jar:./xspcomm-java.jar -ea com.ut.example +elif [[ $* == *"scala"* ]]; then + scala -cp ./UT_RandomGenerator-scala.jar:./xspcomm-scala.jar -ea com.ut.example +elif [[ $* == *"golang"* ]]; then + GO111MODULE=off GOPATH="$(pwd)/golang" go build example.go + ./example +elif [[ $* == *"lua"* ]]; then + LUA_PATH="./xspcomm/?.lua" lua example.lua +else + ./UTRandomGenerator_example fi diff --git a/example/RandomGenerator/release-verilator.sh b/example/RandomGenerator/release-verilator.sh index 3b926f6f..7b98a2b3 100755 --- a/example/RandomGenerator/release-verilator.sh +++ b/example/RandomGenerator/release-verilator.sh @@ -1,19 +1,21 @@ #!/bin/bash -rm -rf picker_out_rmg/ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/RandomGenerator" -./build/bin/picker export example/RandomGenerator/RandomGenerator.v --autobuild false -w RandomGenerator.fst $@ --tdir picker_out_rmg +rm -rf "$OUT_DIR" +./build/bin/picker export example/RandomGenerator/RandomGenerator.v --autobuild false -w RandomGenerator.fst "$@" --tdir "$OUT_DIR" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then - cp example/RandomGenerator/example.py picker_out_rmg/python/ -elif [[ $@ == *"java"* ]]; then - cp example/RandomGenerator/example.java picker_out_rmg/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/RandomGenerator/example.scala picker_out_rmg/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/RandomGenerator/example.go picker_out_rmg/golang/ +if [[ $* == *"python"* ]]; then + cp example/RandomGenerator/example.py "$OUT_DIR/python/" +elif [[ $* == *"java"* ]]; then + cp example/RandomGenerator/example.java "$OUT_DIR/java/" +elif [[ $* == *"scala"* ]]; then + cp example/RandomGenerator/example.scala "$OUT_DIR/scala/" +elif [[ $* == *"golang"* ]]; then + cp example/RandomGenerator/example.go "$OUT_DIR/golang/" else - cp example/RandomGenerator/example.cpp picker_out_rmg/cpp/ + cp example/RandomGenerator/example.cpp "$OUT_DIR/cpp/" fi -cd picker_out_rmg && make EXAMPLE=ON +cd "$OUT_DIR" && make EXAMPLE=ON diff --git a/example/XDummyCache/release-vcs.sh b/example/XDummyCache/release-vcs.sh index 0c25080f..4636ad63 100755 --- a/example/XDummyCache/release-vcs.sh +++ b/example/XDummyCache/release-vcs.sh @@ -1,10 +1,8 @@ #!/bin/bash +set -e -rm -rf ./picker_out -./build/bin/picker export example/XDummyCache/Cache.sv --autobuild true --sim vcs -w XDumyCache.fsdb --sname XDumyCache --tdir ./picker_out/temp --sdir template $@ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="$(realpath -m "${OUT_ROOT}/XDummyCache")" -if [[ $@ == *"python"* ]]; then - cd ./picker_out/temp - echo "'cannot allocate memory in static TLS block'error for VCS is expected, please ignore it" - LD_PRELOAD=./libUTXDumyCache.so python3 example.py -fi +rm -rf "$OUT_DIR" +./build/bin/picker export example/XDummyCache/Cache.sv --autobuild true --sim vcs -w XDumyCache.fsdb --sname XDumyCache --tdir "$OUT_DIR" --sdir template "$@" diff --git a/example/XDummyCache/release-verilator.sh b/example/XDummyCache/release-verilator.sh index 7f11a0ef..7d90cd0b 100755 --- a/example/XDummyCache/release-verilator.sh +++ b/example/XDummyCache/release-verilator.sh @@ -2,6 +2,9 @@ # This script is used to release the XDummyCache library. +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/XDummyCache" + # rebuild picker if with parameter --rebuild if [ "$1" == "--rebuild" ]; then rm -rf build @@ -12,4 +15,5 @@ fi # run cache codegen rm -rf temp -./build/bin/picker export example/XDummyCache/Cache.sv --autobuild true --sdir ./template --tdir ./picker_out/temp --sname XDumyCache --tname Cache -w Cache.fst --sim verilator $@ +rm -rf "$OUT_DIR" +./build/bin/picker export example/XDummyCache/Cache.sv --autobuild true --sdir ./template --tdir "$OUT_DIR" --sname XDumyCache --tname Cache -w Cache.fst --sim verilator "$@" diff --git a/example/e203_ifu_ift2icb/release-verilator.sh b/example/e203_ifu_ift2icb/release-verilator.sh index 66e92b65..3135ccad 100755 --- a/example/e203_ifu_ift2icb/release-verilator.sh +++ b/example/e203_ifu_ift2icb/release-verilator.sh @@ -1,20 +1,23 @@ #!/bin/bash -rm -rf picker_e203_ifu_ift2icb/ -./build/bin/picker export --fs example/e203_ifu_ift2icb/filelist.txt --autobuild false -w e203_ifu_ift2icb.fst --sname e203_ifu_ift2icb --tdir picker_e203_ifu_ift2icb/e203_ifu_ift2icb -V "--no-timing" --sdir template $@ +OUT_ROOT="${OUT_ROOT:-output}" +OUT_DIR="${OUT_ROOT}/e203_ifu_ift2icb" + +rm -rf "$OUT_DIR" +./build/bin/picker export --fs example/e203_ifu_ift2icb/filelist.txt --autobuild false -w e203_ifu_ift2icb.fst --sname e203_ifu_ift2icb --tdir "$OUT_DIR" -V "--no-timing" --sdir template "$@" # if python in $@, then it will generate python binding -if [[ $@ == *"python"* ]]; then - cp example/e203_ifu_ift2icb/example.py picker_e203_ifu_ift2icb/e203_ifu_ift2icb/python/ -elif [[ $@ == *"java"* ]]; then - cp example/e203_ifu_ift2icb/example.java picker_e203_ifu_ift2icb/e203_ifu_ift2icb/java/ -elif [[ $@ == *"scala"* ]]; then - cp example/e203_ifu_ift2icb/example.scala picker_e203_ifu_ift2icb/e203_ifu_ift2icb/scala/ -elif [[ $@ == *"golang"* ]]; then - cp example/e203_ifu_ift2icb/example.go picker_e203_ifu_ift2icb/e203_ifu_ift2icb/golang/ -elif [[ $@ == *"lua"* ]]; then - cp example/e203_ifu_ift2icb/example.lua picker_e203_ifu_ift2icb/e203_ifu_ift2icb/lua/ +if [[ $* == *"python"* ]]; then + cp example/e203_ifu_ift2icb/example.py "$OUT_DIR/python/" +elif [[ $* == *"java"* ]]; then + cp example/e203_ifu_ift2icb/example.java "$OUT_DIR/java/" +elif [[ $* == *"scala"* ]]; then + cp example/e203_ifu_ift2icb/example.scala "$OUT_DIR/scala/" +elif [[ $* == *"golang"* ]]; then + cp example/e203_ifu_ift2icb/example.go "$OUT_DIR/golang/" +elif [[ $* == *"lua"* ]]; then + cp example/e203_ifu_ift2icb/example.lua "$OUT_DIR/lua/" else - cp example/e203_ifu_ift2icb/example.cpp picker_e203_ifu_ift2icb/e203_ifu_ift2icb/cpp/ + cp example/e203_ifu_ift2icb/example.cpp "$OUT_DIR/cpp/" fi -cd picker_e203_ifu_ift2icb/e203_ifu_ift2icb && make EXAMPLE=ON +cd "$OUT_DIR" && make EXAMPLE=ON diff --git a/example/example.mk b/example/example.mk new file mode 100644 index 00000000..4273a58b --- /dev/null +++ b/example/example.mk @@ -0,0 +1,53 @@ +EXAMPLE_OUT_ROOT ?= output +EXAMPLE_LANG ?= python + +EXAMPLE_VERILATOR_TARGETS := \ + Adder \ + AdderMultiInstance \ + Cache \ + CacheSignalCFG \ + DualPortStackCb \ + InternalSignals \ + MultiClock \ + RandomGenerator \ + XDummyCache \ + e203_ifu_ift2icb + +EXAMPLE_TEST_ALL := Adder RandomGenerator AdderMultiInstance Cache +EXAMPLE_TEST_ALL_JAVA := Adder RandomGenerator DualPortStackCb InternalSignals CacheSignalCFG +EXAMPLE_TEST_ALL_SCALA := Adder RandomGenerator DualPortStackCb InternalSignals CacheSignalCFG + +.PHONY: $(addprefix test_,$(EXAMPLE_VERILATOR_TARGETS)) \ + $(addprefix test_vcs_,$(EXAMPLE_VERILATOR_TARGETS)) \ + $(addprefix clean_,$(EXAMPLE_VERILATOR_TARGETS)) + +define EXAMPLE_RULES +test_$(1): + @script="example/$(1)/release-verilator.sh"; \ + if [ ! -f "$$$$script" ]; then \ + echo "Unknown example '$(1)' or missing $$$$script"; \ + exit 1; \ + fi; \ + lang_args=""; \ + if [ -n "$(EXAMPLE_LANG)" ]; then \ + lang_args="--lang $(EXAMPLE_LANG)"; \ + fi; \ + OUT_ROOT="$(EXAMPLE_OUT_ROOT)" bash "$$$$script" $$$$lang_args $(ARGS) + +test_vcs_$(1): + @script="example/$(1)/release-vcs.sh"; \ + if [ ! -f "$$$$script" ]; then \ + echo "Example '$(1)' does not provide VCS flow: $$$$script"; \ + exit 1; \ + fi; \ + lang_args=""; \ + if [ -n "$(EXAMPLE_LANG)" ]; then \ + lang_args="--lang $(EXAMPLE_LANG)"; \ + fi; \ + GLIBC_TUNABLES=glibc.rtld.optional_static_tls=262144 OUT_ROOT="$(EXAMPLE_OUT_ROOT)" bash "$$$$script" $$$$lang_args $(ARGS) + +clean_$(1): + rm -rf $(EXAMPLE_OUT_ROOT)/$(1) +endef + +$(foreach example,$(EXAMPLE_VERILATOR_TARGETS),$(eval $(call EXAMPLE_RULES,$(example)))) diff --git a/include/type.hpp b/include/type.hpp index f49b46e8..b513023e 100644 --- a/include/type.hpp +++ b/include/type.hpp @@ -37,6 +37,7 @@ typedef struct export_opts { std::string frequency; std::string wave_file_name; bool coverage; + std::string verdi_mode; // legacy: -P novas.tab, modern: -debug_access+all std::string vflag; std::string cflag; bool verbose; diff --git a/scripts/init.sh b/scripts/init.sh index 8f8d61b4..421bb780 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -5,12 +5,16 @@ ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) SLANG_DIR="${SLANG_DIR:-${ROOT_DIR}/dependence/slang}" SLANG_REPO="${SLANG_REPO:-https://github.com/MikePopoloski/slang.git}" -SLANG_TAG="${SLANG_TAG:-v10.0}" +SLANG_TAG="${SLANG_TAG:-v11.0}" FMT_DIR="${FMT_DIR:-${ROOT_DIR}/dependence/fmt}" FMT_REPO="${FMT_REPO:-https://github.com/fmtlib/fmt.git}" FMT_TAG="${FMT_TAG:-12.1.0}" +YAML_CPP_DIR="${YAML_CPP_DIR:-${ROOT_DIR}/dependence/yaml-cpp}" +YAML_CPP_REPO="${YAML_CPP_REPO:-https://github.com/jbeder/yaml-cpp.git}" +YAML_CPP_TAG="${YAML_CPP_TAG:-yaml-cpp-0.9.0}" + XCOMM_DIR="${XCOMM_DIR:-${ROOT_DIR}/dependence/xcomm}" XCOMM_REPO="${XCOMM_REPO:-https://github.com/XS-MLVP/xcomm.git}" XCOMM_REPO_FALLBACK="${XCOMM_REPO_FALLBACK:-https://gitlink.org.cn/XS-MLVP/xcomm.git}" @@ -51,6 +55,29 @@ else git -c advice.detachedHead=false -C "${SLANG_DIR}" checkout --detach "${SLANG_TAG}" fi +if [[ -d "${YAML_CPP_DIR}" && ! -d "${YAML_CPP_DIR}/.git" ]]; then + echo "[yaml-cpp] Removing non-git directory ${YAML_CPP_DIR} before clean fetch." + rm -rf "${YAML_CPP_DIR}" +fi + +if [[ ! -d "${YAML_CPP_DIR}/.git" ]]; then + mkdir -p "${YAML_CPP_DIR}" + git -C "${YAML_CPP_DIR}" init -q + git -C "${YAML_CPP_DIR}" remote add origin "${YAML_CPP_REPO}" + git -C "${YAML_CPP_DIR}" fetch --depth=1 origin "refs/tags/${YAML_CPP_TAG}:refs/tags/${YAML_CPP_TAG}" + git -c advice.detachedHead=false -C "${YAML_CPP_DIR}" checkout --detach "${YAML_CPP_TAG}" + echo "[yaml-cpp] fetched release tag ${YAML_CPP_TAG} from ${YAML_CPP_REPO}" +elif [[ -n "${YAML_CPP_SKIP_ALIGN:-}" ]]; then + echo "[yaml-cpp] YAML_CPP_SKIP_ALIGN is set, skipping automatic tag alignment." +elif [[ -n "$(git -C "${YAML_CPP_DIR}" status --porcelain)" ]]; then + echo "[yaml-cpp] Local changes detected in ${YAML_CPP_DIR}, skipping automatic tag alignment." +elif ! git -C "${YAML_CPP_DIR}" fetch --depth=1 origin "refs/tags/${YAML_CPP_TAG}:refs/tags/${YAML_CPP_TAG}"; then + echo "[yaml-cpp] Fetch failed, skipping automatic tag alignment." +else + echo "[yaml-cpp] Checking out release tag '${YAML_CPP_TAG}'" + git -c advice.detachedHead=false -C "${YAML_CPP_DIR}" checkout --detach "${YAML_CPP_TAG}" +fi + if [[ ! -d "${XCOMM_DIR}/.git" ]]; then mkdir -p "$(dirname "${XCOMM_DIR}")" if git clone --depth=1 "${XCOMM_REPO}" "${XCOMM_DIR}"; then diff --git a/src/codegen/lib.cpp b/src/codegen/lib.cpp index e6aeffa5..36645a80 100644 --- a/src/codegen/lib.cpp +++ b/src/codegen/lib.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "codegen/lib.hpp" #include "picker.hpp" #include "codegen/sv.hpp" @@ -200,6 +201,47 @@ namespace picker { namespace codegen { std::string verilaotr_coverage, vcs_coverage; } + int vcs_coverage_metric_bit(const std::string &metric) + { + if (metric == "line") return 1 << 0; + if (metric == "cond") return 1 << 1; + if (metric == "fsm") return 1 << 2; + if (metric == "tgl" || metric == "toggle") return 1 << 3; + if (metric == "branch") return 1 << 4; + if (metric == "assert" || metric == "assertion") return 1 << 5; + if (metric == "all") return 0b111111; + return 0; + } + + int parse_vcs_coverage_metrics(const std::string &vflag, bool &has_cm) + { + std::string normalized = vflag; + for (auto &ch : normalized) { + if (ch == '"' || ch == '\'' || ch == ',' || ch == '+') ch = ' '; + } + + std::vector tokens; + std::stringstream ss(normalized); + for (std::string token; ss >> token;) tokens.push_back(token); + + int metrics = 0; + for (size_t i = 0; i < tokens.size(); ++i) { + const auto &token = tokens[i]; + if (token == "-cm") { + has_cm = true; + if (i + 1 < tokens.size()) metrics |= vcs_coverage_metric_bit(tokens[++i]); + continue; + } + if (token.starts_with("-cm=")) { + has_cm = true; + metrics |= vcs_coverage_metric_bit(token.substr(token.find('=') + 1)); + continue; + } + if (has_cm) metrics |= vcs_coverage_metric_bit(token); + } + return metrics; + } + void gen_coverage_metrics(std::string &simulator, picker::export_opts &opts, std::string &vflag, nlohmann::json &data) { @@ -218,9 +260,14 @@ namespace picker { namespace codegen { if (coverage && simulator == "verilator") { // Verilator doesn't support fsm coverage metrics = 0b111011; - } else if (simulator == "vcs") { - PK_MESSAGE("VCS not supported now"); - // TODO: Parse the vflag for vcs + } else if (coverage && simulator == "vcs") { + bool has_cm = false; + metrics = parse_vcs_coverage_metrics(vflag, has_cm); + if (!has_cm) { + if (!vflag.empty()) vflag += " "; + vflag += "-cm line+cond+fsm+tgl+branch+assert"; + metrics = 0b111111; + } } data["__COVERAGE__"] = coverage ? "ON" : "OFF"; @@ -276,15 +323,15 @@ namespace picker { namespace codegen { std::vector incdirs; gen_filelist(files, ifilelists, ofilelist, incdirs); append_incdirs_to_vflag(simulator, incdirs, vflag); + + // Get coverage metrics before rendering Makefile/CMake, because VCS coverage may add -cm flags. + gen_coverage_metrics(simulator, opts, vflag, data); gen_cmake(src_dir, dst_dir, wave_file_name, simulator, vflag, cflag, env, data); // Set clock period printf("Frequency: %s\n", opts.frequency.c_str()); get_clock_period(vcs_clock_period_h, vcs_clock_period_l, opts.frequency); - // Get coverage metrics - gen_coverage_metrics(simulator, opts, vflag, data); - // Render expins info auto expins = nlohmann::json::array(); gen_expins(expins, opts, ret); @@ -296,6 +343,7 @@ namespace picker { namespace codegen { data["__EXAMPLE__"] = opts.example ? "ON" : "OFF"; data["__CHECKPOINTS__"] = opts.checkpoints ? "ON" : "OFF"; data["__VPI__"] = opts.vpi ? "ON" : "OFF"; + data["__VERDI_MODE__"] = opts.verdi_mode; data["__RW_TYPE__"] = opts.rw_type == picker::SignalAccessType::MEM_DIRECT ? "MEM_DIRECT" : "DPI"; data["__TARGET_LANGUAGE__"] = opts.language; data["__FILELIST__"] = ofilelist; diff --git a/src/codegen/mem_direct.cpp b/src/codegen/mem_direct.cpp index 4619ff3a..27ab707b 100644 --- a/src/codegen/mem_direct.cpp +++ b/src/codegen/mem_direct.cpp @@ -80,6 +80,7 @@ namespace picker { namespace codegen { if (varibles.size() == 0) { return; } inja::Environment env; nlohmann::json data; + std::string erro_message; std::vector offset_array; std::string offset_funcs, offset_funcs_define; // begin with "render_varible_info_0(base);\n" std::string src_dir = opts.source_dir; // "mem_direct" folder has been added in the upper level @@ -106,9 +107,12 @@ namespace picker { namespace codegen { for (const auto &type : type_set) { cpp_type_set.push_back(type); } + auto cpplib_location = picker::get_xcomm_lib("lib", erro_message); + if (cpplib_location.empty()) { PK_FATAL("%s", erro_message.c_str()); } + data["__XSPCOMM_LIB__"] = cpplib_location; data["__yaml_varible_type_set__"] = cpp_type_set; data["__SIMULATOR__"] = opts.sim; recursive_render(dst_dir_tmp, dst_dir, data, env); } -}}; // namespace picker::codegen \ No newline at end of file +}}; // namespace picker::codegen diff --git a/src/codegen/python.cpp b/src/codegen/python.cpp index 54c8f06c..e8b00947 100644 --- a/src/codegen/python.cpp +++ b/src/codegen/python.cpp @@ -146,6 +146,7 @@ namespace picker { namespace codegen { data["__USE_SIMULATOR__"] = "USE_" + simulator; data["__COPY_XSPCOMM_LIB__"] = opts.cp_lib; data["__SIMULATOR__"] = opts.sim; + data["__VERDI_MODE__"] = opts.verdi_mode; // Render inja::Environment env; diff --git a/src/codegen/sv.cpp b/src/codegen/sv.cpp index fca3fafc..71bcfde1 100644 --- a/src/codegen/sv.cpp +++ b/src/codegen/sv.cpp @@ -32,6 +32,48 @@ namespace picker { namespace codegen { " $finish;\n" " endfunction\n"; + static const std::string vcs_fsdb_control_sv_template = + " export \"DPI-C\" function vcs_fsdb_set_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " function void vcs_fsdb_set_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " input string filename;\n" + " $fsdbDumpFinish;\n" + " $fsdbDumpfile(filename);\n" + " $fsdbDumpvars(0, {{__TOP_MODULE_NAME__}}_top{{__DUMP_VAR_OPTIONS__}});\n" + " endfunction\n\n" + " export \"DPI-C\" function vcs_fsdb_finish_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " function void vcs_fsdb_finish_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " $fsdbDumpFinish;\n" + " endfunction\n\n" + " export \"DPI-C\" function vcs_fsdb_flush_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " function void vcs_fsdb_flush_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " $fsdbDumpflush;\n" + " endfunction\n\n" + " export \"DPI-C\" function vcs_fsdb_waveform_enable_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " function void vcs_fsdb_waveform_enable_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " input byte unsigned enable;\n" + " if (enable) $fsdbDumpon;\n" + " else $fsdbDumpoff;\n" + " endfunction\n"; + + static const std::string vcs_coverage_sv_template = + " export \"DPI-C\" task vcs_coverage_start_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " task vcs_coverage_start_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " $cg_coverage_control(1);\n" + " endtask\n\n" + " export \"DPI-C\" task vcs_coverage_stop_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " task vcs_coverage_stop_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " $cg_coverage_control(0);\n" + " endtask\n\n" + " export \"DPI-C\" task vcs_coverage_reset_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " task vcs_coverage_reset_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " $coverage_reset();\n" + " endtask\n\n" + " export \"DPI-C\" task vcs_coverage_dump_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " task vcs_coverage_dump_{{__LIB_DPI_FUNC_NAME_HASH__}};\n" + " input string name;\n" + " $coverage_dump(name);\n" + " endtask\n"; + /// @brief Export external pin for verilog render, contains pin connect, /// @param pin /// @param pin_connect @@ -130,14 +172,15 @@ namespace picker { namespace codegen { void render_sv_waveform(const std::string &simulator, const std::string &wave_file_name, nlohmann::json &data) { inja::Environment env; - std::string sv_dump_wave, trace, dum_var_options; + std::string sv_dump_wave, sv_waveform_control, trace, dum_var_options; dum_var_options = picker::get_env("DUMPVARS_OPTION", ""); if (!dum_var_options.empty()) { PK_DEBUG("Find DUMPVARS_OPTION=%s", dum_var_options.c_str()); dum_var_options = ", \"" + dum_var_options + "\""; } - data["__WAVE_FILE_NAME__"] = wave_file_name; - data["__DUMP_VAR_OPTIONS__"] = dum_var_options; + data["__WAVE_FILE_NAME__"] = wave_file_name; + data["__DUMP_VAR_OPTIONS__"] = dum_var_options; + data["__LIB_DPI_FUNC_NAME_HASH__"] = std::string(lib_random_hash); if (simulator == "verilator") { if (wave_file_name.length() > 0) { if (wave_file_name.ends_with(".vcd") || wave_file_name.ends_with(".fst")) @@ -151,13 +194,15 @@ namespace picker { namespace codegen { PK_FATAL("Verilator trace file must be .vcd or .fst format.\n"); } } else if (simulator == "vcs") { + sv_waveform_control = env.render(vcs_fsdb_control_sv_template, data) + + env.render(vcs_coverage_sv_template, data); if (wave_file_name.length() > 0) { if (wave_file_name.ends_with(".fsdb") == false) PK_FATAL("VCS trace file must be .fsdb format.\n"); sv_dump_wave = env.render(" initial begin\n" " $fsdbDumpfile(\"{{__WAVE_FILE_NAME__}}\");\n" " $fsdbDumpvars(0, {{__TOP_MODULE_NAME__}}_top{{__DUMP_VAR_OPTIONS__}});\n" - " end", + " end\n\n", data); } } else if (simulator == "uvs") { @@ -177,7 +222,7 @@ namespace picker { namespace codegen { data["__TRACE__"] = sv_dump_wave.length() > 0 ? wave_file_name.substr(wave_file_name.find_last_of(".") + 1, wave_file_name.length()) : "OFF"; - data["__SV_DUMP_WAVE__"] = sv_dump_wave; + data["__SV_DUMP_WAVE__"] = sv_dump_wave + sv_waveform_control; } void render_signal_tree(const std::vector &external_pin, diff --git a/src/parser/sv.cpp b/src/parser/sv.cpp index f369d183..f366a8e9 100644 --- a/src/parser/sv.cpp +++ b/src/parser/sv.cpp @@ -10,6 +10,7 @@ #include "slang/diagnostics/DiagnosticEngine.h" #include "slang/diagnostics/Diagnostics.h" #include "slang/driver/Driver.h" +#include "slang/syntax/SyntaxTree.h" #include "slang/syntax/SyntaxVisitor.h" #include "slang/text/SourceManager.h" diff --git a/src/picker.cpp b/src/picker.cpp index 4ec48499..059d621b 100644 --- a/src/picker.cpp +++ b/src/picker.cpp @@ -127,6 +127,15 @@ int set_options_export_rtl(CLI::App &top_app) // Enable coverage, Optional, default is OFF app->add_flag("-c,--coverage", export_opts.coverage, "Enable coverage, default is not selected as OFF"); + // Select Verdi integration mode for VCS simulator, Optional, default is legacy + app->add_option("--verdi-mode", export_opts.verdi_mode, + "Select Verdi integration mode when compiling with VCS.\n" + "legacy: use -P novas.tab (default, for older Verdi).\n" + "modern: use -debug_access+all (required for Verdi >= 2024.09).\n" + "Only applies when --sim vcs.") + ->default_val("legacy") + ->check(CLI::IsMember(std::set{"legacy", "modern"}, CLI::ignore_case)); + // Enable copy xspcomm lib to DUT location app->add_option("--cp_lib, --copy_xspcomm_lib", export_opts.cp_lib, "Copy xspcomm lib to generated DUT dir, default is true") diff --git a/template/cpp/Makefile b/template/cpp/Makefile index 8d055cda..0513fa83 100644 --- a/template/cpp/Makefile +++ b/template/cpp/Makefile @@ -34,6 +34,6 @@ clean: @rm -rf *.fst *.vcd *.fsdb *.log *.key *.dat build purge: clean - @mv ./* ../ || true + @find . -mindepth 1 -maxdepth 1 -not -name '*.vdb' -exec mv -t ../ {} + 2>/dev/null || true @echo "purge complete" @rm -rf $(CURRENT_DIR) diff --git a/template/cpp/dut.cpp b/template/cpp/dut.cpp index 6a4ac5bf..09e16ba3 100644 --- a/template/cpp/dut.cpp +++ b/template/cpp/dut.cpp @@ -54,10 +54,7 @@ void UT{{__TOP_MODULE_NAME__}}::init() // add {{__TOP_MODULE_NAME__}} ports {{__XPORT_ADD__}} - xfunction stepfunc = [&](bool d) -> int { - return this->dut->simStep(d); - }; - this->xclock.ReInit(stepfunc, {}, {}); + this->xclock.ReInit(this->dut->pxcStep, this->dut->pSelf, {}, {}); this->xclock.Add(this->xport); this->xcfg = new XSignalCFG(this->dut->GetXSignalCFGPath(), this->dut->GetXSignalCFGBasePtr()); diff --git a/template/cpp/dut.hpp b/template/cpp/dut.hpp index a9194a2e..29ac5212 100644 --- a/template/cpp/dut.hpp +++ b/template/cpp/dut.hpp @@ -99,6 +99,10 @@ class UT{{__TOP_MODULE_NAME__}} { this->dut->SetCoverage((const char *)filename.c_str()); } + void ResetCoverage() + { + this->dut->ResetCoverage(); + } int GetCovMetrics() { return this->dut->GetCovMetrics(); diff --git a/template/golang/Makefile b/template/golang/Makefile index a18f2098..094e9f69 100644 --- a/template/golang/Makefile +++ b/template/golang/Makefile @@ -39,7 +39,7 @@ clean: @rm -rf *.fst *.vcd *.fsdb *.log *.key *.a build purge: clean - @find . -mindepth 1 -maxdepth 1 -not -name golang -exec rm -rf {} + - @mv ./* ../ || true + @find . -mindepth 1 -maxdepth 1 \( -name golang -o -name "*.vdb" \) -prune -o -exec rm -rf {} + + @find . -mindepth 1 -maxdepth 1 -name golang -exec mv -t ../ {} + 2>/dev/null || true @echo "purge complete" @rm -rf $(CURRENT_DIR) diff --git a/template/golang/dut.go b/template/golang/dut.go index 8f04b302..32ca2320 100644 --- a/template/golang/dut.go +++ b/template/golang/dut.go @@ -229,6 +229,10 @@ func (self *UT_{{__TOP_MODULE_NAME__}}) SetCoverage(filename string){ self.Dut.SetCoverage(filename) } +func (self *UT_{{__TOP_MODULE_NAME__}}) ResetCoverage(){ + self.Dut.ResetCoverage() +} + func (self *UT_{{__TOP_MODULE_NAME__}}) GetCovMetrics() int { return DutUnifiedBaseGetCovMetrics() } diff --git a/template/java/Makefile b/template/java/Makefile index fb8db928..1f8c3640 100644 --- a/template/java/Makefile +++ b/template/java/Makefile @@ -29,7 +29,7 @@ clean: @rm -rf *.fst *.vcd *.fsdb *.log *.key *.a build purge: clean - @find . -mindepth 1 -maxdepth 1 -not -name "*.jar" -exec rm -rf {} + - @mv ./* ../ || true + @find . -mindepth 1 -maxdepth 1 \( -name "*.jar" -o -name "*.vdb" \) -prune -o -exec rm -rf {} + + @find . -mindepth 1 -maxdepth 1 -name "*.jar" -exec mv -t ../ {} + 2>/dev/null || true @echo "purge complete" @rm -rf $(CURRENT_DIR) diff --git a/template/java/dut.java b/template/java/dut.java index 9c96d9b8..02466453 100644 --- a/template/java/dut.java +++ b/template/java/dut.java @@ -140,6 +140,9 @@ public void FlushWaveform() { public void SetCoverage(String coverage_name){ this.dut.SetCoverage(coverage_name); } + public void ResetCoverage(){ + this.dut.ResetCoverage(); + } public int GetCovMetrics() { return this.dut.GetCovMetrics(); } diff --git a/template/lib/Makefile b/template/lib/Makefile index de01f908..cc192f6e 100644 --- a/template/lib/Makefile +++ b/template/lib/Makefile @@ -55,6 +55,9 @@ endif release: compile @cp -r build/${TARGET} . + # Bring .vdb alongside the .so so the runtime -cm_dir (anchored to the .so + # directory by dut_base.cpp) finds the database and appends new testdata. + @cp -r build/${PROJECT}.vdb . 2>/dev/null || true @cp build/_SRC/*.h ${TARGET}/ 2>/dev/null|| true @cp build/_SRC/*.hpp ${TARGET}/ 2>/dev/null|| true @cp *.hpp ${TARGET}/ diff --git a/template/lib/cmake/vcs.cmake b/template/lib/cmake/vcs.cmake index 66f087e8..75c2f3e4 100644 --- a/template/lib/cmake/vcs.cmake +++ b/template/lib/cmake/vcs.cmake @@ -42,6 +42,31 @@ if(SIMULATOR STREQUAL "vcs") set(SIMULATOR_FLAGS "${SIMULATOR_FLAGS};+vpi;-debug_access+all") endif() + if(${COVERAGE} STREQUAL "ON") + add_definitions(-DVCS_COVERAGE) + set(VCS_HAS_COVERAGE_FLAGS OFF) + set(VCS_HAS_COVERAGE_DIR OFF) + set(VCS_HAS_COVERAGE_NAME OFF) + foreach(flag IN LISTS SIMULATOR_FLAGS) + if(flag MATCHES "^-cm$" OR flag MATCHES "^-cm=") + set(VCS_HAS_COVERAGE_FLAGS ON) + elseif(flag STREQUAL "-cm_dir") + set(VCS_HAS_COVERAGE_DIR ON) + elseif(flag STREQUAL "-cm_name") + set(VCS_HAS_COVERAGE_NAME ON) + endif() + endforeach() + if(NOT VCS_HAS_COVERAGE_FLAGS) + set(SIMULATOR_FLAGS "${SIMULATOR_FLAGS};-cm;line+cond+fsm+tgl+branch+assert") + endif() + if(NOT VCS_HAS_COVERAGE_DIR) + set(SIMULATOR_FLAGS "${SIMULATOR_FLAGS};-cm_dir;${ModuleName}.vdb") + endif() + if(NOT VCS_HAS_COVERAGE_NAME) + set(SIMULATOR_FLAGS "${SIMULATOR_FLAGS};-cm_name;${ModuleName}") + endif() + endif() + # Using Compiled vcs dynamic library if(NOT "${VCS_DYN}" STREQUAL "") message(STATUS "Using VCS dyn target: ${VCS_DYN}") @@ -52,18 +77,33 @@ if(SIMULATOR STREQUAL "vcs") endif() else() # Using VCS compile + + # ---------- Verdi PLI selection ---------- + # The exported --verdi-mode value is rendered into this template. + # modern: use -debug_access+all for Verdi >= 2024.09. + # legacy: use the older novas.tab interface. +{% if __VERDI_MODE__ == "modern" %} + message(STATUS "Verdi PLI: modern (-debug_access+all, from --verdi-mode modern)") + set(_VCS_VERDI_FLAGS "-debug_access+all") +{% else %} + message(STATUS "Verdi PLI: legacy (-P novas.tab, default; use --verdi-mode modern for Verdi >= 2024.09)") + set(_VCS_VERDI_FLAGS "-P;${VERDI_HOME}/share/PLI/VCS/LINUX64/novas.tab;-P;pli.tab") +{% endif %} + # pli.a is required in both modes to pull in the VCS runtime symbols. + set(_VCS_VERDI_LIBS "${VERDI_HOME}/share/PLI/VCS/LINUX64/pli.a") + # --------------------------------------------------- + execute_process( WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND vcs -e VcsMain -slave ${VCS_TRACE} -sverilog -lca -l compile.log - -top ${ModuleName}_top -full64 -timescale=1ns/1ps - ${ModuleName}_top.sv ${ModuleName}.v -f filelist.f + -top ${ModuleName}_top -full64 -timescale=1ns/1ps + ${ModuleName}_top.sv ${ModuleName}.v -f filelist.f -o libDPI${ModuleName}.so +modelsave -LDFLAGS "-shared" - ${SIMULATOR_FLAGS} + ${SIMULATOR_FLAGS} ${SIMULATOR_CFLAGS} - -P ${VERDI_HOME}/share/PLI/VCS/LINUX64/novas.tab - -P pli.tab - ${VERDI_HOME}/share/PLI/VCS/LINUX64/pli.a) + ${_VCS_VERDI_FLAGS} + ${_VCS_VERDI_LIBS}) endif() # Add VCS dependency library diff --git a/template/lib/dut_base.cpp b/template/lib/dut_base.cpp index 735c965d..e0445c55 100644 --- a/template/lib/dut_base.cpp +++ b/template/lib/dut_base.cpp @@ -18,6 +18,65 @@ int enable_xinfo = 0; // 0: disable, 1: enable, 2: debug +#if defined(USE_VCS) + +// argv[0] is the .so path; VCS options start at index 1. +static bool has_argv_option(int argc, char **argv, const char *opt) +{ + for (int i = 1; i < argc; ++i) + if (argv[i] && std::strcmp(argv[i], opt) == 0) return true; + return false; +} + +static void append_argv_option(int &argc, char **argv, const std::string &val, int cap) +{ + if (argc >= cap) { XWarning("VCS argv overflow, option '%s' skipped", val.c_str()); return; } + char *p = (char *)malloc(val.size() + 1); + std::memcpy(p, val.c_str(), val.size() + 1); + argv[argc++] = p; +} + +static constexpr int vcs_coverage_metrics_mask = {{__COVERAGE_METRICS__}}; + +static std::string vcs_coverage_metric_string() +{ + static constexpr std::pair kMetrics[] = { + {1 << 0, "line"}, {1 << 1, "cond"}, {1 << 2, "fsm"}, + {1 << 3, "tgl"}, {1 << 4, "branch"}, {1 << 5, "assert"}, + }; + std::string s; + for (auto [bit, name] : kMetrics) + if (vcs_coverage_metrics_mask & bit) { if (!s.empty()) s += '+'; s += name; } + return s; +} + +// Sanitize user-provided name into a valid VCS testdata name. +// "foo.fsdb" -> "foo", "./dir/" -> "{{__TOP_MODULE_NAME__}}" +static std::string vcs_coverage_test_name(const std::string &val) +{ + std::string name = std::filesystem::path(val).stem().string(); + if (name.empty() || name == ".") name = "{{__TOP_MODULE_NAME__}}"; + for (char &c : name) + if (!std::isalnum((unsigned char)c) && c != '_' && c != '-') c = '_'; + return name; +} + +// Return the absolute directory containing this .so; falls back to CWD. +static std::string vcs_so_dir() +{ + Dl_info info; + if (dladdr(reinterpret_cast(&vcs_so_dir), &info) && info.dli_fname) { + std::error_code ec; + auto abs = std::filesystem::absolute(info.dli_fname, ec); + if (!ec) return abs.parent_path().string(); + } + std::error_code ec; + auto cwd = std::filesystem::current_path(ec); + return ec ? "." : cwd.string(); +} + +#endif + DutBase::DutBase() { cycle = 0; @@ -56,6 +115,9 @@ void DutVcsBase::init(int argc, char **argv) this->vcs_clock_period[0] = {{__VCS_CLOCK_PERIOD_HIGH__}}; this->vcs_clock_period[1] = {{__VCS_CLOCK_PERIOD_LOW__}}; this->vcs_clock_period[2] = {{__VCS_CLOCK_PERIOD_LOW__}} + {{__VCS_CLOCK_PERIOD_HIGH__}}; +{% if __COVERAGE__ == "ON" %} + vcs_coverage_start_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +{% endif %} } DutVcsBase::~DutVcsBase() {}; @@ -82,36 +144,63 @@ int DutVcsBase::Step(uint64_t ncycle, bool dump) int DutVcsBase::Finish() { - // Finish VCS context +{% if __TRACE__ == "fsdb" %} + vcs_fsdb_finish_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +{% endif %} +{% if __COVERAGE__ == "ON" %} + if (this->coverage_file_path.size() > 0) + vcs_coverage_dump_{{__LIB_DPI_FUNC_NAME_HASH__}}(vcs_coverage_test_name(this->coverage_file_path).c_str()); + else + vcs_coverage_dump_{{__LIB_DPI_FUNC_NAME_HASH__}}("{{__TOP_MODULE_NAME__}}"); + vcs_coverage_stop_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +{% endif %} finish_{{__LIB_DPI_FUNC_NAME_HASH__}}(); return 0; }; void DutVcsBase::SetWaveform(const char *filename) { - XInfo("VCS waveform is not supported"); + if (filename == nullptr || !std::string(filename).ends_with(".fsdb")) { + XFatal("VCS trace file must be .fsdb format"); + } + vcs_fsdb_set_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}}(filename); }; void DutVcsBase::SetCoverage(const char *filename) { - XInfo("VCS coverage is not supported"); +{% if __COVERAGE__ == "ON" %} + if (filename == nullptr || std::strlen(filename) == 0) { + XFatal("VCS coverage file path is empty"); + } + this->coverage_file_path = filename; +{% else %} + XFatal("VCS coverage is not enabled"); +{% endif %} +}; +void DutVcsBase::ResetCoverage() +{ +{% if __COVERAGE__ == "ON" %} + vcs_coverage_reset_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +{% else %} + XFatal("VCS coverage is not enabled"); +{% endif %} }; void DutVcsBase::FlushWaveform() { - XInfo("VCS waveform is not supported"); + vcs_fsdb_flush_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}}(); }; bool DutVcsBase::ResumeWaveformDump() { - XInfo("VCS waveform is not supported"); + vcs_fsdb_waveform_enable_{{__LIB_DPI_FUNC_NAME_HASH__}}(1); return true; }; bool DutVcsBase::PauseWaveformDump() { - XInfo("VCS waveform is not supported"); + vcs_fsdb_waveform_enable_{{__LIB_DPI_FUNC_NAME_HASH__}}(0); return true; }; void DutVcsBase::WaveformEnable(bool enable) { - XInfo("VCS waveform is not supported"); + vcs_fsdb_waveform_enable_{{__LIB_DPI_FUNC_NAME_HASH__}}(enable ? 1 : 0); }; int DutVcsBase::CheckPoint(const char *filename) { @@ -198,6 +287,10 @@ void DutUvsBase::SetCoverage(const char *filename) { XInfo("UVS coverage is not supported"); }; +void DutUvsBase::ResetCoverage() +{ + XInfo("UVS coverage is not supported"); +}; void DutUvsBase::FlushWaveform() { XInfo("UVS waveform is not supported"); @@ -304,6 +397,9 @@ void DutGSimBase::WaveformEnable(bool enable) void DutGSimBase::SetCoverage(const char *filename) { } +void DutGSimBase::ResetCoverage() +{ +} int DutGSimBase::CheckPoint(const char *filename) { @@ -546,6 +642,11 @@ void DutVerilatorBase::SetCoverage(const char *filename) exit(-1); #endif }; +void DutVerilatorBase::ResetCoverage() +{ + std::cerr << "Verilator coverage reset is not supported"; + exit(-1); +}; #if defined(VL_SAVEABLE) #include "verilated_save.h" @@ -757,6 +858,26 @@ void DutUnifiedBase::init(int argc, const char **argv) this->argc++; } +#if defined(USE_VCS) + if (vcs_coverage_metrics_mask != 0) { + // argv was allocated with 128 extra slots; cap prevents silent overflow. + const int argv_cap = this->argc + 128; + const auto try_append = [&](const char *key, const std::string &val) { + if (!has_argv_option(this->argc, this->argv, key)) { + append_argv_option(this->argc, this->argv, key, argv_cap); + append_argv_option(this->argc, this->argv, val, argv_cap); + } + }; + const std::string metrics = vcs_coverage_metric_string(); + if (!metrics.empty()) try_append("-cm", metrics); + try_append("-cm_name", "{{__TOP_MODULE_NAME__}}"); + // Anchor .vdb to the .so directory so coverage is written to the + // release dir regardless of where pytest/the test is invoked from. + try_append("-cm_dir", + (std::filesystem::path(vcs_so_dir()) / "{{__TOP_MODULE_NAME__}}.vdb").string()); + } +#endif + // the main namespace instance doesn't need to load the shared library if (!main_ns_flag) { XInfo("Using main namespace"); @@ -1049,6 +1170,10 @@ void DutUnifiedBase::SetCoverage(const char *filename) { return this->dut->SetCoverage(filename); } +void DutUnifiedBase::ResetCoverage() +{ + return this->dut->ResetCoverage(); +} int DutUnifiedBase::GetCovMetrics() { return DutUnifiedBase::coverage_metrics; diff --git a/template/lib/dut_base.hpp b/template/lib/dut_base.hpp index 1c126aac..f89e4bac 100644 --- a/template/lib/dut_base.hpp +++ b/template/lib/dut_base.hpp @@ -42,6 +42,7 @@ class DutBase virtual void WaveformEnable(bool enable) = 0; // Set coverage file path virtual void SetCoverage(const char *filename) = 0; + virtual void ResetCoverage() = 0; // Save Model Status with Simulator Capabilities virtual int CheckPoint(const char *filename) = 0; // Load Model Status with Simulator Capabilities @@ -80,6 +81,7 @@ class DutGSimBase : public DutBase bool PauseWaveformDump(); void WaveformEnable(bool enable); void SetCoverage(const char *filename); + void ResetCoverage(); int CheckPoint(const char *filename); int Restore(const char *filename); uint64_t NativeSignalAddr(const char *name); @@ -117,6 +119,7 @@ class DutVerilatorBase : public DutBase bool PauseWaveformDump(); void WaveformEnable(bool enable); void SetCoverage(const char *filename); + void ResetCoverage(); int CheckPoint(const char *filename); int Restore(const char *filename); uint64_t NativeSignalAddr(const char *name); @@ -134,6 +137,14 @@ int VcsMain(int argc, char **argv); void VcsInit(); void VcsSimUntil(uint64_t *); void finish_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +void vcs_fsdb_set_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}}(const char *filename); +void vcs_fsdb_finish_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +void vcs_fsdb_flush_waveform_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +void vcs_fsdb_waveform_enable_{{__LIB_DPI_FUNC_NAME_HASH__}}(unsigned char enable); +void vcs_coverage_start_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +void vcs_coverage_stop_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +void vcs_coverage_reset_{{__LIB_DPI_FUNC_NAME_HASH__}}(); +void vcs_coverage_dump_{{__LIB_DPI_FUNC_NAME_HASH__}}(const char *filename); } #include "vc_hdrs.h" @@ -142,6 +153,7 @@ class DutVcsBase : public DutBase protected: uint64_t cycle_hl; uint64_t vcs_clock_period[3]; + std::string coverage_file_path; public: std::string sv_scope = "{{__TOP_MODULE_NAME__}}_top"; @@ -157,6 +169,7 @@ class DutVcsBase : public DutBase bool PauseWaveformDump(); void WaveformEnable(bool enable); void SetCoverage(const char *filename); + void ResetCoverage(); int CheckPoint(const char *filename); int Restore(const char *filename); uint64_t NativeSignalAddr(const char *name); @@ -193,6 +206,7 @@ class DutUvsBase : public DutBase bool PauseWaveformDump(); void WaveformEnable(bool enable); void SetCoverage(const char *filename); + void ResetCoverage(); int CheckPoint(const char *filename); int Restore(const char *filename); uint64_t NativeSignalAddr(const char *name); @@ -305,6 +319,7 @@ class DutUnifiedBase // Set coverage file path void SetCoverage(const char *filename); void SetCoverage(const std::string filename); + void ResetCoverage(); // Get the bitmask for collected coverage metrics. 0 means coverage is disabled static int GetCovMetrics(); diff --git a/template/lua/Makefile b/template/lua/Makefile index 9aef0f02..73345a66 100644 --- a/template/lua/Makefile +++ b/template/lua/Makefile @@ -32,6 +32,6 @@ clean: purge: clean @rm -rf *.txt Makefile *.hpp *.cmake *.i __pycache__ - @mv ./* ../ || true + @find . -mindepth 1 -maxdepth 1 -not -name '*.vdb' -exec mv -t ../ {} + 2>/dev/null || true @echo "purge complete" @rm -rf $(CURRENT_DIR) diff --git a/template/lua/dut.lua b/template/lua/dut.lua index 23eb7836..76d38909 100644 --- a/template/lua/dut.lua +++ b/template/lua/dut.lua @@ -143,6 +143,10 @@ function DUT{{__TOP_MODULE_NAME__}}:SetCoverage(filename) self.dut:SetCoverage(filename) end +function DUT{{__TOP_MODULE_NAME__}}:ResetCoverage() + self.dut:ResetCoverage() +end + function DUT{{__TOP_MODULE_NAME__}}:GetCovMetrics() return self.dut:GetCovMetrics() end diff --git a/template/mem_direct/Makefile b/template/mem_direct/Makefile index 33d78fbc..9963211e 100644 --- a/template/mem_direct/Makefile +++ b/template/mem_direct/Makefile @@ -20,8 +20,8 @@ V_ROOT := $(shell verilator -V | grep ROOT | grep verilator | tail -n 1 | awk '{ CXXFLAGS += -I ${V_ROOT}/include -I ${V_ROOT}/include/vltstd/ \ -I ../build/DPI${TOP_NAME} \ -L../build ${CFLAGS} -LDFLAGS += $(WHOLE_ARCHIVE_LDFLAGS) -Wl,-undefined,dynamic_lookup -LDLIBS += -lpthread -lz +LDFLAGS += $(WHOLE_ARCHIVE_LDFLAGS) -Wl,-undefined,dynamic_lookup -Wl,-rpath,{{__XSPCOMM_LIB__}} +LDLIBS += -lpthread -lz -L{{__XSPCOMM_LIB__}} -lxspcomm {% endif %} {% if __SIMULATOR__ == "gsim" %} diff --git a/template/python/Makefile b/template/python/Makefile index 66c5d39d..7e8d81b7 100644 --- a/template/python/Makefile +++ b/template/python/Makefile @@ -37,6 +37,6 @@ clean: purge: clean @rm -rf *.txt Makefile *.hpp *.cmake *.i __pycache__ @rm ../__init__.py || true - @mv ./* ../ || true + @find . -mindepth 1 -maxdepth 1 -not -name '*.vdb' -exec mv -t ../ {} + 2>/dev/null || true @echo "purge complete" @rm -rf $(CURRENT_DIR) diff --git a/template/python/dut.py b/template/python/dut.py index dd9357d4..fec4e100 100644 --- a/template/python/dut.py +++ b/template/python/dut.py @@ -10,6 +10,24 @@ else: from libUT_{{__TOP_MODULE_NAME__}} import * +{% if __SIMULATOR__ == "vcs" and __VERDI_MODE__ == "modern" %} +# After import, promote libvcsnew.so to RTLD_GLOBAL for VCS 2024.09+. +# At this point the library is already loaded through the dependency chain. +# RTLD_NOLOAD|RTLD_GLOBAL only changes symbol visibility and does not reload it. +import ctypes as _ctypes, os as _os +_vcs_home = _os.environ.get("VCS_HOME", "") +if _vcs_home: + _libvcsnew = _os.path.join(_vcs_home, "linux64/lib/libvcsnew.so") + if _os.path.exists(_libvcsnew): + _RTLD_NOLOAD = 0x4 # Do not reload; only update the symbol scope. + try: + _ctypes.CDLL(_libvcsnew, mode=_RTLD_NOLOAD | _ctypes.RTLD_GLOBAL) + except OSError: + pass +del _ctypes, _os +{% endif %} + + class DUT{{__TOP_MODULE_NAME__}}(object): @@ -97,6 +115,9 @@ def FlushWaveform(self): def SetCoverage(self, filename: str): self.dut.SetCoverage(filename) + def ResetCoverage(self): + self.dut.ResetCoverage() + def GetCovMetrics(self) -> int: """ Get the bitmask for collected coverage metrics. 0 means coverage is disabled diff --git a/template/scala/Makefile b/template/scala/Makefile index 0ed6c70b..c2129643 100644 --- a/template/scala/Makefile +++ b/template/scala/Makefile @@ -30,7 +30,7 @@ clean: @rm -rf *.fst *.vcd *.fsdb *.log *.key *.a build purge: clean - @find . -mindepth 1 -maxdepth 1 -not -name "*.jar" -exec rm -rf {} + - @mv ./* ../ || true + @find . -mindepth 1 -maxdepth 1 \( -name "*.jar" -o -name "*.vdb" \) -prune -o -exec rm -rf {} + + @find . -mindepth 1 -maxdepth 1 -name "*.jar" -exec mv -t ../ {} + 2>/dev/null || true @echo "purge complete" @rm -rf $(CURRENT_DIR) diff --git a/template/scala/dut.scala b/template/scala/dut.scala index 0a6a5f80..74c23613 100644 --- a/template/scala/dut.scala +++ b/template/scala/dut.scala @@ -86,6 +86,9 @@ class UT_{{__TOP_MODULE_NAME__}}(args: Array[String]) extends JavaUT_{{__TOP_MOD def SetCoverage(coverage_name: String) = { this.dut.SetCoverage(coverage_name) } + def ResetCoverage() = { + this.dut.ResetCoverage() + } def GetCovMetrics(): Int = { com.ut.{{__TOP_MODULE_NAME__}}.DutUnifiedBase.GetCovMetrics() } diff --git a/test/test_codegen_sv_param_multi.cpp b/test/test_codegen_sv_param_multi.cpp index bade98a8..d4a9d2da 100644 --- a/test/test_codegen_sv_param_multi.cpp +++ b/test/test_codegen_sv_param_multi.cpp @@ -47,6 +47,17 @@ int main() const auto sv_wave = data["__SV_DUMP_WAVE__"].get(); assert(contains_line(sv_wave, "$fsdbDumpfile(\"dump.fsdb\")")); + assert(contains_line(sv_wave, "export \"DPI-C\" function vcs_fsdb_set_waveform_H")); + assert(contains_line(sv_wave, "export \"DPI-C\" function vcs_fsdb_finish_waveform_H")); + assert(contains_line(sv_wave, "$fsdbDumpFinish")); + assert(contains_line(sv_wave, "$fsdbDumpflush")); + assert(contains_line(sv_wave, "$fsdbDumpoff")); + assert(contains_line(sv_wave, "export \"DPI-C\" task vcs_coverage_start_H")); + assert(contains_line(sv_wave, "$cg_coverage_control(1)")); + assert(contains_line(sv_wave, "$cg_coverage_control(0)")); + assert(contains_line(sv_wave, "export \"DPI-C\" task vcs_coverage_dump_H")); + assert(contains_line(sv_wave, "$coverage_dump(name)")); + assert(contains_line(sv_wave, "$coverage_reset()")); assert(data["__TRACE__"].get() == "fsdb"); nlohmann::json data2; diff --git a/third/type_safe/.clang-format b/third/type_safe/.clang-format deleted file mode 100644 index 88b932e7..00000000 --- a/third/type_safe/.clang-format +++ /dev/null @@ -1,73 +0,0 @@ -AccessModifierOffset: -4 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: true -AlignConsecutiveDeclarations: true -AlignEscapedNewlinesLeft: Right -AlignOperands: true -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Empty -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: true -BinPackArguments: true -BinPackParameters: true -BreakBeforeBraces: Custom -BraceWrapping: - AfterClass: true - AfterControlStatement: true - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterStruct: true - AfterUnion: true - AfterExternBlock: true - BeforeCatch: true - BeforeElse: true - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: false -BreakBeforeBinaryOperators: All -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeColon -BreakStringLiterals: false -ColumnLimit: 100 -CompactNamespaces: true -ConstructorInitializerAllOnOneLineOrOnePerLine: false -ConstructorInitializerIndentWidth: 0 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: false -FixNamespaceComments: true -IncludeBlocks: Preserve -IndentCaseLabels: false -IndentPPDirectives: AfterHash -IndentWidth: 4 -IndentWrappedFunctionNames: true -KeepEmptyLinesAtTheStartOfBlocks: false -Language: Cpp -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: Inner -PenaltyBreakBeforeFirstCallParameter: 19937 -PenaltyReturnTypeOnItsOwnLine: 19937 -PointerAlignment: Left -ReflowComments: true -SortIncludes: true -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Cpp11 -TabWidth: 4 -UseTab: Never diff --git a/third/type_safe/CHANGELOG.md b/third/type_safe/CHANGELOG.md deleted file mode 100644 index 358683a1..00000000 --- a/third/type_safe/CHANGELOG.md +++ /dev/null @@ -1,67 +0,0 @@ -## Version 0.2.3 - -* Enable the use of `import std` (#141, #147). -* Make `strong_typedef` structural so it can be used as NTTP (#126). -* Add safe integer comparisons (#134). -* Enable EBO on MSVC (#128). -* Various bugfixes and CMake improvements (#132, #133, #137, #139, #143, #146, #148). - -## Version 0.2.2 - -* Replace `TYPE_SAFE_ARITHMETIC_UB` CMake option by `TYPE_SAFE_ARITHMETIC_POLICY` to enable checked arithmetic by default (#106) -* Be less strict in the signed/unsigned conversion of `integer` (#104) -* Various bugfixes (#97, #108, #111, #115) - -## Version 0.2.1 - -This release is mainly bugfixes: - -* Added `explicit_bool` strong typedef -* Fixed forwarding bug in `with()` of `array_ref` -* Silenced some warnings -* Improved CMake configuration - -## Version 0.2 - -This release took a long time, so here are just the most important changes. - -* Added `downcast()` utility function -* Fixed GCC 4.8 and clang support -* Improved documentation -* Improved CMake and added Conan support -* Hashing support for `boolean`, `integer`, `floating_point` and `strong_typedef` - -## Vocabulary Types - -* Added `object_ref` and and `xvalue_ref` -* Added `array_ref` -* Added `function_ref` -* Added `flag_set` -* Breaking: renamed `distance_t` to `difference_t` -* Improved `index_t` and `difference_t` - -### Optional & Variant: - -* Breaking: `optional` now auto-unwraps, removed `unwrap()` function -* Breaking: `optional_ref` creation function now `opt_ref()` instead of `ref()`, but more than before -* Breaking: Removed `optional_ref::value_or()` -* Added `optional_for` utility typedef -* Added support for additional parameters to `with()` and make it more optimizer friendly -* Added `with()` for `tagged_union` -* Improved map functions: additional arguments, member function pointers, `void` returning function objects -* Bugfix for trivial variant copy/move/destroy - -### Type Safe Building Blocks: - -* Added pointer like access to `constrained_type` -* Added `constrained_ref` -* Added `throwing_verifier` for `constrained_ref` along with `sanitize()` helper functions -* Added literal operator to create a static bound of `bounded_type` -* Added bitwise operators for `strong_typedef` -* Added `constexpr` support to `strong_typedef` -* Added support for mixed operators in `strong_typedef` -* Made `constrained_type` `constexpr` -* Fixed strong typedef `get()` for rvalues - - -Thanks to @johelgp, @xtofl, @nicola-gigante, @BRevzin, @verri, @lisongmin, @Manu343726, @MandarJKulkarni, @gerboengels. diff --git a/third/type_safe/CMakeLists.txt b/third/type_safe/CMakeLists.txt deleted file mode 100644 index a1e310f7..00000000 --- a/third/type_safe/CMakeLists.txt +++ /dev/null @@ -1,171 +0,0 @@ -# Copyright (C) 2016-2019 Jonathan Müller -# This file is subject to the license terms in the LICENSE file -# found in the top-level directory of this distribution. - -cmake_minimum_required(VERSION 3.1) - -project(TYPE_SAFE) - -include(external/external.cmake) - -# options -if(CMAKE_BUILD_TYPE MATCHES Debug) - set(_type_safe_default_assertions ON) -else() - set(_type_safe_default_assertions OFF) -endif() - -option(TYPE_SAFE_ENABLE_ASSERTIONS "whether or not to enable internal assertions for the type_safe library" ${_type_safe_default_assertions}) -if(${TYPE_SAFE_ENABLE_ASSERTIONS}) - set(_type_safe_enable_assertions 1) -else() - set(_type_safe_enable_assertions 0) -endif() - -option(TYPE_SAFE_ENABLE_PRECONDITION_CHECKS "whether or not to enable precondition checks" ON) -if(${TYPE_SAFE_ENABLE_PRECONDITION_CHECKS}) - set(_type_safe_enable_precondition_checks 1) -else() - set(_type_safe_enable_precondition_checks 0) -endif() - -option(TYPE_SAFE_ENABLE_WRAPPER "whether or not the wrappers in types.hpp are used" ON) -if(${TYPE_SAFE_ENABLE_WRAPPER}) - set(_type_safe_enable_wrapper 1) -else() - set(_type_safe_enable_wrapper 0) -endif() - -set(TYPE_SAFE_ARITHMETIC_POLICY "ub" CACHE STRING "which policy (ub/checked/default) is going to be used") -option(TYPE_SAFE_ARITHMETIC_UB "deprecated" ON) - -if(NOT ${TYPE_SAFE_ARITHMETIC_UB}) - set(_type_safe_arithmetic_policy 0) - message(DEPRECATION "option TYPE_SAFE_ARITHMETIC_UB is deprecated, use TYPE_SAFE_ARITHMETIC_POLICY instead") - message(STATUS "arithmetic_policy_default is default_arithmetic") -elseif(${TYPE_SAFE_ARITHMETIC_POLICY} STREQUAL "ub") - set(_type_safe_arithmetic_policy 1) - message(STATUS "arithmetic_policy_default is undefined_behavior_arithmetic") -elseif(${TYPE_SAFE_ARITHMETIC_POLICY} STREQUAL "checked") - set(_type_safe_arithmetic_policy 2) - message(STATUS "arithmetic_policy_default is checked_arithmetic") -else() - set(_type_safe_arithmetic_policy 0) - message(STATUS "arithmetic_policy_default is default_arithmetic") -endif() - -option(TYPE_SAFE_IMPORT_STD_MODULE "Build using the standard library modules rather than #include" OFF) - -# interface target -set(detail_header_files - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/aligned_union.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/all_of.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/assert.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/assign_or_construct.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/constant_parser.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/copy_move_control.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/force_inline.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/is_nothrow_swappable.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/map_invoke.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/detail/variant_impl.hpp) -set(header_files - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/config.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/arithmetic_policy.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/boolean.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/bounded_type.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/compact_optional.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/constrained_type.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/deferred_construction.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/downcast.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/flag.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/flag_set.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/floating_point.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/index.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/integer.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/narrow_cast.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/optional.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/optional_ref.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/output_parameter.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/reference.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/strong_typedef.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/tagged_union.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/types.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/variant.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/type_safe/visitor.hpp) - -add_library(type_safe INTERFACE) -target_sources(type_safe INTERFACE "$") -target_include_directories(type_safe INTERFACE $) -target_include_directories(type_safe SYSTEM INTERFACE $/include>) -target_compile_definitions(type_safe INTERFACE - TYPE_SAFE_ENABLE_ASSERTIONS=${_type_safe_enable_assertions} - TYPE_SAFE_ENABLE_PRECONDITION_CHECKS=${_type_safe_enable_precondition_checks} - TYPE_SAFE_ENABLE_WRAPPER=${_type_safe_enable_wrapper} - TYPE_SAFE_ARITHMETIC_POLICY=${_type_safe_arithmetic_policy}) -target_link_libraries(type_safe INTERFACE debug_assert) - - -if(TYPE_SAFE_IMPORT_STD_MODULE) - target_compile_definitions(type_safe INTERFACE TYPE_SAFE_IMPORT_STD_MODULE) - - # If a user has set TYPE_SAFE_IMPORT_STD_MODULE to ON this indicates they want the type_safe headers to import std - # This is a C++ 23 feature so we require them to use C++ in their build - target_compile_features(type_safe INTERFACE cxx_std_23) -endif() - -if(MSVC) - target_compile_options(type_safe INTERFACE /wd4800) # truncation to bool warning -endif() - -# Setup package config -include( CMakePackageConfigHelpers ) -set(CONFIG_PACKAGE_INSTALL_DIR lib/cmake/type_safe) - -set(TYPE_SAFE_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) -set(CMAKE_SIZEOF_VOID_P "") -write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/type_safe-config-version.cmake - VERSION 0.2.3 - COMPATIBILITY SameMajorVersion -) -set(CMAKE_SIZEOF_VOID_P ${TYPE_SAFE_CMAKE_SIZEOF_VOID_P}) - -# Install target -install(DIRECTORY include/type_safe DESTINATION include) - -# Only export target when using imported targets -if(TYPE_SAFE_HAS_IMPORTED_TARGETS) - install(TARGETS type_safe - EXPORT type_safe-targets - DESTINATION lib) - - install( EXPORT type_safe-targets - DESTINATION - ${CONFIG_PACKAGE_INSTALL_DIR} - ) - - install( FILES - ${CMAKE_CURRENT_SOURCE_DIR}/type_safe-config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/type_safe-config-version.cmake - DESTINATION - ${CONFIG_PACKAGE_INSTALL_DIR} ) - -endif() - -# other subdirectories -# only add if not inside add_subdirectory() -option(TYPE_SAFE_BUILD_TEST_EXAMPLE "build test and example" ON) -if(${TYPE_SAFE_BUILD_TEST_EXAMPLE} AND (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)) - enable_testing() - add_subdirectory(example/) - add_subdirectory(test/) -endif() - -if(TYPE_SAFE_IMPORT_STD_MODULE) - add_subdirectory(test_std_module/) -endif() - -option(TYPE_SAFE_BUILD_DOC "generate documentation" OFF) -if(TYPE_SAFE_BUILD_DOC) - add_subdirectory(doc/) -endif() diff --git a/third/type_safe/LICENSE b/third/type_safe/LICENSE deleted file mode 100644 index 8a13e584..00000000 --- a/third/type_safe/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016-2020 Jonathan Müller - -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/type_safe/README.md b/third/type_safe/README.md deleted file mode 100644 index 87f390e6..00000000 --- a/third/type_safe/README.md +++ /dev/null @@ -1,102 +0,0 @@ -# type_safe - -![Project Status](https://img.shields.io/endpoint?url=https%3A%2F%2Fwww.jonathanmueller.dev%2Fproject%2Ftype_safe%2Findex.json) -![Build Status](https://github.com/foonathan/type_safe/workflows/Main%20CI/badge.svg) - -type_safe provides zero overhead abstractions that use the C++ type system to prevent bugs. - -> Zero overhead abstractions here and in following mean abstractions that have no cost with optimizations enabled, -> but may lead to slightly lower runtime in debug mode, -> especially when assertions for this library are enabled. - -The library features cannot really be explained in the scope of this readme, -I highly suggest that you check out [the first](https://www.foonathan.net/2016/10/type-safe/) and [second blog post](https://www.foonathan.net/2016/10/strong-typedefs/) and the examples. - -> |[![](https://www.jonathanmueller.dev/embarcadero-logo.png)](https://www.embarcadero.com/de/products/cbuilder/starter) | Sponsored by [Embarcadero C++Builder](https://www.embarcadero.com/de/products/cbuilder/starter). | -> |-------------------------------------|----------------| -> -> If you like this project, consider [supporting me](https://jonathanmueller.dev/support-me/). - -## Features - -### Improved built-in types - -* `ts::integer` - a zero overhead wrapper over a built-in integer type - * no default constructor to force meaningful initialization - * no "lossy" conversions (i.e. from a bigger type or a type with a different signedness) - * no mixed arithmetic with floating points or integer types of a different signedness - * no mixed comparison with floating points - * over/underflow is undefined behavior in release mode - even for `unsigned` integers, - enabling compiler optimizations -* `ts::floating_point` - a zero overhead wrapper over a built-in floating point - * no default constructor to force meaningful initialization - * no "lossy" conversion (i.e. from a bigger type) - * no "lossy" comparisons - * no mixed arithmetic/comparison with integers -* `ts::boolean` - a zero overhead wrapper over `bool` - * no default constructor to force meaningful initialization - * no conversion from integer values - * no arithmetic operators -* aliases like `ts::uint32_t` or `ts::size_t` that are either wrapper or built-in type depending on macro -* literal operators for those aliases like `342_u32` or `0_usize` - -### Vocabulary types - -* `ts::object_ref` - a non-null pointer -* `ts::index_t` and `ts::distance_t` - index and distance integer types with only a subset of operations available -* `ts::array_ref` - non-null reference to contigous storage -* `ts::function_ref` - non-null reference to a function -* `ts::flag` - an improved flag type, better than a regular `bool` or `ts::boolean` -* `ts::flag_set` - a set of flags -* `ts::output_parameter` - an improved output parameter compared to the naive lvalue reference - -### Optional & Variant - -* `ts::basic_optional` - a generic, improved `std::optional` that is fully monadic, - also `ts::optional` and `ts::optional_ref` implementations -* `ts::compact_optional` implementation for no space overhead optionals -* `ts::basic_variant` - a generic, improved `std::variant`, also `ts::variant` and `ts::fallback_variant` implementations - -### Type safe building blocks - -* `ts::constrained_type` - a wrapper over some type that verifies that a certain constraint is always fulfilled - * `ts::constraints::*` - predefined constraints like `non_null`, `non_empty`, ... - * `ts::tagged_type` - constrained type without checking, useful for tagging - * `ts::bounded_type` - constrained type that ensures a value in a certain interval - * `ts::clamped_type` - constrained type that clamps a value to ensure that it is in the certain interval -* `ts::strong_typedef` - a generic facility to create strong typedefs more easily -* `ts::deferred_construction` - create an object without initializing it yet - -## Installation - -Header-only, just copy the files in your project. -You need to add the type_safe `include` directory to your include path as well as make [debug_assert.hpp](https://github.com/foonathan/debug_assert) available. -The repository is included. -You also need to enable C++11. - -Behavior can be customized with the following macros: - -* `TYPE_SAFE_ENABLE_ASSERTIONS` (default is `1`): whether or not assertions are enabled in this library -* `TYPE_SAFE_ENABLE_WRAPPER` (default is `1`): whether or not the typedefs in `type_safe/types.hpp` use the wrapper classes -* `TYPE_SAFE_ARITHMETIC_POLICY` (`ub`/`checked`/`default`, default is `ub`): whether under/overflow in the better integer types is UB, an exception, or the default behavior - -If you're using CMake there is the target `type_safe` available after you've called `add_subdirectory(path/to/type_safe)`. -Simply link this target to your target and it will setup everything automagically. -For convenience the macros are also mapped to CMake options of the same name. - -## Documentation - -You can find the full documentation generated by [standardese](https://github.com/standardese/standardese) [here](https://type_safe.foonathan.net/). - -## Acknowledgements - -This project is greatly supported by my [patrons](https://patreon.com/foonathan). -In particular thanks to the individual supporters: - -* Mark Atkinson -* Reiner Eiteljörge - -And big thanks to the main contributors as well: - -* Johel Ernesto Guerrero Peña [@johelegp](https://github.com/johelegp) - diff --git a/third/type_safe/conanfile.py b/third/type_safe/conanfile.py deleted file mode 100644 index 9831127e..00000000 --- a/third/type_safe/conanfile.py +++ /dev/null @@ -1,23 +0,0 @@ -from conans import ConanFile -from conans.tools import download, untargz -import os - -class TypeSafe(ConanFile): - name = 'type_safe' - url = 'https://github.com/foonathan/type_safe' - version = '0.2.3' - requires = 'debug_assert/1.3@Manu343726/testing' - exports = '*.hpp' - generators = 'cmake' - - - def source(self): - tar = 'type_safe-{}.tar.gz'.format(self.version) - url = 'https://github.com/foonathan/type_safe/archive/v{}.tar.gz'.format(self.version) - download(url, tar) - untargz(tar) - - def package(self): - includedir = os.path.join('include', 'type_safe') - srcdir = os.path.join('type_safe-{}'.format(self.version), includedir) - self.copy('*.hpp', src=srcdir, dst=includedir) diff --git a/third/type_safe/doc/CMakeLists.txt b/third/type_safe/doc/CMakeLists.txt deleted file mode 100644 index aec52e8d..00000000 --- a/third/type_safe/doc/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) 2016-2019 Jonathan Müller -# This file is subject to the license terms in the LICENSE file -# found in the top-level directory of this distribution. - -set(TYPE_SAFE_STANDARDESE_DOWNLOAD_DIRECTORY "" CACHE PATH "path to directory with pre-built standardese") - -find_package(standardese QUIET) -if(NOT standardese_FOUND) - find_program(STANDARDESE_TOOL standardese ${TYPE_SAFE_STANDARDESE_DOWNLOAD_DIRECTORY}) - include(${TYPE_SAFE_STANDARDESE_DOWNLOAD_DIRECTORY}/standardese-config.cmake) -endif() - -standardese_generate(type_safe - CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/standardese.config - INCLUDE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../include/ - ${CMAKE_CURRENT_SOURCE_DIR}/../external/debug_assert/ - INPUT ${header_files}) diff --git a/third/type_safe/doc/doc_template.html b/third/type_safe/doc/doc_template.html deleted file mode 100644 index cf079076..00000000 --- a/third/type_safe/doc/doc_template.html +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: docs -title: type_safe - Zero overhead abstractions for more type safety -project: type_safe ---- - -{{ standardese_doc $file $format }} - - diff --git a/third/type_safe/doc/standardese.config b/third/type_safe/doc/standardese.config deleted file mode 100644 index ab2714d1..00000000 --- a/third/type_safe/doc/standardese.config +++ /dev/null @@ -1,10 +0,0 @@ -[input] -blacklist_entity_name=TYPE_SAFE_DETAIL_MAKE_OP - -[template] -default_template=doc_template.html - -[output] -format=html -show_complex_noexcept=false -require_comment_for_full_synopsis=false diff --git a/third/type_safe/example/CMakeLists.txt b/third/type_safe/example/CMakeLists.txt deleted file mode 100644 index cbbdf426..00000000 --- a/third/type_safe/example/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2016-2019 Jonathan Müller -# This file is subject to the license terms in the LICENSE file -# found in the top-level directory of this distribution. - -function(_type_safe_example name) - add_executable(type_safe_example_${name} ${name}.cpp) - target_link_libraries(type_safe_example_${name} PUBLIC type_safe) - set_property(TARGET type_safe_example_${name} PROPERTY CXX_STANDARD 11) -endfunction() - -_type_safe_example(constrained) -_type_safe_example(optional) -_type_safe_example(output_parameter) -_type_safe_example(strong_typedef) -_type_safe_example(types) diff --git a/third/type_safe/example/constrained.cpp b/third/type_safe/example/constrained.cpp deleted file mode 100644 index bfe7c554..00000000 --- a/third/type_safe/example/constrained.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include -#include - -#include - -namespace ts = type_safe; - -// a string type that is never empty -// the constraint is just a predicate, you can easily write your own -using non_empty_string = ts::constrained_type; - -// this function must not get an empty string -// the return value is also not empty -non_empty_string func(non_empty_string str) -{ - std::cout << str.get_value() << '\n'; - // get_value() returns a const reference - // if we want to modify it: - { - auto modifier = str.modify(); - modifier.get() += " suffix"; - // destructor of modifier verifies that str fulfills constraint again - } // extra scope is important here - return str; -} - -int main() -{ - // std::cout << func("foo") << '\n'; // error: "foo" is not a non_empty_string - // we must be explicit - std::string str = func(non_empty_string("foo")).release(); // release() moves the string out - std::cout << str << '\n'; - - non_empty_string str2("foobar"); - // an alternative to str2.modify(): - ts::with(str2, [&](std::string& s) { s += str; }); - std::cout << str2.get_value() << '\n'; -} - -// some constraints do not need to be checked -// (example taken from: https://www.youtube.com/watch?v=ojZbFIQSdl8) -struct sanitized -{}; -struct unsanitized -{}; - -// ts::tagged_type is an alias for ts::constrained_type with the ts::null_verifier as third -// parameter it is a constrained type where the constraint isn't checked so the constraint does not -// need to be a predicate it is just there to create different, non convertible types -using sanitized_string = ts::tagged_type; -using unsanitized_string = ts::tagged_type; - -unsanitized_string get_form_data(); -sanitized_string sanitize(const unsanitized_string& str); -void execute_query(const sanitized_string& str); - -// now impossible to accidentally use unsanitized strings -void do_stuff() -{ - // execute_query(get_form_data()); // error! - // execute_query(get_form_data().get_value()); // error! - // execute_query(sanitize(get_form_data())); // only this possible (but linker error, - // so...) -} diff --git a/third/type_safe/example/optional.cpp b/third/type_safe/example/optional.cpp deleted file mode 100644 index e7970ab1..00000000 --- a/third/type_safe/example/optional.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include -#include -#include - -#include -#include -#include - -namespace ts = type_safe; - -// type safe back function -// impossible to forget precondition -ts::optional back(const std::string& str) -{ - return str.empty() ? ts::nullopt : ts::make_optional(str.back()); -} - -// some imaginary lookup function -ts::optional lookup(int c) -{ - // simulate lookup - return c == 'T' ? ts::nullopt : ts::make_optional(c + 1); -} - -// task: get last character of string, -// convert it to upper case -// look it up -// and return the integer or 0 if there is no integer - -// this is how'd you do it with std::optional -int task_std(const std::string& str) -{ - auto c = back(str); - if (!c) - return 0; - auto upper_case = std::toupper(c.value()); - auto result = lookup(upper_case); - return result.value_or(0); -} - -// this is how'd you do it with the monadic functionality -// there is no need for branches and no errors possible -// it generates identical assembler code -int task_monadic(const std::string& str) -{ - return back(str) - // map takes a functor and applies it to the stored value, if there is any - // the result is another optional with possibly different type - .map(static_cast(&std::toupper)) - // now we map lookup - // as lookup returns already an optional itself, - // it won't wrap the result in another optional - .map(lookup) - // value_or() as usual - .value_or(0); -} - -// a visitor for an optional -// this again makes branches unnecessary -struct visitor -{ - template - void operator()(const T& val) - { - std::cout << val << '\n'; - } - - void operator()(ts::nullopt_t) - { - std::cout << "nothing :(\n"; - } -}; - -int main() -{ - std::cout << task_std("Hello World") << ' ' << task_monadic("Hello World") << '\n'; - std::cout << task_std("Hallo Welt") << ' ' << task_monadic("Hallo Welt") << '\n'; - std::cout << task_std("") << ' ' << task_monadic("") << '\n'; - - // visit an optional - ts::optional opt(45); - ts::visit(visitor{}, opt); - opt.reset(); - ts::visit(visitor{}, opt); - - // safely manipulate the value if there is one - // with() is an inplace map() - // and thus more efficient if you do not need to change the type - ts::with(opt, [](int& i) { - std::cout << "got: " << i << '\n'; - ++i; - }); - - // an optional reference - // basically a pointer, but provides the functionality of optional - ts::optional_ref ref; - - int a = 42; - ref = ts::ref(a); // assignment rebinds - std::cout << ref.value() << '\n'; - - ref.value() = 0; - std::cout << a << '\n'; - - int b = 5; - ref.value_or(b)++; - std::cout << a << ' ' << b << '\n'; - - ref = nullptr; // assign nullptr as additional way to reset - - // an optional reference to const - ts::optional_ref ref_const(ref); - - // create optional_ref from pointer - auto ptr = ts::opt_ref(&a); - auto ptr_const = ts::opt_cref(&a); - - /// transform an optional_ref to an optional by copying - auto ptr_transformed = ts::copy(ptr); // there is also ts::move() to move the value - std::cout << ptr_transformed.value() << '\n'; -} diff --git a/third/type_safe/example/output_parameter.cpp b/third/type_safe/example/output_parameter.cpp deleted file mode 100644 index c9189ec4..00000000 --- a/third/type_safe/example/output_parameter.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include -#include -#include - -#include - -namespace ts = type_safe; - -// task: read strings from stream until EOF -// concatenate all strings -// return whether any strings read - -// using a reference as output parameter - BAD: -// * not obvious from the caller that the string will be modified (in the general case) -// * requires default constructor -// * implicit precondition that the output is empty -bool read_str_naive(std::istream& in, std::string& out) -{ - for (std::string tmp; in >> tmp;) - out += tmp; - return !out.empty(); -} - -// does not have these problems -bool read_str_better(std::istream& in, ts::output_parameter out) -{ - std::string result; // no way to access the string directly - // so need to create new one - - for (std::string tmp; in >> tmp;) - result += tmp; - - // granted, that's verbose - auto empty = result.empty(); // we need to query here, because after move it might be empty - out = std::move(result); // set output parameter - return !empty; - - // so use this one: - // assignment op returns the value that was assigned - return (out = std::move(result)).empty(); -} - -int main() -{ - { - std::istringstream in("hello world"); - std::string str; - auto res = read_str_naive(in, str); - std::cout << res << ' ' << str << '\n'; - } - { - std::istringstream in("hello world"); - std::string str; - // use ts::out() to create an output_parameter easily - auto res = read_str_better(in, ts::out(str)); - std::cout << res << ' ' << str << '\n'; - } - // what if std::string had no default constructor? - { - // use this one: - ts::deferred_construction str; - // str is not initialized yet, - // so it does not require a constructor - // once you give it a value, it will never be empty again - - std::istringstream in("hello world"); - auto res = read_str_better(in, ts::out(str)); - // if the function assigned a value to the output parameter, - // it will call the constructor and directly initializes it with the correct value - std::cout << res << ' ' << str.has_value() << ' ' << str.value() << '\n'; - } -} diff --git a/third/type_safe/example/strong_typedef.cpp b/third/type_safe/example/strong_typedef.cpp deleted file mode 100644 index 967f4f93..00000000 --- a/third/type_safe/example/strong_typedef.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include -#include -#include - -#include - -namespace ts = type_safe; - -// we want some kind of handle to an int -struct handle : ts::strong_typedef, // required - ts::strong_typedef_op::equality_comparison, // for operator==/operator!= - ts::strong_typedef_op::dereference // for operator*/operator-> -{ - using strong_typedef::strong_typedef; - - // we also want the operator bool() - explicit operator bool() const noexcept - { - return static_cast(*this) != nullptr; - } -}; - -void use_handle(handle h) -{ - // we can dereference it - std::cout << *h << '\n'; - - // and compare it - (void)(h == handle(nullptr)); - - // and reassign - int a; - h = handle(&a); - // or get back - int* ptr = static_cast(h); - std::cout << &a << ' ' << ptr << '\n'; -} - -// integer representing a distance -struct distance -: ts::strong_typedef, // required - ts::strong_typedef_op::equality_comparison, // for operator==/operator!= - ts::strong_typedef_op::relational_comparison, // for operator< etc. - ts::strong_typedef_op::integer_arithmetic // all arithmetic operators that make sense - // for integers -{ - using strong_typedef::strong_typedef; -}; - -// we want to output it -std::ostream& operator<<(std::ostream& out, const distance& d) -{ - return out << static_cast(d) << " distance"; -} - -namespace std -{ -// we want to use it with the std::unordered_* containers -template <> -struct hash<::distance> : type_safe::hashable<::distance> -{}; - -} // namespace std - -int main() -{ - distance d(4); - // int val = d; // error - // d += 3; // error - d += distance(3); // works - - std::unordered_set set{d}; - - std::cout << *set.find(d) << '\n'; -} diff --git a/third/type_safe/example/types.cpp b/third/type_safe/example/types.cpp deleted file mode 100644 index 39f981c5..00000000 --- a/third/type_safe/example/types.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include // narrow_cast<> -#include // boolean<>, integer<>, floating_point<>, aliases - -namespace ts = type_safe; - -// ts::unsigned_t is alias for ts::integer -// function is type safe - only unsigned integer types smaller than unsigned can be passed to the -// function -void only_unsigned(ts::unsigned_t val) -{ - std::cout << "only_unsigned() got: " << val << '\n'; -} - -int main() -{ - using namespace ts::literals; // for the literal operators - - //=== type safe boolean ===// - // ts::bool_t is alias for ts::boolean - ts::bool_t b1(true); - // ts::bool_t b2; // error: no default constructor - // ts::bool_t b3(0); // error: 0 is not a bool - std::cout << "boolean value: " << b1 << '\n'; - - ts::bool_t b4 = !b1; - if (b4) - std::cout << "b4 is true\n"; - else - std::cout << "b4 is false\n"; - - // b4 + 0; // error: arithmetic not possible - // ++b4; // error: arithmetic not possible - - //=== type safe integer ===// - // ts::int_t is alias for ts::integer - // ts::unsigned_t is alias for ts::integer - ts::int_t i1(0); - // ts::int_t i2; // error: no default constructor - // ts::int_t i3(100ll); // error: long long -> int would be narrowing - - ts::unsigned_t u1(0u); - // ts::unsigned_t u2; // error: no default constructor - // ts::unsigned_t u3(0); // error: 0 is signed - - std::cout << "integer value: " << i1 << ' ' << u1 << '\n'; - - i1 += 4; - ts::integer i4 = i1 + 100ll; // 100ll is long long, so result is long long - std::cout << i4 << '\n'; - - // --u1; // runtime error: unsigned underflow - // -u1; // error: no unary minus for unsigned - - ts::uint8_t u4(255_u8); // instead of std::uint8_t(255) - // u4 += 2; // error: 2 is signed - // u4 += 2_u8; // runtime error: unsigned overflow - - // only_unsigned(-4); // error: -4 is not unsigned - // only_unsigned(10); // error: 10 is not unsigned - // only_unsigned(i1); // error: i1 is not unsigned - only_unsigned(u4); - - ts::unsigned_t u5 = ts::make_unsigned(i1); - // ts::unsigned_t u6 = ts::make_unsigned(-i1); // runtime error: value does not fit - ts::unsigned_t u7 = ts::abs(-i1); // but this works and returns an the unsigned integer - std::cout << u5 << ' ' << u7 << '\n'; - - // ts::int8_t i5 = ts::make_signed(u4); // runtime error: value does not fit - ts::int8_t i6 = ts::make_signed(u4 - 200_u8); - std::cout << i6 << '\n'; - - //=== type safe floating points ===// - // ts::float_t is alias for ts::floating_point (std::float_t is float) - // ts::double_t is alias for ts::floating_point (std::double_t is double) - ts::float_t f1(0.f); - // ts::float_t f2; // error: no default constructor - // ts::float_t f3(0.); // error: 0. is double literal - - ts::double_t d1(0.); - // ts::double_t d2; // error: no default constructor - ts::double_t d3(0.f); // okay: float -> double is allowed - - std::cout << "floating point value: " << f1 << ' ' << d1 << ' ' << d3 << '\n'; - - // f1++; // error: no in/decrement for floats - // f1 == 0.f; // error: no equality comparison for floats - - //=== narrow cast ===// - ts::uint32_t uint32_val(325_u32); - // ts::uint8_t uint8_val1 = - // ts::narrow_cast(uint32_val); // runtime error: value does not fit - uint32_val = 100_u32; - ts::uint8_t uint8_val2 = ts::narrow_cast(uint32_val); // works - std::cout << uint32_val << ' ' << uint8_val2 << '\n'; - - ts::double_t double_val(0.1); - // ts::float_t float_val1 = - // ts::narrow_cast(double_val); // runtime error: 0.1 is not exact - double_val = 0.5; - ts::float_t float_val2 = ts::narrow_cast(double_val); // works, 0.5 is exact - std::cout << double_val << ' ' << float_val2 << '\n'; -} diff --git a/third/type_safe/external/debug_assert/CMakeLists.txt b/third/type_safe/external/debug_assert/CMakeLists.txt deleted file mode 100644 index 7005afc7..00000000 --- a/third/type_safe/external/debug_assert/CMakeLists.txt +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (C) 2016-2018 Jonathan Müller -# This file is subject to the license terms in the LICENSE file -# found in the top-level directory of this distribution. - -cmake_minimum_required(VERSION 3.1) -project(DEBUG_ASSERT) - -# Determine if debug_assert is built as a subproject (using add_subdirectory) -# or if it is the master project. -set(MASTER_PROJECT OFF) -if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) - set(MASTER_PROJECT ON) -endif () - -# options -option(DEBUG_ASSERT_NO_STDIO "whether or not the default_handler uses fprintf() to print an error message" OFF) -if(DEBUG_ASSERT_NO_STDIO) - set(_debug_assert_no_stdio DEBUG_ASSERT_NO_STDIO) -endif() - -option(DEBUG_ASSERT_DISABLE "completely disable assertion macro" OFF) -if(DEBUG_ASSERT_DISABLE) - set(_debug_assert_disable DEBUG_ASSERT_DISABLE) -endif() - -set(DEBUG_ASSERT_MARK_UNREACHABLE "" CACHE STRING "override of DEBUG_ASSERT_MARK_UNREACHABLE") -if(DEBUG_ASSERT_MARK_UNREACHABLE) - set(_debug_assert_mark_unreachable "DEBUG_ASSERT_MARK_UNREACHABLE=${DEBUG_ASSERT_MARK_UNREACHABLE}") -endif() - -set(DEBUG_ASSERT_ASSUME "" CACHE STRING "override of DEBUG_ASSERT_ASSUME macro") -if(DEBUG_ASSERT_ASSUME) - set(_debug_assert_assume "DEBUG_ASSERT_ASSUME=${DEBUG_ASSERT_ASSUME}") -endif() - -set(DEBUG_ASSERT_FORCE_INLINE "" CACHE STRING "override of DEBUG_ASSERT_FORCE_INLINE macro") -if(DEBUG_ASSERT_FORCE_INLINE) - set(_debug_assert_force_inline "DEBUG_ASSERT_FORCE_INLINE=${DEBUG_ASSERT_FORCE_INLINE}") -endif() - -option(DEBUG_ASSERT_INSTALL "Generate the install target." ${MASTER_PROJECT}) - -# interface target -add_library(debug_assert INTERFACE) -target_sources(debug_assert INTERFACE $) -target_include_directories(debug_assert INTERFACE $) -target_include_directories(debug_assert SYSTEM INTERFACE $/include>) -target_compile_definitions(debug_assert INTERFACE - ${_debug_assert_no_stdio} - ${_debug_assert_disable} - ${_debug_assert_mark_unreachable} - ${_debug_assert_assume} - ${_debug_assert_force_inline}) - -# example target -if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) - add_executable(debug_assert_example EXCLUDE_FROM_ALL example.cpp) - target_link_libraries(debug_assert_example PUBLIC debug_assert) -endif() - -# Create package config files -include( CMakePackageConfigHelpers ) -set(CONFIG_PACKAGE_INSTALL_DIR lib/cmake/debug_assert) - -file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/debug_assert-config.cmake " -include(\${CMAKE_CURRENT_LIST_DIR}/debug_assert-targets.cmake) -set(debug_assert_LIBRARY debug_assert) -set(debug_assert_LIBRARIES debug_assert) -") - -set(DEBUG_ASSERT_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) -set(CMAKE_SIZEOF_VOID_P "") -write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/debug_assert-config-version.cmake - VERSION 1.3.1 - COMPATIBILITY SameMajorVersion -) -set(CMAKE_SIZEOF_VOID_P ${DEBUG_ASSERT_CMAKE_SIZEOF_VOID_P}) - -if(DEBUG_ASSERT_INSTALL) - # Install target and header - install(TARGETS debug_assert - EXPORT debug_assert-targets - DESTINATION lib) - - install(FILES debug_assert.hpp DESTINATION include) - - install( EXPORT debug_assert-targets - DESTINATION - ${CONFIG_PACKAGE_INSTALL_DIR} - ) - - install( FILES - ${CMAKE_CURRENT_BINARY_DIR}/debug_assert-config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/debug_assert-config-version.cmake - DESTINATION - ${CONFIG_PACKAGE_INSTALL_DIR} ) -endif() - diff --git a/third/type_safe/external/debug_assert/debug_assert.hpp b/third/type_safe/external/debug_assert/debug_assert.hpp deleted file mode 100644 index cd268e12..00000000 --- a/third/type_safe/external/debug_assert/debug_assert.hpp +++ /dev/null @@ -1,370 +0,0 @@ -//======================================================================// -// Copyright (C) 2016-2018 Jonathan Müller -// -// This software is provided 'as-is', without any express or -// implied warranty. In no event will the authors be held -// liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute -// it freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but -// is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any -// source distribution. -//======================================================================// - -#ifndef DEBUG_ASSERT_HPP_INCLUDED -#define DEBUG_ASSERT_HPP_INCLUDED - -#include - -#ifndef DEBUG_ASSERT_NO_STDIO -# include -#endif - -#ifndef DEBUG_ASSERT_MARK_UNREACHABLE -# ifdef __GNUC__ -# define DEBUG_ASSERT_MARK_UNREACHABLE __builtin_unreachable() -# elif defined(_MSC_VER) -# define DEBUG_ASSERT_MARK_UNREACHABLE __assume(0) -# else -/// Hint to the compiler that a code branch is unreachable. -/// Define it yourself prior to including the header to override it. -/// \notes This must be usable in an expression. -# define DEBUG_ASSERT_MARK_UNREACHABLE -# endif -#endif - -#ifndef DEBUG_ASSERT_FORCE_INLINE -# ifdef __GNUC__ -# define DEBUG_ASSERT_FORCE_INLINE [[gnu::always_inline]] inline -# elif defined(_MSC_VER) -# define DEBUG_ASSERT_FORCE_INLINE __forceinline -# else -/// Strong hint to the compiler to inline a function. -/// Define it yourself prior to including the header to override it. -# define DEBUG_ASSERT_FORCE_INLINE inline -# endif -#endif - -namespace debug_assert -{ -//=== source location ===// -/// Defines a location in the source code. -struct source_location -{ - const char* file_name; ///< The file name. - unsigned line_number; ///< The line number. -}; - -/// Expands to the current [debug_assert::source_location](). -#define DEBUG_ASSERT_CUR_SOURCE_LOCATION \ - debug_assert::source_location \ - { \ - __FILE__, static_cast(__LINE__) \ - } - -//=== level ===// -/// Tag type to indicate the level of an assertion. -template -struct level -{}; - -/// Helper class that sets a certain level. -/// Inherit from it in your module handler. -template -struct set_level -{ - static const unsigned level = Level; -}; - -template -const unsigned set_level::level; - -/// Helper class that controls whether the handler can throw or not. -/// Inherit from it in your module handler. -/// If the module does not inherit from this class, it is assumed that -/// the handle does not throw. -struct allow_exception -{ - static const bool throwing_exception_is_allowed = true; -}; - -//=== handler ===// -/// Does not do anything to handle a failed assertion (except calling -/// [std::abort()]()). -/// Inherit from it in your module handler. -struct no_handler -{ - /// \effects Does nothing. - /// \notes Can take any additional arguments. - template - static void handle(const source_location&, const char*, Args&&...) noexcept - {} -}; - -/// The default handler that writes a message to `stderr`. -/// Inherit from it in your module handler. -struct default_handler -{ - /// \effects Prints a message to `stderr`. - /// \notes It can optionally accept an additional message string. - /// \notes If `DEBUG_ASSERT_NO_STDIO` is defined, it will do nothing. - static void handle(const source_location& loc, const char* expression, - const char* message = nullptr) noexcept - { -#ifndef DEBUG_ASSERT_NO_STDIO - if (*expression == '\0') - { - if (message) - std::fprintf(stderr, "[debug assert] %s:%u: Unreachable code reached - %s.\n", - loc.file_name, loc.line_number, message); - else - std::fprintf(stderr, "[debug assert] %s:%u: Unreachable code reached.\n", - loc.file_name, loc.line_number); - } - else if (message) - std::fprintf(stderr, "[debug assert] %s:%u: Assertion '%s' failed - %s.\n", - loc.file_name, loc.line_number, expression, message); - else - std::fprintf(stderr, "[debug assert] %s:%u: Assertion '%s' failed.\n", loc.file_name, - loc.line_number, expression); -#else - (void)loc; - (void)expression; - (void)message; -#endif - } -}; - -/// \exclude -namespace detail -{ - //=== boilerplate ===// - // from http://en.cppreference.com/w/cpp/types/remove_reference - template - struct remove_reference - { - using type = T; - }; - - template - struct remove_reference - { - using type = T; - }; - - template - struct remove_reference - { - using type = T; - }; - - // from http://stackoverflow.com/a/27501759 - template - T&& forward(typename remove_reference::type& t) - { - return static_cast(t); - } - - template - T&& forward(typename remove_reference::type&& t) - { - return static_cast(t); - } - - template - struct enable_if; - - template - struct enable_if - { - using type = T; - }; - - template - struct enable_if - {}; - - //=== helper class to check if throw is allowed ===// - template - struct allows_exception - { - static const bool value = false; - }; - - template - struct allows_exception::type> - { - static const bool value = Handler::throwing_exception_is_allowed; - }; - - //=== regular void fake ===// - struct regular_void - { - constexpr regular_void() = default; - - // enable conversion to anything - // conversion must not actually be used - template - constexpr operator T&() const noexcept - { - // doesn't matter how to get the T - return DEBUG_ASSERT_MARK_UNREACHABLE, *static_cast(nullptr); - } - }; - - //=== assert implementation ===// - // function name will be shown on constexpr assertion failure - template - regular_void debug_assertion_failed(const source_location& loc, const char* expression, - Args&&... args) - { -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4702) -#endif - return Handler::handle(loc, expression, detail::forward(args)...), std::abort(), - regular_void(); -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - } - - // use enable if instead of tag dispatching - // this removes on additional function and encourage optimization - template - constexpr auto do_assert( - const Expr& expr, const source_location& loc, const char* expression, Handler, level, - Args&&... args) noexcept(!allows_exception::value - || noexcept(Handler::handle(loc, expression, - detail::forward(args)...))) -> - typename enable_if::type - { - static_assert(Level > 0, "level of an assertion must not be 0"); - return expr() ? regular_void() - : debug_assertion_failed(loc, expression, - detail::forward(args)...); - } - - template - DEBUG_ASSERT_FORCE_INLINE constexpr auto do_assert(const Expr&, const source_location&, - const char*, Handler, level, - Args&&...) noexcept -> - typename enable_if<(Level > Handler::level), regular_void>::type - { - return regular_void(); - } - - template - constexpr auto do_assert( - const Expr& expr, const source_location& loc, const char* expression, Handler, - Args&&... args) noexcept(!allows_exception::value - || noexcept(Handler::handle(loc, expression, - detail::forward(args)...))) -> - typename enable_if::type - { - return expr() ? regular_void() - : debug_assertion_failed(loc, expression, - detail::forward(args)...); - } - - template - DEBUG_ASSERT_FORCE_INLINE constexpr auto do_assert(const Expr&, const source_location&, - const char*, Handler, Args&&...) noexcept -> - typename enable_if::type - { - return regular_void(); - } - - constexpr bool always_false() noexcept - { - return false; - } -} // namespace detail -} // namespace debug_assert - -//=== assertion macros ===// -#ifndef DEBUG_ASSERT_DISABLE -/// The assertion macro. -// -/// Usage: `DEBUG_ASSERT(, , [], -/// []. -/// Where: -/// * `` - the expression to check for, the expression `!` must be -/// well-formed and contextually convertible to `bool`. -/// * `` - an object of the module specific handler -/// * `` (optional, defaults to `1`) - the level of the assertion, must -/// be an object of type [debug_assert::level](). -/// * `` (optional) - any additional arguments that are -/// just forwarded to the handler function. -/// -/// It will only check the assertion if `` is less than or equal to -/// `Handler::level`. -/// A failed assertion will call: `Handler::handle(location, expression, args)`. -/// `location` is the [debug_assert::source_location]() at the macro expansion, -/// `expression` is the stringified expression and `args` are the -/// `` as-is. -/// If the handler function returns, it will call [std::abort()]. -/// -/// The macro will expand to a `void` expression. -/// -/// \notes Define `DEBUG_ASSERT_DISABLE` to completely disable this macro, it -/// will expand to nothing. -/// This should not be necessary, the regular version is optimized away -/// completely. -# define DEBUG_ASSERT(Expr, ...) \ - static_cast(debug_assert::detail::do_assert([&]() noexcept { return Expr; }, \ - DEBUG_ASSERT_CUR_SOURCE_LOCATION, #Expr, \ - __VA_ARGS__)) - -/// Marks a branch as unreachable. -/// -/// Usage: `DEBUG_UNREACHABLE(, [], [])` -/// Where: -/// * `` - an object of the module specific handler -/// * `` (optional, defaults to `1`) - the level of the assertion, must -/// be an object of type [debug_assert::level](). -/// * `` (optional) - any additional arguments that are -/// just forwarded to the handler function. -/// -/// It will only check the assertion if `` is less than or equal to -/// `Handler::level`. -/// A failed assertion will call: `Handler::handle(location, "", args)`. -/// and `args` are the `` as-is. -/// If the handler function returns, it will call [std::abort()]. -/// -/// This macro is also usable in a constant expression, -/// i.e. you can use it in a `constexpr` function to verify a condition like so: -/// `cond(val) ? do_sth(val) : DEBUG_UNREACHABLE(…)`. -/// You can't use `DEBUG_ASSERT` there. -/// -/// The macro will expand to an expression convertible to any type, -/// although the resulting object is invalid, -/// which doesn't matter, as the statement is unreachable anyway. -/// -/// \notes Define `DEBUG_ASSERT_DISABLE` to completely disable this macro, it -/// will expand to `DEBUG_ASSERT_MARK_UNREACHABLE`. -/// This should not be necessary, the regular version is optimized away -/// completely. -# define DEBUG_UNREACHABLE(...) \ - debug_assert::detail::do_assert(debug_assert::detail::always_false, \ - DEBUG_ASSERT_CUR_SOURCE_LOCATION, "", __VA_ARGS__) -#else -# define DEBUG_ASSERT(Expr, ...) static_cast(0) - -# define DEBUG_UNREACHABLE(...) \ - (DEBUG_ASSERT_MARK_UNREACHABLE, debug_assert::detail::regular_void()) -#endif - -#endif // DEBUG_ASSERT_HPP_INCLUDED diff --git a/third/type_safe/external/external.cmake b/third/type_safe/external/external.cmake deleted file mode 100644 index 1302f42b..00000000 --- a/third/type_safe/external/external.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2016-2019 Jonathan Müller -# This file is subject to the license terms in the LICENSE file -# found in the top-level directory of this distribution. - -find_package(debug_assert QUIET) -if(debug_assert_FOUND) - set(TYPE_SAFE_HAS_IMPORTED_TARGETS ON) -else() - set(TYPE_SAFE_HAS_IMPORTED_TARGETS OFF) - if(TARGET debug_assert) - message(STATUS "Using inherited debug_assert target") - else() - message(STATUS "Using vendored debug_assert") - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/debug_assert EXCLUDE_FROM_ALL) - endif() -endif() diff --git a/third/type_safe/include/type_safe/arithmetic_policy.hpp b/third/type_safe/include/type_safe/arithmetic_policy.hpp deleted file mode 100644 index 4ed4ac56..00000000 --- a/third/type_safe/include/type_safe/arithmetic_policy.hpp +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_ARITHMETIC_POLICY_HPP_INCLUDED -#define TYPE_SAFE_ARITHMETIC_POLICY_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#endif - -#include -#include -#include - -namespace type_safe -{ -/// An `ArithmeticPolicy` that behaves like the default integer implementations: -/// Signed under/overflow is UB, unsigned under/overflow wraps around. -/// \module types -class default_arithmetic -{ -public: - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_addition(T a, T b) noexcept - { - return a + b; - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_subtraction(T a, T b) noexcept - { - return a - b; - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_multiplication(T a, T b) noexcept - { - return a * b; - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_division(T a, T b) noexcept - { - return a / b; - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_modulo(T a, T b) noexcept - { - return a % b; - } -}; - -/// \exclude -namespace detail -{ - struct signed_integer_tag - {}; - struct unsigned_integer_tag - {}; - - template - using arithmetic_tag_for = - typename std::conditional::value, signed_integer_tag, - unsigned_integer_tag>::type; - - template - constexpr bool will_addition_error(signed_integer_tag, T a, T b) - { - return b > T(0) ? a > std::numeric_limits::max() - b - : a < std::numeric_limits::min() - b; - } - template - constexpr bool will_addition_error(unsigned_integer_tag, T a, T b) - { - return std::numeric_limits::max() - b < a; - } - - template - constexpr bool will_subtraction_error(signed_integer_tag, T a, T b) - { - return b > T(0) ? a < std::numeric_limits::min() + b - : a > std::numeric_limits::max() + b; - } - template - constexpr bool will_subtraction_error(unsigned_integer_tag, T a, T b) - { - return a < b; - } - - template - constexpr bool will_multiplication_error(signed_integer_tag, T a, T b) - { - return a > T(0) ? (b > T(0) ? a > std::numeric_limits::max() / b : // a, b > 0 - b < std::numeric_limits::min() / a) - : // a > 0, b <= 0 - (b > T(0) ? a < std::numeric_limits::min() / b : // a <= 0, b > 0 - a != T(0) && b < std::numeric_limits::max() / a); // a, b <= 0 - } - template - constexpr bool will_multiplication_error(unsigned_integer_tag, T a, T b) - { - return b != T(0) && a > std::numeric_limits::max() / b; - } - - template - constexpr bool will_division_error(signed_integer_tag, T a, T b) - { - return b == T(0) || (b == T(-1) && a == std::numeric_limits::min()); - } - template - constexpr bool will_division_error(unsigned_integer_tag, T, T b) - { - return b == T(0); - } - - template - constexpr bool will_modulo_error(signed_integer_tag, T, T b) - { - return b == T(0); - } - template - constexpr bool will_modulo_error(unsigned_integer_tag, T, T b) - { - return b == T(0); - } -} // namespace detail - -/// An `ArithmeticPolicy` where under/overflow is always undefined behavior, -/// albeit checked when assertions are enabled. -/// \module types -class undefined_behavior_arithmetic -{ -public: - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_addition(T a, T b) noexcept - { - return detail::will_addition_error(detail::arithmetic_tag_for{}, a, b) - ? DEBUG_UNREACHABLE(detail::precondition_error_handler{}, - "addition will result in overflow") - : T(a + b); - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_subtraction(T a, T b) noexcept - { - return detail::will_subtraction_error(detail::arithmetic_tag_for{}, a, b) - ? DEBUG_UNREACHABLE(detail::precondition_error_handler{}, - "subtraction will result in underflow") - : T(a - b); - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_multiplication(T a, T b) noexcept - { - return detail::will_multiplication_error(detail::arithmetic_tag_for{}, a, b) - ? DEBUG_UNREACHABLE(detail::precondition_error_handler{}, - "multiplication will result in overflow") - : T(a * b); - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_division(T a, T b) noexcept - { - return detail::will_division_error(detail::arithmetic_tag_for{}, a, b) - ? DEBUG_UNREACHABLE(detail::precondition_error_handler{}, - "division by zero/overflow") - : T(a / b); - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_modulo(T a, T b) noexcept - { - return detail::will_modulo_error(detail::arithmetic_tag_for{}, a, b) - ? DEBUG_UNREACHABLE(detail::precondition_error_handler{}, "modulo by zero") - : T(a % b); - } -}; - -/// An `ArithmeticPolicy` where under/overflow throws an exception. -/// \notes If exceptions are not supported, -/// this is will assert. -/// \module types -class checked_arithmetic -{ -public: - class error : public std::range_error - { - public: - error(const char* msg) : std::range_error(msg) - { -#if !TYPE_SAFE_USE_EXCEPTIONS - DEBUG_UNREACHABLE(detail::precondition_error_handler{}, msg); -#endif - } - }; - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_addition(T a, T b) - { - return detail::will_addition_error(detail::arithmetic_tag_for{}, a, b) - ? TYPE_SAFE_THROW(error("addition will result in overflow")), - a : a + b; - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_subtraction(T a, T b) - { - return detail::will_subtraction_error(detail::arithmetic_tag_for{}, a, b) - ? TYPE_SAFE_THROW(error("subtraction will result in underflow")), - a : a - b; - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_multiplication(T a, T b) - { - return detail::will_multiplication_error(detail::arithmetic_tag_for{}, a, b) - ? TYPE_SAFE_THROW(error("multiplication will result in overflow")), - a : a * b; - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_division(T a, T b) - { - return detail::will_division_error(detail::arithmetic_tag_for{}, a, b) - ? TYPE_SAFE_THROW(error("division by zero/overflow")), - a : a / b; - } - - template - TYPE_SAFE_FORCE_INLINE static constexpr T do_modulo(T a, T b) - { - return detail::will_modulo_error(detail::arithmetic_tag_for{}, a, b) - ? TYPE_SAFE_THROW(error("modulo by zero")), - a : a % b; - } -}; - -#if TYPE_SAFE_ARITHMETIC_POLICY == 1 -/// The default `ArithmeticPolicy`. -/// -/// It depends on the [TYPE_SAFE_ARITHMETIC_POLICY]() macro, -/// and is either [ts::undefined_behavior_arithmetic](), [ts::checked_arithmetic](), or -/// [ts::default_arithmetic](). \exclude target \module types -using arithmetic_policy_default = undefined_behavior_arithmetic; -#elif TYPE_SAFE_ARITHMETIC_POLICY == 2 -using arithmetic_policy_default = checked_arithmetic; -#else -using arithmetic_policy_default = default_arithmetic; -#endif -} // namespace type_safe - -#endif // TYPE_SAFE_ARITHMETIC_POLICY_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/boolean.hpp b/third/type_safe/include/type_safe/boolean.hpp deleted file mode 100644 index eab9789e..00000000 --- a/third/type_safe/include/type_safe/boolean.hpp +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_BOOLEAN_HPP_INCLUDED -#define TYPE_SAFE_BOOLEAN_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#include -#endif - -#include - -namespace type_safe -{ -class boolean; - -/// \exclude -namespace detail -{ - template - struct is_boolean : std::false_type - {}; - - template <> - struct is_boolean : std::true_type - {}; - - template <> - struct is_boolean : std::true_type - {}; - - template - using enable_boolean = typename std::enable_if::value>::type; -} // namespace detail - -/// A type safe boolean class. -/// -/// It is a tiny, no overhead wrapper over `bool`. -/// It can only be constructed from `bool` values -/// and does not implicitly convert to integral types. -/// \module types -class boolean -{ -public: - boolean() = delete; - - /// \effects Creates a boolean from the given `value`. - /// \notes This function does not participate in overload resolution if `T` is not a boolean - /// type. \param 1 \exclude - template > - TYPE_SAFE_FORCE_INLINE constexpr boolean(T value) noexcept : value_(value) - {} - - /// \effects Assigns the given `value` to the boolean. - /// \notes This function does not participate in overload resolution if `T` is not a boolean - /// type. \param 1 \exclude - template > - TYPE_SAFE_FORCE_INLINE boolean& operator=(T value) noexcept - { - value_ = value; - return *this; - } - - /// \returns The stored `bool` value. - TYPE_SAFE_FORCE_INLINE explicit constexpr operator bool() const noexcept - { - return value_; - } - - /// \returns The same as `!static_cast(*this)`. - TYPE_SAFE_FORCE_INLINE constexpr boolean operator!() const noexcept - { - return boolean(!value_); - } - -private: - bool value_; -}; - -//=== comparison ===// -/// [ts::boolean]() equality comparison. -/// \returns `true` if (1) both [ts::boolean]() objects have the same value, -/// (2)/(3) the boolean has the same value as the given value, -/// `false` otherwise. -/// \notes (2)/(3) do not participate in overload resolution if `T` is not a boolean type. -/// \group boolean_comp_equal -/// \module types -TYPE_SAFE_FORCE_INLINE constexpr bool operator==(const boolean& a, const boolean& b) noexcept -{ - return static_cast(a) == static_cast(b); -} - -/// \group boolean_comp_equal -/// \param 1 -/// \exclude -template > -TYPE_SAFE_FORCE_INLINE constexpr bool operator==(const boolean& a, T b) noexcept -{ - return static_cast(a) == static_cast(b); -} - -/// \group boolean_comp_equal -/// \param 1 -/// \exclude -template > -TYPE_SAFE_FORCE_INLINE constexpr bool operator==(T a, const boolean& b) noexcept -{ - return static_cast(a) == static_cast(b); -} - -/// [ts::boolean]() in-equality comparison. -/// \returns `false` if (1) both [ts::boolean]() objects have the same value, -/// (2)/(3) the boolean has the same value as the given value, -/// `true` otherwise. -/// \notes (2)/(3) do not participate in overload resolution if `T` is not a boolean type. -/// \group boolean_comp_unequal -/// \module types -TYPE_SAFE_FORCE_INLINE constexpr bool operator!=(const boolean& a, const boolean& b) noexcept -{ - return static_cast(a) != static_cast(b); -} - -/// \group boolean_comp_unequal -/// \param 1 -/// \exclude -template > -TYPE_SAFE_FORCE_INLINE constexpr bool operator!=(const boolean& a, T b) noexcept -{ - return static_cast(a) != static_cast(b); -} - -/// \group boolean_comp_unequal -/// \param 1 -/// \exclude -template > -TYPE_SAFE_FORCE_INLINE constexpr bool operator!=(T a, const boolean& b) noexcept -{ - return static_cast(a) != static_cast(b); -} - -//=== input/output ===/ -/// [ts::boolean]() input operator. -/// \effects Reads a `bool` from the [std::istream]() and assigns it to the given [ts::boolean](). -/// \output_section Input/output -/// \module types -template -std::basic_istream& operator>>(std::basic_istream& in, - boolean& b) -{ - bool val; - in >> val; - b = val; - return in; -} - -/// [ts::boolean]() output operator. -/// \effects Converts the given [ts::boolean]() to `bool` and writes it to the [std::ostream](). -/// \module types -template -std::basic_ostream& operator<<(std::basic_ostream& out, - const boolean& b) -{ - return out << static_cast(b); -} - -//=== comparison functors ===// -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_PREDICATE(Name, Op) \ - struct Name \ - { \ - using is_transparent = int; \ - \ - template \ - constexpr bool operator()(T1&& a, T2&& b) const \ - noexcept(noexcept(std::forward(a) Op std::forward(b))) \ - { \ - return static_cast(std::forward(a) Op std::forward(b)); \ - } \ - }; - -/// Comparison functors similar to the `std::` version, -/// but explicitly cast the result of the comparison to `bool`. -/// -/// This allows using types where the comparison operator returns [ts::boolean](), -/// as it can not be implicitly converted to `bool` -/// so, for example, [std::less]() can not be used. -/// \notes These comparison functors are always transparent, -/// i.e. can be used with two different types. -/// \group comparison_functors Comparison function objects -/// \module types -TYPE_SAFE_DETAIL_MAKE_PREDICATE(equal_to, ==) -/// \group comparison_functors -TYPE_SAFE_DETAIL_MAKE_PREDICATE(not_equal_to, !=) -/// \group comparison_functors -TYPE_SAFE_DETAIL_MAKE_PREDICATE(less, <) -/// \group comparison_functors -TYPE_SAFE_DETAIL_MAKE_PREDICATE(less_equal, <=) -/// \group comparison_functors -TYPE_SAFE_DETAIL_MAKE_PREDICATE(greater, >) -/// \group comparison_functors -TYPE_SAFE_DETAIL_MAKE_PREDICATE(greater_equal, >=) - -#undef TYPE_SAFE_DETAIL_MAKE_PREDICATE -} // namespace type_safe - -namespace std -{ -/// Hash specialization for [ts::boolean](). -/// \module types -template <> -struct hash -{ - std::size_t operator()(type_safe::boolean b) const noexcept - { - return std::hash()(static_cast(b)); - } -}; -} // namespace std - -#endif // TYPE_SAFE_BOOLEAN_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/bounded_type.hpp b/third/type_safe/include/type_safe/bounded_type.hpp deleted file mode 100644 index 3472caae..00000000 --- a/third/type_safe/include/type_safe/bounded_type.hpp +++ /dev/null @@ -1,567 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_BOUNDED_TYPE_HPP_INCLUDED -#define TYPE_SAFE_BOUNDED_TYPE_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#endif - -#include -#include - -namespace type_safe -{ -namespace constraints -{ - /// Tag type to enable a dynamic bound. - struct dynamic_bound - {}; - - /// \exclude - namespace detail - { - // Base to enable empty base optimization when Bound is not dynamic_bound. - // Necessary when T is not a class. - template - struct wrapper - { - using value_type = T; - T value; - }; - - template - struct is_dynamic : std::is_same - {}; - - template - struct select_bound; - - template - struct select_bound - { - using type = wrapper; - }; - - template - struct select_bound - { - static_assert( - std::is_convertible() < Bound::value), bool>::value, - "static bound has wrong type"); - using type = Bound; - }; - - template - using base = typename select_bound::value, T, Bound>::type; - } // namespace detail - -// clang-format off -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE(Name, Op) \ - template \ - class Name : detail::base \ - { \ - static constexpr bool is_dynamic = detail::is_dynamic::value; \ - \ - using base = detail::base; \ - using arg_type = typename std::conditional::type; \ - \ - public: \ - using value_type = decltype(base::value); \ - using bound_type = Bound; \ - \ - /** Initializes it with a static bound. - * \effects Does nothing, a static bound is not stored. - * It will use `Bound::value` as the bound. - * \notes This constructor only participates in overload resolution, - * if a static bound is used, i.e. `Bound` is not [ts::constraints::dynamic_bound](). - * \param Condition - * \exclude - * \param 1 - * \exclude */ \ - template ::type> \ - constexpr Name(Bound = {}) \ - { \ - } \ - \ - /** Initializes it with a dynamic bound. - * \effects Copies (1)/moves (2) the object and uses that as bound. - * \notes These constructors only participate in overload resolution, - * if a dynamic bound is used, i.e. `Bound` is [ts::constraints::dynamic_bound](). - * \group dynamic_ctor - * \param Condition - * \exclude - * \param 1 - * \exclude */ \ - template ::type> \ - explicit constexpr Name(const T& bound) : base{bound} \ - { \ - } \ - \ - /** \group dynamic_ctor - * \param Condition - * \exclude - * \param 1 - * \exclude */ \ - template ::type> \ - explicit constexpr Name(T&& bound) noexcept(std::is_nothrow_move_constructible::value) \ - : base{std::move(bound)} \ - { \ - } \ - \ - /** Does the actual bounds check.*/ \ - template \ - constexpr bool operator()(const U& u) const \ - { \ - return u Op get_bound(); \ - } \ - \ - /** \returns The bound.*/ \ - constexpr const value_type& get_bound() const noexcept \ - { \ - return base::value; \ - } \ - }; - // clang-format on - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value is valid if it is less than some given value. - TYPE_SAFE_DETAIL_MAKE(less, <) - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value is valid if it is less than or equal to some given value. - TYPE_SAFE_DETAIL_MAKE(less_equal, <=) - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value is valid if it is greater than some given value. - TYPE_SAFE_DETAIL_MAKE(greater, >) - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value is valid if it is greater than or equal to some given value. - TYPE_SAFE_DETAIL_MAKE(greater_equal, >=) - -#undef TYPE_SAFE_DETAIL_MAKE - - /// \exclude - namespace detail - { - // checks that that the value is less than the upper bound - template - using upper_bound_t = - typename std::conditional, less>::type; - - // checks that the value is greater than the lower bound - template - using lower_bound_t = - typename std::conditional, greater>::type; - } // namespace detail - - /// Tag objects to specify bounds for [ts::constraints::bounded](). - /// \group open_closed Open/Closed Tags - constexpr bool open = false; - /// \group open_closed - constexpr bool closed = true; - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value is valid if it is between two given bounds, - /// `LowerInclusive`/`UpperInclusive` control whether the lower/upper bound itself is valid too. - template - class bounded : detail::lower_bound_t, - detail::upper_bound_t - { - static constexpr bool lower_is_dynamic = detail::is_dynamic::value; - static constexpr bool upper_is_dynamic = detail::is_dynamic::value; - - using lower_type = detail::lower_bound_t; - using upper_type = detail::upper_bound_t; - - constexpr const lower_type& lower() const noexcept - { - return static_cast(*this); - } - constexpr const upper_type& upper() const noexcept - { - return static_cast(*this); - } - - template - using decay_same = std::is_same::type, T>; - - public: - using value_type = T; - using lower_bound = LowerBound; - using upper_bound = UpperBound; - - static constexpr auto lower_inclusive = LowerInclusive; - static constexpr auto upper_inclusive = UpperInclusive; - - /// Initializes it with static bounds. - /// \effects Does nothing, a static bound is not stored. - /// It will use `LowerBound::value` as lower bound and `UpperBound::value` as upper bound. - /// \notes This constructor does not participate in overload resolution, - /// unless both bounds are static, - /// i.e. not [ts::constraints::dynamic_bound](). - /// \param Condition - /// \exclude - /// \param 1 - /// \exclude - template ::type> - constexpr bounded() - {} - - /// Initializes it with (mixed) dynamic bounds. - /// \effects Perfectly forwards the arguments to the bounds. - /// If a bound is static, the static member `value` will be used as bound, - /// if it is dynamic, a copy created by perfectly forwarding will be stored and used as - /// bound. \notes This constructor does not participate in overload resolution, unless the - /// arguments are convertible to the bounds. \param 2 \exclude \param 3 \exclude - template - explicit constexpr bounded(U1&& lower, U2&& upper, - decltype(lower_type(std::forward(lower)), 0) = 0, - decltype(upper_type(std::forward(upper)), 0) = 0) - : lower_type(std::forward(lower)), upper_type(std::forward(upper)) - {} - - /// Does the bounds check. - template - constexpr bool operator()(const U& u) const - { - return lower()(u) && upper()(u); - } - - /// \returns The value of the lower bound. - constexpr const typename lower_type::value_type& get_lower_bound() const noexcept - { - return lower().get_bound(); - } - - /// \returns The value of the upper bound. - constexpr const typename upper_type::value_type& get_upper_bound() const noexcept - { - return upper().get_bound(); - } - }; - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value is valid if it is between two given bounds but not the bounds themselves. - template - using open_interval = bounded; - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value is valid if it is between two given bounds or the bounds themselves. - template - using closed_interval = bounded; -} // namespace constraints - -/// \exclude -namespace detail -{ - template - struct valid_bound : std::integral_constant - {}; - - template - struct bounded_type_impl - { - static_assert(valid_bound::value && valid_bound::value, - "make_bounded() called with mismatched types"); - - using value_type = T; - using lower_constant = U1; - using upper_constant = U2; - - using type - = constrained_type, - Verifier>; - }; - - template - struct bounded_type_impl - { - using value_type = T; - using lower_constant = constraints::dynamic_bound; - using upper_constant = constraints::dynamic_bound; - - using type - = constrained_type, - Verifier>; - }; - - template - struct bounded_type_impl - { - static_assert(valid_bound::value, - "make_bounded() called with mismatched types"); - - using value_type = T; - using lower_constant = constraints::dynamic_bound; - using upper_constant = UpperBound; - - using type - = constrained_type, - Verifier>; - }; - - template - struct bounded_type_impl - { - static_assert(valid_bound::value, - "make_bounded() called with mismatched types"); - - using value_type = T; - using lower_constant = LowerBound; - using upper_constant = constraints::dynamic_bound; - - using type - = constrained_type, - Verifier>; - }; - - template - using make_bounded_type = - typename bounded_type_impl::type, typename std::decay::type, - typename std::decay::type>::type; -} // namespace detail - -/// An alias for [ts::constrained_type]() that uses [ts::constraints::bounded]() as its -/// `Constraint`. \notes This is some type where the values must be in a certain interval. -template -using bounded_type = constrained_type< - T, constraints::bounded, Verifier>; - -inline namespace literals -{ - /// \exclude - namespace lit_detail - { - template - struct integer_bound - { - static constexpr T value = Value; - }; - - template - constexpr T integer_bound::value; - - template - constexpr auto operator-(integer_bound) noexcept - -> integer_bound - { - static_assert(std::is_signed::value, "must be a signed integer type"); - return {}; - } - } // namespace lit_detail - - /// Creates a static bound for [ts::bounded_type](). - /// - /// This is a bound encapsulated in the type, so there is no overhead. - /// You can use it for example like this `ts::make_bounded(50, 0_bound, 100_bound)`, - /// to bound an integer between `0` and `100`. - /// \returns A type representing the given value, - /// the value has type `long long` (1)/`unsigned long long`(2). - /// \group bound_lit - template - constexpr auto operator"" _bound() - -> lit_detail::integer_bound()> - { - return {}; - } - - /// \group bound_lit - template - constexpr auto operator"" _boundu() - -> lit_detail::integer_bound()> - { - return {}; - } -} // namespace literals - -/// Creates a [ts::bounded_type]() to a specified [ts::constraints::closed_interval](). -/// \returns A [ts::bounded_type]() with the given `value` and lower and upper bounds, -/// where the bounds are valid values as well. -/// \requires As it uses [ts::assertion_verifier](), -/// the value must be valid. -/// \notes If this function is passed in dynamic values of the same type as `value`, -/// it will create a dynamic bound. -/// Otherwise it must be passed static bounds. -template -constexpr auto make_bounded(T&& value, U1&& lower, U2&& upper) - -> detail::make_bounded_type -{ - using result_type = detail::make_bounded_type; - return result_type(std::forward(value), - typename result_type::constraint_predicate(std::forward(lower), - std::forward(upper))); -} - -/// Creates a [ts::bounded_type]() to a specified [ts::constraints::closed_interval](). -/// \returns A [ts::bounded_type]() with the given `value` and lower and upper bounds, -/// where the bounds are valid values as well. -/// \throws A [ts::constrain_error]() if the `value` isn't valid, -/// or anything else thrown by the constructor. -/// \notes This is meant for sanitizing user input, -/// using a recoverable error handling strategy. -/// \notes If this function is passed in dynamic values of the same type as `value`, -/// it will create a dynamic bound. -/// Otherwise it must be passed static bounds. -template -constexpr auto sanitize_bounded(T&& value, U1&& lower, U2&& upper) - -> detail::make_bounded_type -{ - using result_type = detail::make_bounded_type; - return result_type(std::forward(value), - typename result_type::constraint_predicate(std::forward(lower), - std::forward(upper))); -} - -/// Creates a [ts::bounded_type]() to a specified [ts::constraints::open_interval](). -/// \returns A [ts::bounded_type]() with the given `value` and lower and upper bounds, -/// where the bounds are not valid values. -/// \requires As it uses [ts::assertion_verifier](), -/// the value must be valid. -/// \notes If this function is passed in dynamic values of the same type as `value`, -/// it will create a dynamic bound. -/// Otherwise it must be passed static bounds. -template -constexpr auto make_bounded_exclusive(T&& value, U1&& lower, U2&& upper) - -> detail::make_bounded_type -{ - using result_type = detail::make_bounded_type; - return result_type(std::forward(value), - typename result_type::constraint_predicate(std::forward(lower), - std::forward(upper))); -} - -/// Creates a [ts::bounded_type]() to a specified [ts::constraints::open_interval](), -/// using [ts::throwing_verifier](). -/// \returns A [ts::bounded_type]() with the given `value` and lower and upper bounds, -/// where the bounds are not valid values. -/// \throws A [ts::constrain_error]() if the `value` isn't valid, -/// or anything else thrown by the constructor. -/// \notes This is meant for sanitizing user input, -/// using a recoverable error handling strategy. -/// \notes If this function is passed in dynamic values of the same type as `value`, -/// it will create a dynamic bound. -/// Otherwise it must be passed static bounds. -template -constexpr auto sanitize_bounded_exclusive(T&& value, U1&& lower, U2&& upper) - -> detail::make_bounded_type -{ - using result_type = detail::make_bounded_type; - return result_type(std::forward(value), - typename result_type::constraint_predicate(std::forward(lower), - std::forward(upper))); -} - -/// Returns a copy of `val` so that it is in the given [ts::constraints::closed_interval](). -/// \effects If it is not in the interval, returns the bound that is closer to the value. -/// \output_section clamped_type -template -constexpr auto clamp(const constraints::closed_interval& interval, - U&& val) -> typename std::decay::type -{ - return val < interval.get_lower_bound() - ? static_cast::type>(interval.get_lower_bound()) - : (val > interval.get_upper_bound() - ? static_cast::type>(interval.get_upper_bound()) - : std::forward(val)); -} - -/// A `Verifier` for [ts::constrained_type]() that clamps the value to make it valid. -/// -/// It must be used together with [ts::constraints::less_equal](), -/// [ts::constraints::greater_equal]() or [ts::constraints::closed_interval](). -struct clamping_verifier -{ - /// \returns If `val` is greater than the bound of `p`, - /// returns the bound. - /// Otherwise returns the value unchanged - template - static constexpr auto verify(Value&& val, const constraints::less_equal& p) -> - typename std::decay::type - { - return p(val) ? std::forward(val) - : static_cast::type>(p.get_bound()); - } - - /// \returns If `val` is less than the bound of `p`, - /// returns the bound. - /// Otherwise returns the value unchanged - template - static constexpr auto verify(Value&& val, const constraints::greater_equal& p) -> - typename std::decay::type - { - return p(val) ? std::forward(val) - : static_cast::type>(p.get_bound()); - } - - /// \returns Same as `clamp(interval, val)`. - template - static constexpr auto verify( - Value&& val, const constraints::closed_interval& interval) -> - typename std::decay::type - { - return clamp(interval, std::forward(val)); - } -}; - -/// An alias for [ts::constrained_type]() that uses [ts::constraints::closed_interval]() as its -/// `Constraint` and [ts::clamping_verifier]() as its `Verifier`. \notes This is some type where the -/// values are always clamped so that they are in a certain interval. -template -using clamped_type = constrained_type, - clamping_verifier>; - -/// Creates a [ts::clamped_type]() from the specified [ts::constraints::closed_interval](). -/// \returns A [ts::clamped_type]() with the given `value` and lower and upper bounds, -/// where the bounds are valid values. -/// \notes If this function is passed in dynamic values of the same type as `value`, -/// it will create a dynamic bound. -/// Otherwise it must be passed static bounds. -template -constexpr auto make_clamped(T&& value, U1&& lower, U2&& upper) - -> detail::make_bounded_type -{ - using result_type = detail::make_bounded_type; - return result_type(std::forward(value), - typename result_type::constraint_predicate(std::forward(lower), - std::forward(upper))); -} -} // namespace type_safe - -#endif // TYPE_SAFE_BOUNDED_TYPE_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/compact_optional.hpp b/third/type_safe/include/type_safe/compact_optional.hpp deleted file mode 100644 index 149d88b0..00000000 --- a/third/type_safe/include/type_safe/compact_optional.hpp +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_COMPACT_OPTIONAL_HPP_INCLUDED -#define TYPE_SAFE_COMPACT_OPTIONAL_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#endif - -#include - -namespace type_safe -{ -/// \exclude -namespace detail -{ - template - using storage_reference = - typename std::conditional::value, T, ValueType>::type; -} // namespace detail - -/// A `StoragePolicy` for [ts::basic_optional]() that is more space efficient than -/// [ts::direct_optional_storage](). -/// -/// It is designed to have no space overhead compared to a regular object of the stored type. -/// This is accomplished by marking one value of the stored type as invalid -/// and using that in the empty state. -/// What the invalid value is is controlled by the `CompactPolicy`. -/// It must provide the following `static` member functions and typedefs: -/// * `value_type` - the value that is being stored conceptually -/// * `storage_type` - the actual type that is being stored -/// * `storage_type invalid_value()` - returns the value that marks the optional as empty -/// * `bool is_invalid(const storage_type&)` - returns `true` if the given value is invalid, `false` -/// otherwise -/// -/// In the cases where `value_type` and `storage_type` differ, -/// the `get_value()` functions will not return references, but a copy instead. -/// The implementation assumes that `invalid_value()` and `is_invalid()` are `noexcept` and cheap. -/// \notes For a compact optional of pointer type, -/// use [ts::optional_ref](). -/// \module optional -template -class compact_optional_storage -{ -public: - using value_type = typename std::remove_cv::type; - static_assert(!std::is_reference::value, - "value_type must not be a reference; use optional_ref for that"); - using storage_type = typename CompactPolicy::storage_type; - - using lvalue_reference = detail::storage_reference; - using const_lvalue_reference - = detail::storage_reference; - - using rvalue_reference = detail::storage_reference; - using const_rvalue_reference - = detail::storage_reference; - - template - using rebind = direct_optional_storage; - - /// \effects Initializes it in the state without value, - /// i.e. sets the storage to the invalid value. - compact_optional_storage() noexcept : storage_(CompactPolicy::invalid_value()) {} - - /// \effects Creates a temporary `value_type` by perfectly forwarding `args`, - /// converts that to the `storage_type` and assigns it. - /// Afterwards `has_value()` will return `true`. - /// \throws Anything thrown by the constructor of `value_type`/`storage_type` or its move - /// assignment operator in which case `has_value()` is still `false`. \requires `has_value() == - /// false` and the given value must not be invalid. \notes This function does not participate in - /// overload resolution unless `value_type` is constructible from `args`. \synopsis template - /// \\nvoid create_value(Args&&... args); - template - auto create_value(Args&&... args) -> - typename std::enable_if::value>::type - { - storage_ = static_cast(value_type(std::forward(args)...)); - DEBUG_ASSERT(has_value(), detail::precondition_error_handler{}, - "create_value() called creating an invalid value"); - } - - /// \effects Copy assigns the `storage_type`. - void create_value(const compact_optional_storage& other) - { - storage_ = other.storage_; - } - - /// \effects Move assigns the `storage_type`. - void create_value(compact_optional_storage&& other) - { - storage_ = std::move(other.storage_); - } - - void create_value_explicit() {} - - /// \effects Copy assigns the `storage_type`. - void copy_value(const compact_optional_storage& other) - { - storage_ = other.storage_; - } - - /// \effects Move assigns the `storage_type`. - void copy_value(compact_optional_storage&& other) - { - storage_ = std::move(other.storage_); - } - - /// \effects Swaps the `storage_type`. - void swap_value(compact_optional_storage& other) - { - using std::swap; - swap(storage_, other.storage_); - } - - /// \effects Destroys the value by setting it to the invalid storage value. - /// Afterwards `has_value()` will return `false`. - /// \requires `has_value() == true`. - void destroy_value() noexcept - { - storage_ = CompactPolicy::invalid_value(); - } - - /// \returns Whether or not there is a value stored, - /// i.e. whether the stored value is not invalid. - bool has_value() const noexcept - { - return !CompactPolicy::is_invalid(storage_); - } - - /// \returns A (suitable) reference to the stored value - /// or a copy of the value depending on the policy. - /// \requires `has_value() == true`. - /// \group get_value - lvalue_reference get_value() TYPE_SAFE_LVALUE_REF noexcept - { - return static_cast(storage_); - } - - /// \group get_value - const_lvalue_reference get_value() const TYPE_SAFE_LVALUE_REF noexcept - { - return static_cast(storage_); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group get_value - rvalue_reference get_value() && noexcept - { - return static_cast(storage_); - } - - /// \group get_value - const_rvalue_reference get_value() const&& noexcept - { - return static_cast(storage_); - } -#endif - - /// \returns Either `get_value()` or `u` converted to `value_type`. - /// \requires `value_type` must be copy (1)/move (2) constructible and `u` convertible to - /// `value_type`. \group get_value_or \param 1 \exclude - template ::value - && std::is_convertible::value>::type> - value_type get_value_or(U&& u) const TYPE_SAFE_LVALUE_REF - { - return has_value() ? get_value() : static_cast(std::forward(u)); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group get_value_or - /// \param 1 - /// \exclude - template ::value - && std::is_convertible::value>::type> - value_type get_value_or(U&& u) && - { - return has_value() ? std::move(get_value()) : static_cast(std::forward(u)); - } -#endif - -private: - storage_type storage_; -}; - -/// An alias for [ts::basic_optional]() using [ts::compact_optional_storage]() with the given -/// `CompactPolicy`. \module optional -template -using compact_optional = basic_optional>; - -/// A `CompactPolicy` for [ts::compact_optional_storage]() for boolean types. -/// -/// It is designed for either `bool` or [ts::boolean](). -/// \notes It uses a different `storage_type` and thus cannot return a reference to the stored -/// value. \module optional -template -class compact_bool_policy -{ -public: - using value_type = Boolean; - using storage_type = char; - - static storage_type invalid_value() noexcept - { - return 3; - } - - static bool is_invalid(storage_type storage) noexcept - { - return storage == invalid_value(); - } -}; - -/// A `CompactPolicy` for [ts::compact_optional_storage]() for integer types. -/// -/// The given `Invalid` value will be used to mark an empty optional. -template -class compact_integer_policy -{ - static_assert(std::is_integral::value, "must be an integral value"); - -public: - using value_type = Integer; - using storage_type = Integer; - - static storage_type invalid_value() noexcept - { - return Invalid; - } - - static bool is_invalid(const storage_type& storage) noexcept - { - return storage == Invalid; - } -}; - -/// A `CompactPolicy` for [ts::compact_optional_storage]() for floating point types. -/// -/// `NaN` will be used to mark an empty optional. -/// \module optional -template -class compact_floating_point_policy -{ - static_assert(std::is_floating_point::value, "must be a floating point"); - -public: - using value_type = FloatingPoint; - using storage_type = FloatingPoint; - - static storage_type invalid_value() noexcept - { - return std::numeric_limits::quiet_NaN(); - } - - static bool is_invalid(const storage_type& storage) noexcept - { - // NaN is not equal to anything - return storage != storage; - } -}; - -/// \exclude -namespace compact_enum_detail -{ - template - struct underlying_type_impl - { - static_assert(std::is_enum::value, "must be an enumeration type"); - using type = typename std::underlying_type::type; - }; - - template - using underlying_type = typename underlying_type_impl::type; -} // namespace compact_enum_detail - -/// A `CompactPolicy` for [ts::compact_optional_storage]() for enumeration types. -/// -/// It uses the given `Invalid` value of the underlying type to mark an empty optional. -/// \notes It uses a different `storage_type` and thus cannot return a reference to the stored -/// value. \module optional -template Invalid> -class compact_enum_policy -{ -public: - using value_type = Enum; - using storage_type = compact_enum_detail::underlying_type; - - static storage_type invalid_value() noexcept - { - return Invalid; - } - - static bool is_invalid(const storage_type& storage) noexcept - { - return storage == Invalid; - } -}; - -/// \exclude -namespace detail -{ - template - auto is_empty(int, const Container& c) -> decltype(c.empty()) - { - return c.empty(); - } - - template - auto is_empty(short, const Container& c) -> decltype(empty(c)) - { - return empty(c); - } -} // namespace detail - -/// A `CompactPolicy` for [ts::compact_optional_storage]() for container types. -/// -/// A `Container` is a type with a cheap no-throwing default constructor initializing it empty, -/// and either an `empty()` member function or ADL function that returns `true` if the container is -/// empty, `false` otherwise. An empty container will be marked as an empty optional. \module -/// optional -template -class compact_container_policy -{ -public: - using value_type = Container; - using storage_type = Container; - - static storage_type invalid_value() noexcept - { - return {}; - } - - static bool is_invalid(const storage_type& storage) noexcept - { - return static_cast(detail::is_empty(0, storage)); - } -}; -} // namespace type_safe - -#endif // TYPE_SAFE_COMPACT_OPTIONAL_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/config.hpp b/third/type_safe/include/type_safe/config.hpp deleted file mode 100644 index cdb41866..00000000 --- a/third/type_safe/include/type_safe/config.hpp +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_CONFIG_HPP_INCLUDED -#define TYPE_SAFE_CONFIG_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#endif - -#ifndef TYPE_SAFE_ENABLE_ASSERTIONS -/// Controls whether internal assertions are enabled. -/// -/// It is disabled by default. -# define TYPE_SAFE_ENABLE_ASSERTIONS 0 -#endif - -#ifndef TYPE_SAFE_ENABLE_PRECONDITION_CHECKS -/// Controls whether preconditions are checked. -/// -/// It is enabled by default. -# define TYPE_SAFE_ENABLE_PRECONDITION_CHECKS 1 -#endif - -#ifndef TYPE_SAFE_ENABLE_WRAPPER -/// Controls whether the typedefs in [types.hpp]() use the type safe wrapper types. -/// -/// It is enabled by default. -# define TYPE_SAFE_ENABLE_WRAPPER 1 -#endif - -#ifndef TYPE_SAFE_ARITHMETIC_POLICY -/// Controls whether [ts::arithmetic_policy_default]() is [ts::undefined_behavior_arithmetic](), -/// [ts::checked_arithmetic](), or [ts::default_arithmetic](). -/// -/// It is [ts::undefined_behavior_arithmetic]() by default. -# define TYPE_SAFE_ARITHMETIC_POLICY 1 -#endif - -#ifndef TYPE_SAFE_DELETE_FUNCTIONS -# if defined(_MSC_VER) && _MSC_VER < 1914 -# define TYPE_SAFE_DELETE_FUNCTIONS 0 -# else -/// \exclude -# define TYPE_SAFE_DELETE_FUNCTIONS 0 -# endif -#endif - -#ifndef TYPE_SAFE_USE_REF_QUALIFIERS -# if defined(__cpp_ref_qualifiers) && __cpp_ref_qualifiers >= 200710 -/// \exclude -# define TYPE_SAFE_USE_REF_QUALIFIERS 1 -# elif defined(_MSC_VER) && _MSC_VER >= 1900 -# define TYPE_SAFE_USE_REF_QUALIFIERS 1 -# else -# define TYPE_SAFE_USE_REF_QUALIFIERS 0 -# endif -#endif - -#if TYPE_SAFE_USE_REF_QUALIFIERS -/// \exclude -# define TYPE_SAFE_LVALUE_REF & -/// \exclude -# define TYPE_SAFE_RVALUE_REF && -#else -# define TYPE_SAFE_LVALUE_REF -# define TYPE_SAFE_RVALUE_REF -#endif - -#ifndef TYPE_SAFE_USE_RETURN_TYPE_DEDUCTION -# if defined(__cpp_return_type_deduction) && __cpp_return_type_deduction >= 201304 -/// \exclude -# define TYPE_SAFE_USE_RETURN_TYPE_DEDUCTION 1 -# elif defined(_MSC_VER) && _MSC_VER >= 1900 -# define TYPE_SAFE_USE_RETURN_TYPE_DEDUCTION 1 -# else -# define TYPE_SAFE_USE_RETURN_TYPE_DEDUCTION 0 -# endif -#endif - -#ifndef TYPE_SAFE_USE_NOEXCEPT_DEFAULT - -# if defined(__GNUC__) && __GNUC__ < 5 -// GCC before 5.0 doesn't handle noexcept and = default properly -/// \exclude -# define TYPE_SAFE_USE_NOEXCEPT_DEFAULT 0 -# else -/// \exclude -# define TYPE_SAFE_USE_NOEXCEPT_DEFAULT 1 -# endif - -#endif - -#if TYPE_SAFE_USE_NOEXCEPT_DEFAULT -/// \exclude -# define TYPE_SAFE_NOEXCEPT_DEFAULT(Val) noexcept(Val) -#else -/// \exclude -# define TYPE_SAFE_NOEXCEPT_DEFAULT(Val) -#endif - -#ifndef TYPE_SAFE_USE_CONSTEXPR14 - -# if defined(__cpp_constexpr) && __cpp_constexpr >= 201304 -/// \exclude -# define TYPE_SAFE_USE_CONSTEXPR14 1 -# else -/// \exclude -# define TYPE_SAFE_USE_CONSTEXPR14 0 -# endif - -#endif - -#if TYPE_SAFE_USE_CONSTEXPR14 -/// \exclude -# define TYPE_SAFE_CONSTEXPR14 constexpr -#else -/// \exclude -# define TYPE_SAFE_CONSTEXPR14 -#endif - -#ifndef TYPE_SAFE_USE_EXCEPTIONS - -# if __cpp_exceptions -/// \exclude -# define TYPE_SAFE_USE_EXCEPTIONS 1 -# elif defined(__GNUC__) && defined(__EXCEPTIONS) -/// \exclude -# define TYPE_SAFE_USE_EXCEPTIONS 1 -# elif defined(_MSC_VER) && defined(_CPPUNWIND) -/// \exclude -# define TYPE_SAFE_USE_EXCEPTIONS 1 -# else -/// \exclude -# define TYPE_SAFE_USE_EXCEPTIONS 0 -# endif - -#endif - -#if TYPE_SAFE_USE_EXCEPTIONS -/// \exclude -# define TYPE_SAFE_THROW(Ex) throw Ex -/// \exclude -# define TYPE_SAFE_TRY try -/// \exclude -# define TYPE_SAFE_CATCH_ALL catch (...) -/// \exclude -# define TYPE_SAFE_RETHROW throw -#else - -/// \exclude -namespace type_safe -{ -namespace detail -{ - void on_disabled_exception() noexcept; -} -} // namespace type_safe - -# define TYPE_SAFE_THROW(Ex) (Ex, type_safe::detail::on_disabled_exception()) -# define TYPE_SAFE_TRY if (true) -# define TYPE_SAFE_CATCH_ALL if (false) -# define TYPE_SAFE_RETHROW type_safe::detail::on_disabled_exception() -#endif - -#ifndef TYPE_SAFE_USE_RTTI - -# ifdef __GXX_RTTI -# define TYPE_SAFE_USE_RTTI 1 -# elif defined(_CPPRTTI_) -# define TYPE_SAFE_USE_RTTI 1 -# else -# define TYPE_SAFE_USE_RTTI 0 -# endif - -#endif - -/// \entity type_safe -/// \unique_name ts - -#endif // TYPE_SAFE_CONFIG_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/constrained_type.hpp b/third/type_safe/include/type_safe/constrained_type.hpp deleted file mode 100644 index d01f36c8..00000000 --- a/third/type_safe/include/type_safe/constrained_type.hpp +++ /dev/null @@ -1,625 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_CONSTRAINED_TYPE_HPP_INCLUDED -#define TYPE_SAFE_CONSTRAINED_TYPE_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#include -#endif - -#include -#include -#include - -namespace type_safe -{ -//=== constrained_type ===// -/// A `Verifier` for [ts::constrained_type]() that `DEBUG_ASSERT`s the constraint. -/// -/// If [TYPE_SAFE_ENABLE_PRECONDITION_CHECKS]() is `true`, -/// it will assert that the value fulfills the predicate and returns it unchanged. -/// If assertions are disabled, it will just return the value unchanged. -/// \output_section Constrained type -struct assertion_verifier -{ - template - static constexpr auto verify(Value&& val, const Predicate& p) -> - typename std::decay::type - { - return p(val) ? std::forward(val) - : (DEBUG_UNREACHABLE(detail::precondition_error_handler{}, - "value does not fulfill constraint"), - std::forward(val)); - } -}; - -/// The exception class thrown by the [ts::throwing_verifier](). -class constrain_error : public std::logic_error -{ -public: - constrain_error() - : std::logic_error("Constraint of type_safe::constrained_type wasn't fulfilled") - {} -}; - -/// A `Verifier` for [ts::constrained_type]() that throws an exception in case of failure. -/// -/// Unlike [ts::assertion_verifier](), it will *always* check the constrain. -/// If it is not fulfilled, it throws an exception of type [ts::constrain_error](), -/// otherwise return the original value unchanged. -/// \notes [ts::assertion_verifier]() is the default, -/// because a constrain violation is a logic error, -/// usually done by a programmer. -/// Use this one only if you want to use [ts::constrained_type]() -/// with unsanitized user input, for example. -struct throwing_verifier -{ - template - static constexpr auto verify(Value&& val, const Predicate& p) -> - typename std::decay::type - { - return p(val) ? std::forward(val) - : (TYPE_SAFE_THROW(constrain_error{}), std::forward(val)); - } -}; - -/// \exclude -namespace detail -{ - template - auto verify_static_constrained(int) -> typename Constraint::template is_valid; - - template - auto verify_static_constrained(char) -> std::true_type; - - template - struct is_valid : decltype(verify_static_constrained(0)) - {}; -} // namespace detail - -template -class constrained_modifier; - -/// A value of type `T` that always fulfills the predicate `Constraint`. -/// -/// The `Constraint` is checked by the `Verifier`. -/// The `Constraint` can also provide a nested template `is_valid` to statically check types. -/// Those will be checked regardless of the `Verifier`. -/// -/// If `T` is `const`, the `modify()` function will not be available, -/// you can only modify the type by assigning a completely new value to it. -/// \requires `T` must not be a reference, `Constraint` must be a moveable, non-final class where no -/// operation throws, and `Verifier` must provide a `static` function `[const] T[&] verify(const T&, -/// const Predicate&)`. The return value is stored and it must always fulfill the predicate. It also -/// requires that no `const` operation on `T` may modify it in a way that the predicate isn't -/// fulfilled anymore. \notes Additional requirements of the `Constraint` depend on the `Verifier` -/// used. If not stated otherwise, a `Verifier` in this library requires that the `Constraint` is a -/// `Predicate` for `T`. -template -class constrained_type : Constraint -{ -public: - using value_type = typename std::remove_cv::type; - using constraint_predicate = Constraint; - - /// \effects Creates it giving it a valid `value` and a `predicate`. - /// The `value` will be copied(1)/moved(2) and verified. - /// \throws Anything thrown by the copy(1)/move(2) constructor of `value_type` - /// or the `Verifier` if the `value` is invalid. - /// \group value_ctor - explicit constexpr constrained_type(const value_type& value, - constraint_predicate predicate = {}) - : Constraint(std::move(predicate)), value_(Verifier::verify(value, get_constraint())) - {} - - /// \group value_ctor - explicit constexpr constrained_type( - value_type&& value, - constraint_predicate predicate - = {}) noexcept(std::is_nothrow_constructible:: - value&& noexcept(Verifier::verify(std::move(value), - std::move(predicate)))) - : Constraint(std::move(predicate)), value_(Verifier::verify(std::move(value), get_constraint())) - {} - - /// \exclude - template ::value>::type> - constrained_type(U) = delete; - - /// \effects Copies the value and predicate of `other`. - /// \throws Anything thrown by the copy constructor of `value_type`. - /// \requires `Constraint` must be copyable. - constexpr constrained_type(const constrained_type& other) - : Constraint(other), value_(other.debug_verify()) - {} - - /// \effects Destroys the value. - ~constrained_type() noexcept = default; - - /// \effects Same as assigning `constrained_type(other, get_constraint()).release()` to the - /// stored value. It will invoke copy(1)/move(2) constructor followed by move assignment - /// operator. \throws Anything thrown by the copy(1)/move(2) constructor or move assignment - /// operator of `value_type`, or the `Verifier` if the `value` is invalid. If the `value` is - /// invalid, nothing will be changed. \requires `Constraint` must be copyable. \group - /// assign_value - TYPE_SAFE_CONSTEXPR14 constrained_type& operator=(const value_type& other) - { - constrained_type tmp(other, get_constraint()); - value_ = std::move(tmp).release(); - return *this; - } - - /// \group assign_value - TYPE_SAFE_CONSTEXPR14 constrained_type& operator=(value_type&& other) noexcept( - std::is_nothrow_move_assignable::value&& noexcept( - Verifier::verify(std::move(other), std::declval()))) - { - constrained_type tmp(std::move(other), get_constraint()); - value_ = std::move(tmp).release(); - return *this; - } - - /// \exclude - template ::value>::type> - constrained_type& operator=(U) = delete; - - /// \effects Copies the value and predicate from `other`. - /// \throws Anything thrown by the copy assignment operator of `value_type`. - /// \requires `Constraint` must be copyable. - TYPE_SAFE_CONSTEXPR14 constrained_type& operator=(const constrained_type& other) - { - constrained_type tmp(other); - swap(*this, tmp); - return *this; - } - - /// \effects Swaps the value and predicate of a `a` and `b`. - /// \throws Anything thrown by the swap function of `value_type`. - /// \requires `Constraint` must be swappable. - friend TYPE_SAFE_CONSTEXPR14 void swap(constrained_type& a, constrained_type& b) noexcept( - detail::is_nothrow_swappable::value) - { - a.debug_verify(); - b.debug_verify(); - - using std::swap; - swap(a.value_, b.value_); - swap(static_cast(a), static_cast(b)); - } - - /// \returns A proxy object to provide verified write-access to the stored value. - /// \notes This function does not participate in overload resolution if `T` is `const`. - template ::value>::type> - constrained_modifier modify() noexcept - { - debug_verify(); - return constrained_modifier(*this); - } - - /// \effects Moves the stored value out of the `constrained_type`, - /// it will not be checked further. - /// \returns An rvalue reference to the stored value. - /// \notes After this function is called, the object must not be used anymore - /// except as target for assignment or in the destructor. - TYPE_SAFE_CONSTEXPR14 value_type&& release() TYPE_SAFE_RVALUE_REF noexcept - { - debug_verify(); - return std::move(value_); - } - - /// Dereference operator. - /// \returns A `const` reference to the stored value. - constexpr const value_type& operator*() const noexcept - { - return get_value(); - } - - /// Member access operator. - /// \returns A `const` pointer to the stored value. - constexpr const value_type* operator->() const noexcept - { - return std::addressof(get_value()); - } - - /// \returns A `const` reference to the stored value. - constexpr const value_type& get_value() const noexcept - { - return debug_verify(); - } - - /// \returns The predicate that determines validity. - constexpr const constraint_predicate& get_constraint() const noexcept - { - return *this; - } - -private: - constexpr const value_type& debug_verify() const noexcept - { -#if TYPE_SAFE_ENABLE_ASSERTIONS - return Verifier::verify(value_, get_constraint()), value_; -#else - return value_; -#endif - } - - TYPE_SAFE_CONSTEXPR14 value_type& get_non_const() noexcept - { - return value_; - } - - value_type value_; - friend constrained_modifier; -}; - -/// Specialization of [ts::constrained_type]() for references. -/// -/// It models a reference to a value that always fulfills the given constraint. -/// The value must not be changed by other means, it is thus perfect for function parameters. -/// \unique_name constrained_type_ref -template -class constrained_type : Constraint -{ -public: - using value_type = T; - using constraint_predicate = Constraint; - - /// \effects Binds the reference to the given object. - explicit constexpr constrained_type(T& value, constraint_predicate predicate = {}) - : Constraint(std::move(predicate)), ref_(&Verifier::verify(value, get_constraint())) - {} - - /// \exclude - template ::value>::type> - constrained_type(U) = delete; - - /// \returns A proxy object to provide verified write-access to the referred value. - /// \notes This function does not participate in overload resolution if `T` is `const`. - template ::value>::type> - constrained_modifier modify() noexcept - { - debug_verify(); - return constrained_modifier(*this); - } - - /// Dereference operator. - /// \returns A `const` reference to the referred value. - constexpr const value_type& operator*() const noexcept - { - return get_value(); - } - - /// Member access operator. - /// \returns A `const` pointer to the referred value. - constexpr const value_type* operator->() const noexcept - { - return &get_value(); - } - - /// \returns A `const` reference to the referred value. - constexpr const value_type& get_value() const noexcept - { - return debug_verify(); - } - - /// \returns The predicate that determines validity. - constexpr const constraint_predicate& get_constraint() const noexcept - { - return *this; - } - -private: - constexpr const value_type& debug_verify() const noexcept - { -#if TYPE_SAFE_ENABLE_ASSERTIONS - return Verifier::verify(*ref_, get_constraint()); -#else - return *ref_; -#endif - } - - TYPE_SAFE_CONSTEXPR14 value_type& get_non_const() noexcept - { - return *ref_; - } - - T* ref_; - friend constrained_modifier; -}; - -/// Alias for [ts::constrained_type](standardese://ts::constrained_type_ref/). -template -using constrained_ref = constrained_type; - -/// A proxy class to provide write access to the stored value of a [ts::constrained_type](). -/// -/// The destructor will verify the value again. -template -class constrained_modifier -{ -public: - using value_type = typename constrained_type::value_type; - - /// \effects Move constructs it. - /// `other` will not verify any value afterwards. - constrained_modifier(constrained_modifier&& other) noexcept : value_(other.value_) - { - other.value_ = nullptr; - } - - /// \effects Verifies the value, if there is any. - ~constrained_modifier() noexcept(false) - { - if (value_) - Verifier::verify(**value_, value_->get_constraint()); - } - - /// \effects Move assigns it. - /// `other` will not verify any value afterwards. - constrained_modifier& operator=(constrained_modifier&& other) noexcept - { - value_ = other.value_; - other.value_ = nullptr; - return *this; - } - - /// Dereference operator. - /// \returns A reference to the stored value. - /// \requires It must not be in the moved-from state. - value_type& operator*() noexcept - { - return get(); - } - - /// Member access operator. - /// \returns A pointer to the stored value. - /// \requires It must not be in the moved-from state. - value_type* operator->() noexcept - { - return &get(); - } - - /// \returns A reference to the stored value. - /// \requires It must not be in the moved-from state. - value_type& get() noexcept - { - DEBUG_ASSERT(value_, detail::precondition_error_handler{}); - return value_->get_non_const(); - } - -private: - constrained_modifier(constrained_type& value) noexcept : value_(&value) - {} - - constrained_type* value_; - friend constrained_type; -}; - -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op) \ - template \ - constexpr auto operator Op(const constrained_type& lhs, \ - const constrained_type& \ - rhs) noexcept(noexcept(lhs.get_value() Op rhs.get_value())) \ - ->decltype(lhs.get_value() Op rhs.get_value()) \ - { \ - return lhs.get_value() Op rhs.get_value(); \ - } - -/// Compares a [ts::constrained_type](). -/// \returns The result of the comparison of the underlying value. -/// \notes The comparison operators do not participate in overload resolution, -/// unless the stored type provides them as well. -/// \synopsis_return bool -/// \group constrained_comp -Constrained type comparison -TYPE_SAFE_DETAIL_MAKE_OP(==) -/// \synopsis_return bool -/// \group constrained_comp -TYPE_SAFE_DETAIL_MAKE_OP(!=) -/// \synopsis_return bool -/// \group constrained_comp -TYPE_SAFE_DETAIL_MAKE_OP(<) -/// \synopsis_return bool -/// \group constrained_comp -TYPE_SAFE_DETAIL_MAKE_OP(<=) -/// \synopsis_return bool -/// \group constrained_comp -TYPE_SAFE_DETAIL_MAKE_OP(>) -/// \synopsis_return bool -/// \group constrained_comp -TYPE_SAFE_DETAIL_MAKE_OP(>=) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -/// Creates a [ts::constrained_type](). -/// \returns A [ts::constrained_type]() with the given `value`, `Constraint` and `Verifier`. -/// \unique_name constrain_verifier -template -constexpr auto constrain(T&& value, Constraint c) - -> constrained_type::type, Constraint, Verifier> -{ - return constrained_type::type, Constraint, Verifier>(std::forward( - value), - std::move(c)); -} - -/// Creates a [ts::constrained_type]() with the default verifier, [ts::assertion_verifier](). -/// \returns A [ts::constrained_type]() with the given `value` and `Constraint`. -/// \requires As it uses a `DEBUG_ASSERT` to check constrain, -/// the value must be valid. -/// \unique_name constrain -template -constexpr auto constrain(T&& value, Constraint c) - -> constrained_type::type, Constraint> -{ - return constrained_type::type, Constraint>(std::forward(value), - std::move(c)); -} - -/// Creates a [ts::constrained_type]() using the [ts::throwing_verifier](). -/// \returns A [ts::constrained_type]() with the given `value` and `Constraint`. -/// \throws A [ts::constrain_error]() if the `value` isn't valid, -/// or anything else thrown by the constructor. -/// \notes This is meant for sanitizing user input, -/// using a recoverable error handling strategy. -template -constexpr auto sanitize(T&& value, Constraint c) - -> constrained_type::type, Constraint, throwing_verifier> -{ - return constrained_type::type, Constraint, - throwing_verifier>(std::forward(value), std::move(c)); -} - -/// With operation for [ts::constrained_type](). -/// \effects Calls `f` with a non-`const` reference to the stored value of the -/// [ts::constrained_type](). It checks that `f` does not change the validity of the object. \notes -/// The same behavior can be accomplished by using the `modify()` member function. -template -void with(constrained_type& value, Func&& f, Args&&... additional_args) -{ - auto modifier = value.modify(); - std::forward(f)(modifier.get(), std::forward(additional_args)...); -} - -//=== tagged_type ===// -/// A `Verifier` for [ts::constrained_type]() that doesn't check the constraint. -/// -/// It will simply return the value unchanged, without any checks. -/// \notes It does not impose any additional requirements on the `Predicate`. -/// \output_section Tagged type -struct null_verifier -{ - template - static constexpr Value&& verify(Value&& v, const Predicate&) - { - return std::forward(v); - } -}; - -/// An alias for [ts::constrained_type]() that never checks the constraint. -/// -/// It is useful for creating tagged types: -/// The `Constraint` - which does not need to be a predicate anymore - is a "tag" to differentiate a -/// type in different states. For example, you could have a "sanitized" value and a "non-sanitized" -/// value that have different types, so you cannot accidentally mix them. \notes It is only intended -/// if the `Constraint` cannot be formalized easily and/or is expensive. Otherwise -/// [ts::constrained_type]() is recommended as it does additional runtime checks in debug mode. -template -using tagged_type = constrained_type; - -/// An alias for [ts::tagged_type]() with reference. -template -using tagged_ref = constrained_ref; - -/// Creates a new [ts::tagged_type](). -/// \returns A [ts::tagged_type]() with the given `value` and `Constraint`. -template -constexpr auto tag(T&& value, Constraint c) -> tagged_type::type, Constraint> -{ - return tagged_type::type, Constraint>(std::forward(value), - std::move(c)); -} - -//=== constraints ===// -namespace constraints -{ - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value of a pointer type is valid if it is not equal to `nullptr`. - /// This is borrowed from GSL's - /// [non_null](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#a-namess-viewsagslview-views). - struct non_null - { - template - struct is_valid : std::true_type - {}; - - template - constexpr bool operator()(const T& ptr) const noexcept - { - return ptr != nullptr; - } - }; - - template <> - struct non_null::is_valid : std::false_type - {}; - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value of a container type is valid if it is not empty. - /// Empty-ness is determined with either a member or non-member function. - class non_empty - { - template - constexpr auto is_empty(int, const T& t) const noexcept(noexcept(t.empty())) - -> decltype(t.empty()) - { - return !t.empty(); - } - - template - constexpr bool is_empty(short, const T& t) const - { - return !empty(t); - } - - public: - template - constexpr bool operator()(const T& t) const - { - return is_empty(0, t); - } - }; - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value is valid if it not equal to the default constructed value. - struct non_default - { - template - constexpr bool operator()(const T& t) const noexcept(noexcept(t == T())) - { - return !(t == T()); - } - }; - - /// A `Constraint` for the [ts::constrained_type](). - /// - /// A value of a pointer-like type is valid if the expression `!value` is `false`. - struct non_invalid - { - template - constexpr bool operator()(const T& t) const noexcept(noexcept(!!t)) - { - return !!t; - } - }; - - /// A `Constraint` for the [ts::tagged_type](). - /// - /// It marks an owning pointer. - /// It is borrowed from GSL's - /// [non_null](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#a-namess-viewsagslview-views). - /// \notes This is not actually a predicate. - struct owner - {}; -} // namespace constraints -} // namespace type_safe - -#endif // TYPE_SAFE_CONSTRAINED_TYPE_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/deferred_construction.hpp b/third/type_safe/include/type_safe/deferred_construction.hpp deleted file mode 100644 index 5cf97ba2..00000000 --- a/third/type_safe/include/type_safe/deferred_construction.hpp +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DEFERRED_CONSTRUCTION_HPP_INCLUDED -#define TYPE_SAFE_DEFERRED_CONSTRUCTION_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#endif - -#include - -namespace type_safe -{ -/// A tiny wrapper to create an object without constructing it yet. -/// -/// This is useful if you have a type that is default constructible, -/// but can't be initialized properly - yet. -/// It works especially well with [ts::output_parameter](). -/// -/// It has two states: -/// Either it is *initialized* in which case you can get its value, -/// or it is *un-initialized* in which case you cannot get its value. -/// All objects start out un-initialized. -/// For consistency with [ts::basic_optional]() it provides a similar interface, -/// yet it is not as flexible and does not allow to reset it to the uninitialized state, -/// once initialized. -template -class deferred_construction -{ -public: - using value_type = T; - - //=== constructors/assignment/destructor ===// - /// Default constructor. - /// \effects Creates it in the un-initialized state. - deferred_construction() noexcept : initialized_(false) {} - - /// Copy constructor: - /// \effects If `other` is un-initialized, it will be un-initialized as well. - /// If `other` is initialized, it will copy the stored value. - /// \throws Anything thrown by the copy constructor of `value_type` if `other` is initialized. - deferred_construction(const deferred_construction& other) : initialized_(other.initialized_) - { - if (initialized_) - ::new (as_void()) value_type(other.value()); - } - - /// Move constructor: - /// \effects If `other` is un-initialized, it will be un-initialized as well. - /// If `other` is initialized, it will copy the stored value. - /// \throws Anything thrown by the move constructor of `value_type` if `other` is initialized. - /// \notes `other` will still be initialized after the move operation, - /// it is just in a moved-from state. - deferred_construction(deferred_construction&& other) noexcept( - std::is_nothrow_move_constructible::value) - : initialized_(other.initialized_) - { - if (initialized_) - ::new (as_void()) value_type(std::move(other).value()); - } - - /// \notes You cannot construct it from the type directly. - /// If you are able to do that, there is no need to use `defer_construction`! - deferred_construction(value_type) = delete; - - /// \effects If it is initialized, it will destroy the value. - /// Otherwise it has no effect. - ~deferred_construction() noexcept - { - if (initialized_) - value().~value_type(); - } - - /// \notes You cannot copy or move assign it. - /// This is a deliberate design decision to guarantee, - /// that an initialized object stays initialized, no matter what. - deferred_construction& operator=(deferred_construction) = delete; - - /// \effects Same as `emplace(std::forward(u))`. - /// \requires `value_type` must be constructible from `U`. - /// \notes You must not use this function to actually "assign" the value, - /// like `emplace()`, the object must not be initialized. - /// \synopsis_return deferred_construction& - template - auto operator=(U&& u) -> - typename std::enable_if(u))>::value, - deferred_construction&>::type - { - emplace(std::forward(u)); - return *this; - } - - //=== modifiers ===// - /// \effects Initializes the object with the `value_type` constructed from `args`. - /// \requires `has_value() == false`. - /// \throws Anything thrown by the chosen constructor of `value_type`. - /// \notes You must only call this function once, - /// after the object has been initialized, - /// you can use `value()` to assign to it. - /// \output_section Modifiers - template - void emplace(Args&&... args) - { - DEBUG_ASSERT(!has_value(), detail::precondition_error_handler{}); - ::new (as_void()) value_type(std::forward(args)...); - initialized_ = true; - } - - //=== observers ===// - /// \returns `true` if the object is initialized, `false` otherwise. - /// \output_section Observers - bool has_value() const noexcept - { - return initialized_; - } - - /// \returns The same as `has_value()`. - explicit operator bool() const noexcept - { - return has_value(); - } - - /// Access the stored value. - /// \returns A (`const`) (rvalue) reference to the stored value. - /// \requires `has_value() == true`. - /// \group value - value_type& value() TYPE_SAFE_LVALUE_REF noexcept - { - DEBUG_ASSERT(has_value(), detail::precondition_error_handler{}); - return *static_cast(as_void()); - } - - /// \group value - const value_type& value() const TYPE_SAFE_LVALUE_REF noexcept - { - DEBUG_ASSERT(has_value(), detail::precondition_error_handler{}); - return *static_cast(as_void()); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group value - value_type&& value() && noexcept - { - DEBUG_ASSERT(has_value(), detail::precondition_error_handler{}); - return std::move(*static_cast(as_void())); - } - - /// \group value - const value_type&& value() const&& noexcept - { - DEBUG_ASSERT(has_value(), detail::precondition_error_handler{}); - return std::move(*static_cast(as_void())); - } -#endif - -private: - void* as_void() noexcept - { - return static_cast(&storage_); - } - - const void* as_void() const noexcept - { - return static_cast(&storage_); - } - - alignas(T) unsigned char storage_[sizeof(T)]; - bool initialized_; -}; - -} // namespace type_safe - -#endif // TYPE_SAFE_DEFER_CONSTRUCTION_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/detail/aligned_union.hpp b/third/type_safe/include/type_safe/detail/aligned_union.hpp deleted file mode 100644 index 981b50b3..00000000 --- a/third/type_safe/include/type_safe/detail/aligned_union.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_ALIGNED_UNION_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_ALIGNED_UNION_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -# include -# include -#endif - -namespace type_safe -{ -namespace detail -{ - // max for variadic number of types. - template - constexpr const T& max(const T& a) - { - return a; - } - - template - constexpr const T& max(const T& a, const T& b) - { - return a < b ? b : a; - } - - template - constexpr const T& max(const T& t, const Ts&... ts) - { - return max(t, max(ts...)); - } - - template - class aligned_union - { - public: - static constexpr auto size_value = detail::max(sizeof(Types)...); - static constexpr auto alignment_value = detail::max(alignof(Types)...); - - void* get() noexcept - { - return &storage_; - } - const void* get() const noexcept - { - return &storage_; - } - - private: - alignas(alignment_value) unsigned char storage_[size_value]; - }; -} // namespace detail -} // namespace type_safe - -#endif // TYPE_SAFE_DETAIL_ALIGNED_UNION_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/detail/all_of.hpp b/third/type_safe/include/type_safe/detail/all_of.hpp deleted file mode 100644 index 80ff47f4..00000000 --- a/third/type_safe/include/type_safe/detail/all_of.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_ALL_OF_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_ALL_OF_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#endif - -namespace type_safe -{ -namespace detail -{ - template - struct bool_sequence - {}; - - template - using all_of = std::is_same, bool_sequence<(true || Bs)...>>; - - template - using none_of = std::is_same, bool_sequence<(false && Bs)...>>; - - template - using any_of = std::integral_constant::value>; -} // namespace detail -} // namespace type_safe - -#endif // TYPE_SAFE_DETAIL_ALL_OF_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/detail/assert.hpp b/third/type_safe/include/type_safe/detail/assert.hpp deleted file mode 100644 index c6b5111b..00000000 --- a/third/type_safe/include/type_safe/detail/assert.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_ASSERT_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_ASSERT_HPP_INCLUDED - -#include - -#include - -namespace type_safe -{ -namespace detail -{ - struct assert_handler : debug_assert::set_level, - debug_assert::default_handler - {}; - - struct precondition_error_handler - : debug_assert::set_level, - debug_assert::default_handler - {}; - - inline void on_disabled_exception() noexcept - { - struct handler : debug_assert::set_level<1>, debug_assert::default_handler - {}; - DEBUG_UNREACHABLE(handler{}, "attempt to throw an exception but exceptions are disabled"); - } -} // namespace detail -} // namespace type_safe - -#endif // TYPE_SAFE_DETAIL_ASSERT_HPP_INCLUDED` diff --git a/third/type_safe/include/type_safe/detail/assign_or_construct.hpp b/third/type_safe/include/type_safe/detail/assign_or_construct.hpp deleted file mode 100644 index b53feb8f..00000000 --- a/third/type_safe/include/type_safe/detail/assign_or_construct.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_ASSIGN_OR_CONSTRUCT_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_ASSIGN_OR_CONSTRUCT_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#endif - -namespace type_safe -{ -namespace detail -{ - // std::is_assignable but without user-defined conversions - template - struct is_direct_assignable - { - template - struct consume_udc - { - operator U() const; - }; - - template - static std::true_type check(decltype(std::declval() = std::declval>(), - 0)*); - - template - static std::false_type check(...); - - static constexpr bool value = decltype(check(0))::value; - }; -} // namespace detail -} // namespace type_safe - -#endif // TYPE_SAFE_DETAIL_ASSIGN_OR_CONSTRUCT_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/detail/constant_parser.hpp b/third/type_safe/include/type_safe/detail/constant_parser.hpp deleted file mode 100644 index 996c46e4..00000000 --- a/third/type_safe/include/type_safe/detail/constant_parser.hpp +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_CONSTANT_PARSER_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_CONSTANT_PARSER_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#endif - -namespace type_safe -{ -namespace detail -{ - template - struct conditional_impl; - - template - struct conditional_impl - { - using type = Else; - }; - - template - struct conditional_impl - { - using type = Result; - }; - - template - struct conditional_impl - { - using type = typename conditional_impl::type; - }; - - template - using conditional = typename conditional_impl::type; - - template - using bool_constant = std::integral_constant; - - struct decimal_digit - {}; - struct lower_hexadecimal_digit - {}; - struct upper_hexadecimal_digit - {}; - struct no_digit - {}; - - template - using digit_category - = conditional= '0' && C <= '9'>, decimal_digit, - bool_constant= 'a' && C <= 'f'>, lower_hexadecimal_digit, - bool_constant= 'A' && C <= 'F'>, upper_hexadecimal_digit, no_digit>; - - template - struct to_digit_impl - { - static_assert(!std::is_same::value, "invalid character, expected digit"); - }; - - template - struct to_digit_impl - { - static constexpr auto value = static_cast(C) - static_cast('0'); - }; - - template - struct to_digit_impl - { - static constexpr auto value = static_cast(C) - static_cast('a') + 10; - }; - - template - struct to_digit_impl - { - static constexpr auto value = static_cast(C) - static_cast('A') + 10; - }; - - template - constexpr T to_digit() - { - using impl = to_digit_impl>; - static_assert(impl::value < Base, "invalid digit for base"); - return impl::value; - } - - template - struct parse_loop; - - template <> - struct parse_loop<> - { - template - static constexpr T parse(T value) - { - return value; - } - }; - - template - struct parse_loop<'\'', Tail...> - { - template - static constexpr T parse(T value) - { - return parse_loop::template parse(value); - } - }; - - template - struct parse_loop - { - template - static constexpr T parse(T value) - { - return parse_loop::template parse(value * Base - + to_digit()); - } - }; - - template - constexpr T do_parse_loop() - { - return parse_loop::template parse(to_digit()); - } - - template - struct parse_base - { - static constexpr T parse() - { - return do_parse_loop(); - } - }; - - template - struct parse_base - { - static constexpr T parse() - { - return do_parse_loop(); - } - }; - - template - struct parse_base - { - static constexpr T parse() - { - return do_parse_loop(); - } - }; - - template - struct parse_base - { - static constexpr T parse() - { - return do_parse_loop(); - } - }; - - template - struct parse_base - { - static constexpr T parse() - { - return do_parse_loop(); - } - }; - - template - struct parse_base - { - static constexpr T parse() - { - return do_parse_loop(); - } - }; - - template - constexpr T parse() - { - return parse_base::parse(); - } -} // namespace detail -} // namespace type_safe - -#endif // TYPE_SAFE_DETAIL_CONSTANT_PARSER_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/detail/copy_move_control.hpp b/third/type_safe/include/type_safe/detail/copy_move_control.hpp deleted file mode 100644 index a17b4e0f..00000000 --- a/third/type_safe/include/type_safe/detail/copy_move_control.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_COPY_MOVE_CONTROL_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_COPY_MOVE_CONTROL_HPP_INCLUDED - -namespace type_safe -{ -namespace detail -{ - template - struct copy_control; - - template <> - struct copy_control - { - copy_control() noexcept = default; - - copy_control(const copy_control&) noexcept = default; - copy_control& operator=(const copy_control&) noexcept = default; - - copy_control(copy_control&&) noexcept = default; - copy_control& operator=(copy_control&&) noexcept = default; - }; - - template <> - struct copy_control - { - copy_control() noexcept = default; - - copy_control(const copy_control&) noexcept = delete; - copy_control& operator=(const copy_control&) noexcept = delete; - - copy_control(copy_control&&) noexcept = default; - copy_control& operator=(copy_control&&) noexcept = default; - }; - - template - struct move_control; - - template <> - struct move_control - { - move_control() noexcept = default; - - move_control(const move_control&) noexcept = default; - move_control& operator=(const move_control&) noexcept = default; - - move_control(move_control&&) noexcept = default; - move_control& operator=(move_control&&) noexcept = default; - }; - - template <> - struct move_control - { - move_control() noexcept = default; - - move_control(const move_control&) noexcept = default; - move_control& operator=(const move_control&) noexcept = default; - - move_control(move_control&&) noexcept = delete; - move_control& operator=(move_control&&) noexcept = delete; - }; -} // namespace detail -} // namespace type_safe - -#endif // TYPE_SAFE_DETAIL_COPY_MOVE_CONTROL_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/detail/force_inline.hpp b/third/type_safe/include/type_safe/detail/force_inline.hpp deleted file mode 100644 index 726555ca..00000000 --- a/third/type_safe/include/type_safe/detail/force_inline.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_FORCE_INLINE_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_FORCE_INLINE_HPP_INCLUDED - -#include - -#define TYPE_SAFE_FORCE_INLINE DEBUG_ASSERT_FORCE_INLINE - -#endif // TYPE_SAFE_DETAIL_FORCE_INLINE_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/detail/is_nothrow_swappable.hpp b/third/type_safe/include/type_safe/detail/is_nothrow_swappable.hpp deleted file mode 100644 index b49574c6..00000000 --- a/third/type_safe/include/type_safe/detail/is_nothrow_swappable.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_IS_NOTHROW_SWAPABLE_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_IS_NOTHROW_SWAPABLE_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#endif - -namespace type_safe -{ -namespace detail -{ - template - struct is_nothrow_swappable - { - template - static auto adl_swap(int, U& a, U& b) noexcept(noexcept(swap(a, b))) - -> decltype(swap(a, b)); - - template - static auto adl_swap(short, U& a, U& b) noexcept(noexcept(std::swap(a, b))) - -> decltype(std::swap(a, b)); - - static void adl_swap(...) noexcept(false); - - static constexpr bool value = noexcept(adl_swap(0, std::declval(), std::declval())); - }; -} // namespace detail -} // namespace type_safe - -#endif // TYPE_SAFE_DETAIL_IS_NOTHROW_SWAPABLE_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/detail/map_invoke.hpp b/third/type_safe/include/type_safe/detail/map_invoke.hpp deleted file mode 100644 index af03811d..00000000 --- a/third/type_safe/include/type_safe/detail/map_invoke.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_MAP_INVOKE_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_MAP_INVOKE_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#endif - -namespace type_safe -{ -namespace detail -{ - template - auto map_invoke(Func&& f, Value&& v, Args&&... args) - -> decltype(std::forward(f)(std::forward(v), std::forward(args)...)) - { - return std::forward(f)(std::forward(v), std::forward(args)...); - } - - template - auto map_invoke(Func&& f, Value&& v) -> decltype(std::forward(v).*std::forward(f)) - { - return std::forward(v).*std::forward(f); - } - - template - auto map_invoke(Func&& f, Value&& v, Args&&... args) - -> decltype((std::forward(v).*std::forward(f))(std::forward(args)...)) - { - return (std::forward(v).*std::forward(f))(std::forward(args)...); - } -} // namespace detail -} // namespace type_safe - -#endif // TYPE_SAFE_MAP_INVOKE_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/detail/variant_impl.hpp b/third/type_safe/include/type_safe/detail/variant_impl.hpp deleted file mode 100644 index d8673f96..00000000 --- a/third/type_safe/include/type_safe/detail/variant_impl.hpp +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DETAIL_VARIANT_IMPL_HPP_INCLUDED -#define TYPE_SAFE_DETAIL_VARIANT_IMPL_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include - -namespace type_safe -{ -template -class basic_variant; - -namespace detail -{ - //=== variant traits ===// - template - struct is_variant_impl : std::false_type - {}; - - template - struct is_variant_impl> : std::true_type - {}; - - template - using is_variant = is_variant_impl::type>; - - template - struct traits_impl - { - using copy_constructible = all_of::value...>; - using move_constructible = all_of::value...>; - using nothrow_move_constructible - = all_of::value...>; - using nothrow_move_assignable = all_of::value - ? std::is_nothrow_move_assignable::value - : true)...>; - using nothrow_swappable - = all_of::value...>; - }; - - template - using traits = traits_impl::type...>; - - //=== copy_assign_union_value ===// - template - struct copy_assign_union_value - { - struct visitor - { - template ::value>::type> - void do_assign(Union& dest, const T& value) - { - dest.value(union_type{}) = value; - } - - template ::value, int>::type = 0> - void do_assign(Union& dest, const T& value) - { - VariantPolicy::change_value(union_type{}, dest, value); - } - - template - void operator()(const T& value, Union& dest) - { - constexpr auto id = typename Union::type_id(union_type{}); - if (dest.type() == id) - do_assign(dest, value); - else - VariantPolicy::change_value(union_type{}, dest, value); - } - }; - - static void assign(Union& dest, const Union& org) - { - with(org, visitor{}, dest); - } - }; - - //==== move_assign_union_value ===// - template - struct move_assign_union_value - { - struct visitor - { - template ::value>::type> - void do_assign(Union& dest, T&& value) - { - dest.value(union_type{}) = std::move(value); - } - - template ::value, int>::type = 0> - void do_assign(Union& dest, T&& value) - { - VariantPolicy::change_value(union_type::type>{}, dest, - std::move(value)); - } - - template - void operator()(T&& value, Union& dest) - { - constexpr auto id = - typename Union::type_id(union_type::type>{}); - if (dest.type() == id) - do_assign(dest, std::move(value)); - else - VariantPolicy::change_value(union_type::type>{}, dest, - std::move(value)); - } - }; - - static void assign(Union& dest, Union&& org) - { - with(std::move(org), visitor{}, dest); - } - }; - - //=== swap_union ===// - template - struct swap_union - { - struct visitor - { - template - void operator()(T&, Union& a, Union& b) - { - constexpr auto id = typename Union::type_id(union_type{}); - DEBUG_ASSERT(a.type() == id, detail::assert_handler{}); - - if (b.type() == id) - { - using std::swap; - swap(a.value(union_type{}), b.value(union_type{})); - } - else - { - T tmp(std::move(a).value(union_type{})); // save old value from a - // assign a to value in b - move_assign_union_value::assign(a, std::move(b)); - // change value in b to tmp - VariantPolicy::change_value(union_type{}, b, std::move(tmp)); - } - } - }; - - static void swap(Union& a, Union& b) - { - with(a, visitor{}, a, b); - } - }; - - //=== map_union ===// - template - struct map_union - { - struct visitor - { - template - auto call(int, Union& res, Functor&& f, T&& value, Args&&... args) - -> decltype((void)map_invoke(std::forward(f), std::forward(value), - std::forward(args)...)) - { - using result = decltype(map_invoke(std::forward(f), std::forward(value), - std::forward(args)...)); - res.emplace(union_type::type>{}, - map_invoke(std::forward(f), std::forward(value), - std::forward(args)...)); - } - template - void call(short, Union& res, Functor&&, T&& value, Args&&...) - { - res.emplace(union_type::type>{}, std::forward(value)); - } - - template - void operator()(T&& value, Union& res, Functor&& f, Args&&... args) - { - call(0, res, std::forward(f), std::forward(value), - std::forward(args)...); - } - }; - - template - static void map(Union& res, const Union& u, Functor&& f, Args&&... args) - { - DEBUG_ASSERT(!res.has_value(), precondition_error_handler{}); - with(u, visitor{}, res, std::forward(f), std::forward(args)...); - } - - template - static void map(Union& res, Union&& u, Functor&& f, Args&&... args) - { - DEBUG_ASSERT(!res.has_value(), precondition_error_handler{}); - with(std::move(u), visitor{}, res, std::forward(f), - std::forward(args)...); - } - }; - - //=== compare_variant ===// - template - struct compare_variant - { - struct equal_visitor - { - bool result = false; - - template - void operator()(const T& value, const Variant& other) - { - result = (value == other); - } - }; - - struct less_visitor - { - bool result = false; - - template - void operator()(const T& value, const Variant& other) - { - result = (value < other); - } - }; - - static bool compare_equal(const Variant& a, const Variant& b) - { - if (!a.has_value()) - // to be equal, b must not have value as well - return !b.has_value(); - - equal_visitor v; - with(a, v, b); - return v.result; - } - - static bool compare_less(const Variant& a, const Variant& b) - { - if (!a.has_value()) - // for a to be less than b, - // b must have a value - return b.has_value(); - - less_visitor v; - with(a, v, b); - return v.result; - } - }; - - //=== variant_storage ===// - template - class variant_storage - { - using traits = detail::traits; - - public: - variant_storage() noexcept = default; - - variant_storage(const variant_storage& other) - { - copy(storage_, other.storage_); - } - - variant_storage(variant_storage&& other) noexcept(traits::nothrow_move_constructible::value) - { - move(storage_, std::move(other.storage_)); - } - - ~variant_storage() noexcept - { - destroy(storage_); - } - - variant_storage& operator=(const variant_storage& other) - { - if (storage_.has_value() && other.storage_.has_value()) - copy_assign_union_value>::assign(storage_, other.storage_); - else if (storage_.has_value() && !other.storage_.has_value()) - destroy(storage_); - else if (!storage_.has_value() && other.storage_.has_value()) - copy(storage_, other.storage_); - - return *this; - } - - variant_storage& operator=(variant_storage&& other) noexcept( - traits::nothrow_move_assignable::value) - { - if (storage_.has_value() && other.storage_.has_value()) - move_assign_union_value>::assign(storage_, - std::move(other.storage_)); - else if (storage_.has_value() && !other.storage_.has_value()) - destroy(storage_); - else if (!storage_.has_value() && other.storage_.has_value()) - move(storage_, std::move(other.storage_)); - - return *this; - } - - tagged_union& get_union() noexcept - { - return storage_; - } - - const tagged_union& get_union() const noexcept - { - return storage_; - } - - private: - tagged_union storage_; - }; - - struct storage_access - { - template - static auto get(Variant& var) -> decltype(var.storage_)& - { - return var.storage_; - } - - template - static auto get(const Variant& var) -> const decltype(var.storage_)& - { - return var.storage_; - } - }; - - template - using variant_copy = copy_control::copy_constructible::value>; - - template - using variant_move = move_control::move_constructible::value>; - - template - using enable_variant_type_impl = - typename std::enable_if() - && std::is_constructible::value>::type; - - template - using enable_variant_type - = enable_variant_type_impl::type, Args...>; -} // namespace detail -} // namespace type_safe - -#endif // TYPE_SAFE_DETAIL_VARIANT_IMPL_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/downcast.hpp b/third/type_safe/include/type_safe/downcast.hpp deleted file mode 100644 index 2211958e..00000000 --- a/third/type_safe/include/type_safe/downcast.hpp +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_DOWNCAST_HPP_INCLUDED -#define TYPE_SAFE_DOWNCAST_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#endif - -#include -#include - -namespace type_safe -{ -/// Tag type to specify the derived type of a [ts::downcast](). -/// -/// Pass it as first parameter to the appropriate overload. -template -struct derived_type -{}; - -namespace detail -{ - // same type - template - bool is_safe_downcast(derived_type, const T&) - { - return true; - } - - // polymorphic type, so we can check - template - auto is_safe_downcast(derived_type, const Base& obj) -> - typename std::enable_if::value, bool>::type - { -#if TYPE_SAFE_USE_RTTI - return dynamic_cast(&obj) != nullptr; -#else - return true; -#endif - } - - // non-polymorphic type, no check possible - template - auto is_safe_downcast(derived_type, const Base&) -> - typename std::enable_if::value, bool>::type - { - return true; - } - - template - void validate_downcast(const Base& obj) noexcept - { - using derived_t = typename std::decay::type; - static_assert(std::is_base_of::value, - "can only downcast from base to derived class"); - DEBUG_ASSERT(detail::is_safe_downcast(derived_type{}, obj), - detail::precondition_error_handler{}, "not a safe downcast"); - } -} // namespace detail - -/// Casts an object of base class type to the derived class type. -/// \returns The object converted as if `static_cast(obj)`. -/// \requires `Base` must be a base class of `Derived`, -/// and the dynamic type of `obj` must be `Derived`. -template -Derived downcast(Base& obj) noexcept -{ - detail::validate_downcast(obj); - return static_cast(obj); -} - -/// Casts an object of base class type to the derived class type. -/// \returns The object converted as if `static_cast(obj)`, -/// where `derived_ref` is the type of `Derived` with matching qualifiers. -/// \requires `Base` must be a base class of `Derived`, -/// and the dynamic type of `obj` must be `Derived`. -/// \group downcast_tag -template -Derived& downcast(derived_type, Base& obj) noexcept -{ - detail::validate_downcast(obj); - return static_cast(obj); -} - -/// \group downcast_tag -template -const Derived& downcast(derived_type, const Base& obj) noexcept -{ - detail::validate_downcast(obj); - return static_cast(obj); -} -} // namespace type_safe - -#endif // TYPE_SAFE_DOWNCAST_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/flag.hpp b/third/type_safe/include/type_safe/flag.hpp deleted file mode 100644 index 1d2a6fea..00000000 --- a/third/type_safe/include/type_safe/flag.hpp +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_FLAG_HPP_INCLUDED -#define TYPE_SAFE_FLAG_HPP_INCLUDED - -#include -#include - -namespace type_safe -{ -class flag; - -/// \exclude -template > -constexpr bool operator==(flag lhs, T rhs) noexcept; - -/// A type safe flag, it can either be `true` or `false`. -/// -/// Consider the following snippet: -/// ```cpp -/// auto was_newl = false; -/// for (auto x : …) -/// { -/// if (x == '\n') -/// { -/// assert(!was_newl); // want to change value here -/// was_newl = true; -/// } -/// else if (was_newl) -/// { -/// do_sth(c); -/// was_newl = false; // separate step, easy to forget (I did here originally!) -/// } -/// } -/// ``` -/// -/// With flag, it is better: -/// ```cpp -/// type_safe::flag was_newl(false); -/// for (auto x : …) -/// { -/// if (x == '\n') -/// was_newl.change(true); // asserts that value is changed -/// else if (was_newl.try_reset()) // resets flag and returns whether value changed -/// do_sth(x); // no way to forget -/// } -/// ``` -/// \notes It is named `flag` for consistency with [std::atomic_flag](), -/// even though this one can provide an extended interface as it is not atomic. -/// `flag` has nothing to do with [ts::flag_set](). -/// \module types -class flag -{ -public: - flag() = delete; - - /// \effects Gives the flag the initial state. - /// \notes This function does not participate in overload resolution if `T` is not a boolean - /// type. \param 1 \exclude - template > - constexpr flag(T initial_state) noexcept : state_(static_cast(initial_state)) - {} - - /// \effects Flips the state of the flag. - /// \returns The old value. - bool toggle() noexcept - { - auto old = state_; - state_ = !state_; - return old; - } - - /// \effects Sets its state to the new one. - /// \requires The new state must be different than the old one. - /// \param 1 - /// \exclude - template > - void change(T new_state) noexcept - { - DEBUG_ASSERT(state_ != new_state, detail::precondition_error_handler{}); - state_ = new_state; - } - - /// \effects Sets its state to `true`. - void set() noexcept - { - state_ = true; - } - - /// \effects Sets its state to `true`. - /// \returns `true` if the previous state was `false`, `false` otherwise, - /// i.e. whether or not the state was changed. - bool try_set() noexcept - { - auto old = state_; - state_ = true; - return old != state_; - } - - /// \effects Sets its state to `false`. - void reset() noexcept - { - state_ = false; - } - - /// \effects Sets its state to `false`. - /// \returns `true` if the previous state was `true`, `false` otherwise, - /// i.e. whether or not the state was changed. - bool try_reset() noexcept - { - auto old = state_; - state_ = false; - return old != state_; - } - -private: - bool state_; - - friend constexpr bool operator==(flag lhs, flag rhs) noexcept; - - template - friend constexpr bool operator==(flag lhs, T rhs) noexcept; -}; - -/// [ts::flag]() equality comparison. -/// \returns `true` if (1) both [ts::flag]() objects are in the same state, -/// (2)/(3) the flag is in the given state. -/// \notes (2)/(3) do not participate in overload resolution unless `T` is a boolean type. -/// \group flag_equal -/// \module types -constexpr bool operator==(flag lhs, flag rhs) noexcept -{ - return lhs.state_ == rhs.state_; -} - -/// \group flag_equal -/// \param 1 -/// \exclude -template -constexpr bool operator==(flag lhs, T rhs) noexcept -{ - return lhs.state_ == static_cast(rhs); -} - -/// \group flag_equal -/// \param 1 -/// \exclude -template > -constexpr bool operator==(T lhs, flag rhs) noexcept -{ - return rhs == lhs; -} - -/// [ts::flag]() in-equality comparison. -/// \returns `true` if (1) both [ts::flag]() objects are in the same state, -/// (2)/(3) the flag is in the given state. -/// \notes (2)/(3) do not participate in overload resolution unless `T` is a boolean type. -/// \group flag_unequal -/// \module types -constexpr bool operator!=(flag lhs, flag rhs) noexcept -{ - return !(lhs == rhs); -} - -/// \group flag_unequal -/// \param 1 -/// \exclude -template > -constexpr bool operator!=(flag lhs, T rhs) noexcept -{ - return !(lhs == rhs); -} - -/// \group flag_unequal -/// \param 1 -/// \exclude -template > -constexpr bool operator!=(T lhs, flag rhs) noexcept -{ - return !(lhs == rhs); -} -} // namespace type_safe - -#endif // TYPE_SAFE_FLAG_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/flag_set.hpp b/third/type_safe/include/type_safe/flag_set.hpp deleted file mode 100644 index 0d4ce705..00000000 --- a/third/type_safe/include/type_safe/flag_set.hpp +++ /dev/null @@ -1,799 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_FLAG_SET_HPP_INCLUDED -#define TYPE_SAFE_FLAG_SET_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#endif - -#include -#include - -namespace type_safe -{ -/// \exclude -namespace detail -{ - template - struct is_flag_set : std::false_type - {}; - - template - struct is_flag_set(Enum::_flag_set_size))> : std::is_enum - {}; - - template - constexpr typename std::enable_if::value, std::size_t>::type - flag_set_size() noexcept - { - return static_cast(Enum::_flag_set_size); - } - - template - constexpr typename std::enable_if::value, std::size_t>::type - flag_set_size() noexcept - { - return 0u; - } -} // namespace detail - -/// Traits for the enum used in a [ts::flag_set](). -/// -/// For each enum that should be used with [ts::flag_set]() it must provide the following interface: -/// * Inherit from [std::true_type](). -/// * `static constexpr std::size_t size()` that returns the number of enumerators. -/// -/// The default specialization automatically works for enums that have an enumerator -/// `_flag_set_size`, whose value is the number of enumerators. But you can also specialize the -/// traits for your own enums. Enums which work with [ts::flag_set]() are called flags. -/// -/// \requires For all specializations the enum must be contiguous starting at `0`, -/// simply don't set an explicit value to the enumerators. -template -struct flag_set_traits : detail::is_flag_set -{ - static constexpr std::size_t size() noexcept - { - return detail::flag_set_size(); - } -}; - -/// Tag type to mark a [ts::flag_set]() without any flags set. -struct noflag_t -{ - constexpr noflag_t() {} -}; - -/// Tag object of type [ts::noflag_t](). -constexpr noflag_t noflag; - -/// \exclude -namespace detail -{ - template - struct select_flag_set_int - { - static_assert(Size != 0u, - "number of bits not supported, complain loud enough so I'll do it"); - }; - -/// \exclude -#define TYPE_SAFE_DETAIL_SELECT(Min, Max, Type) \ - template \ - struct select_flag_set_int Min && Size <= Max)>::type> \ - { \ - using type = Type; \ - }; - - TYPE_SAFE_DETAIL_SELECT(0u, 8u, std::uint_least8_t) - TYPE_SAFE_DETAIL_SELECT(8u, 16u, std::uint_least16_t) - TYPE_SAFE_DETAIL_SELECT(16u, 32u, std::uint_least32_t) - TYPE_SAFE_DETAIL_SELECT(32u, sizeof(std::uint_least64_t) * CHAR_BIT, std::uint_least64_t) - -#undef TYPE_SAFE_DETAIL_SELECT - - template - class flag_set_impl - { - public: - using traits = flag_set_traits; - using int_type = typename select_flag_set_int::type; - - static constexpr flag_set_impl all_set() - { - return flag_set_impl(int_type((int_type(1) << traits::size()) - int_type(1))); - } - static constexpr flag_set_impl none_set() - { - return flag_set_impl(int_type(0)); - } - - explicit constexpr flag_set_impl(const Enum& e) : bits_(mask(e)) {} - template - explicit constexpr flag_set_impl(const flag_set_impl& other) - : bits_(other.bits_) - {} - - constexpr flag_set_impl set(const Enum& e) const - { - return flag_set_impl(bits_ | mask(e)); - } - constexpr flag_set_impl reset(const Enum& e) const - { - return flag_set_impl(bits_ & ~mask(e)); - } - constexpr flag_set_impl toggle(const Enum& e) const - { - return flag_set_impl(bits_ ^ mask(e)); - } - - constexpr flag_set_impl toggle_all() const - { - return flag_set_impl(bits_ ^ all_set().to_int()); - } - - constexpr int_type to_int() const - { - return bits_; - } - - constexpr bool is_set(const Enum& e) const - { - return (bits_ & mask(e)) != int_type(0u); - } - - constexpr flag_set_impl bitwise_or(const flag_set_impl& other) const - { - return flag_set_impl(bits_ | other.bits_); - } - - constexpr flag_set_impl bitwise_xor(const flag_set_impl& other) const - { - return flag_set_impl(bits_ ^ other.bits_); - } - - constexpr flag_set_impl bitwise_and(const flag_set_impl& other) const - { - return flag_set_impl(bits_ & other.bits_); - } - - private: - static constexpr int_type mask(const Enum& e) - { - return int_type(int_type(1u) << static_cast(e)); - } - - template ::value - && std::is_unsigned::value>> - explicit constexpr flag_set_impl(T bits) : bits_(int_type(bits)) - {} - - int_type bits_; - - template - friend class flag_set_impl; - }; - - template - using flag_combo = flag_set_impl; - - template - using flag_mask = flag_set_impl; - - template - constexpr bool operator==(const flag_combo& a, noflag_t) - { - return a == a.none_set(); - } - template - constexpr bool operator==(noflag_t, const flag_combo& a) - { - return a == a.none_set(); - } - template - constexpr bool operator==(const flag_combo& a, const flag_combo& b) - { - return a.to_int() == b.to_int(); - } - template - constexpr bool operator==(const flag_combo& a, const Enum& b) - { - return a == flag_combo(b); - } - template - constexpr bool operator==(const Enum& a, const flag_combo& b) - { - return flag_combo(a) == b; - } - - template - constexpr bool operator!=(const flag_combo& a, noflag_t b) - { - return !(a == b); - } - template - constexpr bool operator!=(noflag_t a, const flag_combo& b) - { - return !(a == b); - } - template - constexpr bool operator!=(const flag_combo& a, const flag_combo& b) - { - return !(a == b); - } - template - constexpr bool operator!=(const flag_combo& a, const Enum& b) - { - return !(a == b); - } - template - constexpr bool operator!=(const Enum& a, const flag_combo& b) - { - return !(a == b); - } - - template - constexpr flag_combo operator|(const flag_combo& a, const flag_combo& b) - { - return a.bitwise_or(b); - } - template - constexpr flag_combo operator|(const flag_combo& a, const Enum& b) - { - return a | flag_combo(b); - } - template - constexpr flag_combo operator|(const Enum& a, const flag_combo& b) - { - return flag_combo(a) | b; - } - - template - constexpr bool operator==(const flag_mask& a, const flag_mask& b) - { - return a.to_int() == b.to_int(); - } - template - constexpr bool operator==(const flag_mask& a, noflag_t) - { - return a == a.none_set(); - } - template - constexpr bool operator==(noflag_t, const flag_mask& a) - { - return a == a.none_set(); - } - template - constexpr bool operator!=(const flag_mask& a, const flag_mask& b) - { - return !(a == b); - } - template - constexpr bool operator!=(const flag_mask& a, noflag_t b) - { - return !(a == b); - } - template - constexpr bool operator!=(noflag_t a, const flag_mask& b) - { - return !(a == b); - } - - template - constexpr flag_mask operator&(const flag_mask& a, const flag_mask& b) - { - return a.bitwise_and(b); - } - - template - constexpr flag_mask operator~(const flag_combo& a) - { - return flag_mask(a.toggle_all()); - } - template - constexpr flag_combo operator~(const flag_mask& a) - { - return flag_combo(a.toggle_all()); - } - - template - struct is_flag_combo : std::false_type - {}; - - template - struct is_flag_combo : flag_set_traits - {}; - - template - struct is_flag_combo, Enum> : flag_set_traits - {}; - - template - using enable_flag = typename std::enable_if::value>::type; - - template - using enable_flag_combo = typename std::enable_if::value>::type; - - struct get_flag_set_impl - { - template - static constexpr auto get(const Set& set) -> decltype(set.flags_) - { - return set.flags_; - } - }; -} // namespace detail - -/// Represents a combination of multiple flags. -/// -/// This type is created when you write `a | b`, -/// where `a` and `b` are enumerators of a flag. -/// -/// Objects of this type and the flags themselves -/// are flag combinations. -/// You can compare two flag combinations, -/// combine two with `|` -/// and use them in [ts::flag_set]() to set or toggle a combination of flags. -/// Creating the complement with `~` will create a [ts::flag_mask](). -/// -/// \requires `Enum` must be a flag, -/// i.e. valid with the [ts::flag_set_traits](). -template -using flag_combo = detail::flag_combo; - -/// Represents a mask of flags. -/// -/// This type is created when you write `~a`, -/// where `a` is the enumerator of a flag. -/// -/// Objects of this type are flag masks. -/// You can compare two flag masks, -/// combine them with `&` -/// and use them in [ts::flag_set]() to clear a combination of flags. -/// Creating the complement with `~` will create a [ts::flag_combo](). -/// -/// \requires `Enum` must be a flag, -/// i.e. valid with the [ts::flag_set_traits](). -template -using flag_mask = detail::flag_mask; - -/// Converts a flag mask to a flag combination. -/// \returns The flag combination with the same value as the mask. -/// \notes As you cannot use a mask to set flags in a [ts::flag_set](), -/// you cannot write `~a` to set all flags except `a` directly, -/// you have to be explicit. -template -constexpr flag_combo combo(const flag_mask& mask) noexcept -{ - return flag_combo(mask); -} - -/// Converts a flag combination to a flag mask. -/// \returns The flag mask with the same value as the flag combination. -/// \notes (1) does not participate in overload resolution, -/// unless the argument is a flagg. -/// \notes As you cannot use a combination to clear flags in a [ts::flag_set](), -/// you cannot write `a` to clear all flags except `a` directly, -/// you have to be explicit. -/// \group mask_combo -/// \param 1 -/// \exclude -template > -constexpr flag_mask mask(const Enum& flag) noexcept -{ - return flag_mask(flag); -} - -/// \group mask_combo -template -constexpr flag_mask mask(const flag_combo& combo) noexcept -{ - return flag_mask(combo); -} - -/// A set of flags where each one can either be `0` or `1`. -/// -/// Each enumeration member represents the index of one bit. -/// -/// Unlike [ts::flag_combo]() or [ts::flag_mask]() this does not have this semantic distinction. -/// It is just a generic container of flags, -/// which can be set, cleared or toggled. -/// It can be interpreted as either a flag combination or flag mask, however. -/// -/// \requires `Enum` must be a flag, -/// i.e. valid with the [ts::flag_set_traits](). -template -class flag_set -{ - static_assert(std::is_enum::value, "not an enum"); - static_assert(flag_set_traits::value, "invalid enum for flag_set"); - -public: - //=== constructors/assignment ===// - /// \effects Creates a set where all flags are set to `0`. - /// \group ctor_null - constexpr flag_set() noexcept : flags_(detail::flag_set_impl::none_set()) {} - - /// \group ctor_null - constexpr flag_set(noflag_t) noexcept : flag_set() {} - - /// \effects Creates a set where all bits are set to `0` except the given ones. - /// \notes This constructor only participates in overload resolution - /// if the argument is a flag combination. - template > - constexpr flag_set(const FlagCombo& combo) noexcept : flags_(combo) - {} - - /// \effects Same as `*this = flag_set(combo)`. - template > - flag_set& operator=(const FlagCombo& combo) noexcept - { - return *this = flag_set(combo); - } - - /// \effects Same as [*reset_all](). - flag_set& operator=(noflag_t) noexcept - { - reset_all(); - return *this; - } - - //=== flag operation ===// - /// \effects Sets the specified flag to `1` (1)/`value` (2/3). - /// \notes (2) does not participate in overload resolution unless `T` is a boolean-like type. - /// \group set - void set(const Enum& flag) noexcept - { - flags_ = flags_.set(flag); - } - - /// \group set - /// \param 1 - /// \exclude - template > - void set(const Enum& flag, T value) noexcept - { - if (value) - set(flag); - else - reset(flag); - } - - /// \group set - void set(const Enum& f, flag value) noexcept - { - set(f, value == true); - } - - /// \effects Sets the specified flag to `0`. - void reset(const Enum& flag) noexcept - { - flags_ = flags_.reset(flag); - } - - /// \effects Toggles the specified flag. - void toggle(const Enum& flag) noexcept - { - flags_ = flags_.toggle(flag); - } - - /// \effects Sets/resets/toggles all flags. - /// \group all - void set_all() noexcept - { - flags_ = flags_.all_set(); - } - - /// \group all - /// \param 1 - /// \exclude - template > - void set_all(T value) noexcept - { - if (value) - set_all(); - else - reset_all(); - } - - /// \group all - void set_all(flag value) noexcept - { - set_all(value == true); - } - - /// \group all - void reset_all() noexcept - { - flags_ = flags_.none_set(); - } - - /// \group all - void toggle_all() noexcept - { - flags_ = flags_.toggle_all(); - } - - /// \returns Whether or not the specified flag is set. - constexpr bool is_set(const Enum& flag) const noexcept - { - return flags_.is_set(flag); - } - - /// \returns Same as `flag(is_set(flag))`. - constexpr flag as_flag(const Enum& flag) const noexcept - { - return is_set(flag); - } - - //=== accessors ===// - /// \returns Whether any flag is set. - constexpr bool any() const noexcept - { - return flags_.to_int() != flags_.none_set().to_int(); - } - - /// \returns Whether all flags are set. - constexpr bool all() const noexcept - { - return flags_.to_int() == flags_.all_set().to_int(); - } - - /// \returns Whether no flag is set. - constexpr bool none() const noexcept - { - return !any(); - } - - /// \returns An integer where each bit has the value of the corresponding flag. - /// \requires `T` must be an unsigned integer type with enough bits. - template - constexpr T to_int() const noexcept - { - static_assert(std::is_unsigned::value - && sizeof(T) * CHAR_BIT >= flag_set_traits::size(), - "invalid integer type, lossy conversion"); - return flags_.to_int(); - } - - //=== bitwise operations ===// - /// \returns A set with all the flags flipped. - constexpr flag_set operator~() const noexcept - { - return flag_set(flag_combo(flags_.toggle_all())); - } - - /// \effects Sets all flags that are set in the given flag combination. - /// \returns `*this` - /// \notes This operator does not participate in overload resolution, - /// unless the argument is a flag combination. - /// If you truly want to write `set |= ~a`, - /// i.e. set all flags except `a`, use `set |= combo(~a)`. - template > - flag_set& operator|=(const FlagCombo& other) noexcept - { - flags_ = flags_.bitwise_or(detail::flag_set_impl(other)); - return *this; - } - - /// \effects Toggles all flags that are set in the given flag combination. - /// \returns `*this` - /// \notes This operator does not participate in overload resolution, - /// unless the argument is a flag combination. - /// If you truly want to write `set ^= ~a`, - /// i.e. toggle all flags except `a`, use `set ^= combo(~a)`. - template > - flag_set& operator^=(const FlagCombo& other) noexcept - { - flags_ = flags_.bitwise_xor(detail::flag_set_impl(other)); - return *this; - } - - /// \effects Clears all flags that aren't set in the given flag mask. - /// \returns `*this` - /// \notes This operator does not participate in overload resolution, - /// unless the argument is a flag mask. - /// If you truly want to write `set &= a`, - /// i.e. clear all flags except `a`, use `set &= mask(a)`. - flag_set& operator&=(const flag_mask& other) noexcept - { - flags_ = flags_.bitwise_and(detail::flag_set_impl(other)); - return *this; - } - -private: - detail::flag_set_impl flags_; - - friend detail::get_flag_set_impl; -}; - -/// Converts a [ts::flag_set]() to a flag combination. -/// \returns The flag combination with the same value as the set. -template -constexpr flag_combo combo(const flag_set& set) noexcept -{ - return flag_combo(detail::get_flag_set_impl::get(set)); -} - -/// Converts a [ts::flag_set]() to a flag mask. -/// \returns The flag mask with the same value as the set. -template -constexpr flag_mask mask(const flag_set& set) noexcept -{ - return flag_mask(detail::get_flag_set_impl::get(set)); -} - -/// `flag_set` equality comparison. -/// \returns Whether both flag sets have the same combination of flags set/not set. -/// \group flag_set_equal flag_set equality comparison -template -constexpr bool operator==(const flag_set& a, const flag_set& b) noexcept -{ - return combo(a) == combo(b); -} - -/// \group flag_set_equal -template -constexpr bool operator==(const flag_set& a, noflag_t b) noexcept -{ - return combo(a) == b; -} - -/// \group flag_set_equal -template -constexpr bool operator==(noflag_t a, const flag_set& b) noexcept -{ - return a == combo(b); -} - -/// \group flag_set_equal -template > -constexpr bool operator==(const flag_set& a, const FlagCombo& b) noexcept -{ - return combo(a) == b; -} - -/// \group flag_set_equal -template > -constexpr bool operator==(const FlagCombo& a, const flag_set& b) noexcept -{ - return a == combo(b); -} - -/// \group flag_set_equal -template -constexpr bool operator!=(const flag_set& a, const flag_set& b) noexcept -{ - return !(a == b); -} - -/// \group flag_set_equal -template -constexpr bool operator!=(const flag_set& a, noflag_t b) noexcept -{ - return !(a == b); -} - -/// \group flag_set_equal -template -constexpr bool operator!=(noflag_t a, const flag_set& b) noexcept -{ - return !(a == b); -} - -/// \group flag_set_equal -template > -constexpr bool operator!=(const flag_set& a, const FlagCombo& b) noexcept -{ - return !(a == b); -} - -/// \group flag_set_equal -template > -constexpr bool operator!=(const FlagCombo& a, const flag_set& b) noexcept -{ - return !(a == b); -} - -/// \returns The same as `a Op= b`. -/// \group bitwise_op Bitwise operations for flag_set -/// \param 2 -/// \exclude -template > -constexpr flag_set operator|(const flag_set& a, const FlagCombo& b) -{ - return combo(a).bitwise_or(flag_combo(b)); -} -/// \group bitwise_op -/// \param 2 -/// \exclude -template > -constexpr flag_set operator|(const FlagCombo& a, const flag_set& b) -{ - return b | a; -} -/// \group bitwise_op -/// \param 2 -/// \exclude -template > -constexpr flag_set operator^(const flag_set& a, const FlagCombo& b) -{ - return combo(a).bitwise_xor(flag_combo(b)); -} -/// \group bitwise_op -/// \param 2 -/// \exclude -template > -constexpr flag_set operator^(const FlagCombo& a, const flag_set& b) -{ - return b ^ a; -} -/// \group bitwise_op -template -constexpr flag_set operator&(const flag_set& a, const flag_mask& b) -{ - return combo(mask(a).bitwise_and(b)); -} -/// \group bitwise_op -template -constexpr flag_set operator&(const flag_mask& a, const flag_set& b) -{ - return b & a; -} - -/// Checks whether a combination of flags is set in `a`. -/// \returns `true` if all the flags set in `b` are also set in `a`, -/// `false` otherwise. -/// \notes These functions do not participate in overload resolution, -/// unless `FlagCombo` is a flag operation. -/// \group bitwise_and_check Bitwise and for flag_set -/// \param 2 -/// \exclude -template > -constexpr bool operator&(const flag_set& a, const FlagCombo& b) -{ - return static_cast(combo(a).bitwise_and(flag_combo(b)).to_int()); -} -/// \group bitwise_and_check -/// \param 2 -/// \exclude -template > -constexpr bool operator&(const FlagCombo& a, const flag_set& b) -{ - return b & a; -} -} // namespace type_safe - -/// Creates a [ts::flag_mask]() for the single enum value. -/// \returns A [ts::flag_mask]() where all bits are set, -/// unless the given one. -/// \notes This function does not participate in overload resolution, -/// unless `Enum` is an `enum` where the [ts::flag_set_traits]() are specialized. -/// \param 1 -/// \exclude -template > -constexpr type_safe::flag_mask operator~(const Enum& e) noexcept -{ - return type_safe::flag_mask::all_set().reset(e); -} - -/// Creates a [ts::flag_combo]() from two enums. -/// \returns A [ts::flag_combo]() where the two given bits are set. -/// \notes These functions do not participate in overload resolution, -/// unless `Enum` is an `enum` where the [ts::flag_set_traits]() are specialized. -/// \param 1 -/// \exclude -template > -constexpr type_safe::flag_combo operator|(const Enum& a, const Enum& b) noexcept -{ - return type_safe::flag_combo(a) | b; -} - -#endif // TYPE_SAFE_FLAG_SET_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/floating_point.hpp b/third/type_safe/include/type_safe/floating_point.hpp deleted file mode 100644 index 8a613a2c..00000000 --- a/third/type_safe/include/type_safe/floating_point.hpp +++ /dev/null @@ -1,465 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_FLOATING_POINT_HPP_INCLUDED -#define TYPE_SAFE_FLOATING_POINT_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#endif - -#include - -namespace type_safe -{ -template -class floating_point; - -/// \exclude -namespace detail -{ - template - struct is_safe_floating_point_conversion - : std::integral_constant::value - && std::is_floating_point::value - && sizeof(From) <= sizeof(To)> - {}; - - template - using enable_safe_floating_point_conversion = - typename std::enable_if::value>::type; - - template - using fallback_safe_floating_point_conversion = - typename std::enable_if::value>::type; - - template - struct is_safe_floating_point_comparison - : std::integral_constant::value - || is_safe_floating_point_conversion::value> - {}; - - template - using enable_safe_floating_point_comparison = - typename std::enable_if::value>::type; - - template - using fallback_safe_floating_point_comparison = - typename std::enable_if::value>::type; - - template - struct is_safe_floating_point_operation - : std::integral_constant::value && std::is_floating_point::value> - {}; - - template - using floating_point_result_t = floating_point::value, - typename std::conditional::type>::type>; - template - using fallback_floating_point_result = - typename std::enable_if::value>::type; -} // namespace detail - -/// A type safe floating point class. -/// -/// It is a tiny, no overhead wrapper over a standard floating point type. -/// It behaves exactly like the built-in types except it does not allow narrowing conversions. -/// -/// \requires `FloatT` must be a floating point type. -/// \notes It intentionally does not provide equality or increment/decrement operators. -/// \module types -template -class floating_point -{ - static_assert(std::is_floating_point::value, "must be a floating point type"); - -public: - using floating_point_type = FloatT; - - //=== constructors ===// -#if TYPE_SAFE_DELETE_FUNCTIONS - /// \exclude - floating_point() = delete; -#endif - - /// \effects Initializes the floating point with the given value. - /// \notes These functions do not participate in overload resolution, - /// if `T` is not a floating point type safely convertible to this type. - /// \group constructor - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE constexpr floating_point(const T& val) noexcept : value_(val) - {} - - /// \group constructor - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE constexpr floating_point(const floating_point& val) noexcept - : value_(static_cast(val)) - {} - -#if TYPE_SAFE_DELETE_FUNCTIONS - /// \exclude - template > - constexpr floating_point(T) = delete; - /// \exclude - template > - constexpr floating_point(const floating_point&) = delete; -#endif - - //=== assignment ===// - /// \effects Assigns the floating point the given value. - /// \notes These functions do not participate in overload resolution, - /// if `T` is not a floating point type safely convertible to this type. - /// \group assignment - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE floating_point& operator=(const T& val) noexcept - { - value_ = val; - return *this; - } - - /// \group assignment - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE floating_point& operator=(const floating_point& val) noexcept - { - value_ = static_cast(val); - return *this; - } - -#if TYPE_SAFE_DELETE_FUNCTIONS - /// \exclude - template > - floating_point& operator=(T) = delete; - /// \exclude - template > - floating_point& operator=(const floating_point&) = delete; -#endif - - //=== conversion back ===// - /// \returns The stored value as the native floating point type. - /// \group conversion - TYPE_SAFE_FORCE_INLINE explicit constexpr operator floating_point_type() const noexcept - { - return value_; - } - - /// \group conversion - TYPE_SAFE_FORCE_INLINE constexpr floating_point_type get() const noexcept - { - return value_; - } - - //=== unary operators ===// - /// \returns The value unchanged. - TYPE_SAFE_FORCE_INLINE constexpr floating_point operator+() const noexcept - { - return *this; - } - - /// \returns The negative value. - TYPE_SAFE_FORCE_INLINE constexpr floating_point operator-() const noexcept - { - return -value_; - } - -//=== compound assignment ====// -/// \entity TYPE_SAFE_DETAIL_MAKE_OP -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op) \ - /** \group compound_assign \ - * \module types \ - * \param 1 \ - * \exclude \ - */ \ - template > \ - TYPE_SAFE_FORCE_INLINE floating_point& operator Op(const T& other) noexcept \ - { \ - return *this Op floating_point(other); \ - } \ - /** \exclude */ \ - template > \ - floating_point& operator Op(floating_point) = delete; \ - /** \exclude */ \ - template > \ - floating_point& operator Op(T) = delete; - - /// \effects Same as the operation on the floating point type. - /// \notes These functions do not participate in overload resolution, - /// if `T` is not a floating point type safely convertible to this type. - /// \group compound_assign Compound assignment - /// \module types - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE floating_point& operator+=(const floating_point& other) noexcept - { - value_ += static_cast(other); - return *this; - } - TYPE_SAFE_DETAIL_MAKE_OP(+=) - - /// \group compound_assign - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE floating_point& operator-=(const floating_point& other) noexcept - { - value_ -= static_cast(other); - return *this; - } - TYPE_SAFE_DETAIL_MAKE_OP(-=) - - /// \group compound_assign - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE floating_point& operator*=(const floating_point& other) noexcept - { - value_ *= static_cast(other); - return *this; - } - TYPE_SAFE_DETAIL_MAKE_OP(*=) - - /// \group compound_assign - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE floating_point& operator/=(const floating_point& other) noexcept - { - value_ /= static_cast(other); - return *this; - } - TYPE_SAFE_DETAIL_MAKE_OP(/=) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -private: - floating_point_type value_; -}; - -//=== comparison ===// -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op) \ - /** \group float_comp \ - * \param 2 \ - * \exclude */ \ - template > \ - TYPE_SAFE_FORCE_INLINE constexpr bool operator Op(const A& a, const floating_point& b) \ - { \ - return floating_point(a) Op b; \ - } \ - /** \group float_comp \ - * \param 2 \ - * \exclude */ \ - template > \ - TYPE_SAFE_FORCE_INLINE constexpr bool operator Op(const floating_point& a, const B& b) \ - { \ - return a Op floating_point(b); \ - } \ - /** \exclude */ \ - template > \ - constexpr bool operator Op(floating_point, floating_point) = delete; \ - /** \exclude */ \ - template > \ - constexpr bool operator Op(A, floating_point) = delete; \ - /** \exclude */ \ - template > \ - constexpr bool operator Op(floating_point, B) = delete; - -/// \returns The result of the comparison of the stored floating point value in the -/// [ts::floating_point](). \notes These functions do not participate in overload resolution unless -/// `A` and `B` are both floating point types. \group float_comp Comparison operators \module types -/// \param 2 -/// \exclude -template > -TYPE_SAFE_FORCE_INLINE constexpr bool operator<(const floating_point& a, - const floating_point& b) noexcept -{ - return static_cast(a) < static_cast(b); -} -TYPE_SAFE_DETAIL_MAKE_OP(<) - -/// \group float_comp -/// \param 2 -/// \exclude -template > -TYPE_SAFE_FORCE_INLINE constexpr bool operator<=(const floating_point& a, - const floating_point& b) noexcept -{ - return static_cast(a) <= static_cast(b); -} -TYPE_SAFE_DETAIL_MAKE_OP(<=) - -/// \group float_comp -/// \param 2 -/// \exclude -template > -TYPE_SAFE_FORCE_INLINE constexpr bool operator>(const floating_point& a, - const floating_point& b) noexcept -{ - return static_cast(a) > static_cast(b); -} -TYPE_SAFE_DETAIL_MAKE_OP(>) - -/// \group float_comp -/// \param 2 -/// \exclude -template > -TYPE_SAFE_FORCE_INLINE constexpr bool operator>=(const floating_point& a, - const floating_point& b) noexcept -{ - return static_cast(a) >= static_cast(b); -} -TYPE_SAFE_DETAIL_MAKE_OP(>=) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -//=== binary operations ===// -/// \entity TYPE_SAFE_DETAIL_MAKE_OP -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op) \ - /** \group float_binary_op */ \ - template \ - TYPE_SAFE_FORCE_INLINE constexpr auto operator Op(const A& a, \ - const floating_point& b) noexcept \ - ->detail::floating_point_result_t \ - { \ - return floating_point(a) Op b; \ - } \ - /** \group float_binary_op */ \ - template \ - TYPE_SAFE_FORCE_INLINE constexpr auto operator Op(const floating_point& a, \ - const B& b) noexcept \ - ->detail::floating_point_result_t \ - { \ - return a Op floating_point(b); \ - } \ - /** \exclude */ \ - template > \ - constexpr int operator Op(floating_point, floating_point) noexcept = delete; \ - /** \exclude */ \ - template > \ - constexpr int operator Op(A, floating_point) noexcept = delete; \ - /** \exclude */ \ - template > \ - constexpr int operator Op(floating_point, B) noexcept = delete; - -/// \returns The result of the binary operation of the stored floating point value in the -/// [ts::floating_point](). The type is a [ts::floating_point]() of the bigger floating point type. -/// \notes These functions do not participate in overload resolution, -/// unless `A` and `B` are both floating point types. -/// \module types -/// \group float_binary_op Binary operations -template -TYPE_SAFE_FORCE_INLINE constexpr auto operator+(const floating_point& a, - const floating_point& b) noexcept - -> detail::floating_point_result_t -{ - return static_cast(a) + static_cast(b); -} -TYPE_SAFE_DETAIL_MAKE_OP(+) - -/// \group float_binary_op -template -TYPE_SAFE_FORCE_INLINE constexpr auto operator-(const floating_point& a, - const floating_point& b) noexcept - -> detail::floating_point_result_t -{ - return static_cast(a) - static_cast(b); -} -TYPE_SAFE_DETAIL_MAKE_OP(-) - -/// \group float_binary_op -template -TYPE_SAFE_FORCE_INLINE constexpr auto operator*(const floating_point& a, - const floating_point& b) noexcept - -> detail::floating_point_result_t -{ - return static_cast(a) * static_cast(b); -} -TYPE_SAFE_DETAIL_MAKE_OP(*) - -/// \group float_binary_op -template -TYPE_SAFE_FORCE_INLINE constexpr auto operator/(const floating_point& a, - const floating_point& b) noexcept - -> detail::floating_point_result_t -{ - return static_cast(a) / static_cast(b); -} -TYPE_SAFE_DETAIL_MAKE_OP(/) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -//=== input/output ===/ -/// \effects Reads a float from the [std::istream]() and assigns it to the given -/// [ts::floating_point](). \module types \output_section Input/output -template -std::basic_istream& operator>>(std::basic_istream& in, - floating_point& f) -{ - FloatT val; - in >> val; - f = val; - return in; -} - -/// \effects Converts the given [ts::floating_point]() to the underlying floating point and writes -/// it to the [std::ostream](). \module types -template -std::basic_ostream& operator<<(std::basic_ostream& out, - const floating_point& f) -{ - return out << static_cast(f); -} -} // namespace type_safe - -namespace std -{ -/// Hash specialization for [ts::floating_point]. -/// \module types -template -struct hash> -{ - std::size_t operator()(const type_safe::floating_point& f) const noexcept - { - return std::hash()(static_cast(f)); - } -}; -} // namespace std - -#endif // TYPE_SAFE_FLOATING_POINT_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/index.hpp b/third/type_safe/include/type_safe/index.hpp deleted file mode 100644 index eb3c0e3c..00000000 --- a/third/type_safe/include/type_safe/index.hpp +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_INDEX_HPP_INCLUDED -#define TYPE_SAFE_INDEX_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#endif - -#include -#include -#include - -namespace type_safe -{ -/// A type modelling the difference between two [ts::index_t]() objects. -/// -/// It is a [ts::strong_typedef]() for [ts::ptrdiff_t](). -/// It is comparable and you can add and subtract two differences. -/// \module types -struct difference_t : strong_typedef, - strong_typedef_op::equality_comparison, - strong_typedef_op::relational_comparison, - strong_typedef_op::unary_plus, - strong_typedef_op::unary_minus, - strong_typedef_op::addition, - strong_typedef_op::subtraction -{ - /// \effects Initializes it to `0`. - constexpr difference_t() noexcept : strong_typedef(0) {} - - /// \effects Initializes it from a valid `signed` integer type. - /// \notes This constructor does not participate in overload resolution, - /// if `T` is not safely convertible to [ts::ptrdiff_t](). - /// \group int_ctor - /// \param 1 - /// \exclude - template ::value>::type> - constexpr difference_t(T i) noexcept : strong_typedef(i) - {} - - /// \group int_ctor - /// \param 1 - /// \exclude - template ::value>::type> - constexpr difference_t(integer i) noexcept : strong_typedef(static_cast(i)) - {} -}; - -/// A type modelling an index into an array. -/// -/// It is a [ts::strong_typedef]() for [ts::size_t](). -/// It is comparable and you can increment and decrement it, -/// as well as adding/subtracting a [ts::distance_t](). -/// \notes It has a similar interface to a `RandomAccessIterator`, -/// but without the dereference functions. -/// \module types -struct index_t : strong_typedef, - strong_typedef_op::equality_comparison, - strong_typedef_op::relational_comparison, - strong_typedef_op::increment, - strong_typedef_op::decrement, - strong_typedef_op::unary_plus -{ - /// \effects Initializes it to `0`. - constexpr index_t() noexcept : strong_typedef(0u) {} - - /// \effects Initializes it from a valid `unsigned` integer type. - /// \notes This constructor does not participate in overload resolution, - /// if `T` is not safely convertible to [ts::size_t](). - /// \group int_ctor - /// \param 1 - /// \exclude - template ::value>::type> - constexpr index_t(T i) noexcept : strong_typedef(i) - {} - - /// \group int_ctor - /// \param 1 - /// \exclude - template ::value>::type> - constexpr index_t(integer i) noexcept : strong_typedef(static_cast(i)) - {} - - /// \effects Advances the index by the distance specified in `rhs`. - /// If `rhs` is a negative distance, it advances backwards. - /// \requires The new index must be greater or equal to `0`. - index_t& operator+=(const difference_t& rhs) noexcept - { - get(*this) = make_unsigned(make_signed(get(*this)) + get(rhs)); - return *this; - } - - /// \effects Advances the index backwards by the distance specified in `rhs`. - /// If `rhs` is a negative distance, it advances forwards. - /// \requires The new index must be greater or equal to `0`. - index_t& operator-=(const difference_t& rhs) noexcept - { - get(*this) = make_unsigned(make_signed(get(*this)) - get(rhs)); - return *this; - } -}; - -/// \returns The given [ts::index_t]() advanced by the given [ts::distance_t](). -/// \module types -/// \group index_distance_plus -constexpr index_t operator+(const index_t& lhs, const difference_t& rhs) noexcept -{ - return index_t(make_unsigned(make_signed(get(lhs)) + get(rhs))); -} - -/// \group index_distance_plus -constexpr index_t operator+(const difference_t& lhs, const index_t& rhs) noexcept -{ - return rhs + lhs; -} - -/// \returns The given [ts::index_t]() advanced backwards by the given [ts::distance_t](). -/// \module types -constexpr index_t operator-(const index_t& lhs, const difference_t& rhs) noexcept -{ - return index_t(make_unsigned(make_signed(get(lhs)) - get(rhs))); -} - -/// \returns Returns the distance between two indices. -/// This is the number of steps you need to increment `lhs` to reach `rhs`, -/// it is negative if `lhs > rhs`. -/// \module types -constexpr difference_t operator-(const index_t& lhs, const index_t& rhs) noexcept -{ - return difference_t(make_signed(get(lhs)) - make_signed(get(rhs))); -} - -/// \exclude -namespace detail -{ - struct no_size - {}; - - template - bool index_valid(no_size, const Indexable&, const std::size_t&) - { - return true; - } - - struct non_member_size : no_size - {}; - - template - auto index_valid(non_member_size, const Indexable& obj, const std::size_t& index) - -> decltype(index < size(obj)) - { - return index < size(obj); - } - - struct member_size : non_member_size - {}; - - template - auto index_valid(member_size, const Indexable& obj, const std::size_t& index) - -> decltype(index < obj.size()) - { - return index < obj.size(); - } - - template - bool index_valid(member_size, const T (&)[Size], const std::size_t& index) - { - return index < Size; - } -} // namespace detail - -/// \returns The `i`th element of `obj` by invoking its `operator[]` with the [ts::index_t]() -/// converted to `std::size_t`. \requires `index` must be a valid index for `obj`, i.e. less than -/// the size of `obj`. \exclude return \module types -template -auto at(Indexable&& obj, const index_t& index) - -> decltype(std::forward(obj)[static_cast(get(index))]) -{ - DEBUG_ASSERT(detail::index_valid(detail::member_size{}, obj, - static_cast(get(index))), - detail::precondition_error_handler{}); - return std::forward(obj)[static_cast(get(index))]; -} - -/// \effects Increments the [ts::index_t]() by the specified distance. -/// If the distance is negative, decrements the index instead. -/// \notes This is the same as `index += dist` and the equivalent of [std::advance()](). -/// \module types -inline void advance(index_t& index, const difference_t& dist) -{ - index += dist; -} - -/// \returns The distance between two [ts::index_t]() objects, -/// i.e. how often you'd have to increment `a` to reach `b`. -/// \notes This is the same as `b - a` and the equivalent of [std::distance()](). -/// \module types -constexpr difference_t distance(const index_t& a, const index_t& b) -{ - return b - a; -} - -/// \returns The [ts::index_t]() that is `dist` greater than `index`. -/// \notes This is the same as `index + dist` and the equivalent of [std::next()](). -/// \module types -constexpr index_t next(const index_t& index, const difference_t& dist = difference_t(1)) -{ - return index + dist; -} - -/// \returns The [ts::index_t]() that is `dist` smaller than `index`. -/// \notes This is the same as `index - dist` and the equivalent of [std::prev()](). -/// \module types -constexpr index_t prev(const index_t& index, const difference_t& dist = difference_t(1)) -{ - return index - dist; -} -} // namespace type_safe - -#endif // TYPE_SAFE_INDEX_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/integer.hpp b/third/type_safe/include/type_safe/integer.hpp deleted file mode 100644 index 45b39981..00000000 --- a/third/type_safe/include/type_safe/integer.hpp +++ /dev/null @@ -1,769 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_INTEGER_HPP_INCLUDED -#define TYPE_SAFE_INTEGER_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#include -#endif - -#include -#include -#include - -namespace type_safe -{ -template -class integer; - -/// \exclude -namespace detail -{ - template - struct is_integer - : std::integral_constant::value && !std::is_same::value - && !std::is_same::value> - {}; - - template - struct is_safe_integer_conversion - : std::integral_constant::value && detail::is_integer::value - && ((sizeof(From) <= sizeof(To) - && std::is_signed::value == std::is_signed::value) - || (sizeof(From) < sizeof(To) && std::is_unsigned::value - && std::is_signed::value))> - {}; - - template - using enable_safe_integer_conversion = - typename std::enable_if::value>::type; - - template - using fallback_safe_integer_conversion = - typename std::enable_if::value>::type; - - template - struct is_safe_integer_comparison - : std::integral_constant::value - || is_safe_integer_conversion::value> - {}; - - template - struct is_safe_integer_operation - : std::integral_constant::value && detail::is_integer::value - && std::is_signed::value == std::is_signed::value> - {}; - - template - struct integer_result_type - : std::enable_if::value, - typename std::conditional::type> - {}; - - template - using integer_result_t = typename integer_result_type::type; - - template - using fallback_integer_result = - typename std::enable_if::value>::type; -} // namespace detail - -/// A type safe integer class. -/// -/// This is a tiny, no overhead wrapper over a standard integer type. -/// It behaves exactly like the built-in types except that narrowing conversions are not allowed. -/// It also checks against `unsigned` under/overflow in debug mode -/// and marks it as undefined for the optimizer otherwise. -/// -/// A conversion is considered safe if both integer types have the same signedness -/// and the size of the value being converted is less than or equal to the destination size. -/// -/// \requires `IntegerT` must be an integral type except `bool` and `char` (use `signed -/// char`/`unsigned char`). \notes It intentionally does not provide the bitwise operations. \module -/// types -template -class integer -{ - static_assert(detail::is_integer::value, "must be a real integer type"); - -public: - using integer_type = IntegerT; - - //=== constructors ===// -#if TYPE_SAFE_DELETE_FUNCTIONS - /// \exclude - integer() = delete; -#endif - - /// \effects Initializes it with the given value. - /// \notes This function does not participate in overload resolution - /// if `T` is not an integer type safely convertible to this type. - /// \group constructor - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE constexpr integer(const T& val) : value_(val) - {} - - /// \group constructor - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE constexpr integer(const integer& val) - : value_(static_cast(val)) - {} - -#if TYPE_SAFE_DELETE_FUNCTIONS - /// \exclude - template > - constexpr integer(T) = delete; - /// \exclude - template > - constexpr integer(const integer&) = delete; -#endif - - //=== assignment ===// - /// \effects Assigns it with the given value. - /// \notes This function does not participate in overload resolution - /// if `T` is not an integer type safely convertible to this type. - /// \group assignment - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE integer& operator=(const T& val) - { - value_ = val; - return *this; - } - - /// \group assignment - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE integer& operator=(const integer& val) - { - value_ = static_cast(val); - return *this; - } - -#if TYPE_SAFE_DELETE_FUNCTIONS - /// \exclude - template > - constexpr integer(T) = delete; - /// \exclude - template > - integer& operator=(const integer&) = delete; -#endif - - //=== conversion back ===// - /// \returns The stored value as the native integer type. - /// \group conversion - TYPE_SAFE_FORCE_INLINE explicit constexpr operator integer_type() const noexcept - { - return value_; - } - - /// \group conversion - TYPE_SAFE_FORCE_INLINE constexpr integer_type get() const noexcept - { - return value_; - } - - //=== unary operators ===// - /// \returns The integer type unchanged. - TYPE_SAFE_FORCE_INLINE constexpr integer operator+() const - { - return *this; - } - - /// \returns The negative integer type. - /// \requires The integer type must not be unsigned. - TYPE_SAFE_FORCE_INLINE constexpr integer operator-() const - { - static_assert(std::is_signed::value, - "cannot call unary minus on unsigned integer"); - return integer(Policy::template do_multiplication(value_, integer_type(-1))); - } - - /// \effects Increments the integer by one. - /// \group increment - TYPE_SAFE_FORCE_INLINE integer& operator++() - { - value_ = Policy::template do_addition(value_, integer_type(1)); - return *this; - } - - /// \group increment - TYPE_SAFE_FORCE_INLINE integer operator++(int) - { - auto res = *this; - ++*this; - return res; - } - - /// \effects Decrements the integer by one. - /// \group decrement - TYPE_SAFE_FORCE_INLINE integer& operator--() - { - value_ = Policy::template do_subtraction(value_, integer_type(1)); - return *this; - } - - /// \group decrement - TYPE_SAFE_FORCE_INLINE integer operator--(int) - { - auto res = *this; - --*this; - return res; - } - -//=== compound assignment ====// -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op) \ - /** \group compound_assign \ - * \param 1 \ - * \exclude */ \ - template > \ - TYPE_SAFE_FORCE_INLINE integer& operator Op(const T& other) \ - { \ - return *this Op integer(other); \ - } \ - /** \exclude */ \ - template > \ - integer& operator Op(integer) = delete; \ - /** \exclude */ \ - template > \ - integer& operator Op(T) = delete; - - /// \effects Same as the operation on the integer type. - /// \notes These functions do not participate in overload resolution, - /// if `T` is not an integer type safely convertible to this type. - /// \group compound_assign Compound assignment - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE integer& operator+=(const integer& other) - { - value_ = Policy::template do_addition(value_, static_cast(other)); - return *this; - } - TYPE_SAFE_DETAIL_MAKE_OP(+=) - - /// \group compound_assign - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE integer& operator-=(const integer& other) - { - value_ = Policy::template do_subtraction(value_, static_cast(other)); - return *this; - } - TYPE_SAFE_DETAIL_MAKE_OP(-=) - - /// \group compound_assign - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE integer& operator*=(const integer& other) - { - value_ = Policy::template do_multiplication(value_, static_cast(other)); - return *this; - } - TYPE_SAFE_DETAIL_MAKE_OP(*=) - - /// \group compound_assign - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE integer& operator/=(const integer& other) - { - value_ = Policy::template do_division(value_, static_cast(other)); - return *this; - } - TYPE_SAFE_DETAIL_MAKE_OP(/=) - - /// \group compound_assign - /// \param 1 - /// \exclude - template > - TYPE_SAFE_FORCE_INLINE integer& operator%=(const integer& other) - { - value_ = Policy::template do_modulo(value_, static_cast(other)); - return *this; - } - TYPE_SAFE_DETAIL_MAKE_OP(%=) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -private: - integer_type value_; -}; - -//=== operations ===// -/// \exclude -namespace detail -{ - template - struct make_signed - { - using type = typename std::make_signed::type; - }; - - template - struct make_signed> - { - using type = integer::type, Policy>; - }; - - template - struct make_unsigned - { - using type = typename std::make_unsigned::type; - }; - - template - struct make_unsigned> - { - using type = integer::type, Policy>; - }; -} // namespace detail - -/// [std::make_signed]() for [ts::integer](). -/// \module types -/// \exclude target -template -using make_signed_t = typename detail::make_signed::type; - -/// \returns A new integer of the corresponding signed integer type. -/// \requires The value of `i` must fit into signed type. -/// \module types -/// \param 1 -/// \exclude -template ::value>::type> -TYPE_SAFE_FORCE_INLINE constexpr make_signed_t make_signed(const Integer& i) -{ - using result_type = make_signed_t; - return i <= Integer(std::numeric_limits::max()) - ? static_cast(i) - : DEBUG_UNREACHABLE(detail::precondition_error_handler{}, "conversion " - "would " - "overflow"); -} - -/// \returns A new [ts::integer]() of the corresponding signed integer type. -/// \requires The value of `i` must fit into signed type. -/// \module types -template -TYPE_SAFE_FORCE_INLINE constexpr make_signed_t> make_signed( - const integer& i) -{ - return make_signed(static_cast(i)); -} - -/// [std::make_unsigned]() for [ts::integer](). -/// \module types -/// \exclude target -template -using make_unsigned_t = typename detail::make_unsigned::type; - -/// \returns A new integer of the corresponding unsigned integer type. -/// \requires The value of `i` must not be negative. -/// \module types -/// \param 1 -/// \exclude -template ::value>::type> -TYPE_SAFE_FORCE_INLINE constexpr make_unsigned_t make_unsigned(const Integer& i) -{ - using result_type = make_unsigned_t; - return i >= Integer(0) ? static_cast(i) - : DEBUG_UNREACHABLE(detail::precondition_error_handler{}, - "conversion would underflow"); -} - -/// \returns A new [ts::integer]() of the corresponding unsigned integer type. -/// \requires The value of `i` must not be negative. -/// \module types -template -TYPE_SAFE_FORCE_INLINE constexpr make_unsigned_t> make_unsigned( - const integer& i) -{ - return make_unsigned(static_cast(i)); -} - -/// \returns The absolute value of a built-in signed integer. -/// It will be changed to the unsigned return type as well. -/// \module types -/// \param 1 -/// \exclude -template ::value>::type> -TYPE_SAFE_FORCE_INLINE constexpr make_unsigned_t abs(const SignedInteger& i) -{ - return make_unsigned(i > 0 ? i : -i); -} - -/// \returns The absolute value of an [ts::integer](). -/// \module types -/// \param 2 -/// \exclude -template ::value>::type> -TYPE_SAFE_FORCE_INLINE constexpr make_unsigned_t> abs( - const integer& i) -{ - return make_unsigned(i > 0 ? i : -i); -} - -/// \returns `i` unchanged. -/// \notes This is an optimization of `abs()` for unsigned integer types. -/// \module types -/// \param 1 -/// \exclude -template ::value>::type> -TYPE_SAFE_FORCE_INLINE constexpr UnsignedInteger abs(const UnsignedInteger& i) -{ - return i; -} - -/// \returns `i` unchanged. -/// \notes This is an optimization of `abs()` for unsigned integer types. -/// \module types -/// \param 2 -/// \exclude -template ::value>::type> -TYPE_SAFE_FORCE_INLINE constexpr integer abs( - const integer& i) -{ - return i; -} - -//=== comparison ===// -/// \exclude -namespace detail -{ - // A signed, B unsigned - template - TYPE_SAFE_FORCE_INLINE constexpr bool cmp_equal_unsafe_impl(const integer& a, - const integer& b, - std::true_type, - std::false_type) noexcept - { - using UA = typename make_unsigned::type; - return static_cast(a) < 0 ? false : UA(static_cast(a)) == static_cast(b); - } - - // A unsigned, B signed - template - TYPE_SAFE_FORCE_INLINE constexpr bool cmp_equal_unsafe_impl(const integer& a, - const integer& b, - std::false_type, - std::true_type) noexcept - { - using UB = typename make_unsigned::type; - return static_cast(b) < 0 ? false : UB(static_cast(b)) == static_cast(a); - } - - // A and B same signedness - template - TYPE_SAFE_FORCE_INLINE constexpr bool cmp_equal_impl(const integer& a, - const integer& b, - std::true_type) noexcept - { - return static_cast(a) == static_cast(b); - } - - // A and B different signedness - template - TYPE_SAFE_FORCE_INLINE constexpr bool cmp_equal_impl(const integer& a, - const integer& b, - std::false_type) noexcept - { - return cmp_equal_unsafe_impl(a, b, std::is_signed(), std::is_signed()); - } - - // A signed, B unsigned - template - TYPE_SAFE_FORCE_INLINE constexpr bool cmp_less_unsafe_impl(const integer& a, - const integer& b, - std::true_type, - std::false_type) noexcept - { - using UA = typename make_unsigned::type; - return static_cast(a) < 0 ? true : UA(static_cast(a)) < static_cast(b); - } - - // A unsigned, B signed - template - TYPE_SAFE_FORCE_INLINE constexpr bool cmp_less_unsafe_impl(const integer& a, - const integer& b, - std::false_type, - std::true_type) noexcept - { - using UB = typename make_unsigned::type; - return static_cast(b) < 0 ? false : static_cast(a) < UB(static_cast(b)); - } - - // A and B same signedness - template - TYPE_SAFE_FORCE_INLINE constexpr bool cmp_less_impl(const integer& a, - const integer& b, - std::true_type) noexcept - { - return static_cast(a) < static_cast(b); - } - - // A and B different signedness - template - TYPE_SAFE_FORCE_INLINE constexpr bool cmp_less_impl(const integer& a, - const integer& b, - std::false_type) noexcept - { - return cmp_less_unsafe_impl(a, b, std::is_signed(), std::is_signed()); - } - -} // namespace detail - -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op) \ - /** \group int_comp \ - * \param 2 \ - * \exclude */ \ - template \ - TYPE_SAFE_FORCE_INLINE constexpr bool operator Op(const A& a, \ - const integer& b) noexcept \ - { \ - return integer(a) Op b; \ - } \ - /** \group int_comp \ - * \param 2 \ - * \exclude */ \ - template \ - TYPE_SAFE_FORCE_INLINE constexpr bool operator Op(const integer& a, \ - const B& b) noexcept \ - { \ - return a Op integer(b); \ - } - -/// \returns The result of the comparison of the stored integer value in the [ts::integer](). -/// \notes These functions do not participate in overload resolution -/// unless `A` and `B` are both integer types. -/// \group int_comp Comparison operators -/// \module types -/// \param 2 -/// \exclude -template -TYPE_SAFE_FORCE_INLINE constexpr bool operator==(const integer& a, - const integer& b) noexcept -{ - return detail::cmp_equal_impl(a, b, detail::is_safe_integer_comparison()); -} -TYPE_SAFE_DETAIL_MAKE_OP(==) - -/// \group int_comp Comparison operators -/// \param 2 -/// \exclude -template -TYPE_SAFE_FORCE_INLINE constexpr bool operator!=(const integer& a, - const integer& b) noexcept -{ - return !detail::cmp_equal_impl(a, b, detail::is_safe_integer_comparison()); -} -TYPE_SAFE_DETAIL_MAKE_OP(!=) - -/// \group int_comp Comparison operators -/// \param 2 -/// \exclude -template -TYPE_SAFE_FORCE_INLINE constexpr bool operator<(const integer& a, - const integer& b) noexcept -{ - return detail::cmp_less_impl(a, b, detail::is_safe_integer_comparison()); -} -TYPE_SAFE_DETAIL_MAKE_OP(<) - -/// \group int_comp Comparison operators -/// \param 2 -/// \exclude -template -TYPE_SAFE_FORCE_INLINE constexpr bool operator<=(const integer& a, - const integer& b) noexcept -{ - return !detail::cmp_less_impl(b, a, detail::is_safe_integer_comparison()); -} -TYPE_SAFE_DETAIL_MAKE_OP(<=) - -/// \group int_comp Comparison operators -/// \param 2 -/// \exclude -template -TYPE_SAFE_FORCE_INLINE constexpr bool operator>(const integer& a, - const integer& b) noexcept -{ - return detail::cmp_less_impl(b, a, detail::is_safe_integer_comparison()); -} -TYPE_SAFE_DETAIL_MAKE_OP(>) - -/// \group int_comp Comparison operators -/// \param 2 -/// \exclude -template -TYPE_SAFE_FORCE_INLINE constexpr bool operator>=(const integer& a, - const integer& b) noexcept -{ - return !detail::cmp_less_impl(a, b, detail::is_safe_integer_comparison()); -} -TYPE_SAFE_DETAIL_MAKE_OP(>=) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -//=== binary operations ===// -/// \entity TYPE_SAFE_DETAIL_MAKE_OP -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op) \ - /** \exclude return \ - * \group int_binary_op */ \ - template \ - TYPE_SAFE_FORCE_INLINE constexpr auto operator Op(const A& a, const integer& b) \ - ->integer, Policy> \ - { \ - return integer(a) Op b; \ - } \ - /** \exclude return \ - * \group int_binary_op */ \ - template \ - TYPE_SAFE_FORCE_INLINE constexpr auto operator Op(const integer& a, const B& b) \ - ->integer, Policy> \ - { \ - return a Op integer(b); \ - } \ - /** \exclude */ \ - template > \ - constexpr int operator Op(integer, integer) = delete; \ - /** \exclude */ \ - template > \ - constexpr int operator Op(A, integer) = delete; \ - /** \exclude */ \ - template > \ - constexpr int operator Op(integer, B) = delete; - -/// \returns The result of the binary operation of the stored integer value in the [ts::integer](). -/// The type is a [ts::integer]() of the bigger integer type. -/// \notes These functions do not participate in overload resolution, -/// unless `A` and `B` are both integer types. -/// \group int_binary_op Binary operations -/// \module types -/// \exclude return -template -TYPE_SAFE_FORCE_INLINE constexpr auto operator+(const integer& a, - const integer& b) - -> integer, Policy> -{ - using type = detail::integer_result_t; - return Policy::template do_addition(static_cast(a), static_cast(b)); -} -TYPE_SAFE_DETAIL_MAKE_OP(+) - -/// \group int_binary_op -/// \exclude return -template -TYPE_SAFE_FORCE_INLINE constexpr auto operator-(const integer& a, - const integer& b) - -> integer, Policy> -{ - using type = detail::integer_result_t; - return Policy::template do_subtraction(static_cast(a), static_cast(b)); -} -TYPE_SAFE_DETAIL_MAKE_OP(-) - -/// \group int_binary_op -/// \exclude return -template -TYPE_SAFE_FORCE_INLINE constexpr auto operator*(const integer& a, - const integer& b) - -> integer, Policy> -{ - using type = detail::integer_result_t; - return Policy::template do_multiplication(static_cast(a), static_cast(b)); -} -TYPE_SAFE_DETAIL_MAKE_OP(*) - -/// \group int_binary_op -/// \exclude return -template -TYPE_SAFE_FORCE_INLINE constexpr auto operator/(const integer& a, - const integer& b) - -> integer, Policy> -{ - using type = detail::integer_result_t; - return Policy::template do_division(static_cast(a), static_cast(b)); -} -TYPE_SAFE_DETAIL_MAKE_OP(/) - -/// \group int_binary_op -/// \exclude return -template -TYPE_SAFE_FORCE_INLINE constexpr auto operator%(const integer& a, - const integer& b) - -> integer, Policy> -{ - using type = detail::integer_result_t; - return Policy::template do_modulo(static_cast(a), static_cast(b)); -} -TYPE_SAFE_DETAIL_MAKE_OP(%) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -//=== input/output ===/ -/// \effects Reads an integer from the [std::istream]() and assigns it to the given [ts::integer](). -/// \module types -/// \output_section Input/output -template -std::basic_istream& operator>>(std::basic_istream& in, - integer& i) -{ - IntegerT val; - in >> val; - i = val; - return in; -} - -/// \effects Converts the given [ts::integer]() to the underlying integer type and writes it to th -/// [std::ostream](). \module types -template -std::basic_ostream& operator<<(std::basic_ostream& out, - const integer& i) -{ - return out << static_cast(i); -} -} // namespace type_safe - -namespace std -{ -/// Hash specialization for [ts::integer]. -/// \module types -template -struct hash> -{ - std::size_t operator()(const type_safe::integer& i) const noexcept - { - return std::hash()(static_cast(i)); - } -}; -} // namespace std - -#endif // TYPE_SAFE_INTEGER_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/narrow_cast.hpp b/third/type_safe/include/type_safe/narrow_cast.hpp deleted file mode 100644 index 47187b1a..00000000 --- a/third/type_safe/include/type_safe/narrow_cast.hpp +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_NARROW_CAST_HPP_INCLUDED -#define TYPE_SAFE_NARROW_CAST_HPP_INCLUDED - -#include -#include - -namespace type_safe -{ -/// \exclude -namespace detail -{ - template - struct get_target_underlying_integer - { - using type = T; - }; - template - struct get_target_underlying_integer> - { - using type = T; - }; - - template - struct get_target_integer - { - using type = integer; - }; - template - struct get_target_integer, Policy> - { - using type = integer; - }; - - template - struct get_target_floating_point - { - using type = floating_point; - }; - template - struct get_target_floating_point> - { - using type = floating_point; - }; - - template - TYPE_SAFE_FORCE_INLINE constexpr bool is_narrowing( - const Source& source, - typename std::enable_if::value, int>::type = 0) - { - using limits = std::numeric_limits; - return sizeof(Target) < sizeof(Source) // no narrowing possible - && (source > Source(limits::max()) - || source < Source(limits::min())); // otherwise check bounds - } - - template - TYPE_SAFE_FORCE_INLINE constexpr bool is_narrowing( - const Source& source, - typename std::enable_if::value, int>::type = 0) - - { - return sizeof(Target) < sizeof(Source) // no narrowing possible - // cast source -> underlying float -> target float -> - // source and check if it changed the value - && static_cast(static_cast(source)) != source; - } -} // namespace detail - -/// \returns An arithmetic type with the same value as in `source`, -/// but converted to to a different type. -/// \requires The value of `source` must be representable by the new target type. -/// \module types -/// \param 2 -/// \exclude -template ::value>::type> -TYPE_SAFE_FORCE_INLINE constexpr Target narrow_cast(const Source& source) noexcept -{ - using underlying = typename detail::get_target_underlying_integer::type; - return detail::is_narrowing(source) - ? DEBUG_UNREACHABLE(detail::precondition_error_handler{}, - "conversion would truncate value") - : static_cast(static_cast(source)); -} - -/// \returns A [ts::integer]() with the same value as `source` but of a different type. -/// \requires The value of `source` must be representable by the new target type. -/// \notes `Target` can either be a specialization of the `integer` template itself -/// or a built-in integer type, the result will be wrapped if needed. -/// \module types -/// \exclude return -template -TYPE_SAFE_FORCE_INLINE constexpr auto narrow_cast(const integer& source) noexcept -> - typename detail::get_target_integer::type -{ - using target_integer = typename detail::get_target_integer::type; - using target_t = typename target_integer::integer_type; - return narrow_cast(static_cast(source)); -} - -/// \returns A [ts::floating_point]() with the same value as `source` but of a different type. -/// \requires The value of `source` must be representable by the new target type. -/// \notes `Target` can either be a specialization of the `floating_point` template itself -/// or a built-in floating point type, the result will be wrapped if needed. -/// \module types -/// \exclude return -template -TYPE_SAFE_FORCE_INLINE constexpr auto narrow_cast(const floating_point& source) noexcept -> - typename detail::get_target_floating_point::type -{ - using target_float = typename detail::get_target_floating_point::type; - using target_t = typename target_float::floating_point_type; - return narrow_cast(static_cast(source)); -} -} // namespace type_safe - -#endif // TYPE_SAFE_NARROW_CAST_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/optional.hpp b/third/type_safe/include/type_safe/optional.hpp deleted file mode 100644 index 014a63d5..00000000 --- a/third/type_safe/include/type_safe/optional.hpp +++ /dev/null @@ -1,1003 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_OPTIONAL_HPP_INCLUDED -#define TYPE_SAFE_OPTIONAL_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#endif - -#include -#include -#include -#include -#include - -namespace type_safe -{ -template -class basic_optional; - -/// \exclude -namespace detail -{ - template - struct optional_storage - { - StoragePolicy storage; - - optional_storage() noexcept = default; - - optional_storage(const optional_storage& other) - { - storage.create_value(other.storage); - } - - optional_storage(optional_storage&& other) noexcept( - std::is_nothrow_move_constructible::value) - { - storage.create_value(std::move(other.storage)); - } - - ~optional_storage() noexcept - { - if (storage.has_value()) - storage.destroy_value(); - } - - optional_storage& operator=(const optional_storage& other) - { - storage.copy_value(other.storage); - return *this; - } - - optional_storage& operator=(optional_storage&& other) noexcept( - std::is_nothrow_move_constructible::value - && (!std::is_move_assignable::value - || std::is_nothrow_move_assignable::value)) - { - storage.copy_value(std::move(other.storage)); - return *this; - } - }; - - template - using optional_copy = copy_control::value>; - - template - using optional_move = move_control::value>; - - //=== is_optional ===// - template - struct is_optional_impl : std::false_type - {}; - - template - struct is_optional_impl> : std::true_type - {}; - - template - using is_optional = is_optional_impl::type>; -} // namespace detail - -template -class basic_optional; - -//=== basic_optional ===// -/// Tag type to mark a [ts::basic_optional]() without a value. -/// \module optional -/// \output_section Basic optional -struct nullopt_t -{ - constexpr nullopt_t() {} -}; - -/// Tag object of type [ts::nullopt_t](). -/// \module optional -constexpr nullopt_t nullopt; - -/// Selects the storage policy used when rebinding a [ts::basic_optional](). -/// -/// Some operations like [ts::basic_optional::map()]() change the type of an optional. -/// This traits controls which `StoragePolicy` is going to be used for the new optional. -/// You can for example requests a [ts::compact_optional_storage]() for your type, -/// simply specialize it and set a `type` typedef. -/// \module optional -template -struct optional_storage_policy_for -{ - using type = void; -}; - -/// Specialization of [ts::optional_storage_policy_for]() for [ts::basic_optional]() itself. -/// -/// It will simply forward to the same policy, so `ts::optional_for>` is simply -/// `ts::optional`, not `ts::optional>`. \module optional -template -struct optional_storage_policy_for> -{ - using type = StoragePolicy; -}; - -template -class reference_optional_storage; - -/// Specialization of [ts::optional_storage_policy_for]() for lvalue references. -/// -/// It will use [ts::reference_optional_storage]() as policy. -/// \module optional -template -struct optional_storage_policy_for -{ - using type = reference_optional_storage; -}; - -/// Specialization of [ts::optional_storage_policy_for]() for rvalue references. -/// -/// They are not supported. -/// \module optional -template -struct optional_storage_policy_for -{ - static_assert(sizeof(T) != sizeof(T), "no optional for rvalue references supported"); -}; - -/// \exclude -namespace detail -{ - template - using select_optional_storage_policy = - typename std::conditional::value, Fallback, - TraitsResult>::type; - - template - using rebind_optional = typename std::conditional< - std::is_void::value, void, - basic_optional::type, - Fallback>>>::type; -} // namespace detail - -/// An optional type, i.e. a type that may or may not be there. -/// -/// It is similar to [std::optional]() but lacks some functions and provides some others. -/// It can be in one of two states: it contains a value of a certain type or it does not (it is -/// "empty"). -/// -/// The storage itself is managed via the `StoragePolicy`. -/// It must provide the following members: -/// * Typedef `value_type` - the type stored in the optional -/// * Typedef `(const_)lvalue_reference` - `const` lvalue reference type -/// * Typedef `(const_)rvalue_reference` - `const` rvalue reference type -/// * Template alias `rebind` - the same policy for a different type -/// * `StoragePolicy() noexcept` - a no-throw default constructor that initializes it in the "empty" -/// state -/// * `void create_value(Args&&... args)` - creates a value by forwarding the arguments to its -/// constructor -/// * `void create_value_explicit(T&& obj)` - creates a value requiring an `explicit` constructor -/// * `void create_value(const StoragePolicy&/StoragePolicy&&)` - creates a value by using the value -/// stored in the other policy -/// * `void copy_value(const StoragePolicy&/StoragePolicy&&)` - similar to above, but *this may -/// contain a value already -/// * `void swap_value(StoragePolicy&)` - swaps the stored value (if any) with the one in the other -/// policy -/// * `void destroy_value() noexcept` - calls the destructor of the value, afterwards the storage is -/// "empty" -/// * `bool has_value() const noexcept` - returns whether or not there is a value, i.e. -/// `create_value()` has been called but `destroy_value()` has not -/// * `U get_value() (const)& noexcept` - returns a reference to the stored value, U is one of the -/// `XXX_reference` typedefs -/// * `U get_value() (const)&& noexcept` - returns a reference to the stored value, U is one of the -/// `XXX_reference` typedefs -/// * `U get_value_or(T&& val) [const&/&&]` - returns either `get_value()` or `val` -/// \module optional -template -class basic_optional : detail::optional_storage, - detail::optional_copy, - detail::optional_move -{ -public: - using storage = StoragePolicy; - using value_type = typename storage::value_type; - - /// Rebinds the current optional to the type `U`. - /// - /// It will use [ts::optional_storage_policy_for]() to determine whether a change of storage - /// policy is needed. \notes If `U` is `void`, the result will be `void` as well. \notes Due to - /// a specialization of [ts::optional_storage_policy_for](), if `U` is an optional itself, the - /// result will be `U`, not an optional of an optional. \exclude target - template - using rebind = detail::rebind_optional>; - -private: - storage& get_storage() TYPE_SAFE_LVALUE_REF noexcept - { - return static_cast&>(*this).storage; - } - - const storage& get_storage() const TYPE_SAFE_LVALUE_REF noexcept - { - return static_cast&>(*this).storage; - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - storage&& get_storage() && noexcept - { - return std::move(static_cast&>(*this).storage); - } - - const storage&& get_storage() const&& noexcept - { - return std::move( - static_cast&>(*this).storage); - } -#endif - -public: - //=== constructors/destructors/assignment/swap ===// - /// \effects Creates it without a value. - /// \group empty - basic_optional() noexcept = default; - - /// \group empty - basic_optional(nullopt_t) noexcept {} - - /// \effects Creates it with a value by forwarding `value`. - /// \throws Anything thrown by the constructor of `value_type`. - /// \requires The `create_value()` function of the `StoragePolicy` must accept `value`. - /// \param 1 - /// \exclude - template ::type, basic_optional>::value>::type> - basic_optional(T&& value, - decltype(std::declval().create_value(std::declval()), 0) = 0) - { - get_storage().create_value(std::forward(value)); - } - - /// \effects Creates it with a value by forwarding `value`. - /// \throws Anything thrown by the constructor of `value_type`. - /// \requires The `create_value_explicit()` function of the `StoragePolicy` must accept `value`. - /// \param 1 - /// \exclude - template < - typename T, - typename std::enable_if< - !std::is_same::type, basic_optional>::value, int>::type - = 0> - explicit basic_optional( - T&& value, - decltype(std::declval().create_value_explicit(std::declval()), 0) = 0) - { - get_storage().create_value_explicit(std::forward(value)); - } - - /// Copy constructor. - /// \effects If `other` does not have a value, it will be created without a value as well. - /// If `other` has a value, it will be created with a value by copying `other.value()`. - /// \throws Anything thrown by the copy constructor of `value_type` if `other` has a value. - /// \notes This constructor will not participate in overload resolution, - /// unless the `value_type` is copy constructible. - basic_optional(const basic_optional& other) = default; - - /// Move constructor. - /// \effects If `other` does not have a value, it will be created without a value as well. - /// If `other` has a value, it will be created with a value by moving `other.value()`. - /// \throws Anything thrown by the move constructor of `value_type` if `other` has a value. - /// \notes `other` will still have a value after the move operation, - /// it is just in a moved-from state./ - /// \notes This constructor will not participate in overload resolution, - /// unless the `value_type` is move constructible. - basic_optional(basic_optional&& other) - TYPE_SAFE_NOEXCEPT_DEFAULT(std::is_nothrow_move_constructible::value) - = default; - - /// Destructor. - /// \effects If it has a value, it will be destroyed. - ~basic_optional() noexcept = default; - - /// \effects Same as `reset()`. - basic_optional& operator=(nullopt_t) noexcept - { - reset(); - return *this; - } - - /// \effects Same as `emplace(std::forward(t))`. - /// \requires The call to `emplace()` must be well-formed. - /// \param 1 - /// \exclude - /// \synopsis_return basic_optional& - template ::type, basic_optional>::value>::type> - auto operator=(T&& value) -> decltype( - std::declval>().get_storage().create_value(std::forward(value)), - *this) - { - emplace(std::forward(value)); - return *this; - } - - /// Copy assignment operator. - /// \effects If `other` has a value, does something equivalent to `emplace(other.value())` (this - /// will always trigger the single parameter version). Otherwise will reset the optional to the - /// empty state. \throws Anything thrown by the call to `emplace()`. \notes This operator will - /// not participate in overload resolution, unless the `value_type` is copy constructible. - basic_optional& operator=(const basic_optional& other) = default; - - /// Move assignment operator. - /// \effects If `other` has a value, does something equivalent to - /// `emplace(std::move(other).value())` (this will always trigger the single parameter version). - /// Otherwise will reset the optional to the empty state. - /// \throws Anything thrown by the call to `emplace()`. - /// \notes This operator will not participate in overload resolution, - /// unless the `value_type` is copy constructible. - basic_optional& operator=(basic_optional&& other) - TYPE_SAFE_NOEXCEPT_DEFAULT(std::is_nothrow_move_constructible::value - && (!std::is_move_assignable::value - || std::is_nothrow_move_assignable::value)) - = default; - - /// \effects Swap. - /// If both `a` and `b` have values, swaps the values with their swap function. - /// Otherwise, if only one of them have a value, moves that value to the other one and makes the - /// moved-from empty. Otherwise, if both are empty, does nothing. \throws Anything thrown by the - /// move construction or swap. - friend void swap(basic_optional& a, basic_optional& b) noexcept( - std::is_nothrow_move_constructible::value&& - detail::is_nothrow_swappable::value) - { - a.get_storage().swap_value(b.get_storage()); - } - - //=== modifiers ===// - /// \effects Destroys the value by calling its destructor, if there is any stored. - /// Afterwards `has_value()` will return `false`. - /// \output_section Modifiers - void reset() noexcept - { - if (has_value()) - get_storage().destroy_value(); - } - - /// \effects First destroys any old value like `reset()`. - /// Then creates the value by perfectly forwarding `args...` to the constructor of `value_type`. - /// \throws Anything thrown by the constructor of `value_type`. - /// If this function is left by an exception, the optional will be empty. - /// \notes If the `create_value()` function of the `StoragePolicy` does not accept the - /// arguments, this function will not participate in overload resolution. \synopsis_return void - template - auto emplace(Args&&... args) noexcept(std::is_nothrow_constructible::value) - -> decltype(std::declval>().get_storage().create_value( - std::forward(args)...)) - { - reset(); - get_storage().create_value(std::forward(args)...); - } - - /// \effects If `has_value()` is `false` creates it by calling the constructor with `arg` - /// perfectly forwarded. Otherwise assigns a perfectly forwarded `arg` to `value()`. \throws - /// Anything thrown by the constructor or assignment operator chosen. \notes This function does - /// not participate in overload resolution unless there is an `operator=` that takes `arg` - /// without an implicit user-defined conversion and the `create_value()` function of the - /// `StoragePolicy` accepts the argument. \synopsis_return void - template ().get_value()), Arg&&>::value>::type> - auto emplace(Arg&& arg) noexcept(std::is_nothrow_constructible::value&& - std::is_nothrow_assignable::value) - -> decltype(std::declval>().get_storage().create_value( - std::forward(arg))) - { - if (!has_value()) - get_storage().create_value(std::forward(arg)); - else - value() = std::forward(arg); - } - - //=== observers ===// - /// \returns The same as `has_value()`. - /// \output_section Observers - explicit operator bool() const noexcept - { - return has_value(); - } - - /// \returns Whether or not the optional has a value. - bool has_value() const noexcept - { - return get_storage().has_value(); - } - - /// Access to the stored value. - /// \returns A reference to the stored value. - /// The exact type depends on the `StoragePolicy`. - /// \requires `has_value() == true`. - /// \group value - auto value() TYPE_SAFE_LVALUE_REF noexcept -> decltype(std::declval().get_value()) - { - DEBUG_ASSERT(has_value(), detail::precondition_error_handler{}); - return get_storage().get_value(); - } - - /// \group value - auto value() const TYPE_SAFE_LVALUE_REF noexcept - -> decltype(std::declval().get_value()) - { - DEBUG_ASSERT(has_value(), detail::precondition_error_handler{}); - return get_storage().get_value(); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group value - auto value() && noexcept -> decltype(std::declval().get_value()) - { - DEBUG_ASSERT(has_value(), detail::precondition_error_handler{}); - return std::move(get_storage()).get_value(); - } - - /// \group value - auto value() const && noexcept -> decltype(std::declval().get_value()) - { - DEBUG_ASSERT(has_value(), detail::precondition_error_handler{}); - return std::move(get_storage()).get_value(); - } -#endif - - /// \returns If it has a value, `value()`, otherwise `u` converted to the same type as - /// `value()`. \requires `u` must be valid argument to the `value_or()` function of the - /// `StoragePolicy`. \notes Depending on the `StoragePolicy`, this either returns a decayed type - /// or a reference. \group value_or - template - auto value_or(U&& u) const TYPE_SAFE_LVALUE_REF - -> decltype(std::declval().get_value_or(std::forward(u))) - { - return get_storage().get_value_or(std::forward(u)); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group value_or - template - auto value_or(U&& u) && -> decltype(std::declval().get_value_or(std::forward(u))) - { - return std::move(get_storage()).get_value_or(std::forward(u)); - } -#endif - - //=== factories ===// - /// Maps an optional. - /// \effects If the optional contains a value, - /// calls the function with the value followed by the additional arguments perfectly forwarded. - /// \returns A `basic_optional` rebound to the result type of the function, - /// that is empty if `*this` is empty and contains the result of the function otherwise. - /// \requires `f` must either be a function or function object of matching signature, - /// or a member function pointer of the stored type with compatible signature. - /// \notes Due to the way [ts::basic_optional::rebind]() works, - /// if the result of the function is `void`, `map()` will return `void` as well, - /// and if the result of the function is an optional itself, - /// `map()` will return the optional unchanged. - /// \unique_name *map - /// \group map - /// \exclude return - template - auto map(Func&& f, Args&&... args) TYPE_SAFE_LVALUE_REF -#if !TYPE_SAFE_USE_RETURN_TYPE_DEDUCTION - -> rebind(f), this->value(), - std::forward(args)...))> -#endif - { - using return_type = decltype( - detail::map_invoke(std::forward(f), value(), std::forward(args)...)); - if (has_value()) - return rebind( - detail::map_invoke(std::forward(f), value(), std::forward(args)...)); - else - return static_cast>(nullopt); - } - - /// \unique_name *map_const - /// \group map - /// \exclude return - template - auto map(Func&& f, Args&&... args) const TYPE_SAFE_LVALUE_REF -#if !TYPE_SAFE_USE_RETURN_TYPE_DEDUCTION - -> rebind(f), this->value(), - std::forward(args)...))> -#endif - { - using return_type = decltype( - detail::map_invoke(std::forward(f), value(), std::forward(args)...)); - if (has_value()) - return rebind( - detail::map_invoke(std::forward(f), value(), std::forward(args)...)); - else - return static_cast>(nullopt); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \unique_name *map_rvalue - /// \group map - /// \exclude return - template - auto map(Func&& f, Args&&... args) && -# if !TYPE_SAFE_USE_RETURN_TYPE_DEDUCTION - -> rebind(f), this->value(), - std::forward(args)...))> -# endif - { - using return_type = decltype( - detail::map_invoke(std::forward(f), value(), std::forward(args)...)); - if (has_value()) - return rebind( - detail::map_invoke(std::forward(f), value(), std::forward(args)...)); - else - return static_cast>(nullopt); - } - - /// \unique_name *map_rvalue_const - /// \group map - /// \exclude return - template - auto map(Func&& f, Args&&... args) const&& -# if !TYPE_SAFE_USE_RETURN_TYPE_DEDUCTION - -> rebind(f), this->value(), - std::forward(args)...))> -# endif - { - using return_type = decltype( - detail::map_invoke(std::forward(f), value(), std::forward(args)...)); - if (has_value()) - return rebind( - detail::map_invoke(std::forward(f), value(), std::forward(args)...)); - else - return static_cast>(nullopt); - } -#endif -}; - -/// \entity TYPE_SAFE_DETAIL_MAKE_OP -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op, Expr, Expr2) \ - template \ - bool operator Op(const basic_optional& lhs, nullopt_t) \ - { \ - return (void)lhs, Expr; \ - } /** \group optional_comp_null */ \ - template \ - bool operator Op(nullopt_t, const basic_optional& rhs) \ - { \ - return (void)rhs, Expr2; \ - } - -/// Comparison of [ts::basic_optional]() with [ts::nullopt](). -/// -/// An optional is equal to [ts::nullopt]() if it does not have a value. -/// Nothing is less than [ts::nullopt](), it is only less than an optional, -/// A optional compares equal to `nullopt`, when it does not have a value. -/// A optional compares never less to `nullopt`, `nullopt` compares less only if the optional has a -/// value. The other comparisons behave accordingly. \group optional_comp_null Optional null -/// comparison \module optional -TYPE_SAFE_DETAIL_MAKE_OP(==, !lhs.has_value(), !rhs.has_value()) -/// \group optional_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(!=, lhs.has_value(), rhs.has_value()) -/// \group optional_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(<, false, rhs.has_value()) -/// \group optional_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(<=, !lhs.has_value(), true) -/// \group optional_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(>, lhs.has_value(), false) -/// \group optional_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(>=, true, !rhs.has_value()) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -/// \entity TYPE_SAFE_DETAIL_MAKE_OP -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op, Expr, Expr2) \ - template \ - auto operator Op(const basic_optional& lhs, const U& rhs) \ - ->decltype(typename StoragePolicy::value_type(lhs.value()) Op rhs) \ - { \ - using value_type = typename StoragePolicy::value_type; \ - return Expr; \ - } \ - /** \synopsis_return bool \ - * \group optional_comp_value */ \ - template \ - auto operator Op(const U& lhs, const basic_optional& rhs) \ - ->decltype(lhs Op typename StoragePolicy::value_type(rhs.value())) \ - { \ - using value_type = typename StoragePolicy::value_type; \ - return Expr2; \ - } - -/// Compares a [ts::basic_optional]() with a value. -/// -/// An optional compares equal to a value if it has a value -/// and the value compares equal. -/// An optional compares less to a value if it does not have a value -/// or the value compares less. -/// A value compares less to an optional if the optional has a value -/// and the value compares less than the optional. -/// The other comparisons behave accordingly. -/// -/// Value comparison is done by the comparison operator of the `value_type`, -/// a function only participates in overload resolution if the `value_type`, -/// has that comparison function. -/// \synopsis_return bool -/// \group optional_comp_value Optional value comparison -/// \module optional -TYPE_SAFE_DETAIL_MAKE_OP(==, lhs.has_value() && value_type(lhs.value()) == rhs, - rhs.has_value() && lhs == value_type(rhs.value())) -/// \synopsis_return bool -/// \group optional_comp_value -TYPE_SAFE_DETAIL_MAKE_OP(!=, !lhs.has_value() || value_type(lhs.value()) != rhs, - !rhs.has_value() || lhs != value_type(rhs.value())) -/// \synopsis_return bool -/// \group optional_comp_value -TYPE_SAFE_DETAIL_MAKE_OP(<, !lhs.has_value() || value_type(lhs.value()) < rhs, - rhs.has_value() && lhs < value_type(rhs.value())) -/// \synopsis_return bool -/// \group optional_comp_value -TYPE_SAFE_DETAIL_MAKE_OP(<=, !lhs.has_value() || value_type(lhs.value()) <= rhs, - rhs.has_value() && lhs <= value_type(rhs.value())) -/// \synopsis_return bool -/// \group optional_comp_value -TYPE_SAFE_DETAIL_MAKE_OP(>, lhs.has_value() && value_type(lhs.value()) > rhs, - !rhs.has_value() || lhs > value_type(rhs.value())) -/// \synopsis_return bool -/// \group optional_comp_value -TYPE_SAFE_DETAIL_MAKE_OP(>=, lhs.has_value() && value_type(lhs.value()) >= rhs, - !rhs.has_value() || lhs >= value_type(rhs.value())) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -/// \entity TYPE_SAFE_DETAIL_MAKE_OP -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op) \ - template \ - auto operator Op(const basic_optional& lhs, \ - const basic_optional& rhs) \ - ->decltype(lhs.value() Op rhs.value()) \ - { \ - return lhs.has_value() ? lhs.value() Op rhs : nullopt Op rhs; \ - } - -/// Compares two [ts::basic_optional]() objects. -/// -/// If `lhs` has a value, forwards to `lhs.value() rhs`. -/// Else forwards to `nullopt rhs`. -/// \synopsis_return bool -/// \group optional_comp Optional comparison -/// \module optional -TYPE_SAFE_DETAIL_MAKE_OP(==) -/// \synopsis_return bool -/// \group optional_comp -TYPE_SAFE_DETAIL_MAKE_OP(!=) -/// \synopsis_return bool -/// \group optional_comp -TYPE_SAFE_DETAIL_MAKE_OP(<) -/// \synopsis_return bool -/// \group optional_comp -TYPE_SAFE_DETAIL_MAKE_OP(<=) -/// \synopsis_return bool -/// \group optional_comp -TYPE_SAFE_DETAIL_MAKE_OP(>) -/// \synopsis_return bool -/// \group optional_comp -TYPE_SAFE_DETAIL_MAKE_OP(>=) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -/// With operation for [ts::optional](). -/// \effects Calls the `operator()` of `f` passing it the value of `opt` and additional arguments, -/// if it has a value. -/// Otherwise does nothing. -/// \module optional -/// \param 3 -/// \exclude -template ::value>::type> -void with(Optional&& opt, Func&& f, Args&&... additional_args) -{ - if (opt.has_value()) - std::forward(f)(std::forward(opt).value(), - std::forward(additional_args)...); -} - -//=== optional ===// -/// A `StoragePolicy` for [ts::basic_optional]() that is similar to [std::optional]()'s -/// implementation. -/// -/// It uses [std::aligned_storage]() and a `bool` flag whether a value was created. -/// \requires `T` must not be a reference. -/// \module optional -/// \output_section Optional -template -class direct_optional_storage -{ - static_assert(!std::is_reference::value, - "T must not be a reference; use optional_ref for that"); - -public: - using value_type = typename std::remove_cv::type; - using lvalue_reference = T&; - using const_lvalue_reference = const T&; - using rvalue_reference = T&&; - using const_rvalue_reference = const T&&; - - template - using rebind = direct_optional_storage; - - /// \effects Initializes it in the state without value. - direct_optional_storage() noexcept : empty_(true) {} - - /// \effects Calls the constructor of `value_type` by perfectly forwarding `args`. - /// Afterwards `has_value()` will return `true`. - /// \throws Anything thrown by the constructor of `value_type` in which case `has_value()` is - /// still `false`. \requires `has_value() == false`. \notes This function does not participate - /// in overload resolution unless `value_type` is constructible from `args`. \synopsis_return - /// void - template - auto create_value(Args&&... args) -> - typename std::enable_if::value>::type - { - ::new (as_void()) value_type(std::forward(args)...); - empty_ = false; - } - - /// \effects Creates a value by copy(1)/move(2) constructing from the value stored in `other`, - /// if there is any. - /// \group create_value - void create_value(const direct_optional_storage& other) - { - if (other.has_value()) - create_value(other.get_value()); - } - - /// \group create_value - void create_value(direct_optional_storage&& other) - { - if (other.has_value()) - create_value(std::move(other.get_value())); - } - - void create_value_explicit() {} - - /// \effects Copies the policy from `other`, by copy-constructing or assigning the stored value, - /// if any. - /// \throws Anything thrown by the copy constructor or copy assignment operator of `other`. - /// \group copy_value - /// \unique_name copy_value_assign - /// \param Dummy - /// \exclude - /// \param 1 - /// \exclude - template ::value>::type> - void copy_value(const direct_optional_storage& other) - { - if (has_value()) - { - if (other.has_value()) - get_value() = other.get_value(); - else - destroy_value(); - } - else if (other.has_value()) - create_value(other.get_value()); - } - - /// \unique_name copy_value_construct - /// \group copy_value - /// \param Dummy - /// \exclude - /// \param 1 - /// \exclude - template ::value, int>::type = 0> - void copy_value(const direct_optional_storage& other) - { - if (has_value()) - destroy_value(); - create_value(other.get_value()); - } - - /// \effects Copies the policy from `other`, by move-constructing or assigning the stored value, - /// if any. - /// \throws Anything thrown by the move constructor or move assignment operator of `other`. - /// \unique_name copy_value_move_assign - /// \group copy_value_move - /// \param Dummy - /// \exclude - /// \param 1 - /// \exclude - template ::value>::type> - void copy_value(direct_optional_storage&& other) - { - if (has_value()) - { - if (other.has_value()) - get_value() = std::move(other).get_value(); - else - destroy_value(); - } - else if (other.has_value()) - create_value(std::move(other).get_value()); - } - - /// \group copy_value_move - /// \param Dummy - /// \exclude - /// \param 1 - /// \exclude - template ::value, int>::type = 0> - void copy_value(direct_optional_storage&& other) - { - if (has_value()) - destroy_value(); - create_value(std::move(other).get_value()); - } - - /// \effects Swaps the value with the value in `other`. - void swap_value(direct_optional_storage& other) - { - if (has_value() && other.has_value()) - { - using std::swap; - swap(get_value(), other.get_value()); - } - else if (has_value()) - { - other.create_value(std::move(get_value())); - destroy_value(); - } - else if (other.has_value()) - { - create_value(std::move(other).get_value()); - other.destroy_value(); - } - } - - /// \effects Calls the destructor of `value_type`. - /// Afterwards `has_value()` will return `false`. - /// \requires `has_value() == true`. - void destroy_value() noexcept - { - get_value().~value_type(); - empty_ = true; - } - - /// \returns Whether or not there is a value stored. - bool has_value() const noexcept - { - return !empty_; - } - - /// \returns A (`const`) (rvalue) reference to the stored value. - /// \requires `has_value() == true`. - /// \group value - lvalue_reference get_value() TYPE_SAFE_LVALUE_REF noexcept - { - return *static_cast(as_void()); - } - - /// \group value - const_lvalue_reference get_value() const TYPE_SAFE_LVALUE_REF noexcept - { - return *static_cast(as_void()); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group value - rvalue_reference get_value() && noexcept - { - return std::move(*static_cast(as_void())); - } - - /// \group value - const_rvalue_reference get_value() const&& noexcept - { - return std::move(*static_cast(as_void())); - } -#endif - - /// \returns Either `get_value()` or `u` converted to `value_type`. - /// \requires `value_type` must be copy(1)/move(2) constructible and `u` convertible to - /// `value_type`. \group get_value_or \param 1 \exclude - template ::value - && std::is_convertible::value>::type> - value_type get_value_or(U&& u) const TYPE_SAFE_LVALUE_REF - { - return has_value() ? get_value() : static_cast(std::forward(u)); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group get_value_or - /// \param 1 - /// \exclude - template ::value - && std::is_convertible::value>::type> - value_type get_value_or(U&& u) && - { - return has_value() ? std::move(get_value()) : static_cast(std::forward(u)); - } -#endif - -private: - void* as_void() noexcept - { - return static_cast(&storage_); - } - - const void* as_void() const noexcept - { - return static_cast(&storage_); - } - - alignas(value_type) unsigned char storage_[sizeof(value_type)]; - bool empty_; -}; - -/// A [ts::basic_optional]() that uses [ts::direct_optional_storage](). -/// \module optional -template -using optional = basic_optional>; - -/// Uses [ts::optional_storage_policy_for]() to select the appropriate [ts::basic_optional](). -/// -/// By default, it uses [ts::direct_optional_storage](). -/// \notes If `T` is `void`, `optional_for` will also be `void`. -/// \module optional -template -using optional_for = basic_optional>::rebind; - -/// \returns A new [ts::optional]() storing a copy of `t`. -/// \module optional -template -optional::type> make_optional(T&& t) -{ - return std::forward(t); -} - -/// \returns A new [ts::optional]() with a value created by perfectly forwarding `args` to the -/// constructor. \module optional -template -optional make_optional(Args&&... args) -{ - optional result; - result.emplace(std::forward(args)...); - return result; -} -} // namespace type_safe - -namespace std -{ -/// Hash for [ts::basic_optional](). -/// \module optional -template -struct hash> -{ - using value_type = typename StoragePolicy::value_type; - using value_hash = std::hash; - - std::size_t operator()(const type_safe::basic_optional& opt) const - noexcept(noexcept(value_hash{}(std::declval()))) - { - return opt ? value_hash{}(opt.value()) : 19937; // magic value - } -}; -} // namespace std - -#endif // TYPE_SAFE_OPTIONAL_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/optional_ref.hpp b/third/type_safe/include/type_safe/optional_ref.hpp deleted file mode 100644 index b88a62a7..00000000 --- a/third/type_safe/include/type_safe/optional_ref.hpp +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_OPTIONAL_REF_HPP_INCLUDED -#define TYPE_SAFE_OPTIONAL_REF_HPP_INCLUDED - -#include -#include - -namespace type_safe -{ -/// \exclude -namespace detail -{ - template - T& move_if(std::false_type, T& obj) noexcept - { - return obj; - } - - template - T&& move_if(std::true_type, T& obj) noexcept - { - return std::move(obj); - } -} // namespace detail - -/// A `StoragePolicy` for [ts::basic_optional]() that allows optional references. -/// -/// The actual `value_type` passed to the optional is [ts::object_ref](), -/// but the reference types are normal references, so `value()` will return a `T&` -/// and `value_or()` takes a fallback reference of the same type and returns one of them. -/// Assigning an optional will always change the target of the reference. -/// You cannot pass rvalues. -/// -/// If `XValue` is `true`, you still cannot pass rvalues, -/// but the result of `value()`/`value_or()` will return an rvalue reference, -/// to allow moving of the stored value into something else. -/// -/// Depending on the const-ness of `T` is the reference to `const` or non-const as well, -/// unless `XValue` is true`, in which case `T` must not be `const`. -/// \module optional -template -class reference_optional_storage -{ - static_assert(!std::is_reference::value, "pass the type without reference"); - static_assert(!XValue || !std::is_const::value, "must not be const if xvalue reference"); - - using result_type = typename std::conditional::type; - - struct prevent_rvalues - {}; - -public: - using value_type = object_ref; - using lvalue_reference = T&; - using const_lvalue_reference = lvalue_reference; - /// \exclude target - using rvalue_reference = prevent_rvalues; - using const_rvalue_reference = rvalue_reference; - - template - using rebind = reference_optional_storage; - - /// \effects Creates it without a bound reference. - reference_optional_storage() noexcept : pointer_(nullptr) {} - - /// \effects Binds the same reference as stored in the optional. - /// \notes This function only participates in overload resolution, if `U` is a reference - /// compatible with `T`. \param 1 \exclude - template () = std::declval())> - void create_value(const basic_optional>& ref) - { - pointer_ = ref.has_value() ? &ref.value() : nullptr; - } - - /// \effects Binds the reference to the same reference as in `other`. - void create_value(const reference_optional_storage& other) noexcept - { - pointer_ = other.pointer_; - } - - /// \effects Binds the reference to the same reference as in `ref`. - void create_value(const object_ref& other) noexcept - { - pointer_ = other.operator->(); - } - - /// \effects Same as `destroy_value()`. - void create_value(std::nullptr_t) noexcept - { - destroy_value(); - } - - /// \effects Binds the reference to `obj`. - /// \notes This function only participates in overload resolution, if `U` is a reference - /// compatible with `T`. \param 1 \exclude - template () = std::declval())> - void create_value_explicit(U& obj) noexcept - { - pointer_ = &obj; - } - - void create_value_explicit(T&&) = delete; - - /// \effects Binds the reference to the same reference in `other`. - void copy_value(const reference_optional_storage& other) noexcept - { - pointer_ = other.pointer_; - } - - /// \effects Swaps the reference with the reference in `other`, - /// i.e. rebinds them, no value change. - void swap_value(reference_optional_storage& other) noexcept - { - std::swap(pointer_, other.pointer_); - } - - /// \effects Unbinds the reference. - void destroy_value() noexcept - { - pointer_ = nullptr; - } - - /// \returns `true` if the reference is bound, `false` otherwise. - bool has_value() const noexcept - { - return pointer_ != nullptr; - } - - /// \returns The target of the reference. - /// Depending on `XValue`, this will either be `T&` or `T&&`. - /// \exclude return - result_type get_value() const noexcept - { - return static_cast(*pointer_); - } - - /// \returns Either `get_value()` or `other`. - /// This must be given an lvalue of type `T` and it returns either an lvalue or an rvalue, - /// depending on `XValue`. - /// \exclude return - result_type get_value_or(lvalue_reference other) const noexcept - { - if (has_value()) - return get_value(); - return detail::move_if(std::integral_constant{}, other); - } - - result_type get_value_or(T&&) const = delete; - -private: - T* pointer_; -}; - -/// A [ts::basic_optional]() that uses [ts::reference_optional_storage](). -/// It is an optional reference. -/// \notes `T` is the type without the reference, i.e. `optional_ref`. -/// \module optional -template -using optional_ref = basic_optional>; - -/// \returns A [ts::optional_ref]() to the same target as `ref`. -/// \module optional -template -optional_ref opt_ref(const object_ref& ref) noexcept -{ - return optional_ref(ref.get()); -} - -/// \returns A [ts::optional_ref]() to `const` to the same target as `ref`. -/// \module optional -template -optional_ref opt_cref(const object_ref& ref) noexcept -{ - return optional_ref(ref.get()); -} - -/// \returns A [ts::optional_ref]() to the given object. -/// \module optional -/// \param 1 -/// \exclude -template ::value>::type> -optional_ref opt_ref(T& ref) noexcept -{ - return optional_ref(ref); -} - -/// \returns A [ts::optional_ref]() to the given object. -/// \module optional -/// \param 1 -/// \exclude -template ::value>::type> -optional_ref opt_cref(const T& ref) noexcept -{ - return optional_ref(ref); -} - -/// \returns A [ts::optional_ref]() to the stored value in `opt`. -/// \module optional -template -optional_ref opt_ref(optional& opt) noexcept -{ - return opt ? optional_ref(opt.value()) : nullopt; -} - -/// \returns A [ts::optional_ref]() to `const` to the stored value in `opt`. -/// \module optional -template -optional_ref opt_cref(const optional& opt) noexcept -{ - return opt ? optional_ref(opt.value()) : nullopt; -} - -/// \returns A [ts::optional_ref]() to the pointee of `ptr` or `nullopt`. -/// \module optional -template -optional_ref opt_ref(T* ptr) noexcept -{ - return ptr ? optional_ref(*ptr) : nullopt; -} - -/// \returns A [ts::optional_ref]() to `const` to the pointee of `ptr` or `nullopt`. -/// \module optional -template -optional_ref opt_cref(const T* ptr) noexcept -{ - return ptr ? optional_ref(*ptr) : nullopt; -} - -/// A [ts::basic_optional]() that uses [ts::reference_optional_storage]() with `XValue` being -/// `true`. It is an optional reference to an xvalue, i.e. an lvalue that can be moved from, like -/// returned by `std::move()`. \notes `T` is the type without the reference, i.e. -/// `optional_xvalue_ref`. \module optional -template -using optional_xvalue_ref = basic_optional>; - -/// \returns A [ts::optional_xvalue_ref]() to the pointee of `ptr` or `nullopt`. -/// \notes The pointee will be moved from when you call `value()`. -/// \module optional -template -optional_xvalue_ref opt_xref(T* ptr) noexcept -{ - return ptr ? optional_xvalue_ref(*ptr) : nullopt; -} - -/// \returns A [ts::optional_xvalue_ref]() to the given object. -/// \notes The pointee will be moved from when you call `value()`. -/// \module optional -/// \param 1 -/// \exclude -template ::value>::type> -optional_xvalue_ref opt_xref(T& obj) noexcept -{ - return optional_xvalue_ref(obj); -} - -/// \returns A [ts::optional]() containing a copy of the value of `ref` -/// if there is any value. -/// \requires `T` must be copyable. -/// \module optional -template -optional::type> copy(const optional_ref& ref) -{ - return ref.has_value() ? type_safe::make_optional(ref.value()) : nullopt; -} - -/// \returns A [ts::optional]() containing a copy of the value of `ref` created by move -/// constructing if there is any value. \requires `T` must be moveable. \module optional -template -optional move(const optional_xvalue_ref& ref) noexcept( - std::is_nothrow_move_constructible::value) -{ - return ref.has_value() ? type_safe::make_optional(ref.value()) : nullopt; -} -} // namespace type_safe - -#endif // TYPE_SAFE_OPTIONAL_REF_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/output_parameter.hpp b/third/type_safe/include/type_safe/output_parameter.hpp deleted file mode 100644 index 278fd23b..00000000 --- a/third/type_safe/include/type_safe/output_parameter.hpp +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_OUTPUT_PARAMETER_HPP_INCLUDED -#define TYPE_SAFE_OUTPUT_PARAMETER_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#endif - -#include -#include - -namespace type_safe -{ -/// A tiny wrapper modelling an output parameter of a function. -/// -/// An output parameter is a parameter that will be used to transport output of a function to its -/// caller, like a return value does. Usually they are implemented with lvalue references. They have -/// a couple of disadvantages though: -/// * They require an already created object, i.e. a default constructor or similar. -/// * It is not obvious when just looking at the call that the argument will be changed. -/// * They make it easy to accidentally use them as regular parameters, i.e. reading their value, -/// even though that was not intended. -/// -/// If you use this class as your output parameter type, -/// you do not have these disadvantages. -/// The creation is explicit, you cannot read the value, -/// and it works with [ts::deferred_construction](). -/// -/// \notes While you could use this class in other locations besides parameters, -/// this is not recommended. -template -class output_parameter -{ -public: - using parameter_type = T; - - //=== constructors/assignment ===// - /// \effects Creates it from an lvalue reference. - /// All output will be assigned to the object referred by the reference. - /// \requires The referred object must live as long as the function has not returned. - explicit output_parameter(T& obj) noexcept : ptr_(&obj), is_normal_ptr_(true) {} - - /// \group delete_val - output_parameter(const T&) = delete; - /// \group delete_val - output_parameter(T&&) = delete; - /// \group delete_val - output_parameter(const T&&) = delete; - - /// \effects Creates it from a [ts::deferred_construction]() object. - /// All output will be assigned or created in the storage of the defer construction object, - /// depending on wheter it is initialized. - /// \requires The referred object must live as long as the function has not returned. - explicit output_parameter(deferred_construction& out) noexcept - { - if (out.has_value()) - { - is_normal_ptr_ = true; - ptr_ = &out.value(); - } - else - { - is_normal_ptr_ = false; - ptr_ = &out; - } - } - - /// \group delete_deferred - output_parameter(const deferred_construction&) = delete; - /// \group delete_deferred - output_parameter(deferred_construction&&) = delete; - /// \group delete_deferred - output_parameter(const deferred_construction&&) = delete; - - /// \effects Moves an output parameter. - /// This will put `other` in an invalid state, it must not be used afterwards. - /// \notes This constructor is only there because guaranteed copy elision isn't available - /// and otherwise the `out()` function could not be implemented. - /// It is not intended to use it otherwise. - output_parameter(output_parameter&& other) noexcept - : ptr_(other.ptr_), is_normal_ptr_(other.is_normal_ptr_) - { - other.ptr_ = nullptr; - } - - ~output_parameter() noexcept = default; - - /// \group delete_assign - output_parameter& operator=(const output_parameter&) = delete; - /// \group delete_assign - output_parameter& operator=(output_parameter&&) = delete; - - //=== modifiers ===// - /// \effects Same as `assign(std::forward(u))`. - /// \returns A reference to the value that was assigned, *not* `*this` as normal "assignment" - /// operators. \requires `value_type` must be constructible from `U`. \synopsis_return - /// parameter_type& - template - auto operator=(U&& u) -> - typename std::enable_if(u))>::value, - parameter_type&>::type - { - return assign(std::forward(u)); - } - - /// \effects If the output object is not already created, forwards `args` to the constructor. - /// Otherwise if `args` is a single type and can be assigned to `T`, assigns it. - /// Otherwise if `args` cannot be assigned directly, creates a temporary object and move assigns - /// that. \returns A reference to the value that was assigned. \throws Anything thrown by the - /// constructor for `T` or the chosen assignment operator. \requires `T` must be constructible - /// from the arguments, - // and `T` must be move-assignable. - template - T& assign(Args&&... args) - { - if (is_normal_ptr_) - assign_impl(std::forward(args)...); - else - { - auto defer = static_cast*>(ptr_); - defer->emplace(std::forward(args)...); - ptr_ = &defer->value(); - is_normal_ptr_ = true; - } - - DEBUG_ASSERT(is_normal_ptr_, detail::assert_handler{}); - return *static_cast(ptr_); - } - -private: - template - auto assign_impl(U&& u) -> - typename std::enable_if(u))>::value>::type - { - *static_cast(ptr_) = std::forward(u); - } - - template - void assign_impl(Args&&... args) - { - *static_cast(ptr_) = T(std::forward(args)...); - } - - void* ptr_; - bool is_normal_ptr_; -}; - -/// \returns A new [ts::output_parameter]() using the reference `obj` as output. -template -output_parameter out(T& obj) noexcept -{ - return output_parameter(obj); -} - -/// \returns A new [ts::output_parameter]() using the [ts::deferred_construction]() as output. -template -output_parameter out(deferred_construction& o) noexcept -{ - return output_parameter(o); -} -} // namespace type_safe - -#endif // TYPE_SAFE_OUTPUT_PARAMETER_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/reference.hpp b/third/type_safe/include/type_safe/reference.hpp deleted file mode 100644 index a6a5044d..00000000 --- a/third/type_safe/include/type_safe/reference.hpp +++ /dev/null @@ -1,712 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_REFERENCE_HPP_INCLUDED -#define TYPE_SAFE_REFERENCE_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -# include -# include -# include -#endif - -#include -#include -#include -#include - -namespace type_safe -{ -template -class object_ref; - -/// \exclude -namespace detail -{ - template - struct rebind_object_ref_impl - { - using type = object_ref; - }; - - template - struct rebind_object_ref_impl, XValue2> - { - using type = object_ref; - }; - - template - using rebind_object_ref = - typename rebind_object_ref_impl::type, XValue>::type; -} // namespace detail - -/// A reference to an object of some type `T`. -/// -/// Unlike [std::reference_wrapper]() it does not try to model reference semantics, -/// instead it is basically a non-null pointer to a single object. -/// This allows rebinding on assignment. -/// Apart from the different access syntax it can be safely used instead of a reference, -/// and is safe for all kinds of containers. -/// -/// If the given type is `const`, it will only return a `const` reference, -/// but then `XValue` must be `false`. -/// -/// If `XValue` is `true`, dereferencing will [std::move()]() the object, -/// modelling a reference to an expiring lvalue. -/// \notes `T` is the type without the reference, ie. `object_ref`. -template -class object_ref -{ - static_assert(!std::is_void::value, "must not be void"); - static_assert(!std::is_reference::value, "pass the type without reference"); - static_assert(!XValue || !std::is_const::value, "must not be const if xvalue reference"); - - T* ptr_; - -public: - using value_type = T; - using reference_type = typename std::conditional::type; - - /// \effects Binds the reference to the given object. - /// \notes This constructor will only participate in overload resolution - /// if `U` is a compatible type (i.e. non-const variant or derived type). - /// \group ctor_assign - /// \param 1 - /// \exclude - template () = std::declval())> - explicit constexpr object_ref(U& obj) noexcept : ptr_(&obj) - {} - - /// \group ctor_assign - /// \param 1 - /// \exclude - template () = std::declval())> - constexpr object_ref(const object_ref& obj) noexcept : ptr_(&*obj) - {} - - /// \group ctor_assign - /// \param 1 - /// \exclude - template () = std::declval())> - object_ref& operator=(const object_ref& obj) noexcept - { - ptr_ = &*obj; - return *this; - } - - /// \returns A native reference to the referenced object. - /// if `XValue` is true, this will be an rvalue reference, - /// else an lvalue reference. - /// \group deref - constexpr reference_type get() const noexcept - { - return **this; - } - - /// \group deref - constexpr reference_type operator*() const noexcept - { - return static_cast(*ptr_); - } - - /// Member access operator. - constexpr T* operator->() const noexcept - { - return ptr_; - } - - /// \effects Invokes the function with the referred object followed by the arguments. - /// \returns A [ts::object_ref]() to the result of the function, - /// if `*this` is an xvalue reference, the result is as well. - /// \requires The function must return an lvalue or another [ts::object_ref]() object. - template - auto map(Func&& f, Args&&... args) - -> detail::rebind_object_ref(f), - std::declval().get(), - std::forward(args)...)), - XValue> - { - using result = decltype(detail::map_invoke(std::forward(f), get(), - std::forward(args)...)); - return detail::rebind_object_ref( - detail::map_invoke(std::forward(f), get(), std::forward(args)...)); - } -}; - -template -class reference_optional_storage; - -template -struct optional_storage_policy_for; - -/// Sets the [ts::basic_optional]() storage policy for [ts::object_ref]() to -/// [ts::reference_optional_storage](). -/// -/// It will be used when the optional is rebound. -/// \module optional -template -struct optional_storage_policy_for> -{ - using type = reference_optional_storage; -}; - -/// Comparison operator for [ts::object_ref](). -/// -/// Two references are equal if both refer to the same object. -/// A reference is equal to an object if the reference refers to that object. -/// \notes These functions do not participate in overload resolution -/// if the types are not compatible (i.e. const/non-const or derived). -/// \group ref_compare Object reference comparison -/// \param 3 -/// \exclude -template () == std::declval())> -constexpr bool operator==(const object_ref& a, const object_ref& b) noexcept -{ - return a.operator->() == b.operator->(); -} - -/// \group ref_compare -/// \param 3 -/// \exclude -template () == std::declval())> -constexpr bool operator==(const object_ref& a, U& b) noexcept -{ - return a.operator->() == &b; -} - -/// \group ref_compare -/// \param 3 -/// \exclude -template () == std::declval())> -constexpr bool operator==(const T& a, const object_ref& b) noexcept -{ - return &a == b.operator->(); -} - -/// \group ref_compare -/// \param 3 -/// \exclude -template () == std::declval())> -constexpr bool operator!=(const object_ref& a, const object_ref& b) noexcept -{ - return !(a == b); -} - -/// \group ref_compare -/// \param 3 -/// \exclude -template () == std::declval())> -constexpr bool operator!=(const object_ref& a, U& b) noexcept -{ - return !(a == b); -} - -/// \group ref_compare -/// \param 3 -/// \exclude -template () == std::declval())> -constexpr bool operator!=(const T& a, const object_ref& b) noexcept -{ - return !(a == b); -} - -/// With operation for [ts::object_ref](). -/// \effects Calls the `operator()` of `f` passing it `*ref` and the additional arguments. -template -void with(const object_ref& ref, Func&& f, Args&&... additional_args) -{ - std::forward(f)(*ref, std::forward(additional_args)...); -} - -/// Creates a (const) [ts::object_ref](). -/// \returns A [ts::object_ref]() to the given object. -/// \group object_ref_ref -template -constexpr object_ref ref(T& obj) noexcept -{ - return object_ref(obj); -} - -/// \group object_ref_ref -template -constexpr object_ref cref(const T& obj) noexcept -{ - return object_ref(obj); -} - -/// Convenience alias of [ts::object_ref]() where `XValue` is `true`. -template -using xvalue_ref = object_ref; - -/// Creates a [ts::xvalue_ref](). -/// \returns A [ts::xvalue_ref]() to the given object. -template -constexpr xvalue_ref xref(T& obj) noexcept -{ - return xvalue_ref(obj); -} - -/// \returns A new object containing a copy of the referenced object. -/// It will use the copy (1)/move constructor (2). -/// \throws Anything thrown by the copy (1)/move (2) constructor. -/// \group object_ref_copy -template -constexpr typename std::remove_const::type copy(const object_ref& obj) -{ - return *obj; -} - -/// \group object_ref_copy -template -constexpr T move(const xvalue_ref& obj) noexcept(std::is_nothrow_move_constructible::value) -{ - return *obj; -} - -/// A reference to an array of objects of type `T`. -/// -/// It is a simple pointer + size pair that allows reference access to each element in the array. -/// An "array" here is any contiguous storage (so C arrays, [std::vector](), etc.). -/// It does not allow changing the size of the array, only the individual elements. -/// Like [ts::object_ref]() it can be safely used in containers. -/// -/// If the given type is `const`, it will only return a `const` reference to each element, -/// but then `XValue` must be `false`. -/// -/// If `XValue` is `true`, dereferencing will [std::move()]() the object, -/// modelling a reference to an expiring lvalue. -/// \notes `T` is the type stored in the array, so `array_ref` to reference a contiguous -/// storage of `int`s. \notes Unlike the other types it isn't technically non-null, as it may -/// contain an empty array. But the range `[data(), data() + size)` will always be valid. -template -class array_ref -{ - static_assert(!std::is_void::value, "must not be void"); - static_assert(!std::is_reference::value, "pass the type without reference"); - static_assert(!XValue || !std::is_const::value, "must not be const if xvalue reference"); - -public: - using value_type = T; - using reference_type = typename std::conditional::type; - using iterator = T*; - - /// \effects Sets the reference to an empty array. - /// \group empty - array_ref(std::nullptr_t) : begin_(nullptr), size_(0u) {} - - /// \effects Sets the reference to the memory range `[begin, end)`. - /// \requires `begin <= end`. - /// \group range - array_ref(T* begin, T* end) noexcept : size_(0u) - { - assign(begin, end); - } - - /// \effects Sets the reference to the memory range `[array, array + size)`. - /// \requires `array` must not be `nullptr` unless `size` is `0`. - /// \group ptr_size - array_ref(T* array, size_t size) noexcept : size_(size) - { - assign(array, size); - } - - /// \effects Sets the reference to the C array. - /// \group c_array - template - explicit array_ref(T (&arr)[Size]) : begin_(arr), size_(Size) - {} - - /// \group empty - void assign(std::nullptr_t) noexcept - { - begin_ = nullptr; - size_ = 0u; - } - - /// \group range - void assign(T* begin, T* end) noexcept - { - DEBUG_ASSERT(begin <= end, detail::precondition_error_handler{}, "invalid array bounds"); - begin_ = begin; - size_ = static_cast(make_unsigned(end - begin)); - } - - /// \group ptr_size - void assign(T* array, size_t size) noexcept - { - DEBUG_ASSERT(size == 0u || array, detail::precondition_error_handler{}, - "invalid array bounds"); - begin_ = array; - size_ = size; - } - - /// \group c_array - template - void assign(T (&arr)[Size]) noexcept - { - begin_ = arr; - size_ = Size; - } - - /// \returns An iterator to the beginning of the array. - iterator begin() const noexcept - { - return begin_; - } - - /// \returns An iterator one past the last element of the array. - iterator end() const noexcept - { - return begin_ + static_cast(size_); - } - - /// \returns A pointer to the beginning of the array. - /// If `size()` isn't zero, the pointer is guaranteed to be non-null. - T* data() const noexcept - { - return begin_; - } - - /// \returns The number of elements in the array. - size_t size() const noexcept - { - return size_; - } - - /// \returns A (`rvalue` if `Xvalue` is `true`) reference to the `i`th element of the array. - /// \requires `i < size()`. - reference_type operator[](index_t i) const noexcept - { - DEBUG_ASSERT(static_cast(i) < size_, detail::precondition_error_handler{}, - "out of bounds array access"); - return static_cast(at(begin_, i)); - } - -private: - T* begin_; - size_t size_; -}; - -/// With operation for [ts::array_ref](). -/// \effects For every element of the array in order, it will invoke `f`, passing it the current -/// element and the additional arguments. -//// If `XValue` is `true`, it will pass an rvalue reference to the element, allowing it to be moved -/// from. -template -void with(const array_ref& ref, Func&& f, Args&&... additional_args) -{ - for (auto&& elem : ref) - f(std::forward(elem), additional_args...); -} - -/// Creates a [ts::array_ref](). -/// \returns The reference created by forwarding the parameter(s) to the constructor. -/// \group array_ref_ref -template -array_ref ref(T (&arr)[Size]) noexcept -{ - return array_ref(arr); -} - -/// \group array_ref_ref -template -array_ref ref(T* begin, T* end) noexcept -{ - return array_ref(begin, end); -} - -/// \group array_ref_ref -template -array_ref ref(T* array, size_t size) noexcept -{ - return array_ref(array, size); -} - -/// Creates a [ts::array_ref]() to `const`. -/// \returns The reference created by forwarding the parameter(s) to the constructor. -/// \group array_ref_cref -template -array_ref cref(const T (&arr)[Size]) noexcept -{ - return array_ref(arr); -} - -/// \group array_ref_cref -template -array_ref cref(const T* begin, const T* end) noexcept -{ - return array_ref(begin, end); -} - -/// \group array_ref_cref -template -array_ref cref(const T* array, size_t size) noexcept -{ - return array_ref(array, size); -} - -/// Convenience alias for [ts::array_ref]() where `XValue` is `true`. -template -using array_xvalue_ref = array_ref; - -/// Creates a [ts::array_xvalue_ref](). -/// \returns The reference created by forwarding the parameter(s) to the constructor. -/// \group array_xvalue_ref_ref -template -array_xvalue_ref xref(T (&arr)[Size]) noexcept -{ - return array_xvalue_ref(arr); -} - -/// \group array_xvalue_ref_ref -template -array_xvalue_ref xref(T* begin, T* end) noexcept -{ - return array_xvalue_ref(begin, end); -} - -/// \group array_xvalue_ref_ref -template -array_xvalue_ref xref(T* array, size_t size) noexcept -{ - return array_xvalue_ref(array, size); -} - -/// \exclude -namespace detail -{ - template - struct compatible_return_type - : std::integral_constant::value - || std::is_convertible::value> - {}; - - struct matching_function_pointer_tag - {}; - struct matching_functor_tag - {}; - struct invalid_functor_tag - {}; - - template - struct get_callable_tag - { - // use unary + to convert to function pointer - template ())(std::declval()...))> - static matching_function_pointer_tag test( - int, T& obj, - typename std::enable_if::value, int>::type = 0); - - template ()(std::declval()...))> - static matching_functor_tag test( - short, T& obj, - typename std::enable_if::value, int>::type = 0); - - static invalid_functor_tag test(...); - - using type = decltype(test(0, std::declval())); - }; - - template - using enable_function_tag = typename std::enable_if< - std::is_same::type, Result>::value, - int>::type; -} // namespace detail - -template -class function_ref; - -namespace detail -{ - template - struct function_ref_trait { using type = void; }; - - template - struct function_ref_trait> - { - using type = function_ref; - - using return_type = typename type::return_type; - }; -} // namespace detail - -/// A reference to a function. -/// -/// This is a lightweight reference to a function. -/// It can refer to any function that is compatible with given signature. -/// -/// A function is compatible if it is callable with regular function call syntax from the given -/// argument types, and its return type is either implicitly convertible to the specified return -/// type or the specified return type is `void`. -/// -/// In general it will store a pointer to the functor, -/// requiring an lvalue. -/// But if it is created with a function pointer or something convertible to a function pointer, -/// it will store the function pointer itself. -/// This allows creating it from stateless lambdas. -/// \notes Due to implementation reasons, -/// it does not support member function pointers, -/// as it requires regular function call syntax. -/// Create a reference to the object returned by [std::mem_fn](), if that is required. -template -class function_ref -{ -public: - using return_type = Return; - - using signature = Return(Args...); - - /// \effects Creates a reference to the function specified by the function pointer. - /// \requires `fptr` must not be `nullptr`. - /// \notes (2) only participates in overload resolution if the type of the function is - /// compatible with the specified signature. \group function_ptr_ctor - function_ref(Return (*fptr)(Args...)) - : function_ref(detail::matching_function_pointer_tag{}, fptr) - {} - - /// \group function_ptr_ctor - /// \param 1 - /// \exclude - template - function_ref( - Return2 (*fptr)(Args2...), - typename std::enable_if::value, int>::type - = 0) - : function_ref(detail::matching_function_pointer_tag{}, fptr) - {} - - /// \effects Creates a reference to the function created by the stateless lambda. - /// \notes This constructor is intended for stateless lambdas, - /// which are implicitly convertible to function pointers. - /// It does not participate in overload resolution, - /// unless the type is implicitly convertible to a function pointer - /// that is compatible with the specified signature. - /// \notes Due to to implementation reasons, - /// it does not work for polymorphic lambdas, - /// it needs an explicit cast to the desired function pointer type. - /// A polymorphic lambda convertible to a direct match function pointer, - /// works however. - /// \param 1 - /// \exclude - template > - function_ref(const Functor& f) : function_ref(detail::matching_function_pointer_tag{}, +f) - {} - - /// \effects Creates a reference to the specified functor. - /// It will store a pointer to the function object, - /// so it must live as long as the reference. - /// \notes This constructor does not participate in overload resolution, - /// unless the functor is compatible with the specified signature. - /// \param 1 - /// \exclude - template < - typename Functor, - typename = detail::enable_function_tag, - // This overload restricts us to not directly referencing another function_ref. - typename std::enable_if::type, void>::value, int>::type = 0 - > - explicit function_ref(Functor& f) : cb_(&invoke_functor) - { - // Ref to this functor - ::new (storage_.get()) void*(&f); - } - - /// Converting copy constructor. - /// \effects Creates a reference to the same function referred by `other`. - /// \notes This constructor does not participate in overload resolution, - /// unless the signature of `other` is compatible with the specified signature. - /// \notes This constructor may create a bigger conversion chain. - /// For example, if `other` has signature `void(const char*)` it can refer to a function taking - /// `std::string`. If this signature than accepts a type `T` implicitly convertible to `const - /// char*`, calling this will call the function taking `std::string`, converting `T -> - /// std::string`, even though such a conversion would be ill-formed otherwise. \param 1 \exclude - template < - typename Functor, - // This overloading allows us to directly referencing another function_ref. - typename std::enable_if::type, void>::value, int>::type = 0, - // Requires that the signature not be consistent (if it is then the copy construct should be called). - typename std::enable_if::type, function_ref>::value, int>::type = 0, - // Of course, the return type and parameter types must be compatible. - typename = detail::enable_function_tag - > - explicit function_ref(Functor& f) : cb_(&invoke_functor) - { - // Ref to this function_ref - ::new (storage_.get()) void*(&f); - } - - /// \effects Rebinds the reference to the specified functor. - /// \notes This assignment operator only participates in overload resolution, - /// if the argument can also be a valid constructor argument. - /// \param 1 - /// \exclude - template ::type, function_ref>::value, - decltype(function_ref(std::declval()))>::type> - void assign(Functor&& f) noexcept - { - auto ref = function_ref(std::forward(f)); - storage_ = ref.storage_; - cb_ = ref.cb_; - } - - /// \effects Invokes the stored function with the specified arguments and returns the result. - Return operator()(Args... args) const - { - return cb_(storage_.get(), static_cast(args)...); - } - -private: - template - static Return invoke_functor(const void* memory, Args... args) - { - using ptr_t = void*; - ptr_t ptr = *static_cast(memory); - Functor& func = *static_cast(ptr); - return static_cast(func(static_cast(args)...)); - } - - template - static Return invoke_function_pointer(const void* memory, Args... args) - { - auto ptr = *static_cast(memory); - auto func = reinterpret_cast(ptr); - return static_cast(func(static_cast(args)...)); - } - - template - function_ref(detail::matching_function_pointer_tag, Return2 (*fptr)(Args2...)) - { - using pointer_type = Return2 (*)(Args2...); - using stored_pointer_type = void (*)(); - - DEBUG_ASSERT(fptr, detail::precondition_error_handler{}, - "function pointer must not be null"); - ::new (storage_.get()) stored_pointer_type(reinterpret_cast(fptr)); - - cb_ = &invoke_function_pointer; - } - - using storage = detail::aligned_union; - using callback = Return (*)(const void*, Args...); - - storage storage_; - callback cb_; -}; -} // namespace type_safe - -#endif // TYPE_SAFE_REFERENCE_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/strong_typedef.hpp b/third/type_safe/include/type_safe/strong_typedef.hpp deleted file mode 100644 index 939d322b..00000000 --- a/third/type_safe/include/type_safe/strong_typedef.hpp +++ /dev/null @@ -1,806 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_STRONG_TYPEDEF_HPP_INCLUDED -#define TYPE_SAFE_STRONG_TYPEDEF_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#include -#endif - -#include -#include - -#ifdef _MSC_VER -# define TYPE_SAFE_MSC_EMPTY_BASES __declspec(empty_bases) -#else -# define TYPE_SAFE_MSC_EMPTY_BASES -#endif - -namespace type_safe -{ -/// A strong typedef emulation. -/// -/// Unlike regular typedefs, this does create a new type and only allows explicit conversion from -/// the underlying one. The `Tag` is used to differentiate between different strong typedefs to the -/// same type. It is designed to be used as a base class and does not provide any operations by -/// itself. Use the types in the `strong_typedef_op` namespace to generate operations and/or your -/// own member functions. -/// -/// Example: -/// ```cpp -/// struct my_handle -/// : strong_typedef, -/// strong_typedef_op::equality_comparison -/// { -/// using strong_typedef::strong_typedef; -/// }; -/// -/// struct my_int -/// : strong_typedef, -/// strong_typedef_op::integer_arithmetic, -/// strong_typedef_op::equality_comparison, -/// strong_typedef_op::relational_comparison -/// { -/// using strong_typedef::strong_typedef; -/// }; -/// ``` -template -class strong_typedef -{ -public: - /// \effects Value initializes the underlying value. - constexpr strong_typedef() : value_() {} - - /// \effects Copy (1)/moves (2) the underlying value. - /// \group value_ctor - explicit constexpr strong_typedef(const T& value) : value_(value) {} - - /// \group value_ctor - explicit constexpr strong_typedef(T&& value) noexcept( - std::is_nothrow_move_constructible::value) - : value_(static_cast(value)) // std::move() might not be constexpr - {} - - /// \returns A reference to the stored underlying value. - /// \group value_conv - explicit TYPE_SAFE_CONSTEXPR14 operator T&() TYPE_SAFE_LVALUE_REF noexcept - { - return value_; - } - - /// \group value_conv - explicit constexpr operator const T&() const TYPE_SAFE_LVALUE_REF noexcept - { - return value_; - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group value_conv - explicit TYPE_SAFE_CONSTEXPR14 operator T &&() && noexcept - { - return std::move(value_); - } - - /// \group value_conv - explicit constexpr operator const T &&() const&& noexcept - { - return std::move(value_); - } -#endif - - friend void swap(strong_typedef& a, strong_typedef& b) noexcept - { - using std::swap; - swap(static_cast(a), static_cast(b)); - } - - T value_; -}; - -/// \exclude -namespace detail -{ - template - T underlying_type(strong_typedef); - - template - struct make_void - { - typedef void type; - }; - template - using void_t = typename make_void::type; -} // namespace detail - -/// The underlying type of the [ts::strong_typedef](). -/// \exclude target -template -using underlying_type - = decltype(detail::underlying_type(std::declval::type>())); - - -/// \group is_strong_typedef -/// Whether a type `T` is a [ts::strong_type]() -template > -struct TYPE_SAFE_MSC_EMPTY_BASES is_strong_typedef : std::false_type -{}; - -/// \group is_strong_typedef -template -struct is_strong_typedef()))>> - : std::true_type -{}; - -/// Accesses the underlying value. -/// \returns A reference to the underlying value. -/// \group strong_typedef_get -template -TYPE_SAFE_CONSTEXPR14 T& get(strong_typedef& type) noexcept -{ - return static_cast(type); -} - -/// \group strong_typedef_get -template -constexpr const T& get(const strong_typedef& type) noexcept -{ - return static_cast(type); -} - -/// \group strong_typedef_get -template -TYPE_SAFE_CONSTEXPR14 T&& get(strong_typedef&& type) noexcept -{ - return static_cast(static_cast(type)); -} - -/// \group strong_typedef_get -template -constexpr const T&& get(const strong_typedef&& type) noexcept -{ - return static_cast(static_cast(type)); -} - -/// Some operations for [ts::strong_typedef](). -/// -/// They all generate operators forwarding to the underlying type. -/// Inherit from them in the typedef definition. -namespace strong_typedef_op -{ - /// \exclude - namespace detail - { - template - using enable_if_convertible = typename std::enable_if< - !std::is_same::type, To>::value - && !std::is_base_of::type>::value - && std::is_convertible::type, To>::value>::type; - - template - using enable_if_convertible_same = typename std::enable_if< - std::is_convertible::type, To>::value>::type; - - template - constexpr const underlying_type& get_underlying(const StrongTypedef& type) - { - return get(type); - } - - template - TYPE_SAFE_CONSTEXPR14 underlying_type& get_underlying(StrongTypedef& type) - { - return get(static_cast(type)); - } - - template - TYPE_SAFE_CONSTEXPR14 underlying_type&& get_underlying(StrongTypedef&& type) - { - return get(static_cast(type)); - } - - // ensure constexpr - template - constexpr T&& forward(typename std::remove_reference::type& t) noexcept - { - return static_cast(t); - } - - template - constexpr T&& forward(typename std::remove_reference::type&& t) noexcept - { - static_assert(!std::is_lvalue_reference::value, - "Can not forward an rvalue as an lvalue."); - return static_cast(t); - } - - template ::value>::type> - constexpr auto forward_or_underlying(StrongTypedef&& type) noexcept - -> decltype(get(forward(type))) - { - return get(forward(type)); - } - template - constexpr typename std::enable_if::value, T&&>::type - forward_or_underlying(T&& type) noexcept - { - return detail::forward(type); - } - } // namespace detail - -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op, Name, Result) \ - /** \exclude */ \ - template \ - constexpr Result operator Op(const Name& lhs, const Name& rhs) \ - { \ - return Result( \ - detail::get_underlying(static_cast(lhs)) \ - Op detail::get_underlying(static_cast(rhs))); \ - } \ - /** \exclude */ \ - template \ - constexpr Result operator Op(Name&& lhs, const Name& rhs) \ - { \ - return Result( \ - detail::get_underlying(static_cast(lhs)) \ - Op detail::get_underlying(static_cast(rhs))); \ - } \ - /** \exclude */ \ - template \ - constexpr Result operator Op(const Name& lhs, Name&& rhs) \ - { \ - return Result(detail::get_underlying(static_cast( \ - lhs)) Op detail::get_underlying(static_cast(rhs))); \ - } \ - /** \exclude */ \ - template \ - constexpr Result operator Op(Name&& lhs, Name&& rhs) \ - { \ - return Result(detail::get_underlying(static_cast( \ - lhs)) Op detail::get_underlying(static_cast(rhs))); \ - } \ - /* mixed */ \ - /** \exclude */ \ - template > \ - constexpr Result operator Op(const Name& lhs, Other&& rhs) \ - { \ - return Result(detail::get_underlying(static_cast( \ - lhs)) Op detail::get_underlying(detail::forward(rhs))); \ - } \ - /** \exclude */ \ - template > \ - constexpr Result operator Op(Name&& lhs, Other&& rhs) \ - { \ - return Result(detail::get_underlying(static_cast(lhs)) \ - Op detail::get_underlying(detail::forward(rhs))); \ - } \ - /** \exclude */ \ - template > \ - constexpr Result operator Op(Other&& lhs, const Name& rhs) \ - { \ - return Result( \ - detail::get_underlying(detail::forward(lhs)) \ - Op detail::get_underlying(static_cast(rhs))); \ - } \ - /** \exclude */ \ - template > \ - constexpr Result operator Op(Other&& lhs, Name&& rhs) \ - { \ - return Result(detail::get_underlying(detail::forward( \ - lhs)) Op detail::get_underlying(static_cast(rhs))); \ - } - -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP_STRONGTYPEDEF_OTHER(Op, Name, Result) \ - /** \exclude */ \ - template > \ - constexpr Result operator Op(const Name& lhs, Other&& rhs) \ - { \ - return Result(get(static_cast(lhs)) \ - Op detail::forward_or_underlying(detail::forward(rhs))); \ - } \ - /** \exclude */ \ - template > \ - constexpr Result operator Op(Name&& lhs, Other&& rhs) \ - { \ - return Result(get(static_cast(lhs)) \ - Op detail::forward_or_underlying(detail::forward(rhs))); \ - } - -#define TYPE_SAFE_DETAIL_MAKE_OP_OTHER_STRONGTYPEDEF(Op, Name, Result) \ - /** \exclude */ \ - template > \ - constexpr Result operator Op(Other&& lhs, const Name& rhs) \ - { \ - return Result(detail::forward_or_underlying(detail::forward(lhs)) \ - Op get(static_cast(rhs))); \ - } \ - /** \exclude */ \ - template > \ - constexpr Result operator Op(Other&& lhs, Name&& rhs) \ - { \ - return Result(detail::forward_or_underlying(detail::forward(lhs)) \ - Op get(static_cast(rhs))); \ - } - -#define TYPE_SAFE_DETAIL_MAKE_OP_MIXED(Op, Name, Result) \ - TYPE_SAFE_DETAIL_MAKE_OP_STRONGTYPEDEF_OTHER(Op, Name, Result) \ - TYPE_SAFE_DETAIL_MAKE_OP_OTHER_STRONGTYPEDEF(Op, Name, Result) - -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP_COMPOUND(Op, Name) \ - /** \exclude */ \ - template \ - TYPE_SAFE_CONSTEXPR14 StrongTypedef& operator Op(Name& lhs, \ - const Name& rhs) \ - { \ - detail::get_underlying(static_cast(lhs)) \ - Op detail::get_underlying(static_cast(rhs)); \ - return static_cast(lhs); \ - } /** \exclude */ \ - template \ - TYPE_SAFE_CONSTEXPR14 StrongTypedef& operator Op(Name& lhs, \ - Name&& rhs) \ - { \ - detail::get_underlying(static_cast(lhs)) \ - Op detail::get_underlying(static_cast(rhs)); \ - return static_cast(lhs); \ - } \ - /** \exclude */ \ - template \ - TYPE_SAFE_CONSTEXPR14 StrongTypedef&& operator Op(Name&& lhs, \ - const Name& rhs) \ - { \ - detail::get_underlying(static_cast(lhs)) \ - Op detail::get_underlying(static_cast(rhs)); \ - return static_cast(lhs); \ - } /** \exclude */ \ - template \ - TYPE_SAFE_CONSTEXPR14 StrongTypedef&& operator Op(Name&& lhs, \ - Name&& rhs) \ - { \ - detail::get_underlying(static_cast(lhs)) \ - Op detail::get_underlying(static_cast(rhs)); \ - return static_cast(lhs); \ - } \ - /* mixed */ \ - /** \exclude */ \ - template > \ - TYPE_SAFE_CONSTEXPR14 StrongTypedef& operator Op(Name& lhs, Other&& rhs) \ - { \ - detail::get_underlying(static_cast(lhs)) \ - Op detail::get_underlying(detail::forward(rhs)); \ - return static_cast(lhs); \ - } \ - /** \exclude */ \ - template > \ - TYPE_SAFE_CONSTEXPR14 StrongTypedef&& operator Op(Name&& lhs, Other&& rhs) \ - { \ - detail::get_underlying(static_cast(lhs)) \ - Op detail::get_underlying(detail::forward(rhs)); \ - return static_cast(lhs); \ - } - -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP_COMPOUND_MIXED(Op, Name) \ - /** \exclude */ \ - template > \ - TYPE_SAFE_CONSTEXPR14 StrongTypedef& operator Op(Name& lhs, \ - Other&& rhs) \ - { \ - get(static_cast(lhs)) \ - Op detail::forward_or_underlying(detail::forward(rhs)); \ - return static_cast(lhs); \ - } \ - /** \exclude */ \ - template > \ - TYPE_SAFE_CONSTEXPR14 StrongTypedef&& operator Op(Name&& lhs, \ - Other&& rhs) \ - { \ - get(static_cast(lhs)) \ - Op detail::forward_or_underlying(detail::forward(rhs)); \ - return static_cast(lhs); \ - } - -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(Name, Op) \ - template \ - struct Name \ - {}; \ - TYPE_SAFE_DETAIL_MAKE_OP(Op, Name, StrongTypedef) \ - TYPE_SAFE_DETAIL_MAKE_OP_COMPOUND(Op## =, Name) \ - template \ - struct mixed_##Name \ - {}; \ - TYPE_SAFE_DETAIL_MAKE_OP_MIXED(Op, mixed_##Name, StrongTypedef) \ - TYPE_SAFE_DETAIL_MAKE_OP_COMPOUND_MIXED(Op## =, mixed_##Name) \ - template \ - struct mixed_##Name##_noncommutative \ - {}; \ - TYPE_SAFE_DETAIL_MAKE_OP_STRONGTYPEDEF_OTHER(Op, mixed_##Name##_noncommutative, StrongTypedef) \ - TYPE_SAFE_DETAIL_MAKE_OP_COMPOUND_MIXED(Op## =, mixed_##Name##_noncommutative) - - template - struct equality_comparison - {}; - TYPE_SAFE_DETAIL_MAKE_OP(==, equality_comparison, bool) - TYPE_SAFE_DETAIL_MAKE_OP(!=, equality_comparison, bool) - - template - struct mixed_equality_comparison - {}; - TYPE_SAFE_DETAIL_MAKE_OP_MIXED(==, mixed_equality_comparison, bool) - TYPE_SAFE_DETAIL_MAKE_OP_MIXED(!=, mixed_equality_comparison, bool) - - template - struct relational_comparison - {}; - TYPE_SAFE_DETAIL_MAKE_OP(<, relational_comparison, bool) - TYPE_SAFE_DETAIL_MAKE_OP(<=, relational_comparison, bool) - TYPE_SAFE_DETAIL_MAKE_OP(>, relational_comparison, bool) - TYPE_SAFE_DETAIL_MAKE_OP(>=, relational_comparison, bool) - - template - struct mixed_relational_comparison - {}; - TYPE_SAFE_DETAIL_MAKE_OP_MIXED(<, mixed_relational_comparison, bool) - TYPE_SAFE_DETAIL_MAKE_OP_MIXED(<=, mixed_relational_comparison, bool) - TYPE_SAFE_DETAIL_MAKE_OP_MIXED(>, mixed_relational_comparison, bool) - TYPE_SAFE_DETAIL_MAKE_OP_MIXED(>=, mixed_relational_comparison, bool) - - TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(addition, +) - TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(subtraction, -) - TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(multiplication, *) - TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(division, /) - TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(modulo, %) - - template - struct explicit_bool - { - /// \exclude - explicit constexpr operator bool() const - { - return static_cast( - detail::get_underlying(static_cast(*this))); - } - }; - - template - struct increment - { - /// \exclude - TYPE_SAFE_CONSTEXPR14 StrongTypedef& operator++() - { - using type = underlying_type; - ++static_cast(static_cast(*this)); - return static_cast(*this); - } - - /// \exclude - TYPE_SAFE_CONSTEXPR14 StrongTypedef operator++(int) - { - auto result = static_cast(*this); - ++*this; - return result; - } - }; - - template - struct decrement - { - /// \exclude - TYPE_SAFE_CONSTEXPR14 StrongTypedef& operator--() - { - using type = underlying_type; - --static_cast(static_cast(*this)); - return static_cast(*this); - } - - /// \exclude - TYPE_SAFE_CONSTEXPR14 StrongTypedef operator--(int) - { - auto result = static_cast(*this); - --*this; - return result; - } - }; - - template - struct unary_plus - {}; - - /// \exclude - template - constexpr StrongTypedef operator+(const unary_plus& lhs) - { - return StrongTypedef(+get(static_cast(lhs))); - } - /// \exclude - template - constexpr StrongTypedef operator+(unary_plus&& lhs) - { - return StrongTypedef(+get(static_cast(lhs))); - } - - template - struct unary_minus - {}; - - /// \exclude - template - constexpr StrongTypedef operator-(const unary_minus& lhs) - { - return StrongTypedef(-get(static_cast(lhs))); - } - /// \exclude - template - constexpr StrongTypedef operator-(unary_minus&& lhs) - { - return StrongTypedef(-get(static_cast(lhs))); - } - - template - struct TYPE_SAFE_MSC_EMPTY_BASES integer_arithmetic : unary_plus, - unary_minus, - addition, - subtraction, - multiplication, - division, - modulo, - increment, - decrement - {}; - - template - struct TYPE_SAFE_MSC_EMPTY_BASES floating_point_arithmetic : unary_plus, - unary_minus, - addition, - subtraction, - multiplication, - division - {}; - - template - struct complement - {}; - - /// \exclude - template - constexpr StrongTypedef operator~(const complement& lhs) - { - return StrongTypedef(~get(static_cast(lhs))); - } - /// \exclude - template - constexpr StrongTypedef operator~(complement&& lhs) - { - return StrongTypedef(~get(static_cast(lhs))); - } - - TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(bitwise_or, |) - TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(bitwise_xor, ^) - TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(bitwise_and, &) - - template - struct TYPE_SAFE_MSC_EMPTY_BASES bitmask : complement, - bitwise_or, - bitwise_xor, - bitwise_and - {}; - - template - struct bitshift - {}; - TYPE_SAFE_DETAIL_MAKE_OP_MIXED(<<, bitshift, StrongTypedef) - TYPE_SAFE_DETAIL_MAKE_OP_MIXED(>>, bitshift, StrongTypedef) - TYPE_SAFE_DETAIL_MAKE_OP_COMPOUND_MIXED(<<=, bitshift) - TYPE_SAFE_DETAIL_MAKE_OP_COMPOUND_MIXED(>>=, bitshift) - - template - struct dereference - { - /// \exclude - Result& operator*() - { - using type = underlying_type; - return *static_cast(static_cast(*this)); - } - - /// \exclude - const Result& operator*() const - { - using type = underlying_type; - return *static_cast(static_cast(*this)); - } - - /// \exclude - ResultPtr operator->() - { - using type = underlying_type; - return static_cast(static_cast(*this)); - } - - /// \exclude - ResultConstPtr operator->() const - { - using type = underlying_type; - return static_cast(static_cast(*this)); - } - }; - - template - struct array_subscript - { - /// \exclude - Result& operator[](const Index& i) - { - using type = underlying_type; - return static_cast(static_cast(*this))[i]; - } - - /// \exclude - const Result& operator[](const Index& i) const - { - using type = underlying_type; - return static_cast(static_cast(*this))[i]; - } - }; - - template - struct TYPE_SAFE_MSC_EMPTY_BASES iterator : dereference, - increment - { - using iterator_category = Category; - using value_type = typename std::remove_cv::type; - using difference_type = Distance; - using pointer = T*; - using reference = T&; - }; - - template - struct TYPE_SAFE_MSC_EMPTY_BASES input_iterator : iterator, - equality_comparison - {}; - - template - struct TYPE_SAFE_MSC_EMPTY_BASES output_iterator : iterator - {}; - - template - struct TYPE_SAFE_MSC_EMPTY_BASES forward_iterator : input_iterator - { - using iterator_category = std::forward_iterator_tag; - }; - - template - struct TYPE_SAFE_MSC_EMPTY_BASES bidirectional_iterator : forward_iterator, - decrement - { - using iterator_category = std::bidirectional_iterator_tag; - }; - - template - struct TYPE_SAFE_MSC_EMPTY_BASES random_access_iterator : bidirectional_iterator, - array_subscript, - relational_comparison - { - using iterator_category = std::random_access_iterator_tag; - - /// \exclude - StrongTypedef& operator+=(const Distance& d) - { - using type = underlying_type; - static_cast(static_cast(*this)) += d; - return static_cast(*this); - } - - /// \exclude - StrongTypedef& operator-=(const Distance& d) - { - using type = underlying_type; - static_cast(static_cast(*this)) -= d; - return static_cast(*this); - } - - /// \exclude - friend StrongTypedef operator+(const StrongTypedef& iter, const Distance& n) - { - using type = underlying_type; - return StrongTypedef(static_cast(iter) + n); - } - - /// \exclude - friend StrongTypedef operator+(const Distance& n, const StrongTypedef& iter) - { - return iter + n; - } - - /// \exclude - friend StrongTypedef operator-(const StrongTypedef& iter, const Distance& n) - { - using type = underlying_type; - return StrongTypedef(static_cast(iter) - n); - } - - /// \exclude - friend Distance operator-(const StrongTypedef& lhs, const StrongTypedef& rhs) - { - using type = underlying_type; - return static_cast(lhs) - static_cast(rhs); - } - }; - - template - struct input_operator - { - /// \exclude - template - friend std::basic_istream& operator>>( - std::basic_istream& in, StrongTypedef& val) - { - using type = underlying_type; - return in >> static_cast(val); - } - }; - - template - struct output_operator - { - /// \exclude - template - friend std::basic_ostream& operator<<( - std::basic_ostream& out, const StrongTypedef& val) - { - using type = underlying_type; - return out << static_cast(val); - } - }; - -#undef TYPE_SAFE_DETAIL_MAKE_OP -#undef TYPE_SAFE_DETAIL_MAKE_OP_MIXED -#undef TYPE_SAFE_DETAIL_MAKE_OP_STRONGTYPEDEF_OTHER -#undef TYPE_SAFE_DETAIL_MAKE_OP_OTHER_STRONGTYPEDEF -#undef TYPE_SAFE_DETAIL_MAKE_OP_COMPOUND -#undef TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP -} // namespace strong_typedef_op - -/// Inherit from it in the `std::hash` specialization to make -/// it hashable like the underlying type. See example/strong_typedef.cpp. -template -struct TYPE_SAFE_MSC_EMPTY_BASES hashable : std::hash> -{ - using underlying_type = type_safe::underlying_type; - using underlying_hash = std::hash; - - std::size_t operator()(const StrongTypedef& lhs) const - noexcept(noexcept(underlying_hash{}(std::declval()))) - { - return underlying_hash{}(static_cast(lhs)); - } -}; -} // namespace type_safe - -#undef TYPE_SAFE_MSC_EMPTY_BASES - -#endif // TYPE_SAFE_STRONG_TYPEDEF_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/tagged_union.hpp b/third/type_safe/include/type_safe/tagged_union.hpp deleted file mode 100644 index 17b57ca6..00000000 --- a/third/type_safe/include/type_safe/tagged_union.hpp +++ /dev/null @@ -1,453 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_TAGGED_UNION_HPP_INCLUDED -#define TYPE_SAFE_TAGGED_UNION_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -# include -#endif - -#include -#include -#include -#include -#include - -namespace type_safe -{ -/// \exclude -namespace detail -{ - struct union_type_id : strong_typedef, - strong_typedef_op::equality_comparison, - strong_typedef_op::relational_comparison - { - using strong_typedef::strong_typedef; - }; - - //=== get_type_index ==// - template - struct get_type_index_impl; - - // type not found at all - template - struct get_type_index_impl : std::integral_constant - {}; - - // found type at the beginning - template - struct get_type_index_impl : std::integral_constant - {}; - - // type not in the beginning - template - struct get_type_index_impl - : std::integral_constant::value == 0u - ? 0u - : 1 + get_type_index_impl::value> - {}; - - template - using get_type_index = get_type_index_impl::type...>; - - template - struct destroy_union; - template - struct copy_union; - template - struct move_union; -} // namespace detail - -/// Tag type so no explicit template instantiation of function parameters is required. -/// \module variant -template -struct union_type -{ - constexpr union_type() {} -}; - -/// Very basic typelist. -/// \module variant -template -struct union_types -{}; - -/// A tagged union. -/// -/// It is much like a plain old C `union`, -/// but remembers which type it currently stores. -/// It can either store one of the given types or no type at all. -/// \notes Like the C `union` it does not automatically destroy the currently stored type, -/// and copy operations are deleted. -/// \module variant -template -class tagged_union -{ -#if defined(__GNUC__) && __GNUC__ < 5 - // does not have is_trivially_copyable - using trivial = detail::all_of::value...>; -#else - using trivial = detail::all_of::value...>; -#endif - - template - friend struct detail::destroy_union; - template - friend struct detail::copy_union; - template - friend struct detail::move_union; - -public: - using types = union_types::type...>; - - /// The id of a type. - /// - /// It is a [ts::strong_typedef]() for `std::size_t` - /// and provides equality and relational comparison. - class type_id : public strong_typedef, - public strong_typedef_op::equality_comparison, - public strong_typedef_op::relational_comparison - { - public: - /// \returns `true` if `T` is a valid type, `false` otherwise. - template - static constexpr bool is_valid() - { - return detail::get_type_index::value != 0u; - } - - /// \effects Initializes it to an invalid value. - /// \notes The invalid value compares less than all valid values. - constexpr type_id() noexcept : strong_typedef(0u) {} - - /// \effects Initializes it to the value of the type `T`. - /// If `T` is not one of the types of the union types, - /// it will be the same as the default constructor. - template - constexpr type_id(union_type) noexcept - : type_id(detail::get_type_index::value) - {} - - /// \returns `true` if the id is valid, - /// `false` otherwise. - explicit operator bool() const noexcept - { - return *this != type_id(); - } - - private: - explicit constexpr type_id(std::size_t value) : strong_typedef(value) - {} - }; - - /// A global invalid type id object. - static constexpr type_id invalid_type = type_id(); - - //=== constructors/destructors/assignment ===// - tagged_union() noexcept = default; - - /// \notes Does not destroy the currently stored type. - ~tagged_union() noexcept = default; - - tagged_union(const tagged_union&) = delete; - tagged_union& operator=(const tagged_union&) = delete; - - //=== modifiers ===// - /// \effects Creates a new object of given type by perfectly forwarding `args`. - /// \throws Anything thrown by `T`s constructor, - /// in which case the union will stay empty. - /// \requires The union must currently be empty. - /// and `T` must be a valid type and constructible from the arguments. - template - void emplace(union_type, Args&&... args) - { - constexpr auto index = type_id(union_type{}); - // MSVC doesn't like operator!= of the strong typedef here, for some reason... - static_assert(get(index) != get(invalid_type), "T must not be stored in variant"); - static_assert(std::is_constructible::value, - "T not constructible from arguments"); - - ::new (storage_.get()) T(std::forward(args)...); - cur_type_ = index; - } - - /// \effects Destroys the currently stored type by calling its destructor, - /// and setting the union to the empty state. - /// \requires The union must currently store an object of the given type. - template - void destroy(union_type type) noexcept - { - check(type); - value(type).~T(); - cur_type_ = invalid_type; - } - - //=== accessors ===// - /// \returns The [*type_id]() of the type currently stored, - /// or [*invalid_type]() if there is none. - const type_id& type() const noexcept - { - return cur_type_; - } - - /// \returns `true` if there is a type stored, - /// `false` otherwise. - bool has_value() const noexcept - { - return type() != invalid_type; - } - - /// \returns A (`const`) lvalue/rvalue reference to the currently stored type. - /// \requires The union must currently store an object of the given type. - /// \group value - template - T& value(union_type type) TYPE_SAFE_LVALUE_REF noexcept - { - check(type); - return *static_cast(storage_.get()); - } - - /// \group value - template - const T& value(union_type type) const TYPE_SAFE_LVALUE_REF noexcept - { - check(type); - return *static_cast(storage_.get()); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group value - template - T&& value(union_type type) && noexcept - { - check(type); - return std::move(*static_cast(storage_.get())); - } - - /// \group value - template - const T&& value(union_type type) const&& noexcept - { - check(type); - return std::move(*static_cast(storage_.get())); - } -#endif - -private: - template - void check(union_type type) const noexcept - { - DEBUG_ASSERT(cur_type_ == type, detail::precondition_error_handler{}, - "different type stored in union"); - } - - using storage_t = detail::aligned_union; - storage_t storage_; - type_id cur_type_; -}; - -/// \exclude -template -constexpr typename tagged_union::type_id tagged_union::invalid_type; - -/// \exclude -namespace detail -{ - template - class with_union; - - template - class with_union, Args...> - { - public: - static void with(Union&& u, Func&& func, Args&&... args) - { - with_impl(typename std::decay::type::types{}, std::forward(u), - std::forward(func), std::forward(args)...); - } - - private: - template - static auto call(int, Union&& u, Func&& func, Args&&... args) - -> decltype(std::forward(func)(std::forward(u).value(union_type{}), - std::forward(args)...)) - { - return std::forward(func)(std::forward(u).value(union_type{}), - std::forward(args)...); - } - - template - static void call(short, Union&&, Func&&, Args&&...) - {} - - static void with_impl(union_types<>, Union&&, Func&&, Args&&...) {} - - template - static void with_impl(union_types, Union&& u, Func&& func, Args&&... args) - { - if (u.type() == union_type{}) - call(0, std::forward(u), std::forward(func), - std::forward(args)...); - else - with_impl(union_types{}, std::forward(u), std::forward(func), - std::forward(args)...); - } - }; -} // namespace detail - -/// \effects If the union is empty, does nothing. -/// Otherwise let the union contain an object of type `T`. -/// If the functor is callable for the `T`, calls its `operator()` passing it the stored object. -/// Else does nothing. -/// \group union_with -/// \module variant -template -void with(tagged_union& u, Func&& f, Args&&... additional_args) -{ - detail::with_union::types, - Args&&...>::with(u, std::forward(f), - std::forward(additional_args)...); -} - -/// \group union_with -template -void with(const tagged_union& u, Func&& f, Args&&... additional_args) -{ - detail::with_union::types, - Args&&...>::with(u, std::forward(f), - std::forward(additional_args)...); -} - -/// \group union_with -template -void with(tagged_union&& u, Func&& f, Args&&... additional_args) -{ - detail::with_union::types, - Args&&...>::with(std::move(u), std::forward(f), - std::forward(additional_args)...); -} - -/// \group union_with -template -void with(const tagged_union&& u, Func&& f, Args&&... additional_args) -{ - detail::with_union::types, - Args&&...>::with(std::move(u), std::forward(f), - std::forward(additional_args)...); -} - -/// \exclude -namespace detail -{ - template - struct destroy_union - { - struct visitor - { - template - void operator()(const T&, Union& u) - { - u.destroy(union_type{}); - } - }; - - static void destroy(Union& u) noexcept - { - if (Union::trivial::value) - u.cur_type_ = Union::invalid_type; - else - with(u, visitor{}, u); - } - }; - - template - struct copy_union - { - struct visitor - { - template - void operator()(const T& value, Union& dest) - { - dest.emplace(union_type{}, value); - } - }; - - static void copy(Union& dest, const Union& org) - { - if (Union::trivial::value) - { - dest.storage_ = org.storage_; - dest.cur_type_ = org.cur_type_; - } - else - with(org, visitor{}, dest); - } - }; - - template - struct move_union - { - struct visitor - { - template - void operator()(T&& value, Union& dest) - { - dest.emplace(union_type::type>{}, std::move(value)); - } - }; - - static void move(Union& dest, Union&& org) - { - if (Union::trivial::value) - { - dest.storage_ = org.storage_; - dest.cur_type_ = org.cur_type_; - } - else - with(std::move(org), visitor{}, dest); - } - }; -} // namespace detail - -/// \effects Destroys the type currently stored in the [ts::tagged_union](), -/// by calling `u.destroy(union_type{})`. -/// \module variant -template -void destroy(tagged_union& u) noexcept -{ - detail::destroy_union>::destroy(u); -} - -/// \effects Copies the type currently stored in one [ts::tagged_union]() to another. -/// This is equivalent to calling `dest.emplace(union_type{}, org.value(union_type{}))` (1)/ -/// `dest.emplace(union_type{}, std::move(org).value(union_type{}))` (2), -/// where `T` is the type currently stored in the union. -/// \throws Anything by the copy/move constructor in which case nothing has changed. -/// \requires `dest` must not store a type, -/// and all types must be copyable/moveable. -/// \group union_copy_move -/// \module variant -/// \unique_name *copy_union -template -void copy(tagged_union& dest, const tagged_union& org) -{ - DEBUG_ASSERT(!dest.has_value(), detail::precondition_error_handler{}); - detail::copy_union>::copy(dest, org); -} - -/// \group union_copy_move -/// \module variant -/// \unique_name *move_union -template -void move(tagged_union& dest, tagged_union&& org) -{ - DEBUG_ASSERT(!dest.has_value(), detail::precondition_error_handler{}); - detail::move_union>::move(dest, std::move(org)); -} -} // namespace type_safe - -#endif // TYPE_SAFE_TAGGED_UNION_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/types.hpp b/third/type_safe/include/type_safe/types.hpp deleted file mode 100644 index 1f6087b3..00000000 --- a/third/type_safe/include/type_safe/types.hpp +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_TYPES_HPP_INCLUDED -#define TYPE_SAFE_TYPES_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#include -#include -#include -#endif - -#include -#include -#include -#include -#include - -namespace type_safe -{ -/// \exclude -namespace detail -{ - template - constexpr T validate_value() - { - static_assert(sizeof(T) <= sizeof(U) - && std::is_signed::value == std::is_signed::value, - "mismatched types"); - static_assert(U(std::numeric_limits::min()) <= Value - && Value <= U(std::numeric_limits::max()), - "integer literal overflow"); - return static_cast(Value); - } - - template - constexpr T parse_signed() - { - return validate_value()>(); - } - - template - constexpr T parse_unsigned() - { - return validate_value()>(); - } -} // namespace detail - -#if TYPE_SAFE_ENABLE_WRAPPER -/// \exclude -# define TYPE_SAFE_DETAIL_WRAP(templ, x) templ -#else -# define TYPE_SAFE_DETAIL_WRAP(templ, x) x -#endif - -inline namespace types -{ - //=== fixed width integer ===// - /// \module types - using int8_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int8_t); - /// \module types - using int16_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int16_t); - /// \module types - using int32_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int32_t); - /// \module types - using int64_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int64_t); - /// \module types - using uint8_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint8_t); - /// \module types - using uint16_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint16_t); - /// \module types - using uint32_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint32_t); - /// \module types - using uint64_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint64_t); - - inline namespace literals - { - /// \module types - template - constexpr int8_t operator"" _i8() - { - return int8_t(detail::parse_signed()); - } - - /// \module types - template - constexpr int16_t operator"" _i16() - { - return int16_t(detail::parse_signed()); - } - - /// \module types - template - constexpr int32_t operator"" _i32() - { - return int32_t(detail::parse_signed()); - } - - /// \module types - template - constexpr int64_t operator"" _i64() - { - return int64_t(detail::parse_signed()); - } - - /// \module types - template - constexpr uint8_t operator"" _u8() - { - return uint8_t(detail::parse_unsigned()); - } - - /// \module types - template - constexpr uint16_t operator"" _u16() - { - return uint16_t(detail::parse_unsigned()); - } - - /// \module types - template - constexpr uint32_t operator"" _u32() - { - return uint32_t(detail::parse_unsigned()); - } - - /// \module types - template - constexpr uint64_t operator"" _u64() - { - return uint64_t(detail::parse_unsigned()); - } - } // namespace literals - - /// \module types - using int_fast8_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int_fast8_t); - /// \module types - using int_fast16_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int_fast16_t); - /// \module types - using int_fast32_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int_fast32_t); - /// \module types - using int_fast64_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int_fast64_t); - /// \module types - using uint_fast8_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint_fast8_t); - /// \module types - using uint_fast16_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint_fast16_t); - /// \module types - using uint_fast32_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint_fast32_t); - /// \module types - using uint_fast64_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint_fast64_t); - - /// \module types - using int_least8_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int_least8_t); - /// \module types - using int_least16_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int_least16_t); - /// \module types - using int_least32_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int_least32_t); - /// \module types - using int_least64_t = TYPE_SAFE_DETAIL_WRAP(integer, std::int_least64_t); - /// \module types - using uint_least8_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint_least8_t); - /// \module types - using uint_least16_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint_least16_t); - /// \module types - using uint_least32_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint_least32_t); - /// \module types - using uint_least64_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uint_least64_t); - - /// \module types - using intmax_t = TYPE_SAFE_DETAIL_WRAP(integer, std::intmax_t); - /// \module types - using uintmax_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uintmax_t); - /// \module types - using intptr_t = TYPE_SAFE_DETAIL_WRAP(integer, std::intptr_t); - /// \module types - using uintptr_t = TYPE_SAFE_DETAIL_WRAP(integer, std::uintptr_t); - - //=== special integer types ===// - /// \module types - using ptrdiff_t = TYPE_SAFE_DETAIL_WRAP(integer, std::ptrdiff_t); - /// \module types - using size_t = TYPE_SAFE_DETAIL_WRAP(integer, std::size_t); - - /// \module types - using int_t = TYPE_SAFE_DETAIL_WRAP(integer, int); - /// \module types - using unsigned_t = TYPE_SAFE_DETAIL_WRAP(integer, unsigned); - - inline namespace literals - { - /// \module types - template - constexpr ptrdiff_t operator"" _isize() - { - return ptrdiff_t(detail::parse_signed()); - } - - /// \module types - template - constexpr size_t operator"" _usize() - { - return size_t(detail::parse_unsigned()); - } - - /// \module types - template - constexpr int_t operator"" _i() - { - // int is at least 16 bits - return int_t(detail::parse_signed()); - } - - /// \module types - template - constexpr unsigned_t operator"" _u() - { - // int is at least 16 bits - return unsigned_t(detail::parse_unsigned()); - } - } // namespace literals - - //=== floating point types ===// - /// \module types - using float_t = TYPE_SAFE_DETAIL_WRAP(floating_point, std::float_t); - /// \module types - using double_t = TYPE_SAFE_DETAIL_WRAP(floating_point, std::double_t); - - inline namespace literals - { - /// \module types - constexpr float_t operator"" _f(long double val) - { - return float_t(static_cast(val)); - } - - /// \module types - constexpr double_t operator"" _d(long double val) - { - return double_t(static_cast(val)); - } - } // namespace literals - -//=== boolean ===// -#if TYPE_SAFE_ENABLE_WRAPPER - /// \module types - using bool_t = boolean; -#else - using bool_t = bool; -#endif -} // namespace types - -#undef TYPE_SAFE_DETAIL_WRAP -} // namespace type_safe - -#endif // TYPE_SAFE_TYPES_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/variant.hpp b/third/type_safe/include/type_safe/variant.hpp deleted file mode 100644 index 29914934..00000000 --- a/third/type_safe/include/type_safe/variant.hpp +++ /dev/null @@ -1,934 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_VARIANT_HPP_INCLUDED -#define TYPE_SAFE_VARIANT_HPP_INCLUDED - -#include -#include - -namespace type_safe -{ -/// Convenience alias for [ts::union_type](). -/// \module variant -template -using variant_type = union_type; - -/// Convenience alias for [ts::union_types](). -/// \module variant -template -using variant_types = union_types; - -/// Tag type to mark a [ts::basic_variant]() without a value. -/// \module variant -struct nullvar_t -{ - constexpr nullvar_t() {} -}; - -/// Tag object of type [ts::nullvar_t](). -/// \module variant -constexpr nullvar_t nullvar; - -/// An improved `union` storing at most one of the given types at a time (or possibly none). -/// -/// It is an improved version of [std::variant](). -/// A big problem with variant is implementing the operation that changes the type. -/// It has to destroy the old value and then create the new one. -/// But how to handle an exception when creating the new type? -/// There are multiple ways of handling this, so it is outsourced in a policy. -/// The variant policy is a class that must have the following members: -/// * `allow_empty` - either [std::true_type]() or [std::false_type](). -/// If it is "true", the variant can be put in the empty state explicitly. -/// * `void change_value(variant_type, tagged_union&, Args&&... args)` - changes the -/// value and type. It will be called when the variant already contains an object of a different -/// type. It must destroy the old type and create a new one with the given type and arguments. -/// \module variant -template -class basic_variant : detail::variant_copy, detail::variant_move -{ - using union_t = tagged_union; - using traits = detail::traits; - -public: - using types = typename union_t::types; - using type_id = typename union_t::type_id; - - using allow_empty = typename VariantPolicy::allow_empty; - - static constexpr type_id invalid_type = union_t::invalid_type; - - //=== constructors/destructors/assignment/swap ===// - /// \effects Initializes the variant to the empty state. - /// \notes This constructor only participates in overload resolution, - /// if the policy allows an empty variant. - /// \group default - /// \param Dummy - /// \exclude - /// \param 1 - /// \exclude - template ::type> - basic_variant() noexcept - {} - - /// \group default - /// \param Dummy - /// \exclude - /// \param 1 - /// \exclude - template ::type> - basic_variant(nullvar_t) noexcept : basic_variant() - {} - - /// Copy (1)/move (2) constructs a variant. - /// \effects If the other variant is not empty, it will call - /// [ts::copy](standardese://ts::copy_union/) (1) or [ts::move](standardese://ts::move_union/) - /// (2). \throws Anything thrown by the copy (1)/move (2) constructor. \notes This constructor - /// only participates in overload resolution, if all types are copy (1)/move (2) constructible./ - /// \notes The move constructor only moves the stored value, - /// and does not make the other variant empty. - /// \group copy_move_ctor - basic_variant(const basic_variant&) = default; - - /// \group copy_move_ctor - basic_variant(basic_variant&&) - TYPE_SAFE_NOEXCEPT_DEFAULT(traits::nothrow_move_constructible::value) - = default; - - /// Initializes it containing a new object of the given type. - /// \effects Creates it by calling `T`s constructor with the perfectly forwarded arguments. - /// \throws Anything thrown by `T`s constructor. - /// \notes This constructor does not participate in overload resolution, - /// unless `T` is a valid type for the variant and constructible from the arguments. - /// \param 2 - /// \exclude - template > - explicit basic_variant(variant_type type, Args&&... args) - { - storage_.get_union().emplace(type, std::forward(args)...); - } - - /// Initializes it with a copy of the given object. - /// \effects Same as the type + argument constructor called with the decayed type of the - /// argument and the object perfectly forwarded. \throws Anything thrown by `T`s copy/move - /// constructor. \notes This constructor does not participate in overload resolution, unless `T` - /// is a valid type for the variant and copy/move constructible. \param 1 \exclude - template > - basic_variant(T&& obj) - : basic_variant(variant_type::type>{}, std::forward(obj)) - {} - - /// Initializes it from a [ts::tagged_union](). - /// \effects Copies the currently stored type of the union - /// into the variant by calling the copy (1)/move (2) constructor of the stored type. - /// \throws Anything thrown by the selected copy (1)/move (2) constructor. - /// \requires If the variant policy does not allow the empty state, - /// the union must not be empty. - /// \group ctor_union - explicit basic_variant(const tagged_union& u) - { - DEBUG_ASSERT(allow_empty::value || u.has_value(), detail::precondition_error_handler{}); - copy(storage_.get_union(), u); - } - - /// \group ctor_union - explicit basic_variant(tagged_union&& u) - { - DEBUG_ASSERT(allow_empty::value || u.has_value(), detail::precondition_error_handler{}); - move(storage_.get_union(), std::move(u)); - } - - /// \effects Destroys the currently stored value, - /// if there is any. - ~basic_variant() noexcept = default; - - /// Copy (1)/move (2) assigns a variant. - /// \effects If the other variant is empty, - /// makes this one empty as well. - /// Otherwise let the other variant contains an object of type `T`. - /// If this variant contains the same type and there is a copy (1)/move (2) assignment operator - /// available, assigns the object to this object. Else forwards to the variant policy's - /// `change_value()` function. \throws Anything thrown by either the copy (1)/move (2) - /// assignment operator or copy (1)/move (2) constructor. If the assignment operator throws, the - /// variant will contain the partially assigned object. If the constructor throws, the state - /// depends on the variant policy. \notes This function does not participate in overload - /// resolution, unless all types are copy (1)/move (2) constructible. \group copy_move_assign - basic_variant& operator=(const basic_variant&) = default; - /// \group copy_move_assign - basic_variant& operator=(basic_variant&&) - TYPE_SAFE_NOEXCEPT_DEFAULT(traits::nothrow_move_assignable::value) - = default; - - /// Alias for [*reset()](). - /// \param Dummy - /// \exclude - /// \param 1 - /// \exclude - template ::type> - basic_variant& operator=(nullvar_t) noexcept - { - reset(); - return *this; - } - - /// Same as the single argument `emplace()`. - /// \effects Changes the value to a copy of `obj`. - /// \throws Anything thrown by `T`s copy/move constructor. - /// \notes This function does not participate in overload resolution, - /// unless `T` is a valid type for the variant and copy/move constructible. - /// \param 1 - /// \exclude - template > - basic_variant& operator=(T&& obj) - { - emplace(variant_type::type>{}, std::forward(obj)); - return *this; - } - - /// Swaps two variants. - /// \effects There are four cases: - /// * Both variants are empty. Then the function has no effect. - /// * Both variants contain the same type, `T`. Then it calls swap on the stored type. - /// * Both variants contain a type, but different types. - /// Then it swaps the variant by move constructing the objects from one type to the other, - /// using the variant policy. - /// * Only one variant contains an object. Then it moves the value to the empty variant, - /// and destroys it in the non-empty variant. - /// - /// \effects In either case, it will only call the swap() function or the move constructor. - /// \throws Anything thrown by the swap function, - /// in which case both variants contain the partially swapped values, - /// or the mvoe constructor, in which case the exact behavior depends on the variant policy. - friend void swap(basic_variant& a, basic_variant& b) noexcept(traits::nothrow_swappable::value) - { - auto& a_union = a.storage_.get_union(); - auto& b_union = b.storage_.get_union(); - - if (a_union.has_value() && b_union.has_value()) - detail::swap_union::swap(a_union, b_union); - else if (a_union.has_value() && !b_union.has_value()) - { - b = std::move(a); - a.reset(); - } - else if (!a_union.has_value() && b_union.has_value()) - { - a = std::move(b); - b.reset(); - } - } - - //=== modifiers ===// - /// \effects Destroys the stored value in the variant, if any. - /// \notes This function only participate in overload resolution, - /// if the variant policy allows the empty state. - /// \param Dummy - /// \exclude - /// \param 1 - /// \exclude - template ::type> - void reset() noexcept - { - destroy(storage_.get_union()); - } - - /// Changes the value to a new object of the given type. - /// \effects If the variant contains an object of the same type, - /// assigns the argument to it. - /// Otherwise behaves as the other emplace version. - /// \throws Anything thrown by the chosen assignment operator - /// or the other `emplace()`. - /// If the assignment operator throws, - /// the variant contains a partially assigned object. - /// Otherwise it depends on the variant policy. - /// \notes This function does not participate in overload resolution, - /// unless `T` is a valid type for the variant and assignable from the argument - /// without creating an additional temporary. - /// \param 2 - /// \exclude - /// \param 3 - /// \exclude - template ::value>::type, - typename = detail::enable_variant_type> - void emplace(variant_type type, Arg&& arg) - { - if (storage_.get_union().type() == typename union_t::type_id(type)) - storage_.get_union().value(type) = std::forward(arg); - else - emplace_impl(type, std::forward(arg)); - } - - /// Changes the value to a new object of given type. - /// \effects If variant is empty, creates the object directly in place - /// by perfectly forwarding the arguments. - /// Otherwise it forwards to the variant policy's `change_value()` function. - /// \throws Anything thrown by `T`s constructor or possibly move constructor. - /// If the variant was empty before, it is still empty afterwards. - /// Otherwise the state depends on the policy. - /// \notes This function does not participate in overload resolution, - /// unless `T` is a valid type for the variant and constructible from the arguments. - /// \param 2 - /// \exclude - template > - void emplace(variant_type type, Args&&... args) - { - emplace_impl(type, std::forward(args)...); - } - -private: - template - void emplace_impl(variant_type type, Args&&... args) - { - if (storage_.get_union().has_value()) - VariantPolicy::change_value(type, storage_.get_union(), std::forward(args)...); - else - storage_.get_union().emplace(type, std::forward(args)...); - } - - template - using enable_valid = typename std::enable_if<(type_id::template is_valid)()>::type; - -public: - //=== observers ===// - /// \returns The type id representing the type of the value currently stored in the variant. - /// \notes If it does not have a value stored, returns [*invalid_type](). - type_id type() const noexcept - { - return storage_.get_union().type(); - } - - /// \returns `true` if the variant currently contains a value, - /// `false` otherwise. - /// \notes Depending on the variant policy, - /// it can be guaranteed to return `true` all the time. - /// \group has_value - bool has_value() const noexcept - { - return storage_.get_union().has_value(); - } - - /// \group has_value - explicit operator bool() const noexcept - { - return has_value(); - } - - /// \group has_value - bool has_value(variant_type) const noexcept - { - return !has_value(); - } - - /// \returns `true` if the variant currently stores an object of type `T`, - /// `false` otherwise. - /// \notes `T` must not necessarily be a type that can be stored in the variant. - template - bool has_value(variant_type type) const noexcept - { - return this->type() == type_id(type); - } - - /// \returns A copy of [ts::nullvar](). - /// \requires The variant must be empty. - nullvar_t value(variant_type) const noexcept - { - DEBUG_ASSERT(!has_value(), detail::precondition_error_handler{}); - return nullvar; - } - - /// \returns A (`const`) lvalue (1, 2)/rvalue (3, 4) reference to the stored object of the given - /// type. \requires The variant must currently store an object of the given type, i.e. - /// `has_value(type)` must return `true`. \group value \param 1 \exclude - template > - T& value(variant_type type) TYPE_SAFE_LVALUE_REF noexcept - { - return storage_.get_union().value(type); - } - - /// \group value - /// \param 1 - /// \exclude - template > - const T& value(variant_type type) const TYPE_SAFE_LVALUE_REF noexcept - { - return storage_.get_union().value(type); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group value - /// \param 1 - /// \exclude - template > - T&& value(variant_type type) && noexcept - { - return std::move(storage_.get_union()).value(type); - } - - /// \group value - /// \param 1 - /// \exclude - template > - const T&& value(variant_type type) const&& noexcept - { - return std::move(storage_.get_union()).value(type); - } -#endif - - /// \returns A [ts::optional_ref]() to [ts::nullvar](). - /// If the variant is not empty, returns a null reference. - optional_ref optional_value(variant_type) const noexcept - { - return has_value() ? nullptr : type_safe::opt_ref(&nullvar); - } - - /// \returns A (`const`) [ts::optional_ref]() (1, 2)/[ts::optional_xvalue_ref]() to the stored - /// value of given type. If it stores a different type, returns a null reference. \group - /// optional_value - template - optional_ref optional_value(variant_type type) TYPE_SAFE_LVALUE_REF noexcept - { - return has_value(type) ? type_safe::opt_ref(&storage_.get_union().value(type)) : nullptr; - } - - /// \group optional_value - template - optional_ref optional_value(variant_type type) const TYPE_SAFE_LVALUE_REF noexcept - { - return has_value(type) ? type_safe::opt_ref(&storage_.get_union().value(type)) : nullptr; - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group optional_value - template - optional_xvalue_ref optional_value(variant_type type) && noexcept - { - return has_value(type) ? type_safe::opt_xref(&storage_.get_union().value(type)) : nullptr; - } - - /// \group optional_value - template - optional_xvalue_ref optional_value(variant_type type) const&& noexcept - { - return has_value(type) ? type_safe::opt_xref(&storage_.get_union().value(type)) : nullptr; - } -#endif - - /// \returns If the variant currently stores an object of type `T`, - /// returns a copy of that by copy (1)/move (2) constructing. - /// Otherwise returns `other` converted to `T`. - /// \throws Anything thrown by `T`s copy (1)/move (2) constructor or the converting constructor. - /// \notes `T` must not necessarily be a type that can be stored in the variant./ - /// \notes This function does not participate in overload resolution, - /// unless `T` is copy (1)/move (2) constructible and the fallback convertible to `T`. - /// \group value_or - /// \param 2 - /// \exclude - template - T value_or( - variant_type type, U&& other, - typename std::enable_if< - std::is_copy_constructible::value && std::is_convertible::value, int>::type - = 0) const TYPE_SAFE_LVALUE_REF - { - return has_value(type) ? value(type) : static_cast(std::forward(other)); - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group value_or - /// \param 2 - /// \exclude - template - T value_or( - variant_type type, U&& other, - typename std::enable_if< - std::is_move_constructible::value && std::is_convertible::value, int>::type - = 0) && - { - return has_value(type) ? std::move(value(type)) : static_cast(std::forward(other)); - } -#endif - - /// Maps a variant with a function. - /// \effects If the variant is not empty, - /// calls the function using either `std::forward(f)(current-value, - /// std::forward(args)...)` or member call syntax - /// `(current-value.*std::forward(f))(std::forward(args)...)`. If those two - /// expressions are both ill-formed, does nothing. \returns A new variant of the same type. It - /// contains nothing, if `*this` contains nothing. Otherwise, if the function was called, it - /// contains the result of the function. Otherwise, it is a copy of the current variant. \throws - /// Anything thrown by the function or copy/move constructor, in which case the variant will be - /// left unchanged, unless the object was already moved into the function and modified there. - /// \requires The result of the function - if it is called - can be stored in the variant. - /// \notes (1) will use the copy constructor, (2) will use the move constructor. - /// The function does not participate in overload resolution, - /// if copy (1)/move (2) constructors are not available for all types. - /// \group map - /// \param 1 - /// \exclude - /// \param 2 - /// \exclude - template ::type> - basic_variant map(Functor&& f, Args&&... args) const TYPE_SAFE_LVALUE_REF - { - basic_variant result(force_empty{}); - if (!has_value()) - return result; - detail::map_union::map(result.storage_.get_union(), - storage_.get_union(), std::forward(f), - std::forward(args)...); - DEBUG_ASSERT(result.has_value(), detail::assert_handler{}); - return result; - } - -#if TYPE_SAFE_USE_REF_QUALIFIERS - /// \group map - /// \param 1 - /// \exclude - /// \param 2 - /// \exclude - template ::type> - basic_variant map(Functor&& f, Args&&... args) && - { - basic_variant result(force_empty{}); - if (!has_value()) - return result; - detail::map_union::map(result.storage_.get_union(), - std::move(storage_.get_union()), - std::forward(f), - std::forward(args)...); - DEBUG_ASSERT(result.has_value(), detail::assert_handler{}); - return result; - } -#endif - -private: - struct force_empty - {}; - - basic_variant(force_empty) noexcept {} - - detail::variant_storage storage_; - - friend detail::storage_access; -}; - -/// \exclude -template -constexpr typename basic_variant::type_id - basic_variant::invalid_type; - -//=== comparison ===// -/// \exclude -#define TYPE_SAFE_DETAIL_MAKE_OP(Op, Expr, Expr2) \ - template \ - bool operator Op(const basic_variant& lhs, nullvar_t) \ - { \ - return (void)lhs, Expr; \ - } \ - /** \group variant_comp_null */ \ - template \ - bool operator Op(nullvar_t, const basic_variant& rhs) \ - { \ - return (void)rhs, Expr2; \ - } - -/// Compares a [ts::basic_variant]() with [ts::nullvar](). -/// -/// A variant compares equal to `nullvar`, when it does not have a value. -/// A variant compares never less to `nullvar`, `nullvar` compares less only if the variant has a -/// value. The other comparisons behave accordingly. \group variant_comp_null \module variant -TYPE_SAFE_DETAIL_MAKE_OP(==, !lhs.has_value(), !rhs.has_value()) -/// \group variant_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(!=, lhs.has_value(), rhs.has_value()) -/// \group variant_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(<, false, rhs.has_value()) -/// \group variant_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(<=, !lhs.has_value(), true) -/// \group variant_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(>, lhs.has_value(), false) -/// \group variant_comp_null -TYPE_SAFE_DETAIL_MAKE_OP(>=, true, !rhs.has_value()) - -#undef TYPE_SAFE_DETAIL_MAKE_OP - -/// Compares a [ts::basic_variant]() with a value. -/// -/// A variant compares equal to a value, if it contains an object of the same type and the object -/// compares equal. A variant compares less to a value, if - when it has a different type - the type -/// id compares less than the type id of the value, or - when it has the same type - the object -/// compares less to the value. The other comparisons behave accordingly. \notes The value must not -/// necessarily have a type that can be stored in the variant. \group variant_comp_t \module variant -template -bool operator==(const basic_variant& lhs, const T& rhs) -{ - return lhs.has_value(variant_type{}) && lhs.value(variant_type{}) == rhs; -} -/// \group variant_comp_t -template -bool operator==(const T& lhs, const basic_variant& rhs) -{ - return rhs == lhs; -} - -/// \group variant_comp_t -template -bool operator!=(const basic_variant& lhs, const T& rhs) -{ - return !(lhs == rhs); -} -/// \group variant_comp_t -template -bool operator!=(const T& lhs, const basic_variant& rhs) -{ - return !(rhs == lhs); -} - -/// \group variant_comp_t -template -bool operator<(const basic_variant& lhs, const T& rhs) -{ - constexpr auto id = - typename basic_variant::type_id(variant_type{}); - if (lhs.type() != id) - return lhs.type() < id; - return lhs.value(variant_type{}) < rhs; -} -/// \group variant_comp_t -template -bool operator<(const T& lhs, const basic_variant& rhs) -{ - constexpr auto id = - typename basic_variant::type_id(variant_type{}); - if (id != rhs.type()) - return id < rhs.type(); - return lhs < rhs.value(variant_type{}); -} - -/// \group variant_comp_t -template -bool operator<=(const basic_variant& lhs, const T& rhs) -{ - return !(rhs < lhs); -} -/// \group variant_comp_t -template -bool operator<=(const T& lhs, const basic_variant& rhs) -{ - return !(rhs < lhs); -} - -/// \group variant_comp_t -template -bool operator>(const basic_variant& lhs, const T& rhs) -{ - return rhs < lhs; -} -/// \group variant_comp_t -template -bool operator>(const T& lhs, const basic_variant& rhs) -{ - return rhs < lhs; -} - -/// \group variant_comp_t -template -bool operator>=(const basic_variant& lhs, const T& rhs) -{ - return !(lhs < rhs); -} -/// \group variant_comp_t -template -bool operator>=(const T& lhs, const basic_variant& rhs) -{ - return !(lhs < rhs); -} - -/// Compares two [ts::basic_variant]()s. -/// -/// They compare equal if both store the same type (or none) and the stored object compares equal. -/// A variant is less than another if they store mismatched types and the type id of the first is -/// less than the other, or if they store the same type and the stored object compares less. The -/// other comparisons behave accordingly. \module variant \group variant_comp -template -bool operator==(const basic_variant& lhs, - const basic_variant& rhs) -{ - return detail::compare_variant< - basic_variant>::compare_equal(lhs, rhs); -} - -/// \group variant_comp -template -bool operator!=(const basic_variant& lhs, - const basic_variant& rhs) -{ - return !(lhs == rhs); -} - -/// \group variant_comp -template -bool operator<(const basic_variant& lhs, - const basic_variant& rhs) -{ - return detail::compare_variant>::compare_less(lhs, - rhs); -} - -/// \group variant_comp -template -bool operator<=(const basic_variant& lhs, - const basic_variant& rhs) -{ - return !(rhs < lhs); -} - -/// \group variant_comp -template -bool operator>(const basic_variant& lhs, - const basic_variant& rhs) -{ - return rhs < lhs; -} - -/// \group variant_comp -template -bool operator>=(const basic_variant& lhs, - const basic_variant& rhs) -{ - return !(lhs < rhs); -} - -/// \effects If the variant is empty, does nothing. -/// Otherwise let the variant contain an object of type `T`. -/// If the functor is callable for the `T`, calls its `operator()` passing it the stored object. -/// Else does nothing. -/// \module variant -/// \group variant_with -template -void with(basic_variant& variant, Func&& func, - Args&&... additional_args) -{ - with(detail::storage_access::get(variant).get_union(), std::forward(func), - std::forward(additional_args)...); -} - -/// \group variant_with -template -void with(const basic_variant& variant, Func&& func, - Args&&... additional_args) -{ - with(detail::storage_access::get(variant).get_union(), std::forward(func), - std::forward(additional_args)...); -} - -/// \group variant_with -template -void with(basic_variant&& variant, Func&& func, - Args&&... additional_args) -{ - with(std::move(detail::storage_access::get(variant).get_union()), std::forward(func), - std::forward(additional_args)...); -} - -/// \group variant_with -template -void with(const basic_variant&& variant, Func&& func, - Args&&... additional_args) -{ - with(std::move(detail::storage_access::get(variant).get_union()), std::forward(func), - std::forward(additional_args)...); -} - -/// A variant policy for [ts::basic_variant]() that uses a fallback type. -/// -/// When changing the type of the variant throws an exception, -/// the variant will create an object of the fallback type instead. -/// The variant will never be empty. -/// \requires `Fallback` must be nothrow default constructible -/// and a type that can be stored in the variant. -/// \module variant -template -class fallback_variant_policy -{ - static_assert(std::is_nothrow_default_constructible::value, - "fallback must be nothrow default constructible"); - -public: - using allow_empty = std::false_type; - - template - static void change_value(union_type type, tagged_union& storage, Args&&... args) - { - change_value_impl(type, storage, std::forward(args)...); - } - -private: - template - static auto change_value_impl(union_type type, tagged_union& storage, - Args&&... args) noexcept -> - typename std::enable_if::value>::type - { - destroy(storage); - // won't throw - storage.emplace(type, std::forward(args)...); - } - - template - static auto change_value_impl(union_type type, tagged_union& storage, - Args&&... args) -> - typename std::enable_if::value>::type - { - destroy(storage); - TYPE_SAFE_TRY - { - // might throw - storage.emplace(type, std::forward(args)...); - } - TYPE_SAFE_CATCH_ALL - { - // won't throw - storage.emplace(union_type{}); - TYPE_SAFE_RETHROW; - } - } -}; - -/// A [ts::basic_variant]() using the [ts::fallback_variant_policy](). -/// -/// This is a variant that is never empty, where exceptions on changing the type -/// leaves it with a default-constructed object of the `Fallback` type. -/// \requires `Fallback` must be nothrow default constructible. -/// \module variant -template -using fallback_variant = basic_variant, Fallback, OtherTypes...>; - -/// A variant policy for [ts::basic_variant]() that creates a variant with explicit empty state. -/// -/// It allows an empty variant explicitly. -/// When changing the type of the variant throws an exception, -/// the variant will be left in that empty state. -/// \module variant -class optional_variant_policy -{ -public: - using allow_empty = std::true_type; - - template - static void change_value(union_type type, tagged_union& storage, Args&&... args) - { - destroy(storage); - storage.emplace(type, std::forward(args)...); - } -}; - -/// \exclude -namespace detail -{ - template - class non_empty_variant_policy - { - public: - using allow_empty = std::false_type; - - template - static void change_value(union_type type, tagged_union& storage, - Args&&... args) - { - change_value_impl(type, storage, std::forward(args)...); - } - - private: - template - static void move_emplace(union_type type, tagged_union& storage, - T&& obj) noexcept(ForceNonEmpty) - { - // if this throws, there's nothing we can do - storage.emplace(type, std::move(obj)); - } - - template - static void change_value_impl(union_type type, tagged_union& storage, T&& obj) - { - destroy(storage); - move_emplace(type, storage, std::move(obj)); // throw handled - } - - template - static auto change_value_impl(union_type type, tagged_union& storage, - Args&&... args) -> - typename std::enable_if::value>::type - { - destroy(storage); - // won't throw - storage.emplace(type, std::forward(args)...); - } - - template - static auto change_value_impl(union_type type, tagged_union& storage, - Args&&... args) -> - typename std::enable_if::value>::type - { - T tmp(std::forward(args)...); // might throw - destroy(storage); - move_emplace(type, storage, std::move(tmp)); // throw handled - } - }; -} // namespace detail - -/// A variant policy for [ts::basic_variant]() that creates a variant which is rarely empty. -/// -/// When changing the type of the variant, it will use a the move constructor with a temporary. -/// If the move constructor throws, the variant will be left in the empty state. -/// Putting it into the empty state explicitly is not allowed. -/// \module variant -using rarely_empty_variant_policy = detail::non_empty_variant_policy; - -/// A variant policy for [ts::basic_variant]() that creates a variant which is never empty. -/// -/// Similar to [ts::rarely_empty_variant_policy]() but when the move constructor throws, -/// it calls [std::terminate()](). -/// \module variant -using never_empty_variant_policy = detail::non_empty_variant_policy; - -/// \exclude -namespace detail -{ - template - struct select_variant_policy - { - using type = basic_variant; - }; - - template - struct select_variant_policy - { - using type = basic_variant; - }; -} // namespace detail - -/// A [ts::basic_variant]() with the recommended default semantics. -/// -/// If the first type is [ts::nullvar_t]() it will use the [ts::optional_variant_policy](), -/// which explicitly allows the empty state. -/// Otherwise it will use the [ts::rarely_empty_variant_policy]() -/// where it tries to avoid the empty state as good as possible. -/// \notes If you pass [ts::nullvar_t]() as the first type, -/// it is not actually one of the types that can be stored in the variant, -/// but a tag to enable the empty state. -/// \module variant -template -using variant = typename detail::select_variant_policy::type; -} // namespace type_safe - -#endif // TYPE_SAFE_VARIANT_HPP_INCLUDED diff --git a/third/type_safe/include/type_safe/visitor.hpp b/third/type_safe/include/type_safe/visitor.hpp deleted file mode 100644 index 7535bc77..00000000 --- a/third/type_safe/include/type_safe/visitor.hpp +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_VISITOR_HPP_INCLUDED -#define TYPE_SAFE_VISITOR_HPP_INCLUDED - -#if defined(TYPE_SAFE_IMPORT_STD_MODULE) -import std; -#else -#include -#endif - -#include -#include - -namespace type_safe -{ -/// \exclude -namespace detail -{ - // common type where void is wildcard - template - struct common_type - { - using type = typename std::conditional::value, A, - typename std::common_type::type>::type; - }; - - template - struct common_type - { - using type = A; - }; - - template - struct common_type - { - using type = A; - }; - - template <> - struct common_type - { - using type = void; - }; - - template - using common_type_t = typename common_type::type; - - //=== visit optional ===// - template - struct visit_optional; - - template - struct visit_optional - { - template - static auto call_visitor(int, Visitor&& visitor, Args&&... args) - -> decltype(std::forward(visitor)(std::forward(args)...)) - { - return std::forward(visitor)(std::forward(args)...); - } - - template - static void call_visitor(short, Visitor&&, Args&&...) - { - static_assert(!Save, "call to visitor does not cover all possible combinations"); - } - - template - static auto call(Visitor&& visitor, Optional&& opt, Args&&... args) -> - typename common_type(visitor), - std::forward(args)..., nullopt)), - decltype(call_visitor(0, std::forward(visitor), - std::forward(args)..., - std::forward(opt).value()))>::type - { - return opt.has_value() ? call_visitor(0, std::forward(visitor), - std::forward(args)..., - std::forward(opt).value()) - : call_visitor(0, std::forward(visitor), - std::forward(args)..., nullopt); - } - }; - - template - struct visit_optional - { - template - static auto call(Visitor&& visitor, Optional&& opt, Rest&&... rest, Args&&... args) -> - typename common_type::call( - std::forward(visitor), std::forward(rest)..., - std::forward(args)..., - std::forward(opt).value())), - decltype(visit_optional::call( - std::forward(visitor), std::forward(rest)..., - std::forward(args)..., nullopt))>::type - { - return opt.has_value() - ? visit_optional::call(std::forward(visitor), - std::forward(rest)..., - std::forward(args)..., - std::forward(opt).value()) - : visit_optional::call(std::forward( - visitor), - std::forward(rest)..., - std::forward(args)..., - nullopt); - } - }; - - template - struct visitor_allow_incomplete - { - template - static std::true_type test(int); - - template - static std::true_type test(int, decltype(U::incomplete_visitor)); - - template - static std::false_type test(short); - - static const bool value = decltype(test::type>(0))::value; - }; - - template - auto visit_optional_impl(Visitor&& visitor, Optionals&&... optionals) -> decltype( - detail::visit_optional< - !visitor_allow_incomplete::value, decltype(std::forward(visitor)), - decltype(std::forward(optionals))...>::call(std::forward(visitor), - std::forward( - optionals)...)) - { - return detail::visit_optional< - !visitor_allow_incomplete::value, decltype(std::forward(visitor)), - decltype(std::forward(optionals))...>::call(std::forward(visitor), - std::forward( - optionals)...); - } -} // namespace detail - -/// Visits a [ts::basic_optional](). -/// \effects Effectively calls `visitor((optionals.has_value() ? optionals.value() : nullopt)...)`, -/// i.e. the `operator()` of `visitor` passing it `sizeof...(Optionals)` arguments, -/// where the `i`th argument is the `value()` of the `i`th optional or `nullopt`, if it has none. -/// If the particular combination of types is not overloaded, -/// the program is ill-formed, -/// unless the `Visitor` provides a member named `incomplete_visitor`, -/// then `visit()` does not do anything instead of the error. -/// \returns The result of the chosen `operator()`, -/// its the type is the common type of all possible combinations. -/// \module optional -/// \exclude return -/// \param 2 -/// \exclude -template ::value...>::value, - int>::type - = 0> -auto visit(Visitor&& visitor, Optionals&&... optionals) - -> decltype(detail::visit_optional_impl(std::forward(visitor), - std::forward(optionals)...)) -{ - return detail::visit_optional_impl(std::forward(visitor), - std::forward(optionals)...); -} - -/// \exclude -namespace detail -{ - template - class visit_variant_impl; - - template - class visit_variant_impl - { - template - static auto call_impl(int, Visitor&& visitor, Args&&... args) - -> decltype(std::forward(visitor)(std::forward(args)...)) - { - return std::forward(visitor)(std::forward(args)...); - } - - template - static void call_impl(short, Visitor&&, Args&&...) - { - static_assert(AllowIncomplete, "visitor does not cover all possible combinations"); - } - - public: - template - static auto call(Visitor&& visitor, Args&&... args) - -> decltype(call_impl(0, std::forward(visitor), std::forward(args)...)) - { - return call_impl(0, std::forward(visitor), std::forward(args)...); - } - }; - - // should not be called - template - Head get_dummy_type(const Variant& var, variant_types) - { - return var.value(variant_type{}); - } - - template - auto get_dummy_type(const Variant& var) - -> decltype(get_dummy_type(var, typename Variant::types{})) - { - return get_dummy_type(var, typename Variant::types{}); - } - - template - class visit_variant_impl - { - template ::type> - static auto call_type(Visitor&& visitor, variant_types<>, Variant&& variant, Args&&... args) - -> typename std::enable_if::call( - std::forward(visitor), - std::forward(args)..., nullvar))>::type - { - DEBUG_ASSERT(!variant.has_value(), assert_handler{}, - "it has a value but we are in this overload?!"); - return visit_variant_impl::call(std::forward( - visitor), - std::forward(args)..., - nullvar); - } - - template ::type> - static auto call_type(Visitor&& visitor, variant_types<>, Variant&& variant, Args&&... args) - -> - typename std::enable_if::call( - std::forward(visitor), std::forward(args)..., - get_dummy_type(variant)))>::type - { - DEBUG_ASSERT(!variant.has_value(), assert_handler{}, - "it has a value but we are in this overload?!"); - DEBUG_UNREACHABLE(precondition_error_handler{}, "variant in invalid state for visit"); - return visit_variant_impl::call(std::forward( - visitor), - std::forward(args)..., - get_dummy_type(variant)); - } - - template - static auto call_type(Visitor&& visitor, variant_types, Variant&& variant, - Args&&... args) - -> common_type_t::call( - std::forward(visitor), std::forward(args)..., - std::forward(variant).value(variant_type{}))), - decltype(RecursiveDecltype::template call_type( - std::forward(visitor), variant_types{}, - std::forward(variant), std::forward(args)...))> - { - if (variant.has_value(variant_type{})) - return visit_variant_impl::call(std::forward(visitor), - std::forward(args)..., - std::forward(variant).value( - variant_type{})); - else - return RecursiveDecltype::template call_type< - RecursiveDecltype>(std::forward(visitor), variant_types{}, - std::forward(variant), std::forward(args)...); - } - - public: - template - static auto call(Visitor&& visitor, Variant&& variant, Args&&... args) - -> decltype(call_type(std::forward(visitor), - typename std::decay::type::types{}, - std::forward(variant), - std::forward(args)...)) - { - return visit_variant_impl::call_type< - visit_variant_impl>(std::forward(visitor), - typename std::decay::type::types{}, - std::forward(variant), std::forward(args)...); - } - }; - - template - class visit_variant_impl - { - template ::type> - static auto call_type(Visitor&& visitor, variant_types<>, Variant&& variant, Rest&&... rest, - Args&&... args) -> - typename std::enable_if< - Variant2::allow_empty::value, - decltype(visit_variant_impl::call( - std::forward(visitor), std::forward(rest)..., - std::forward(args)..., nullvar))>::type - { - DEBUG_ASSERT(std::decay::type::allow_empty::value && !variant.has_value(), - precondition_error_handler{}, "variant in invalid state for visitor"); - return visit_variant_impl::call(std::forward(visitor), - std::forward(rest)..., - std::forward(args)..., nullvar); - } - - template ::type> - static auto call_type(Visitor&& visitor, variant_types<>, Variant&& variant, Rest&&... rest, - Args&&... args) -> - typename std::enable_if< - !Variant2::allow_empty::value, - decltype(visit_variant_impl::call( - std::forward(visitor), std::forward(rest)..., - std::forward(args)..., get_dummy_type(variant)))>::type - { - DEBUG_ASSERT(!variant.has_value(), assert_handler{}, - "it has a value but we are in this overload?!"); - DEBUG_UNREACHABLE(precondition_error_handler{}, "variant in invalid state for visit"); - return visit_variant_impl::call(std::forward(visitor), - std::forward(rest)..., - std::forward(args)..., - get_dummy_type(variant)); - } - - template - static auto call_type(Visitor&& visitor, variant_types, Variant&& variant, - Rest&&... rest, Args&&... args) - -> common_type_t::call( - std::forward(visitor), std::forward(rest)..., - std::forward(args)..., - std::forward(variant).value(variant_type{}))), - decltype(RecursiveDecltype::template call_type( - std::forward(visitor), variant_types{}, - std::forward(variant), std::forward(rest)..., - std::forward(args)...))> - { - if (variant.has_value(variant_type{})) - return visit_variant_impl::call(std::forward(visitor), - std::forward(rest)..., - std::forward(args)..., - std::forward(variant).value( - variant_type{})); - else - return RecursiveDecltype::template call_type< - RecursiveDecltype>(std::forward(visitor), variant_types{}, - std::forward(variant), std::forward(rest)..., - std::forward(args)...); - } - - public: - template - static auto call(Visitor&& visitor, Variant&& variant, Rest&&... rest, Args&&... args) - -> decltype(call_type(std::forward(visitor), - typename std::decay::type::types{}, - std::forward(variant), - std::forward(rest)..., - std::forward(args)...)) - { - return visit_variant_impl::call_type< - visit_variant_impl>(std::forward(visitor), - typename std::decay::type::types{}, - std::forward(variant), std::forward(rest)..., - std::forward(args)...); - } - }; - - template - auto visit_variant(Visitor&& visitor, Variants&&... variants) - -> decltype(visit_variant_impl::value, Visitor&&, - Variants&&...>::call(std::forward(visitor), - std::forward(variants)...)) - { - return visit_variant_impl::value, Visitor&&, - Variants&&...>::call(std::forward(visitor), - std::forward(variants)...); - } -} // namespace detail - -/// Visits a [ts::basic_variant](). -/// \effects Effectively calls `visitor(variants.value(variant_type{})...)`, -/// where `Ts...` are the types of the currently active element in the variant, -/// i.e. it calls the `operator()` of the `visitor` where the `i`th argument is the currently stored -/// value in the `i`th variant, perfectly forwarded. If the `i`th variant is empty and it allows the -/// empty state, it passes `nullvar` as parameter, otherwise the behavior is undefined. If the -/// particular combination of types is not overloaded, the program is ill-formed, unless the -/// `Visitor` provides a member named `incomplete_visitor`, then `visit()` does not do anything -/// instead of the error. \returns The result of the chosen `operator()`, its the type is the common -/// type of all possible combinations. \exclude return \module variant -template ::value...>::value>::type> -auto visit(Visitor&& visitor, Variants&&... variants) - -> decltype(detail::visit_variant(std::forward(visitor), - std::forward(variants)...)) -{ - return detail::visit_variant(std::forward(visitor), - std::forward(variants)...); -} -} // namespace type_safe - -#endif // TYPE_SAFE_VISITOR_HPP_INCLUDED diff --git a/third/type_safe/test/CMakeLists.txt b/third/type_safe/test/CMakeLists.txt deleted file mode 100644 index 3d914143..00000000 --- a/third/type_safe/test/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (C) 2016-2019 Jonathan Müller -# This file is subject to the license terms in the LICENSE file -# found in the top-level directory of this distribution. - -if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/catch.hpp) - file(DOWNLOAD - https://github.com/catchorg/Catch2/releases/download/v2.13.10/catch.hpp - ${CMAKE_CURRENT_BINARY_DIR}/catch.hpp - STATUS status - LOG log) - - list(GET status 0 status_code) - list(GET status 1 status_string) - - if(NOT status_code EQUAL 0) - message(FATAL_ERROR "error downloading catch: ${status_string}" - "${log}") - endif() -endif() - -set(source_files test.cpp - arithmetic_policy.cpp - boolean.cpp - bounded_type.cpp - compact_optional.cpp - constrained_type.cpp - constant_parser.cpp - deferred_construction.cpp - downcast.cpp - flag.cpp - flag_set.cpp - floating_point.cpp - index.cpp - integer.cpp - narrow_cast.cpp - optional.cpp - optional_ref.cpp - output_parameter.cpp - reference.cpp - strong_typedef.cpp - tagged_union.cpp - variant.cpp - visitor.cpp) -add_executable(type_safe_test debugger_type.hpp ${source_files}) -target_link_libraries(type_safe_test PUBLIC type_safe) -target_include_directories(type_safe_test PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) - -if(NOT TYPE_SAFE_IMPORT_STD_MODULE) - target_compile_features(type_safe_test PRIVATE cxx_std_14) # some tests require 14 -endif() - -if(MSVC) - target_compile_definitions(type_safe_test PRIVATE TYPE_SAFE_TEST_NO_STATIC_ASSERT) -elseif(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) - target_compile_definitions(type_safe_test PRIVATE TYPE_SAFE_TEST_NO_STATIC_ASSERT) -endif() - -add_test(NAME test COMMAND type_safe_test) diff --git a/third/type_safe/test/arithmetic_policy.cpp b/third/type_safe/test/arithmetic_policy.cpp deleted file mode 100644 index 78f816b2..00000000 --- a/third/type_safe/test/arithmetic_policy.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -using namespace type_safe; - -TEST_CASE("over/underflow") -{ - SECTION("unsigned") - { - auto max = std::numeric_limits::max(); - - REQUIRE(detail::will_addition_error(detail::unsigned_integer_tag{}, max, 1u)); - REQUIRE(detail::will_addition_error(detail::unsigned_integer_tag{}, max - 5u, 10u)); - REQUIRE(detail::will_addition_error(detail::unsigned_integer_tag{}, max - 1u, max)); - REQUIRE(!detail::will_addition_error(detail::unsigned_integer_tag{}, 0u, max)); - REQUIRE(!detail::will_addition_error(detail::unsigned_integer_tag{}, 1u, max - 1u)); - - REQUIRE(detail::will_subtraction_error(detail::unsigned_integer_tag{}, 0u, 1u)); - REQUIRE(detail::will_subtraction_error(detail::unsigned_integer_tag{}, 5u, 6u)); - REQUIRE(detail::will_subtraction_error(detail::unsigned_integer_tag{}, 0u, max)); - REQUIRE(!detail::will_subtraction_error(detail::unsigned_integer_tag{}, 5u, 5u)); - - REQUIRE(detail::will_multiplication_error(detail::unsigned_integer_tag{}, max, max)); - REQUIRE(detail::will_multiplication_error(detail::unsigned_integer_tag{}, max, 2u)); - REQUIRE(detail::will_multiplication_error(detail::unsigned_integer_tag{}, max / 2u, 3u)); - REQUIRE(!detail::will_multiplication_error(detail::unsigned_integer_tag{}, max / 3u, 3u)); - - REQUIRE(detail::will_division_error(detail::unsigned_integer_tag{}, 1u, 0u)); - REQUIRE(!detail::will_division_error(detail::unsigned_integer_tag{}, 1u, 1u)); - - REQUIRE(detail::will_modulo_error(detail::unsigned_integer_tag{}, 1u, 0u)); - REQUIRE(!detail::will_modulo_error(detail::unsigned_integer_tag{}, 1u, 1u)); - } - SECTION("signed") - { - auto max = std::numeric_limits::max(); - auto min = std::numeric_limits::min(); - - REQUIRE(detail::will_addition_error(detail::signed_integer_tag{}, max, 1)); - REQUIRE(detail::will_addition_error(detail::signed_integer_tag{}, max - 5, 10)); - REQUIRE(detail::will_addition_error(detail::signed_integer_tag{}, max - 1, max)); - REQUIRE(!detail::will_addition_error(detail::signed_integer_tag{}, 0, max)); - REQUIRE(!detail::will_addition_error(detail::signed_integer_tag{}, 1, max - 1)); - REQUIRE(detail::will_addition_error(detail::signed_integer_tag{}, min, -1)); - REQUIRE(detail::will_addition_error(detail::signed_integer_tag{}, min + 5, -10)); - REQUIRE(!detail::will_addition_error(detail::signed_integer_tag{}, 0, min)); - REQUIRE(!detail::will_addition_error(detail::signed_integer_tag{}, -1, min + 1)); - - REQUIRE(detail::will_subtraction_error(detail::signed_integer_tag{}, min, 1)); - REQUIRE(detail::will_subtraction_error(detail::signed_integer_tag{}, min + 5, 6)); - REQUIRE(detail::will_subtraction_error(detail::signed_integer_tag{}, min, max)); - REQUIRE(!detail::will_subtraction_error(detail::signed_integer_tag{}, 5, 5)); - REQUIRE(detail::will_subtraction_error(detail::signed_integer_tag{}, max, -1)); - REQUIRE(detail::will_subtraction_error(detail::signed_integer_tag{}, max - 5, -6)); - REQUIRE(!detail::will_subtraction_error(detail::signed_integer_tag{}, 5, -5)); - - REQUIRE(detail::will_multiplication_error(detail::signed_integer_tag{}, max, max)); - REQUIRE(detail::will_multiplication_error(detail::signed_integer_tag{}, max, 2)); - REQUIRE(detail::will_multiplication_error(detail::signed_integer_tag{}, max / 2, 3)); - REQUIRE(!detail::will_multiplication_error(detail::signed_integer_tag{}, max / 3, 3)); - REQUIRE(detail::will_multiplication_error(detail::signed_integer_tag{}, max, min)); - REQUIRE(detail::will_multiplication_error(detail::signed_integer_tag{}, max, -2)); - REQUIRE(detail::will_multiplication_error(detail::signed_integer_tag{}, max / 2, -3)); - REQUIRE(!detail::will_multiplication_error(detail::signed_integer_tag{}, max / 3, -3)); - - REQUIRE(detail::will_division_error(detail::signed_integer_tag{}, 1, 0)); - REQUIRE(detail::will_division_error(detail::signed_integer_tag{}, min, -1)); - REQUIRE(!detail::will_division_error(detail::signed_integer_tag{}, 1, 1)); - - REQUIRE(detail::will_modulo_error(detail::signed_integer_tag{}, 1, 0)); - REQUIRE(!detail::will_modulo_error(detail::signed_integer_tag{}, 1, 1)); - } -} diff --git a/third/type_safe/test/boolean.cpp b/third/type_safe/test/boolean.cpp deleted file mode 100644 index 2267f8e6..00000000 --- a/third/type_safe/test/boolean.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -#include - -using namespace type_safe; - -#ifndef TYPE_SAFE_TEST_NO_STATIC_ASSERT -static_assert(std::is_standard_layout::value, ""); -static_assert(std::is_trivially_copyable::value, ""); -// conversion checks -static_assert(std::is_constructible::value, ""); -static_assert(!std::is_constructible::value, ""); -static_assert(std::is_assignable::value, ""); -static_assert(!std::is_assignable::value, ""); -#endif - -TEST_CASE("boolean") -{ - SECTION("constructor") - { - boolean b1(true); - REQUIRE(static_cast(b1)); - - boolean b2(false); - REQUIRE(!static_cast(b2)); - } - SECTION("assignment") - { - boolean b1(true); - b1 = false; - REQUIRE(!static_cast(b1)); - b1 = true; - REQUIRE(static_cast(b1)); - } - SECTION("negate") - { - boolean b1(true); - REQUIRE(!b1 == false); - - boolean b2(false); - REQUIRE(!b2 == true); - } - SECTION("comparison") - { - boolean b1(true); - REQUIRE(b1 == true); - REQUIRE(true == b1); - REQUIRE(b1 != false); - REQUIRE(false != b1); - REQUIRE(b1 == boolean(true)); - REQUIRE(b1 != boolean(false)); - - boolean b2(false); - REQUIRE(b2 == false); - REQUIRE(false == b2); - REQUIRE(b2 != true); - REQUIRE(true != b2); - REQUIRE(b2 == boolean(false)); - REQUIRE(b2 != boolean(true)); - } - SECTION("i/o") - { - std::ostringstream out; - std::istringstream in("0"); - - boolean b(true); - out << b; - REQUIRE(out.str() == "1"); - - in >> b; - REQUIRE(!static_cast(b)); - } -} diff --git a/third/type_safe/test/bounded_type.cpp b/third/type_safe/test/bounded_type.cpp deleted file mode 100644 index c323239d..00000000 --- a/third/type_safe/test/bounded_type.cpp +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -#include - -using namespace type_safe; - -TEST_CASE("constraints::less") -{ - constraints::less p(42); - REQUIRE(p.get_bound() == 42); - REQUIRE(p(0)); - REQUIRE(p(40)); - REQUIRE(!p(42)); - REQUIRE(!p(50)); - REQUIRE(!p(100)); -} - -TEST_CASE("constraints::less_equal") -{ - constraints::less_equal p(42); - REQUIRE(p.get_bound() == 42); - REQUIRE(p(0)); - REQUIRE(p(40)); - REQUIRE(p(42)); - REQUIRE(!p(50)); - REQUIRE(!p(100)); -} - -TEST_CASE("constraints::greater") -{ - constraints::greater p(42); - REQUIRE(p.get_bound() == 42); - REQUIRE(!p(0)); - REQUIRE(!p(40)); - REQUIRE(!p(42)); - REQUIRE(p(50)); - REQUIRE(p(100)); -} - -TEST_CASE("constraints::greater_equal") -{ - constraints::greater_equal p(42); - REQUIRE(p.get_bound() == 42); - REQUIRE(!p(0)); - REQUIRE(!p(40)); - REQUIRE(p(42)); - REQUIRE(p(50)); - REQUIRE(p(100)); -} - -TEST_CASE("constraints::bounded") -{ - SECTION("closed, closed") - { - constraints::bounded p(0, 42); - static_assert(std::is_same>::value, ""); - REQUIRE(p.get_lower_bound() == 0); - REQUIRE(p.get_upper_bound() == 42); - - REQUIRE(p(30)); - REQUIRE(p(41)); - REQUIRE(p(1)); - - REQUIRE(p(0)); - REQUIRE(p(42)); - - REQUIRE(!p(-5)); - REQUIRE(!p(100)); - } - SECTION("open, closed") - { - constraints::bounded p(0, 42); - REQUIRE(p.get_lower_bound() == 0); - REQUIRE(p.get_upper_bound() == 42); - - REQUIRE(p(30)); - REQUIRE(p(41)); - REQUIRE(p(1)); - - REQUIRE(!p(0)); - REQUIRE(p(42)); - - REQUIRE(!p(-5)); - REQUIRE(!p(100)); - } - SECTION("closed, open") - { - constraints::bounded p(0, 42); - REQUIRE(p.get_lower_bound() == 0); - REQUIRE(p.get_upper_bound() == 42); - - REQUIRE(p(30)); - REQUIRE(p(41)); - REQUIRE(p(1)); - - REQUIRE(p(0)); - REQUIRE(!p(42)); - - REQUIRE(!p(-5)); - REQUIRE(!p(100)); - } - SECTION("open, open") - { - constraints::bounded p(0, 42); - static_assert(std::is_same>::value, ""); - REQUIRE(p.get_lower_bound() == 0); - REQUIRE(p.get_upper_bound() == 42); - - REQUIRE(p(30)); - REQUIRE(p(41)); - REQUIRE(p(1)); - - REQUIRE(!p(0)); - REQUIRE(!p(42)); - - REQUIRE(!p(-5)); - REQUIRE(!p(100)); - } -} - -TEST_CASE("bounded literal") -{ - SECTION("unsigned") - { - constraints::less, lit_detail::integer_bound> p( - 42_boundu); - static_assert(std::is_same::value, - "ups"); - REQUIRE(p.get_bound() == 42); - } - SECTION("signed") - { - constraints::less, lit_detail::integer_bound> p(42_bound); - static_assert(std::is_same::value, "ups"); - REQUIRE(p.get_bound() == 42); - } - SECTION("signed negative") - { - constraints::less, lit_detail::integer_bound> p(-42_bound); - static_assert(std::is_same::value, "ups"); - REQUIRE(p.get_bound() == -42); - } - - bounded_type, true, true, lit_detail::integer_bound, - lit_detail::integer_bound> - bounded = make_bounded(integer(50), 0_bound, 100_bound); - REQUIRE(bounded.get_constraint().get_lower_bound() == 0); - REQUIRE(bounded.get_constraint().get_upper_bound() == 100); -} - -TEST_CASE("bounded_type") -{ - constrained_type> dynamic_closed - = make_bounded(10, 0, 42); - static_assert(std::is_same>::value, ""); - REQUIRE(dynamic_closed.get_value() == 10); - REQUIRE(dynamic_closed.get_constraint().get_lower_bound() == 0); - REQUIRE(dynamic_closed.get_constraint().get_upper_bound() == 42); - - constrained_type> dynamic_open - = make_bounded_exclusive(10, 0, 42); - static_assert(std::is_same>::value, ""); - REQUIRE(dynamic_open.get_value() == 10); - REQUIRE(dynamic_open.get_constraint().get_lower_bound() == 0); - REQUIRE(dynamic_open.get_constraint().get_upper_bound() == 42); - - constrained_type, - std::integral_constant>> - static_closed - = make_bounded(10, std::integral_constant{}, std::integral_constant{}); - static_assert(std::is_same, - std::integral_constant>>::value, - ""); - REQUIRE(static_closed.get_value() == 10); - REQUIRE(static_closed.get_constraint().get_lower_bound() == 0); - REQUIRE(static_closed.get_constraint().get_upper_bound() == 42); - - decltype(static_closed) static_closed_default(10); - REQUIRE(static_closed_default.get_value() == 10); - REQUIRE(static_closed_default.get_constraint().get_lower_bound() == 0); - REQUIRE(static_closed_default.get_constraint().get_upper_bound() == 42); - - constrained_type, - std::integral_constant>> - static_open = make_bounded_exclusive(10, std::integral_constant{}, - std::integral_constant{}); - static_assert(std::is_same, - std::integral_constant>>::value, - ""); - REQUIRE(static_open.get_value() == 10); - REQUIRE(static_open.get_constraint().get_lower_bound() == 0); - REQUIRE(static_open.get_constraint().get_upper_bound() == 42); - - decltype(static_open) static_open_default(10); - REQUIRE(static_open_default.get_value() == 10); - REQUIRE(static_open_default.get_constraint().get_lower_bound() == 0); - REQUIRE(static_open_default.get_constraint().get_upper_bound() == 42); - - constrained_type>> - mixed_closed = make_bounded(10, 0, std::integral_constant{}); - static_assert(std::is_same>>::value, - ""); - REQUIRE(mixed_closed.get_value() == 10); - REQUIRE(mixed_closed.get_constraint().get_lower_bound() == 0); - REQUIRE(mixed_closed.get_constraint().get_upper_bound() == 42); - - constrained_type>> - mixed_open = make_bounded_exclusive(10, 0, std::integral_constant{}); - static_assert(std::is_same>>::value, - ""); - REQUIRE(mixed_open.get_value() == 10); - REQUIRE(mixed_open.get_constraint().get_lower_bound() == 0); - REQUIRE(mixed_open.get_constraint().get_upper_bound() == 42); -} - -TEST_CASE("clamping_verifier") -{ - SECTION("less_equal") - { - constraints::less_equal p(42); - - int a = 0; - a = clamping_verifier::verify(a, p); - REQUIRE(a == 0); - - int b = 30; - b = clamping_verifier::verify(b, p); - REQUIRE(b == 30); - - int c = 42; - c = clamping_verifier::verify(c, p); - REQUIRE(c == 42); - - int d = 50; - d = clamping_verifier::verify(d, p); - REQUIRE(d == 42); - } - SECTION("greater_equal") - { - constraints::greater_equal p(42); - - int a = 0; - a = clamping_verifier::verify(a, p); - REQUIRE(a == 42); - - int b = 30; - b = clamping_verifier::verify(b, p); - REQUIRE(b == 42); - - int c = 42; - c = clamping_verifier::verify(c, p); - REQUIRE(c == 42); - - int d = 50; - d = clamping_verifier::verify(d, p); - REQUIRE(d == 50); - } - SECTION("closed_interval") - { - constraints::closed_interval p(0, 42); - - int a = 30; - a = clamping_verifier::verify(a, p); - REQUIRE(a == 30); - - int b = 10; - b = clamping_verifier::verify(b, p); - REQUIRE(b == 10); - - int c = 0; - c = clamping_verifier::verify(c, p); - REQUIRE(c == 0); - - int d = 42; - d = clamping_verifier::verify(d, p); - REQUIRE(d == 42); - - int e = 50; - e = clamping_verifier::verify(e, p); - REQUIRE(e == 42); - - int f = -20; - f = clamping_verifier::verify(f, p); - REQUIRE(f == 0); - } -} - -TEST_CASE("clamped_type") -{ - int value; - SECTION("no_clamping") - { - value = 10; - } - SECTION("clamping_lower") - { - value = -42; - } - SECTION("clamping_upper") - { - value = 100; - } - - clamped_type dynamic = make_clamped(value, 0, 42); - - auto clamped_val = value; - clamped_val = clamp(dynamic.get_constraint(), clamped_val); - REQUIRE(dynamic.get_value() == clamped_val); - - REQUIRE(dynamic.get_constraint().get_lower_bound() == 0); - REQUIRE(dynamic.get_constraint().get_upper_bound() == 42); - - clamped_type, std::integral_constant> static_ - = make_clamped(value, std::integral_constant{}, std::integral_constant{}); - - clamped_val = value; - clamped_val = clamp(static_.get_constraint(), clamped_val); - REQUIRE(static_.get_value() == clamped_val); - - REQUIRE(static_.get_constraint().get_lower_bound() == 0); - REQUIRE(static_.get_constraint().get_upper_bound() == 42); - - clamped_type> mixed - = make_clamped(value, std::integral_constant{}, 42); - - clamped_val = value; - clamped_val = clamp(mixed.get_constraint(), clamped_val); - REQUIRE(mixed.get_value() == clamped_val); - - REQUIRE(mixed.get_constraint().get_lower_bound() == 0); - REQUIRE(mixed.get_constraint().get_upper_bound() == 42); -} diff --git a/third/type_safe/test/compact_optional.cpp b/third/type_safe/test/compact_optional.cpp deleted file mode 100644 index 9f9c51d1..00000000 --- a/third/type_safe/test/compact_optional.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -using namespace type_safe; - -namespace type_safe -{ -template class basic_optional>>; -template class basic_optional>>; -template class basic_optional>>; -} // namespace type_safe - -TEST_CASE("compact_bool") -{ - using storage = compact_optional_storage>; - - storage s; - REQUIRE(!s.has_value()); - - s.create_value(true); - REQUIRE(s.has_value()); - REQUIRE(s.get_value() == true); - - s.destroy_value(); - REQUIRE(!s.has_value()); - - s.create_value(false); - REQUIRE(s.has_value()); - REQUIRE(s.get_value() == false); -} - -TEST_CASE("compact_integer") -{ - using storage = compact_optional_storage>; - - storage s; - REQUIRE(!s.has_value()); - - s.create_value(0); - REQUIRE(s.has_value()); - REQUIRE(s.get_value() == 0); - - s.destroy_value(); - REQUIRE(!s.has_value()); - - s.create_value(1); - REQUIRE(s.has_value()); - REQUIRE(s.get_value() == 1); -} - -TEST_CASE("compact_floating_point") -{ - using storage = compact_optional_storage>; - - storage s; - REQUIRE(!s.has_value()); - - s.create_value(0.1); - REQUIRE(s.has_value()); - REQUIRE(s.get_value() == 0.1f); - - s.destroy_value(); - REQUIRE(!s.has_value()); - - s.create_value(1.0); - REQUIRE(s.has_value()); - REQUIRE(s.get_value() == 1.0); -} - -enum class test_compact_enum -{ - a, - b, -}; - -template class type_safe::basic_optional< - compact_optional_storage>>; - -TEST_CASE("compact_enum") -{ - using storage = compact_optional_storage>; - - storage s; - REQUIRE(!s.has_value()); - - s.create_value(test_compact_enum::a); - REQUIRE(s.has_value()); - REQUIRE(s.get_value() == test_compact_enum::a); - - s.destroy_value(); - REQUIRE(!s.has_value()); - - s.create_value(test_compact_enum::b); - REQUIRE(s.has_value()); - REQUIRE(s.get_value() == test_compact_enum::b); -} - -struct test_compact_container -{ - bool empty_ = true; - - test_compact_container() {} - - test_compact_container(int) : empty_(false) {} - - bool empty() const - { - return empty_; - } -}; -template class type_safe::basic_optional< - compact_optional_storage>>; - -TEST_CASE("compact_container") -{ - using storage = compact_optional_storage>; - - storage s; - REQUIRE(!s.has_value()); - - s.create_value(0); - REQUIRE(s.has_value()); - REQUIRE(!s.get_value().empty()); - - s.destroy_value(); - REQUIRE(!s.has_value()); -} diff --git a/third/type_safe/test/constant_parser.cpp b/third/type_safe/test/constant_parser.cpp deleted file mode 100644 index e7d5b8bb..00000000 --- a/third/type_safe/test/constant_parser.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -using namespace type_safe; - -TEST_CASE("detail::parse") -{ - REQUIRE((detail::parse() == 0)); - REQUIRE((detail::parse() == 10)); - REQUIRE((detail::parse() == 423)); - REQUIRE((detail::parse() == 23900)); - - REQUIRE((detail::parse() == 8)); - REQUIRE((detail::parse() == 10)); - REQUIRE((detail::parse() == 1)); -} diff --git a/third/type_safe/test/constrained_type.cpp b/third/type_safe/test/constrained_type.cpp deleted file mode 100644 index 0f3ae67b..00000000 --- a/third/type_safe/test/constrained_type.cpp +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -using namespace type_safe; - -struct test_verifier -{ - static bool expected; - - template - static T&& verify(T&& value, const Predicate& p) - { - REQUIRE(p(value) == expected); - return std::forward(value); - } -}; - -bool test_verifier::expected; - -struct test_predicate -{ - bool operator()(int i) const - { - return i != -1; - } -}; - -TEST_CASE("constrained_type") -{ - using my_int = constrained_type; - - SECTION("constructor") - { - test_verifier::expected = true; - my_int a(5); - REQUIRE(a.get_value() == 5); - my_int b(-4); - REQUIRE(b.get_value() == -4); - - test_verifier::expected = false; - my_int c(-1); - REQUIRE(c.get_value() == -1); - } - SECTION("assignment") - { - test_verifier::expected = true; - my_int a(5); - a = 2; - a = 3; - a = -2; - - test_verifier::expected = false; - a = -1; - } - SECTION("constrain") - { - test_verifier::expected = true; - my_int a = constrain(5, test_predicate{}); - REQUIRE(a.get_value() == 5); - my_int b = constrain(-4, test_predicate{}); - REQUIRE(b.get_value() == -4); - - test_verifier::expected = false; - my_int c = constrain(-1, test_predicate{}); - REQUIRE(c.get_value() == -1); - } - SECTION("modify()") - { - // with() is the same - test_verifier::expected = true; - my_int a(4); - { - auto modify = a.modify(); - modify.get() += 4; - } - REQUIRE(a.get_value() == 8); - { - auto modify = a.modify(); - modify.get() -= 5; - modify.get() = 2; - } - REQUIRE(a.get_value() == 2); - - { - auto modify = a.modify(); - modify.get() = -1; - test_verifier::expected = false; - } - REQUIRE(a.get_value() == -1); - try - { - auto modify = a.modify(); - modify.get() = -1; - throw 0; - } - catch (...) - { - REQUIRE(a.get_value() == -1); - } - } -} - -TEST_CASE("constrained_ref") -{ - using my_ref = constrained_ref; - - auto valid1 = 5; - auto valid2 = -4; - auto invalid = -1; - - SECTION("constructor") - { - test_verifier::expected = true; - my_ref a(valid1); - REQUIRE(a.get_value() == 5); - my_ref b(valid2); - REQUIRE(b.get_value() == -4); - - test_verifier::expected = false; - my_ref c(invalid); - REQUIRE(c.get_value() == -1); - } - SECTION("modify()") - { - // with() is the same - test_verifier::expected = true; - my_ref a(valid1); - { - auto modify = a.modify(); - modify.get() += 3; - } - REQUIRE(a.get_value() == 8); - { - auto modify = a.modify(); - modify.get() -= 5; - modify.get() = 2; - } - REQUIRE(a.get_value() == 2); - - { - auto modify = a.modify(); - modify.get() = -1; - test_verifier::expected = false; - } - REQUIRE(a.get_value() == -1); - try - { - auto modify = a.modify(); - modify.get() = -1; - throw 0; - } - catch (...) - { - REQUIRE(a.get_value() == -1); - } - } -} - -TEST_CASE("throwing_verifier") -{ - auto dummy1 = 0, dummy2 = 0; - - constrained_type a(&dummy1); - REQUIRE_NOTHROW((a = &dummy2, true)); - REQUIRE_THROWS_AS(a = static_cast(nullptr), constrain_error); - - constrained_type b - = sanitize(&dummy2, constraints::non_null{}); - REQUIRE_NOTHROW((b = &dummy2, true)); - REQUIRE_THROWS_AS(b = static_cast(nullptr), constrain_error); -} - -TEST_CASE("constraints::non_null") -{ -#ifndef TYPE_SAFE_TEST_NO_STATIC_ASSERT - // conversion checks - using ptr = constrained_type; - static_assert(std::is_constructible::value, ""); - static_assert(!std::is_constructible::value, ""); - static_assert(std::is_assignable::value, ""); - static_assert(!std::is_assignable::value, ""); -#endif - - constraints::non_null p; - REQUIRE(!p(static_cast(nullptr))); - REQUIRE(!p(static_cast(0))); - - int a; - REQUIRE(p(&a)); -} - -struct my_container -{ - bool empty; -}; - -bool empty(my_container c) -{ - return c.empty; -} - -TEST_CASE("constraints::non_empty") -{ - constraints::non_empty p; - REQUIRE(p(std::string("hi"))); - REQUIRE(!p(std::string())); - - REQUIRE(p(my_container{false})); - REQUIRE(!p(my_container{true})); -} - -TEST_CASE("constraints::non_default") -{ - constraints::non_default p; - REQUIRE(p(5)); - REQUIRE(p(-1)); - REQUIRE(!p(int())); -} - -TEST_CASE("constraints::non_invalid") -{ - constraints::non_invalid p; - - REQUIRE(p(&p)); - REQUIRE(!p(static_cast(nullptr))); - - REQUIRE(!p(false)); - REQUIRE(p(true)); - - struct my_bool - { - bool b; - - explicit operator bool() const noexcept - { - return b; - } - }; - REQUIRE(p(my_bool{true})); - REQUIRE(!p(my_bool{false})); -} diff --git a/third/type_safe/test/debugger_type.hpp b/third/type_safe/test/debugger_type.hpp deleted file mode 100644 index f11bb483..00000000 --- a/third/type_safe/test/debugger_type.hpp +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#ifndef TYPE_SAFE_TEST_DEBUGGER_TYPE_HPP_INCLUDED -#define TYPE_SAFE_TEST_DEBUGGER_TYPE_HPP_INCLUDED - -struct debugger_type -{ - int id; - bool from_ctor = false; - bool from_move_ctor = false; - bool from_copy_ctor = false; - bool was_move_assigned = false; - bool was_copy_assigned = false; - bool swapped = false; - - debugger_type(int id, double = 0., char = 0) : id(id) - { - from_ctor = true; - } - - debugger_type(debugger_type&& other) : debugger_type(other.id) - { - from_move_ctor = true; - } - - debugger_type(const debugger_type& other) : debugger_type(other.id) - { - from_copy_ctor = true; - } - - ~debugger_type() = default; - - debugger_type& operator=(debugger_type&& other) - { - id = other.id; - was_move_assigned = true; - return *this; - } - - debugger_type& operator=(const debugger_type& other) - { - id = other.id; - was_copy_assigned = true; - return *this; - } - - friend void swap(debugger_type& a, debugger_type& b) noexcept - { - std::swap(a.id, b.id); - a.swapped = b.swapped = true; - } - - bool ctor() const - { - return from_ctor; - } - - bool move_ctor() const - { - return !from_copy_ctor; - } - - bool copy_ctor() const - { - return !from_move_ctor; - } - - bool not_assigned() const - { - return !was_copy_assigned && !was_move_assigned; - } - - bool move_assigned() const - { - return was_move_assigned && !was_copy_assigned; - } - - bool copy_assigned() const - { - return was_copy_assigned && !was_move_assigned; - } -}; - -inline bool operator==(const debugger_type& a, const debugger_type& b) -{ - return a.id == b.id; -} - -inline bool operator<(const debugger_type& a, const debugger_type& b) -{ - return a.id < b.id; -} - -#endif // TYPE_SAFE_TEST_DEBUGGER_TYPE_HPP_INCLUDED diff --git a/third/type_safe/test/deferred_construction.cpp b/third/type_safe/test/deferred_construction.cpp deleted file mode 100644 index f8a6da4e..00000000 --- a/third/type_safe/test/deferred_construction.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include -#include - -using namespace type_safe; - -TEST_CASE("deferred_construction") -{ - SECTION("constructor - empty") - { - deferred_construction a; - REQUIRE(!a.has_value()); - } - SECTION("constructor - copy/move") - { - deferred_construction a; - a = 0; - - deferred_construction b(a); - REQUIRE(b.has_value()); - REQUIRE(b.value() == 0); - - deferred_construction c(std::move(a)); - REQUIRE(c.has_value()); - REQUIRE(c.value() == 0); - - deferred_construction d; - - deferred_construction e(d); - REQUIRE(!e.has_value()); - - deferred_construction f(std::move(d)); - REQUIRE(!d.has_value()); - } - SECTION("assignment") - { - deferred_construction a; - REQUIRE(!a.has_value()); - - a = 42; - REQUIRE(a.has_value()); - REQUIRE(a.value() == 42); - } - SECTION("emplace") - { - deferred_construction a; - REQUIRE(!a.has_value()); - - a.emplace(3u, 'c'); - REQUIRE(a.has_value()); - REQUIRE(a.value() == "ccc"); - } - SECTION("operator bool") - { - deferred_construction a; - REQUIRE(!a); - a = 42; - REQUIRE(a); - } -} diff --git a/third/type_safe/test/downcast.cpp b/third/type_safe/test/downcast.cpp deleted file mode 100644 index baa91f27..00000000 --- a/third/type_safe/test/downcast.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -using namespace type_safe; - -TEST_CASE("downcast") -{ - struct base - { - virtual ~base() = default; - }; - - struct derived : base - { - ~derived() override = default; - }; - - base b; - derived d; - - SECTION("base -> base") - { - base& ref = b; - - base& res1 = downcast(ref); - REQUIRE(&res1 == &ref); - - base& res2 = downcast(derived_type{}, ref); - REQUIRE(&res2 == &ref); - } - SECTION("const base -> const base") - { - const base& ref = b; - - const base& res1 = downcast(ref); - REQUIRE(&res1 == &ref); - - const base& res2 = downcast(derived_type{}, ref); - REQUIRE(&res2 == &ref); - } - SECTION("base -> derived") - { - base& ref = d; - - derived& res1 = downcast(ref); - REQUIRE(&res1 == &ref); - - derived& res2 = downcast(derived_type{}, ref); - REQUIRE(&res2 == &ref); - } - SECTION("const base -> const derived") - { - const base& ref = d; - - const derived& res1 = downcast(ref); - REQUIRE(&res1 == &ref); - - const derived& res2 = downcast(derived_type{}, ref); - REQUIRE(&res2 == &ref); - } -} diff --git a/third/type_safe/test/flag.cpp b/third/type_safe/test/flag.cpp deleted file mode 100644 index b580ffc2..00000000 --- a/third/type_safe/test/flag.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -using namespace type_safe; - -TEST_CASE("flag") -{ - SECTION("constructor") - { - flag a(true); - REQUIRE(a == true); - - flag b(false); - REQUIRE(b == false); - } - SECTION("toggle") - { - flag a(true); - REQUIRE(a.toggle()); - REQUIRE(a == false); - - flag b(false); - REQUIRE(!b.toggle()); - REQUIRE(b == true); - } - SECTION("change") - { - flag a(true); - a.change(false); - REQUIRE(a == false); - - flag b(false); - b.change(true); - REQUIRE(b == true); - } - SECTION("set") - { - flag a(true); - a.set(); - REQUIRE(a == true); - - flag b(false); - b.set(); - REQUIRE(b == true); - } - SECTION("try_set") - { - flag a(true); - REQUIRE(!a.try_set()); - REQUIRE(a == true); - - flag b(false); - REQUIRE(b.try_set()); - REQUIRE(b == true); - } - SECTION("reset") - { - flag a(true); - a.reset(); - REQUIRE(a == false); - - flag b(false); - b.reset(); - REQUIRE(b == false); - } - SECTION("try_reset") - { - flag a(true); - REQUIRE(a.try_reset()); - REQUIRE(a == false); - - flag b(false); - REQUIRE(!b.try_reset()); - REQUIRE(b == false); - } -} diff --git a/third/type_safe/test/flag_set.cpp b/third/type_safe/test/flag_set.cpp deleted file mode 100644 index 7a2f380a..00000000 --- a/third/type_safe/test/flag_set.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -// no using namespace to test operator namespace - -enum class test_flags -{ - a, - b, - c -}; - -namespace type_safe -{ -template <> -struct flag_set_traits : std::true_type -{ - static constexpr std::size_t size() - { - return 3; - } -}; -} // namespace type_safe - -void check_set(const type_safe::flag_set& set, bool a, bool b, bool c) -{ - REQUIRE(set.is_set(test_flags::a) == a); - REQUIRE(set.as_flag(test_flags::a) == a); - if (a) - REQUIRE((set & test_flags::a)); - - REQUIRE(set.is_set(test_flags::b) == b); - REQUIRE(set.as_flag(test_flags::b) == b); - if (b) - REQUIRE((set & test_flags::b)); - - REQUIRE(set.is_set(test_flags::c) == c); - REQUIRE(set.as_flag(test_flags::c) == c); - if (c) - REQUIRE((set & test_flags::c)); - - if (a || b || c) - { - REQUIRE(set.any()); - REQUIRE_FALSE(set.none()); - REQUIRE(set != type_safe::noflag); - REQUIRE(type_safe::noflag != set); - } - else - { - REQUIRE_FALSE(set.any()); - REQUIRE(set.none()); - REQUIRE(set == type_safe::noflag); - REQUIRE(type_safe::noflag == set); - } - - auto number = (a ? 4 : 0) + (b ? 2 : 0) + (c ? 1 : 0); - switch (number) - { - case 0: - REQUIRE(set == type_safe::flag_set()); - break; - case 1: - REQUIRE(set == test_flags::c); - REQUIRE(set == type_safe::combo(~test_flags::a & ~test_flags::b)); - REQUIRE((set & test_flags::c)); - break; - case 2: - REQUIRE(set == test_flags::b); - REQUIRE(set == type_safe::combo(~test_flags::a & ~test_flags::c)); - REQUIRE((set & test_flags::b)); - break; - case 3: - REQUIRE(set == (test_flags::b | test_flags::c)); - REQUIRE(set == type_safe::combo(~test_flags::a)); - REQUIRE((set & (test_flags::b | test_flags::c))); - break; - case 4: - REQUIRE(set == test_flags::a); - REQUIRE(set == type_safe::combo(~test_flags::b & ~test_flags::c)); - REQUIRE((set & test_flags::a)); - break; - case 5: - REQUIRE(set == (test_flags::a | test_flags::c)); - REQUIRE(set == type_safe::combo(~test_flags::b)); - REQUIRE((set & (test_flags::a | test_flags::c))); - break; - case 6: - REQUIRE(set == (test_flags::a | test_flags::b)); - REQUIRE(set == type_safe::combo(~test_flags::c)); - REQUIRE((set & (test_flags::a | test_flags::b))); - break; - case 7: - REQUIRE(set.all()); - REQUIRE(set == (test_flags::a | test_flags::b | test_flags::c)); - REQUIRE((set & (test_flags::a | test_flags::b | test_flags::c))); - break; - - default: - REQUIRE(false); - break; - } -} - -TEST_CASE("flag_set_traits") -{ - using namespace type_safe; - - enum class a - { - e1, - e2, - e3 - }; - static_assert(!flag_set_traits::value, "a is not a flag set enum"); - - enum class b - { - e1, - e2, - e3, - _flag_set_size, - }; - static_assert(flag_set_traits::value, "b is a flag set enum"); - static_assert(flag_set_traits::size() == 3u, "size of b is 3"); -} - -TEST_CASE("flag_set") -{ - using namespace type_safe; - - using set = flag_set; - - set s; - check_set(s, false, false, false); - - SECTION("constructor/assignment") - { - set a; - check_set(a, false, false, false); - - set b(test_flags::a); - check_set(b, true, false, false); - - a = test_flags::b; - check_set(a, false, true, false); - - b = test_flags::c; - check_set(b, false, false, true); - } - SECTION("set") - { - s.set(test_flags::a); - check_set(s, true, false, false); - - s.set(test_flags::b, true); - check_set(s, true, true, false); - - s.set(test_flags::a, false); - check_set(s, false, true, false); - - s.set(test_flags::a, flag(true)); - check_set(s, true, true, false); - } - SECTION("reset") - { - s.set(test_flags::a); - check_set(s, true, false, false); - - s.reset(test_flags::b); - check_set(s, true, false, false); - - s.reset(test_flags::a); - check_set(s, false, false, false); - } - SECTION("toggle") - { - s.toggle(test_flags::a); - check_set(s, true, false, false); - - s.toggle(test_flags::b); - check_set(s, true, true, false); - - s.toggle(test_flags::a); - check_set(s, false, true, false); - } - SECTION("set_all/reset_all/toggle_all") - { - s.set_all(); - check_set(s, true, true, true); - - s.reset_all(); - check_set(s, false, false, false); - - s.set(test_flags::c); - check_set(s, false, false, true); - - s.toggle_all(); - check_set(s, true, true, false); - } - SECTION("binary op") - { - s |= test_flags::a; - check_set(s, true, false, false); - - s |= test_flags::b | test_flags::c; - check_set(s, true, true, true); - - s &= ~test_flags::c; - check_set(s, true, true, false); - - s = ~s; - check_set(s, false, false, true); - - s ^= test_flags::a | test_flags::c; - check_set(s, true, false, false); - } -} diff --git a/third/type_safe/test/floating_point.cpp b/third/type_safe/test/floating_point.cpp deleted file mode 100644 index 5ac7bc54..00000000 --- a/third/type_safe/test/floating_point.cpp +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -#include - -using namespace type_safe; - -#ifndef TYPE_SAFE_TEST_NO_STATIC_ASSERT -static_assert(std::is_trivially_copyable>::value, ""); -static_assert(std::is_standard_layout>::value, ""); -// conversion checks -static_assert(std::is_constructible, float>::value, ""); -static_assert(!std::is_constructible, double>::value, ""); -static_assert(std::is_constructible, double>::value, ""); -static_assert(std::is_constructible, double>::value, ""); -static_assert(!std::is_constructible, long double>::value, ""); -static_assert(std::is_assignable, float>::value, ""); -static_assert(!std::is_assignable, double>::value, ""); -static_assert(std::is_assignable, double>::value, ""); -static_assert(std::is_assignable, double>::value, ""); -static_assert(!std::is_assignable, long double>::value, ""); -#endif - -TEST_CASE("floating_point") -{ - using float_t = floating_point; - - SECTION("constructor") - { - float_t a(0.); - REQUIRE(static_cast(a) == 0.); - float_t b(3.14); - REQUIRE(static_cast(b) == 3.14); - float_t c(-42.5); - REQUIRE(static_cast(c) == -42.5); - } - SECTION("assignment") - { - float_t a(0.); - a = 3.14; - REQUIRE(static_cast(a) == 3.14); - a = -42.5; - REQUIRE(static_cast(a) == -42.5); - } - SECTION("unary") - { - float_t a(13.255); - REQUIRE(static_cast(+a) == static_cast(a)); - REQUIRE(static_cast(-a) == -static_cast(a)); - } - SECTION("addition") - { - float_t wrapper(0.); - double normal(0.); - REQUIRE(static_cast(wrapper) == normal); - - wrapper += 4.5; - normal += 4.5; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = wrapper + (-2.3); - normal = normal + (-2.3); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = 1.1 + wrapper; - normal = 1.1 + normal; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = float_t(-11.0) + wrapper; - normal = -11.0 + normal; - REQUIRE(static_cast(wrapper) == normal); - } - SECTION("subtraction") - { - float_t wrapper(0.); - double normal(0.); - REQUIRE(static_cast(wrapper) == normal); - - wrapper -= 4.5; - normal -= 4.5; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = wrapper - (-2.3); - normal = normal - (-2.3); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = 1.1 - wrapper; - normal = 1.1 - normal; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = float_t(-11.0) - wrapper; - normal = -11.0 - normal; - REQUIRE(static_cast(wrapper) == normal); - } - SECTION("multiplication") - { - float_t wrapper(1.); - double normal(1.); - REQUIRE(static_cast(wrapper) == normal); - - wrapper *= 4.5; - normal *= 4.5; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = wrapper * (-2.3); - normal = normal * (-2.3); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = 1.1 * wrapper; - normal = 1.1 * normal; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = float_t(-11.0) * wrapper; - normal = -11.0 * normal; - REQUIRE(static_cast(wrapper) == normal); - } - SECTION("division") - { - float_t wrapper(10.); - double normal(10.); - REQUIRE(static_cast(wrapper) == normal); - - wrapper /= 4.5; - normal /= 4.5; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = wrapper / (-2.3); - normal = normal / (-2.3); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = 1.1 / wrapper; - normal = 1.1 / normal; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = float_t(-11.0) / wrapper; - normal = -11.0 / normal; - REQUIRE(static_cast(wrapper) == normal); - } - SECTION("comparison") - { - // < - REQUIRE(bool(float_t(4.) < float_t(5.))); - REQUIRE(!(float_t(5.) < float_t(4.))); - REQUIRE(!(float_t(4.) < float_t(4.))); - - REQUIRE(bool(4. < float_t(5.))); - REQUIRE(!(5. < float_t(4.))); - REQUIRE(!(4. < float_t(4.))); - - REQUIRE(bool(float_t(4.) < 5.)); - REQUIRE(!(float_t(5.) < 4.)); - REQUIRE(!(float_t(4.) < 4.)); - - // <= - REQUIRE(bool(float_t(4.) <= float_t(5.))); - REQUIRE(!(float_t(5.) <= float_t(4.))); - REQUIRE(bool(float_t(4.) <= float_t(4.))); - - REQUIRE(bool(4. <= float_t(5.))); - REQUIRE(!(5. <= float_t(4.))); - REQUIRE(bool(4. <= float_t(4.))); - - REQUIRE(bool(float_t(4.) <= 5.)); - REQUIRE(!(float_t(5.) <= 4.)); - REQUIRE(bool(float_t(4.) <= 4.)); - - // > - REQUIRE(bool(float_t(5.) > float_t(4.))); - REQUIRE(!(float_t(4.) > float_t(5.))); - REQUIRE(!(float_t(5.) > float_t(5.))); - - REQUIRE(bool(5. > float_t(4.))); - REQUIRE(!(4. > float_t(5.))); - REQUIRE(!(5. > float_t(5.))); - - REQUIRE(bool(float_t(5.) > 4.)); - REQUIRE(!(float_t(4.) > 5.)); - REQUIRE(!(float_t(5.) > 5.)); - - // >= - REQUIRE(bool(float_t(5.) >= float_t(4.))); - REQUIRE(!(float_t(4.) >= float_t(5.))); - REQUIRE(bool(float_t(5.) >= float_t(5.))); - - REQUIRE(bool(5. >= float_t(4.))); - REQUIRE(!(4. >= float_t(5.))); - REQUIRE(bool(5. >= float_t(5.))); - - REQUIRE(bool(float_t(5.) >= 4.)); - REQUIRE(!(float_t(4.) >= 5.)); - REQUIRE(bool(float_t(5.) >= 5.)); - } - SECTION("i/o") - { - std::ostringstream out; - std::istringstream in("1.0"); - - float_t f(0.0); - out << f; - REQUIRE(out.str() == "0"); - - in >> f; - REQUIRE(static_cast(f) == 1.0); - } -} diff --git a/third/type_safe/test/index.cpp b/third/type_safe/test/index.cpp deleted file mode 100644 index 72ff6bdd..00000000 --- a/third/type_safe/test/index.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -using type_safe::difference_t; -using type_safe::index_t; - -TEST_CASE("index_t") -{ - index_t idx; - REQUIRE(idx == index_t(0u)); - - SECTION("operator+=") - { - difference_t a(5); - idx += a; - REQUIRE(idx == index_t(5u)); - - difference_t b(-3); - idx += b; - REQUIRE(idx == index_t(2u)); - } - SECTION("operator-=") - { - idx = index_t(10u); - - difference_t a(5); - idx -= a; - REQUIRE(idx == index_t(5u)); - - difference_t b(-3); - idx -= b; - REQUIRE(idx == index_t(8u)); - } - SECTION("operator+") - { - auto c = idx + difference_t(5); - REQUIRE(c == index_t(5u)); - - auto d = difference_t(5) + idx; - REQUIRE(d == index_t(5u)); - - auto e = c + difference_t(-3); - REQUIRE(e == index_t(2u)); - - auto f = difference_t(-3) + d; - REQUIRE(f == index_t(2u)); - } - SECTION("next") - { - auto a = next(idx, difference_t(5)); - REQUIRE(a == index_t(5u)); - - auto b = next(a, difference_t(-3)); - REQUIRE(b == index_t(2u)); - } - SECTION("prev") - { - idx = index_t(10u); - - auto a = prev(idx, difference_t(5)); - REQUIRE(a == index_t(5u)); - - auto b = prev(a, difference_t(-3)); - REQUIRE(b == index_t(8u)); - } - SECTION("advance") - { - advance(idx, difference_t(5)); - REQUIRE(idx == index_t(5u)); - - advance(idx, difference_t(-3)); - REQUIRE(idx == index_t(2u)); - } - SECTION("operator-") - { - idx = index_t(10u); - - auto c = idx - difference_t(5); - REQUIRE(c == index_t(5u)); - - auto d = c - difference_t(-3); - REQUIRE(d == index_t(8u)); - } - SECTION("distance") - { - auto a = index_t(5u) - idx; - REQUIRE(a == difference_t(5)); - REQUIRE(a == distance(idx, index_t(5u))); - - auto b = idx - index_t(5u); - REQUIRE(b == difference_t(-5)); - REQUIRE(b == distance(index_t(5u), idx)); - } - SECTION("at") - { - std::size_t array[] = {0, 1, 2, 3, 4, 5}; - - for (index_t i; i != 5u; ++i) - REQUIRE(at(array, i) == std::size_t(get(i))); - } -} diff --git a/third/type_safe/test/integer.cpp b/third/type_safe/test/integer.cpp deleted file mode 100644 index 9044a2a3..00000000 --- a/third/type_safe/test/integer.cpp +++ /dev/null @@ -1,576 +0,0 @@ -// Copyright (C) 206 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -#include -#include - -using namespace type_safe; - -#ifndef TYPE_SAFE_TEST_NO_STATIC_ASSERT -static_assert(std::is_standard_layout>::value, ""); -static_assert(std::is_trivially_copyable>::value, ""); -// conversion checks -static_assert(sizeof(short) < sizeof(int), ""); -static_assert(std::is_constructible, short>::value, ""); -static_assert(!std::is_constructible, int>::value, ""); -static_assert(!std::is_constructible, unsigned short>::value, ""); -static_assert(!std::is_constructible, short>::value, ""); - -static_assert(std::is_assignable, short>::value, ""); -static_assert(!std::is_assignable, int>::value, ""); -static_assert(!std::is_assignable, unsigned short>::value, ""); -static_assert(!std::is_assignable, short>::value, ""); - -static_assert(sizeof(int) < sizeof(long long), ""); -static_assert(std::is_constructible, int>::value, ""); -static_assert(std::is_constructible, short>::value, ""); -static_assert(!std::is_constructible, long long>::value, ""); -static_assert(!std::is_constructible, unsigned>::value, ""); -static_assert(!std::is_constructible, int>::value, ""); - -static_assert(std::is_assignable, int>::value, ""); -static_assert(std::is_assignable, short>::value, ""); -static_assert(!std::is_assignable, long long>::value, ""); -static_assert(!std::is_assignable, unsigned>::value, ""); -static_assert(!std::is_assignable, int>::value, ""); -#endif - -TEST_CASE("integer") -{ - using int_t = integer; - using uint_t = integer; - - SECTION("constructor") - { - int_t a(0); - REQUIRE(static_cast(a) == 0); - int_t b(32); - REQUIRE(static_cast(b) == 32); - int_t c(-25); - REQUIRE(static_cast(c) == -25); - } - SECTION("assignment") - { - int_t a(0); - a = 32; - REQUIRE(static_cast(a) == 32); - a = -25; - REQUIRE(static_cast(a) == -25); - } - SECTION("unary") - { - int_t a(13); - REQUIRE(static_cast(+a) == static_cast(a)); - REQUIRE(static_cast(-a) == -static_cast(a)); - } - SECTION("increment") - { - int_t a(0); - REQUIRE(static_cast(++a) == 1); - REQUIRE(static_cast(a++) == 1); - REQUIRE(static_cast(a) == 2); - } - SECTION("decrement") - { - int_t a(0); - REQUIRE(static_cast(--a) == -1); - REQUIRE(static_cast(a--) == -1); - REQUIRE(static_cast(a) == -2); - } - SECTION("addition") - { - int_t wrapper(0); - int normal(0); - REQUIRE(static_cast(wrapper) == normal); - - wrapper += 5; - normal += 5; - REQUIRE(static_cast(wrapper) == normal); - - wrapper += short(5); - normal += short(5); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = wrapper + (-23); - normal = normal + (-23); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = 22 + wrapper; - normal = 22 + normal; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = int_t(-4) + wrapper; - normal = (-4) + normal; - REQUIRE(static_cast(wrapper) == normal); - } - SECTION("subtraction") - { - int_t wrapper(0); - int normal(0); - REQUIRE(static_cast(wrapper) == normal); - - wrapper -= 5; - normal -= 5; - REQUIRE(static_cast(wrapper) == normal); - - wrapper -= short(5); - normal -= short(5); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = wrapper - (-23); - normal = normal - (-23); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = 22 - wrapper; - normal = 22 - normal; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = int_t(-4) - wrapper; - normal = (-4) - normal; - REQUIRE(static_cast(wrapper) == normal); - } - SECTION("multiplication") - { - int_t wrapper(1); - int normal(1); - REQUIRE(static_cast(wrapper) == normal); - - wrapper *= 5; - normal *= 5; - REQUIRE(static_cast(wrapper) == normal); - - wrapper *= short(5); - normal *= short(5); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = wrapper * (-23); - normal = normal * (-23); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = 22 * wrapper; - normal = 22 * normal; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = int_t(-4) * wrapper; - normal = (-4) * normal; - REQUIRE(static_cast(wrapper) == normal); - } - SECTION("division") - { - int_t wrapper(23 * 25); - int normal(23 * 25); - REQUIRE(static_cast(wrapper) == normal); - - wrapper /= 5; - normal /= 5; - REQUIRE(static_cast(wrapper) == normal); - - wrapper /= short(5); - normal /= short(5); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = wrapper / (-23); - normal = normal / (-23); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = 22 / wrapper; - normal = 22 / normal; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = int_t(-4) / wrapper; - normal = (-4) / normal; - REQUIRE(static_cast(wrapper) == normal); - } - SECTION("modulo") - { - int_t wrapper(24 * 6); - int normal(24 * 6); - REQUIRE(static_cast(wrapper) == normal); - - wrapper %= 5; - normal %= 5; - REQUIRE(static_cast(wrapper) == normal); - - wrapper %= short(5); - normal %= short(5); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = wrapper % (-23); - normal = normal % (-23); - REQUIRE(static_cast(wrapper) == normal); - - wrapper = 22 % wrapper; - normal = 22 % normal; - REQUIRE(static_cast(wrapper) == normal); - - wrapper = int_t(-4) % wrapper; - normal = (-4) % normal; - REQUIRE(static_cast(wrapper) == normal); - } - SECTION("comparison") - { - unsigned int u32_max = std::numeric_limits::max(); - - // == - REQUIRE(bool(int_t(4) == int_t(4))); - REQUIRE(!(int_t(5) == int_t(4))); - REQUIRE(bool(uint_t(4u) == int_t(4))); - REQUIRE(!(uint_t(5u) == int_t(4))); - REQUIRE(!(uint_t(u32_max) == int_t(-1))); - REQUIRE(bool(int_t(4) == uint_t(4u))); - REQUIRE(!(int_t(5) == uint_t(4u))); - REQUIRE(!(int_t(-1) == uint_t(u32_max))); - - REQUIRE(bool(4 == int_t(4))); - REQUIRE(!(5 == int_t(4))); - REQUIRE(bool(4u == int_t(4))); - REQUIRE(!(5u == int_t(4))); - REQUIRE(!(u32_max == int_t(-1))); - REQUIRE(bool(4 == uint_t(4u))); - REQUIRE(!(5 == uint_t(4u))); - REQUIRE(!(-1 == uint_t(u32_max))); - - REQUIRE(bool(int_t(4) == 4)); - REQUIRE(!(int_t(5) == 4)); - REQUIRE(bool(int_t(4) == 4u)); - REQUIRE(!(int_t(5) == 4u)); - REQUIRE(!(int_t(-1) == u32_max)); - REQUIRE(bool(uint_t(4u) == 4)); - REQUIRE(!(uint_t(5u) == 4)); - REQUIRE(!(uint_t(u32_max) == -1)); - - // != - REQUIRE(bool(int_t(5) != int_t(4))); - REQUIRE(!(int_t(4) != int_t(4))); - REQUIRE(bool(uint_t(5u) != int_t(4))); - REQUIRE(!(uint_t(4u) != int_t(4))); - REQUIRE(bool(uint_t(u32_max) != int_t(-1))); - REQUIRE(bool(int_t(5) != uint_t(4u))); - REQUIRE(!(int_t(4) != uint_t(4u))); - REQUIRE(bool(int_t(-1) != uint_t(u32_max))); - - REQUIRE(bool(5 != int_t(4))); - REQUIRE(!(4 != int_t(4))); - REQUIRE(bool(5u != int_t(4))); - REQUIRE(!(4u != int_t(4))); - REQUIRE(bool(u32_max != int_t(-1))); - REQUIRE(bool(5 != uint_t(4u))); - REQUIRE(!(4 != uint_t(4u))); - REQUIRE(bool(-1 != uint_t(u32_max))); - - REQUIRE(bool(int_t(5) != 4)); - REQUIRE(!(int_t(4) != 4)); - REQUIRE(bool(int_t(5) != 4u)); - REQUIRE(!(int_t(4) != 4u)); - REQUIRE(bool(int_t(-1) != u32_max)); - REQUIRE(bool(uint_t(5u) != 4)); - REQUIRE(!(uint_t(4u) != 4)); - REQUIRE(bool(uint_t(u32_max) != -1)); - - // < - REQUIRE(bool(int_t(4) < int_t(5))); - REQUIRE(!(int_t(5) < int_t(4))); - REQUIRE(!(int_t(4) < int_t(4))); - REQUIRE(bool(uint_t(4u) < int_t(5))); - REQUIRE(!bool(uint_t(4u) < int_t(-5))); - REQUIRE(!(uint_t(5u) < int_t(4))); - REQUIRE(!(uint_t(4u) < int_t(4))); - REQUIRE(bool(int_t(4) < uint_t(5u))); - REQUIRE(bool(int_t(-4) < uint_t(5u))); - REQUIRE(!(int_t(5) < uint_t(4u))); - REQUIRE(!(int_t(4) < uint_t(4u))); - - REQUIRE(bool(4 < int_t(5))); - REQUIRE(!(5 < int_t(4))); - REQUIRE(!(4 < int_t(4))); - REQUIRE(bool(4u < int_t(5))); - REQUIRE(!bool(4u < int_t(-5))); - REQUIRE(!(5u < int_t(4))); - REQUIRE(!(4u < int_t(4))); - REQUIRE(bool(4 < uint_t(5u))); - REQUIRE(bool(-4 < uint_t(5u))); - REQUIRE(!(5 < uint_t(4u))); - REQUIRE(!(4 < uint_t(4u))); - - REQUIRE(bool(int_t(4) < 5)); - REQUIRE(!(int_t(5) < 4)); - REQUIRE(!(int_t(4) < 4)); - REQUIRE(bool(int_t(4) < 5u)); - REQUIRE(!(int_t(5) < 4u)); - REQUIRE((int_t(-5) < 4u)); - REQUIRE(!(int_t(4) < 4u)); - REQUIRE(bool(uint_t(4u) < 5)); - REQUIRE(!bool(uint_t(4u) < -5)); - REQUIRE(!(uint_t(5u) < 4)); - REQUIRE(!(uint_t(4u) < 4)); - - // <= - REQUIRE(bool(int_t(4) <= int_t(5))); - REQUIRE(!(int_t(5) <= int_t(4))); - REQUIRE(bool(int_t(4) <= int_t(4))); - REQUIRE(bool(uint_t(4u) <= int_t(5))); - REQUIRE(!(uint_t(4u) <= int_t(-5))); - REQUIRE(!(uint_t(5u) <= int_t(4))); - REQUIRE(bool(uint_t(4u) <= int_t(4))); - REQUIRE(bool(int_t(4) <= uint_t(5u))); - REQUIRE(!(int_t(5) <= uint_t(4u))); - REQUIRE(bool(int_t(-5) <= uint_t(4u))); - REQUIRE(bool(int_t(4) <= uint_t(4u))); - - REQUIRE(bool(4 <= int_t(5))); - REQUIRE(!(5 <= int_t(4))); - REQUIRE(bool(4 <= int_t(4))); - REQUIRE(bool(4u <= int_t(5))); - REQUIRE(!(5u <= int_t(4))); - REQUIRE(bool(4u <= int_t(4))); - REQUIRE(bool(4 <= int_t(5))); - REQUIRE(!(5 <= int_t(4))); - REQUIRE(bool(4 <= int_t(4))); - REQUIRE(!(4 <= int_t(-4))); - REQUIRE(bool(4u <= int_t(5))); - REQUIRE(!(5u <= int_t(4))); - REQUIRE(bool(4u <= int_t(4))); - REQUIRE(bool(4 <= uint_t(5u))); - REQUIRE(!(5 <= uint_t(4u))); - REQUIRE(bool(4 <= uint_t(4u))); - REQUIRE(bool(-4 <= uint_t(4u))); - - REQUIRE(bool(int_t(4) <= 5)); - REQUIRE(!(int_t(5) <= 4)); - REQUIRE(bool(int_t(4) <= 4)); - REQUIRE(bool(int_t(-4) <= 4)); - REQUIRE(bool(int_t(4) <= 5u)); - REQUIRE(!(int_t(5) <= 4u)); - REQUIRE(bool(int_t(4) <= 4u)); - REQUIRE((int_t(4) <= 5)); - REQUIRE(!(int_t(5) <= 4)); - REQUIRE(bool(int_t(4) <= 4)); - REQUIRE(bool(uint_t(4u) <= 5)); - REQUIRE(!(uint_t(5u) <= 4)); - REQUIRE(bool(uint_t(4u) <= 4)); - REQUIRE(!(uint_t(4u) <= -4)); - REQUIRE(bool(int_t(4) <= 5u)); - REQUIRE(!(int_t(5) <= 4u)); - REQUIRE(bool(int_t(4) <= 4u)); - REQUIRE(bool(int_t(-4) <= 4u)); - - // > - REQUIRE(bool(int_t(5) > int_t(4))); - REQUIRE(!(int_t(4) > int_t(5))); - REQUIRE(!(int_t(5) > int_t(5))); - REQUIRE(bool(uint_t(5u) > int_t(4))); - REQUIRE(bool(uint_t(5u) > int_t(-4))); - REQUIRE(!(uint_t(4u) > int_t(5))); - REQUIRE(!(uint_t(5u) > int_t(5))); - REQUIRE(bool(int_t(5) > uint_t(4u))); - REQUIRE(!(int_t(-5) > uint_t(4u))); - REQUIRE(!(int_t(4) > uint_t(5u))); - REQUIRE(!(int_t(5) > uint_t(5u))); - - REQUIRE(bool(5 > int_t(4))); - REQUIRE(!(4 > int_t(5))); - REQUIRE(!(5 > int_t(5))); - REQUIRE(bool(5u > int_t(4))); - REQUIRE(!(4u > int_t(5))); - REQUIRE(!(5u > int_t(5))); - REQUIRE(bool(5u > int_t(4))); - REQUIRE(bool(5u > int_t(-4))); - REQUIRE(!(4u > int_t(5))); - REQUIRE(!(5u > int_t(5))); - REQUIRE(bool(5 > uint_t(4u))); - REQUIRE(!(-5 > uint_t(4u))); - REQUIRE(!(4 > uint_t(5u))); - REQUIRE(!(5 > uint_t(5u))); - - REQUIRE(bool(int_t(5) > 4)); - REQUIRE(!(int_t(4) > 5)); - REQUIRE(!(int_t(5) > 5)); - REQUIRE(bool(uint_t(5u) > 4)); - REQUIRE(bool(uint_t(5u) > -4)); - REQUIRE(!(uint_t(4u) > 5)); - REQUIRE(!(uint_t(5u) > 5)); - REQUIRE(bool(int_t(5) > 4u)); - REQUIRE(!(int_t(-5) > 4u)); - REQUIRE(!(int_t(4) > 5u)); - REQUIRE(!(int_t(5) > 5u)); - - // >= - REQUIRE(bool(int_t(5) >= int_t(4))); - REQUIRE(!(int_t(4) >= int_t(5))); - REQUIRE(bool(int_t(5) >= int_t(5))); - REQUIRE(bool(uint_t(5u) >= int_t(4))); - REQUIRE(!(uint_t(4u) >= int_t(5))); - REQUIRE(bool(uint_t(4u) >= int_t(-5))); - REQUIRE(bool(uint_t(5u) >= int_t(5))); - REQUIRE(bool(int_t(5) >= uint_t(4u))); - REQUIRE(!(int_t(4) >= uint_t(5u))); - REQUIRE(bool(int_t(5) >= uint_t(5u))); - REQUIRE(!(int_t(-5) >= uint_t(5u))); - - REQUIRE(bool(5 >= int_t(4))); - REQUIRE(!(4 >= int_t(5))); - REQUIRE(bool(5 >= int_t(5))); - REQUIRE(bool(5u >= int_t(4))); - REQUIRE(!(4u >= int_t(5))); - REQUIRE(bool(4u >= int_t(-5))); - REQUIRE(bool(5u >= int_t(5))); - REQUIRE(bool(5u >= int_t(-5))); - REQUIRE(bool(5 >= uint_t(4u))); - REQUIRE(!(4 >= uint_t(5u))); - REQUIRE(bool(5 >= uint_t(5u))); - REQUIRE(!(-5 >= uint_t(5u))); - - REQUIRE(bool(int_t(5) >= 4)); - REQUIRE(!(int_t(4) >= 5)); - REQUIRE(bool(int_t(5) >= 5)); - REQUIRE(bool(uint_t(5u) >= 4)); - REQUIRE(!(uint_t(4u) >= 5)); - REQUIRE(bool(uint_t(4u) >= -5)); - REQUIRE(bool(uint_t(5u) >= 5)); - REQUIRE(bool(int_t(5) >= 4u)); - REQUIRE(!(int_t(-5) >= 4u)); - REQUIRE(!(int_t(4) >= 5u)); - REQUIRE(bool(int_t(5) >= 5u)); - } - SECTION("make_(un)signed") - { - int_t a = 5; - integer b = make_unsigned(a); - REQUIRE(static_cast(b) == 5); - - b = 125u; - a = make_signed(b); - REQUIRE(static_cast(a) == 125); - } - SECTION("i/o") - { - std::ostringstream out; - std::istringstream in("10"); - - int_t i(0); - out << i; - REQUIRE(out.str() == "0"); - - in >> i; - REQUIRE(static_cast(i) == 10); - } - SECTION("abs") - { - int i = 123; - integer ia = type_safe::abs(i); - REQUIRE(static_cast(ia) == 123u); - - i = -123; - ia = type_safe::abs(i); - REQUIRE(static_cast(ia) == 123u); - } - SECTION("signed_to_unsigned") - { - // From int8_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - - // From int16_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - - // From int32_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - - // From int64_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - } - SECTION("unsigned_to_signed") - { - // From uint8_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - - // From uint16_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - - // From uint32_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - - // From uint32_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - } - SECTION("signed_to_signed") - { - // From int8_t - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - - // From int16_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - - // From int32_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - - // From int64_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - } - SECTION("unsigned_to_unsigned") - { - // From uint8_t - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - - // From uint16_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - - // From uint32_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - - // From uint64_t - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(!std::is_convertible, integer>::value); - REQUIRE(std::is_convertible, integer>::value); - } -} diff --git a/third/type_safe/test/narrow_cast.cpp b/third/type_safe/test/narrow_cast.cpp deleted file mode 100644 index f75d2a5d..00000000 --- a/third/type_safe/test/narrow_cast.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -using namespace type_safe; - -TEST_CASE("narrow_cast") -{ - integer a(4); - - integer b = narrow_cast(a); - REQUIRE(static_cast(b) == 4); - - integer c = narrow_cast>(a); - REQUIRE(static_cast(c) == 4); - - integer d = narrow_cast>(42); - REQUIRE(static_cast(d) == 42); -} - -TEST_CASE("narrow_cast") -{ - floating_point a(1.); - - floating_point b = narrow_cast(a); - REQUIRE(static_cast(b) == 1.); - - floating_point c = narrow_cast>(a); - REQUIRE(static_cast(c) == 1.); -} diff --git a/third/type_safe/test/optional.cpp b/third/type_safe/test/optional.cpp deleted file mode 100644 index c0d6f2d4..00000000 --- a/third/type_safe/test/optional.cpp +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include -#include - -#include - -#include "debugger_type.hpp" - -using type_safe::optional; -using type_safe::optional_ref; -using type_safe::make_optional; -using type_safe::nullopt; - -TEST_CASE("optional") -{ - SECTION("constructor - empty") - { - optional a; - REQUIRE_FALSE(a.has_value()); - - optional b(nullopt); - REQUIRE_FALSE(b.has_value()); - } - SECTION("constructor - value") - { - optional a(debugger_type(3)); - REQUIRE(a.has_value()); - REQUIRE(a.value().id == 3); - REQUIRE(a.value().move_ctor()); - - debugger_type dbg(2); - optional b(dbg); - REQUIRE(b.has_value()); - REQUIRE(b.value().id == 2); - REQUIRE(b.value().copy_ctor()); - - optional c(std::move(dbg)); - REQUIRE(c.has_value()); - REQUIRE(c.value().id == 2); - REQUIRE(c.value().move_ctor()); - - optional d(0); - REQUIRE(d.has_value()); - REQUIRE(d.value().id == 0); - REQUIRE(d.value().ctor()); - } - SECTION("constructor - move/copy") - { - optional org_empty; - optional org_value(debugger_type(0)); - - optional a(org_empty); - REQUIRE_FALSE(a.has_value()); - - optional b(std::move(org_empty)); - REQUIRE_FALSE(b.has_value()); - - optional c(org_value); - REQUIRE(c.has_value()); - REQUIRE(c.value().id == 0); - REQUIRE(c.value().copy_ctor()); - - optional d(std::move(org_value)); - REQUIRE(d.has_value()); - REQUIRE(d.value().id == 0); - REQUIRE(d.value().move_ctor()); - } - SECTION("assignment - nullopt_t") - { - optional a; - a = nullopt; - REQUIRE_FALSE(a.has_value()); - - optional b(4); - b = nullopt; - REQUIRE_FALSE(b.has_value()); - } - SECTION("assignment - value") - { - optional a; - a = debugger_type(0); - REQUIRE(a.has_value()); - REQUIRE(a.value().id == 0); - REQUIRE(a.value().move_ctor()); - REQUIRE(a.value().not_assigned()); - - debugger_type dbg(0); - optional b; - b = dbg; - REQUIRE(b.has_value()); - REQUIRE(b.value().id == 0); - REQUIRE(b.value().copy_ctor()); - REQUIRE(b.value().not_assigned()); - - optional c; - c = 0; - REQUIRE(c.has_value()); - REQUIRE(c.value().id == 0); - REQUIRE(c.value().ctor()); - REQUIRE(c.value().not_assigned()); - - optional d(0); - d = debugger_type(1); - REQUIRE(d.has_value()); - REQUIRE(d.value().id == 1); - REQUIRE(d.value().ctor()); - REQUIRE(d.value().move_assigned()); - - dbg.id = 1; - optional e(0); - e = dbg; - REQUIRE(e.has_value()); - REQUIRE(e.value().id == 1); - REQUIRE(e.value().ctor()); - REQUIRE(e.value().copy_assigned()); - - optional f(0); - f = 1; // assignment would use implicit conversion, so it destroys & recreates - REQUIRE(f.has_value()); - REQUIRE(f.value().id == 1); - REQUIRE(f.value().ctor()); - REQUIRE(f.value().not_assigned()); - } - SECTION("assignment - move/copy") - { - optional new_empty; - optional new_value(debugger_type(1)); - - optional a; - a = new_empty; - REQUIRE_FALSE(a.has_value()); - - optional b; - b = new_value; - REQUIRE(b.has_value()); - REQUIRE(b.value().id == 1); - REQUIRE(b.value().copy_ctor()); - REQUIRE(b.value().not_assigned()); - - optional c; - c = std::move(new_value); - REQUIRE(c.has_value()); - REQUIRE(c.value().id == 1); - REQUIRE(c.value().not_assigned()); - - optional d(0); - d = new_empty; - REQUIRE_FALSE(d.has_value()); - - optional e(0); - e = new_value; - REQUIRE(e.has_value()); - REQUIRE(e.value().id == 1); - REQUIRE(e.value().ctor()); - REQUIRE(e.value().copy_assigned()); - - optional f(0); - f = std::move(new_value); - REQUIRE(f.has_value()); - REQUIRE(f.value().id == 1); - REQUIRE(f.value().ctor()); - } - SECTION("swap") - { - optional empty1, empty2; - optional a(0); - optional b(1); - - SECTION("empty, empty") - { - swap(empty1, empty2); - REQUIRE_FALSE(empty1.has_value()); - REQUIRE_FALSE(empty2.has_value()); - } - SECTION("value, value") - { - swap(a, b); - REQUIRE(a.has_value()); - REQUIRE(a.value().id == 1); - REQUIRE(a.value().swapped); - REQUIRE(b.has_value()); - REQUIRE(b.value().id == 0); - REQUIRE(b.value().swapped); - } - SECTION("empty, value") - { - swap(empty1, a); - REQUIRE_FALSE(a.has_value()); - REQUIRE(empty1.has_value()); - REQUIRE(empty1.value().id == 0); - REQUIRE(empty1.value().not_assigned()); - REQUIRE_FALSE(empty1.value().swapped); - } - SECTION("value, empty") - { - swap(a, empty1); - REQUIRE_FALSE(a.has_value()); - REQUIRE(empty1.has_value()); - REQUIRE(empty1.value().id == 0); - REQUIRE(empty1.value().move_ctor()); - REQUIRE(empty1.value().not_assigned()); - REQUIRE_FALSE(empty1.value().swapped); - } - } - SECTION("reset") - { - optional a; - a.reset(); - REQUIRE_FALSE(a.has_value()); - - optional b(0); - b.reset(); - REQUIRE_FALSE(b.has_value()); - } - SECTION("emplace") - { - debugger_type dbg(1); - - optional a; - a.emplace(1); - REQUIRE(a.has_value()); - REQUIRE(a.value().id == 1); - REQUIRE(a.value().ctor()); - REQUIRE(a.value().not_assigned()); - - optional b; - b.emplace(dbg); - REQUIRE(b.has_value()); - REQUIRE(b.value().id == 1); - REQUIRE(b.value().copy_ctor()); - REQUIRE(b.value().not_assigned()); - - optional c; - c.emplace(std::move(dbg)); - REQUIRE(c.has_value()); - REQUIRE(c.value().id == 1); - REQUIRE(c.value().not_assigned()); - - optional d(0); - d.emplace(1); - REQUIRE(d.has_value()); - REQUIRE(d.value().id == 1); - REQUIRE(d.value().ctor()); - REQUIRE(d.value().not_assigned()); - - optional e(0); - e.emplace(dbg); - REQUIRE(e.has_value()); - REQUIRE(e.value().id == 1); - REQUIRE(e.value().ctor()); - REQUIRE(e.value().copy_assigned()); - - optional f(0); - f.emplace(std::move(dbg)); - REQUIRE(f.has_value()); - REQUIRE(f.value().id == 1); - REQUIRE(f.value().ctor()); - REQUIRE(f.value().move_assigned()); - } - SECTION("operator bool") - { - optional a; - REQUIRE_FALSE(static_cast(a)); - - optional b(0); - REQUIRE(static_cast(b)); - } - SECTION("value") - { - // only test the return types - optional a(0); - static_assert(std::is_same::value, ""); - static_assert(std::is_same::value, ""); - - const optional b(0); - static_assert(std::is_same::value, ""); - static_assert(std::is_same::value, - ""); - } - SECTION("value_or") - { - optional a; - auto a_res = a.value_or(1); - REQUIRE(a_res.id == 1); - - optional b(0); - auto b_res = b.value_or(1); - REQUIRE(b_res.id == 0); - } - SECTION("map") - { - auto func = [](int i) { return "abc"[i]; }; - - optional a; - optional a_res = a.map(func); - REQUIRE_FALSE(a_res.has_value()); - - optional b(0); - optional b_res = b.map(func); - REQUIRE(b_res.has_value()); - REQUIRE(b_res.value() == 'a'); - - struct foo - { - int var = 42; - - int func(int i) - { - return 2 * i; - } - - void func2(int i) - { - REQUIRE(i == 42); - } - }; - - optional c(foo{}); - - optional c_res = c.map(&foo::func, 2); - REQUIRE(c_res.has_value()); - REQUIRE(c_res.value() == 4); - - c.map(&foo::func2, 42); - - optional_ref c_res2 = c.map(&foo::var); - REQUIRE(c_res2.has_value()); - REQUIRE(c_res2.value() == 42); - -#if TYPE_SAFE_USE_RETURN_TYPE_DEDUCTION - // just compiler check, see https://github.com/foonathan/type_safe/issues/60 - struct bar - { - void non_const() {} - }; - - optional f = bar{}; - f.map([](auto&& b) { - b.non_const(); - return 42; - }); -#endif - } - SECTION("with") - { - optional a; - with(a, [](int) { REQUIRE(false); }); - - a = 0; - with(a, [](int& i) { - REQUIRE(i == 0); - i = 1; - }); - REQUIRE(a.has_value()); - REQUIRE(a.value() == 1); - } - SECTION("comparison") - { - optional a; - optional b(1); - optional c(2); - - // == - REQUIRE(b == b); - REQUIRE(!(b == c)); - REQUIRE(!(b == a)); - - REQUIRE(a == nullopt); - REQUIRE(nullopt == a); - REQUIRE(!(b == nullopt)); - REQUIRE(!(nullopt == b)); - - REQUIRE(b == 1); - REQUIRE(!(a == 1)); - REQUIRE(!(1 == a)); - REQUIRE(!(c == 1)); - REQUIRE(!(1 == c)); - - // != - REQUIRE(a != b); - REQUIRE(b != c); - REQUIRE(!(a != a)); - - REQUIRE(b != nullopt); - REQUIRE(nullopt != b); - REQUIRE(!(a != nullopt)); - REQUIRE(!(nullopt != a)); - - REQUIRE(b != 2); - REQUIRE(2 != b); - REQUIRE(a != 2); - REQUIRE(2 != a); - REQUIRE(!(c != 2)); - REQUIRE(!(2 != c)); - - // < - REQUIRE(a < b); - REQUIRE(b < c); - REQUIRE(!(c < b)); - REQUIRE(!(b < a)); - - REQUIRE(!(a < nullopt)); - REQUIRE(!(nullopt < a)); - REQUIRE(!(b < nullopt)); - REQUIRE(nullopt < b); - - REQUIRE(a < 2); - REQUIRE(!(2 < a)); - REQUIRE(!(c < 2)); - REQUIRE(!(2 < c)); - - // <= - REQUIRE(a <= b); - REQUIRE(b <= c); - REQUIRE(b <= b); - REQUIRE(!(c <= b)); - - REQUIRE(a <= nullopt); - REQUIRE(nullopt <= a); - REQUIRE(!(b <= nullopt)); - REQUIRE(nullopt <= b); - - REQUIRE(a <= 2); - REQUIRE(!(2 <= a)); - REQUIRE(b <= 2); - REQUIRE(!(2 <= b)); - REQUIRE(c <= 2); - REQUIRE(2 <= c); - - // > - REQUIRE(c > b); - REQUIRE(b > a); - REQUIRE(!(a > b)); - - REQUIRE(b > nullopt); - REQUIRE(!(nullopt > b)); - REQUIRE(!(a > nullopt)); - REQUIRE(!(nullopt > b)); - - REQUIRE(c > 1); - REQUIRE(!(1 > c)); - REQUIRE(!(b > 1)); - REQUIRE(!(1 > b)); - REQUIRE(!(a > 1)); - REQUIRE(1 > a); - - // >= - REQUIRE(c >= b); - REQUIRE(b >= a); - REQUIRE(a >= a); - REQUIRE(!(a >= b)); - - REQUIRE(a >= nullopt); - REQUIRE(nullopt >= a); - REQUIRE(b >= nullopt); - REQUIRE(!(nullopt >= b)); - - REQUIRE(b >= 1); - REQUIRE(1 >= b); - REQUIRE(c >= 1); - REQUIRE(!(1 >= c)); - REQUIRE(!(a >= 1)); - REQUIRE(1 >= a); - } - SECTION("make_optional") - { - optional a = make_optional(5); - REQUIRE(a.has_value()); - REQUIRE(a.value() == 5); - - optional b = make_optional(1u, 'a'); - REQUIRE(b.has_value()); - REQUIRE(b.value() == "a"); - } -} diff --git a/third/type_safe/test/optional_ref.cpp b/third/type_safe/test/optional_ref.cpp deleted file mode 100644 index 6bd82653..00000000 --- a/third/type_safe/test/optional_ref.cpp +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -#include "debugger_type.hpp" - -using type_safe::optional; -using type_safe::object_ref; -using type_safe::optional_ref; -using type_safe::optional_xvalue_ref; -using type_safe::opt_ref; -using type_safe::opt_cref; -using type_safe::opt_xref; -using type_safe::ref; - -template -void test_optional_ref_conversion(Value) -{ - static_assert(std::is_constructible, B>::value == Value::value, ""); - static_assert(std::is_assignable, B>::value == Value::value, ""); -} - -TEST_CASE("optional_ref") -{ - // only test stuff special for optional_ref - struct base - {}; - struct derived : base - {}; - - test_optional_ref_conversion(std::false_type{}); - test_optional_ref_conversion(std::false_type{}); - test_optional_ref_conversion>(std::false_type{}); - test_optional_ref_conversion>(std::true_type{}); - test_optional_ref_conversion>(std::true_type{}); - test_optional_ref_conversion>(std::true_type{}); - test_optional_ref_conversion>(std::true_type{}); - - int value = 0; - SECTION("constructor") - { - optional_ref a(nullptr); - REQUIRE_FALSE(a.has_value()); - - optional_ref b(value); - REQUIRE(b.has_value()); - REQUIRE(&b.value() == &value); - - optional_ref c(ref(value)); - REQUIRE(c.has_value()); - REQUIRE(&c.value() == &value); - } - SECTION("assignment") - { - optional_ref a; - a = nullptr; - REQUIRE_FALSE(a.has_value()); - - optional_ref b; - b = ref(value); - REQUIRE(b.has_value()); - REQUIRE(&b.value() == &value); - } - SECTION("value_or") - { - int v1 = 0, v2 = 0; - - optional_ref a; - a.value_or(v2) = 1; - REQUIRE(v2 == 1); - REQUIRE(v1 == 0); - v2 = 0; - - optional_ref b(v1); - b.value_or(v2) = 1; - REQUIRE(v1 == 1); - REQUIRE(v2 == 0); - } - SECTION("ref") - { - optional_ref a = opt_ref(static_cast(nullptr)); - REQUIRE_FALSE(a.has_value()); - - optional_ref b = opt_ref(&value); - REQUIRE(b.has_value()); - REQUIRE(&b.value() == &value); - - optional_ref c = opt_ref(ref(value)); - REQUIRE(c.has_value()); - REQUIRE(&c.value() == &value); - - optional opt_a, opt_b(42); - - optional_ref d = opt_ref(opt_a); - REQUIRE_FALSE(d.has_value()); - - optional_ref e = opt_ref(opt_b); - REQUIRE(e.has_value()); - REQUIRE(&e.value() == &opt_b.value()); - - optional_ref f = opt_ref(value); - REQUIRE(f.has_value()); - REQUIRE(&f.value() == &value); - } - SECTION("cref") - { - optional_ref a = opt_cref(static_cast(nullptr)); - REQUIRE_FALSE(a.has_value()); - - optional_ref b = opt_cref(&value); - REQUIRE(b.has_value()); - REQUIRE(&b.value() == &value); - - optional_ref c = opt_cref(ref(value)); - REQUIRE(c.has_value()); - REQUIRE(&c.value() == &value); - - optional opt_a, opt_b(42); - - optional_ref d = opt_cref(opt_a); - REQUIRE_FALSE(d.has_value()); - - optional_ref e = opt_cref(opt_b); - REQUIRE(e.has_value()); - REQUIRE(&e.value() == &opt_b.value()); - - optional_ref f = opt_cref(value); - REQUIRE(f.has_value()); - REQUIRE(&f.value() == &value); - } - SECTION("copy") - { - debugger_type dbg(0); - - optional_ref a; - optional a_res = copy(a); - REQUIRE_FALSE(a_res.has_value()); - - optional_ref b(dbg); - optional b_res = copy(b); - REQUIRE(b_res.has_value()); - REQUIRE(b_res.value().id == 0); - } - SECTION("value comparison") - { - int value2 = 0; - - optional_ref a; - optional_ref b(value); - optional_ref c(value2); - - REQUIRE_FALSE(a == value); - REQUIRE_FALSE(value == a); - REQUIRE_FALSE(a == value2); - REQUIRE_FALSE(value2 == a); - - REQUIRE(b == value); - REQUIRE(value == b); - REQUIRE_FALSE(b == value2); - REQUIRE_FALSE(value2 == b); - - REQUIRE_FALSE(c == value); - REQUIRE_FALSE(value == c); - REQUIRE(c == value2); - REQUIRE(value2 == c); - } -} - -TEST_CASE("optional_xvalue_ref") -{ - int value = 0; - - SECTION("constructor") - { - optional_xvalue_ref a(nullptr); - REQUIRE_FALSE(a.has_value()); - - optional_xvalue_ref b(value); - REQUIRE(b.has_value()); - REQUIRE(b.value() == value); - } - SECTION("assignment") - { - optional_xvalue_ref a; - a = nullptr; - REQUIRE_FALSE(a.has_value()); - - optional_xvalue_ref b; - b = ref(value); - REQUIRE(b.has_value()); - REQUIRE(b.value() == value); - } - SECTION("value_or") - { - int v1 = 1, v2 = 0; - - optional_xvalue_ref a; - REQUIRE(a.value_or(v2) == v2); - - optional_xvalue_ref b(v1); - REQUIRE(b.value_or(v2) == v1); - } - SECTION("xref") - { - optional_xvalue_ref a = opt_xref(static_cast(nullptr)); - REQUIRE_FALSE(a.has_value()); - - optional_xvalue_ref b = opt_xref(&value); - REQUIRE(b.has_value()); - REQUIRE(b.value() == value); - } - SECTION("move") - { - debugger_type dbg(0); - - optional_xvalue_ref a; - optional a_res = move(a); - REQUIRE_FALSE(a_res.has_value()); - - optional_xvalue_ref b(dbg); - optional b_res = move(b); - REQUIRE(b_res.has_value()); - REQUIRE(b_res.value().id == 0); -#ifndef _MSC_VER - REQUIRE(b_res.value().move_ctor()); -#endif - } -} diff --git a/third/type_safe/test/output_parameter.cpp b/third/type_safe/test/output_parameter.cpp deleted file mode 100644 index 13c7f8b7..00000000 --- a/third/type_safe/test/output_parameter.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include -#include - -using namespace type_safe; - -TEST_CASE("output_parameter") -{ - SECTION("reference") - { - std::string output; - - output_parameter out(output); - SECTION("operator=") - { - std::string& res = (out = "abc"); - REQUIRE(&res == &output); - REQUIRE(res == "abc"); - } - SECTION("assign") - { - std::string& res = out.assign(3u, 'c'); - REQUIRE(&res == &output); - REQUIRE(res == "ccc"); - } - SECTION("multi") - { - std::string& res_a = (out = "abc"); - REQUIRE(&res_a == &output); - REQUIRE(res_a == "abc"); - - std::string& res_b = (out = "def"); - REQUIRE(&res_b == &output); - REQUIRE(res_b == "def"); - - std::string& res_c = out.assign(3u, 'c'); - REQUIRE(&res_c == &output); - REQUIRE(res_c == "ccc"); - } - } - SECTION("deferred_construction") - { - deferred_construction output; - - output_parameter out(output); - SECTION("operator=") - { - std::string& res = (out = "abc"); - REQUIRE(output.has_value()); - REQUIRE(&res == &output.value()); - REQUIRE(res == "abc"); - } - SECTION("assign") - { - std::string& res = out.assign(3u, 'c'); - REQUIRE(output.has_value()); - REQUIRE(&res == &output.value()); - REQUIRE(res == "ccc"); - } - SECTION("multi") - { - std::string& res_a = (out = "abc"); - REQUIRE(output.has_value()); - REQUIRE(&res_a == &output.value()); - REQUIRE(res_a == "abc"); - - std::string& res_b = (out = "def"); - REQUIRE(&res_b == &output.value()); - REQUIRE(res_b == "def"); - - std::string& res_c = out.assign(3u, 'c'); - REQUIRE(&res_c == &output.value()); - REQUIRE(res_c == "ccc"); - } - } -} diff --git a/third/type_safe/test/reference.cpp b/third/type_safe/test/reference.cpp deleted file mode 100644 index 8e8327b1..00000000 --- a/third/type_safe/test/reference.cpp +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright (C) 2017 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include -#include - -#include "debugger_type.hpp" - -using type_safe::array_ref; -using type_safe::function_ref; -using type_safe::object_ref; -using type_safe::cref; -using type_safe::ref; -using type_safe::xvalue_ref; - -template -void check_object_ref(const object_ref& ref, const debugger_type& value) -{ - REQUIRE(value.ctor()); - REQUIRE(&ref.get() == &value); - REQUIRE(&*ref == &value); - REQUIRE(ref->id == value.id); - REQUIRE(ref == value); - REQUIRE(value == ref); -} - -void check_object_ref(const xvalue_ref ref, const debugger_type& value) -{ - REQUIRE(value.ctor()); - REQUIRE(ref->id == value.id); - REQUIRE(ref == value); - REQUIRE(value == ref); -} - -TEST_CASE("object_ref") -{ - debugger_type value(42); - const debugger_type cvalue(128); - - // value ctor - object_ref a(value); - check_object_ref(a, value); - - object_ref b(cvalue); - check_object_ref(b, cvalue); - - object_ref c(value); - check_object_ref(c, value); - - // ref ctor - object_ref d(a); - check_object_ref(d, value); - - object_ref e(b); - check_object_ref(e, cvalue); - - object_ref f(a); - check_object_ref(f, value); - - // map - auto int_a = 0; - auto int_b = 42; - auto func_a = [&](int& a) -> int& { return a ? a : int_b; }; - auto func_b = [](int& a, int& b) { return a ? ref(a) : ref(b); }; - - object_ref map_ref(int_a); - - auto map_a = map_ref.map(func_a); - REQUIRE(&map_a.get() == &int_b); - - *map_ref = 1; - auto map_b = map_ref.map(func_b, int_b); - REQUIRE(&map_b.get() == &int_a); - - // comparison - REQUIRE(a == d); - REQUIRE(b == e); - REQUIRE(c == f); - REQUIRE(a == c); - REQUIRE(a != b); - REQUIRE(a != e); - - REQUIRE(a != cvalue); - REQUIRE(cvalue != a); - REQUIRE(e != value); - REQUIRE(value != e); - - // with - with(a, - [&](debugger_type& a, int i) { - REQUIRE(i == 42); - REQUIRE(a.id == value.id); - }, - 42); - - // ref/cref - auto g = ref(value); - static_assert(std::is_same>::value, ""); - check_object_ref(g, value); - - auto h = ref(cvalue); - static_assert(std::is_same>::value, ""); - check_object_ref(h, cvalue); - - auto i = cref(value); - static_assert(std::is_same>::value, ""); - check_object_ref(i, value); - - // copy/move - auto value2 = copy(a); - REQUIRE(value2.id == value.id); - REQUIRE(value2.copy_ctor()); - - xvalue_ref j(value); - check_object_ref(j, value); - - auto value3 = move(j); - REQUIRE(value3.id == value.id); - REQUIRE(value3.move_ctor()); -} - -TEST_CASE("array_ref") -{ - int array[3] = {1, 2, 3}; - int array2[1] = {1}; - - array_ref ref(array); - REQUIRE(ref.data() == array); - REQUIRE((ref.size() == 3u)); - - REQUIRE(ref[0u] == 1); - REQUIRE(ref[1u] == 2); - REQUIRE(ref[2u] == 3); - - ref[0u] = 100; - REQUIRE(array[0] == 100); - - SECTION("ctor") - { - array_ref a(array, array + 3); - REQUIRE(a.data() == array); - REQUIRE((a.size() == 3u)); - - array_ref b(array, 3u); - REQUIRE(b.data() == array); - REQUIRE((b.size() == 3u)); - - array_ref c(array); - REQUIRE(c.data() == array); - REQUIRE((c.size() == 3u)); - - array_ref d(nullptr, 0u); - REQUIRE(d.data() == nullptr); - REQUIRE((d.size() == 0u)); - } - SECTION("assign range") - { - ref.assign(array2, array2 + 1); - REQUIRE(ref.data() == array2); - REQUIRE((ref.size() == 1u)); - } - SECTION("assign size") - { - ref.assign(array2, 1u); - REQUIRE(ref.data() == array2); - REQUIRE((ref.size() == 1u)); - } - SECTION("assign array") - { - ref.assign(array2); - REQUIRE(ref.data() == array2); - REQUIRE((ref.size() == 1u)); - } - SECTION("begin()/end()") - { - REQUIRE(ref.begin() == array); - REQUIRE(ref.end() == array + 3); - } - SECTION("with") - { - struct test_arg - { - bool moved_from = false; - - test_arg() = default; - - test_arg(const test_arg&) = default; - - test_arg(test_arg&&) noexcept : moved_from(true) {} - }; - - with(ref, [](int, test_arg arg) { REQUIRE(!arg.moved_from); }, test_arg{}); - - with(ref, - [&](int i, std::size_t& index) { - REQUIRE(i == ref[index]); - ++index; - }, - std::size_t(0u)); - } -} - -// fake polymorphic lambda, due to C++11 requirement -struct lambda -{ - template - void operator()(T obj) const - { - REQUIRE(obj == 0); - } - - template - using ptr_type = void (*)(T); - - template - operator ptr_type() const - { - return [](T obj) { REQUIRE(obj == 0); }; - } -}; - -TEST_CASE("function_ref") -{ - SECTION("functor") - { - struct functor - { - int operator()(int a, int b) - { - return a + b; - } - - void operator()(int& i) - { - REQUIRE(i == 0); - i = 1; - } - } f; - - function_ref a(f); - REQUIRE(a(1, 3) == 4); - - function_ref b(f); - REQUIRE(b(1, 3) == 4); - - auto var = 0; - function_ref c(f); - c(1, var); - - function_ref d(f); - d(var); - REQUIRE(var == 1); - } - SECTION("function pointer") - { - auto f = static_cast([](int a, int b) { return a + b; }); - - function_ref a(f); - REQUIRE(a(1, 3) == 4); - - function_ref b(f); - REQUIRE(a(1, 3) == 4); - - function_ref c(f); - c(1, 3); - } - SECTION("lambda") - { - auto f = [](int a, int b) { return a + b; }; - - function_ref a(f); - REQUIRE(a(1, 3) == 4); - - function_ref b(f); - REQUIRE(a(1, 3) == 4); - - function_ref c(f); - c(1, 3); - } - SECTION("polymorphic lambda") - { - function_ref a(lambda{}); - a(0); - - function_ref b(lambda{}); - b(0); - } - SECTION("member function") - { - struct foo - { - void func(int i) - { - REQUIRE(i == 0); - } - }; - - function_ref a([](foo f, int i) { f.func(i); }); - a(foo{}, 0); - - auto fnc = std::mem_fn(&foo::func); - function_ref b(fnc); - b(foo{}, 0); - } - SECTION("ref conversion") - { - function_ref a([](int a, int b) { return a + b; }); - REQUIRE(a(1, 3) == 4); - - function_ref b(a); - REQUIRE(b(1, 3) == 4); - - function_ref c(a); - c(1, 3); - } - SECTION("assignment") - { - auto f = [] { return 0; }; - auto g = [] { return 1; }; - - function_ref a(f); - REQUIRE(a() == 0); - - function_ref b(g); - REQUIRE(g() == 1); - - b = a; - REQUIRE(b() == 0); - - a.assign(g); - REQUIRE(a() == 1); - } -} diff --git a/third/type_safe/test/strong_typedef.cpp b/third/type_safe/test/strong_typedef.cpp deleted file mode 100644 index f227f85f..00000000 --- a/third/type_safe/test/strong_typedef.cpp +++ /dev/null @@ -1,617 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -#include - -using namespace type_safe; - -#define CREATE_IS_OPERATOR_CALLABLE_WITH_ARGS_CHECKER(Op, CheckerName) \ - template \ - struct CheckerName : std::false_type \ - {}; \ - template \ - struct CheckerName( \ - std::declval()) Op static_cast(std::declval()))>> \ - : std::true_type \ - {}; - -CREATE_IS_OPERATOR_CALLABLE_WITH_ARGS_CHECKER(+, is_operator_plus_callable_with) -CREATE_IS_OPERATOR_CALLABLE_WITH_ARGS_CHECKER(-, is_operator_minus_callable_with) -CREATE_IS_OPERATOR_CALLABLE_WITH_ARGS_CHECKER(/, is_division_callable_with) - -TEST_CASE("strong_typedef") -{ - // only check compilation here - SECTION("general") - { - struct type : strong_typedef, strong_typedef_op::equality_comparison - { - using strong_typedef::strong_typedef; - }; - - // type + type - type t1, t2; - REQUIRE(t1 == t2); - REQUIRE(t1 == std::move(t2)); - REQUIRE(std::move(t1) == t2); - REQUIRE(std::move(t1) == std::move(t2)); - - // type + convert_a - struct convert_a : type - { - using type::type; - }; - convert_a a; - REQUIRE(t1 == a); - REQUIRE(t1 == std::move(a)); - REQUIRE(std::move(t1) == a); - REQUIRE(std::move(t1) == std::move(a)); - - REQUIRE(a == a); - REQUIRE(std::move(a) == a); - REQUIRE(a == std::move(a)); - REQUIRE(std::move(a) == std::move(a)); - - // type + convert_b - struct convert_b - { - operator type() const - { - return type(0); - } - }; - convert_b b; - REQUIRE(t1 == b); - REQUIRE(t1 == std::move(b)); - REQUIRE(std::move(t1) == b); - REQUIRE(std::move(t1) == std::move(b)); - } - SECTION("general mixed") - { - struct type : strong_typedef, - strong_typedef_op::mixed_equality_comparison - { - using strong_typedef::strong_typedef; - }; - - int i = 0; - - // type + int - type t1; - REQUIRE(t1 == i); - REQUIRE(t1 == std::move(i)); - REQUIRE(std::move(t1) == i); - REQUIRE(std::move(t1) == std::move(i)); - - // type + convert - struct convert - { - operator int() const - { - return 0; - } - }; - convert a; - REQUIRE(t1 == a); - REQUIRE(t1 == std::move(a)); - REQUIRE(std::move(t1) == a); - REQUIRE(std::move(t1) == std::move(a)); - } - SECTION("general mixed + non mixed") - { - struct type : strong_typedef, - strong_typedef_op::equality_comparison, - strong_typedef_op::mixed_equality_comparison - { - using strong_typedef::strong_typedef; - }; - - // type + type - type t1, t2; - REQUIRE(t1 == t2); - REQUIRE(t1 == std::move(t2)); - REQUIRE(std::move(t1) == t2); - REQUIRE(std::move(t1) == std::move(t2)); - - // type + convert_a - struct convert_a : type - { - using type::type; - }; - convert_a a; - REQUIRE(t1 == a); - REQUIRE(t1 == std::move(a)); - REQUIRE(std::move(t1) == a); - REQUIRE(std::move(t1) == std::move(a)); - - REQUIRE(a == a); - REQUIRE(std::move(a) == a); - REQUIRE(a == std::move(a)); - REQUIRE(std::move(a) == std::move(a)); - - // type + convert_b - struct convert_b - { - operator type() const - { - return type(0); - } - }; - convert_b b; - REQUIRE(t1 == b); - REQUIRE(t1 == std::move(b)); - REQUIRE(std::move(t1) == b); - REQUIRE(std::move(t1) == std::move(b)); - - // type + int - int i = 0; - REQUIRE(t1 == i); - REQUIRE(t1 == std::move(i)); - REQUIRE(std::move(t1) == i); - REQUIRE(std::move(t1) == std::move(i)); - - // type + convert - struct convert_c - { - operator int() const - { - return 0; - } - }; - convert_c c; - REQUIRE(t1 == c); - REQUIRE(t1 == std::move(c)); - REQUIRE(std::move(t1) == c); - REQUIRE(std::move(t1) == std::move(c)); - } - SECTION("equality_comparison") - { - struct type : strong_typedef, - strong_typedef_op::equality_comparison, - strong_typedef_op::mixed_equality_comparison - { - using strong_typedef::strong_typedef; - }; - - type a(0); - type b(1); - - REQUIRE(a == a); - REQUIRE(a == 0); - REQUIRE(0 == a); - REQUIRE(!(a == b)); - - REQUIRE(a != b); - REQUIRE(a != 1); - REQUIRE(1 != a); - REQUIRE(!(a != a)); - } - SECTION("relational_comparison") - { - struct type : strong_typedef, - strong_typedef_op::relational_comparison, - strong_typedef_op::mixed_relational_comparison - { - using strong_typedef::strong_typedef; - }; - - type a(0); - type b(1); - - REQUIRE(a < b); - REQUIRE(0 < b); - REQUIRE(a < 1); - REQUIRE(!(b < a)); - REQUIRE(a <= b); - REQUIRE(a <= 1); - REQUIRE(1 <= b); - REQUIRE(a <= a); - REQUIRE(b > a); - REQUIRE(1 > a); - REQUIRE(b > 0); - REQUIRE(!(a > b)); - REQUIRE(b >= a); - REQUIRE(b >= 0); - REQUIRE(1 >= a); - REQUIRE(b >= b); - } - SECTION("addition") - { - struct type : strong_typedef, - strong_typedef_op::addition, - strong_typedef_op::mixed_addition - { - using strong_typedef::strong_typedef; - }; - - type a(0); - a += type(1); - a = a + type(1); - a = type(1) + a; - REQUIRE(static_cast(a) == 3); - - type b(0); - b += 1; - b = b + 1; - b = 1 + b; - REQUIRE(static_cast(b) == 3); - } - SECTION("addition with other strong_typedef") - { - struct type_a : strong_typedef - { - using strong_typedef::strong_typedef; - }; - struct type_b : strong_typedef, - strong_typedef_op::mixed_addition - { - using strong_typedef::strong_typedef; - }; - type_a a(3); - type_b b(1); - b += a; // 4 - b = b + a; // 7 - b = a + b; // 10 - REQUIRE(static_cast(b) == 10); - - struct type_c : strong_typedef - {}; - - static_assert(is_operator_plus_callable_with::value, - "type_b supports addition with type_a"); - static_assert(is_operator_plus_callable_with::value, - "type_b supports commutative addition with type_a"); - static_assert(!is_operator_plus_callable_with::value, - "type_b support addition only with type_a, not with int"); - static_assert(!is_operator_plus_callable_with::value, - "type_b support addition only with type_a, not with other strong_typedefs"); - } - SECTION("subtraction") - { - struct type : strong_typedef, - strong_typedef_op::subtraction, - strong_typedef_op::mixed_subtraction - { - using strong_typedef::strong_typedef; - }; - - type a(0); - a -= type(1); // -1 - a = a - type(1); // -2 - a = type(1) - a; // 3 - REQUIRE(static_cast(a) == 3); - - type b(0); - b -= 1; - b = b - 1; - b = 1 - b; - REQUIRE(static_cast(b) == 3); - } - SECTION("subtraction noncommutative") - { - struct type : strong_typedef, - strong_typedef_op::subtraction, - strong_typedef_op::mixed_subtraction_noncommutative - { - using strong_typedef::strong_typedef; - }; - - type a(0); - a -= type(1); // -1 - a = a - type(1); // -2 - a = type(1) - a; // 3 - REQUIRE(static_cast(a) == 3); - - type b(0); - b -= 1; - b = b - 1; - REQUIRE(static_cast(b) == -2); - static_assert(is_operator_minus_callable_with::value, ""); - static_assert(!is_operator_minus_callable_with::value, "type is noncommutative"); - } - SECTION("multiplication") - { - struct type : strong_typedef, - strong_typedef_op::multiplication, - strong_typedef_op::mixed_multiplication - { - using strong_typedef::strong_typedef; - }; - - type a(1); - a *= type(2); - a = a * type(2); - a = type(2) * a; - REQUIRE(static_cast(a) == 8); - - type b(1); - b *= 2; - b = b * 2; - b = 2 * b; - REQUIRE(static_cast(b) == 8); - } - SECTION("division") - { - struct type : strong_typedef, - strong_typedef_op::division, - strong_typedef_op::mixed_division - { - using strong_typedef::strong_typedef; - }; - - type a(8); - a /= type(2); - a = a / type(2); - a = type(2) / a; - REQUIRE(static_cast(a) == 1); - - type b(8); - b /= 2; - b = b / 2; - b = 2 / b; - REQUIRE(static_cast(b) == 1); - } - SECTION("division noncommutative") - { - struct type : strong_typedef, - strong_typedef_op::division, - strong_typedef_op::mixed_division_noncommutative - { - using strong_typedef::strong_typedef; - }; - - type a(8); - a /= type(2); - a = a / type(2); - a = type(2) / a; - REQUIRE(static_cast(a) == 1); - - type b(8); - b /= 2; - b = b / 2; - REQUIRE(static_cast(b) == 2); - static_assert(is_division_callable_with::value, ""); - static_assert(!is_division_callable_with::value, - "division of type and int is noncommutative"); - } - SECTION("modulo") - { - struct type : strong_typedef, - strong_typedef_op::modulo, - strong_typedef_op::mixed_modulo - { - using strong_typedef::strong_typedef; - }; - - type a(11); - a %= type(6); // 5 - a = a % type(2); // 1 - a = type(2) % a; // 0 - REQUIRE(static_cast(a) == 0); - - type b(11); - b %= 6; - b = b % 2; - b = 2 % b; - REQUIRE(static_cast(b) == 0); - } - SECTION("increment") - { - struct type : strong_typedef, strong_typedef_op::increment - { - using strong_typedef::strong_typedef; - }; - - type a(0); - REQUIRE(static_cast(++a) == 1); - REQUIRE(static_cast(a++) == 1); - REQUIRE(static_cast(a) == 2); - } - SECTION("decrement") - { - struct type : strong_typedef, strong_typedef_op::decrement - { - using strong_typedef::strong_typedef; - }; - - type a(0); - REQUIRE(static_cast(--a) == -1); - REQUIRE(static_cast(a--) == -1); - REQUIRE(static_cast(a) == -2); - } - SECTION("unary") - { - struct type : strong_typedef, - strong_typedef_op::unary_minus, - strong_typedef_op::unary_plus - { - using strong_typedef::strong_typedef; - }; - - type a(2); - REQUIRE(static_cast(+a) == 2); - REQUIRE(static_cast(-a) == -2); - } - SECTION("complement") - { - struct type : strong_typedef, strong_typedef_op::complement - { - using strong_typedef::strong_typedef; - }; - - type a(1u); - REQUIRE(static_cast(~a) == ~1u); - - type b(42u); - REQUIRE(static_cast(~b) == ~42u); - } - SECTION("bitwise") - { - struct type : strong_typedef, - strong_typedef_op::bitwise_or, - strong_typedef_op::bitwise_xor, - strong_typedef_op::bitwise_and - { - using strong_typedef::strong_typedef; - }; - - type a(0u); - - REQUIRE(static_cast(a | type(3u)) == 3u); - REQUIRE(static_cast(type(3u) | a) == 3u); - a |= type(3u); - REQUIRE(static_cast(a) == 3u); - - REQUIRE(static_cast(a & type(2u)) == 2u); - REQUIRE(static_cast(type(2u) & a) == 2u); - a &= type(2u); - REQUIRE(static_cast(a) == 2u); - - REQUIRE(static_cast(a ^ type(3u)) == 1u); - REQUIRE(static_cast(type(3u) ^ a) == 1u); - a ^= type(3u); - REQUIRE(static_cast(a) == 1u); - } - SECTION("bitshift") - { - struct type : strong_typedef, strong_typedef_op::bitshift - { - using strong_typedef::strong_typedef; - }; - - type a(1u); - - REQUIRE(static_cast(a << 1u) == 2u); - a <<= 1u; - REQUIRE(static_cast(a) == 2u); - - REQUIRE(static_cast(a >> 1u) == 1u); - a >>= 1u; - REQUIRE(static_cast(a) == 1u); - } - SECTION("dereference") - { - struct test - { - int a; - } t{0}; - - struct type : strong_typedef, strong_typedef_op::dereference - { - using strong_typedef::strong_typedef; - }; - - type a(&t); - REQUIRE((*a).a == 0); - REQUIRE(a->a == 0); - } - SECTION("array subscript") - { - int arr[] = {0, 1, 2}; - - struct type : strong_typedef, strong_typedef_op::array_subscript - { - using strong_typedef::strong_typedef; - }; - - type a(arr); - REQUIRE(a[0] == 0); - REQUIRE(a[1] == 1); - REQUIRE(a[2] == 2); - } - SECTION("iterator") - { - int arr[] = {0, 1, 2}; - - struct type : strong_typedef, - strong_typedef_op::random_access_iterator - { - using strong_typedef::strong_typedef; - }; - - type a(arr); - a += 1; - REQUIRE(a == type(&arr[1])); - - a -= 1; - REQUIRE(a == type(&arr[0])); - - a = a + 1; - a = 1 + a; - REQUIRE(a == type(&arr[2])); - - a = a - 1; - REQUIRE(a == type(&arr[1])); - - REQUIRE(a - type(&arr[0]) == 1); - } - SECTION("i/o") - { - struct type : strong_typedef, - strong_typedef_op::input_operator, - strong_typedef_op::output_operator - { - using strong_typedef::strong_typedef; - }; - - std::ostringstream out; - std::istringstream in("1"); - - type a(0); - out << a; - REQUIRE(out.str() == "0"); - - in >> a; - REQUIRE(static_cast(a) == 1); - } - SECTION("explicit bool") - { - struct type : strong_typedef, strong_typedef_op::explicit_bool - { - using strong_typedef::strong_typedef; - }; - - type a(0); - REQUIRE(!a); - type b(1); - REQUIRE(b); - } - SECTION("explicit bool nonconstexpr") - { - struct foo - { - bool flag; - - explicit operator bool() const - { - return flag; - } - }; - - struct type : strong_typedef, strong_typedef_op::explicit_bool - { - using strong_typedef::strong_typedef; - }; - - type a(foo{false}); - REQUIRE(!a); - type b(foo{true}); - REQUIRE(b); - } - SECTION("is_strong_typedef") - { - struct strong : strong_typedef - { - using strong_typedef::strong_typedef; - }; - - REQUIRE(is_strong_typedef::value); - REQUIRE(!is_strong_typedef::value); - } -} diff --git a/third/type_safe/test/tagged_union.cpp b/third/type_safe/test/tagged_union.cpp deleted file mode 100644 index 4268ee8f..00000000 --- a/third/type_safe/test/tagged_union.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -#include "debugger_type.hpp" - -using namespace type_safe; - -TEST_CASE("tagged_union") -{ - using union_t = tagged_union; - REQUIRE(union_t::invalid_type == union_t::type_id()); - - union_t tunion; - REQUIRE(!tunion.has_value()); - REQUIRE(tunion.type() == union_t::invalid_type); - REQUIRE(static_cast(tunion.type()) == 0u); - - SECTION("emplace int") - { - tunion.emplace(union_type{}, 5); - REQUIRE(tunion.has_value()); - REQUIRE(tunion.type() == union_t::type_id(union_type{})); - REQUIRE(static_cast(tunion.type()) == 1u); - REQUIRE(tunion.value(union_type{}) == 5); - - union_t other; - copy(other, tunion); - REQUIRE(other.has_value()); - REQUIRE(other.type() == union_t::type_id(union_type{})); - REQUIRE(other.value(union_type{}) == 5); - - SECTION("member") - { - tunion.destroy(union_type{}); - REQUIRE(!tunion.has_value()); - REQUIRE(tunion.type() == union_t::invalid_type); - } - SECTION("non-member") - { - destroy(tunion); - REQUIRE(!tunion.has_value()); - REQUIRE(tunion.type() == union_t::invalid_type); - } - } - SECTION("emplace double") - { - tunion.emplace(union_type{}, 3.0); - REQUIRE(tunion.has_value()); - REQUIRE(tunion.type() == union_t::type_id(union_type{})); - REQUIRE(static_cast(tunion.type()) == 2u); - REQUIRE(tunion.value(union_type{}) == 3.0); - - union_t other; - copy(other, tunion); - REQUIRE(other.has_value()); - REQUIRE(other.type() == union_t::type_id(union_type{})); - REQUIRE(other.value(union_type{}) == 3.0); - - SECTION("member") - { - tunion.destroy(union_type{}); - REQUIRE(!tunion.has_value()); - REQUIRE(tunion.type() == union_t::invalid_type); - } - SECTION("non-member") - { - destroy(tunion); - REQUIRE(!tunion.has_value()); - REQUIRE(tunion.type() == union_t::invalid_type); - } - } - SECTION("emplace debugger_type") - { - tunion.emplace(union_type{}, 42); - REQUIRE(tunion.has_value()); - REQUIRE(tunion.type() == union_t::type_id(union_type{})); - REQUIRE(static_cast(tunion.type()) == 3u); - - auto& val = tunion.value(union_type{}); - REQUIRE(val.id == 42); - REQUIRE(val.ctor()); - - SECTION("copy") - { - union_t other; - copy(other, tunion); - REQUIRE(other.has_value()); - REQUIRE(other.type() == union_t::type_id(union_type{})); - - auto& otherval = other.value(union_type{}); - REQUIRE(otherval.id == 42); - REQUIRE(otherval.copy_ctor()); - } - SECTION("move") - { - union_t other; - move(other, std::move(tunion)); - REQUIRE(other.has_value()); - REQUIRE(other.type() == union_t::type_id(union_type{})); - - auto& otherval = other.value(union_type{}); - REQUIRE(otherval.id == 42); - REQUIRE(otherval.move_ctor()); - } - - SECTION("member") - { - tunion.destroy(union_type{}); - REQUIRE(!tunion.has_value()); - REQUIRE(tunion.type() == union_t::invalid_type); - } - SECTION("non-member") - { - destroy(tunion); - REQUIRE(!tunion.has_value()); - REQUIRE(tunion.type() == union_t::invalid_type); - } - } -} diff --git a/third/type_safe/test/test.cpp b/third/type_safe/test/test.cpp deleted file mode 100644 index 5f604d40..00000000 --- a/third/type_safe/test/test.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#define CATCH_CONFIG_MAIN -#include diff --git a/third/type_safe/test/variant.cpp b/third/type_safe/test/variant.cpp deleted file mode 100644 index 49b1fc42..00000000 --- a/third/type_safe/test/variant.cpp +++ /dev/null @@ -1,712 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -#include "debugger_type.hpp" - -using type_safe::fallback_variant; -using type_safe::nullvar; -using type_safe::nullvar_t; -using type_safe::tagged_union; -using type_safe::union_type; -using type_safe::variant; -using type_safe::variant_type; - -// use optional variant to be able to test all functions -// test policies separately -using variant_t = variant; -using union_t = tagged_union; - -template -void check_variant_empty(const Variant& var) -{ - // boolean queries - REQUIRE(!var.has_value()); - REQUIRE(!var); - - // type queries - REQUIRE(var.type() == Variant::invalid_type); - REQUIRE(var.has_value(variant_type{})); - - // value query - // (check that it compiles and does not abort) - nullvar_t null = var.value(variant_type{}); - (void)null; - - // optional_value queries - REQUIRE(var.optional_value(variant_type{})); - REQUIRE(!var.optional_value(variant_type{})); -} - -template -void check_variant_value(const Variant& var, const T& val) -{ - // boolean queries - REQUIRE(var.has_value()); - REQUIRE(var); - - // type queries - REQUIRE(var.type() == typename Variant::type_id(variant_type{})); - REQUIRE(var.has_value(variant_type{})); - - // value query - REQUIRE(var.value(variant_type{}) == val); - - // optional_value queries - using is_int = std::is_same; - using is_double = std::is_same; - using is_dbg = std::is_same; - - REQUIRE(!var.optional_value(variant_type{})); - REQUIRE(bool(var.optional_value(variant_type{})) == is_int::value); - REQUIRE(bool(var.optional_value(variant_type{})) == is_double::value); - REQUIRE(bool(var.optional_value(variant_type{})) == is_dbg::value); -} - -TEST_CASE("basic_variant") -{ - variant_t empty; - variant_t non_empty1(5); - variant_t non_empty2(debugger_type(42)); - - SECTION("constructor - empty") - { - variant_t a; - check_variant_empty(a); - - variant_t b(nullvar); - check_variant_empty(b); - } - SECTION("constructor - value") - { - variant_t a(5); - check_variant_value(a, 5); - - variant_t b(3.0); - check_variant_value(b, 3.0); - - variant_t c(debugger_type(42)); - check_variant_value(c, debugger_type(42)); - REQUIRE(c.value(variant_type{}).move_ctor()); - } - SECTION("constructor - args") - { - variant_t a(variant_type{}, 5); - check_variant_value(a, 5); - - variant_t b(variant_type{}, 3.0); - check_variant_value(b, 3.0); - - variant_t c(variant_type{}, 42); - check_variant_value(c, debugger_type(42)); - REQUIRE(c.value(variant_type{}).ctor()); - } - SECTION("constructor - union copy") - { - union_t u; - - variant_t a(u); - check_variant_empty(a); - - u.emplace(union_type{}, 5); - - variant_t b(u); - check_variant_value(b, 5); - - u.destroy(union_type{}); - u.emplace(union_type{}, debugger_type(42)); - - variant_t c(u); - check_variant_value(c, debugger_type(42)); - REQUIRE(c.value(variant_type{}).copy_ctor()); - } - SECTION("constructor - union move") - { - union_t u; - - variant_t a(std::move(u)); - check_variant_empty(a); - - u.emplace(union_type{}, 5); - - variant_t b(std::move(u)); - check_variant_value(b, 5); - - u.destroy(union_type{}); - u.emplace(union_type{}, debugger_type(42)); - - variant_t c(std::move(u)); - check_variant_value(c, debugger_type(42)); - REQUIRE(c.value(variant_type{}).move_ctor()); - } - SECTION("constructor - copy") - { - variant_t a(empty); - check_variant_empty(a); - - variant_t b(non_empty1); - check_variant_value(b, 5); - - variant_t c(non_empty2); - check_variant_value(c, debugger_type(42)); - REQUIRE(c.value(variant_type{}).copy_ctor()); - } - SECTION("constructor - move") - { - variant_t a(std::move(empty)); - check_variant_empty(a); - - variant_t b(std::move(non_empty1)); - check_variant_value(b, 5); - - variant_t c(std::move(non_empty2)); - check_variant_value(c, debugger_type(42)); - REQUIRE(c.value(variant_type{}).move_ctor()); - } - SECTION("copy assignment") - { - variant_t a; - a = empty; - check_variant_empty(a); - a = non_empty1; - check_variant_value(a, 5); - a = non_empty2; - check_variant_value(a, debugger_type(42)); - REQUIRE(a.value(variant_type{}).copy_ctor()); - - variant_t b(5); - b = non_empty1; - check_variant_value(b, 5); - b = non_empty2; - check_variant_value(b, debugger_type(42)); - REQUIRE(b.value(variant_type{}).copy_ctor()); - b = empty; - check_variant_empty(b); - - variant_t c(debugger_type(42)); - c = non_empty2; - check_variant_value(c, debugger_type(42)); - REQUIRE(c.value(variant_type{}).copy_assigned()); - c = non_empty1; - check_variant_value(c, 5); - c = empty; - check_variant_empty(c); - } - SECTION("move assignment") - { - variant_t a; - a = std::move(empty); - check_variant_empty(a); - a = std::move(non_empty1); - check_variant_value(a, 5); - a = std::move(non_empty2); - check_variant_value(a, debugger_type(42)); - REQUIRE(a.value(variant_type{}).move_ctor()); - - variant_t b(5); - b = std::move(non_empty1); - check_variant_value(b, 5); - b = std::move(non_empty2); - check_variant_value(b, debugger_type(42)); - REQUIRE(b.value(variant_type{}).move_ctor()); - b = std::move(empty); - check_variant_empty(b); - - variant_t c(debugger_type(42)); - c = std::move(non_empty2); - check_variant_value(c, debugger_type(42)); - REQUIRE(c.value(variant_type{}).move_assigned()); - c = std::move(non_empty1); - check_variant_value(c, 5); - c = std::move(empty); - check_variant_empty(c); - } - SECTION("swap") - { - SECTION("empty, empty") - { - swap(empty, empty); - check_variant_empty(empty); - - variant_t empty2(empty); - swap(empty, empty2); - check_variant_empty(empty); - check_variant_empty(empty2); - } - SECTION("empty, non_empty1") - { - swap(empty, non_empty1); - check_variant_value(empty, 5); - check_variant_empty(non_empty1); - - swap(empty, non_empty1); - check_variant_value(non_empty1, 5); - check_variant_empty(empty); - } - SECTION("empty, non_empty2") - { - swap(empty, non_empty2); - check_variant_value(empty, debugger_type(42)); - check_variant_empty(non_empty2); - REQUIRE(empty.value(variant_type{}).ctor()); - - swap(empty, non_empty2); - check_variant_value(non_empty2, debugger_type(42)); - check_variant_empty(empty); - REQUIRE(non_empty2.value(variant_type{}).ctor()); - } - SECTION("non-empty, different types") - { - swap(non_empty1, non_empty2); - check_variant_value(non_empty1, debugger_type(42)); - check_variant_value(non_empty2, 5); - REQUIRE(non_empty1.value(variant_type{}).move_ctor()); - - swap(non_empty1, non_empty2); - check_variant_value(non_empty2, debugger_type(42)); - check_variant_value(non_empty1, 5); - REQUIRE(non_empty2.value(variant_type{}).move_ctor()); - } - SECTION("non-empty, same types") - { - swap(non_empty2, non_empty2); - check_variant_value(non_empty2, debugger_type(42)); - REQUIRE(non_empty2.value(variant_type{}).swapped); - - variant_t other(debugger_type(43)); - swap(non_empty2, other); - check_variant_value(non_empty2, debugger_type(43)); - check_variant_value(other, debugger_type(42)); - REQUIRE(non_empty2.value(variant_type{}).swapped); - REQUIRE(other.value(variant_type{}).swapped); - - swap(non_empty2, other); - check_variant_value(non_empty2, debugger_type(42)); - check_variant_value(other, debugger_type(43)); - REQUIRE(non_empty2.value(variant_type{}).swapped); - REQUIRE(other.value(variant_type{}).swapped); - } - } - SECTION("reset") - { - empty.reset(); - check_variant_empty(empty); - - non_empty1.reset(); - check_variant_empty(non_empty1); - - non_empty2.reset(); - check_variant_empty(non_empty2); - } - SECTION("reset assignment") - { - empty = nullvar; - check_variant_empty(empty); - - non_empty1 = nullvar; - check_variant_empty(non_empty1); - - non_empty2 = nullvar; - check_variant_empty(non_empty2); - } - SECTION("emplace single arg") - { - empty.emplace(variant_type{}, debugger_type(43)); - check_variant_value(empty, debugger_type(43)); - REQUIRE(empty.value(variant_type{}).move_ctor()); - - non_empty1.emplace(variant_type{}, debugger_type(43)); - check_variant_value(non_empty1, debugger_type(43)); - REQUIRE(non_empty1.value(variant_type{}).move_ctor()); - - non_empty2.emplace(variant_type{}, debugger_type(43)); - check_variant_value(non_empty1, debugger_type(43)); - REQUIRE(non_empty2.value(variant_type{}).move_assigned()); - } - SECTION("emplace assignment") - { - empty = debugger_type(43); - check_variant_value(empty, debugger_type(43)); - REQUIRE(empty.value(variant_type{}).move_ctor()); - - non_empty1 = debugger_type(43); - check_variant_value(non_empty1, debugger_type(43)); - REQUIRE(non_empty1.value(variant_type{}).move_ctor()); - - non_empty2 = debugger_type(43); - check_variant_value(non_empty1, debugger_type(43)); - REQUIRE(non_empty2.value(variant_type{}).move_assigned()); - } - SECTION("emplace multiple args") - { - empty.emplace(variant_type{}, 43, 5.0, 'a'); - check_variant_value(empty, debugger_type(43)); - REQUIRE(empty.value(variant_type{}).ctor()); - - non_empty1.emplace(variant_type{}, 43, 5.0, 'a'); - check_variant_value(non_empty1, debugger_type(43)); - REQUIRE(non_empty1.value(variant_type{}).ctor()); - - non_empty2.emplace(variant_type{}, 43, 5.0, 'a'); - check_variant_value(non_empty1, debugger_type(43)); - REQUIRE(non_empty2.value(variant_type{}).ctor()); - } - SECTION("value_or") - { - REQUIRE(empty.value_or(variant_type{}, 3) == 3); - REQUIRE(non_empty1.value_or(variant_type{}, 3) == 5); - REQUIRE(non_empty2.value_or(variant_type{}, 3) == 3); - - REQUIRE(non_empty2.value_or(variant_type{}, 3.14) == 3.14); - } - SECTION("map") - { - struct functor_t - { - bool expect_call = false; - - int operator()(int i, int j) - { - REQUIRE(expect_call); - REQUIRE(i == 5); - REQUIRE(j == 0); - return 12; - } - - int operator()(const debugger_type& dbg, int j) - { - REQUIRE(expect_call); - REQUIRE(dbg.id == 42); - REQUIRE(j == 0); - return 42; - } - - int operator()(double, int) = delete; - } functor; - - functor.expect_call = false; - auto a = empty.map(functor, 0); - check_variant_empty(a); - - functor.expect_call = true; - auto b = non_empty1.map(functor, 0); - check_variant_value(b, 12); - - functor.expect_call = true; - auto c = non_empty2.map(functor, 0); - check_variant_value(c, 42); - - functor.expect_call = false; - auto d = variant_t(3.0).map(functor, 0); - check_variant_value(d, 3.0); - } - SECTION("compare null") - { - REQUIRE(empty == nullvar); - REQUIRE_FALSE(empty != nullvar); - REQUIRE_FALSE(empty < nullvar); - REQUIRE_FALSE(nullvar < empty); - REQUIRE(empty <= nullvar); - REQUIRE(nullvar <= empty); - REQUIRE_FALSE(empty > nullvar); - REQUIRE_FALSE(nullvar > empty); - REQUIRE(empty >= nullvar); - REQUIRE(nullvar >= empty); - - REQUIRE_FALSE(non_empty1 == nullvar); - REQUIRE(non_empty1 != nullvar); - REQUIRE_FALSE(non_empty1 < nullvar); - REQUIRE(nullvar < non_empty1); - REQUIRE_FALSE(non_empty1 <= nullvar); - REQUIRE(nullvar <= non_empty1); - REQUIRE(non_empty1 > nullvar); - REQUIRE_FALSE(nullvar > non_empty1); - REQUIRE(non_empty1 >= nullvar); - REQUIRE_FALSE(nullvar >= non_empty1); - } - SECTION("compare value") - { - REQUIRE_FALSE(empty == 4); - REQUIRE(empty != 4); - REQUIRE(empty < 4); - REQUIRE_FALSE(4 < empty); - REQUIRE(empty <= 4); - REQUIRE_FALSE(4 <= empty); - REQUIRE_FALSE(empty > 4); - REQUIRE(4 > empty); - REQUIRE_FALSE(empty >= 4); - REQUIRE(4 >= empty); - - REQUIRE_FALSE(non_empty1 == 4); - REQUIRE(non_empty1 != 4); - REQUIRE_FALSE(non_empty1 < 4); - REQUIRE(4 < non_empty1); - REQUIRE_FALSE(non_empty1 <= 4); - REQUIRE(4 <= non_empty1); - REQUIRE(non_empty1 > 4); - REQUIRE_FALSE(4 > non_empty1); - REQUIRE(non_empty1 >= 4); - REQUIRE_FALSE(4 >= non_empty1); - - REQUIRE(non_empty1 == 5); - REQUIRE_FALSE(non_empty1 != 5); - REQUIRE_FALSE(non_empty1 < 5); - REQUIRE_FALSE(5 < non_empty1); - REQUIRE(non_empty1 <= 5); - REQUIRE(5 <= non_empty1); - REQUIRE_FALSE(non_empty1 > 5); - REQUIRE_FALSE(5 > non_empty1); - REQUIRE(non_empty1 >= 5); - REQUIRE(5 >= non_empty1); - - REQUIRE_FALSE(non_empty2 == 4); - REQUIRE(non_empty2 != 4); - REQUIRE_FALSE(non_empty2 < 4); - REQUIRE(4 < non_empty2); - REQUIRE_FALSE(non_empty2 <= 4); - REQUIRE(4 <= non_empty2); - REQUIRE(non_empty2 > 4); - REQUIRE_FALSE(4 > non_empty2); - REQUIRE(non_empty2 >= 4); - REQUIRE_FALSE(4 >= non_empty2); - } - SECTION("compare variant") - { - REQUIRE(empty == variant_t()); - REQUIRE_FALSE(empty != variant_t()); - REQUIRE_FALSE(empty < variant_t()); - REQUIRE_FALSE(variant_t() < empty); - REQUIRE(empty <= variant_t()); - REQUIRE(variant_t() <= empty); - REQUIRE_FALSE(empty > variant_t()); - REQUIRE_FALSE(variant_t() > empty); - REQUIRE(empty >= variant_t()); - REQUIRE(variant_t() >= empty); - - REQUIRE_FALSE(non_empty1 == variant_t()); - REQUIRE(non_empty1 != variant_t()); - REQUIRE_FALSE(non_empty1 < variant_t()); - REQUIRE(variant_t() < non_empty1); - REQUIRE_FALSE(non_empty1 <= variant_t()); - REQUIRE(variant_t() <= non_empty1); - REQUIRE(non_empty1 > variant_t()); - REQUIRE_FALSE(variant_t() > non_empty1); - REQUIRE(non_empty1 >= variant_t()); - REQUIRE_FALSE(variant_t() >= non_empty1); - - REQUIRE_FALSE(empty == variant_t(4)); - REQUIRE(empty != variant_t(4)); - REQUIRE(empty < variant_t(4)); - REQUIRE_FALSE(variant_t(4) < empty); - REQUIRE(empty <= variant_t(4)); - REQUIRE_FALSE(variant_t(4) <= empty); - REQUIRE_FALSE(empty > variant_t(4)); - REQUIRE(variant_t(4) > empty); - REQUIRE_FALSE(empty >= variant_t(4)); - REQUIRE(variant_t(4) >= empty); - - REQUIRE_FALSE(non_empty1 == variant_t(4)); - REQUIRE(non_empty1 != variant_t(4)); - REQUIRE_FALSE(non_empty1 < variant_t(4)); - REQUIRE(variant_t(4) < non_empty1); - REQUIRE_FALSE(non_empty1 <= variant_t(4)); - REQUIRE(variant_t(4) <= non_empty1); - REQUIRE(non_empty1 > variant_t(4)); - REQUIRE_FALSE(variant_t(4) > non_empty1); - REQUIRE(non_empty1 >= variant_t(4)); - REQUIRE_FALSE(variant_t(4) >= non_empty1); - - REQUIRE(non_empty1 == variant_t(5)); - REQUIRE_FALSE(non_empty1 != variant_t(5)); - REQUIRE_FALSE(non_empty1 < variant_t(5)); - REQUIRE_FALSE(variant_t(5) < non_empty1); - REQUIRE(non_empty1 <= variant_t(5)); - REQUIRE(variant_t(5) <= non_empty1); - REQUIRE_FALSE(non_empty1 > variant_t(5)); - REQUIRE_FALSE(variant_t(5) > non_empty1); - REQUIRE(non_empty1 >= variant_t(5)); - REQUIRE(variant_t(5) >= non_empty1); - - REQUIRE_FALSE(non_empty2 == variant_t(4)); - REQUIRE(non_empty2 != variant_t(4)); - REQUIRE_FALSE(non_empty2 < variant_t(4)); - REQUIRE(variant_t(4) < non_empty2); - REQUIRE_FALSE(non_empty2 <= variant_t(4)); - REQUIRE(variant_t(4) <= non_empty2); - REQUIRE(non_empty2 > variant_t(4)); - REQUIRE_FALSE(variant_t(4) > non_empty2); - REQUIRE(non_empty2 >= variant_t(4)); - REQUIRE_FALSE(variant_t(4) >= non_empty2); - } - SECTION("with") - { - struct visitor - { - int i; - - void operator()(int val) const - { - REQUIRE(i == 1); - REQUIRE(val == 5); - } - - void operator()(double f) const - { - REQUIRE(i == 2); - REQUIRE(f == 3.14); - } - } v; - - variant_t a; - v.i = 0; - with(a, v); - - variant_t b(5); - v.i = 1; - with(b, v); - - variant_t c(3.14); - v.i = 2; - with(c, v); - - variant_t d(5); - with(d, [](int& i) { ++i; }); - check_variant_value(d, 6); - } -} - -struct evil_variant_test_type -{ - bool move_throw = false; - - evil_variant_test_type(int) noexcept {} - - evil_variant_test_type(const char*) - { - throw "buh!"; - } - - evil_variant_test_type(double) - { - move_throw = true; - } - - evil_variant_test_type(evil_variant_test_type&& other) - { - if (other.move_throw) - throw "haha!"; - } -}; - -inline bool operator==(const evil_variant_test_type&, const evil_variant_test_type&) -{ - return true; -} - -TEST_CASE("fallback_variant") -{ - fallback_variant var(3); - - SECTION("harmless ctor") - { - var.emplace(variant_type{}, 42); - check_variant_value(var, evil_variant_test_type(42)); - } - SECTION("move ctor") - { - var = evil_variant_test_type(42); - check_variant_value(var, evil_variant_test_type(42)); - } - SECTION("throwing move") - { - evil_variant_test_type test(42); - test.move_throw = true; - try - { - var = std::move(test); - } - catch (...) - {} - check_variant_value(var, 0); - } -} - -TEST_CASE("optional_variant") -{ - variant var(3); - - SECTION("harmless ctor") - { - var.emplace(variant_type{}, 42); - check_variant_value(var, evil_variant_test_type(42)); - } - SECTION("move ctor") - { - var = evil_variant_test_type(42); - check_variant_value(var, evil_variant_test_type(42)); - } - SECTION("throwing move") - { - evil_variant_test_type test(42); - test.move_throw = true; - try - { - var = std::move(test); - } - catch (...) - {} - check_variant_empty(var); - } -} - -TEST_CASE("rarely_empty_variant") -{ - variant var(3); - - SECTION("harmless ctor") - { - var.emplace(variant_type{}, 42); - check_variant_value(var, evil_variant_test_type(42)); - } - SECTION("move ctor") - { - var = evil_variant_test_type(42); - check_variant_value(var, evil_variant_test_type(42)); - } - SECTION("throwing ctor") - { - try - { - var.emplace(variant_type{}, "I will throw"); - } - catch (...) - {} - check_variant_value(var, 3); - } - SECTION("delayed throwing move") - { - try - { - var.emplace(variant_type{}, 3.14); - } - catch (...) - {} - check_variant_empty(var); - } - SECTION("throwing move") - { - evil_variant_test_type test(42); - test.move_throw = true; - try - { - var = std::move(test); - } - catch (...) - {} - check_variant_empty(var); - } -} diff --git a/third/type_safe/test/visitor.cpp b/third/type_safe/test/visitor.cpp deleted file mode 100644 index b1adedf2..00000000 --- a/third/type_safe/test/visitor.cpp +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (C) 2016-2020 Jonathan Müller -// This file is subject to the license terms in the LICENSE file -// found in the top-level directory of this distribution. - -#include - -#include - -using type_safe::nullopt_t; -using type_safe::nullvar_t; -using type_safe::optional; -using type_safe::variant; - -TEST_CASE("visit optional") -{ - struct visitor - { - using incomplete_visitor = void; - - int value; - - void operator()(nullopt_t) const - { - REQUIRE(value == -1); - } - - void operator()(int i) const - { - REQUIRE(value == i); - } - - void operator()(int, nullopt_t) const - { - REQUIRE(value == -1); - } - - void operator()(int, int b) const - { - REQUIRE(value == b); - } - }; - - optional a; - visit(visitor{-1}, a); - - a = 42; - visit(visitor{42}, a); - - optional b; - visit(visitor{-1}, a, b); - - b = 32; - visit(visitor{32}, a, b); -} - -TEST_CASE("visit variant") -{ - SECTION("optional variant") - { - struct visitor - { - int value; - - void operator()(nullvar_t) const - { - REQUIRE(value == -1); - } - - void operator()(int i) const - { - REQUIRE(value == i); - } - - void operator()(float f) const - { - REQUIRE(f == 3.14f); - } - - void operator()(nullvar_t, nullvar_t) const - { - REQUIRE(false); - } - void operator()(nullvar_t, int) const - { - REQUIRE(false); - } - - void operator()(int, nullvar_t) const - { - REQUIRE(value == -1); - } - void operator()(int, int b) const - { - REQUIRE(value == b); - } - - void operator()(float, nullvar_t) const - { - REQUIRE(false); - } - void operator()(float a, int b) const - { - REQUIRE(value == b); - REQUIRE(a == 3.14f); - } - }; - - variant a; - visit(visitor{-1}, a); - - a = 42; - visit(visitor{42}, a); - - variant b; - visit(visitor{-1}, a, b); - - b = 32; - visit(visitor{32}, a, b); - - a = 3.14f; - visit(visitor{-1}, a); - visit(visitor{32}, a, b); - } - SECTION("returning reference") - { - struct visitor - { - int value; - int& operator()(int) - { - return value; - } - }; - - visitor v{1}; - variant x{1}; - visit(v, x) = 2; - - REQUIRE(v.value == 2); - } - SECTION("rarely empty variant") - { - struct visitor - { - int value; - - void operator()(int a) - { - REQUIRE(a == value); - } - - void operator()(float b) - { - REQUIRE(b == 3.14f); - REQUIRE(value == -1); - } - - void operator()(int, int) - { - REQUIRE(false); - } - - void operator()(int, float) - { - REQUIRE(false); - } - - void operator()(float a, int b) - { - REQUIRE(a == 3.14f); - REQUIRE(b == value); - } - - void operator()(float, float) - { - REQUIRE(false); - } - }; - - variant a(0); - visit(visitor{0}, a); - - a = 3.14f; - visit(visitor{-1}, a); - - variant b(0); - visit(visitor{0}, a, b); - } - SECTION("return type") - { - variant a(1); - auto b = a; - - REQUIRE(visit([](int) { return 0; }, a) == 0); - REQUIRE(visit([](int, int) { return 0; }, a, b) == 0); - } -} diff --git a/third/type_safe/test_std_module/CMakeLists.txt b/third/type_safe/test_std_module/CMakeLists.txt deleted file mode 100644 index d453098f..00000000 --- a/third/type_safe/test_std_module/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (C) 2016-2019 Jonathan Müller -# This file is subject to the license terms in the LICENSE file -# found in the top-level directory of this distribution. - -add_executable(type_safe_test_std_module test.cpp) -target_link_libraries(type_safe_test_std_module PUBLIC type_safe) -target_include_directories(type_safe_test_std_module PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - -# Hopefully MS will provide a better/automatic/IJW way to use the standard library module, in other words "import std;" should just work -if( MSVC ) - # Try to find "VCToolsInstallDir" from the environment variable, then look for "std.ixx" according to its path - if (DEFINED ENV{VCToolsInstallDir} AND EXISTS $ENV{VCToolsInstallDir} AND EXISTS $ENV{VCToolsInstallDir}modules/std.ixx) - target_sources(type_safe PUBLIC "$ENV{VCToolsInstallDir}modules/std.ixx") - else () - # We use a path relative to the compiler location which should be stable and avoid VS upgrade/version/preview install location issues - cmake_path(GET CMAKE_CXX_COMPILER PARENT_PATH CompilerDir) - target_sources(type_safe PUBLIC "${CompilerDir}/../../../modules/std.ixx") - endif (DEFINED ENV{VCToolsInstallDir} AND EXISTS $ENV{VCToolsInstallDir} AND EXISTS $ENV{VCToolsInstallDir}modules/std.ixx) -endif() diff --git a/third/type_safe/test_std_module/test.cpp b/third/type_safe/test_std_module/test.cpp deleted file mode 100644 index 2479adae..00000000 --- a/third/type_safe/test_std_module/test.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// This test really only includes all the type_safe header and checks we can so a build -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main( ) -{ - return 0; -} diff --git a/third/type_safe/type_safe-config.cmake b/third/type_safe/type_safe-config.cmake deleted file mode 100644 index cc434375..00000000 --- a/third/type_safe/type_safe-config.cmake +++ /dev/null @@ -1,46 +0,0 @@ - -include(CMakeFindDependencyMacro OPTIONAL RESULT_VARIABLE _CMakeFindDependencyMacro_FOUND) -if (NOT _CMakeFindDependencyMacro_FOUND) - macro(find_dependency dep) - if (NOT ${dep}_FOUND) - set(cmake_fd_version) - if (${ARGC} GREATER 1) - set(cmake_fd_version ${ARGV1}) - endif() - set(cmake_fd_exact_arg) - if(${CMAKE_FIND_PACKAGE_NAME}_FIND_VERSION_EXACT) - set(cmake_fd_exact_arg EXACT) - endif() - set(cmake_fd_quiet_arg) - if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) - set(cmake_fd_quiet_arg QUIET) - endif() - set(cmake_fd_required_arg) - if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED) - set(cmake_fd_required_arg REQUIRED) - endif() - find_package(${dep} ${cmake_fd_version} - ${cmake_fd_exact_arg} - ${cmake_fd_quiet_arg} - ${cmake_fd_required_arg} - ) - string(TOUPPER ${dep} cmake_dep_upper) - if (NOT ${dep}_FOUND AND NOT ${cmake_dep_upper}_FOUND) - set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency ${dep} could not be found.") - set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False) - return() - endif() - set(cmake_fd_version) - set(cmake_fd_required_arg) - set(cmake_fd_quiet_arg) - set(cmake_fd_exact_arg) - endif() - endmacro() -endif() - -find_dependency(debug_assert) - -include( "${CMAKE_CURRENT_LIST_DIR}/type_safe-targets.cmake" ) - -set( type_safe_LIBRARY type_safe) -set( type_safe_LIBRARIES type_safe) \ No newline at end of file diff --git a/third/yaml-cpp/.clang-format b/third/yaml-cpp/.clang-format deleted file mode 100644 index d6d46fb4..00000000 --- a/third/yaml-cpp/.clang-format +++ /dev/null @@ -1,47 +0,0 @@ ---- -# BasedOnStyle: Google -AccessModifierOffset: -1 -ConstructorInitializerIndentWidth: 4 -AlignEscapedNewlinesLeft: true -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakTemplateDeclarations: true -AlwaysBreakBeforeMultilineStrings: true -BreakBeforeBinaryOperators: false -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BinPackParameters: true -ColumnLimit: 80 -ConstructorInitializerAllOnOneLineOrOnePerLine: true -DerivePointerBinding: true -ExperimentalAutoDetectBinPacking: false -IndentCaseLabels: true -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCSpaceBeforeProtocolList: false -PenaltyBreakBeforeFirstCallParameter: 1 -PenaltyBreakComment: 60 -PenaltyBreakString: 1000 -PenaltyBreakFirstLessLess: 120 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 200 -PointerBindsToType: true -SpacesBeforeTrailingComments: 2 -Cpp11BracedListStyle: true -Standard: Cpp11 -IndentWidth: 2 -TabWidth: 8 -UseTab: Never -BreakBeforeBraces: Attach -IndentFunctionDeclarationAfterType: true -SpacesInParentheses: false -SpacesInAngles: false -SpaceInEmptyParentheses: false -SpacesInCStyleCastParentheses: false -SpaceAfterControlStatementKeyword: true -SpaceBeforeAssignmentOperators: true -ContinuationIndentWidth: 4 -... - diff --git a/third/yaml-cpp/.codedocs b/third/yaml-cpp/.codedocs deleted file mode 100644 index 02e43821..00000000 --- a/third/yaml-cpp/.codedocs +++ /dev/null @@ -1,50 +0,0 @@ -# CodeDocs.xyz Configuration File - -# Optional project name, if left empty the GitHub repository name will be used. -PROJECT_NAME = - -# One or more directories and files that contain example code to be included. -EXAMPLE_PATH = - -# One or more directories and files to exclude from documentation generation. -# Use relative paths with respect to the repository root directory. -EXCLUDE = test/gtest-1.8.0/ - -# One or more wildcard patterns to exclude files and directories from document -# generation. -EXCLUDE_PATTERNS = - -# One or more symbols to exclude from document generation. Symbols can be -# namespaces, classes, or functions. -EXCLUDE_SYMBOLS = - -# Override the default parser (language) used for each file extension. -EXTENSION_MAPPING = - -# Set the wildcard patterns used to filter out the source-files. -# If left blank the default is: -# *.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, -# *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. -FILE_PATTERNS = - -# Hide undocumented class members. -HIDE_UNDOC_MEMBERS = - -# Hide undocumented classes. -HIDE_UNDOC_CLASSES = - -# Specify a markdown page whose contents should be used as the main page -# (index.html). This will override a page marked as \mainpage. For example, a -# README.md file usually serves as a useful main page. -USE_MDFILE_AS_MAINPAGE = README.md - -# Specify external repository to link documentation with. -# This is similar to Doxygen's TAGFILES option, but will automatically link to -# tags of other repositories already using CodeDocs. List each repository to -# link with by giving its location in the form of owner/repository. -# For example: -# TAGLINKS = doxygen/doxygen CodeDocs/osg -# Note: these repositories must already be built on CodeDocs. -TAGLINKS = diff --git a/third/yaml-cpp/.github/workflows/build.yml b/third/yaml-cpp/.github/workflows/build.yml deleted file mode 100644 index a408a9df..00000000 --- a/third/yaml-cpp/.github/workflows/build.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Github PR -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - workflow_dispatch: -permissions: read-all -jobs: - cmake-build: - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - build: [static, shared] - generator: ["Default Generator", "MinGW Makefiles"] - exclude: - - os: macos-latest - build: shared - - os: macos-latest - generator: "MinGW Makefiles" - - os: ubuntu-latest - generator: "MinGW Makefiles" - env: - YAML_BUILD_SHARED_LIBS: ${{ matrix.build == 'shared' && 'ON' || 'OFF' }} - YAML_CPP_BUILD_TESTS: 'ON' - CMAKE_GENERATOR: >- - ${{format(matrix.generator != 'Default Generator' && '-G "{0}"' || '', matrix.generator)}} - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - - - name: Get number of CPU cores - uses: SimenB/github-actions-cpu-cores@v1 - - - name: Build - shell: bash - run: | - cmake ${{ env.CMAKE_GENERATOR }} -S "${{ github.workspace }}" -B build -DYAML_BUILD_SHARED_LIBS=${{ env.YAML_BUILD_SHARED_LIBS }} - cd build && cmake --build . --parallel ${{ steps.cpu-cores.outputs.count }} - - - name: Build Tests - shell: bash - run: | - cmake ${{ env.CMAKE_GENERATOR }} -S "${{ github.workspace }}" -B build -DYAML_BUILD_SHARED_LIBS=${{ env.YAML_BUILD_SHARED_LIBS }} -DYAML_CPP_BUILD_TESTS=${{ env.YAML_CPP_BUILD_TESTS }} - cd build && cmake --build . --parallel ${{ steps.cpu-cores.outputs.count }} - - - name: Run Tests - shell: bash - run: | - cd build && ctest -C Debug --output-on-failure --verbose - - bazel-build: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - - - name: Build - shell: bash - run: | - cd "${{ github.workspace }}" - bazel build :all - - - name: Test - shell: bash - run: | - cd "${{ github.workspace }}" - bazel test test - diff --git a/third/yaml-cpp/.gitignore b/third/yaml-cpp/.gitignore deleted file mode 100644 index 2f9d10f0..00000000 --- a/third/yaml-cpp/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -build/ -/tags -/bazel-* diff --git a/third/yaml-cpp/BUILD.bazel b/third/yaml-cpp/BUILD.bazel deleted file mode 100644 index 23e847e7..00000000 --- a/third/yaml-cpp/BUILD.bazel +++ /dev/null @@ -1,21 +0,0 @@ -yaml_cpp_defines = select({ - # On Windows, ensure static linking is used. - "@platforms//os:windows": ["YAML_CPP_STATIC_DEFINE", "YAML_CPP_NO_CONTRIB"], - "//conditions:default": [], -}) - -cc_library( - name = "yaml-cpp_internal", - visibility = ["//:__subpackages__"], - strip_include_prefix = "src", - hdrs = glob(["src/**/*.h"]), -) - -cc_library( - name = "yaml-cpp", - visibility = ["//visibility:public"], - includes = ["include"], - hdrs = glob(["include/**/*.h"]), - srcs = glob(["src/**/*.cpp", "src/**/*.h"]), - defines = yaml_cpp_defines, -) diff --git a/third/yaml-cpp/CMakeLists.txt b/third/yaml-cpp/CMakeLists.txt deleted file mode 100644 index e02a73e0..00000000 --- a/third/yaml-cpp/CMakeLists.txt +++ /dev/null @@ -1,199 +0,0 @@ -# CMake 4.0 and above no longer support compatibility with versions earlier than 3.5 -cmake_minimum_required(VERSION 3.5) - -# enable MSVC_RUNTIME_LIBRARY target property -# see https://cmake.org/cmake/help/latest/policy/CMP0091.html -if(POLICY CMP0091) - cmake_policy(SET CMP0091 NEW) -endif() - -project(YAML_CPP VERSION 0.8.0 LANGUAGES CXX) - -set(YAML_CPP_MAIN_PROJECT OFF) -if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) - set(YAML_CPP_MAIN_PROJECT ON) -endif() - -include(CMakePackageConfigHelpers) -include(CMakeDependentOption) -include(CheckCXXCompilerFlag) -include(GNUInstallDirs) -include(CTest) - -option(YAML_CPP_BUILD_CONTRIB "Enable yaml-cpp contrib in library" ON) -option(YAML_CPP_BUILD_TOOLS "Enable parse tools" ON) -option(YAML_BUILD_SHARED_LIBS "Build yaml-cpp shared library" ${BUILD_SHARED_LIBS}) -option(YAML_CPP_INSTALL "Enable generation of yaml-cpp install targets" ${YAML_CPP_MAIN_PROJECT}) -option(YAML_CPP_FORMAT_SOURCE "Format source" ON) -cmake_dependent_option(YAML_CPP_BUILD_TESTS - "Enable yaml-cpp tests" OFF - "BUILD_TESTING;YAML_CPP_MAIN_PROJECT" OFF) -cmake_dependent_option(YAML_MSVC_SHARED_RT - "MSVC: Build yaml-cpp with shared runtime libs (/MD)" ON - "CMAKE_SYSTEM_NAME MATCHES Windows" OFF) - -if (YAML_CPP_FORMAT_SOURCE) - find_program(YAML_CPP_CLANG_FORMAT_EXE NAMES clang-format) -endif() - -if (YAML_BUILD_SHARED_LIBS) - set(yaml-cpp-type SHARED) - set(yaml-cpp-label-postfix "shared") -else() - set(yaml-cpp-type STATIC) - set(yaml-cpp-label-postfix "static") -endif() - -set(build-shared $) -set(build-windows-dll $,${build-shared}>) -set(not-msvc $>) -set(msvc-shared_rt $) - -if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) - set(CMAKE_MSVC_RUNTIME_LIBRARY - MultiThreaded$<$:Debug>$<${msvc-shared_rt}:DLL>) -endif() - -set(contrib-pattern "src/contrib/*.cpp") -set(src-pattern "src/*.cpp") -if (CMAKE_VERSION VERSION_GREATER 3.12) - list(INSERT contrib-pattern 0 CONFIGURE_DEPENDS) - list(INSERT src-pattern 0 CONFIGURE_DEPENDS) -endif() - -file(GLOB yaml-cpp-contrib-sources ${contrib-pattern}) -file(GLOB yaml-cpp-sources ${src-pattern}) - -set(msvc-rt $) - -set(msvc-rt-mtd-static $) -set(msvc-rt-mt-static $) - -set(msvc-rt-mtd-dll $) -set(msvc-rt-mt-dll $) - -set(backport-msvc-runtime $) - -add_library(yaml-cpp ${yaml-cpp-type} "") -add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp) - -set_property(TARGET yaml-cpp - PROPERTY - MSVC_RUNTIME_LIBRARY ${CMAKE_MSVC_RUNTIME_LIBRARY}) -set_property(TARGET yaml-cpp - PROPERTY - CXX_STANDARD_REQUIRED ON) - -if (NOT YAML_BUILD_SHARED_LIBS) - set_property(TARGET yaml-cpp PROPERTY POSITION_INDEPENDENT_CODE ON) -endif() - -target_include_directories(yaml-cpp - PUBLIC - $ - $ - PRIVATE - $) - -if (NOT DEFINED CMAKE_CXX_STANDARD) - set_target_properties(yaml-cpp - PROPERTIES - CXX_STANDARD 11) -endif() - -if(YAML_CPP_MAIN_PROJECT) - target_compile_options(yaml-cpp - PRIVATE - $<${not-msvc}:-Wall -Wextra -Wshadow -Weffc++ -Wno-long-long> - $<${not-msvc}:-pedantic -pedantic-errors>) -endif() - -target_compile_options(yaml-cpp - PRIVATE - $<$:-MTd> - $<$:-MT> - $<$:-MDd> - $<$:-MD> - - # /wd4127 = disable warning C4127 "conditional expression is constant" - # http://msdn.microsoft.com/en-us/library/6t66728h.aspx - # /wd4355 = disable warning C4355 "'this' : used in base member initializer list - # http://msdn.microsoft.com/en-us/library/3c594ae3.aspx - $<$:/W3 /wd4127 /wd4355>) - -target_compile_definitions(yaml-cpp - PUBLIC - $<$>:YAML_CPP_STATIC_DEFINE> - PRIVATE - $<${build-windows-dll}:${PROJECT_NAME}_DLL> - $<$>:YAML_CPP_NO_CONTRIB>) - -target_sources(yaml-cpp - PRIVATE - $<$:${yaml-cpp-contrib-sources}> - ${yaml-cpp-sources}) - -if (NOT DEFINED CMAKE_DEBUG_POSTFIX) - set(CMAKE_DEBUG_POSTFIX "d") -endif() - -set_target_properties(yaml-cpp PROPERTIES - VERSION "${PROJECT_VERSION}" - SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}" - PROJECT_LABEL "yaml-cpp ${yaml-cpp-label-postfix}" - DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}") - -set(CONFIG_EXPORT_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/yaml-cpp") -set(EXPORT_TARGETS yaml-cpp) -configure_package_config_file( - "${PROJECT_SOURCE_DIR}/yaml-cpp-config.cmake.in" - "${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake" - INSTALL_DESTINATION "${CONFIG_EXPORT_DIR}" - PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR CONFIG_EXPORT_DIR YAML_BUILD_SHARED_LIBS) -unset(EXPORT_TARGETS) - -write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake" - COMPATIBILITY AnyNewerVersion) - -configure_file(yaml-cpp.pc.in yaml-cpp.pc @ONLY) - -if (YAML_CPP_INSTALL) - install(TARGETS yaml-cpp - EXPORT yaml-cpp-targets - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) - install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING PATTERN "*.h") - install(EXPORT yaml-cpp-targets - NAMESPACE yaml-cpp:: - DESTINATION "${CONFIG_EXPORT_DIR}") - install(FILES - "${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake" - "${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake" - DESTINATION "${CONFIG_EXPORT_DIR}") - install(FILES "${PROJECT_BINARY_DIR}/yaml-cpp.pc" - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) -endif() -unset(CONFIG_EXPORT_DIR) - -if (YAML_CPP_FORMAT_SOURCE AND YAML_CPP_CLANG_FORMAT_EXE) - add_custom_target(format - COMMAND clang-format --style=file -i $ - COMMAND_EXPAND_LISTS - COMMENT "Running clang-format" - VERBATIM) -endif() - -# uninstall target -if(NOT TARGET uninstall) - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - IMMEDIATE @ONLY) - - add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) -endif() diff --git a/third/yaml-cpp/CONTRIBUTING.md b/third/yaml-cpp/CONTRIBUTING.md deleted file mode 100644 index 5705fe2b..00000000 --- a/third/yaml-cpp/CONTRIBUTING.md +++ /dev/null @@ -1,26 +0,0 @@ -# Style - -This project is formatted with [clang-format][fmt] using the style file at the root of the repository. Please run clang-format before sending a pull request. - -In general, try to follow the style of surrounding code. We mostly follow the [Google C++ style guide][cpp-style]. - -Commit messages should be in the imperative mood, as described in the [Git contributing file][git-contrib]: - -> Describe your changes in imperative mood, e.g. "make xyzzy do frotz" -> instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy -> to do frotz", as if you are giving orders to the codebase to change -> its behaviour. - -[fmt]: http://clang.llvm.org/docs/ClangFormat.html -[cpp-style]: https://google.github.io/styleguide/cppguide.html -[git-contrib]: http://git.kernel.org/cgit/git/git.git/tree/Documentation/SubmittingPatches?id=HEAD - -# Tests - -Please verify the tests pass by running the target `test/yaml-cpp-tests`. - -If you are adding functionality, add tests accordingly. - -# Pull request process - -Every pull request undergoes a code review. Unfortunately, github's code review process isn't great, but we'll manage. During the code review, if you make changes, add new commits to the pull request for each change. Once the code review is complete, rebase against the master branch and squash into a single commit. diff --git a/third/yaml-cpp/LICENSE b/third/yaml-cpp/LICENSE deleted file mode 100644 index 991fdbbe..00000000 --- a/third/yaml-cpp/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2008-2015 Jesse Beder. - -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/yaml-cpp/README.md b/third/yaml-cpp/README.md deleted file mode 100644 index 70c23144..00000000 --- a/third/yaml-cpp/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# yaml-cpp ![Build Status](https://github.com/jbeder/yaml-cpp/actions/workflows/build.yml/badge.svg) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/) - -`yaml-cpp` is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html). - -## Usage - -See [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) and [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML) for reference. For the old API (until 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)). - -## Any Problems? - -If you find a bug, post an [issue](https://github.com/jbeder/yaml-cpp/issues)! If you have questions about how to use yaml-cpp, please post it on http://stackoverflow.com and tag it [`yaml-cpp`](http://stackoverflow.com/questions/tagged/yaml-cpp). - -## How to Build - -`yaml-cpp` uses [CMake](http://www.cmake.org) to support cross-platform building. Install [CMake](http://www.cmake.org) _(Resources -> Download)_ before proceeding. The basic steps to build are: - -**Note:** If you don't use the provided installer for your platform, make sure that you add `CMake`'s bin folder to your path. - -#### 1. Navigate into the source directory, create build folder and run `CMake`: - -```sh -mkdir build -cd build -cmake [-G generator] [-DYAML_BUILD_SHARED_LIBS=on|OFF] .. -``` - - * The `generator` option is the build system you'd like to use. Run `cmake` without arguments to see a full list of available generators. - * On Windows, you might use "Visual Studio 12 2013" (VS 2013 32-bits), or "Visual Studio 14 2015 Win64" (VS 2015 64-bits). - * On OS X, you might use "Xcode". - * On a UNIX-like system, omit the option (for a Makefile). - - * `yaml-cpp` builds a static library by default, you may want to build a shared library by specifying `-DYAML_BUILD_SHARED_LIBS=ON`. - - * For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file. - -#### 2. Build it! - * The command you'll need to run depends on the generator you chose earlier. - -**Note:** To clean up, just remove the `build` directory. - -## Recent Releases - -[yaml-cpp 0.6.0](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.6.0) released! This release requires C++11, and no longer depends on Boost. - -[yaml-cpp 0.3.0](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.3.0) is still available if you want the old API. - -**The old API will continue to be supported, and will still receive bugfixes!** The 0.3.x and 0.4.x versions will be old API releases, and 0.5.x and above will all be new API releases. - -# API Documentation - -The autogenerated API reference is hosted on [CodeDocs](https://codedocs.xyz/jbeder/yaml-cpp/index.html) - -# Third Party Integrations - -The following projects are not officially supported: - -- [Qt wrapper](https://gist.github.com/brcha/d392b2fe5f1e427cc8a6) -- [UnrealEngine Wrapper](https://github.com/jwindgassen/UnrealYAML) diff --git a/third/yaml-cpp/SECURITY.md b/third/yaml-cpp/SECURITY.md deleted file mode 100644 index 06a17511..00000000 --- a/third/yaml-cpp/SECURITY.md +++ /dev/null @@ -1,13 +0,0 @@ -# Security Policy - -## Supported Versions - -Security updates are applied only to the latest release. - -## Reporting a Vulnerability - -If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released. - -Please disclose it at [security advisory](https://github.com/jbeder/yaml-cpp/security/advisories/new). - -This project is maintained by a team of volunteers on a reasonable-effort basis. As such, vulnerabilities will be disclosed in a best effort base. diff --git a/third/yaml-cpp/WORKSPACE b/third/yaml-cpp/WORKSPACE deleted file mode 100644 index d5ecc0b5..00000000 --- a/third/yaml-cpp/WORKSPACE +++ /dev/null @@ -1,10 +0,0 @@ -workspace(name = "com_github_jbeder_yaml_cpp") - -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "com_google_googletest", - strip_prefix = "googletest-release-1.8.1", - url = "https://github.com/google/googletest/archive/release-1.8.1.tar.gz", - sha256 = "9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c", -) diff --git a/third/yaml-cpp/cmake_uninstall.cmake.in b/third/yaml-cpp/cmake_uninstall.cmake.in deleted file mode 100644 index c2d34d47..00000000 --- a/third/yaml-cpp/cmake_uninstall.cmake.in +++ /dev/null @@ -1,21 +0,0 @@ -if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") - message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") -endif() - -file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) -string(REGEX REPLACE "\n" ";" files "${files}") -foreach(file ${files}) - message(STATUS "Uninstalling $ENV{DESTDIR}${file}") - if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" - OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval - ) - if(NOT "${rm_retval}" STREQUAL 0) - message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") - endif() - else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - message(STATUS "File $ENV{DESTDIR}${file} does not exist.") - endif() -endforeach() diff --git a/third/yaml-cpp/docs/Breaking-Changes.md b/third/yaml-cpp/docs/Breaking-Changes.md deleted file mode 100644 index 959adea2..00000000 --- a/third/yaml-cpp/docs/Breaking-Changes.md +++ /dev/null @@ -1,52 +0,0 @@ -# The following is a list of breaking changes to yaml-cpp, by version # - -# New API # - -## HEAD ## - - * Throws an exception when trying to parse a negative number as an unsigned integer. - * Supports the `as`/`as`, which throws an exception when the value exceeds the range of `int8_t`/`uint8_t`. - -## 0.6.0 ## - - * Requires C++11. - -## 0.5.3 ## - -_none_ - -## 0.5.2 ## - -_none_ - -## 0.5.1 ## - - * `Node::clear` was replaced by `Node::reset`, which takes an optional node, similar to smart pointers. - -## 0.5.0 ## - -Initial version of the new API. - -# Old API # - -## 0.3.0 ## - -_none_ - -## 0.2.7 ## - - * `YAML::Binary` now takes `const unsigned char *` for the binary data (instead of `const char *`). - -## 0.2.6 ## - - * `Node::GetType()` is now `Node::Type()`, and returns an enum `NodeType::value`, where: -> > ` struct NodeType { enum value { Null, Scalar, Sequence, Map }; }; ` - * `Node::GetTag()` is now `Node::Tag()` - * `Node::Identity()` is removed, and `Node::IsAlias()` and `Node::IsReferenced()` have been merged into `Node::IsAliased()`. The reason: there's no reason to distinguish an alias node from its anchor - whichever happens to be emitted first will be the anchor, and the rest will be aliases. - * `Node::Read` is now `Node::to`. This wasn't a documented function, so it shouldn't break anything. - * `Node`'s comparison operators (for example, `operator == (const Node&, const T&)`) have all been removed. These weren't documented either (they were just used for the tests), so this shouldn't break anything either. - * The emitter no longer produces the document start by default - if you want it, you can supply it with the manipulator `YAML::BeginDoc`. - -## 0.2.5 ## - -This wiki was started with v0.2.5. \ No newline at end of file diff --git a/third/yaml-cpp/docs/How-To-Emit-YAML.md b/third/yaml-cpp/docs/How-To-Emit-YAML.md deleted file mode 100644 index 93407019..00000000 --- a/third/yaml-cpp/docs/How-To-Emit-YAML.md +++ /dev/null @@ -1,230 +0,0 @@ -## Contents ## - - - -# Basic Emitting # - -The model for emitting YAML is `std::ostream` manipulators. A `YAML::Emitter` objects acts as an output stream, and its output can be retrieved through the `c_str()` function (as in `std::string`). For a simple example: - -```cpp -#include "yaml-cpp/yaml.h" - -int main() -{ - YAML::Emitter out; - out << "Hello, World!"; - - std::cout << "Here's the output YAML:\n" << out.c_str(); // prints "Hello, World!" - return 0; -} -``` - -# Simple Lists and Maps # - -A `YAML::Emitter` object acts as a state machine, and we use manipulators to move it between states. Here's a simple sequence: - -```cpp -YAML::Emitter out; -out << YAML::BeginSeq; -out << "eggs"; -out << "bread"; -out << "milk"; -out << YAML::EndSeq; -``` - -produces - -```yaml -- eggs -- bread -- milk -``` - -A simple map: - -```cpp -YAML::Emitter out; -out << YAML::BeginMap; -out << YAML::Key << "name"; -out << YAML::Value << "Ryan Braun"; -out << YAML::Key << "position"; -out << YAML::Value << "LF"; -out << YAML::EndMap; -``` - -produces - -```yaml -name: Ryan Braun -position: LF -``` - -These elements can, of course, be nested: - -```cpp -YAML::Emitter out; -out << YAML::BeginMap; -out << YAML::Key << "name"; -out << YAML::Value << "Barack Obama"; -out << YAML::Key << "children"; -out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq; -out << YAML::EndMap; -``` - -produces - -```yaml -name: Barack Obama -children: - - Sasha - - Malia -``` - -# Using Manipulators # - -To deviate from standard formatting, you can use manipulators to modify the output format. For example, - -```cpp -YAML::Emitter out; -out << YAML::Literal << "A\n B\n C"; -``` - -produces - -```yaml -| -A - B - C -``` -and - -```cpp -YAML::Emitter out; -out << YAML::Flow; -out << YAML::BeginSeq << 2 << 3 << 5 << 7 << 11 << YAML::EndSeq; -``` - -produces - -```yaml -[2, 3, 5, 7, 11] -``` - -Comments act like manipulators: - -```cpp -YAML::Emitter out; -out << YAML::BeginMap; -out << YAML::Key << "method"; -out << YAML::Value << "least squares"; -out << YAML::Comment("should we change this method?"); -out << YAML::EndMap; -``` - -produces - -```yaml -method: least squares # should we change this method? -``` - -And so do aliases/anchors: - -```cpp -YAML::Emitter out; -out << YAML::BeginSeq; -out << YAML::Anchor("fred"); -out << YAML::BeginMap; -out << YAML::Key << "name" << YAML::Value << "Fred"; -out << YAML::Key << "age" << YAML::Value << "42"; -out << YAML::EndMap; -out << YAML::Alias("fred"); -out << YAML::EndSeq; -``` - -produces - -```yaml -- &fred - name: Fred - age: 42 -- *fred -``` - -# STL Containers, and Other Overloads # -We overload `operator <<` for `std::vector`, `std::list`, and `std::map`, so you can write stuff like: - -```cpp -std::vector squares; -squares.push_back(1); -squares.push_back(4); -squares.push_back(9); -squares.push_back(16); - -std::map ages; -ages["Daniel"] = 26; -ages["Jesse"] = 24; - -YAML::Emitter out; -out << YAML::BeginSeq; -out << YAML::Flow << squares; -out << ages; -out << YAML::EndSeq; -``` - -produces - -```yaml -- [1, 4, 9, 16] -- - Daniel: 26 - Jesse: 24 -``` - -Of course, you can overload `operator <<` for your own types: - -```cpp -struct Vec3 { int x; int y; int z; }; -YAML::Emitter& operator << (YAML::Emitter& out, const Vec3& v) { - out << YAML::Flow; - out << YAML::BeginSeq << v.x << v.y << v.z << YAML::EndSeq; - return out; -} -``` -and it'll play nicely with everything else. - -# Using Existing Nodes # - -We also overload `operator << ` for `YAML::Node`s in both APIs, so you can output existing Nodes. Of course, Nodes in the old API are read-only, so it's tricky to emit them if you want to modify them. So use the new API! - -# Output Encoding # - -The output is always UTF-8. By default, yaml-cpp will output as much as it can without escaping any characters. If you want to restrict the output to ASCII, use the manipulator `YAML::EscapeNonAscii`: - -```cpp -emitter.SetOutputCharset(YAML::EscapeNonAscii); -``` - -# Lifetime of Manipulators # - -Manipulators affect the **next** output item in the stream. If that item is a `BeginSeq` or `BeginMap`, the manipulator lasts until the corresponding `EndSeq` or `EndMap`. (However, within that sequence or map, you can override the manipulator locally, etc.; in effect, there's a "manipulator stack" behind the scenes.) - -If you want to permanently change a setting, there are global setters corresponding to each manipulator, e.g.: - -```cpp -YAML::Emitter out; -out.SetIndent(4); -out.SetMapStyle(YAML::Flow); -``` - -# When Something Goes Wrong # - -If something goes wrong when you're emitting a document, it must be something like forgetting a `YAML::EndSeq`, or a misplaced `YAML::Key`. In this case, emitting silently fails (no more output is emitted) and an error flag is set. For example: - -```cpp -YAML::Emitter out; -assert(out.good()); -out << YAML::Key; -assert(!out.good()); -std::cout << "Emitter error: " << out.GetLastError() << "\n"; -``` \ No newline at end of file diff --git a/third/yaml-cpp/docs/How-To-Parse-A-Document-(Old-API).md b/third/yaml-cpp/docs/How-To-Parse-A-Document-(Old-API).md deleted file mode 100644 index 82fac718..00000000 --- a/third/yaml-cpp/docs/How-To-Parse-A-Document-(Old-API).md +++ /dev/null @@ -1,265 +0,0 @@ -_The following describes the old API. For the new API, see the [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial)._ - -## Contents ## - - -# Basic Parsing # - -The parser accepts streams, not file names, so you need to first load the file. Since a YAML file can contain many documents, you can grab them one-by-one. A simple way to parse a YAML file might be: - -``` -#include -#include "yaml-cpp/yaml.h" - -int main() -{ - std::ifstream fin("test.yaml"); - YAML::Parser parser(fin); - - YAML::Node doc; - while(parser.GetNextDocument(doc)) { - // ... - } - - return 0; -} -``` - -# Reading From the Document # - -Suppose we have a document consisting only of a scalar. We can read that scalar like this: - -``` -YAML::Node doc; // let's say we've already parsed this document -std::string scalar; -doc >> scalar; -std::cout << "That scalar was: " << scalar << std::endl; -``` - -How about sequences? Let's say our document now consists only of a sequences of scalars. We can use an iterator: - -``` -YAML::Node doc; // already parsed -for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { - std::string scalar; - *it >> scalar; - std::cout << "Found scalar: " << scalar << std::endl; -} -``` - -... or we can just loop through: - -``` -YAML::Node doc; // already parsed -for(unsigned i=0;i> scalar; - std::cout << "Found scalar: " << scalar << std::endl; -} -``` - -And finally maps. For now, let's say our document is a map with all keys/values being scalars. Again, we can iterate: - -``` -YAML::Node doc; // already parsed -for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { - std::string key, value; - it.first() >> key; - it.second() >> value; - std::cout << "Key: " << key << ", value: " << value << std::endl; -} -``` - -Note that dereferencing a map iterator is undefined; instead, use the `first` and `second` methods to get the key and value nodes, respectively. - -Alternatively, we can pick off the values one-by-one, if we know the keys: - -``` -YAML::Node doc; // already parsed -std::string name; -doc["name"] >> name; -int age; -doc["age"] >> age; -std::cout << "Found entry with name '" << name << "' and age '" << age << "'\n"; -``` - -One thing to be keep in mind: reading a map by key (as immediately above) requires looping through all entries until we find the right key, which is an O(n) operation. So if you're reading the entire map this way, it'll be O(n^2). For small n, this isn't a big deal, but I wouldn't recommend reading maps with a very large number of entries (>100, say) this way. - -## Optional Keys ## - -If you try to access a key that doesn't exist, `yaml-cpp` throws an exception (see [When Something Goes Wrong](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)#When_Something_Goes_Wrong). If you have optional keys, it's often easier to use `FindValue` instead of `operator[]`: - -``` -YAML::Node doc; // already parsed -if(const YAML::Node *pName = doc.FindValue("name")) { - std::string name; - *pName >> name; - std::cout << "Key 'name' exists, with value '" << name << "'\n"; -} else { - std::cout << "Key 'name' doesn't exist\n"; -} -``` - -# Getting More Complicated # - -The above three methods can be combined to read from an arbitrary document. But we can make life a lot easier. Suppose we're reading 3-vectors (i.e., vectors with three components), so we've got a structure looking like this: - -``` -struct Vec3 { - float x, y, z; -}; -``` - -We can read this in one operation by overloading the extraction (>>) operator: - -``` -void operator >> (const YAML::Node& node, Vec3& v) -{ - node[0] >> v.x; - node[1] >> v.y; - node[2] >> v.z; -} - -// now it's a piece of cake to read it -YAML::Node doc; // already parsed -Vec3 v; -doc >> v; -std::cout << "Here's the vector: (" << v.x << ", " << v.y << ", " << v.z << ")\n"; -``` - -# A Complete Example # - -Here's a complete example of how to parse a complex YAML file: - -`monsters.yaml` - -``` -- name: Ogre - position: [0, 5, 0] - powers: - - name: Club - damage: 10 - - name: Fist - damage: 8 -- name: Dragon - position: [1, 0, 10] - powers: - - name: Fire Breath - damage: 25 - - name: Claws - damage: 15 -- name: Wizard - position: [5, -3, 0] - powers: - - name: Acid Rain - damage: 50 - - name: Staff - damage: 3 -``` - -`main.cpp` - -``` -#include "yaml-cpp/yaml.h" -#include -#include -#include -#include - -// our data types -struct Vec3 { - float x, y, z; -}; - -struct Power { - std::string name; - int damage; -}; - -struct Monster { - std::string name; - Vec3 position; - std::vector powers; -}; - -// now the extraction operators for these types -void operator >> (const YAML::Node& node, Vec3& v) { - node[0] >> v.x; - node[1] >> v.y; - node[2] >> v.z; -} - -void operator >> (const YAML::Node& node, Power& power) { - node["name"] >> power.name; - node["damage"] >> power.damage; -} - -void operator >> (const YAML::Node& node, Monster& monster) { - node["name"] >> monster.name; - node["position"] >> monster.position; - const YAML::Node& powers = node["powers"]; - for(unsigned i=0;i> power; - monster.powers.push_back(power); - } -} - -int main() -{ - std::ifstream fin("monsters.yaml"); - YAML::Parser parser(fin); - YAML::Node doc; - parser.GetNextDocument(doc); - for(unsigned i=0;i> monster; - std::cout << monster.name << "\n"; - } - - return 0; -} -``` - -# When Something Goes Wrong # - -... we throw an exception (all exceptions are derived from `YAML::Exception`). If there's a parsing exception (i.e., a malformed YAML document), we throw a `YAML::ParserException`: - -``` -try { - std::ifstream fin("test.yaml"); - YAML::Parser parser(fin); - YAML::Node doc; - parser.GetNextDocument(doc); - // do stuff -} catch(YAML::ParserException& e) { - std::cout << e.what() << "\n"; -} -``` - -If you make a programming error (say, trying to read a scalar from a sequence node, or grabbing a key that doesn't exist), we throw some kind of `YAML::RepresentationException`. To prevent this, you can check what kind of node something is: - -``` - YAML::Node node; - YAML::NodeType::value type = node.Type(); // should be: - // YAML::NodeType::Null - // YAML::NodeType::Scalar - // YAML::NodeType::Sequence - // YAML::NodeType::Map -``` - -# Note about copying `YAML::Node` # - -Currently `YAML::Node` is non-copyable, so you need to do something like - -``` - const YAML::Node& node = doc["whatever"]; -``` - -This is intended behavior. If you want to copy a node, use the `Clone` function: - -``` - std::auto_ptr pCopy = myOtherNode.Clone(); -``` - -The intent is that if you'd like to keep a `YAML::Node` around for longer than the document will stay in scope, you can clone it and store it as long as you like. \ No newline at end of file diff --git a/third/yaml-cpp/docs/Strings.md b/third/yaml-cpp/docs/Strings.md deleted file mode 100644 index f2328a1b..00000000 --- a/third/yaml-cpp/docs/Strings.md +++ /dev/null @@ -1,18 +0,0 @@ -# Encodings and `yaml-cpp` # - -`yaml-cpp` will parse any file as specified by the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html#id2570322). Internally, it stores all strings in UTF-8, and representation is done with UTF-8. This means that in - -``` -std::string str; -node >> str; -``` - -`str` will be UTF-8. Similarly, if you're accessing a map by string key, you need to pass the key in UTF-8. If your application uses a different encoding, you need to convert to and from UTF-8 to work with `yaml-cpp`. (It's possible we'll add some small conversion functions, but for now it's restricted.) - ---- - -For convenience, Richard Weeks has kindly provided a google gadget that converts Unicode to a string literal. It's a Google Gadget, so unfortunately it does not work on GitHub. Patches welcome to port it to a usable format here: - -``` - -``` \ No newline at end of file diff --git a/third/yaml-cpp/docs/Tutorial.md b/third/yaml-cpp/docs/Tutorial.md deleted file mode 100644 index a7b0e21d..00000000 --- a/third/yaml-cpp/docs/Tutorial.md +++ /dev/null @@ -1,201 +0,0 @@ -# Introduction # - -A typical example, loading a configuration file, might look like this: - -```cpp -YAML::Node config = YAML::LoadFile("config.yaml"); - -if (config["lastLogin"]) { - std::cout << "Last logged in: " << config["lastLogin"].as() << "\n"; -} - -const std::string username = config["username"].as(); -const std::string password = config["password"].as(); -login(username, password); -config["lastLogin"] = getCurrentDateTime(); - -std::ofstream fout("config.yaml"); -fout << config; -``` - -# Basic Parsing and Node Editing # - -All nodes in a YAML document (including the root) are represented by `YAML::Node`. You can check what kind it is: - -```cpp -YAML::Node node = YAML::Load("[1, 2, 3]"); -assert(node.Type() == YAML::NodeType::Sequence); -assert(node.IsSequence()); // a shortcut! -``` - -Collection nodes (sequences and maps) act somewhat like STL vectors and maps: - -```cpp -YAML::Node primes = YAML::Load("[2, 3, 5, 7, 11]"); -for (std::size_t i=0;i() << "\n"; -} -// or: -for (YAML::const_iterator it=primes.begin();it!=primes.end();++it) { - std::cout << it->as() << "\n"; -} - -primes.push_back(13); -assert(primes.size() == 6); -``` - -and - -```cpp -YAML::Node lineup = YAML::Load("{1B: Prince Fielder, 2B: Rickie Weeks, LF: Ryan Braun}"); -for(YAML::const_iterator it=lineup.begin();it!=lineup.end();++it) { - std::cout << "Playing at " << it->first.as() << " is " << it->second.as() << "\n"; -} - -lineup["RF"] = "Corey Hart"; -lineup["C"] = "Jonathan Lucroy"; -assert(lineup.size() == 5); -``` - -Querying for keys does **not** create them automatically (this makes handling optional map entries very easy) - -```cpp -YAML::Node node = YAML::Load("{name: Brewers, city: Milwaukee}"); -if (node["name"]) { - std::cout << node["name"].as() << "\n"; -} -if (node["mascot"]) { - std::cout << node["mascot"].as() << "\n"; -} -assert(node.size() == 2); // the previous call didn't create a node -``` - -If you're not sure what kind of data you're getting, you can query the type of a node: - -```cpp -switch (node.Type()) { - case Null: // ... - case Scalar: // ... - case Sequence: // ... - case Map: // ... - case Undefined: // ... -} -``` - -or ask directly whether it's a particular type, e.g.: - -```cpp -if (node.IsSequence()) { - // ... -} -``` - -# Building Nodes # - -You can build `YAML::Node` from scratch: - -```cpp -YAML::Node node; // starts out as null -node["key"] = "value"; // it now is a map node -node["seq"].push_back("first element"); // node["seq"] automatically becomes a sequence -node["seq"].push_back("second element"); - -node["mirror"] = node["seq"][0]; // this creates an alias -node["seq"][0] = "1st element"; // this also changes node["mirror"] -node["mirror"] = "element #1"; // and this changes node["seq"][0] - they're really the "same" node - -node["self"] = node; // you can even create self-aliases -node[node["mirror"]] = node["seq"]; // and strange loops :) -``` - -The above node is now: - -```yaml -&1 -key: value -&2 seq: [&3 "element #1", second element] -mirror: *3 -self: *1 -*3 : *2 -``` - -# How Sequences Turn Into Maps # - -Sequences can be turned into maps by asking for non-integer keys. For example, - -```cpp -YAML::Node node = YAML::Load("[1, 2, 3]"); -node[1] = 5; // still a sequence, [1, 5, 3] -node.push_back(-3) // still a sequence, [1, 5, 3, -3] -node["key"] = "value"; // now it's a map! {0: 1, 1: 5, 2: 3, 3: -3, key: value} -``` - -Indexing a sequence node by an index that's not in its range will _usually_ turn it into a map, but if the index is one past the end of the sequence, then the sequence will grow by one to accommodate it. (That's the **only** exception to this rule.) For example, - -```cpp -YAML::Node node = YAML::Load("[1, 2, 3]"); -node[3] = 4; // still a sequence, [1, 2, 3, 4] -node[10] = 10; // now it's a map! {0: 1, 1: 2, 2: 3, 3: 4, 10: 10} -``` - -# Converting To/From Native Data Types # - -Yaml-cpp has built-in conversion to and from most built-in data types, as well as `std::vector`, `std::list`, and `std::map`. The following examples demonstrate when those conversions are used: - -```cpp -YAML::Node node = YAML::Load("{pi: 3.14159, [0, 1]: integers}"); - -// this needs the conversion from Node to double -double pi = node["pi"].as(); - -// this needs the conversion from double to Node -node["e"] = 2.71828; - -// this needs the conversion from Node to std::vector (*not* the other way around!) -std::vector v; -v.push_back(0); -v.push_back(1); -std::string str = node[v].as(); -``` - -To use yaml-cpp with your own data types, you need to specialize the YAML::convert<> template class. For example, suppose you had a simple `Vec3` class: - -```cpp -struct Vec3 { double x, y, z; /* etc - make sure you have overloaded operator== */ }; -``` - -You could write - -```cpp -namespace YAML { -template<> -struct convert { - static Node encode(const Vec3& rhs) { - Node node; - node.push_back(rhs.x); - node.push_back(rhs.y); - node.push_back(rhs.z); - return node; - } - - static bool decode(const Node& node, Vec3& rhs) { - if(!node.IsSequence() || node.size() != 3) { - return false; - } - - rhs.x = node[0].as(); - rhs.y = node[1].as(); - rhs.z = node[2].as(); - return true; - } -}; -} -``` - -Then you could use `Vec3` wherever you could use any other type: - -```cpp -YAML::Node node = YAML::Load("start: [1, 3, 0]"); -Vec3 v = node["start"].as(); -node["end"] = Vec3(2, -1, 0); -``` \ No newline at end of file diff --git a/third/yaml-cpp/docs/_config.yml b/third/yaml-cpp/docs/_config.yml deleted file mode 100644 index c7418817..00000000 --- a/third/yaml-cpp/docs/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-slate \ No newline at end of file diff --git a/third/yaml-cpp/docs/index.md b/third/yaml-cpp/docs/index.md deleted file mode 100644 index 17f13151..00000000 --- a/third/yaml-cpp/docs/index.md +++ /dev/null @@ -1 +0,0 @@ -To learn how to use the library, see the [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) and [How To Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML) diff --git a/third/yaml-cpp/include/yaml-cpp/anchor.h b/third/yaml-cpp/include/yaml-cpp/anchor.h deleted file mode 100644 index f46d1d79..00000000 --- a/third/yaml-cpp/include/yaml-cpp/anchor.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -namespace YAML { -using anchor_t = std::size_t; -const anchor_t NullAnchor = 0; -} - -#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/binary.h b/third/yaml-cpp/include/yaml-cpp/binary.h deleted file mode 100644 index 1050dae9..00000000 --- a/third/yaml-cpp/include/yaml-cpp/binary.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -YAML_CPP_API std::string EncodeBase64(const unsigned char *data, - std::size_t size); -YAML_CPP_API std::vector DecodeBase64(const std::string &input); - -class YAML_CPP_API Binary { - public: - Binary(const unsigned char *data_, std::size_t size_) - : m_data{}, m_unownedData(data_), m_unownedSize(size_) {} - Binary() : Binary(nullptr, 0) {} - Binary(const Binary &) = default; - Binary(Binary &&) = default; - Binary &operator=(const Binary &) = default; - Binary &operator=(Binary &&) = default; - - bool owned() const { return !m_unownedData; } - std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; } - const unsigned char *data() const { - return owned() ? &m_data[0] : m_unownedData; - } - - void swap(std::vector &rhs) { - if (m_unownedData) { - m_data.swap(rhs); - rhs.clear(); - rhs.resize(m_unownedSize); - std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin()); - m_unownedData = nullptr; - m_unownedSize = 0; - } else { - m_data.swap(rhs); - } - } - - bool operator==(const Binary &rhs) const { - const std::size_t s = size(); - if (s != rhs.size()) - return false; - const unsigned char *d1 = data(); - const unsigned char *d2 = rhs.data(); - for (std::size_t i = 0; i < s; i++) { - if (*d1++ != *d2++) - return false; - } - return true; - } - - bool operator!=(const Binary &rhs) const { return !(*this == rhs); } - - private: - std::vector m_data; - const unsigned char *m_unownedData; - std::size_t m_unownedSize; -}; -} // namespace YAML - -#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/contrib/anchordict.h b/third/yaml-cpp/include/yaml-cpp/contrib/anchordict.h deleted file mode 100644 index 1b7809b8..00000000 --- a/third/yaml-cpp/include/yaml-cpp/contrib/anchordict.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "../anchor.h" - -namespace YAML { -/** - * An object that stores and retrieves values correlating to {@link anchor_t} - * values. - * - *

Efficient implementation that can make assumptions about how - * {@code anchor_t} values are assigned by the {@link Parser} class. - */ -template -class AnchorDict { - public: - AnchorDict() : m_data{} {} - void Register(anchor_t anchor, T value) { - if (anchor > m_data.size()) { - m_data.resize(anchor); - } - m_data[anchor - 1] = value; - } - - T Get(anchor_t anchor) const { return m_data[anchor - 1]; } - - private: - std::vector m_data; -}; -} // namespace YAML - -#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h b/third/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h deleted file mode 100644 index dbffd921..00000000 --- a/third/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/mark.h" -#include - -namespace YAML { -class Parser; - -// GraphBuilderInterface -// . Abstraction of node creation -// . pParentNode is always nullptr or the return value of one of the NewXXX() -// functions. -class GraphBuilderInterface { - public: - virtual ~GraphBuilderInterface() = 0; - - // Create and return a new node with a null value. - virtual void *NewNull(const Mark &mark, void *pParentNode) = 0; - - // Create and return a new node with the given tag and value. - virtual void *NewScalar(const Mark &mark, const std::string &tag, - void *pParentNode, const std::string &value) = 0; - - // Create and return a new sequence node - virtual void *NewSequence(const Mark &mark, const std::string &tag, - void *pParentNode) = 0; - - // Add pNode to pSequence. pNode was created with one of the NewXxx() - // functions and pSequence with NewSequence(). - virtual void AppendToSequence(void *pSequence, void *pNode) = 0; - - // Note that no moew entries will be added to pSequence - virtual void SequenceComplete(void *pSequence) { (void)pSequence; } - - // Create and return a new map node - virtual void *NewMap(const Mark &mark, const std::string &tag, - void *pParentNode) = 0; - - // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode - // were created with one of the NewXxx() methods and pMap with NewMap(). - virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0; - - // Note that no more assignments will be made in pMap - virtual void MapComplete(void *pMap) { (void)pMap; } - - // Return the node that should be used in place of an alias referencing - // pNode (pNode by default) - virtual void *AnchorReference(const Mark &mark, void *pNode) { - (void)mark; - return pNode; - } -}; - -// Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines -// Node, Sequence, and Map types. Sequence and Map must derive from Node -// (unless Node is defined as void). Impl must also implement function with -// all of the same names as the virtual functions in GraphBuilderInterface -// -- including the ones with default implementations -- but with the -// prototypes changed to accept an explicit Node*, Sequence*, or Map* where -// appropriate. -template -class GraphBuilder : public GraphBuilderInterface { - public: - typedef typename Impl::Node Node; - typedef typename Impl::Sequence Sequence; - typedef typename Impl::Map Map; - - GraphBuilder(Impl &impl) : m_impl(impl) { - Map *pMap = nullptr; - Sequence *pSeq = nullptr; - Node *pNode = nullptr; - - // Type consistency checks - pNode = pMap; - pNode = pSeq; - } - - GraphBuilderInterface &AsBuilderInterface() { return *this; } - - virtual void *NewNull(const Mark &mark, void *pParentNode) { - return CheckType(m_impl.NewNull(mark, AsNode(pParentNode))); - } - - virtual void *NewScalar(const Mark &mark, const std::string &tag, - void *pParentNode, const std::string &value) { - return CheckType( - m_impl.NewScalar(mark, tag, AsNode(pParentNode), value)); - } - - virtual void *NewSequence(const Mark &mark, const std::string &tag, - void *pParentNode) { - return CheckType( - m_impl.NewSequence(mark, tag, AsNode(pParentNode))); - } - virtual void AppendToSequence(void *pSequence, void *pNode) { - m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode)); - } - virtual void SequenceComplete(void *pSequence) { - m_impl.SequenceComplete(AsSequence(pSequence)); - } - - virtual void *NewMap(const Mark &mark, const std::string &tag, - void *pParentNode) { - return CheckType(m_impl.NewMap(mark, tag, AsNode(pParentNode))); - } - virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) { - m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode)); - } - virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); } - - virtual void *AnchorReference(const Mark &mark, void *pNode) { - return CheckType(m_impl.AnchorReference(mark, AsNode(pNode))); - } - - private: - Impl &m_impl; - - // Static check for pointer to T - template - static T *CheckType(U *p) { - return p; - } - - static Node *AsNode(void *pNode) { return static_cast(pNode); } - static Sequence *AsSequence(void *pSeq) { - return static_cast(pSeq); - } - static Map *AsMap(void *pMap) { return static_cast(pMap); } -}; - -void *BuildGraphOfNextDocument(Parser &parser, - GraphBuilderInterface &graphBuilder); - -template -typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) { - GraphBuilder graphBuilder(impl); - return static_cast( - BuildGraphOfNextDocument(parser, graphBuilder)); -} -} - -#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/depthguard.h b/third/yaml-cpp/include/yaml-cpp/depthguard.h deleted file mode 100644 index 8ca61ac6..00000000 --- a/third/yaml-cpp/include/yaml-cpp/depthguard.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 -#define DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "exceptions.h" - -namespace YAML { - -/** - * @brief The DeepRecursion class - * An exception class which is thrown by DepthGuard. Ideally it should be - * a member of DepthGuard. However, DepthGuard is a templated class which means - * that any catch points would then need to know the template parameters. It is - * simpler for clients to not have to know at the catch point what was the - * maximum depth. - */ -class DeepRecursion : public ParserException { -public: - virtual ~DeepRecursion() = default; - - DeepRecursion(int depth, const Mark& mark_, const std::string& msg_); - - // Returns the recursion depth when the exception was thrown - int depth() const { - return m_depth; - } - -private: - int m_depth = 0; -}; - -/** - * @brief The DepthGuard class - * DepthGuard takes a reference to an integer. It increments the integer upon - * construction of DepthGuard and decrements the integer upon destruction. - * - * If the integer would be incremented past max_depth, then an exception is - * thrown. This is ideally geared toward guarding against deep recursion. - * - * @param max_depth - * compile-time configurable maximum depth. - */ -template -class DepthGuard final { -public: - DepthGuard(int & depth_, const Mark& mark_, const std::string& msg_) : m_depth(depth_) { - ++m_depth; - if ( max_depth <= m_depth ) { - throw DeepRecursion{m_depth, mark_, msg_}; - } - } - - DepthGuard(const DepthGuard & copy_ctor) = delete; - DepthGuard(DepthGuard && move_ctor) = delete; - DepthGuard & operator=(const DepthGuard & copy_assign) = delete; - DepthGuard & operator=(DepthGuard && move_assign) = delete; - - ~DepthGuard() { - --m_depth; - } - - int current_depth() const { - return m_depth; - } - -private: - int & m_depth; -}; - -} // namespace YAML - -#endif // DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 diff --git a/third/yaml-cpp/include/yaml-cpp/dll.h b/third/yaml-cpp/include/yaml-cpp/dll.h deleted file mode 100644 index eabdda1d..00000000 --- a/third/yaml-cpp/include/yaml-cpp/dll.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -// Definition YAML_CPP_STATIC_DEFINE using to building YAML-CPP as static -// library (definition created by CMake or defined manually) - -// Definition yaml_cpp_EXPORTS using to building YAML-CPP as dll/so library -// (definition created by CMake or defined manually) - -#ifdef YAML_CPP_STATIC_DEFINE -# define YAML_CPP_API -# define YAML_CPP_NO_EXPORT -#else -# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) -# ifndef YAML_CPP_API -# ifdef yaml_cpp_EXPORTS - /* We are building this library */ -# pragma message( "Defining YAML_CPP_API for DLL export" ) -# define YAML_CPP_API __declspec(dllexport) -# else - /* We are using this library */ -# pragma message( "Defining YAML_CPP_API for DLL import" ) -# define YAML_CPP_API __declspec(dllimport) -# endif -# endif -# ifndef YAML_CPP_NO_EXPORT -# define YAML_CPP_NO_EXPORT -# endif -# else /* No _MSC_VER */ -# ifndef YAML_CPP_API -# ifdef yaml_cpp_EXPORTS - /* We are building this library */ -# define YAML_CPP_API __attribute__((visibility("default"))) -# else - /* We are using this library */ -# define YAML_CPP_API __attribute__((visibility("default"))) -# endif -# endif -# ifndef YAML_CPP_NO_EXPORT -# define YAML_CPP_NO_EXPORT __attribute__((visibility("hidden"))) -# endif -# endif /* _MSC_VER */ -#endif /* YAML_CPP_STATIC_DEFINE */ - -#ifndef YAML_CPP_DEPRECATED -# ifdef _MSC_VER -# define YAML_CPP_DEPRECATED __declspec(deprecated) -# else -# define YAML_CPP_DEPRECATED __attribute__ ((__deprecated__)) -# endif -#endif - -#ifndef YAML_CPP_DEPRECATED_EXPORT -# define YAML_CPP_DEPRECATED_EXPORT YAML_CPP_API YAML_CPP_DEPRECATED -#endif - -#ifndef YAML_CPP_DEPRECATED_NO_EXPORT -# define YAML_CPP_DEPRECATED_NO_EXPORT YAML_CPP_NO_EXPORT YAML_CPP_DEPRECATED -#endif - -#endif /* DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 */ diff --git a/third/yaml-cpp/include/yaml-cpp/emitfromevents.h b/third/yaml-cpp/include/yaml-cpp/emitfromevents.h deleted file mode 100644 index 1f389c5a..00000000 --- a/third/yaml-cpp/include/yaml-cpp/emitfromevents.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" - -namespace YAML { -struct Mark; -} // namespace YAML - -namespace YAML { -class Emitter; - -class EmitFromEvents : public EventHandler { - public: - EmitFromEvents(Emitter& emitter); - - void OnDocumentStart(const Mark& mark) override; - void OnDocumentEnd() override; - - void OnNull(const Mark& mark, anchor_t anchor) override; - void OnAlias(const Mark& mark, anchor_t anchor) override; - void OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value) override; - - void OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) override; - void OnSequenceEnd() override; - - void OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) override; - void OnMapEnd() override; - - private: - void BeginNode(); - void EmitProps(const std::string& tag, anchor_t anchor); - - private: - Emitter& m_emitter; - - struct State { - enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; - }; - std::stack m_stateStack; -}; -} - -#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/emitter.h b/third/yaml-cpp/include/yaml-cpp/emitter.h deleted file mode 100644 index 210b1ec9..00000000 --- a/third/yaml-cpp/include/yaml-cpp/emitter.h +++ /dev/null @@ -1,281 +0,0 @@ -#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "yaml-cpp/binary.h" -#include "yaml-cpp/dll.h" -#include "yaml-cpp/emitterdef.h" -#include "yaml-cpp/emittermanip.h" -#include "yaml-cpp/null.h" -#include "yaml-cpp/ostream_wrapper.h" - -namespace YAML { -class Binary; -struct _Null; -} // namespace YAML - -namespace YAML { -class EmitterState; - -class YAML_CPP_API Emitter { - public: - Emitter(); - explicit Emitter(std::ostream& stream); - Emitter(const Emitter&) = delete; - Emitter& operator=(const Emitter&) = delete; - ~Emitter(); - - // output - const char* c_str() const; - std::size_t size() const; - - // state checking - bool good() const; - const std::string GetLastError() const; - - // global setters - bool SetOutputCharset(EMITTER_MANIP value); - bool SetStringFormat(EMITTER_MANIP value); - bool SetBoolFormat(EMITTER_MANIP value); - bool SetNullFormat(EMITTER_MANIP value); - bool SetIntBase(EMITTER_MANIP value); - bool SetSeqFormat(EMITTER_MANIP value); - bool SetMapFormat(EMITTER_MANIP value); - bool SetIndent(std::size_t n); - bool SetPreCommentIndent(std::size_t n); - bool SetPostCommentIndent(std::size_t n); - bool SetFloatPrecision(std::size_t n); - bool SetDoublePrecision(std::size_t n); - void RestoreGlobalModifiedSettings(); - - // local setters - Emitter& SetLocalValue(EMITTER_MANIP value); - Emitter& SetLocalIndent(const _Indent& indent); - Emitter& SetLocalPrecision(const _Precision& precision); - - // overloads of write - Emitter& Write(const std::string& str); - Emitter& Write(bool b); - Emitter& Write(char ch); - Emitter& Write(const _Alias& alias); - Emitter& Write(const _Anchor& anchor); - Emitter& Write(const _Tag& tag); - Emitter& Write(const _Comment& comment); - Emitter& Write(const _Null& n); - Emitter& Write(const Binary& binary); - - template - Emitter& WriteIntegralType(T value); - - template - Emitter& WriteStreamable(T value); - - private: - template - void SetStreamablePrecision(std::stringstream&) {} - std::size_t GetFloatPrecision() const; - std::size_t GetDoublePrecision() const; - - void PrepareIntegralStream(std::stringstream& stream) const; - void StartedScalar(); - - private: - void EmitBeginDoc(); - void EmitEndDoc(); - void EmitBeginSeq(); - void EmitEndSeq(); - void EmitBeginMap(); - void EmitEndMap(); - void EmitNewline(); - void EmitKindTag(); - void EmitTag(bool verbatim, const _Tag& tag); - - void PrepareNode(EmitterNodeType::value child); - void PrepareTopNode(EmitterNodeType::value child); - void FlowSeqPrepareNode(EmitterNodeType::value child); - void BlockSeqPrepareNode(EmitterNodeType::value child); - - void FlowMapPrepareNode(EmitterNodeType::value child); - - void FlowMapPrepareLongKey(EmitterNodeType::value child); - void FlowMapPrepareLongKeyValue(EmitterNodeType::value child); - void FlowMapPrepareSimpleKey(EmitterNodeType::value child); - void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child); - - void BlockMapPrepareNode(EmitterNodeType::value child); - - void BlockMapPrepareLongKey(EmitterNodeType::value child); - void BlockMapPrepareLongKeyValue(EmitterNodeType::value child); - void BlockMapPrepareSimpleKey(EmitterNodeType::value child); - void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child); - - void SpaceOrIndentTo(bool requireSpace, std::size_t indent); - - const char* ComputeFullBoolName(bool b) const; - const char* ComputeNullName() const; - bool CanEmitNewline() const; - - private: - std::unique_ptr m_pState; - ostream_wrapper m_stream; -}; - -template -inline Emitter& Emitter::WriteIntegralType(T value) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - - std::stringstream stream; - PrepareIntegralStream(stream); - stream << value; - m_stream << stream.str(); - - StartedScalar(); - - return *this; -} - -template -inline Emitter& Emitter::WriteStreamable(T value) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - - std::stringstream stream; - SetStreamablePrecision(stream); - - bool special = false; - if (std::is_floating_point::value) { - if ((std::numeric_limits::has_quiet_NaN || - std::numeric_limits::has_signaling_NaN) && - std::isnan(value)) { - special = true; - stream << ".nan"; - } else if (std::numeric_limits::has_infinity && std::isinf(value)) { - special = true; - if (std::signbit(value)) { - stream << "-.inf"; - } else { - stream << ".inf"; - } - } - } - - if (!special) { - stream << value; - } - m_stream << stream.str(); - - StartedScalar(); - - return *this; -} - -template <> -inline void Emitter::SetStreamablePrecision(std::stringstream& stream) { - stream.precision(static_cast(GetFloatPrecision())); -} - -template <> -inline void Emitter::SetStreamablePrecision(std::stringstream& stream) { - stream.precision(static_cast(GetDoublePrecision())); -} - -// overloads of insertion -inline Emitter& operator<<(Emitter& emitter, const std::string& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, bool v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, char v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned char v) { - return emitter.Write(static_cast(v)); -} -inline Emitter& operator<<(Emitter& emitter, const _Alias& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const _Anchor& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const _Tag& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const _Comment& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const _Null& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const Binary& b) { - return emitter.Write(b); -} - -inline Emitter& operator<<(Emitter& emitter, const char* v) { - return emitter.Write(std::string(v)); -} - -inline Emitter& operator<<(Emitter& emitter, int v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned int v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, short v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned short v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, long v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned long v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, long long v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned long long v) { - return emitter.WriteIntegralType(v); -} - -inline Emitter& operator<<(Emitter& emitter, float v) { - return emitter.WriteStreamable(v); -} -inline Emitter& operator<<(Emitter& emitter, double v) { - return emitter.WriteStreamable(v); -} - -inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) { - return emitter.SetLocalValue(value); -} - -inline Emitter& operator<<(Emitter& emitter, _Indent indent) { - return emitter.SetLocalIndent(indent); -} - -inline Emitter& operator<<(Emitter& emitter, _Precision precision) { - return emitter.SetLocalPrecision(precision); -} -} // namespace YAML - -#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/emitterdef.h b/third/yaml-cpp/include/yaml-cpp/emitterdef.h deleted file mode 100644 index 0b426957..00000000 --- a/third/yaml-cpp/include/yaml-cpp/emitterdef.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -namespace YAML { -struct EmitterNodeType { - enum value { NoType, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap }; -}; -} - -#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/emittermanip.h b/third/yaml-cpp/include/yaml-cpp/emittermanip.h deleted file mode 100644 index 976d1495..00000000 --- a/third/yaml-cpp/include/yaml-cpp/emittermanip.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -namespace YAML { -enum EMITTER_MANIP { - // general manipulators - Auto, - TagByKind, - Newline, - - // output character set - EmitNonAscii, - EscapeNonAscii, - EscapeAsJson, - - // string manipulators - // Auto, // duplicate - SingleQuoted, - DoubleQuoted, - Literal, - - // null manipulators - LowerNull, - UpperNull, - CamelNull, - TildeNull, - - // bool manipulators - YesNoBool, // yes, no - TrueFalseBool, // true, false - OnOffBool, // on, off - UpperCase, // TRUE, N - LowerCase, // f, yes - CamelCase, // No, Off - LongBool, // yes, On - ShortBool, // y, t - - // int manipulators - Dec, - Hex, - Oct, - - // document manipulators - BeginDoc, - EndDoc, - - // sequence manipulators - BeginSeq, - EndSeq, - Flow, - Block, - - // map manipulators - BeginMap, - EndMap, - Key, - Value, - // Flow, // duplicate - // Block, // duplicate - // Auto, // duplicate - LongKey -}; - -struct _Indent { - _Indent(int value_) : value(value_) {} - int value; -}; - -inline _Indent Indent(int value) { return _Indent(value); } - -struct _Alias { - _Alias(const std::string& content_) : content(content_) {} - std::string content; -}; - -inline _Alias Alias(const std::string& content) { return _Alias(content); } - -struct _Anchor { - _Anchor(const std::string& content_) : content(content_) {} - std::string content; -}; - -inline _Anchor Anchor(const std::string& content) { return _Anchor(content); } - -struct _Tag { - struct Type { - enum value { Verbatim, PrimaryHandle, NamedHandle }; - }; - - explicit _Tag(const std::string& prefix_, const std::string& content_, - Type::value type_) - : prefix(prefix_), content(content_), type(type_) {} - std::string prefix; - std::string content; - Type::value type; -}; - -inline _Tag VerbatimTag(const std::string& content) { - return _Tag("", content, _Tag::Type::Verbatim); -} - -inline _Tag LocalTag(const std::string& content) { - return _Tag("", content, _Tag::Type::PrimaryHandle); -} - -inline _Tag LocalTag(const std::string& prefix, const std::string content) { - return _Tag(prefix, content, _Tag::Type::NamedHandle); -} - -inline _Tag SecondaryTag(const std::string& content) { - return _Tag("", content, _Tag::Type::NamedHandle); -} - -struct _Comment { - _Comment(const std::string& content_) : content(content_) {} - std::string content; -}; - -inline _Comment Comment(const std::string& content) { return _Comment(content); } - -struct _Precision { - _Precision(int floatPrecision_, int doublePrecision_) - : floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {} - - int floatPrecision; - int doublePrecision; -}; - -inline _Precision FloatPrecision(int n) { return _Precision(n, -1); } - -inline _Precision DoublePrecision(int n) { return _Precision(-1, n); } - -inline _Precision Precision(int n) { return _Precision(n, n); } -} - -#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/emitterstyle.h b/third/yaml-cpp/include/yaml-cpp/emitterstyle.h deleted file mode 100644 index 67bb3981..00000000 --- a/third/yaml-cpp/include/yaml-cpp/emitterstyle.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -namespace YAML { -struct EmitterStyle { - enum value { Default, Block, Flow }; -}; -} - -#endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/eventhandler.h b/third/yaml-cpp/include/yaml-cpp/eventhandler.h deleted file mode 100644 index 7242fe1f..00000000 --- a/third/yaml-cpp/include/yaml-cpp/eventhandler.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/emitterstyle.h" - -namespace YAML { -struct Mark; - -class EventHandler { - public: - virtual ~EventHandler() = default; - - virtual void OnDocumentStart(const Mark& mark) = 0; - virtual void OnDocumentEnd() = 0; - - virtual void OnNull(const Mark& mark, anchor_t anchor) = 0; - virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0; - virtual void OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value) = 0; - - virtual void OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) = 0; - virtual void OnSequenceEnd() = 0; - - virtual void OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) = 0; - virtual void OnMapEnd() = 0; - - virtual void OnAnchor(const Mark& /*mark*/, - const std::string& /*anchor_name*/) { - // empty default implementation for compatibility - } -}; -} // namespace YAML - -#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/exceptions.h b/third/yaml-cpp/include/yaml-cpp/exceptions.h deleted file mode 100644 index f6b2602a..00000000 --- a/third/yaml-cpp/include/yaml-cpp/exceptions.h +++ /dev/null @@ -1,303 +0,0 @@ -#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/mark.h" -#include "yaml-cpp/noexcept.h" -#include "yaml-cpp/traits.h" -#include -#include -#include - -namespace YAML { -// error messages -namespace ErrorMsg { -const char* const YAML_DIRECTIVE_ARGS = - "YAML directives must have exactly one argument"; -const char* const YAML_VERSION = "bad YAML version: "; -const char* const YAML_MAJOR_VERSION = "YAML major version too large"; -const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive"; -const char* const TAG_DIRECTIVE_ARGS = - "TAG directives must have exactly two arguments"; -const char* const REPEATED_TAG_DIRECTIVE = "repeated TAG directive"; -const char* const CHAR_IN_TAG_HANDLE = - "illegal character found while scanning tag handle"; -const char* const TAG_WITH_NO_SUFFIX = "tag handle with no suffix"; -const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found"; -const char* const END_OF_MAP = "end of map not found"; -const char* const END_OF_MAP_FLOW = "end of map flow not found"; -const char* const END_OF_SEQ = "end of sequence not found"; -const char* const END_OF_SEQ_FLOW = "end of sequence flow not found"; -const char* const MULTIPLE_TAGS = - "cannot assign multiple tags to the same node"; -const char* const MULTIPLE_ANCHORS = - "cannot assign multiple anchors to the same node"; -const char* const MULTIPLE_ALIASES = - "cannot assign multiple aliases to the same node"; -const char* const ALIAS_CONTENT = - "aliases can't have any content, *including* tags"; -const char* const INVALID_HEX = "bad character found while scanning hex number"; -const char* const INVALID_UNICODE = "invalid unicode: "; -const char* const INVALID_ESCAPE = "unknown escape character: "; -const char* const UNKNOWN_TOKEN = "unknown token"; -const char* const DOC_IN_SCALAR = "illegal document indicator in scalar"; -const char* const EOF_IN_SCALAR = "illegal EOF in scalar"; -const char* const CHAR_IN_SCALAR = "illegal character in scalar"; -const char* const TAB_IN_INDENTATION = - "illegal tab when looking for indentation"; -const char* const FLOW_END = "illegal flow end"; -const char* const BLOCK_ENTRY = "illegal block entry"; -const char* const MAP_KEY = "illegal map key"; -const char* const MAP_VALUE = "illegal map value"; -const char* const ALIAS_NOT_FOUND = "alias not found after *"; -const char* const ANCHOR_NOT_FOUND = "anchor not found after &"; -const char* const CHAR_IN_ALIAS = - "illegal character found while scanning alias"; -const char* const CHAR_IN_ANCHOR = - "illegal character found while scanning anchor"; -const char* const ZERO_INDENT_IN_BLOCK = - "cannot set zero indentation for a block scalar"; -const char* const CHAR_IN_BLOCK = "unexpected character in block scalar"; -const char* const AMBIGUOUS_ANCHOR = - "cannot assign the same alias to multiple nodes"; -const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined: "; - -const char* const INVALID_NODE = - "invalid node; this may result from using a map iterator as a sequence " - "iterator, or vice-versa"; -const char* const INVALID_SCALAR = "invalid scalar"; -const char* const KEY_NOT_FOUND = "key not found"; -const char* const BAD_CONVERSION = "bad conversion"; -const char* const BAD_DEREFERENCE = "bad dereference"; -const char* const BAD_SUBSCRIPT = "operator[] call on a scalar"; -const char* const BAD_PUSHBACK = "appending to a non-sequence"; -const char* const BAD_INSERT = "inserting in a non-convertible-to-map"; - -const char* const UNMATCHED_GROUP_TAG = "unmatched group tag"; -const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token"; -const char* const UNEXPECTED_END_MAP = "unexpected end map token"; -const char* const SINGLE_QUOTED_CHAR = - "invalid character in single-quoted string"; -const char* const INVALID_ANCHOR = "invalid anchor"; -const char* const INVALID_ALIAS = "invalid alias"; -const char* const INVALID_TAG = "invalid tag"; -const char* const BAD_FILE = "bad file"; - -template -inline const std::string KEY_NOT_FOUND_WITH_KEY( - const T&, typename disable_if>::type* = 0) { - return KEY_NOT_FOUND; -} - -inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { - std::stringstream stream; - stream << KEY_NOT_FOUND << ": " << key; - return stream.str(); -} - -inline const std::string KEY_NOT_FOUND_WITH_KEY(const char* key) { - std::stringstream stream; - stream << KEY_NOT_FOUND << ": " << key; - return stream.str(); -} - -template -inline const std::string KEY_NOT_FOUND_WITH_KEY( - const T& key, typename enable_if>::type* = 0) { - std::stringstream stream; - stream << KEY_NOT_FOUND << ": " << key; - return stream.str(); -} - -template -inline const std::string BAD_SUBSCRIPT_WITH_KEY( - const T&, typename disable_if>::type* = nullptr) { - return BAD_SUBSCRIPT; -} - -inline const std::string BAD_SUBSCRIPT_WITH_KEY(const std::string& key) { - std::stringstream stream; - stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")"; - return stream.str(); -} - -inline const std::string BAD_SUBSCRIPT_WITH_KEY(const char* key) { - std::stringstream stream; - stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")"; - return stream.str(); -} - -template -inline const std::string BAD_SUBSCRIPT_WITH_KEY( - const T& key, typename enable_if>::type* = nullptr) { - std::stringstream stream; - stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")"; - return stream.str(); -} - -inline const std::string INVALID_NODE_WITH_KEY(const std::string& key) { - std::stringstream stream; - if (key.empty()) { - return INVALID_NODE; - } - stream << "invalid node; first invalid key: \"" << key << "\""; - return stream.str(); -} -} // namespace ErrorMsg - -class YAML_CPP_API Exception : public std::runtime_error { - public: - Exception(const Mark& mark_, const std::string& msg_) - : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} - ~Exception() YAML_CPP_NOEXCEPT override; - - Exception(const Exception&) = default; - - Mark mark; - std::string msg; - - private: - static const std::string build_what(const Mark& mark, - const std::string& msg) { - if (mark.is_null()) { - return msg; - } - - std::stringstream output; - output << "yaml-cpp: error at line " << mark.line + 1 << ", column " - << mark.column + 1 << ": " << msg; - return output.str(); - } -}; - -class YAML_CPP_API ParserException : public Exception { - public: - ParserException(const Mark& mark_, const std::string& msg_) - : Exception(mark_, msg_) {} - ParserException(const ParserException&) = default; - ~ParserException() YAML_CPP_NOEXCEPT override; -}; - -class YAML_CPP_API RepresentationException : public Exception { - public: - RepresentationException(const Mark& mark_, const std::string& msg_) - : Exception(mark_, msg_) {} - RepresentationException(const RepresentationException&) = default; - ~RepresentationException() YAML_CPP_NOEXCEPT override; -}; - -// representation exceptions -class YAML_CPP_API InvalidScalar : public RepresentationException { - public: - InvalidScalar(const Mark& mark_) - : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} - InvalidScalar(const InvalidScalar&) = default; - ~InvalidScalar() YAML_CPP_NOEXCEPT override; -}; - -class YAML_CPP_API KeyNotFound : public RepresentationException { - public: - template - KeyNotFound(const Mark& mark_, const T& key_) - : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) { - } - KeyNotFound(const KeyNotFound&) = default; - ~KeyNotFound() YAML_CPP_NOEXCEPT override; -}; - -template -class YAML_CPP_API TypedKeyNotFound : public KeyNotFound { - public: - TypedKeyNotFound(const Mark& mark_, const T& key_) - : KeyNotFound(mark_, key_), key(key_) {} - ~TypedKeyNotFound() YAML_CPP_NOEXCEPT override = default; - - T key; -}; - -template -inline TypedKeyNotFound MakeTypedKeyNotFound(const Mark& mark, - const T& key) { - return TypedKeyNotFound(mark, key); -} - -class YAML_CPP_API InvalidNode : public RepresentationException { - public: - InvalidNode(const std::string& key) - : RepresentationException(Mark::null_mark(), - ErrorMsg::INVALID_NODE_WITH_KEY(key)) {} - InvalidNode(const InvalidNode&) = default; - ~InvalidNode() YAML_CPP_NOEXCEPT override; -}; - -class YAML_CPP_API BadConversion : public RepresentationException { - public: - explicit BadConversion(const Mark& mark_) - : RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {} - BadConversion(const BadConversion&) = default; - ~BadConversion() YAML_CPP_NOEXCEPT override; -}; - -template -class TypedBadConversion : public BadConversion { - public: - explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {} -}; - -class YAML_CPP_API BadDereference : public RepresentationException { - public: - BadDereference() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} - BadDereference(const BadDereference&) = default; - ~BadDereference() YAML_CPP_NOEXCEPT override; -}; - -class YAML_CPP_API BadSubscript : public RepresentationException { - public: - template - BadSubscript(const Mark& mark_, const Key& key) - : RepresentationException(mark_, ErrorMsg::BAD_SUBSCRIPT_WITH_KEY(key)) {} - BadSubscript(const BadSubscript&) = default; - ~BadSubscript() YAML_CPP_NOEXCEPT override; -}; - -class YAML_CPP_API BadPushback : public RepresentationException { - public: - BadPushback() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {} - BadPushback(const BadPushback&) = default; - ~BadPushback() YAML_CPP_NOEXCEPT override; -}; - -class YAML_CPP_API BadInsert : public RepresentationException { - public: - BadInsert() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {} - BadInsert(const BadInsert&) = default; - ~BadInsert() YAML_CPP_NOEXCEPT override; -}; - -class YAML_CPP_API EmitterException : public Exception { - public: - EmitterException(const std::string& msg_) - : Exception(Mark::null_mark(), msg_) {} - EmitterException(const EmitterException&) = default; - ~EmitterException() YAML_CPP_NOEXCEPT override; -}; - -class YAML_CPP_API BadFile : public Exception { - public: - explicit BadFile(const std::string& filename) - : Exception(Mark::null_mark(), - std::string(ErrorMsg::BAD_FILE) + ": " + filename) {} - BadFile(const BadFile&) = default; - ~BadFile() YAML_CPP_NOEXCEPT override; -}; -} // namespace YAML - -#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/mark.h b/third/yaml-cpp/include/yaml-cpp/mark.h deleted file mode 100644 index bf94b4f4..00000000 --- a/third/yaml-cpp/include/yaml-cpp/mark.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" - -namespace YAML { -struct YAML_CPP_API Mark { - Mark() : pos(0), line(0), column(0) {} - - static const Mark null_mark() { return Mark(-1, -1, -1); } - - bool is_null() const { return pos == -1 && line == -1 && column == -1; } - - int pos; - int line, column; - - private: - Mark(int pos_, int line_, int column_) - : pos(pos_), line(line_), column(column_) {} -}; -} - -#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/convert.h b/third/yaml-cpp/include/yaml-cpp/node/convert.h deleted file mode 100644 index d0eb450f..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/convert.h +++ /dev/null @@ -1,469 +0,0 @@ -#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if __cplusplus >= 201703L -#include -#endif - -#include "yaml-cpp/binary.h" -#include "yaml-cpp/node/impl.h" -#include "yaml-cpp/node/iterator.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/type.h" -#include "yaml-cpp/null.h" - - -namespace YAML { -class Binary; -struct _Null; -template -struct convert; -} // namespace YAML - -namespace YAML { -namespace conversion { -inline bool IsInfinity(const std::string& input) { - return input == ".inf" || input == ".Inf" || input == ".INF" || - input == "+.inf" || input == "+.Inf" || input == "+.INF"; -} - -inline bool IsNegativeInfinity(const std::string& input) { - return input == "-.inf" || input == "-.Inf" || input == "-.INF"; -} - -inline bool IsNaN(const std::string& input) { - return input == ".nan" || input == ".NaN" || input == ".NAN"; -} -} - -// Node -template <> -struct convert { - static Node encode(const Node& rhs) { return rhs; } - - static bool decode(const Node& node, Node& rhs) { - rhs.reset(node); - return true; - } -}; - -// std::string -template <> -struct convert { - static Node encode(const std::string& rhs) { return Node(rhs); } - - static bool decode(const Node& node, std::string& rhs) { - if (!node.IsScalar()) - return false; - rhs = node.Scalar(); - return true; - } -}; - -// C-strings can only be encoded -template <> -struct convert { - static Node encode(const char* rhs) { return Node(rhs); } -}; - -template <> -struct convert { - static Node encode(const char* rhs) { return Node(rhs); } -}; - -template -struct convert { - static Node encode(const char* rhs) { return Node(rhs); } -}; - -#if __cplusplus >= 201703L -template <> -struct convert { - static Node encode(std::string_view rhs) { return Node(std::string(rhs)); } - - static bool decode(const Node& node, std::string_view& rhs) { - if (!node.IsScalar()) - return false; - rhs = node.Scalar(); - return true; - } -}; -#endif - -template <> -struct convert<_Null> { - static Node encode(const _Null& /* rhs */) { return Node(); } - - static bool decode(const Node& node, _Null& /* rhs */) { - return node.IsNull(); - } -}; - -namespace conversion { -template -typename std::enable_if< std::is_floating_point::value, void>::type -inner_encode(const T& rhs, std::stringstream& stream){ - if (std::isnan(rhs)) { - stream << ".nan"; - } else if (std::isinf(rhs)) { - if (std::signbit(rhs)) { - stream << "-.inf"; - } else { - stream << ".inf"; - } - } else { - stream << rhs; - } -} - -template -typename std::enable_if::value, void>::type -inner_encode(const T& rhs, std::stringstream& stream){ - stream << rhs; -} - -template -typename std::enable_if<(std::is_same::value || - std::is_same::value), bool>::type -ConvertStreamTo(std::stringstream& stream, T& rhs) { - int num; - if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) { - if (num >= (std::numeric_limits::min)() && - num <= (std::numeric_limits::max)()) { - rhs = static_cast(num); - return true; - } - } - return false; -} - -template -typename std::enable_if::value || - std::is_same::value), bool>::type -ConvertStreamTo(std::stringstream& stream, T& rhs) { - if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) { - return true; - } - return false; -} -} - -#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ - template <> \ - struct convert { \ - \ - static Node encode(const type& rhs) { \ - std::stringstream stream; \ - stream.precision(std::numeric_limits::max_digits10); \ - conversion::inner_encode(rhs, stream); \ - return Node(stream.str()); \ - } \ - \ - static bool decode(const Node& node, type& rhs) { \ - if (node.Type() != NodeType::Scalar) { \ - return false; \ - } \ - const std::string& input = node.Scalar(); \ - std::stringstream stream(input); \ - stream.unsetf(std::ios::dec); \ - if ((stream.peek() == '-') && std::is_unsigned::value) { \ - return false; \ - } \ - if (conversion::ConvertStreamTo(stream, rhs)) { \ - return true; \ - } \ - if (std::numeric_limits::has_infinity) { \ - if (conversion::IsInfinity(input)) { \ - rhs = std::numeric_limits::infinity(); \ - return true; \ - } else if (conversion::IsNegativeInfinity(input)) { \ - rhs = negative_op std::numeric_limits::infinity(); \ - return true; \ - } \ - } \ - \ - if (std::numeric_limits::has_quiet_NaN) { \ - if (conversion::IsNaN(input)) { \ - rhs = std::numeric_limits::quiet_NaN(); \ - return true; \ - } \ - } \ - \ - return false; \ - } \ - } - -#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \ - YAML_DEFINE_CONVERT_STREAMABLE(type, -) - -#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \ - YAML_DEFINE_CONVERT_STREAMABLE(type, +) - -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); - -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char); - -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double); - -#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED -#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED -#undef YAML_DEFINE_CONVERT_STREAMABLE - -// bool -template <> -struct convert { - static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } - - YAML_CPP_API static bool decode(const Node& node, bool& rhs); -}; - -// std::map -template -struct convert> { - static Node encode(const std::map& rhs) { - Node node(NodeType::Map); - for (const auto& element : rhs) - node.force_insert(element.first, element.second); - return node; - } - - static bool decode(const Node& node, std::map& rhs) { - if (!node.IsMap()) - return false; - - rhs.clear(); - for (const auto& element : node) -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs[element.first.template as()] = element.second.template as(); -#else - rhs[element.first.as()] = element.second.as(); -#endif - return true; - } -}; - -// std::unordered_map -template -struct convert> { - static Node encode(const std::unordered_map& rhs) { - Node node(NodeType::Map); - for (const auto& element : rhs) - node.force_insert(element.first, element.second); - return node; - } - - static bool decode(const Node& node, std::unordered_map& rhs) { - if (!node.IsMap()) - return false; - - rhs.clear(); - for (const auto& element : node) -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs[element.first.template as()] = element.second.template as(); -#else - rhs[element.first.as()] = element.second.as(); -#endif - return true; - } -}; - -// std::vector -template -struct convert> { - static Node encode(const std::vector& rhs) { - Node node(NodeType::Sequence); - for (const auto& element : rhs) - node.push_back(element); - return node; - } - - static bool decode(const Node& node, std::vector& rhs) { - if (!node.IsSequence()) - return false; - - rhs.clear(); - for (const auto& element : node) -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs.push_back(element.template as()); -#else - rhs.push_back(element.as()); -#endif - return true; - } -}; - -// std::list -template -struct convert> { - static Node encode(const std::list& rhs) { - Node node(NodeType::Sequence); - for (const auto& element : rhs) - node.push_back(element); - return node; - } - - static bool decode(const Node& node, std::list& rhs) { - if (!node.IsSequence()) - return false; - - rhs.clear(); - for (const auto& element : node) -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs.push_back(element.template as()); -#else - rhs.push_back(element.as()); -#endif - return true; - } -}; - -// std::array -template -struct convert> { - static Node encode(const std::array& rhs) { - Node node(NodeType::Sequence); - for (const auto& element : rhs) { - node.push_back(element); - } - return node; - } - - static bool decode(const Node& node, std::array& rhs) { - if (!isNodeValid(node)) { - return false; - } - - for (auto i = 0u; i < node.size(); ++i) { -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs[i] = node[i].template as(); -#else - rhs[i] = node[i].as(); -#endif - } - return true; - } - - private: - static bool isNodeValid(const Node& node) { - return node.IsSequence() && node.size() == N; - } -}; - - -// std::valarray -template -struct convert> { - static Node encode(const std::valarray& rhs) { - Node node(NodeType::Sequence); - for (const auto& element : rhs) { - node.push_back(element); - } - return node; - } - - static bool decode(const Node& node, std::valarray& rhs) { - if (!node.IsSequence()) { - return false; - } - - rhs.resize(node.size()); - for (auto i = 0u; i < node.size(); ++i) { -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs[i] = node[i].template as(); -#else - rhs[i] = node[i].as(); -#endif - } - return true; - } -}; - - -// std::pair -template -struct convert> { - static Node encode(const std::pair& rhs) { - Node node(NodeType::Sequence); - node.push_back(rhs.first); - node.push_back(rhs.second); - return node; - } - - static bool decode(const Node& node, std::pair& rhs) { - if (!node.IsSequence()) - return false; - if (node.size() != 2) - return false; - -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs.first = node[0].template as(); -#else - rhs.first = node[0].as(); -#endif -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs.second = node[1].template as(); -#else - rhs.second = node[1].as(); -#endif - return true; - } -}; - -// binary -template <> -struct convert { - static Node encode(const Binary& rhs) { - return Node(EncodeBase64(rhs.data(), rhs.size())); - } - - static bool decode(const Node& node, Binary& rhs) { - if (!node.IsScalar()) - return false; - - std::vector data = DecodeBase64(node.Scalar()); - if (data.empty() && !node.Scalar().empty()) - return false; - - rhs.swap(data); - return true; - } -}; -} - -#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/detail/impl.h b/third/yaml-cpp/include/yaml-cpp/node/detail/impl.h deleted file mode 100644 index b38038df..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/detail/impl.h +++ /dev/null @@ -1,235 +0,0 @@ -#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/node/detail/node.h" -#include "yaml-cpp/node/detail/node_data.h" - -#include -#include - -namespace YAML { -namespace detail { -template -struct get_idx { - static node* get(const std::vector& /* sequence */, - const Key& /* key */, shared_memory_holder /* pMemory */) { - return nullptr; - } -}; - -template -struct get_idx::value && - !std::is_same::value>::type> { - static node* get(const std::vector& sequence, const Key& key, - shared_memory_holder /* pMemory */) { - return key < sequence.size() ? sequence[key] : nullptr; - } - - static node* get(std::vector& sequence, const Key& key, - shared_memory_holder pMemory) { - if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined())) - return nullptr; - if (key == sequence.size()) - sequence.push_back(&pMemory->create_node()); - return sequence[key]; - } -}; - -template -struct get_idx::value>::type> { - static node* get(const std::vector& sequence, const Key& key, - shared_memory_holder pMemory) { - return key >= 0 ? get_idx::get( - sequence, static_cast(key), pMemory) - : nullptr; - } - static node* get(std::vector& sequence, const Key& key, - shared_memory_holder pMemory) { - return key >= 0 ? get_idx::get( - sequence, static_cast(key), pMemory) - : nullptr; - } -}; - -template -struct remove_idx { - static bool remove(std::vector&, const Key&, std::size_t&) { - return false; - } -}; - -template -struct remove_idx< - Key, typename std::enable_if::value && - !std::is_same::value>::type> { - - static bool remove(std::vector& sequence, const Key& key, - std::size_t& seqSize) { - if (key >= sequence.size()) { - return false; - } else { - sequence.erase(sequence.begin() + key); - if (seqSize > key) { - --seqSize; - } - return true; - } - } -}; - -template -struct remove_idx::value>::type> { - - static bool remove(std::vector& sequence, const Key& key, - std::size_t& seqSize) { - return key >= 0 ? remove_idx::remove( - sequence, static_cast(key), seqSize) - : false; - } -}; - -template -inline bool node::equals(const T& rhs, shared_memory_holder pMemory) { - T lhs; - if (convert::decode(Node(*this, pMemory), lhs)) { - return lhs == rhs; - } - return false; -} - -inline bool node::equals(const char* rhs, shared_memory_holder pMemory) { - std::string lhs; - if (convert::decode(Node(*this, std::move(pMemory)), lhs)) { - return lhs == rhs; - } - return false; -} - -// indexing -template -inline node* node_data::get(const Key& key, - shared_memory_holder pMemory) const { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - return nullptr; - case NodeType::Sequence: - if (node* pNode = get_idx::get(m_sequence, key, pMemory)) - return pNode; - return nullptr; - case NodeType::Scalar: - throw BadSubscript(m_mark, key); - } - - auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) { - return m.first->equals(key, pMemory); - }); - - return it != m_map.end() ? it->second : nullptr; -} - -template -inline node& node_data::get(const Key& key, shared_memory_holder pMemory) { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - if (node* pNode = get_idx::get(m_sequence, key, pMemory)) { - m_type = NodeType::Sequence; - return *pNode; - } - - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadSubscript(m_mark, key); - } - - auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) { - return m.first->equals(key, pMemory); - }); - - if (it != m_map.end()) { - return *it->second; - } - - node& k = convert_to_node(key, pMemory); - node& v = pMemory->create_node(); - insert_map_pair(k, v); - return v; -} - -template -inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) { - if (m_type == NodeType::Sequence) { - return remove_idx::remove(m_sequence, key, m_seqSize); - } - - if (m_type == NodeType::Map) { - kv_pairs::iterator it = m_undefinedPairs.begin(); - while (it != m_undefinedPairs.end()) { - kv_pairs::iterator jt = std::next(it); - if (it->first->equals(key, pMemory)) { - m_undefinedPairs.erase(it); - } - it = jt; - } - - auto iter = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) { - return m.first->equals(key, pMemory); - }); - - if (iter != m_map.end()) { - m_map.erase(iter); - return true; - } - } - - return false; -} - -// map -template -inline void node_data::force_insert(const Key& key, const Value& value, - shared_memory_holder pMemory) { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadInsert(); - } - - node& k = convert_to_node(key, pMemory); - node& v = convert_to_node(value, pMemory); - insert_map_pair(k, v); -} - -template -inline node& node_data::convert_to_node(const T& rhs, - shared_memory_holder pMemory) { - Node value = convert::encode(rhs); - value.EnsureNodeExists(); - pMemory->merge(*value.m_pMemory); - return *value.m_pNode; -} -} -} - -#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/detail/iterator.h b/third/yaml-cpp/include/yaml-cpp/node/detail/iterator.h deleted file mode 100644 index 997c69a1..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/detail/iterator.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/detail/node_iterator.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/ptr.h" -#include -#include - - -namespace YAML { -namespace detail { -struct iterator_value; - -template -class iterator_base { - - private: - template - friend class iterator_base; - struct enabler {}; - using base_type = node_iterator; - - struct proxy { - explicit proxy(const V& x) : m_ref(x) {} - V* operator->() { return std::addressof(m_ref); } - operator V*() { return std::addressof(m_ref); } - - V m_ref; - }; - - public: - using iterator_category = std::forward_iterator_tag; - using value_type = V; - using difference_type = std::ptrdiff_t; - using pointer = V*; - using reference = V; - - public: - iterator_base() : m_iterator(), m_pMemory() {} - explicit iterator_base(base_type rhs, shared_memory_holder pMemory) - : m_iterator(rhs), m_pMemory(pMemory) {} - - template - iterator_base(const iterator_base& rhs, - typename std::enable_if::value, - enabler>::type = enabler()) - : m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {} - - iterator_base& operator++() { - ++m_iterator; - return *this; - } - - iterator_base operator++(int) { - iterator_base iterator_pre(*this); - ++(*this); - return iterator_pre; - } - - template - bool operator==(const iterator_base& rhs) const { - return m_iterator == rhs.m_iterator; - } - - template - bool operator!=(const iterator_base& rhs) const { - return m_iterator != rhs.m_iterator; - } - - value_type operator*() const { - const typename base_type::value_type& v = *m_iterator; - if (v.pNode) - return value_type(Node(*v, m_pMemory)); - if (v.first && v.second) - return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory)); - return value_type(); - } - - proxy operator->() const { return proxy(**this); } - - private: - base_type m_iterator; - shared_memory_holder m_pMemory; -}; -} // namespace detail -} // namespace YAML - -#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h b/third/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h deleted file mode 100644 index 75c9de08..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include -#include -#include - -namespace YAML { - -namespace detail { -struct iterator_value; -template -class iterator_base; -} - -using iterator = detail::iterator_base; -using const_iterator = detail::iterator_base; -} - -#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/detail/memory.h b/third/yaml-cpp/include/yaml-cpp/node/detail/memory.h deleted file mode 100644 index e881545b..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/detail/memory.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/ptr.h" - -namespace YAML { -namespace detail { -class node; -} // namespace detail -} // namespace YAML - -namespace YAML { -namespace detail { -class YAML_CPP_API memory { - public: - memory() : m_nodes{} {} - node& create_node(); - void merge(const memory& rhs); - - private: - using Nodes = std::set; - Nodes m_nodes; -}; - -class YAML_CPP_API memory_holder { - public: - memory_holder() : m_pMemory(new memory) {} - - node& create_node() { return m_pMemory->create_node(); } - void merge(memory_holder& rhs); - - private: - shared_memory m_pMemory; -}; -} // namespace detail -} // namespace YAML - -#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/detail/node.h b/third/yaml-cpp/include/yaml-cpp/node/detail/node.h deleted file mode 100644 index acf60ffb..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/detail/node.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/node/detail/node_ref.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/type.h" -#include -#include - -namespace YAML { -namespace detail { -class node { - private: - struct less { - bool operator ()(const node* l, const node* r) const {return l->m_index < r->m_index;} - }; - - public: - node() : m_pRef(new node_ref), m_dependencies{}, m_index{} {} - node(const node&) = delete; - node& operator=(const node&) = delete; - - bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } - const node_ref* ref() const { return m_pRef.get(); } - - bool is_defined() const { return m_pRef->is_defined(); } - const Mark& mark() const { return m_pRef->mark(); } - NodeType::value type() const { return m_pRef->type(); } - - const std::string& scalar() const { return m_pRef->scalar(); } - const std::string& tag() const { return m_pRef->tag(); } - EmitterStyle::value style() const { return m_pRef->style(); } - - template - bool equals(const T& rhs, shared_memory_holder pMemory); - bool equals(const char* rhs, shared_memory_holder pMemory); - - void mark_defined() { - if (is_defined()) - return; - - m_pRef->mark_defined(); - for (node* dependency : m_dependencies) - dependency->mark_defined(); - m_dependencies.clear(); - } - - void add_dependency(node& rhs) { - if (is_defined()) - rhs.mark_defined(); - else - m_dependencies.insert(&rhs); - } - - void set_ref(const node& rhs) { - if (rhs.is_defined()) - mark_defined(); - m_pRef = rhs.m_pRef; - } - void set_data(const node& rhs) { - if (rhs.is_defined()) - mark_defined(); - m_pRef->set_data(*rhs.m_pRef); - } - - void set_mark(const Mark& mark) { m_pRef->set_mark(mark); } - - void set_type(NodeType::value type) { - if (type != NodeType::Undefined) - mark_defined(); - m_pRef->set_type(type); - } - void set_null() { - mark_defined(); - m_pRef->set_null(); - } - void set_scalar(const std::string& scalar) { - mark_defined(); - m_pRef->set_scalar(scalar); - } - void set_tag(const std::string& tag) { - mark_defined(); - m_pRef->set_tag(tag); - } - - // style - void set_style(EmitterStyle::value style) { - mark_defined(); - m_pRef->set_style(style); - } - - // size/iterator - std::size_t size() const { return m_pRef->size(); } - - const_node_iterator begin() const { - return static_cast(*m_pRef).begin(); - } - node_iterator begin() { return m_pRef->begin(); } - - const_node_iterator end() const { - return static_cast(*m_pRef).end(); - } - node_iterator end() { return m_pRef->end(); } - - // sequence - void push_back(node& input, shared_memory_holder pMemory) { - m_pRef->push_back(input, pMemory); - input.add_dependency(*this); - m_index = m_amount.fetch_add(1); - } - void insert(node& key, node& value, shared_memory_holder pMemory) { - m_pRef->insert(key, value, pMemory); - key.add_dependency(*this); - value.add_dependency(*this); - } - - // indexing - template - node* get(const Key& key, shared_memory_holder pMemory) const { - // NOTE: this returns a non-const node so that the top-level Node can wrap - // it, and returns a pointer so that it can be nullptr (if there is no such - // key). - return static_cast(*m_pRef).get(key, pMemory); - } - template - node& get(const Key& key, shared_memory_holder pMemory) { - node& value = m_pRef->get(key, pMemory); - value.add_dependency(*this); - return value; - } - template - bool remove(const Key& key, shared_memory_holder pMemory) { - return m_pRef->remove(key, pMemory); - } - - node* get(node& key, shared_memory_holder pMemory) const { - // NOTE: this returns a non-const node so that the top-level Node can wrap - // it, and returns a pointer so that it can be nullptr (if there is no such - // key). - return static_cast(*m_pRef).get(key, pMemory); - } - node& get(node& key, shared_memory_holder pMemory) { - node& value = m_pRef->get(key, pMemory); - key.add_dependency(*this); - value.add_dependency(*this); - return value; - } - bool remove(node& key, shared_memory_holder pMemory) { - return m_pRef->remove(key, pMemory); - } - - // map - template - void force_insert(const Key& key, const Value& value, - shared_memory_holder pMemory) { - m_pRef->force_insert(key, value, pMemory); - } - - private: - shared_node_ref m_pRef; - using nodes = std::set; - nodes m_dependencies; - size_t m_index; - static YAML_CPP_API std::atomic m_amount; -}; -} // namespace detail -} // namespace YAML - -#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/detail/node_data.h b/third/yaml-cpp/include/yaml-cpp/node/detail/node_data.h deleted file mode 100644 index 07cf81aa..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/detail/node_data.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include -#include - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/detail/node_iterator.h" -#include "yaml-cpp/node/iterator.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -namespace detail { -class node; -} // namespace detail -} // namespace YAML - -namespace YAML { -namespace detail { -class YAML_CPP_API node_data { - public: - node_data(); - node_data(const node_data&) = delete; - node_data& operator=(const node_data&) = delete; - - void mark_defined(); - void set_mark(const Mark& mark); - void set_type(NodeType::value type); - void set_tag(const std::string& tag); - void set_null(); - void set_scalar(const std::string& scalar); - void set_style(EmitterStyle::value style); - - bool is_defined() const { return m_isDefined; } - const Mark& mark() const { return m_mark; } - NodeType::value type() const { - return m_isDefined ? m_type : NodeType::Undefined; - } - const std::string& scalar() const { return m_scalar; } - const std::string& tag() const { return m_tag; } - EmitterStyle::value style() const { return m_style; } - - // size/iterator - std::size_t size() const; - - const_node_iterator begin() const; - node_iterator begin(); - - const_node_iterator end() const; - node_iterator end(); - - // sequence - void push_back(node& node, const shared_memory_holder& pMemory); - void insert(node& key, node& value, const shared_memory_holder& pMemory); - - // indexing - template - node* get(const Key& key, shared_memory_holder pMemory) const; - template - node& get(const Key& key, shared_memory_holder pMemory); - template - bool remove(const Key& key, shared_memory_holder pMemory); - - node* get(node& key, const shared_memory_holder& pMemory) const; - node& get(node& key, const shared_memory_holder& pMemory); - bool remove(node& key, const shared_memory_holder& pMemory); - - // map - template - void force_insert(const Key& key, const Value& value, - shared_memory_holder pMemory); - - public: - static const std::string& empty_scalar(); - - private: - void compute_seq_size() const; - void compute_map_size() const; - - void reset_sequence(); - void reset_map(); - - void insert_map_pair(node& key, node& value); - void convert_to_map(const shared_memory_holder& pMemory); - void convert_sequence_to_map(const shared_memory_holder& pMemory); - - template - static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); - - private: - bool m_isDefined; - Mark m_mark; - NodeType::value m_type; - std::string m_tag; - EmitterStyle::value m_style; - - // scalar - std::string m_scalar; - - // sequence - using node_seq = std::vector; - node_seq m_sequence; - - mutable std::size_t m_seqSize; - - // map - using node_map = std::vector>; - node_map m_map; - - using kv_pair = std::pair; - using kv_pairs = std::list; - mutable kv_pairs m_undefinedPairs; -}; -} -} - -#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h b/third/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h deleted file mode 100644 index 49dcf958..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h +++ /dev/null @@ -1,181 +0,0 @@ -#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/ptr.h" -#include -#include -#include -#include -#include -#include - -namespace YAML { -namespace detail { -struct iterator_type { - enum value { NoneType, Sequence, Map }; -}; - -template -struct node_iterator_value : public std::pair { - using kv = std::pair; - - node_iterator_value() : kv(), pNode(nullptr) {} - explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {} - explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {} - - V& operator*() const { return *pNode; } - V& operator->() const { return *pNode; } - - V* pNode; -}; - -using node_seq = std::vector; -using node_map = std::vector>; - -template -struct node_iterator_type { - using seq = node_seq::iterator; - using map = node_map::iterator; -}; - -template -struct node_iterator_type { - using seq = node_seq::const_iterator; - using map = node_map::const_iterator; -}; - -template -class node_iterator_base { - private: - struct enabler {}; - - struct proxy { - explicit proxy(const node_iterator_value& x) : m_ref(x) {} - node_iterator_value* operator->() { return std::addressof(m_ref); } - operator node_iterator_value*() { return std::addressof(m_ref); } - - node_iterator_value m_ref; - }; - - public: - using iterator_category = std::forward_iterator_tag; - using value_type = node_iterator_value; - using difference_type = std::ptrdiff_t; - using pointer = node_iterator_value*; - using reference = node_iterator_value; - using SeqIter = typename node_iterator_type::seq; - using MapIter = typename node_iterator_type::map; - - node_iterator_base() - : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {} - explicit node_iterator_base(SeqIter seqIt) - : m_type(iterator_type::Sequence), - m_seqIt(seqIt), - m_mapIt(), - m_mapEnd() {} - explicit node_iterator_base(MapIter mapIt, MapIter mapEnd) - : m_type(iterator_type::Map), - m_seqIt(), - m_mapIt(mapIt), - m_mapEnd(mapEnd) { - m_mapIt = increment_until_defined(m_mapIt); - } - - template - node_iterator_base(const node_iterator_base& rhs, - typename std::enable_if::value, - enabler>::type = enabler()) - : m_type(rhs.m_type), - m_seqIt(rhs.m_seqIt), - m_mapIt(rhs.m_mapIt), - m_mapEnd(rhs.m_mapEnd) {} - - template - friend class node_iterator_base; - - template - bool operator==(const node_iterator_base& rhs) const { - if (m_type != rhs.m_type) - return false; - - switch (m_type) { - case iterator_type::NoneType: - return true; - case iterator_type::Sequence: - return m_seqIt == rhs.m_seqIt; - case iterator_type::Map: - return m_mapIt == rhs.m_mapIt; - } - return true; - } - - template - bool operator!=(const node_iterator_base& rhs) const { - return !(*this == rhs); - } - - node_iterator_base& operator++() { - switch (m_type) { - case iterator_type::NoneType: - break; - case iterator_type::Sequence: - ++m_seqIt; - break; - case iterator_type::Map: - ++m_mapIt; - m_mapIt = increment_until_defined(m_mapIt); - break; - } - return *this; - } - - node_iterator_base operator++(int) { - node_iterator_base iterator_pre(*this); - ++(*this); - return iterator_pre; - } - - value_type operator*() const { - switch (m_type) { - case iterator_type::NoneType: - return value_type(); - case iterator_type::Sequence: - return value_type(**m_seqIt); - case iterator_type::Map: - return value_type(*m_mapIt->first, *m_mapIt->second); - } - return value_type(); - } - - proxy operator->() const { return proxy(**this); } - - MapIter increment_until_defined(MapIter it) { - while (it != m_mapEnd && !is_defined(it)) - ++it; - return it; - } - - bool is_defined(MapIter it) const { - return it->first->is_defined() && it->second->is_defined(); - } - - private: - typename iterator_type::value m_type; - - SeqIter m_seqIt; - MapIter m_mapIt, m_mapEnd; -}; - -using node_iterator = node_iterator_base; -using const_node_iterator = node_iterator_base; -} -} - -#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h b/third/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h deleted file mode 100644 index d8a94f8b..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/type.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/detail/node_data.h" - -namespace YAML { -namespace detail { -class node_ref { - public: - node_ref() : m_pData(new node_data) {} - node_ref(const node_ref&) = delete; - node_ref& operator=(const node_ref&) = delete; - - bool is_defined() const { return m_pData->is_defined(); } - const Mark& mark() const { return m_pData->mark(); } - NodeType::value type() const { return m_pData->type(); } - const std::string& scalar() const { return m_pData->scalar(); } - const std::string& tag() const { return m_pData->tag(); } - EmitterStyle::value style() const { return m_pData->style(); } - - void mark_defined() { m_pData->mark_defined(); } - void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } - - void set_mark(const Mark& mark) { m_pData->set_mark(mark); } - void set_type(NodeType::value type) { m_pData->set_type(type); } - void set_tag(const std::string& tag) { m_pData->set_tag(tag); } - void set_null() { m_pData->set_null(); } - void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } - void set_style(EmitterStyle::value style) { m_pData->set_style(style); } - - // size/iterator - std::size_t size() const { return m_pData->size(); } - - const_node_iterator begin() const { - return static_cast(*m_pData).begin(); - } - node_iterator begin() { return m_pData->begin(); } - - const_node_iterator end() const { - return static_cast(*m_pData).end(); - } - node_iterator end() { return m_pData->end(); } - - // sequence - void push_back(node& node, shared_memory_holder pMemory) { - m_pData->push_back(node, pMemory); - } - void insert(node& key, node& value, shared_memory_holder pMemory) { - m_pData->insert(key, value, pMemory); - } - - // indexing - template - node* get(const Key& key, shared_memory_holder pMemory) const { - return static_cast(*m_pData).get(key, pMemory); - } - template - node& get(const Key& key, shared_memory_holder pMemory) { - return m_pData->get(key, pMemory); - } - template - bool remove(const Key& key, shared_memory_holder pMemory) { - return m_pData->remove(key, pMemory); - } - - node* get(node& key, shared_memory_holder pMemory) const { - return static_cast(*m_pData).get(key, pMemory); - } - node& get(node& key, shared_memory_holder pMemory) { - return m_pData->get(key, pMemory); - } - bool remove(node& key, shared_memory_holder pMemory) { - return m_pData->remove(key, pMemory); - } - - // map - template - void force_insert(const Key& key, const Value& value, - shared_memory_holder pMemory) { - m_pData->force_insert(key, value, pMemory); - } - - private: - shared_node_data m_pData; -}; -} -} - -#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/emit.h b/third/yaml-cpp/include/yaml-cpp/node/emit.h deleted file mode 100644 index 032268c5..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/emit.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -class Emitter; -class Node; - -/** - * Emits the node to the given {@link Emitter}. If there is an error in writing, - * {@link Emitter#good} will return false. - */ -YAML_CPP_API Emitter& operator<<(Emitter& out, const Node& node); - -/** Emits the node to the given output stream. */ -YAML_CPP_API std::ostream& operator<<(std::ostream& out, const Node& node); - -/** Converts the node to a YAML string. */ -YAML_CPP_API std::string Dump(const Node& node); -} // namespace YAML - -#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/impl.h b/third/yaml-cpp/include/yaml-cpp/node/impl.h deleted file mode 100644 index 312281f1..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/impl.h +++ /dev/null @@ -1,385 +0,0 @@ -#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/exceptions.h" -#include "yaml-cpp/node/detail/memory.h" -#include "yaml-cpp/node/detail/node.h" -#include "yaml-cpp/node/iterator.h" -#include "yaml-cpp/node/node.h" -#include -#include - -namespace YAML { -inline Node::Node() - : m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {} - -inline Node::Node(NodeType::value type) - : m_isValid(true), - m_invalidKey{}, - m_pMemory(new detail::memory_holder), - m_pNode(&m_pMemory->create_node()) { - m_pNode->set_type(type); -} - -template -inline Node::Node(const T& rhs) - : m_isValid(true), - m_invalidKey{}, - m_pMemory(new detail::memory_holder), - m_pNode(&m_pMemory->create_node()) { - Assign(rhs); -} - -inline Node::Node(const detail::iterator_value& rhs) - : m_isValid(rhs.m_isValid), - m_invalidKey(rhs.m_invalidKey), - m_pMemory(rhs.m_pMemory), - m_pNode(rhs.m_pNode) {} - -inline Node::Node(const Node&) = default; - -inline Node::Node(Zombie) - : m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {} - -inline Node::Node(Zombie, const std::string& key) - : m_isValid(false), m_invalidKey(key), m_pMemory{}, m_pNode(nullptr) {} - -inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory) - : m_isValid(true), m_invalidKey{}, m_pMemory(pMemory), m_pNode(&node) {} - -inline Node::~Node() = default; - -inline void Node::EnsureNodeExists() const { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - if (!m_pNode) { - m_pMemory.reset(new detail::memory_holder); - m_pNode = &m_pMemory->create_node(); - m_pNode->set_null(); - } -} - -inline bool Node::IsDefined() const { - if (!m_isValid) { - return false; - } - return m_pNode ? m_pNode->is_defined() : true; -} - -inline Mark Node::Mark() const { - if (!m_isValid) { - throw InvalidNode(m_invalidKey); - } - return m_pNode ? m_pNode->mark() : Mark::null_mark(); -} - -inline NodeType::value Node::Type() const { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - return m_pNode ? m_pNode->type() : NodeType::Null; -} - -// access - -// template helpers -template -struct as_if { - explicit as_if(const Node& node_) : node(node_) {} - const Node& node; - - T operator()(const S& fallback) const { - if (!node.m_pNode) - return fallback; - - T t; - if (convert::decode(node, t)) - return t; - return fallback; - } -}; - -template -struct as_if { - explicit as_if(const Node& node_) : node(node_) {} - const Node& node; - - std::string operator()(const S& fallback) const { - if (node.Type() == NodeType::Null) - return "null"; - if (node.Type() != NodeType::Scalar) - return fallback; - return node.Scalar(); - } -}; - -template -struct as_if { - explicit as_if(const Node& node_) : node(node_) {} - const Node& node; - - T operator()() const { - if (!node.m_pNode) - throw TypedBadConversion(node.Mark()); - - T t; - if (convert::decode(node, t)) - return t; - throw TypedBadConversion(node.Mark()); - } -}; - -template <> -struct as_if { - explicit as_if(const Node& node_) : node(node_) {} - const Node& node; - - std::string operator()() const { - if (node.Type() == NodeType::Null) - return "null"; - if (node.Type() != NodeType::Scalar) - throw TypedBadConversion(node.Mark()); - return node.Scalar(); - } -}; - -// access functions -template -inline T Node::as() const { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - return as_if(*this)(); -} - -template -inline T Node::as(const S& fallback) const { - if (!m_isValid) - return fallback; - return as_if(*this)(fallback); -} - -inline const std::string& Node::Scalar() const { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar(); -} - -inline const std::string& Node::Tag() const { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar(); -} - -inline void Node::SetTag(const std::string& tag) { - EnsureNodeExists(); - m_pNode->set_tag(tag); -} - -inline EmitterStyle::value Node::Style() const { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - return m_pNode ? m_pNode->style() : EmitterStyle::Default; -} - -inline void Node::SetStyle(EmitterStyle::value style) { - EnsureNodeExists(); - m_pNode->set_style(style); -} - -// assignment -inline bool Node::is(const Node& rhs) const { - if (!m_isValid || !rhs.m_isValid) - throw InvalidNode(m_invalidKey); - if (!m_pNode || !rhs.m_pNode) - return false; - return m_pNode->is(*rhs.m_pNode); -} - -template -inline Node& Node::operator=(const T& rhs) { - Assign(rhs); - return *this; -} - -inline Node& Node::operator=(const Node& rhs) { - if (is(rhs)) - return *this; - AssignNode(rhs); - return *this; -} - -inline void Node::reset(const YAML::Node& rhs) { - if (!m_isValid || !rhs.m_isValid) - throw InvalidNode(m_invalidKey); - m_pMemory = rhs.m_pMemory; - m_pNode = rhs.m_pNode; -} - -template -inline void Node::Assign(const T& rhs) { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - AssignData(convert::encode(rhs)); -} - -template <> -inline void Node::Assign(const std::string& rhs) { - EnsureNodeExists(); - m_pNode->set_scalar(rhs); -} - -inline void Node::Assign(const char* rhs) { - EnsureNodeExists(); - m_pNode->set_scalar(rhs); -} - -inline void Node::Assign(char* rhs) { - EnsureNodeExists(); - m_pNode->set_scalar(rhs); -} - -inline void Node::AssignData(const Node& rhs) { - EnsureNodeExists(); - rhs.EnsureNodeExists(); - - m_pNode->set_data(*rhs.m_pNode); - m_pMemory->merge(*rhs.m_pMemory); -} - -inline void Node::AssignNode(const Node& rhs) { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - rhs.EnsureNodeExists(); - - if (!m_pNode) { - m_pNode = rhs.m_pNode; - m_pMemory = rhs.m_pMemory; - return; - } - - m_pNode->set_ref(*rhs.m_pNode); - m_pMemory->merge(*rhs.m_pMemory); - m_pNode = rhs.m_pNode; -} - -// size/iterator -inline std::size_t Node::size() const { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - return m_pNode ? m_pNode->size() : 0; -} - -inline const_iterator Node::begin() const { - if (!m_isValid) - return const_iterator(); - return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) - : const_iterator(); -} - -inline iterator Node::begin() { - if (!m_isValid) - return iterator(); - return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator(); -} - -inline const_iterator Node::end() const { - if (!m_isValid) - return const_iterator(); - return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator(); -} - -inline iterator Node::end() { - if (!m_isValid) - return iterator(); - return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator(); -} - -// sequence -template -inline void Node::push_back(const T& rhs) { - if (!m_isValid) - throw InvalidNode(m_invalidKey); - push_back(Node(rhs)); -} - -inline void Node::push_back(const Node& rhs) { - EnsureNodeExists(); - rhs.EnsureNodeExists(); - - m_pNode->push_back(*rhs.m_pNode, m_pMemory); - m_pMemory->merge(*rhs.m_pMemory); -} - -template -std::string key_to_string(const Key& key) { - return streamable_to_string::value>().impl(key); -} - -// indexing -template -inline const Node Node::operator[](const Key& key) const { - EnsureNodeExists(); - detail::node* value = - static_cast(*m_pNode).get(key, m_pMemory); - if (!value) { - return Node(ZombieNode, key_to_string(key)); - } - return Node(*value, m_pMemory); -} - -template -inline Node Node::operator[](const Key& key) { - EnsureNodeExists(); - detail::node& value = m_pNode->get(key, m_pMemory); - return Node(value, m_pMemory); -} - -template -inline bool Node::remove(const Key& key) { - EnsureNodeExists(); - return m_pNode->remove(key, m_pMemory); -} - -inline const Node Node::operator[](const Node& key) const { - EnsureNodeExists(); - key.EnsureNodeExists(); - m_pMemory->merge(*key.m_pMemory); - detail::node* value = - static_cast(*m_pNode).get(*key.m_pNode, m_pMemory); - if (!value) { - return Node(ZombieNode, key_to_string(key)); - } - return Node(*value, m_pMemory); -} - -inline Node Node::operator[](const Node& key) { - EnsureNodeExists(); - key.EnsureNodeExists(); - m_pMemory->merge(*key.m_pMemory); - detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory); - return Node(value, m_pMemory); -} - -inline bool Node::remove(const Node& key) { - EnsureNodeExists(); - key.EnsureNodeExists(); - return m_pNode->remove(*key.m_pNode, m_pMemory); -} - -// map -template -inline void Node::force_insert(const Key& key, const Value& value) { - EnsureNodeExists(); - m_pNode->force_insert(key, value, m_pMemory); -} - -// free functions -inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); } -} // namespace YAML - -#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/iterator.h b/third/yaml-cpp/include/yaml-cpp/node/iterator.h deleted file mode 100644 index 1fcf6e40..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/iterator.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/detail/iterator_fwd.h" -#include "yaml-cpp/node/detail/iterator.h" -#include -#include -#include - -// Assert in place so gcc + libc++ combination properly builds -static_assert(std::is_constructible::value, "Node must be copy constructable"); - -namespace YAML { -namespace detail { -struct iterator_value : public Node, std::pair { - iterator_value() = default; - explicit iterator_value(const Node& rhs) - : Node(rhs), - std::pair(Node(Node::ZombieNode), Node(Node::ZombieNode)) {} - explicit iterator_value(const Node& key, const Node& value) - : Node(Node::ZombieNode), std::pair(key, value) {} -}; -} -} - -#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/node.h b/third/yaml-cpp/include/yaml-cpp/node/node.h deleted file mode 100644 index c9e9a0a4..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/node.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/mark.h" -#include "yaml-cpp/node/detail/iterator_fwd.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -namespace detail { -class node; -class node_data; -struct iterator_value; -} // namespace detail -} // namespace YAML - -namespace YAML { -class YAML_CPP_API Node { - public: - friend class NodeBuilder; - friend class NodeEvents; - friend struct detail::iterator_value; - friend class detail::node; - friend class detail::node_data; - template - friend class detail::iterator_base; - template - friend struct as_if; - - using iterator = YAML::iterator; - using const_iterator = YAML::const_iterator; - - Node(); - explicit Node(NodeType::value type); - template - explicit Node(const T& rhs); - explicit Node(const detail::iterator_value& rhs); - Node(const Node& rhs); - ~Node(); - - YAML::Mark Mark() const; - NodeType::value Type() const; - bool IsDefined() const; - bool IsNull() const { return Type() == NodeType::Null; } - bool IsScalar() const { return Type() == NodeType::Scalar; } - bool IsSequence() const { return Type() == NodeType::Sequence; } - bool IsMap() const { return Type() == NodeType::Map; } - - // bool conversions - explicit operator bool() const { return IsDefined(); } - bool operator!() const { return !IsDefined(); } - - // access - template - T as() const; - template - T as(const S& fallback) const; - const std::string& Scalar() const; - - const std::string& Tag() const; - void SetTag(const std::string& tag); - - // style - // WARNING: This API might change in future releases. - EmitterStyle::value Style() const; - void SetStyle(EmitterStyle::value style); - - // assignment - bool is(const Node& rhs) const; - template - Node& operator=(const T& rhs); - Node& operator=(const Node& rhs); - void reset(const Node& rhs = Node()); - - // size/iterator - std::size_t size() const; - - const_iterator begin() const; - iterator begin(); - - const_iterator end() const; - iterator end(); - - // sequence - template - void push_back(const T& rhs); - void push_back(const Node& rhs); - - // indexing - template - const Node operator[](const Key& key) const; - template - Node operator[](const Key& key); - template - bool remove(const Key& key); - - const Node operator[](const Node& key) const; - Node operator[](const Node& key); - bool remove(const Node& key); - - // map - template - void force_insert(const Key& key, const Value& value); - - private: - enum Zombie { ZombieNode }; - explicit Node(Zombie); - explicit Node(Zombie, const std::string&); - explicit Node(detail::node& node, detail::shared_memory_holder pMemory); - - void EnsureNodeExists() const; - - template - void Assign(const T& rhs); - void Assign(const char* rhs); - void Assign(char* rhs); - - void AssignData(const Node& rhs); - void AssignNode(const Node& rhs); - - private: - bool m_isValid; - // String representation of invalid key, if the node is invalid. - std::string m_invalidKey; - mutable detail::shared_memory_holder m_pMemory; - mutable detail::node* m_pNode; -}; - -YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs); - -YAML_CPP_API Node Clone(const Node& node); - -template -struct convert; -} - -#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/parse.h b/third/yaml-cpp/include/yaml-cpp/node/parse.h deleted file mode 100644 index 7745fd72..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/parse.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -class Node; - -/** - * Loads the input string as a single YAML document. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API Node Load(const std::string& input); - -/** - * Loads the input string as a single YAML document. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API Node Load(const char* input); - -/** - * Loads the input stream as a single YAML document. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API Node Load(std::istream& input); - -/** - * Loads the input file as a single YAML document. - * - * @throws {@link ParserException} if it is malformed. - * @throws {@link BadFile} if the file cannot be loaded. - */ -YAML_CPP_API Node LoadFile(const std::string& filename); - -/** - * Loads the input string as a list of YAML documents. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API std::vector LoadAll(const std::string& input); - -/** - * Loads the input string as a list of YAML documents. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API std::vector LoadAll(const char* input); - -/** - * Loads the input stream as a list of YAML documents. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API std::vector LoadAll(std::istream& input); - -/** - * Loads the input file as a list of YAML documents. - * - * @throws {@link ParserException} if it is malformed. - * @throws {@link BadFile} if the file cannot be loaded. - */ -YAML_CPP_API std::vector LoadAllFromFile(const std::string& filename); -} // namespace YAML - -#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/ptr.h b/third/yaml-cpp/include/yaml-cpp/node/ptr.h deleted file mode 100644 index f55d95ed..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/ptr.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -namespace YAML { -namespace detail { -class node; -class node_ref; -class node_data; -class memory; -class memory_holder; - -using shared_node = std::shared_ptr; -using shared_node_ref = std::shared_ptr; -using shared_node_data = std::shared_ptr; -using shared_memory_holder = std::shared_ptr; -using shared_memory = std::shared_ptr; -} -} - -#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/node/type.h b/third/yaml-cpp/include/yaml-cpp/node/type.h deleted file mode 100644 index 9d55ca96..00000000 --- a/third/yaml-cpp/include/yaml-cpp/node/type.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -namespace YAML { -struct NodeType { - enum value { Undefined, Null, Scalar, Sequence, Map }; -}; -} - -#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/noexcept.h b/third/yaml-cpp/include/yaml-cpp/noexcept.h deleted file mode 100644 index 6aac6351..00000000 --- a/third/yaml-cpp/include/yaml-cpp/noexcept.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8 -#define NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -// This is here for compatibility with older versions of Visual Studio -// which don't support noexcept. -#if defined(_MSC_VER) && _MSC_VER < 1900 - #define YAML_CPP_NOEXCEPT _NOEXCEPT -#else - #define YAML_CPP_NOEXCEPT noexcept -#endif - -#endif diff --git a/third/yaml-cpp/include/yaml-cpp/null.h b/third/yaml-cpp/include/yaml-cpp/null.h deleted file mode 100644 index b9521d48..00000000 --- a/third/yaml-cpp/include/yaml-cpp/null.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include - -namespace YAML { -class Node; - -struct YAML_CPP_API _Null {}; -inline bool operator==(const _Null&, const _Null&) { return true; } -inline bool operator!=(const _Null&, const _Null&) { return false; } - -YAML_CPP_API bool IsNull(const Node& node); // old API only -YAML_CPP_API bool IsNullString(const std::string& str); - -extern YAML_CPP_API _Null Null; -} - -#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/ostream_wrapper.h b/third/yaml-cpp/include/yaml-cpp/ostream_wrapper.h deleted file mode 100644 index cf89741d..00000000 --- a/third/yaml-cpp/include/yaml-cpp/ostream_wrapper.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -class YAML_CPP_API ostream_wrapper { - public: - ostream_wrapper(); - explicit ostream_wrapper(std::ostream& stream); - ostream_wrapper(const ostream_wrapper&) = delete; - ostream_wrapper(ostream_wrapper&&) = delete; - ostream_wrapper& operator=(const ostream_wrapper&) = delete; - ostream_wrapper& operator=(ostream_wrapper&&) = delete; - ~ostream_wrapper(); - - void write(const std::string& str); - void write(const char* str, std::size_t size); - - void set_comment() { m_comment = true; } - - const char* str() const { - if (m_pStream) { - return nullptr; - } else { - m_buffer[m_pos] = '\0'; - return &m_buffer[0]; - } - } - - std::size_t row() const { return m_row; } - std::size_t col() const { return m_col; } - std::size_t pos() const { return m_pos; } - bool comment() const { return m_comment; } - - private: - void update_pos(char ch); - - private: - mutable std::vector m_buffer; - std::ostream* const m_pStream; - - std::size_t m_pos; - std::size_t m_row, m_col; - bool m_comment; -}; - -template -inline ostream_wrapper& operator<<(ostream_wrapper& stream, - const char (&str)[N]) { - stream.write(str, N - 1); - return stream; -} - -inline ostream_wrapper& operator<<(ostream_wrapper& stream, - const std::string& str) { - stream.write(str); - return stream; -} - -inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) { - stream.write(&ch, 1); - return stream; -} -} // namespace YAML - -#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/parser.h b/third/yaml-cpp/include/yaml-cpp/parser.h deleted file mode 100644 index 2f403c35..00000000 --- a/third/yaml-cpp/include/yaml-cpp/parser.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -class EventHandler; -class Node; -class Scanner; -struct Directives; -struct Token; - -/** - * A parser turns a stream of bytes into one stream of "events" per YAML - * document in the input stream. - */ -class YAML_CPP_API Parser { - public: - /** Constructs an empty parser (with no input. */ - Parser(); - - Parser(const Parser&) = delete; - Parser(Parser&&) = delete; - Parser& operator=(const Parser&) = delete; - Parser& operator=(Parser&&) = delete; - - /** - * Constructs a parser from the given input stream. The input stream must - * live as long as the parser. - */ - explicit Parser(std::istream& in); - - ~Parser(); - - /** Evaluates to true if the parser has some valid input to be read. */ - explicit operator bool() const; - - /** - * Resets the parser with the given input stream. Any existing state is - * erased. - */ - void Load(std::istream& in); - - /** - * Handles the next document by calling events on the {@code eventHandler}. - * - * @throw a ParserException on error. - * @return false if there are no more documents - */ - bool HandleNextDocument(EventHandler& eventHandler); - - void PrintTokens(std::ostream& out); - - private: - /** - * Reads any directives that are next in the queue, setting the internal - * {@code m_pDirectives} state. - */ - void ParseDirectives(); - - void HandleDirective(const Token& token); - - /** - * Handles a "YAML" directive, which should be of the form 'major.minor' (like - * a version number). - */ - void HandleYamlDirective(const Token& token); - - /** - * Handles a "TAG" directive, which should be of the form 'handle prefix', - * where 'handle' is converted to 'prefix' in the file. - */ - void HandleTagDirective(const Token& token); - - private: - std::unique_ptr m_pScanner; - std::unique_ptr m_pDirectives; -}; -} // namespace YAML - -#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/stlemitter.h b/third/yaml-cpp/include/yaml-cpp/stlemitter.h deleted file mode 100644 index 210a2f64..00000000 --- a/third/yaml-cpp/include/yaml-cpp/stlemitter.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include - -namespace YAML { -template -inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) { - emitter << BeginSeq; - for (const auto& v : seq) - emitter << v; - emitter << EndSeq; - return emitter; -} - -template -inline Emitter& operator<<(Emitter& emitter, const std::vector& v) { - return EmitSeq(emitter, v); -} - -template -inline Emitter& operator<<(Emitter& emitter, const std::list& v) { - return EmitSeq(emitter, v); -} - -template -inline Emitter& operator<<(Emitter& emitter, const std::set& v) { - return EmitSeq(emitter, v); -} - -template -inline Emitter& operator<<(Emitter& emitter, const std::map& m) { - emitter << BeginMap; - for (const auto& v : m) - emitter << Key << v.first << Value << v.second; - emitter << EndMap; - return emitter; -} -} - -#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/traits.h b/third/yaml-cpp/include/yaml-cpp/traits.h deleted file mode 100644 index ffe9999f..00000000 --- a/third/yaml-cpp/include/yaml-cpp/traits.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include - -namespace YAML { -template -struct is_numeric { - enum { value = false }; -}; - -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -#if defined(_MSC_VER) && (_MSC_VER < 1310) -template <> -struct is_numeric<__int64> { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -#else -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -#endif -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; - -template -struct enable_if_c { - using type = T; -}; - -template -struct enable_if_c {}; - -template -struct enable_if : public enable_if_c {}; - -template -struct disable_if_c { - using type = T; -}; - -template -struct disable_if_c {}; - -template -struct disable_if : public disable_if_c {}; -} - -template -struct is_streamable { - template - static auto test(int) - -> decltype(std::declval() << std::declval(), std::true_type()); - - template - static auto test(...) -> std::false_type; - - static const bool value = decltype(test(0))::value; -}; - -template -struct streamable_to_string { - static std::string impl(const Key& key) { - std::stringstream ss; - ss << key; - return ss.str(); - } -}; - -template -struct streamable_to_string { - static std::string impl(const Key&) { - return ""; - } -}; -#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/include/yaml-cpp/yaml.h b/third/yaml-cpp/include/yaml-cpp/yaml.h deleted file mode 100644 index 7f515efb..00000000 --- a/third/yaml-cpp/include/yaml-cpp/yaml.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/parser.h" -#include "yaml-cpp/emitter.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/stlemitter.h" -#include "yaml-cpp/exceptions.h" - -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/impl.h" -#include "yaml-cpp/node/convert.h" -#include "yaml-cpp/node/iterator.h" -#include "yaml-cpp/node/detail/impl.h" -#include "yaml-cpp/node/parse.h" -#include "yaml-cpp/node/emit.h" - -#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/install.txt b/third/yaml-cpp/install.txt deleted file mode 100644 index 93923624..00000000 --- a/third/yaml-cpp/install.txt +++ /dev/null @@ -1,24 +0,0 @@ -*** With CMake *** - -yaml-cpp uses CMake to support cross-platform building. In a UNIX-like system, the basic steps to build are: - -1. Download and install CMake (if you don't have root privileges, just install to a local directory, like ~/bin) - -2. From the source directory, run: - -mkdir build -cd build -cmake .. - -and then the usual - -make -make install - -3. To clean up, just remove the 'build' directory. - -*** Without CMake *** - -If you don't want to use CMake, just add all .cpp files to a makefile. yaml-cpp does not need any special build settings, so no 'configure' file is necessary. - -(Note: this is pretty tedious. It's sooo much easier to use CMake.) diff --git a/third/yaml-cpp/src/binary.cpp b/third/yaml-cpp/src/binary.cpp deleted file mode 100644 index d27762a2..00000000 --- a/third/yaml-cpp/src/binary.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "yaml-cpp/binary.h" - -#include - -namespace YAML { -static const char encoding[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -std::string EncodeBase64(const unsigned char *data, std::size_t size) { - const char PAD = '='; - - std::string ret; - ret.resize(4 * size / 3 + 3); - char *out = &ret[0]; - - std::size_t chunks = size / 3; - std::size_t remainder = size % 3; - - for (std::size_t i = 0; i < chunks; i++, data += 3) { - *out++ = encoding[data[0] >> 2]; - *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; - *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)]; - *out++ = encoding[data[2] & 0x3f]; - } - - switch (remainder) { - case 0: - break; - case 1: - *out++ = encoding[data[0] >> 2]; - *out++ = encoding[((data[0] & 0x3) << 4)]; - *out++ = PAD; - *out++ = PAD; - break; - case 2: - *out++ = encoding[data[0] >> 2]; - *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; - *out++ = encoding[((data[1] & 0xf) << 2)]; - *out++ = PAD; - break; - } - - ret.resize(out - &ret[0]); - return ret; -} - -static const unsigned char decoding[] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, - 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, - 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, -}; - -std::vector DecodeBase64(const std::string &input) { - using ret_type = std::vector; - if (input.empty()) - return ret_type(); - - ret_type ret(3 * input.size() / 4 + 1); - unsigned char *out = &ret[0]; - - unsigned value = 0; - for (std::size_t i = 0, cnt = 0; i < input.size(); i++) { - if (std::isspace(static_cast(input[i]))) { - // skip newlines - continue; - } - unsigned char d = decoding[static_cast(input[i])]; - if (d == 255) - return ret_type(); - - value = (value << 6) | d; - if (cnt % 4 == 3) { - *out++ = value >> 16; - if (i > 0 && input[i - 1] != '=') - *out++ = value >> 8; - if (input[i] != '=') - *out++ = value; - } - ++cnt; - } - - ret.resize(out - &ret[0]); - return ret; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/collectionstack.h b/third/yaml-cpp/src/collectionstack.h deleted file mode 100644 index 9feba967..00000000 --- a/third/yaml-cpp/src/collectionstack.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -namespace YAML { -struct CollectionType { - enum value { NoCollection, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap }; -}; - -class CollectionStack { - public: - CollectionStack() : collectionStack{} {} - CollectionType::value GetCurCollectionType() const { - if (collectionStack.empty()) - return CollectionType::NoCollection; - return collectionStack.top(); - } - - void PushCollectionType(CollectionType::value type) { - collectionStack.push(type); - } - void PopCollectionType(CollectionType::value type) { - assert(type == GetCurCollectionType()); - (void)type; - collectionStack.pop(); - } - - private: - std::stack collectionStack; -}; -} // namespace YAML - -#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/contrib/graphbuilder.cpp b/third/yaml-cpp/src/contrib/graphbuilder.cpp deleted file mode 100644 index 0352054c..00000000 --- a/third/yaml-cpp/src/contrib/graphbuilder.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "graphbuilderadapter.h" - -#include "yaml-cpp/parser.h" // IWYU pragma: keep - -namespace YAML { -class GraphBuilderInterface; - -void* BuildGraphOfNextDocument(Parser& parser, - GraphBuilderInterface& graphBuilder) { - GraphBuilderAdapter eventHandler(graphBuilder); - if (parser.HandleNextDocument(eventHandler)) { - return eventHandler.RootNode(); - } - return nullptr; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/contrib/graphbuilderadapter.cpp b/third/yaml-cpp/src/contrib/graphbuilderadapter.cpp deleted file mode 100644 index c386a927..00000000 --- a/third/yaml-cpp/src/contrib/graphbuilderadapter.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "graphbuilderadapter.h" -#include "yaml-cpp/contrib/graphbuilder.h" - -namespace YAML { -struct Mark; - -int GraphBuilderAdapter::ContainerFrame::sequenceMarker; - -void GraphBuilderAdapter::OnNull(const Mark &mark, anchor_t anchor) { - void *pParent = GetCurrentParent(); - void *pNode = m_builder.NewNull(mark, pParent); - RegisterAnchor(anchor, pNode); - - DispositionNode(pNode); -} - -void GraphBuilderAdapter::OnAlias(const Mark &mark, anchor_t anchor) { - void *pReffedNode = m_anchors.Get(anchor); - DispositionNode(m_builder.AnchorReference(mark, pReffedNode)); -} - -void GraphBuilderAdapter::OnScalar(const Mark &mark, const std::string &tag, - anchor_t anchor, const std::string &value) { - void *pParent = GetCurrentParent(); - void *pNode = m_builder.NewScalar(mark, tag, pParent, value); - RegisterAnchor(anchor, pNode); - - DispositionNode(pNode); -} - -void GraphBuilderAdapter::OnSequenceStart(const Mark &mark, - const std::string &tag, - anchor_t anchor, - EmitterStyle::value /* style */) { - void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent()); - m_containers.push(ContainerFrame(pNode)); - RegisterAnchor(anchor, pNode); -} - -void GraphBuilderAdapter::OnSequenceEnd() { - void *pSequence = m_containers.top().pContainer; - m_containers.pop(); - - DispositionNode(pSequence); -} - -void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag, - anchor_t anchor, - EmitterStyle::value /* style */) { - void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent()); - m_containers.push(ContainerFrame(pNode, m_pKeyNode)); - m_pKeyNode = nullptr; - RegisterAnchor(anchor, pNode); -} - -void GraphBuilderAdapter::OnMapEnd() { - void *pMap = m_containers.top().pContainer; - m_pKeyNode = m_containers.top().pPrevKeyNode; - m_containers.pop(); - DispositionNode(pMap); -} - -void *GraphBuilderAdapter::GetCurrentParent() const { - if (m_containers.empty()) { - return nullptr; - } - return m_containers.top().pContainer; -} - -void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) { - if (anchor) { - m_anchors.Register(anchor, pNode); - } -} - -void GraphBuilderAdapter::DispositionNode(void *pNode) { - if (m_containers.empty()) { - m_pRootNode = pNode; - return; - } - - void *pContainer = m_containers.top().pContainer; - if (m_containers.top().isMap()) { - if (m_pKeyNode) { - m_builder.AssignInMap(pContainer, m_pKeyNode, pNode); - m_pKeyNode = nullptr; - } else { - m_pKeyNode = pNode; - } - } else { - m_builder.AppendToSequence(pContainer, pNode); - } -} -} // namespace YAML diff --git a/third/yaml-cpp/src/contrib/graphbuilderadapter.h b/third/yaml-cpp/src/contrib/graphbuilderadapter.h deleted file mode 100644 index c1cbcffd..00000000 --- a/third/yaml-cpp/src/contrib/graphbuilderadapter.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/contrib/anchordict.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" - -namespace YAML { -class GraphBuilderInterface; -struct Mark; -} // namespace YAML - -namespace YAML { -class GraphBuilderAdapter : public EventHandler { - public: - GraphBuilderAdapter(GraphBuilderInterface& builder) - : m_builder(builder), - m_containers{}, - m_anchors{}, - m_pRootNode(nullptr), - m_pKeyNode(nullptr) {} - GraphBuilderAdapter(const GraphBuilderAdapter&) = delete; - GraphBuilderAdapter(GraphBuilderAdapter&&) = delete; - GraphBuilderAdapter& operator=(const GraphBuilderAdapter&) = delete; - GraphBuilderAdapter& operator=(GraphBuilderAdapter&&) = delete; - - virtual void OnDocumentStart(const Mark& mark) { (void)mark; } - virtual void OnDocumentEnd() {} - - virtual void OnNull(const Mark& mark, anchor_t anchor); - virtual void OnAlias(const Mark& mark, anchor_t anchor); - virtual void OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value); - - virtual void OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style); - virtual void OnSequenceEnd(); - - virtual void OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style); - virtual void OnMapEnd(); - - void* RootNode() const { return m_pRootNode; } - - private: - struct ContainerFrame { - ContainerFrame(void* pSequence) - : pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {} - ContainerFrame(void* pMap, void* pPreviousKeyNode) - : pContainer(pMap), pPrevKeyNode(pPreviousKeyNode) {} - - void* pContainer; - void* pPrevKeyNode; - - bool isMap() const { return pPrevKeyNode != &sequenceMarker; } - - private: - static int sequenceMarker; - }; - typedef std::stack ContainerStack; - typedef AnchorDict AnchorMap; - - GraphBuilderInterface& m_builder; - ContainerStack m_containers; - AnchorMap m_anchors; - void* m_pRootNode; - void* m_pKeyNode; - - void* GetCurrentParent() const; - void RegisterAnchor(anchor_t anchor, void* pNode); - void DispositionNode(void* pNode); -}; -} // namespace YAML - -#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/contrib/yaml-cpp.natvis b/third/yaml-cpp/src/contrib/yaml-cpp.natvis deleted file mode 100644 index d5c222be..00000000 --- a/third/yaml-cpp/src/contrib/yaml-cpp.natvis +++ /dev/null @@ -1,32 +0,0 @@ - - - - - {{invalid}} - {{pNode==nullptr}} - {{ {*m_pNode} }} - - m_pNode->m_pRef._Ptr->m_pData._Ptr->m_scalar - m_pNode->m_pRef._Ptr->m_pData._Ptr->m_sequence - m_pNode->m_pRef._Ptr->m_pData._Ptr->m_map - m_pNode->m_pRef._Ptr->m_pData._Ptr - - - - - {{node:pRef==nullptr}} - {{node:pRef->pData==nullptr}} - {{undefined}} - {{{m_pRef._Ptr->m_pData._Ptr->m_scalar}}} - {{ Map {m_pRef._Ptr->m_pData._Ptr->m_map}}} - {{ Seq {m_pRef._Ptr->m_pData._Ptr->m_sequence}}} - {{{m_pRef._Ptr->m_pData._Ptr->m_type}}} - - m_pRef._Ptr->m_pData._Ptr->m_scalar - m_pRef._Ptr->m_pData._Ptr->m_sequence - m_pRef._Ptr->m_pData._Ptr->m_map - m_pRef._Ptr->m_pData._Ptr - - - - diff --git a/third/yaml-cpp/src/contrib/yaml-cpp.natvis.md b/third/yaml-cpp/src/contrib/yaml-cpp.natvis.md deleted file mode 100644 index f1d68a86..00000000 --- a/third/yaml-cpp/src/contrib/yaml-cpp.natvis.md +++ /dev/null @@ -1,9 +0,0 @@ -# MSVC debugger visualizer for YAML::Node - -## How to use -Add yaml-cpp.natvis to your Visual C++ project like any other source file. It will be included in the debug information, and improve debugger display on YAML::Node and contained types. - -## Compatibility and Troubleshooting - -This has been tested for MSVC 2017. It is expected to be compatible with VS 2015 and VS 2019. If you have any problems, you can open an issue here: https://github.com/peterchen-cp/yaml-cpp-natvis - diff --git a/third/yaml-cpp/src/convert.cpp b/third/yaml-cpp/src/convert.cpp deleted file mode 100644 index 9658b360..00000000 --- a/third/yaml-cpp/src/convert.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include - -#include "yaml-cpp/node/convert.h" - -namespace { -// we're not gonna mess with the mess that is all the isupper/etc. functions -bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; } -bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; } -char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; } - -std::string tolower(const std::string& str) { - std::string s(str); - std::transform(s.begin(), s.end(), s.begin(), ToLower); - return s; -} - -template -bool IsEntirely(const std::string& str, T func) { - return std::all_of(str.begin(), str.end(), [=](char ch) { return func(ch); }); -} - -// IsFlexibleCase -// . Returns true if 'str' is: -// . UPPERCASE -// . lowercase -// . Capitalized -bool IsFlexibleCase(const std::string& str) { - if (str.empty()) - return true; - - if (IsEntirely(str, IsLower)) - return true; - - bool firstcaps = IsUpper(str[0]); - std::string rest = str.substr(1); - return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper)); -} -} // namespace - -namespace YAML { -bool convert::decode(const Node& node, bool& rhs) { - if (!node.IsScalar()) - return false; - - // we can't use iostream bool extraction operators as they don't - // recognize all possible values in the table below (taken from - // http://yaml.org/type/bool.html) - static const struct { - std::string truename, falsename; - } names[] = { - {"y", "n"}, - {"yes", "no"}, - {"true", "false"}, - {"on", "off"}, - }; - - if (!IsFlexibleCase(node.Scalar())) - return false; - - for (const auto& name : names) { - if (name.truename == tolower(node.Scalar())) { - rhs = true; - return true; - } - - if (name.falsename == tolower(node.Scalar())) { - rhs = false; - return true; - } - } - - return false; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/depthguard.cpp b/third/yaml-cpp/src/depthguard.cpp deleted file mode 100644 index 5bf6cdf0..00000000 --- a/third/yaml-cpp/src/depthguard.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "yaml-cpp/depthguard.h" - -namespace YAML { - -DeepRecursion::DeepRecursion(int depth, const Mark& mark_, - const std::string& msg_) - : ParserException(mark_, msg_), m_depth(depth) {} - -} // namespace YAML diff --git a/third/yaml-cpp/src/directives.cpp b/third/yaml-cpp/src/directives.cpp deleted file mode 100644 index 4c1dc201..00000000 --- a/third/yaml-cpp/src/directives.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "directives.h" - -namespace YAML { -Directives::Directives() : version{true, 1, 2}, tags{} {} - -std::string Directives::TranslateTagHandle( - const std::string& handle) const { - auto it = tags.find(handle); - if (it == tags.end()) { - if (handle == "!!") - return "tag:yaml.org,2002:"; - return handle; - } - - return it->second; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/directives.h b/third/yaml-cpp/src/directives.h deleted file mode 100644 index 18d14c9c..00000000 --- a/third/yaml-cpp/src/directives.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -namespace YAML { -struct Version { - bool isDefault; - int major, minor; -}; - -struct Directives { - Directives(); - - std::string TranslateTagHandle(const std::string& handle) const; - - Version version; - std::map tags; -}; -} - -#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/emit.cpp b/third/yaml-cpp/src/emit.cpp deleted file mode 100644 index b0efb840..00000000 --- a/third/yaml-cpp/src/emit.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "yaml-cpp/node/emit.h" -#include "nodeevents.h" -#include "yaml-cpp/emitfromevents.h" -#include "yaml-cpp/emitter.h" - -namespace YAML { -Emitter& operator<<(Emitter& out, const Node& node) { - EmitFromEvents emitFromEvents(out); - NodeEvents events(node); - events.Emit(emitFromEvents); - return out; -} - -std::ostream& operator<<(std::ostream& out, const Node& node) { - Emitter emitter(out); - emitter << node; - return out; -} - -std::string Dump(const Node& node) { - Emitter emitter; - emitter << node; - return emitter.c_str(); -} -} // namespace YAML diff --git a/third/yaml-cpp/src/emitfromevents.cpp b/third/yaml-cpp/src/emitfromevents.cpp deleted file mode 100644 index 2e97187b..00000000 --- a/third/yaml-cpp/src/emitfromevents.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include - -#include "yaml-cpp/emitfromevents.h" -#include "yaml-cpp/emitter.h" -#include "yaml-cpp/emittermanip.h" -#include "yaml-cpp/null.h" - -namespace YAML { -struct Mark; -} // namespace YAML - -namespace { -std::string ToString(YAML::anchor_t anchor) { - std::stringstream stream; - stream << anchor; - return stream.str(); -} -} // namespace - -namespace YAML { -EmitFromEvents::EmitFromEvents(Emitter& emitter) - : m_emitter(emitter), m_stateStack{} {} - -void EmitFromEvents::OnDocumentStart(const Mark&) {} - -void EmitFromEvents::OnDocumentEnd() {} - -void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) { - BeginNode(); - EmitProps("", anchor); - m_emitter << Null; -} - -void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) { - BeginNode(); - m_emitter << Alias(ToString(anchor)); -} - -void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, - anchor_t anchor, const std::string& value) { - BeginNode(); - EmitProps(tag, anchor); - m_emitter << value; -} - -void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, - anchor_t anchor, - EmitterStyle::value style) { - BeginNode(); - EmitProps(tag, anchor); - switch (style) { - case EmitterStyle::Block: - m_emitter << Block; - break; - case EmitterStyle::Flow: - m_emitter << Flow; - break; - default: - break; - } - // Restore the global settings to eliminate the override from node style - m_emitter.RestoreGlobalModifiedSettings(); - m_emitter << BeginSeq; - m_stateStack.push(State::WaitingForSequenceEntry); -} - -void EmitFromEvents::OnSequenceEnd() { - m_emitter << EndSeq; - assert(m_stateStack.top() == State::WaitingForSequenceEntry); - m_stateStack.pop(); -} - -void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) { - BeginNode(); - EmitProps(tag, anchor); - switch (style) { - case EmitterStyle::Block: - m_emitter << Block; - break; - case EmitterStyle::Flow: - m_emitter << Flow; - break; - default: - break; - } - // Restore the global settings to eliminate the override from node style - m_emitter.RestoreGlobalModifiedSettings(); - m_emitter << BeginMap; - m_stateStack.push(State::WaitingForKey); -} - -void EmitFromEvents::OnMapEnd() { - m_emitter << EndMap; - assert(m_stateStack.top() == State::WaitingForKey); - m_stateStack.pop(); -} - -void EmitFromEvents::BeginNode() { - if (m_stateStack.empty()) - return; - - switch (m_stateStack.top()) { - case State::WaitingForKey: - m_emitter << Key; - m_stateStack.top() = State::WaitingForValue; - break; - case State::WaitingForValue: - m_emitter << Value; - m_stateStack.top() = State::WaitingForKey; - break; - default: - break; - } -} - -void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) { - if (!tag.empty() && tag != "?" && tag != "!") - m_emitter << VerbatimTag(tag); - if (anchor) - m_emitter << Anchor(ToString(anchor)); -} -} // namespace YAML diff --git a/third/yaml-cpp/src/emitter.cpp b/third/yaml-cpp/src/emitter.cpp deleted file mode 100644 index 4d483075..00000000 --- a/third/yaml-cpp/src/emitter.cpp +++ /dev/null @@ -1,972 +0,0 @@ -#include - -#include "emitterutils.h" -#include "indentation.h" // IWYU pragma: keep -#include "yaml-cpp/emitter.h" -#include "yaml-cpp/emitterdef.h" -#include "yaml-cpp/emittermanip.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -class Binary; -struct _Null; - -Emitter::Emitter() : m_pState(new EmitterState), m_stream{} {} - -Emitter::Emitter(std::ostream& stream) - : m_pState(new EmitterState), m_stream(stream) {} - -Emitter::~Emitter() = default; - -const char* Emitter::c_str() const { return m_stream.str(); } - -std::size_t Emitter::size() const { return m_stream.pos(); } - -// state checking -bool Emitter::good() const { return m_pState->good(); } - -const std::string Emitter::GetLastError() const { - return m_pState->GetLastError(); -} - -// global setters -bool Emitter::SetOutputCharset(EMITTER_MANIP value) { - return m_pState->SetOutputCharset(value, FmtScope::Global); -} - -bool Emitter::SetStringFormat(EMITTER_MANIP value) { - return m_pState->SetStringFormat(value, FmtScope::Global); -} - -bool Emitter::SetBoolFormat(EMITTER_MANIP value) { - bool ok = false; - if (m_pState->SetBoolFormat(value, FmtScope::Global)) - ok = true; - if (m_pState->SetBoolCaseFormat(value, FmtScope::Global)) - ok = true; - if (m_pState->SetBoolLengthFormat(value, FmtScope::Global)) - ok = true; - return ok; -} - -bool Emitter::SetNullFormat(EMITTER_MANIP value) { - return m_pState->SetNullFormat(value, FmtScope::Global); -} - -bool Emitter::SetIntBase(EMITTER_MANIP value) { - return m_pState->SetIntFormat(value, FmtScope::Global); -} - -bool Emitter::SetSeqFormat(EMITTER_MANIP value) { - return m_pState->SetFlowType(GroupType::Seq, value, FmtScope::Global); -} - -bool Emitter::SetMapFormat(EMITTER_MANIP value) { - bool ok = false; - if (m_pState->SetFlowType(GroupType::Map, value, FmtScope::Global)) - ok = true; - if (m_pState->SetMapKeyFormat(value, FmtScope::Global)) - ok = true; - return ok; -} - -bool Emitter::SetIndent(std::size_t n) { - return m_pState->SetIndent(n, FmtScope::Global); -} - -bool Emitter::SetPreCommentIndent(std::size_t n) { - return m_pState->SetPreCommentIndent(n, FmtScope::Global); -} - -bool Emitter::SetPostCommentIndent(std::size_t n) { - return m_pState->SetPostCommentIndent(n, FmtScope::Global); -} - -bool Emitter::SetFloatPrecision(std::size_t n) { - return m_pState->SetFloatPrecision(n, FmtScope::Global); -} - -bool Emitter::SetDoublePrecision(std::size_t n) { - return m_pState->SetDoublePrecision(n, FmtScope::Global); -} - -void Emitter::RestoreGlobalModifiedSettings() { - m_pState->RestoreGlobalModifiedSettings(); -} - -// SetLocalValue -// . Either start/end a group, or set a modifier locally -Emitter& Emitter::SetLocalValue(EMITTER_MANIP value) { - if (!good()) - return *this; - - switch (value) { - case BeginDoc: - EmitBeginDoc(); - break; - case EndDoc: - EmitEndDoc(); - break; - case BeginSeq: - EmitBeginSeq(); - break; - case EndSeq: - EmitEndSeq(); - break; - case BeginMap: - EmitBeginMap(); - break; - case EndMap: - EmitEndMap(); - break; - case Key: - case Value: - // deprecated (these can be deduced by the parity of nodes in a map) - break; - case TagByKind: - EmitKindTag(); - break; - case Newline: - EmitNewline(); - break; - default: - m_pState->SetLocalValue(value); - break; - } - return *this; -} - -Emitter& Emitter::SetLocalIndent(const _Indent& indent) { - m_pState->SetIndent(indent.value, FmtScope::Local); - return *this; -} - -Emitter& Emitter::SetLocalPrecision(const _Precision& precision) { - if (precision.floatPrecision >= 0) - m_pState->SetFloatPrecision(precision.floatPrecision, FmtScope::Local); - if (precision.doublePrecision >= 0) - m_pState->SetDoublePrecision(precision.doublePrecision, FmtScope::Local); - return *this; -} - -// EmitBeginDoc -void Emitter::EmitBeginDoc() { - if (!good()) - return; - - if (m_pState->CurGroupType() != GroupType::NoType) { - m_pState->SetError("Unexpected begin document"); - return; - } - - if (m_pState->HasAnchor() || m_pState->HasTag()) { - m_pState->SetError("Unexpected begin document"); - return; - } - - if (m_stream.col() > 0) - m_stream << "\n"; - m_stream << "---\n"; - - m_pState->StartedDoc(); -} - -// EmitEndDoc -void Emitter::EmitEndDoc() { - if (!good()) - return; - - if (m_pState->CurGroupType() != GroupType::NoType) { - m_pState->SetError("Unexpected begin document"); - return; - } - - if (m_pState->HasAnchor() || m_pState->HasTag()) { - m_pState->SetError("Unexpected begin document"); - return; - } - - if (m_stream.col() > 0) - m_stream << "\n"; - m_stream << "...\n"; -} - -// EmitBeginSeq -void Emitter::EmitBeginSeq() { - if (!good()) - return; - - PrepareNode(m_pState->NextGroupType(GroupType::Seq)); - - m_pState->StartedGroup(GroupType::Seq); -} - -// EmitEndSeq -void Emitter::EmitEndSeq() { - if (!good()) - return; - FlowType::value originalType = m_pState->CurGroupFlowType(); - - if (m_pState->CurGroupChildCount() == 0) - m_pState->ForceFlow(); - - if (m_pState->CurGroupFlowType() == FlowType::Flow) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(m_pState->CurIndent()); - if (originalType == FlowType::Block) { - m_stream << "["; - } else { - if (m_pState->CurGroupChildCount() == 0 && !m_pState->HasBegunNode()) - m_stream << "["; - } - m_stream << "]"; - } - - m_pState->EndedGroup(GroupType::Seq); -} - -// EmitBeginMap -void Emitter::EmitBeginMap() { - if (!good()) - return; - - PrepareNode(m_pState->NextGroupType(GroupType::Map)); - - m_pState->StartedGroup(GroupType::Map); -} - -// EmitEndMap -void Emitter::EmitEndMap() { - if (!good()) - return; - FlowType::value originalType = m_pState->CurGroupFlowType(); - - if (m_pState->CurGroupChildCount() == 0) - m_pState->ForceFlow(); - - if (m_pState->CurGroupFlowType() == FlowType::Flow) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(m_pState->CurIndent()); - if (originalType == FlowType::Block) { - m_stream << "{"; - } else { - if (m_pState->CurGroupChildCount() == 0 && !m_pState->HasBegunNode()) - m_stream << "{"; - } - m_stream << "}"; - } - - m_pState->EndedGroup(GroupType::Map); -} - -// EmitNewline -void Emitter::EmitNewline() { - if (!good()) - return; - - PrepareNode(EmitterNodeType::NoType); - m_stream << "\n"; - m_pState->SetNonContent(); -} - -bool Emitter::CanEmitNewline() const { return true; } - -// Put the stream in a state so we can simply write the next node -// E.g., if we're in a sequence, write the "- " -void Emitter::PrepareNode(EmitterNodeType::value child) { - switch (m_pState->CurGroupNodeType()) { - case EmitterNodeType::NoType: - PrepareTopNode(child); - break; - case EmitterNodeType::FlowSeq: - FlowSeqPrepareNode(child); - break; - case EmitterNodeType::BlockSeq: - BlockSeqPrepareNode(child); - break; - case EmitterNodeType::FlowMap: - FlowMapPrepareNode(child); - break; - case EmitterNodeType::BlockMap: - BlockMapPrepareNode(child); - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - assert(false); - break; - } -} - -void Emitter::PrepareTopNode(EmitterNodeType::value child) { - if (child == EmitterNodeType::NoType) - return; - - if (m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0) - EmitBeginDoc(); - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - // TODO: if we were writing null, and - // we wanted it blank, we wouldn't want a space - SpaceOrIndentTo(m_pState->HasBegunContent(), 0); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - if (m_pState->HasBegunNode()) - m_stream << "\n"; - break; - } -} - -void Emitter::FlowSeqPrepareNode(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - if (m_pState->CurGroupChildCount() == 0) - m_stream << "["; - else - m_stream << ","; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::BlockSeqPrepareNode(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - const std::size_t nextIndent = curIndent + m_pState->CurGroupIndent(); - - if (child == EmitterNodeType::NoType) - return; - - if (!m_pState->HasBegunContent()) { - if (m_pState->CurGroupChildCount() > 0 || m_stream.comment()) { - m_stream << "\n"; - } - m_stream << IndentTo(curIndent); - m_stream << "-"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo(m_pState->HasBegunContent(), nextIndent); - break; - case EmitterNodeType::BlockSeq: - m_stream << "\n"; - break; - case EmitterNodeType::BlockMap: - if (m_pState->HasBegunContent() || m_stream.comment()) - m_stream << "\n"; - break; - } -} - -void Emitter::FlowMapPrepareNode(EmitterNodeType::value child) { - if (m_pState->CurGroupChildCount() % 2 == 0) { - if (m_pState->GetMapKeyFormat() == LongKey) - m_pState->SetLongKey(); - - if (m_pState->CurGroupLongKey()) - FlowMapPrepareLongKey(child); - else - FlowMapPrepareSimpleKey(child); - } else { - if (m_pState->CurGroupLongKey()) - FlowMapPrepareLongKeyValue(child); - else - FlowMapPrepareSimpleKeyValue(child); - } -} - -void Emitter::FlowMapPrepareLongKey(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - if (m_pState->CurGroupChildCount() == 0) - m_stream << "{ ?"; - else - m_stream << ", ?"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::FlowMapPrepareLongKeyValue(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - m_stream << ":"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::FlowMapPrepareSimpleKey(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - if (m_pState->CurGroupChildCount() == 0) - m_stream << "{"; - else - m_stream << ","; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - if (m_pState->HasAlias()) { - m_stream << " "; - } - m_stream << ":"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::BlockMapPrepareNode(EmitterNodeType::value child) { - if (m_pState->CurGroupChildCount() % 2 == 0) { - if (m_pState->GetMapKeyFormat() == LongKey) - m_pState->SetLongKey(); - if (child == EmitterNodeType::BlockSeq || - child == EmitterNodeType::BlockMap || - child == EmitterNodeType::Property) - m_pState->SetLongKey(); - - if (m_pState->CurGroupLongKey()) - BlockMapPrepareLongKey(child); - else - BlockMapPrepareSimpleKey(child); - } else { - if (m_pState->CurGroupLongKey()) - BlockMapPrepareLongKeyValue(child); - else - BlockMapPrepareSimpleKeyValue(child); - } -} - -void Emitter::BlockMapPrepareLongKey(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - const std::size_t childCount = m_pState->CurGroupChildCount(); - - if (child == EmitterNodeType::NoType) - return; - - if (!m_pState->HasBegunContent()) { - if (childCount > 0) { - m_stream << "\n"; - } - if (m_stream.comment()) { - m_stream << "\n"; - } - m_stream << IndentTo(curIndent); - m_stream << "?"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo(true, curIndent + 1); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - if (m_pState->HasBegunContent()) - m_stream << "\n"; - break; - } -} - -void Emitter::BlockMapPrepareLongKeyValue(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - - if (child == EmitterNodeType::NoType) - return; - - if (!m_pState->HasBegunContent()) { - m_stream << "\n"; - m_stream << IndentTo(curIndent); - m_stream << ":"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo(true, curIndent + 1); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - if (m_pState->HasBegunContent()) - m_stream << "\n"; - SpaceOrIndentTo(true, curIndent + 1); - break; - } -} - -void Emitter::BlockMapPrepareSimpleKey(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - const std::size_t childCount = m_pState->CurGroupChildCount(); - - if (child == EmitterNodeType::NoType) - return; - - if (!m_pState->HasBegunNode()) { - if (childCount > 0) { - m_stream << "\n"; - } - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo(m_pState->HasBegunContent(), curIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - break; - } -} - -void Emitter::BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - const std::size_t nextIndent = curIndent + m_pState->CurGroupIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_pState->HasAlias()) { - m_stream << " "; - } - m_stream << ":"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo(true, nextIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - m_stream << "\n"; - break; - } -} - -// SpaceOrIndentTo -// . Prepares for some more content by proper spacing -void Emitter::SpaceOrIndentTo(bool requireSpace, std::size_t indent) { - if (m_stream.comment()) - m_stream << "\n"; - if (m_stream.col() > 0 && requireSpace) - m_stream << " "; - m_stream << IndentTo(indent); -} - -void Emitter::PrepareIntegralStream(std::stringstream& stream) const { - - switch (m_pState->GetIntFormat()) { - case Dec: - stream << std::dec; - break; - case Hex: - stream << "0x"; - stream << std::hex; - break; - case Oct: - stream << "0"; - stream << std::oct; - break; - default: - assert(false); - } -} - -void Emitter::StartedScalar() { m_pState->StartedScalar(); } - -// ******************************************************************************************* -// overloads of Write - -StringEscaping::value GetStringEscapingStyle(const EMITTER_MANIP emitterManip) { - switch (emitterManip) { - case EscapeNonAscii: - return StringEscaping::NonAscii; - case EscapeAsJson: - return StringEscaping::JSON; - default: - return StringEscaping::None; - break; - } -} - -Emitter& Emitter::Write(const std::string& str) { - if (!good()) - return *this; - - StringEscaping::value stringEscaping = GetStringEscapingStyle(m_pState->GetOutputCharset()); - - const StringFormat::value strFormat = - Utils::ComputeStringFormat(str, m_pState->GetStringFormat(), - m_pState->CurGroupFlowType(), stringEscaping == StringEscaping::NonAscii); - - if (strFormat == StringFormat::Literal || str.size() > 1024) - m_pState->SetMapKeyFormat(YAML::LongKey, FmtScope::Local); - - PrepareNode(EmitterNodeType::Scalar); - - switch (strFormat) { - case StringFormat::Plain: - m_stream << str; - break; - case StringFormat::SingleQuoted: - Utils::WriteSingleQuotedString(m_stream, str); - break; - case StringFormat::DoubleQuoted: - Utils::WriteDoubleQuotedString(m_stream, str, stringEscaping); - break; - case StringFormat::Literal: - Utils::WriteLiteralString(m_stream, str, - m_pState->CurIndent() + m_pState->GetIndent()); - break; - } - - StartedScalar(); - - return *this; -} - -std::size_t Emitter::GetFloatPrecision() const { - return m_pState->GetFloatPrecision(); -} - -std::size_t Emitter::GetDoublePrecision() const { - return m_pState->GetDoublePrecision(); -} - -const char* Emitter::ComputeFullBoolName(bool b) const { - const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool - ? YesNoBool - : m_pState->GetBoolFormat()); - const EMITTER_MANIP caseFmt = m_pState->GetBoolCaseFormat(); - switch (mainFmt) { - case YesNoBool: - switch (caseFmt) { - case UpperCase: - return b ? "YES" : "NO"; - case CamelCase: - return b ? "Yes" : "No"; - case LowerCase: - return b ? "yes" : "no"; - default: - break; - } - break; - case OnOffBool: - switch (caseFmt) { - case UpperCase: - return b ? "ON" : "OFF"; - case CamelCase: - return b ? "On" : "Off"; - case LowerCase: - return b ? "on" : "off"; - default: - break; - } - break; - case TrueFalseBool: - switch (caseFmt) { - case UpperCase: - return b ? "TRUE" : "FALSE"; - case CamelCase: - return b ? "True" : "False"; - case LowerCase: - return b ? "true" : "false"; - default: - break; - } - break; - default: - break; - } - return b ? "y" : "n"; // should never get here, but it can't hurt to give - // these answers -} - -const char* Emitter::ComputeNullName() const { - switch (m_pState->GetNullFormat()) { - case LowerNull: - return "null"; - case UpperNull: - return "NULL"; - case CamelNull: - return "Null"; - case TildeNull: - // fallthrough - default: - return "~"; - } -} - -Emitter& Emitter::Write(bool b) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - - const char* name = ComputeFullBoolName(b); - if (m_pState->GetBoolLengthFormat() == ShortBool) - m_stream << name[0]; - else - m_stream << name; - - StartedScalar(); - - return *this; -} - -Emitter& Emitter::Write(char ch) { - if (!good()) - return *this; - - - - PrepareNode(EmitterNodeType::Scalar); - Utils::WriteChar(m_stream, ch, GetStringEscapingStyle(m_pState->GetOutputCharset())); - StartedScalar(); - - return *this; -} - -Emitter& Emitter::Write(const _Alias& alias) { - if (!good()) - return *this; - - if (m_pState->HasAnchor() || m_pState->HasTag()) { - m_pState->SetError(ErrorMsg::INVALID_ALIAS); - return *this; - } - - PrepareNode(EmitterNodeType::Scalar); - - if (!Utils::WriteAlias(m_stream, alias.content)) { - m_pState->SetError(ErrorMsg::INVALID_ALIAS); - return *this; - } - - StartedScalar(); - - m_pState->SetAlias(); - - return *this; -} - -Emitter& Emitter::Write(const _Anchor& anchor) { - if (!good()) - return *this; - - if (m_pState->HasAnchor()) { - m_pState->SetError(ErrorMsg::INVALID_ANCHOR); - return *this; - } - - PrepareNode(EmitterNodeType::Property); - - if (!Utils::WriteAnchor(m_stream, anchor.content)) { - m_pState->SetError(ErrorMsg::INVALID_ANCHOR); - return *this; - } - - m_pState->SetAnchor(); - - return *this; -} - -Emitter& Emitter::Write(const _Tag& tag) { - if (!good()) - return *this; - - if (m_pState->HasTag()) { - m_pState->SetError(ErrorMsg::INVALID_TAG); - return *this; - } - - PrepareNode(EmitterNodeType::Property); - - bool success = false; - if (tag.type == _Tag::Type::Verbatim) - success = Utils::WriteTag(m_stream, tag.content, true); - else if (tag.type == _Tag::Type::PrimaryHandle) - success = Utils::WriteTag(m_stream, tag.content, false); - else - success = Utils::WriteTagWithPrefix(m_stream, tag.prefix, tag.content); - - if (!success) { - m_pState->SetError(ErrorMsg::INVALID_TAG); - return *this; - } - - m_pState->SetTag(); - - return *this; -} - -void Emitter::EmitKindTag() { Write(LocalTag("")); } - -Emitter& Emitter::Write(const _Comment& comment) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::NoType); - - if (m_stream.col() > 0) - m_stream << Indentation(m_pState->GetPreCommentIndent()); - Utils::WriteComment(m_stream, comment.content, - m_pState->GetPostCommentIndent()); - - m_pState->SetNonContent(); - - return *this; -} - -Emitter& Emitter::Write(const _Null& /*null*/) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - - m_stream << ComputeNullName(); - - StartedScalar(); - - return *this; -} - -Emitter& Emitter::Write(const Binary& binary) { - Write(SecondaryTag("binary")); - - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - Utils::WriteBinary(m_stream, binary); - StartedScalar(); - - return *this; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/emitterstate.cpp b/third/yaml-cpp/src/emitterstate.cpp deleted file mode 100644 index 3dbe4011..00000000 --- a/third/yaml-cpp/src/emitterstate.cpp +++ /dev/null @@ -1,400 +0,0 @@ -#include - -#include "emitterstate.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -EmitterState::EmitterState() - : m_isGood(true), - m_lastError{}, - // default global manipulators - m_charset(EmitNonAscii), - m_strFmt(Auto), - m_boolFmt(TrueFalseBool), - m_boolLengthFmt(LongBool), - m_boolCaseFmt(LowerCase), - m_nullFmt(TildeNull), - m_intFmt(Dec), - m_indent(2), - m_preCommentIndent(2), - m_postCommentIndent(1), - m_seqFmt(Block), - m_mapFmt(Block), - m_mapKeyFmt(Auto), - m_floatPrecision(std::numeric_limits::max_digits10), - m_doublePrecision(std::numeric_limits::max_digits10), - // - m_modifiedSettings{}, - m_globalModifiedSettings{}, - m_groups{}, - m_curIndent(0), - m_hasAnchor(false), - m_hasAlias(false), - m_hasTag(false), - m_hasNonContent(false), - m_docCount(0) {} - -EmitterState::~EmitterState() = default; - -// SetLocalValue -// . We blindly tries to set all possible formatters to this value -// . Only the ones that make sense will be accepted -void EmitterState::SetLocalValue(EMITTER_MANIP value) { - SetOutputCharset(value, FmtScope::Local); - SetStringFormat(value, FmtScope::Local); - SetBoolFormat(value, FmtScope::Local); - SetBoolCaseFormat(value, FmtScope::Local); - SetBoolLengthFormat(value, FmtScope::Local); - SetNullFormat(value, FmtScope::Local); - SetIntFormat(value, FmtScope::Local); - SetFlowType(GroupType::Seq, value, FmtScope::Local); - SetFlowType(GroupType::Map, value, FmtScope::Local); - SetMapKeyFormat(value, FmtScope::Local); -} - -void EmitterState::SetAnchor() { m_hasAnchor = true; } - -void EmitterState::SetAlias() { m_hasAlias = true; } - -void EmitterState::SetTag() { m_hasTag = true; } - -void EmitterState::SetNonContent() { m_hasNonContent = true; } - -void EmitterState::SetLongKey() { - assert(!m_groups.empty()); - if (m_groups.empty()) { - return; - } - - assert(m_groups.back()->type == GroupType::Map); - m_groups.back()->longKey = true; -} - -void EmitterState::ForceFlow() { - assert(!m_groups.empty()); - if (m_groups.empty()) { - return; - } - - m_groups.back()->flowType = FlowType::Flow; -} - -void EmitterState::StartedNode() { - if (m_groups.empty()) { - m_docCount++; - } else { - m_groups.back()->childCount++; - if (m_groups.back()->childCount % 2 == 0) { - m_groups.back()->longKey = false; - } - } - - m_hasAnchor = false; - m_hasAlias = false; - m_hasTag = false; - m_hasNonContent = false; -} - -EmitterNodeType::value EmitterState::NextGroupType( - GroupType::value type) const { - if (type == GroupType::Seq) { - if (GetFlowType(type) == Block) - return EmitterNodeType::BlockSeq; - return EmitterNodeType::FlowSeq; - } - - if (GetFlowType(type) == Block) - return EmitterNodeType::BlockMap; - return EmitterNodeType::FlowMap; - - // can't happen - assert(false); - return EmitterNodeType::NoType; -} - -void EmitterState::StartedDoc() { - m_hasAnchor = false; - m_hasTag = false; - m_hasNonContent = false; -} - -void EmitterState::EndedDoc() { - m_hasAnchor = false; - m_hasTag = false; - m_hasNonContent = false; -} - -void EmitterState::StartedScalar() { - StartedNode(); - ClearModifiedSettings(); -} - -void EmitterState::StartedGroup(GroupType::value type) { - StartedNode(); - - const std::size_t lastGroupIndent = - (m_groups.empty() ? 0 : m_groups.back()->indent); - m_curIndent += lastGroupIndent; - - // TODO: Create move constructors for settings types to simplify transfer - std::unique_ptr pGroup(new Group(type)); - - // transfer settings (which last until this group is done) - // - // NB: if pGroup->modifiedSettings == m_modifiedSettings, - // m_modifiedSettings is not changed! - pGroup->modifiedSettings = std::move(m_modifiedSettings); - - // set up group - if (GetFlowType(type) == Block) { - pGroup->flowType = FlowType::Block; - } else { - pGroup->flowType = FlowType::Flow; - } - pGroup->indent = GetIndent(); - - m_groups.push_back(std::move(pGroup)); -} - -void EmitterState::EndedGroup(GroupType::value type) { - if (m_groups.empty()) { - if (type == GroupType::Seq) { - return SetError(ErrorMsg::UNEXPECTED_END_SEQ); - } - return SetError(ErrorMsg::UNEXPECTED_END_MAP); - } - - if (m_hasTag) { - SetError(ErrorMsg::INVALID_TAG); - } - if (m_hasAnchor) { - SetError(ErrorMsg::INVALID_ANCHOR); - } - - // get rid of the current group - { - std::unique_ptr pFinishedGroup = std::move(m_groups.back()); - m_groups.pop_back(); - if (pFinishedGroup->type != type) { - return SetError(ErrorMsg::UNMATCHED_GROUP_TAG); - } - } - - // reset old settings - std::size_t lastIndent = (m_groups.empty() ? 0 : m_groups.back()->indent); - assert(m_curIndent >= lastIndent); - m_curIndent -= lastIndent; - - // some global settings that we changed may have been overridden - // by a local setting we just popped, so we need to restore them - m_globalModifiedSettings.restore(); - - ClearModifiedSettings(); - m_hasAnchor = false; - m_hasTag = false; - m_hasNonContent = false; -} - -EmitterNodeType::value EmitterState::CurGroupNodeType() const { - if (m_groups.empty()) { - return EmitterNodeType::NoType; - } - - return m_groups.back()->NodeType(); -} - -GroupType::value EmitterState::CurGroupType() const { - return m_groups.empty() ? GroupType::NoType : m_groups.back()->type; -} - -FlowType::value EmitterState::CurGroupFlowType() const { - return m_groups.empty() ? FlowType::NoType : m_groups.back()->flowType; -} - -std::size_t EmitterState::CurGroupIndent() const { - return m_groups.empty() ? 0 : m_groups.back()->indent; -} - -std::size_t EmitterState::CurGroupChildCount() const { - return m_groups.empty() ? m_docCount : m_groups.back()->childCount; -} - -bool EmitterState::CurGroupLongKey() const { - return m_groups.empty() ? false : m_groups.back()->longKey; -} - -std::size_t EmitterState::LastIndent() const { - if (m_groups.size() <= 1) { - return 0; - } - - return m_curIndent - m_groups[m_groups.size() - 2]->indent; -} - -void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); } - -void EmitterState::RestoreGlobalModifiedSettings() { - m_globalModifiedSettings.restore(); -} - -bool EmitterState::SetOutputCharset(EMITTER_MANIP value, - FmtScope::value scope) { - switch (value) { - case EmitNonAscii: - case EscapeNonAscii: - case EscapeAsJson: - _Set(m_charset, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) { - switch (value) { - case Auto: - case SingleQuoted: - case DoubleQuoted: - case Literal: - _Set(m_strFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) { - switch (value) { - case OnOffBool: - case TrueFalseBool: - case YesNoBool: - _Set(m_boolFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, - FmtScope::value scope) { - switch (value) { - case LongBool: - case ShortBool: - _Set(m_boolLengthFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, - FmtScope::value scope) { - switch (value) { - case UpperCase: - case LowerCase: - case CamelCase: - _Set(m_boolCaseFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetNullFormat(EMITTER_MANIP value, FmtScope::value scope) { - switch (value) { - case LowerNull: - case UpperNull: - case CamelNull: - case TildeNull: - _Set(m_nullFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) { - switch (value) { - case Dec: - case Hex: - case Oct: - _Set(m_intFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetIndent(std::size_t value, FmtScope::value scope) { - if (value <= 1) - return false; - - _Set(m_indent, value, scope); - return true; -} - -bool EmitterState::SetPreCommentIndent(std::size_t value, - FmtScope::value scope) { - if (value == 0) - return false; - - _Set(m_preCommentIndent, value, scope); - return true; -} - -bool EmitterState::SetPostCommentIndent(std::size_t value, - FmtScope::value scope) { - if (value == 0) - return false; - - _Set(m_postCommentIndent, value, scope); - return true; -} - -bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, - FmtScope::value scope) { - switch (value) { - case Block: - case Flow: - _Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope); - return true; - default: - return false; - } -} - -EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const { - // force flow style if we're currently in a flow - if (CurGroupFlowType() == FlowType::Flow) - return Flow; - - // otherwise, go with what's asked of us - return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get()); -} - -bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) { - switch (value) { - case Auto: - case LongKey: - _Set(m_mapKeyFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) { - if (value > std::numeric_limits::max_digits10) - return false; - _Set(m_floatPrecision, value, scope); - return true; -} - -bool EmitterState::SetDoublePrecision(std::size_t value, - FmtScope::value scope) { - if (value > std::numeric_limits::max_digits10) - return false; - _Set(m_doublePrecision, value, scope); - return true; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/emitterstate.h b/third/yaml-cpp/src/emitterstate.h deleted file mode 100644 index 8f379ca9..00000000 --- a/third/yaml-cpp/src/emitterstate.h +++ /dev/null @@ -1,216 +0,0 @@ -#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "setting.h" -#include "yaml-cpp/emitterdef.h" -#include "yaml-cpp/emittermanip.h" - -#include -#include -#include -#include -#include - -namespace YAML { -struct FmtScope { - enum value { Local, Global }; -}; -struct GroupType { - enum value { NoType, Seq, Map }; -}; -struct FlowType { - enum value { NoType, Flow, Block }; -}; - -class EmitterState { - public: - EmitterState(); - ~EmitterState(); - - // basic state checking - bool good() const { return m_isGood; } - const std::string GetLastError() const { return m_lastError; } - void SetError(const std::string& error) { - m_isGood = false; - m_lastError = error; - } - - // node handling - void SetAnchor(); - void SetAlias(); - void SetTag(); - void SetNonContent(); - void SetLongKey(); - void ForceFlow(); - void StartedDoc(); - void EndedDoc(); - void StartedScalar(); - void StartedGroup(GroupType::value type); - void EndedGroup(GroupType::value type); - - EmitterNodeType::value NextGroupType(GroupType::value type) const; - EmitterNodeType::value CurGroupNodeType() const; - - GroupType::value CurGroupType() const; - FlowType::value CurGroupFlowType() const; - std::size_t CurGroupIndent() const; - std::size_t CurGroupChildCount() const; - bool CurGroupLongKey() const; - - std::size_t LastIndent() const; - std::size_t CurIndent() const { return m_curIndent; } - bool HasAnchor() const { return m_hasAnchor; } - bool HasAlias() const { return m_hasAlias; } - bool HasTag() const { return m_hasTag; } - bool HasBegunNode() const { - return m_hasAnchor || m_hasTag || m_hasNonContent; - } - bool HasBegunContent() const { return m_hasAnchor || m_hasTag; } - - void ClearModifiedSettings(); - void RestoreGlobalModifiedSettings(); - - // formatters - void SetLocalValue(EMITTER_MANIP value); - - bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); } - - bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); } - - bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); } - - bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); } - - bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); } - - bool SetNullFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetNullFormat() const { return m_nullFmt.get(); } - - bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); } - - bool SetIndent(std::size_t value, FmtScope::value scope); - std::size_t GetIndent() const { return m_indent.get(); } - - bool SetPreCommentIndent(std::size_t value, FmtScope::value scope); - std::size_t GetPreCommentIndent() const { return m_preCommentIndent.get(); } - bool SetPostCommentIndent(std::size_t value, FmtScope::value scope); - std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); } - - bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value, - FmtScope::value scope); - EMITTER_MANIP GetFlowType(GroupType::value groupType) const; - - bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); } - - bool SetFloatPrecision(std::size_t value, FmtScope::value scope); - std::size_t GetFloatPrecision() const { return m_floatPrecision.get(); } - bool SetDoublePrecision(std::size_t value, FmtScope::value scope); - std::size_t GetDoublePrecision() const { return m_doublePrecision.get(); } - - private: - template - void _Set(Setting& fmt, T value, FmtScope::value scope); - - void StartedNode(); - - private: - // basic state ok? - bool m_isGood; - std::string m_lastError; - - // other state - Setting m_charset; - Setting m_strFmt; - Setting m_boolFmt; - Setting m_boolLengthFmt; - Setting m_boolCaseFmt; - Setting m_nullFmt; - Setting m_intFmt; - Setting m_indent; - Setting m_preCommentIndent, m_postCommentIndent; - Setting m_seqFmt; - Setting m_mapFmt; - Setting m_mapKeyFmt; - Setting m_floatPrecision; - Setting m_doublePrecision; - - SettingChanges m_modifiedSettings; - SettingChanges m_globalModifiedSettings; - - struct Group { - explicit Group(GroupType::value type_) - : type(type_), - flowType{}, - indent(0), - childCount(0), - longKey(false), - modifiedSettings{} {} - - GroupType::value type; - FlowType::value flowType; - std::size_t indent; - std::size_t childCount; - bool longKey; - - SettingChanges modifiedSettings; - - EmitterNodeType::value NodeType() const { - if (type == GroupType::Seq) { - if (flowType == FlowType::Flow) - return EmitterNodeType::FlowSeq; - else - return EmitterNodeType::BlockSeq; - } else { - if (flowType == FlowType::Flow) - return EmitterNodeType::FlowMap; - else - return EmitterNodeType::BlockMap; - } - - // can't get here - assert(false); - return EmitterNodeType::NoType; - } - }; - - std::vector> m_groups; - std::size_t m_curIndent; - bool m_hasAnchor; - bool m_hasAlias; - bool m_hasTag; - bool m_hasNonContent; - std::size_t m_docCount; -}; - -template -void EmitterState::_Set(Setting& fmt, T value, FmtScope::value scope) { - switch (scope) { - case FmtScope::Local: - m_modifiedSettings.push(fmt.set(value)); - break; - case FmtScope::Global: - fmt.set(value); - m_globalModifiedSettings.push( - fmt.set(value)); // this pushes an identity set, so when we restore, - // it restores to the value here, and not the previous one - break; - default: - assert(false); - } -} -} // namespace YAML - -#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/emitterutils.cpp b/third/yaml-cpp/src/emitterutils.cpp deleted file mode 100644 index 6cdf6de7..00000000 --- a/third/yaml-cpp/src/emitterutils.cpp +++ /dev/null @@ -1,497 +0,0 @@ -#include -#include -#include - -#include "emitterutils.h" -#include "exp.h" -#include "indentation.h" -#include "regex_yaml.h" -#include "regeximpl.h" -#include "stringsource.h" -#include "yaml-cpp/binary.h" // IWYU pragma: keep -#include "yaml-cpp/null.h" -#include "yaml-cpp/ostream_wrapper.h" - -namespace YAML { -namespace Utils { -namespace { -enum { REPLACEMENT_CHARACTER = 0xFFFD }; - -bool IsAnchorChar(int ch) { // test for ns-anchor-char - switch (ch) { - case ',': - case '[': - case ']': - case '{': - case '}': // c-flow-indicator - case ' ': - case '\t': // s-white - case 0xFEFF: // c-byte-order-mark - case 0xA: - case 0xD: // b-char - return false; - case 0x85: - return true; - } - - if (ch < 0x20) { - return false; - } - - if (ch < 0x7E) { - return true; - } - - if (ch < 0xA0) { - return false; - } - if (ch >= 0xD800 && ch <= 0xDFFF) { - return false; - } - if ((ch & 0xFFFE) == 0xFFFE) { - return false; - } - if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) { - return false; - } - if (ch > 0x10FFFF) { - return false; - } - - return true; -} - -int Utf8BytesIndicated(char ch) { - int byteVal = static_cast(ch); - switch (byteVal >> 4) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - return 1; - case 12: - case 13: - return 2; - case 14: - return 3; - case 15: - return 4; - default: - return -1; - } -} - -bool IsTrailingByte(char ch) { return (ch & 0xC0) == 0x80; } - -bool GetNextCodePointAndAdvance(int& codePoint, - std::string::const_iterator& first, - std::string::const_iterator last) { - if (first == last) - return false; - - int nBytes = Utf8BytesIndicated(*first); - if (nBytes < 1) { - // Bad lead byte - ++first; - codePoint = REPLACEMENT_CHARACTER; - return true; - } - - if (nBytes == 1) { - codePoint = *first++; - return true; - } - - // Gather bits from trailing bytes - codePoint = static_cast(*first) & ~(0xFF << (7 - nBytes)); - ++first; - --nBytes; - for (; nBytes > 0; ++first, --nBytes) { - if ((first == last) || !IsTrailingByte(*first)) { - codePoint = REPLACEMENT_CHARACTER; - break; - } - codePoint <<= 6; - codePoint |= *first & 0x3F; - } - - // Check for illegal code points - if (codePoint > 0x10FFFF) - codePoint = REPLACEMENT_CHARACTER; - else if (codePoint >= 0xD800 && codePoint <= 0xDFFF) - codePoint = REPLACEMENT_CHARACTER; - else if ((codePoint & 0xFFFE) == 0xFFFE) - codePoint = REPLACEMENT_CHARACTER; - else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF) - codePoint = REPLACEMENT_CHARACTER; - return true; -} - -void WriteCodePoint(ostream_wrapper& out, int codePoint) { - if (codePoint < 0 || codePoint > 0x10FFFF) { - codePoint = REPLACEMENT_CHARACTER; - } - if (codePoint <= 0x7F) { - out << static_cast(codePoint); - } else if (codePoint <= 0x7FF) { - out << static_cast(0xC0 | (codePoint >> 6)) - << static_cast(0x80 | (codePoint & 0x3F)); - } else if (codePoint <= 0xFFFF) { - out << static_cast(0xE0 | (codePoint >> 12)) - << static_cast(0x80 | ((codePoint >> 6) & 0x3F)) - << static_cast(0x80 | (codePoint & 0x3F)); - } else { - out << static_cast(0xF0 | (codePoint >> 18)) - << static_cast(0x80 | ((codePoint >> 12) & 0x3F)) - << static_cast(0x80 | ((codePoint >> 6) & 0x3F)) - << static_cast(0x80 | (codePoint & 0x3F)); - } -} - -bool IsValidPlainScalar(const std::string& str, FlowType::value flowType, - bool allowOnlyAscii) { - // check against null - if (IsNullString(str)) { - return false; - } - - // check the start - const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow() - : Exp::PlainScalar()); - if (!start.Matches(str)) { - return false; - } - - // and check the end for plain whitespace (which can't be faithfully kept in a - // plain scalar) - if (!str.empty() && *str.rbegin() == ' ') { - return false; - } - - // then check until something is disallowed - static const RegEx& disallowed_flow = - Exp::EndScalarInFlow() | (Exp::BlankOrBreak() + Exp::Comment()) | - Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() | - Exp::Tab() | Exp::Ampersand(); - static const RegEx& disallowed_block = - Exp::EndScalar() | (Exp::BlankOrBreak() + Exp::Comment()) | - Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() | - Exp::Tab() | Exp::Ampersand(); - const RegEx& disallowed = - flowType == FlowType::Flow ? disallowed_flow : disallowed_block; - - StringCharSource buffer(str.c_str(), str.size()); - while (buffer) { - if (disallowed.Matches(buffer)) { - return false; - } - if (allowOnlyAscii && (0x80 <= static_cast(buffer[0]))) { - return false; - } - ++buffer; - } - - return true; -} - -bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) { - // TODO: check for non-printable characters? - return std::none_of(str.begin(), str.end(), [=](char ch) { - return (escapeNonAscii && (0x80 <= static_cast(ch))) || - (ch == '\n'); - }); -} - -bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType, - bool escapeNonAscii) { - if (flowType == FlowType::Flow) { - return false; - } - - // TODO: check for non-printable characters? - return std::none_of(str.begin(), str.end(), [=](char ch) { - return (escapeNonAscii && (0x80 <= static_cast(ch))); - }); -} - -std::pair EncodeUTF16SurrogatePair(int codePoint) { - const uint32_t leadOffset = 0xD800 - (0x10000 >> 10); - - return { - leadOffset | (codePoint >> 10), - 0xDC00 | (codePoint & 0x3FF), - }; -} - -void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint, StringEscaping::value stringEscapingStyle) { - static const char hexDigits[] = "0123456789abcdef"; - - out << "\\"; - int digits = 8; - if (codePoint < 0xFF && stringEscapingStyle != StringEscaping::JSON) { - out << "x"; - digits = 2; - } else if (codePoint < 0xFFFF) { - out << "u"; - digits = 4; - } else if (stringEscapingStyle != StringEscaping::JSON) { - out << "U"; - digits = 8; - } else { - auto surrogatePair = EncodeUTF16SurrogatePair(codePoint); - WriteDoubleQuoteEscapeSequence(out, surrogatePair.first, stringEscapingStyle); - WriteDoubleQuoteEscapeSequence(out, surrogatePair.second, stringEscapingStyle); - return; - } - - // Write digits into the escape sequence - for (; digits > 0; --digits) - out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF]; -} - -bool WriteAliasName(ostream_wrapper& out, const std::string& str) { - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - if (!IsAnchorChar(codePoint)) { - return false; - } - - WriteCodePoint(out, codePoint); - } - return true; -} -} // namespace - -StringFormat::value ComputeStringFormat(const std::string& str, - EMITTER_MANIP strFormat, - FlowType::value flowType, - bool escapeNonAscii) { - switch (strFormat) { - case Auto: - if (IsValidPlainScalar(str, flowType, escapeNonAscii)) { - return StringFormat::Plain; - } - return StringFormat::DoubleQuoted; - case SingleQuoted: - if (IsValidSingleQuotedScalar(str, escapeNonAscii)) { - return StringFormat::SingleQuoted; - } - return StringFormat::DoubleQuoted; - case DoubleQuoted: - return StringFormat::DoubleQuoted; - case Literal: - if (IsValidLiteralScalar(str, flowType, escapeNonAscii)) { - return StringFormat::Literal; - } - return StringFormat::DoubleQuoted; - default: - break; - } - - return StringFormat::DoubleQuoted; -} - -bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) { - out << "'"; - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - if (codePoint == '\n') { - return false; // We can't handle a new line and the attendant indentation - // yet - } - - if (codePoint == '\'') { - out << "''"; - } else { - WriteCodePoint(out, codePoint); - } - } - out << "'"; - return true; -} - -bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, - StringEscaping::value stringEscaping) { - out << "\""; - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - switch (codePoint) { - case '\"': - out << "\\\""; - break; - case '\\': - out << "\\\\"; - break; - case '\n': - out << "\\n"; - break; - case '\t': - out << "\\t"; - break; - case '\r': - out << "\\r"; - break; - case '\b': - out << "\\b"; - break; - case '\f': - out << "\\f"; - break; - default: - if (codePoint < 0x20 || - (codePoint >= 0x80 && - codePoint <= 0xA0)) { // Control characters and non-breaking space - WriteDoubleQuoteEscapeSequence(out, codePoint, stringEscaping); - } else if (codePoint == 0xFEFF) { // Byte order marks (ZWNS) should be - // escaped (YAML 1.2, sec. 5.2) - WriteDoubleQuoteEscapeSequence(out, codePoint, stringEscaping); - } else if (stringEscaping == StringEscaping::NonAscii && codePoint > 0x7E) { - WriteDoubleQuoteEscapeSequence(out, codePoint, stringEscaping); - } else { - WriteCodePoint(out, codePoint); - } - } - } - out << "\""; - return true; -} - -bool WriteLiteralString(ostream_wrapper& out, const std::string& str, - std::size_t indent) { - out << "|\n"; - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - if (codePoint == '\n') { - out << "\n"; - } else { - out<< IndentTo(indent); - WriteCodePoint(out, codePoint); - } - } - return true; -} - -bool WriteChar(ostream_wrapper& out, char ch, StringEscaping::value stringEscapingStyle) { - if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) { - out << ch; - } else if (ch == '\"') { - out << R"("\"")"; - } else if (ch == '\t') { - out << R"("\t")"; - } else if (ch == '\n') { - out << R"("\n")"; - } else if (ch == '\b') { - out << R"("\b")"; - } else if (ch == '\r') { - out << R"("\r")"; - } else if (ch == '\f') { - out << R"("\f")"; - } else if (ch == '\\') { - out << R"("\\")"; - } else if (0x20 <= ch && ch <= 0x7e) { - out << "\"" << ch << "\""; - } else { - out << "\""; - WriteDoubleQuoteEscapeSequence(out, ch, stringEscapingStyle); - out << "\""; - } - return true; -} - -bool WriteComment(ostream_wrapper& out, const std::string& str, - std::size_t postCommentIndent) { - const std::size_t curIndent = out.col(); - out << "#" << Indentation(postCommentIndent); - out.set_comment(); - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - if (codePoint == '\n') { - out << "\n" - << IndentTo(curIndent) << "#" << Indentation(postCommentIndent); - out.set_comment(); - } else { - WriteCodePoint(out, codePoint); - } - } - return true; -} - -bool WriteAlias(ostream_wrapper& out, const std::string& str) { - out << "*"; - return WriteAliasName(out, str); -} - -bool WriteAnchor(ostream_wrapper& out, const std::string& str) { - out << "&"; - return WriteAliasName(out, str); -} - -bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) { - out << (verbatim ? "!<" : "!"); - StringCharSource buffer(str.c_str(), str.size()); - const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag(); - while (buffer) { - int n = reValid.Match(buffer); - if (n <= 0) { - return false; - } - - while (--n >= 0) { - out << buffer[0]; - ++buffer; - } - } - if (verbatim) { - out << ">"; - } - return true; -} - -bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, - const std::string& tag) { - out << "!"; - StringCharSource prefixBuffer(prefix.c_str(), prefix.size()); - while (prefixBuffer) { - int n = Exp::URI().Match(prefixBuffer); - if (n <= 0) { - return false; - } - - while (--n >= 0) { - out << prefixBuffer[0]; - ++prefixBuffer; - } - } - - out << "!"; - StringCharSource tagBuffer(tag.c_str(), tag.size()); - while (tagBuffer) { - int n = Exp::Tag().Match(tagBuffer); - if (n <= 0) { - return false; - } - - while (--n >= 0) { - out << tagBuffer[0]; - ++tagBuffer; - } - } - return true; -} - -bool WriteBinary(ostream_wrapper& out, const Binary& binary) { - WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()), - StringEscaping::None); - return true; -} -} // namespace Utils -} // namespace YAML diff --git a/third/yaml-cpp/src/emitterutils.h b/third/yaml-cpp/src/emitterutils.h deleted file mode 100644 index 3a7d5982..00000000 --- a/third/yaml-cpp/src/emitterutils.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "emitterstate.h" -#include "yaml-cpp/emittermanip.h" -#include "yaml-cpp/ostream_wrapper.h" - -namespace YAML { -class ostream_wrapper; -} // namespace YAML - -namespace YAML { -class Binary; - -struct StringFormat { - enum value { Plain, SingleQuoted, DoubleQuoted, Literal }; -}; - -struct StringEscaping { - enum value { None, NonAscii, JSON }; -}; - -namespace Utils { -StringFormat::value ComputeStringFormat(const std::string& str, - EMITTER_MANIP strFormat, - FlowType::value flowType, - bool escapeNonAscii); - -bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str); -bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, - StringEscaping::value stringEscaping); -bool WriteLiteralString(ostream_wrapper& out, const std::string& str, - std::size_t indent); -bool WriteChar(ostream_wrapper& out, char ch, - StringEscaping::value stringEscapingStyle); -bool WriteComment(ostream_wrapper& out, const std::string& str, - std::size_t postCommentIndent); -bool WriteAlias(ostream_wrapper& out, const std::string& str); -bool WriteAnchor(ostream_wrapper& out, const std::string& str); -bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim); -bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, - const std::string& tag); -bool WriteBinary(ostream_wrapper& out, const Binary& binary); -} -} - -#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/exceptions.cpp b/third/yaml-cpp/src/exceptions.cpp deleted file mode 100644 index 43a7976e..00000000 --- a/third/yaml-cpp/src/exceptions.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "yaml-cpp/exceptions.h" -#include "yaml-cpp/noexcept.h" - -namespace YAML { - -// These destructors are defined out-of-line so the vtable is only emitted once. -Exception::~Exception() YAML_CPP_NOEXCEPT = default; -ParserException::~ParserException() YAML_CPP_NOEXCEPT = default; -RepresentationException::~RepresentationException() YAML_CPP_NOEXCEPT = default; -InvalidScalar::~InvalidScalar() YAML_CPP_NOEXCEPT = default; -KeyNotFound::~KeyNotFound() YAML_CPP_NOEXCEPT = default; -InvalidNode::~InvalidNode() YAML_CPP_NOEXCEPT = default; -BadConversion::~BadConversion() YAML_CPP_NOEXCEPT = default; -BadDereference::~BadDereference() YAML_CPP_NOEXCEPT = default; -BadSubscript::~BadSubscript() YAML_CPP_NOEXCEPT = default; -BadPushback::~BadPushback() YAML_CPP_NOEXCEPT = default; -BadInsert::~BadInsert() YAML_CPP_NOEXCEPT = default; -EmitterException::~EmitterException() YAML_CPP_NOEXCEPT = default; -BadFile::~BadFile() YAML_CPP_NOEXCEPT = default; -} // namespace YAML diff --git a/third/yaml-cpp/src/exp.cpp b/third/yaml-cpp/src/exp.cpp deleted file mode 100644 index 992620ff..00000000 --- a/third/yaml-cpp/src/exp.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include - -#include "exp.h" -#include "stream.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -struct Mark; -} // namespace YAML - -namespace YAML { -namespace Exp { -unsigned ParseHex(const std::string& str, const Mark& mark) { - unsigned value = 0; - for (char ch : str) { - int digit = 0; - if ('a' <= ch && ch <= 'f') - digit = ch - 'a' + 10; - else if ('A' <= ch && ch <= 'F') - digit = ch - 'A' + 10; - else if ('0' <= ch && ch <= '9') - digit = ch - '0'; - else - throw ParserException(mark, ErrorMsg::INVALID_HEX); - - value = (value << 4) + digit; - } - - return value; -} - -std::string Str(unsigned ch) { return std::string(1, static_cast(ch)); } - -// Escape -// . Translates the next 'codeLength' characters into a hex number and returns -// the result. -// . Throws if it's not actually hex. -std::string Escape(Stream& in, int codeLength) { - // grab string - std::string str; - for (int i = 0; i < codeLength; i++) - str += in.get(); - - // get the value - unsigned value = ParseHex(str, in.mark()); - - // legal unicode? - if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) { - std::stringstream msg; - msg << ErrorMsg::INVALID_UNICODE << value; - throw ParserException(in.mark(), msg.str()); - } - - // now break it up into chars - if (value <= 0x7F) - return Str(value); - - if (value <= 0x7FF) - return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F)); - - if (value <= 0xFFFF) - return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + - Str(0x80 + (value & 0x3F)); - - return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) + - Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); -} - -// Escape -// . Escapes the sequence starting 'in' (it must begin with a '\' or single -// quote) -// and returns the result. -// . Throws if it's an unknown escape character. -std::string Escape(Stream& in) { - // eat slash - char escape = in.get(); - - // switch on escape character - char ch = in.get(); - - // first do single quote, since it's easier - if (escape == '\'' && ch == '\'') - return "\'"; - - // now do the slash (we're not gonna check if it's a slash - you better pass - // one!) - switch (ch) { - case '0': - return std::string(1, '\x00'); - case 'a': - return "\x07"; - case 'b': - return "\x08"; - case 't': - case '\t': - return "\x09"; - case 'n': - return "\x0A"; - case 'v': - return "\x0B"; - case 'f': - return "\x0C"; - case 'r': - return "\x0D"; - case 'e': - return "\x1B"; - case ' ': - return R"( )"; - case '\"': - return "\""; - case '\'': - return "\'"; - case '\\': - return "\\"; - case '/': - return "/"; - case 'N': - return "\x85"; - case '_': - return "\xA0"; - case 'L': - return "\xE2\x80\xA8"; // LS (#x2028) - case 'P': - return "\xE2\x80\xA9"; // PS (#x2029) - case 'x': - return Escape(in, 2); - case 'u': - return Escape(in, 4); - case 'U': - return Escape(in, 8); - } - - std::stringstream msg; - throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch); -} -} // namespace Exp -} // namespace YAML diff --git a/third/yaml-cpp/src/exp.h b/third/yaml-cpp/src/exp.h deleted file mode 100644 index c8837f0f..00000000 --- a/third/yaml-cpp/src/exp.h +++ /dev/null @@ -1,226 +0,0 @@ -#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "regex_yaml.h" -#include "stream.h" - -namespace YAML { -//////////////////////////////////////////////////////////////////////////////// -// Here we store a bunch of expressions for matching different parts of the -// file. - -namespace Exp { -// misc -inline const RegEx& Empty() { - static const RegEx e; - return e; -} -inline const RegEx& Space() { - static const RegEx e = RegEx(' '); - return e; -} -inline const RegEx& Tab() { - static const RegEx e = RegEx('\t'); - return e; -} -inline const RegEx& Blank() { - static const RegEx e = Space() | Tab(); - return e; -} -inline const RegEx& Break() { - static const RegEx e = RegEx('\n') | RegEx("\r\n") | RegEx('\r'); - return e; -} -inline const RegEx& BlankOrBreak() { - static const RegEx e = Blank() | Break(); - return e; -} -inline const RegEx& Digit() { - static const RegEx e = RegEx('0', '9'); - return e; -} -inline const RegEx& Alpha() { - static const RegEx e = RegEx('a', 'z') | RegEx('A', 'Z'); - return e; -} -inline const RegEx& AlphaNumeric() { - static const RegEx e = Alpha() | Digit(); - return e; -} -inline const RegEx& Word() { - static const RegEx e = AlphaNumeric() | RegEx('-'); - return e; -} -inline const RegEx& Hex() { - static const RegEx e = Digit() | RegEx('A', 'F') | RegEx('a', 'f'); - return e; -} -// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. -// 5.1) -inline const RegEx& NotPrintable() { - static const RegEx e = - RegEx(0) | - RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) | - RegEx(0x0E, 0x1F) | - (RegEx('\xC2') + (RegEx('\x80', '\x84') | RegEx('\x86', '\x9F'))); - return e; -} -inline const RegEx& Utf8_ByteOrderMark() { - static const RegEx e = RegEx("\xEF\xBB\xBF"); - return e; -} - -// actual tags - -inline const RegEx& DocStart() { - static const RegEx e = RegEx("---") + (BlankOrBreak() | RegEx()); - return e; -} -inline const RegEx& DocEnd() { - static const RegEx e = RegEx("...") + (BlankOrBreak() | RegEx()); - return e; -} -inline const RegEx& DocIndicator() { - static const RegEx e = DocStart() | DocEnd(); - return e; -} -inline const RegEx& BlockEntry() { - static const RegEx e = RegEx('-') + (BlankOrBreak() | RegEx()); - return e; -} -inline const RegEx& Key() { - static const RegEx e = RegEx('?') + BlankOrBreak(); - return e; -} -inline const RegEx& KeyInFlow() { - static const RegEx e = RegEx('?') + BlankOrBreak(); - return e; -} -inline const RegEx& Value() { - static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx()); - return e; -} -inline const RegEx& ValueInFlow() { - static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx(",]}", REGEX_OR)); - return e; -} -inline const RegEx& ValueInJSONFlow() { - static const RegEx e = RegEx(':'); - return e; -} -inline const RegEx& Ampersand() { - static const RegEx e = RegEx('&'); - return e; -} -inline const RegEx Comment() { - static const RegEx e = RegEx('#'); - return e; -} -inline const RegEx& Anchor() { - static const RegEx e = !(RegEx("[]{},", REGEX_OR) | BlankOrBreak()); - return e; -} -inline const RegEx& AnchorEnd() { - static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) | BlankOrBreak(); - return e; -} -inline const RegEx& URI() { - static const RegEx e = Word() | RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) | - (RegEx('%') + Hex() + Hex()); - return e; -} -inline const RegEx& Tag() { - static const RegEx e = Word() | RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) | - (RegEx('%') + Hex() + Hex()); - return e; -} - -// Plain scalar rules: -// . Cannot start with a blank. -// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ ` -// . In the block context - ? : must be not be followed with a space. -// . In the flow context ? is illegal and : and - must not be followed with a -// space. -inline const RegEx& PlainScalar() { - static const RegEx e = - !(BlankOrBreak() | RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) | - (RegEx("-?:", REGEX_OR) + (BlankOrBreak() | RegEx()))); - return e; -} -inline const RegEx& PlainScalarInFlow() { - static const RegEx e = - !(BlankOrBreak() | RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) | - (RegEx("-:", REGEX_OR) + (Blank() | RegEx()))); - return e; -} -inline const RegEx& EndScalar() { - static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx()); - return e; -} -inline const RegEx& EndScalarInFlow() { - static const RegEx e = - (RegEx(':') + (BlankOrBreak() | RegEx() | RegEx(",]}", REGEX_OR))) | - RegEx(",?[]{}", REGEX_OR); - return e; -} - -inline const RegEx& ScanScalarEndInFlow() { - static const RegEx e = (EndScalarInFlow() | (BlankOrBreak() + Comment())); - return e; -} - -inline const RegEx& ScanScalarEnd() { - static const RegEx e = EndScalar() | (BlankOrBreak() + Comment()); - return e; -} -inline const RegEx& EscSingleQuote() { - static const RegEx e = RegEx("\'\'"); - return e; -} -inline const RegEx& EscBreak() { - static const RegEx e = RegEx('\\') + Break(); - return e; -} - -inline const RegEx& ChompIndicator() { - static const RegEx e = RegEx("+-", REGEX_OR); - return e; -} -inline const RegEx& Chomp() { - static const RegEx e = (ChompIndicator() + Digit()) | - (Digit() + ChompIndicator()) | ChompIndicator() | - Digit(); - return e; -} - -// and some functions -std::string Escape(Stream& in); -} // namespace Exp - -namespace Keys { -const char Directive = '%'; -const char FlowSeqStart = '['; -const char FlowSeqEnd = ']'; -const char FlowMapStart = '{'; -const char FlowMapEnd = '}'; -const char FlowEntry = ','; -const char Alias = '*'; -const char Anchor = '&'; -const char Tag = '!'; -const char LiteralScalar = '|'; -const char FoldedScalar = '>'; -const char VerbatimTagStart = '<'; -const char VerbatimTagEnd = '>'; -} // namespace Keys -} // namespace YAML - -#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/indentation.h b/third/yaml-cpp/src/indentation.h deleted file mode 100644 index 1a2ccaea..00000000 --- a/third/yaml-cpp/src/indentation.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/ostream_wrapper.h" - -namespace YAML { -struct Indentation { - Indentation(std::size_t n_) : n(n_) {} - std::size_t n; -}; - -inline ostream_wrapper& operator<<(ostream_wrapper& out, - const Indentation& indent) { - for (std::size_t i = 0; i < indent.n; i++) - out << ' '; - return out; -} - -struct IndentTo { - IndentTo(std::size_t n_) : n(n_) {} - std::size_t n; -}; - -inline ostream_wrapper& operator<<(ostream_wrapper& out, - const IndentTo& indent) { - while (out.col() < indent.n) - out << ' '; - return out; -} -} - -#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/memory.cpp b/third/yaml-cpp/src/memory.cpp deleted file mode 100644 index 676e4c7f..00000000 --- a/third/yaml-cpp/src/memory.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "yaml-cpp/node/detail/memory.h" -#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep -#include "yaml-cpp/node/ptr.h" - -namespace YAML { -namespace detail { - -void memory_holder::merge(memory_holder& rhs) { - if (m_pMemory == rhs.m_pMemory) - return; - - m_pMemory->merge(*rhs.m_pMemory); - rhs.m_pMemory = m_pMemory; -} - -node& memory::create_node() { - shared_node pNode(new node); - m_nodes.insert(pNode); - return *pNode; -} - -void memory::merge(const memory& rhs) { - m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end()); -} -} // namespace detail -} // namespace YAML diff --git a/third/yaml-cpp/src/node.cpp b/third/yaml-cpp/src/node.cpp deleted file mode 100644 index badc3110..00000000 --- a/third/yaml-cpp/src/node.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "yaml-cpp/node/node.h" -#include "nodebuilder.h" -#include "nodeevents.h" - -namespace YAML { -Node Clone(const Node& node) { - NodeEvents events(node); - NodeBuilder builder; - events.Emit(builder); - return builder.Root(); -} -} // namespace YAML diff --git a/third/yaml-cpp/src/node_data.cpp b/third/yaml-cpp/src/node_data.cpp deleted file mode 100644 index 8f5422ae..00000000 --- a/third/yaml-cpp/src/node_data.cpp +++ /dev/null @@ -1,324 +0,0 @@ -#include -#include -#include -#include - -#include "yaml-cpp/exceptions.h" -#include "yaml-cpp/node/detail/memory.h" -#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep -#include "yaml-cpp/node/detail/node_data.h" -#include "yaml-cpp/node/detail/node_iterator.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -namespace detail { -YAML_CPP_API std::atomic node::m_amount{0}; - -const std::string& node_data::empty_scalar() { - static const std::string svalue; - return svalue; -} - -node_data::node_data() - : m_isDefined(false), - m_mark(Mark::null_mark()), - m_type(NodeType::Null), - m_tag{}, - m_style(EmitterStyle::Default), - m_scalar{}, - m_sequence{}, - m_seqSize(0), - m_map{}, - m_undefinedPairs{} {} - -void node_data::mark_defined() { - if (m_type == NodeType::Undefined) - m_type = NodeType::Null; - m_isDefined = true; -} - -void node_data::set_mark(const Mark& mark) { m_mark = mark; } - -void node_data::set_type(NodeType::value type) { - if (type == NodeType::Undefined) { - m_type = type; - m_isDefined = false; - return; - } - - m_isDefined = true; - if (type == m_type) - return; - - m_type = type; - - switch (m_type) { - case NodeType::Null: - break; - case NodeType::Scalar: - m_scalar.clear(); - break; - case NodeType::Sequence: - reset_sequence(); - break; - case NodeType::Map: - reset_map(); - break; - case NodeType::Undefined: - assert(false); - break; - } -} - -void node_data::set_tag(const std::string& tag) { m_tag = tag; } - -void node_data::set_style(EmitterStyle::value style) { m_style = style; } - -void node_data::set_null() { - m_isDefined = true; - m_type = NodeType::Null; -} - -void node_data::set_scalar(const std::string& scalar) { - m_isDefined = true; - m_type = NodeType::Scalar; - m_scalar = scalar; -} - -// size/iterator -std::size_t node_data::size() const { - if (!m_isDefined) - return 0; - - switch (m_type) { - case NodeType::Sequence: - compute_seq_size(); - return m_seqSize; - case NodeType::Map: - compute_map_size(); - return m_map.size() - m_undefinedPairs.size(); - default: - return 0; - } - return 0; -} - -void node_data::compute_seq_size() const { - while (m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined()) - m_seqSize++; -} - -void node_data::compute_map_size() const { - auto it = m_undefinedPairs.begin(); - while (it != m_undefinedPairs.end()) { - auto jt = std::next(it); - if (it->first->is_defined() && it->second->is_defined()) - m_undefinedPairs.erase(it); - it = jt; - } -} - -const_node_iterator node_data::begin() const { - if (!m_isDefined) - return {}; - - switch (m_type) { - case NodeType::Sequence: - return const_node_iterator(m_sequence.begin()); - case NodeType::Map: - return const_node_iterator(m_map.begin(), m_map.end()); - default: - return {}; - } -} - -node_iterator node_data::begin() { - if (!m_isDefined) - return {}; - - switch (m_type) { - case NodeType::Sequence: - return node_iterator(m_sequence.begin()); - case NodeType::Map: - return node_iterator(m_map.begin(), m_map.end()); - default: - return {}; - } -} - -const_node_iterator node_data::end() const { - if (!m_isDefined) - return {}; - - switch (m_type) { - case NodeType::Sequence: - return const_node_iterator(m_sequence.end()); - case NodeType::Map: - return const_node_iterator(m_map.end(), m_map.end()); - default: - return {}; - } -} - -node_iterator node_data::end() { - if (!m_isDefined) - return {}; - - switch (m_type) { - case NodeType::Sequence: - return node_iterator(m_sequence.end()); - case NodeType::Map: - return node_iterator(m_map.end(), m_map.end()); - default: - return {}; - } -} - -// sequence -void node_data::push_back(node& node, - const shared_memory_holder& /* pMemory */) { - if (m_type == NodeType::Undefined || m_type == NodeType::Null) { - m_type = NodeType::Sequence; - reset_sequence(); - } - - if (m_type != NodeType::Sequence) - throw BadPushback(); - - m_sequence.push_back(&node); -} - -void node_data::insert(node& key, node& value, - const shared_memory_holder& pMemory) { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadSubscript(m_mark, key); - } - - insert_map_pair(key, value); -} - -// indexing -node* node_data::get(node& key, - const shared_memory_holder& /* pMemory */) const { - if (m_type != NodeType::Map) { - return nullptr; - } - - for (const auto& it : m_map) { - if (it.first->is(key)) - return it.second; - } - - return nullptr; -} - -node& node_data::get(node& key, const shared_memory_holder& pMemory) { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadSubscript(m_mark, key); - } - - for (const auto& it : m_map) { - if (it.first->is(key)) - return *it.second; - } - - node& value = pMemory->create_node(); - insert_map_pair(key, value); - return value; -} - -bool node_data::remove(node& key, const shared_memory_holder& /* pMemory */) { - if (m_type != NodeType::Map) - return false; - - for (auto it = m_undefinedPairs.begin(); it != m_undefinedPairs.end();) { - auto jt = std::next(it); - if (it->first->is(key)) - m_undefinedPairs.erase(it); - it = jt; - } - - auto it = - std::find_if(m_map.begin(), m_map.end(), - [&](std::pair j) { - return (j.first->is(key)); - }); - - if (it != m_map.end()) { - m_map.erase(it); - return true; - } - - return false; -} - -void node_data::reset_sequence() { - m_sequence.clear(); - m_seqSize = 0; -} - -void node_data::reset_map() { - m_map.clear(); - m_undefinedPairs.clear(); -} - -void node_data::insert_map_pair(node& key, node& value) { - m_map.emplace_back(&key, &value); - - if (!key.is_defined() || !value.is_defined()) - m_undefinedPairs.emplace_back(&key, &value); -} - -void node_data::convert_to_map(const shared_memory_holder& pMemory) { - switch (m_type) { - case NodeType::Undefined: - case NodeType::Null: - reset_map(); - m_type = NodeType::Map; - break; - case NodeType::Sequence: - convert_sequence_to_map(pMemory); - break; - case NodeType::Map: - break; - case NodeType::Scalar: - assert(false); - break; - } -} - -void node_data::convert_sequence_to_map(const shared_memory_holder& pMemory) { - assert(m_type == NodeType::Sequence); - - reset_map(); - for (std::size_t i = 0; i < m_sequence.size(); i++) { - std::stringstream stream; - stream << i; - - node& key = pMemory->create_node(); - key.set_scalar(stream.str()); - insert_map_pair(key, *m_sequence[i]); - } - - reset_sequence(); - m_type = NodeType::Map; -} -} // namespace detail -} // namespace YAML diff --git a/third/yaml-cpp/src/nodebuilder.cpp b/third/yaml-cpp/src/nodebuilder.cpp deleted file mode 100644 index bbaefac8..00000000 --- a/third/yaml-cpp/src/nodebuilder.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include - -#include "nodebuilder.h" -#include "yaml-cpp/node/detail/node.h" -#include "yaml-cpp/node/impl.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -struct Mark; - -NodeBuilder::NodeBuilder() - : m_pMemory(new detail::memory_holder), - m_pRoot(nullptr), - m_stack{}, - m_anchors{}, - m_keys{}, - m_mapDepth(0) { - m_anchors.push_back(nullptr); // since the anchors start at 1 -} - -NodeBuilder::~NodeBuilder() = default; - -Node NodeBuilder::Root() { - if (!m_pRoot) - return Node(); - - return Node(*m_pRoot, m_pMemory); -} - -void NodeBuilder::OnDocumentStart(const Mark&) {} - -void NodeBuilder::OnDocumentEnd() {} - -void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) { - detail::node& node = Push(mark, anchor); - node.set_null(); - Pop(); -} - -void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) { - detail::node& node = *m_anchors[anchor]; - Push(node); - Pop(); -} - -void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value) { - detail::node& node = Push(mark, anchor); - node.set_scalar(value); - node.set_tag(tag); - Pop(); -} - -void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) { - detail::node& node = Push(mark, anchor); - node.set_tag(tag); - node.set_type(NodeType::Sequence); - node.set_style(style); -} - -void NodeBuilder::OnSequenceEnd() { Pop(); } - -void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) { - detail::node& node = Push(mark, anchor); - node.set_type(NodeType::Map); - node.set_tag(tag); - node.set_style(style); - m_mapDepth++; -} - -void NodeBuilder::OnMapEnd() { - assert(m_mapDepth > 0); - m_mapDepth--; - Pop(); -} - -detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) { - detail::node& node = m_pMemory->create_node(); - node.set_mark(mark); - RegisterAnchor(anchor, node); - Push(node); - return node; -} - -void NodeBuilder::Push(detail::node& node) { - const bool needsKey = - (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && - m_keys.size() < m_mapDepth); - - m_stack.push_back(&node); - if (needsKey) - m_keys.emplace_back(&node, false); -} - -void NodeBuilder::Pop() { - assert(!m_stack.empty()); - if (m_stack.size() == 1) { - m_pRoot = m_stack[0]; - m_stack.pop_back(); - return; - } - - detail::node& node = *m_stack.back(); - m_stack.pop_back(); - - detail::node& collection = *m_stack.back(); - - if (collection.type() == NodeType::Sequence) { - collection.push_back(node, m_pMemory); - } else if (collection.type() == NodeType::Map) { - assert(!m_keys.empty()); - PushedKey& key = m_keys.back(); - if (key.second) { - collection.insert(*key.first, node, m_pMemory); - m_keys.pop_back(); - } else { - key.second = true; - } - } else { - assert(false); - m_stack.clear(); - } -} - -void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) { - if (anchor) { - assert(anchor == m_anchors.size()); - m_anchors.push_back(&node); - } -} -} // namespace YAML diff --git a/third/yaml-cpp/src/nodebuilder.h b/third/yaml-cpp/src/nodebuilder.h deleted file mode 100644 index c580d40e..00000000 --- a/third/yaml-cpp/src/nodebuilder.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" -#include "yaml-cpp/node/ptr.h" - -namespace YAML { -namespace detail { -class node; -} // namespace detail -struct Mark; -} // namespace YAML - -namespace YAML { -class Node; - -class NodeBuilder : public EventHandler { - public: - NodeBuilder(); - NodeBuilder(const NodeBuilder&) = delete; - NodeBuilder(NodeBuilder&&) = delete; - NodeBuilder& operator=(const NodeBuilder&) = delete; - NodeBuilder& operator=(NodeBuilder&&) = delete; - ~NodeBuilder() override; - - Node Root(); - - void OnDocumentStart(const Mark& mark) override; - void OnDocumentEnd() override; - - void OnNull(const Mark& mark, anchor_t anchor) override; - void OnAlias(const Mark& mark, anchor_t anchor) override; - void OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value) override; - - void OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) override; - void OnSequenceEnd() override; - - void OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) override; - void OnMapEnd() override; - - private: - detail::node& Push(const Mark& mark, anchor_t anchor); - void Push(detail::node& node); - void Pop(); - void RegisterAnchor(anchor_t anchor, detail::node& node); - - private: - detail::shared_memory_holder m_pMemory; - detail::node* m_pRoot; - - using Nodes = std::vector; - Nodes m_stack; - Nodes m_anchors; - - using PushedKey = std::pair; - std::vector m_keys; - std::size_t m_mapDepth; -}; -} // namespace YAML - -#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/nodeevents.cpp b/third/yaml-cpp/src/nodeevents.cpp deleted file mode 100644 index b1774fef..00000000 --- a/third/yaml-cpp/src/nodeevents.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "nodeevents.h" -#include "yaml-cpp/eventhandler.h" -#include "yaml-cpp/mark.h" -#include "yaml-cpp/node/detail/node.h" -#include "yaml-cpp/node/detail/node_iterator.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -void NodeEvents::AliasManager::RegisterReference(const detail::node& node) { - m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor())); -} - -anchor_t NodeEvents::AliasManager::LookupAnchor( - const detail::node& node) const { - auto it = m_anchorByIdentity.find(node.ref()); - if (it == m_anchorByIdentity.end()) - return 0; - return it->second; -} - -NodeEvents::NodeEvents(const Node& node) - : m_pMemory(node.m_pMemory), m_root(node.m_pNode), m_refCount{} { - if (m_root) - Setup(*m_root); -} - -void NodeEvents::Setup(const detail::node& node) { - int& refCount = m_refCount[node.ref()]; - refCount++; - if (refCount > 1) - return; - - if (node.type() == NodeType::Sequence) { - for (auto element : node) - Setup(*element); - } else if (node.type() == NodeType::Map) { - for (auto element : node) { - Setup(*element.first); - Setup(*element.second); - } - } -} - -void NodeEvents::Emit(EventHandler& handler) { - AliasManager am; - - handler.OnDocumentStart(Mark()); - if (m_root) - Emit(*m_root, handler, am); - handler.OnDocumentEnd(); -} - -void NodeEvents::Emit(const detail::node& node, EventHandler& handler, - AliasManager& am) const { - anchor_t anchor = NullAnchor; - if (IsAliased(node)) { - anchor = am.LookupAnchor(node); - if (anchor) { - handler.OnAlias(Mark(), anchor); - return; - } - - am.RegisterReference(node); - anchor = am.LookupAnchor(node); - } - - switch (node.type()) { - case NodeType::Undefined: - break; - case NodeType::Null: - handler.OnNull(Mark(), anchor); - break; - case NodeType::Scalar: - handler.OnScalar(Mark(), node.tag(), anchor, node.scalar()); - break; - case NodeType::Sequence: - handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style()); - for (auto element : node) - Emit(*element, handler, am); - handler.OnSequenceEnd(); - break; - case NodeType::Map: - handler.OnMapStart(Mark(), node.tag(), anchor, node.style()); - for (auto element : node) { - Emit(*element.first, handler, am); - Emit(*element.second, handler, am); - } - handler.OnMapEnd(); - break; - } -} - -bool NodeEvents::IsAliased(const detail::node& node) const { - auto it = m_refCount.find(node.ref()); - return it != m_refCount.end() && it->second > 1; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/nodeevents.h b/third/yaml-cpp/src/nodeevents.h deleted file mode 100644 index efca9149..00000000 --- a/third/yaml-cpp/src/nodeevents.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/node/ptr.h" - -namespace YAML { -namespace detail { -class node; -} // namespace detail -} // namespace YAML - -namespace YAML { -class EventHandler; -class Node; - -class NodeEvents { - public: - explicit NodeEvents(const Node& node); - NodeEvents(const NodeEvents&) = delete; - NodeEvents(NodeEvents&&) = delete; - NodeEvents& operator=(const NodeEvents&) = delete; - NodeEvents& operator=(NodeEvents&&) = delete; - - void Emit(EventHandler& handler); - - private: - class AliasManager { - public: - AliasManager() : m_anchorByIdentity{}, m_curAnchor(0) {} - - void RegisterReference(const detail::node& node); - anchor_t LookupAnchor(const detail::node& node) const; - - private: - anchor_t _CreateNewAnchor() { return ++m_curAnchor; } - - private: - using AnchorByIdentity = std::map; - AnchorByIdentity m_anchorByIdentity; - - anchor_t m_curAnchor; - }; - - void Setup(const detail::node& node); - void Emit(const detail::node& node, EventHandler& handler, - AliasManager& am) const; - bool IsAliased(const detail::node& node) const; - - private: - detail::shared_memory_holder m_pMemory; - detail::node* m_root; - - using RefCount = std::map; - RefCount m_refCount; -}; -} // namespace YAML - -#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/null.cpp b/third/yaml-cpp/src/null.cpp deleted file mode 100644 index db7daebf..00000000 --- a/third/yaml-cpp/src/null.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "yaml-cpp/null.h" - -namespace YAML { -_Null Null; - -bool IsNullString(const std::string& str) { - return str.empty() || str == "~" || str == "null" || str == "Null" || - str == "NULL"; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/ostream_wrapper.cpp b/third/yaml-cpp/src/ostream_wrapper.cpp deleted file mode 100644 index 047a9f7c..00000000 --- a/third/yaml-cpp/src/ostream_wrapper.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "yaml-cpp/ostream_wrapper.h" - -#include -#include -#include - -namespace YAML { -ostream_wrapper::ostream_wrapper() - : m_buffer(1, '\0'), - m_pStream(nullptr), - m_pos(0), - m_row(0), - m_col(0), - m_comment(false) {} - -ostream_wrapper::ostream_wrapper(std::ostream& stream) - : m_buffer{}, - m_pStream(&stream), - m_pos(0), - m_row(0), - m_col(0), - m_comment(false) {} - -ostream_wrapper::~ostream_wrapper() = default; - -void ostream_wrapper::write(const std::string& str) { - if (m_pStream) { - m_pStream->write(str.c_str(), str.size()); - } else { - m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); - std::copy(str.begin(), str.end(), m_buffer.begin() + m_pos); - } - - for (char ch : str) { - update_pos(ch); - } -} - -void ostream_wrapper::write(const char* str, std::size_t size) { - if (m_pStream) { - m_pStream->write(str, size); - } else { - m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1)); - std::copy(str, str + size, m_buffer.begin() + m_pos); - } - - for (std::size_t i = 0; i < size; i++) { - update_pos(str[i]); - } -} - -void ostream_wrapper::update_pos(char ch) { - m_pos++; - m_col++; - - if (ch == '\n') { - m_row++; - m_col = 0; - m_comment = false; - } -} -} // namespace YAML diff --git a/third/yaml-cpp/src/parse.cpp b/third/yaml-cpp/src/parse.cpp deleted file mode 100644 index 262536b8..00000000 --- a/third/yaml-cpp/src/parse.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "yaml-cpp/node/parse.h" - -#include -#include - -#include "nodebuilder.h" -#include "yaml-cpp/node/impl.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/parser.h" - -namespace YAML { -Node Load(const std::string& input) { - std::stringstream stream(input); - return Load(stream); -} - -Node Load(const char* input) { - std::stringstream stream(input); - return Load(stream); -} - -Node Load(std::istream& input) { - Parser parser(input); - NodeBuilder builder; - if (!parser.HandleNextDocument(builder)) { - return Node(); - } - - return builder.Root(); -} - -Node LoadFile(const std::string& filename) { - std::ifstream fin(filename); - if (!fin) { - throw BadFile(filename); - } - return Load(fin); -} - -std::vector LoadAll(const std::string& input) { - std::stringstream stream(input); - return LoadAll(stream); -} - -std::vector LoadAll(const char* input) { - std::stringstream stream(input); - return LoadAll(stream); -} - -std::vector LoadAll(std::istream& input) { - std::vector docs; - - Parser parser(input); - while (true) { - NodeBuilder builder; - if (!parser.HandleNextDocument(builder)) { - break; - } - docs.push_back(builder.Root()); - } - - return docs; -} - -std::vector LoadAllFromFile(const std::string& filename) { - std::ifstream fin(filename); - if (!fin) { - throw BadFile(filename); - } - return LoadAll(fin); -} -} // namespace YAML diff --git a/third/yaml-cpp/src/parser.cpp b/third/yaml-cpp/src/parser.cpp deleted file mode 100644 index b8b78eba..00000000 --- a/third/yaml-cpp/src/parser.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include - -#include "directives.h" // IWYU pragma: keep -#include "scanner.h" // IWYU pragma: keep -#include "singledocparser.h" -#include "token.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep -#include "yaml-cpp/parser.h" - -namespace YAML { -class EventHandler; - -Parser::Parser() : m_pScanner{}, m_pDirectives{} {} - -Parser::Parser(std::istream& in) : Parser() { Load(in); } - -Parser::~Parser() = default; - -Parser::operator bool() const { return m_pScanner && !m_pScanner->empty(); } - -void Parser::Load(std::istream& in) { - m_pScanner.reset(new Scanner(in)); - m_pDirectives.reset(new Directives); -} - -bool Parser::HandleNextDocument(EventHandler& eventHandler) { - if (!m_pScanner) - return false; - - ParseDirectives(); - if (m_pScanner->empty()) { - return false; - } - - SingleDocParser sdp(*m_pScanner, *m_pDirectives); - sdp.HandleDocument(eventHandler); - return true; -} - -void Parser::ParseDirectives() { - bool readDirective = false; - - while (!m_pScanner->empty()) { - Token& token = m_pScanner->peek(); - if (token.type != Token::DIRECTIVE) { - break; - } - - // we keep the directives from the last document if none are specified; - // but if any directives are specific, then we reset them - if (!readDirective) { - m_pDirectives.reset(new Directives); - } - - readDirective = true; - HandleDirective(token); - m_pScanner->pop(); - } -} - -void Parser::HandleDirective(const Token& token) { - if (token.value == "YAML") { - HandleYamlDirective(token); - } else if (token.value == "TAG") { - HandleTagDirective(token); - } -} - -void Parser::HandleYamlDirective(const Token& token) { - if (token.params.size() != 1) { - throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS); - } - - if (!m_pDirectives->version.isDefault) { - throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE); - } - - std::stringstream str(token.params[0]); - str >> m_pDirectives->version.major; - str.get(); - str >> m_pDirectives->version.minor; - if (!str || str.peek() != EOF) { - throw ParserException( - token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]); - } - - if (m_pDirectives->version.major > 1) { - throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION); - } - - m_pDirectives->version.isDefault = false; - // TODO: warning on major == 1, minor > 2? -} - -void Parser::HandleTagDirective(const Token& token) { - if (token.params.size() != 2) - throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS); - - const std::string& handle = token.params[0]; - const std::string& prefix = token.params[1]; - if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) { - throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE); - } - - m_pDirectives->tags[handle] = prefix; -} - -void Parser::PrintTokens(std::ostream& out) { - if (!m_pScanner) { - return; - } - - while (!m_pScanner->empty()) { - out << m_pScanner->peek() << "\n"; - m_pScanner->pop(); - } -} -} // namespace YAML diff --git a/third/yaml-cpp/src/ptr_vector.h b/third/yaml-cpp/src/ptr_vector.h deleted file mode 100644 index d58de04c..00000000 --- a/third/yaml-cpp/src/ptr_vector.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include - -namespace YAML { - -// TODO: This class is no longer needed -template -class ptr_vector { - public: - ptr_vector() : m_data{} {} - ptr_vector(const ptr_vector&) = delete; - ptr_vector(ptr_vector&&) = default; - ptr_vector& operator=(const ptr_vector&) = delete; - ptr_vector& operator=(ptr_vector&&) = default; - - void clear() { m_data.clear(); } - - std::size_t size() const { return m_data.size(); } - bool empty() const { return m_data.empty(); } - - void push_back(std::unique_ptr&& t) { m_data.push_back(std::move(t)); } - T& operator[](std::size_t i) { return *m_data[i]; } - const T& operator[](std::size_t i) const { return *m_data[i]; } - - T& back() { return *(m_data.back().get()); } - - const T& back() const { return *(m_data.back().get()); } - - private: - std::vector> m_data; -}; -} // namespace YAML - -#endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/regex_yaml.cpp b/third/yaml-cpp/src/regex_yaml.cpp deleted file mode 100644 index bf1784b4..00000000 --- a/third/yaml-cpp/src/regex_yaml.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "regex_yaml.h" - -namespace YAML { -// constructors - -RegEx::RegEx(REGEX_OP op) : m_op(op), m_a(0), m_z(0), m_params{} {} -RegEx::RegEx() : RegEx(REGEX_EMPTY) {} - -RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch), m_z(0), m_params{} {} - -RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z), m_params{} {} - -RegEx::RegEx(const std::string& str, REGEX_OP op) - : m_op(op), m_a(0), m_z(0), m_params(str.begin(), str.end()) {} - -// combination constructors -RegEx operator!(const RegEx& ex) { - RegEx ret(REGEX_NOT); - ret.m_params.push_back(ex); - return ret; -} - -RegEx operator|(const RegEx& ex1, const RegEx& ex2) { - RegEx ret(REGEX_OR); - ret.m_params.push_back(ex1); - ret.m_params.push_back(ex2); - return ret; -} - -RegEx operator&(const RegEx& ex1, const RegEx& ex2) { - RegEx ret(REGEX_AND); - ret.m_params.push_back(ex1); - ret.m_params.push_back(ex2); - return ret; -} - -RegEx operator+(const RegEx& ex1, const RegEx& ex2) { - RegEx ret(REGEX_SEQ); - ret.m_params.push_back(ex1); - ret.m_params.push_back(ex2); - return ret; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/regex_yaml.h b/third/yaml-cpp/src/regex_yaml.h deleted file mode 100644 index c70ab60d..00000000 --- a/third/yaml-cpp/src/regex_yaml.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -class Stream; - -enum REGEX_OP { - REGEX_EMPTY, - REGEX_MATCH, - REGEX_RANGE, - REGEX_OR, - REGEX_AND, - REGEX_NOT, - REGEX_SEQ -}; - -// simplified regular expressions -// . Only straightforward matches (no repeated characters) -// . Only matches from start of string -class YAML_CPP_API RegEx { - public: - RegEx(); - explicit RegEx(char ch); - RegEx(char a, char z); - RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ); - ~RegEx() = default; - - friend YAML_CPP_API RegEx operator!(const RegEx& ex); - friend YAML_CPP_API RegEx operator|(const RegEx& ex1, const RegEx& ex2); - friend YAML_CPP_API RegEx operator&(const RegEx& ex1, const RegEx& ex2); - friend YAML_CPP_API RegEx operator+(const RegEx& ex1, const RegEx& ex2); - - bool Matches(char ch) const; - bool Matches(const std::string& str) const; - bool Matches(const Stream& in) const; - template - bool Matches(const Source& source) const; - - int Match(const std::string& str) const; - int Match(const Stream& in) const; - template - int Match(const Source& source) const; - - private: - explicit RegEx(REGEX_OP op); - - template - bool IsValidSource(const Source& source) const; - template - int MatchUnchecked(const Source& source) const; - - template - int MatchOpEmpty(const Source& source) const; - template - int MatchOpMatch(const Source& source) const; - template - int MatchOpRange(const Source& source) const; - template - int MatchOpOr(const Source& source) const; - template - int MatchOpAnd(const Source& source) const; - template - int MatchOpNot(const Source& source) const; - template - int MatchOpSeq(const Source& source) const; - - private: - REGEX_OP m_op; - char m_a{}; - char m_z{}; - std::vector m_params; -}; -} // namespace YAML - -#include "regeximpl.h" - -#endif // REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/regeximpl.h b/third/yaml-cpp/src/regeximpl.h deleted file mode 100644 index a742cdc3..00000000 --- a/third/yaml-cpp/src/regeximpl.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "stream.h" -#include "streamcharsource.h" -#include "stringsource.h" - -namespace YAML { -// query matches -inline bool RegEx::Matches(char ch) const { - std::string str; - str += ch; - return Matches(str); -} - -inline bool RegEx::Matches(const std::string& str) const { - return Match(str) >= 0; -} - -inline bool RegEx::Matches(const Stream& in) const { return Match(in) >= 0; } - -template -inline bool RegEx::Matches(const Source& source) const { - return Match(source) >= 0; -} - -// Match -// . Matches the given string against this regular expression. -// . Returns the number of characters matched. -// . Returns -1 if no characters were matched (the reason for -// not returning zero is that we may have an empty regex -// which is ALWAYS successful at matching zero characters). -// . REMEMBER that we only match from the start of the buffer! -inline int RegEx::Match(const std::string& str) const { - StringCharSource source(str.c_str(), str.size()); - return Match(source); -} - -inline int RegEx::Match(const Stream& in) const { - StreamCharSource source(in); - return Match(source); -} - -template -inline bool RegEx::IsValidSource(const Source& source) const { - return source; -} - -template <> -inline bool RegEx::IsValidSource( - const StringCharSource& source) const { - switch (m_op) { - case REGEX_MATCH: - case REGEX_RANGE: - return source; - default: - return true; - } -} - -template -inline int RegEx::Match(const Source& source) const { - return IsValidSource(source) ? MatchUnchecked(source) : -1; -} - -template -inline int RegEx::MatchUnchecked(const Source& source) const { - switch (m_op) { - case REGEX_EMPTY: - return MatchOpEmpty(source); - case REGEX_MATCH: - return MatchOpMatch(source); - case REGEX_RANGE: - return MatchOpRange(source); - case REGEX_OR: - return MatchOpOr(source); - case REGEX_AND: - return MatchOpAnd(source); - case REGEX_NOT: - return MatchOpNot(source); - case REGEX_SEQ: - return MatchOpSeq(source); - } - - return -1; -} - -////////////////////////////////////////////////////////////////////////////// -// Operators -// Note: the convention MatchOp* is that we can assume -// IsSourceValid(source). -// So we do all our checks *before* we call these functions - -// EmptyOperator -template -inline int RegEx::MatchOpEmpty(const Source& source) const { - return source[0] == Stream::eof() ? 0 : -1; -} - -template <> -inline int RegEx::MatchOpEmpty( - const StringCharSource& source) const { - return !source ? 0 : -1; // the empty regex only is successful on the empty - // string -} - -// MatchOperator -template -inline int RegEx::MatchOpMatch(const Source& source) const { - if (source[0] != m_a) - return -1; - return 1; -} - -// RangeOperator -template -inline int RegEx::MatchOpRange(const Source& source) const { - if (m_a > source[0] || m_z < source[0]) - return -1; - return 1; -} - -// OrOperator -template -inline int RegEx::MatchOpOr(const Source& source) const { - for (const RegEx& param : m_params) { - int n = param.MatchUnchecked(source); - if (n >= 0) - return n; - } - return -1; -} - -// AndOperator -// Note: 'AND' is a little funny, since we may be required to match things -// of different lengths. If we find a match, we return the length of -// the FIRST entry on the list. -template -inline int RegEx::MatchOpAnd(const Source& source) const { - int first = -1; - for (std::size_t i = 0; i < m_params.size(); i++) { - int n = m_params[i].MatchUnchecked(source); - if (n == -1) - return -1; - if (i == 0) - first = n; - } - return first; -} - -// NotOperator -template -inline int RegEx::MatchOpNot(const Source& source) const { - if (m_params.empty()) - return -1; - if (m_params[0].MatchUnchecked(source) >= 0) - return -1; - return 1; -} - -// SeqOperator -template -inline int RegEx::MatchOpSeq(const Source& source) const { - int offset = 0; - for (const RegEx& param : m_params) { - int n = param.Match(source + offset); // note Match, not - // MatchUnchecked because we - // need to check validity after - // the offset - if (n == -1) - return -1; - offset += n; - } - - return offset; -} -} // namespace YAML - -#endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/scanner.cpp b/third/yaml-cpp/src/scanner.cpp deleted file mode 100644 index ea5511a1..00000000 --- a/third/yaml-cpp/src/scanner.cpp +++ /dev/null @@ -1,391 +0,0 @@ -#include -#include - -#include "exp.h" -#include "scanner.h" -#include "token.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -Scanner::Scanner(std::istream& in) - : INPUT(in), - m_tokens{}, - m_startedStream(false), - m_endedStream(false), - m_simpleKeyAllowed(false), - m_canBeJSONFlow(false), - m_simpleKeys{}, - m_indents{}, - m_indentRefs{}, - m_flows{} {} - -Scanner::~Scanner() = default; - -bool Scanner::empty() { - EnsureTokensInQueue(); - return m_tokens.empty(); -} - -void Scanner::pop() { - EnsureTokensInQueue(); - if (!m_tokens.empty()) - m_tokens.pop(); -} - -Token& Scanner::peek() { - EnsureTokensInQueue(); - assert(!m_tokens.empty()); // should we be asserting here? I mean, we really - // just be checking - // if it's empty before peeking. - -#if 0 - static Token *pLast = 0; - if(pLast != &m_tokens.front()) - std::cerr << "peek: " << m_tokens.front() << "\n"; - pLast = &m_tokens.front(); -#endif - - return m_tokens.front(); -} - -Mark Scanner::mark() const { return INPUT.mark(); } - -void Scanner::EnsureTokensInQueue() { - while (true) { - if (!m_tokens.empty()) { - Token& token = m_tokens.front(); - - // if this guy's valid, then we're done - if (token.status == Token::VALID) { - return; - } - - // here's where we clean up the impossible tokens - if (token.status == Token::INVALID) { - m_tokens.pop(); - continue; - } - - // note: what's left are the unverified tokens - } - - // no token? maybe we've actually finished - if (m_endedStream) { - return; - } - - // no? then scan... - ScanNextToken(); - } -} - -void Scanner::ScanNextToken() { - if (m_endedStream) { - return; - } - - if (!m_startedStream) { - return StartStream(); - } - - // get rid of whitespace, etc. (in between tokens it should be irrelevant) - ScanToNextToken(); - - // maybe need to end some blocks - PopIndentToHere(); - - // ***** - // And now branch based on the next few characters! - // ***** - - // end of stream - if (!INPUT) { - return EndStream(); - } - - if (INPUT.column() == 0 && INPUT.peek() == Keys::Directive) { - return ScanDirective(); - } - - // document token - if (INPUT.column() == 0 && Exp::DocStart().Matches(INPUT)) { - return ScanDocStart(); - } - - if (INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT)) { - return ScanDocEnd(); - } - - // flow start/end/entry - if (INPUT.peek() == Keys::FlowSeqStart || - INPUT.peek() == Keys::FlowMapStart) { - return ScanFlowStart(); - } - - if (INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd) { - return ScanFlowEnd(); - } - - if (INPUT.peek() == Keys::FlowEntry) { - return ScanFlowEntry(); - } - - // block/map stuff - if (Exp::BlockEntry().Matches(INPUT)) { - return ScanBlockEntry(); - } - - if ((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT)) { - return ScanKey(); - } - - if (GetValueRegex().Matches(INPUT)) { - return ScanValue(); - } - - // alias/anchor - if (INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor) { - return ScanAnchorOrAlias(); - } - - // tag - if (INPUT.peek() == Keys::Tag) { - return ScanTag(); - } - - // special scalars - if (InBlockContext() && (INPUT.peek() == Keys::LiteralScalar || - INPUT.peek() == Keys::FoldedScalar)) { - return ScanBlockScalar(); - } - - if (INPUT.peek() == '\'' || INPUT.peek() == '\"') { - return ScanQuotedScalar(); - } - - // plain scalars - if ((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow()) - .Matches(INPUT)) { - return ScanPlainScalar(); - } - - // don't know what it is! - throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN); -} - -void Scanner::ScanToNextToken() { - while (true) { - // first eat whitespace - while (INPUT && IsWhitespaceToBeEaten(INPUT.peek())) { - if (InBlockContext() && Exp::Tab().Matches(INPUT)) { - m_simpleKeyAllowed = false; - } - INPUT.eat(1); - } - - // then eat a comment - if (Exp::Comment().Matches(INPUT)) { - // eat until line break - while (INPUT && !Exp::Break().Matches(INPUT)) { - INPUT.eat(1); - } - } - - // if it's NOT a line break, then we're done! - if (!Exp::Break().Matches(INPUT)) { - break; - } - - // otherwise, let's eat the line break and keep going - int n = Exp::Break().Match(INPUT); - INPUT.eat(n); - - // oh yeah, and let's get rid of that simple key - InvalidateSimpleKey(); - - // new line - we may be able to accept a simple key now - if (InBlockContext()) { - m_simpleKeyAllowed = true; - } - } -} - -/////////////////////////////////////////////////////////////////////// -// Misc. helpers - -// IsWhitespaceToBeEaten -// . We can eat whitespace if it's a space or tab -// . Note: originally tabs in block context couldn't be eaten -// "where a simple key could be allowed -// (i.e., not at the beginning of a line, or following '-', '?', or -// ':')" -// I think this is wrong, since tabs can be non-content whitespace; it's just -// that they can't contribute to indentation, so once you've seen a tab in a -// line, you can't start a simple key -bool Scanner::IsWhitespaceToBeEaten(char ch) { - if (ch == ' ') { - return true; - } - - if (ch == '\t') { - return true; - } - - return false; -} - -const RegEx& Scanner::GetValueRegex() const { - if (InBlockContext()) { - return Exp::Value(); - } - - return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow(); -} - -void Scanner::StartStream() { - m_startedStream = true; - m_simpleKeyAllowed = true; - std::unique_ptr pIndent( - new IndentMarker(-1, IndentMarker::NONE)); - m_indentRefs.push_back(std::move(pIndent)); - m_indents.push(&m_indentRefs.back()); -} - -void Scanner::EndStream() { - // force newline - if (INPUT.column() > 0) { - INPUT.ResetColumn(); - } - - PopAllIndents(); - PopAllSimpleKeys(); - - m_simpleKeyAllowed = false; - m_endedStream = true; -} - -Token* Scanner::PushToken(Token::TYPE type) { - m_tokens.push(Token(type, INPUT.mark())); - return &m_tokens.back(); -} - -Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const { - switch (type) { - case IndentMarker::SEQ: - return Token::BLOCK_SEQ_START; - case IndentMarker::MAP: - return Token::BLOCK_MAP_START; - case IndentMarker::NONE: - assert(false); - break; - } - assert(false); - throw std::runtime_error("yaml-cpp: internal error, invalid indent type"); -} - -Scanner::IndentMarker* Scanner::PushIndentTo(int column, - IndentMarker::INDENT_TYPE type) { - // are we in flow? - if (InFlowContext()) { - return nullptr; - } - - std::unique_ptr pIndent(new IndentMarker(column, type)); - IndentMarker& indent = *pIndent; - const IndentMarker& lastIndent = *m_indents.top(); - - // is this actually an indentation? - if (indent.column < lastIndent.column) { - return nullptr; - } - if (indent.column == lastIndent.column && - !(indent.type == IndentMarker::SEQ && - lastIndent.type == IndentMarker::MAP)) { - return nullptr; - } - - // push a start token - indent.pStartToken = PushToken(GetStartTokenFor(type)); - - // and then the indent - m_indents.push(&indent); - m_indentRefs.push_back(std::move(pIndent)); - return &m_indentRefs.back(); -} - -void Scanner::PopIndentToHere() { - // are we in flow? - if (InFlowContext()) { - return; - } - - // now pop away - while (!m_indents.empty()) { - const IndentMarker& indent = *m_indents.top(); - if (indent.column < INPUT.column()) { - break; - } - if (indent.column == INPUT.column() && - !(indent.type == IndentMarker::SEQ && - !Exp::BlockEntry().Matches(INPUT))) { - break; - } - - PopIndent(); - } - - while (!m_indents.empty() && - m_indents.top()->status == IndentMarker::INVALID) { - PopIndent(); - } -} - -void Scanner::PopAllIndents() { - // are we in flow? - if (InFlowContext()) { - return; - } - - // now pop away - while (!m_indents.empty()) { - const IndentMarker& indent = *m_indents.top(); - if (indent.type == IndentMarker::NONE) { - break; - } - - PopIndent(); - } -} - -void Scanner::PopIndent() { - const IndentMarker& indent = *m_indents.top(); - m_indents.pop(); - - if (indent.status != IndentMarker::VALID) { - InvalidateSimpleKey(); - return; - } - - if (indent.type == IndentMarker::SEQ) { - m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark())); - } else if (indent.type == IndentMarker::MAP) { - m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark())); - } -} - -int Scanner::GetTopIndent() const { - if (m_indents.empty()) { - return 0; - } - return m_indents.top()->column; -} - -void Scanner::ThrowParserException(const std::string& msg) const { - Mark mark = Mark::null_mark(); - if (!m_tokens.empty()) { - const Token& token = m_tokens.front(); - mark = token.mark; - } - throw ParserException(mark, msg); -} -} // namespace YAML diff --git a/third/yaml-cpp/src/scanner.h b/third/yaml-cpp/src/scanner.h deleted file mode 100644 index 4af938e6..00000000 --- a/third/yaml-cpp/src/scanner.h +++ /dev/null @@ -1,188 +0,0 @@ -#ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include -#include - -#include "ptr_vector.h" -#include "stream.h" -#include "token.h" -#include "yaml-cpp/mark.h" - -namespace YAML { -class Node; -class RegEx; - -/** - * A scanner transforms a stream of characters into a stream of tokens. - */ -class Scanner { - public: - explicit Scanner(std::istream &in); - ~Scanner(); - - /** Returns true if there are no more tokens to be read. */ - bool empty(); - - /** Removes the next token in the queue. */ - void pop(); - - /** Returns, but does not remove, the next token in the queue. */ - Token &peek(); - - /** Returns the current mark in the input stream. */ - Mark mark() const; - - private: - struct IndentMarker { - enum INDENT_TYPE { MAP, SEQ, NONE }; - enum STATUS { VALID, INVALID, UNKNOWN }; - IndentMarker(int column_, INDENT_TYPE type_) - : column(column_), type(type_), status(VALID), pStartToken(nullptr) {} - - int column; - INDENT_TYPE type; - STATUS status; - Token *pStartToken; - }; - - enum FLOW_MARKER { FLOW_MAP, FLOW_SEQ }; - - private: - // scanning - - /** - * Scans until there's a valid token at the front of the queue, or the queue - * is empty. The state can be checked by {@link #empty}, and the next token - * retrieved by {@link #peek}. - */ - void EnsureTokensInQueue(); - - /** - * The main scanning function; this method branches out to scan whatever the - * next token should be. - */ - void ScanNextToken(); - - /** Eats the input stream until it reaches the next token-like thing. */ - void ScanToNextToken(); - - /** Sets the initial conditions for starting a stream. */ - void StartStream(); - - /** Closes out the stream, finish up, etc. */ - void EndStream(); - - Token *PushToken(Token::TYPE type); - - bool InFlowContext() const { return !m_flows.empty(); } - bool InBlockContext() const { return m_flows.empty(); } - std::size_t GetFlowLevel() const { return m_flows.size(); } - - Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const; - - /** - * Pushes an indentation onto the stack, and enqueues the proper token - * (sequence start or mapping start). - * - * @return the indent marker it generates (if any). - */ - IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type); - - /** - * Pops indentations off the stack until it reaches the current indentation - * level, and enqueues the proper token each time. Then pops all invalid - * indentations off. - */ - void PopIndentToHere(); - - /** - * Pops all indentations (except for the base empty one) off the stack, and - * enqueues the proper token each time. - */ - void PopAllIndents(); - - /** Pops a single indent, pushing the proper token. */ - void PopIndent(); - int GetTopIndent() const; - - // checking input - bool CanInsertPotentialSimpleKey() const; - bool ExistsActiveSimpleKey() const; - void InsertPotentialSimpleKey(); - void InvalidateSimpleKey(); - bool VerifySimpleKey(); - void PopAllSimpleKeys(); - - /** - * Throws a ParserException with the current token location (if available), - * and does not parse any more tokens. - */ - void ThrowParserException(const std::string &msg) const; - - bool IsWhitespaceToBeEaten(char ch); - - /** - * Returns the appropriate regex to check if the next token is a value token. - */ - const RegEx &GetValueRegex() const; - - struct SimpleKey { - SimpleKey(const Mark &mark_, std::size_t flowLevel_); - - void Validate(); - void Invalidate(); - - Mark mark; - std::size_t flowLevel; - IndentMarker *pIndent; - Token *pMapStart, *pKey; - }; - - // and the tokens - void ScanDirective(); - void ScanDocStart(); - void ScanDocEnd(); - void ScanBlockSeqStart(); - void ScanBlockMapSTart(); - void ScanBlockEnd(); - void ScanBlockEntry(); - void ScanFlowStart(); - void ScanFlowEnd(); - void ScanFlowEntry(); - void ScanKey(); - void ScanValue(); - void ScanAnchorOrAlias(); - void ScanTag(); - void ScanPlainScalar(); - void ScanQuotedScalar(); - void ScanBlockScalar(); - - private: - // the stream - Stream INPUT; - - // the output (tokens) - std::queue m_tokens; - - // state info - bool m_startedStream, m_endedStream; - bool m_simpleKeyAllowed; - bool m_canBeJSONFlow; - std::stack m_simpleKeys; - std::stack m_indents; - ptr_vector m_indentRefs; // for "garbage collection" - std::stack m_flows; -}; -} - -#endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/scanscalar.cpp b/third/yaml-cpp/src/scanscalar.cpp deleted file mode 100644 index be57b1cd..00000000 --- a/third/yaml-cpp/src/scanscalar.cpp +++ /dev/null @@ -1,251 +0,0 @@ -#include "scanscalar.h" - -#include - -#include "exp.h" -#include "regeximpl.h" -#include "stream.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -// ScanScalar -// . This is where the scalar magic happens. -// -// . We do the scanning in three phases: -// 1. Scan until newline -// 2. Eat newline -// 3. Scan leading blanks. -// -// . Depending on the parameters given, we store or stop -// and different places in the above flow. -std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) { - bool foundNonEmptyLine = false; - bool pastOpeningBreak = (params.fold == FOLD_FLOW); - bool emptyLine = false, moreIndented = false; - int foldedNewlineCount = 0; - bool foldedNewlineStartedMoreIndented = false; - std::size_t lastEscapedChar = std::string::npos; - std::string scalar; - params.leadingSpaces = false; - - if (!params.end) { - params.end = &Exp::Empty(); - } - - while (INPUT) { - // ******************************** - // Phase #1: scan until line ending - - std::size_t lastNonWhitespaceChar = scalar.size(); - bool escapedNewline = false; - while (!params.end->Matches(INPUT) && !Exp::Break().Matches(INPUT)) { - if (!INPUT) { - break; - } - - // document indicator? - if (INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) { - if (params.onDocIndicator == BREAK) { - break; - } - if (params.onDocIndicator == THROW) { - throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR); - } - } - - foundNonEmptyLine = true; - pastOpeningBreak = true; - - // escaped newline? (only if we're escaping on slash) - if (params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) { - // eat escape character and get out (but preserve trailing whitespace!) - INPUT.get(); - lastNonWhitespaceChar = scalar.size(); - lastEscapedChar = scalar.size(); - escapedNewline = true; - break; - } - - // escape this? - if (INPUT.peek() == params.escape) { - scalar += Exp::Escape(INPUT); - lastNonWhitespaceChar = scalar.size(); - lastEscapedChar = scalar.size(); - continue; - } - - // otherwise, just add the damn character - char ch = INPUT.get(); - scalar += ch; - if (ch != ' ' && ch != '\t') { - lastNonWhitespaceChar = scalar.size(); - } - } - - // eof? if we're looking to eat something, then we throw - if (!INPUT) { - if (params.eatEnd) { - throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR); - } - break; - } - - // doc indicator? - if (params.onDocIndicator == BREAK && INPUT.column() == 0 && - Exp::DocIndicator().Matches(INPUT)) { - break; - } - - // are we done via character match? - int n = params.end->Match(INPUT); - if (n >= 0) { - if (params.eatEnd) { - INPUT.eat(n); - } - break; - } - - // do we remove trailing whitespace? - if (params.fold == FOLD_FLOW) - scalar.erase(lastNonWhitespaceChar); - - // ******************************** - // Phase #2: eat line ending - n = Exp::Break().Match(INPUT); - INPUT.eat(n); - - // ******************************** - // Phase #3: scan initial spaces - - // first the required indentation - while (INPUT.peek() == ' ' && - (INPUT.column() < params.indent || - (params.detectIndent && !foundNonEmptyLine)) && - !params.end->Matches(INPUT)) { - INPUT.eat(1); - } - - // update indent if we're auto-detecting - if (params.detectIndent && !foundNonEmptyLine) { - params.indent = std::max(params.indent, INPUT.column()); - } - - // and then the rest of the whitespace - while (Exp::Blank().Matches(INPUT)) { - // we check for tabs that masquerade as indentation - if (INPUT.peek() == '\t' && INPUT.column() < params.indent && - params.onTabInIndentation == THROW) { - throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION); - } - - if (!params.eatLeadingWhitespace) { - break; - } - - if (params.end->Matches(INPUT)) { - break; - } - - INPUT.eat(1); - } - - // was this an empty line? - bool nextEmptyLine = Exp::Break().Matches(INPUT); - bool nextMoreIndented = Exp::Blank().Matches(INPUT); - if (params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine) - foldedNewlineStartedMoreIndented = moreIndented; - - // for block scalars, we always start with a newline, so we should ignore it - // (not fold or keep) - if (pastOpeningBreak) { - switch (params.fold) { - case DONT_FOLD: - scalar += "\n"; - break; - case FOLD_BLOCK: - if (!emptyLine && !nextEmptyLine && !moreIndented && - !nextMoreIndented && INPUT.column() >= params.indent) { - scalar += " "; - } else if (nextEmptyLine) { - foldedNewlineCount++; - } else { - scalar += "\n"; - } - - if (!nextEmptyLine && foldedNewlineCount > 0) { - scalar += std::string(foldedNewlineCount - 1, '\n'); - if (foldedNewlineStartedMoreIndented || - nextMoreIndented | !foundNonEmptyLine) { - scalar += "\n"; - } - foldedNewlineCount = 0; - } - break; - case FOLD_FLOW: - if (nextEmptyLine) { - scalar += "\n"; - } else if (!emptyLine && !escapedNewline) { - scalar += " "; - } - break; - } - } - - emptyLine = nextEmptyLine; - moreIndented = nextMoreIndented; - pastOpeningBreak = true; - - // are we done via indentation? - if (!emptyLine && INPUT.column() < params.indent) { - params.leadingSpaces = true; - break; - } - } - - // post-processing - if (params.trimTrailingSpaces) { - std::size_t pos = scalar.find_last_not_of(" \t"); - if (lastEscapedChar != std::string::npos) { - if (pos < lastEscapedChar || pos == std::string::npos) { - pos = lastEscapedChar; - } - } - if (pos < scalar.size()) { - scalar.erase(pos + 1); - } - } - - switch (params.chomp) { - case CLIP: { - std::size_t pos = scalar.find_last_not_of('\n'); - if (lastEscapedChar != std::string::npos) { - if (pos < lastEscapedChar || pos == std::string::npos) { - pos = lastEscapedChar; - } - } - if (pos == std::string::npos) { - scalar.erase(); - } else if (pos + 1 < scalar.size()) { - scalar.erase(pos + 2); - } - } break; - case STRIP: { - std::size_t pos = scalar.find_last_not_of('\n'); - if (lastEscapedChar != std::string::npos) { - if (pos < lastEscapedChar || pos == std::string::npos) { - pos = lastEscapedChar; - } - } - if (pos == std::string::npos) { - scalar.erase(); - } else if (pos < scalar.size()) { - scalar.erase(pos + 1); - } - } break; - default: - break; - } - - return scalar; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/scanscalar.h b/third/yaml-cpp/src/scanscalar.h deleted file mode 100644 index 296b885a..00000000 --- a/third/yaml-cpp/src/scanscalar.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "regex_yaml.h" -#include "stream.h" - -namespace YAML { -enum CHOMP { STRIP = -1, CLIP, KEEP }; -enum ACTION { NONE, BREAK, THROW }; -enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW }; - -struct ScanScalarParams { - ScanScalarParams() - : end(nullptr), - eatEnd(false), - indent(0), - detectIndent(false), - eatLeadingWhitespace(0), - escape(0), - fold(DONT_FOLD), - trimTrailingSpaces(0), - chomp(CLIP), - onDocIndicator(NONE), - onTabInIndentation(NONE), - leadingSpaces(false) {} - - // input: - const RegEx* end; // what condition ends this scalar? - // unowned. - bool eatEnd; // should we eat that condition when we see it? - int indent; // what level of indentation should be eaten and ignored? - bool detectIndent; // should we try to autodetect the indent? - bool eatLeadingWhitespace; // should we continue eating this delicious - // indentation after 'indent' spaces? - char escape; // what character do we escape on (i.e., slash or single quote) - // (0 for none) - FOLD fold; // how do we fold line ends? - bool trimTrailingSpaces; // do we remove all trailing spaces (at the very - // end) - CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very - // end) - // Note: strip means kill all, clip means keep at most one, keep means keep - // all - ACTION onDocIndicator; // what do we do if we see a document indicator? - ACTION onTabInIndentation; // what do we do if we see a tab where we should - // be seeing indentation spaces - - // output: - bool leadingSpaces; -}; - -std::string ScanScalar(Stream& INPUT, ScanScalarParams& params); -} - -#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/scantag.cpp b/third/yaml-cpp/src/scantag.cpp deleted file mode 100644 index 176cc5c7..00000000 --- a/third/yaml-cpp/src/scantag.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "exp.h" -#include "regex_yaml.h" -#include "regeximpl.h" -#include "stream.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep -#include "yaml-cpp/mark.h" - -namespace YAML { -const std::string ScanVerbatimTag(Stream& INPUT) { - std::string tag; - - // eat the start character - INPUT.get(); - - while (INPUT) { - if (INPUT.peek() == Keys::VerbatimTagEnd) { - // eat the end character - INPUT.get(); - return tag; - } - - int n = Exp::URI().Match(INPUT); - if (n <= 0) - break; - - tag += INPUT.get(n); - } - - throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG); -} - -const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) { - std::string tag; - canBeHandle = true; - Mark firstNonWordChar; - - while (INPUT) { - if (INPUT.peek() == Keys::Tag) { - if (!canBeHandle) - throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE); - break; - } - - int n = 0; - if (canBeHandle) { - n = Exp::Word().Match(INPUT); - if (n <= 0) { - canBeHandle = false; - firstNonWordChar = INPUT.mark(); - } - } - - if (!canBeHandle) - n = Exp::Tag().Match(INPUT); - - if (n <= 0) - break; - - tag += INPUT.get(n); - } - - return tag; -} - -const std::string ScanTagSuffix(Stream& INPUT) { - std::string tag; - - while (INPUT) { - int n = Exp::Tag().Match(INPUT); - if (n <= 0) - break; - - tag += INPUT.get(n); - } - - if (tag.empty()) - throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX); - - return tag; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/scantag.h b/third/yaml-cpp/src/scantag.h deleted file mode 100644 index 522ba549..00000000 --- a/third/yaml-cpp/src/scantag.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include "stream.h" - -namespace YAML { -const std::string ScanVerbatimTag(Stream& INPUT); -const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle); -const std::string ScanTagSuffix(Stream& INPUT); -} - -#endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/scantoken.cpp b/third/yaml-cpp/src/scantoken.cpp deleted file mode 100644 index 1a94ab1d..00000000 --- a/third/yaml-cpp/src/scantoken.cpp +++ /dev/null @@ -1,437 +0,0 @@ -#include - -#include "exp.h" -#include "regex_yaml.h" -#include "regeximpl.h" -#include "scanner.h" -#include "scanscalar.h" -#include "scantag.h" // IWYU pragma: keep -#include "tag.h" // IWYU pragma: keep -#include "token.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep -#include "yaml-cpp/mark.h" - -namespace YAML { -/////////////////////////////////////////////////////////////////////// -// Specialization for scanning specific tokens - -// Directive -// . Note: no semantic checking is done here (that's for the parser to do) -void Scanner::ScanDirective() { - std::string name; - std::vector params; - - // pop indents and simple keys - PopAllIndents(); - PopAllSimpleKeys(); - - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - // store pos and eat indicator - Token token(Token::DIRECTIVE, INPUT.mark()); - INPUT.eat(1); - - // read name - while (INPUT && !Exp::BlankOrBreak().Matches(INPUT)) - token.value += INPUT.get(); - - // read parameters - while (true) { - // first get rid of whitespace - while (Exp::Blank().Matches(INPUT)) - INPUT.eat(1); - - // break on newline or comment - if (!INPUT || Exp::Break().Matches(INPUT) || Exp::Comment().Matches(INPUT)) - break; - - // now read parameter - std::string param; - while (INPUT && !Exp::BlankOrBreak().Matches(INPUT)) - param += INPUT.get(); - - token.params.push_back(param); - } - - m_tokens.push(token); -} - -// DocStart -void Scanner::ScanDocStart() { - PopAllIndents(); - PopAllSimpleKeys(); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(3); - m_tokens.push(Token(Token::DOC_START, mark)); -} - -// DocEnd -void Scanner::ScanDocEnd() { - PopAllIndents(); - PopAllSimpleKeys(); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(3); - m_tokens.push(Token(Token::DOC_END, mark)); -} - -// FlowStart -void Scanner::ScanFlowStart() { - // flows can be simple keys - InsertPotentialSimpleKey(); - m_simpleKeyAllowed = true; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - char ch = INPUT.get(); - FLOW_MARKER flowType = (ch == Keys::FlowSeqStart ? FLOW_SEQ : FLOW_MAP); - m_flows.push(flowType); - Token::TYPE type = - (flowType == FLOW_SEQ ? Token::FLOW_SEQ_START : Token::FLOW_MAP_START); - m_tokens.push(Token(type, mark)); -} - -// FlowEnd -void Scanner::ScanFlowEnd() { - if (InBlockContext()) - throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END); - - // we might have a solo entry in the flow context - if (InFlowContext()) { - if (m_flows.top() == FLOW_MAP && VerifySimpleKey()) - m_tokens.push(Token(Token::VALUE, INPUT.mark())); - else if (m_flows.top() == FLOW_SEQ) - InvalidateSimpleKey(); - } - - m_simpleKeyAllowed = false; - m_canBeJSONFlow = true; - - // eat - Mark mark = INPUT.mark(); - char ch = INPUT.get(); - - // check that it matches the start - FLOW_MARKER flowType = (ch == Keys::FlowSeqEnd ? FLOW_SEQ : FLOW_MAP); - if (m_flows.top() != flowType) - throw ParserException(mark, ErrorMsg::FLOW_END); - m_flows.pop(); - - Token::TYPE type = (flowType ? Token::FLOW_SEQ_END : Token::FLOW_MAP_END); - m_tokens.push(Token(type, mark)); -} - -// FlowEntry -void Scanner::ScanFlowEntry() { - // we might have a solo entry in the flow context - if (InFlowContext()) { - if (m_flows.top() == FLOW_MAP && VerifySimpleKey()) - m_tokens.push(Token(Token::VALUE, INPUT.mark())); - else if (m_flows.top() == FLOW_SEQ) - InvalidateSimpleKey(); - } - - m_simpleKeyAllowed = true; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(1); - m_tokens.push(Token(Token::FLOW_ENTRY, mark)); -} - -// BlockEntry -void Scanner::ScanBlockEntry() { - // we better be in the block context! - if (InFlowContext()) - throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); - - // can we put it here? - if (!m_simpleKeyAllowed) - throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); - - PushIndentTo(INPUT.column(), IndentMarker::SEQ); - m_simpleKeyAllowed = true; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(1); - m_tokens.push(Token(Token::BLOCK_ENTRY, mark)); -} - -// Key -void Scanner::ScanKey() { - // handle keys differently in the block context (and manage indents) - if (InBlockContext()) { - if (!m_simpleKeyAllowed) - throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY); - - PushIndentTo(INPUT.column(), IndentMarker::MAP); - } - - // can only put a simple key here if we're in block context - m_simpleKeyAllowed = InBlockContext(); - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(1); - m_tokens.push(Token(Token::KEY, mark)); -} - -// Value -void Scanner::ScanValue() { - // and check that simple key - bool isSimpleKey = VerifySimpleKey(); - m_canBeJSONFlow = false; - - if (isSimpleKey) { - // can't follow a simple key with another simple key (dunno why, though - it - // seems fine) - m_simpleKeyAllowed = false; - } else { - // handle values differently in the block context (and manage indents) - if (InBlockContext()) { - if (!m_simpleKeyAllowed) - throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE); - - PushIndentTo(INPUT.column(), IndentMarker::MAP); - } - - // can only put a simple key here if we're in block context - m_simpleKeyAllowed = InBlockContext(); - } - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(1); - m_tokens.push(Token(Token::VALUE, mark)); -} - -// AnchorOrAlias -void Scanner::ScanAnchorOrAlias() { - bool alias; - std::string name; - - // insert a potential simple key - InsertPotentialSimpleKey(); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - // eat the indicator - Mark mark = INPUT.mark(); - char indicator = INPUT.get(); - alias = (indicator == Keys::Alias); - - // now eat the content - while (INPUT && Exp::Anchor().Matches(INPUT)) - name += INPUT.get(); - - // we need to have read SOMETHING! - if (name.empty()) - throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND - : ErrorMsg::ANCHOR_NOT_FOUND); - - // and needs to end correctly - if (INPUT && !Exp::AnchorEnd().Matches(INPUT)) - throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS - : ErrorMsg::CHAR_IN_ANCHOR); - - // and we're done - Token token(alias ? Token::ALIAS : Token::ANCHOR, mark); - token.value = name; - m_tokens.push(token); -} - -// Tag -void Scanner::ScanTag() { - // insert a potential simple key - InsertPotentialSimpleKey(); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - Token token(Token::TAG, INPUT.mark()); - - // eat the indicator - INPUT.get(); - - if (INPUT && INPUT.peek() == Keys::VerbatimTagStart) { - std::string tag = ScanVerbatimTag(INPUT); - - token.value = tag; - token.data = Tag::VERBATIM; - } else { - bool canBeHandle; - token.value = ScanTagHandle(INPUT, canBeHandle); - if (!canBeHandle && token.value.empty()) - token.data = Tag::NON_SPECIFIC; - else if (token.value.empty()) - token.data = Tag::SECONDARY_HANDLE; - else - token.data = Tag::PRIMARY_HANDLE; - - // is there a suffix? - if (canBeHandle && INPUT.peek() == Keys::Tag) { - // eat the indicator - INPUT.get(); - token.params.push_back(ScanTagSuffix(INPUT)); - token.data = Tag::NAMED_HANDLE; - } - } - - m_tokens.push(token); -} - -// PlainScalar -void Scanner::ScanPlainScalar() { - std::string scalar; - - // set up the scanning parameters - ScanScalarParams params; - params.end = - (InFlowContext() ? &Exp::ScanScalarEndInFlow() : &Exp::ScanScalarEnd()); - params.eatEnd = false; - params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1); - params.fold = FOLD_FLOW; - params.eatLeadingWhitespace = true; - params.trimTrailingSpaces = true; - params.chomp = STRIP; - params.onDocIndicator = BREAK; - params.onTabInIndentation = THROW; - - // insert a potential simple key - InsertPotentialSimpleKey(); - - Mark mark = INPUT.mark(); - scalar = ScanScalar(INPUT, params); - - // can have a simple key only if we ended the scalar by starting a new line - m_simpleKeyAllowed = params.leadingSpaces; - m_canBeJSONFlow = false; - - // finally, check and see if we ended on an illegal character - // if(Exp::IllegalCharInScalar.Matches(INPUT)) - // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR); - - Token token(Token::PLAIN_SCALAR, mark); - token.value = scalar; - m_tokens.push(token); -} - -// QuotedScalar -void Scanner::ScanQuotedScalar() { - std::string scalar; - - // peek at single or double quote (don't eat because we need to preserve (for - // the time being) the input position) - char quote = INPUT.peek(); - bool single = (quote == '\''); - - // setup the scanning parameters - ScanScalarParams params; - RegEx end = (single ? RegEx(quote) & !Exp::EscSingleQuote() : RegEx(quote)); - params.end = &end; - params.eatEnd = true; - params.escape = (single ? '\'' : '\\'); - params.indent = 0; - params.fold = FOLD_FLOW; - params.eatLeadingWhitespace = true; - params.trimTrailingSpaces = false; - params.chomp = CLIP; - params.onDocIndicator = THROW; - - // insert a potential simple key - InsertPotentialSimpleKey(); - - Mark mark = INPUT.mark(); - - // now eat that opening quote - INPUT.get(); - - // and scan - scalar = ScanScalar(INPUT, params); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = true; - - Token token(Token::NON_PLAIN_SCALAR, mark); - token.value = scalar; - m_tokens.push(token); -} - -// BlockScalarToken -// . These need a little extra processing beforehand. -// . We need to scan the line where the indicator is (this doesn't count as part -// of the scalar), -// and then we need to figure out what level of indentation we'll be using. -void Scanner::ScanBlockScalar() { - std::string scalar; - - ScanScalarParams params; - params.indent = 1; - params.detectIndent = true; - - // eat block indicator ('|' or '>') - Mark mark = INPUT.mark(); - char indicator = INPUT.get(); - params.fold = (indicator == Keys::FoldedScalar ? FOLD_BLOCK : DONT_FOLD); - - // eat chomping/indentation indicators - params.chomp = CLIP; - int n = Exp::Chomp().Match(INPUT); - for (int i = 0; i < n; i++) { - char ch = INPUT.get(); - if (ch == '+') - params.chomp = KEEP; - else if (ch == '-') - params.chomp = STRIP; - else if (Exp::Digit().Matches(ch)) { - if (ch == '0') - throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK); - - params.indent = ch - '0'; - params.detectIndent = false; - } - } - - // now eat whitespace - while (Exp::Blank().Matches(INPUT)) - INPUT.eat(1); - - // and comments to the end of the line - if (Exp::Comment().Matches(INPUT)) - while (INPUT && !Exp::Break().Matches(INPUT)) - INPUT.eat(1); - - // if it's not a line break, then we ran into a bad character inline - if (INPUT && !Exp::Break().Matches(INPUT)) - throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK); - - // set the initial indentation - if (GetTopIndent() >= 0) - params.indent += GetTopIndent(); - - params.eatLeadingWhitespace = false; - params.trimTrailingSpaces = false; - params.onTabInIndentation = THROW; - - scalar = ScanScalar(INPUT, params); - - // simple keys always ok after block scalars (since we're gonna start a new - // line anyways) - m_simpleKeyAllowed = true; - m_canBeJSONFlow = false; - - Token token(Token::NON_PLAIN_SCALAR, mark); - token.value = scalar; - m_tokens.push(token); -} -} // namespace YAML diff --git a/third/yaml-cpp/src/setting.h b/third/yaml-cpp/src/setting.h deleted file mode 100644 index 4960bbf7..00000000 --- a/third/yaml-cpp/src/setting.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/noexcept.h" -#include -#include -#include - -namespace YAML { - -class SettingChangeBase { - public: - virtual ~SettingChangeBase() = default; - virtual void pop() = 0; -}; - -template -class Setting { - public: - Setting() : m_value() {} - Setting(const T& value) : m_value() { set(value); } - - const T get() const { return m_value; } - std::unique_ptr set(const T& value); - void restore(const Setting& oldSetting) { m_value = oldSetting.get(); } - - private: - T m_value; -}; - -template -class SettingChange : public SettingChangeBase { - public: - SettingChange(Setting* pSetting) - : m_pCurSetting(pSetting), - m_oldSetting(*pSetting) // copy old setting to save its state - {} - SettingChange(const SettingChange&) = delete; - SettingChange(SettingChange&&) = delete; - SettingChange& operator=(const SettingChange&) = delete; - SettingChange& operator=(SettingChange&&) = delete; - - void pop() override { m_pCurSetting->restore(m_oldSetting); } - - private: - Setting* m_pCurSetting; - Setting m_oldSetting; -}; - -template -inline std::unique_ptr Setting::set(const T& value) { - std::unique_ptr pChange(new SettingChange(this)); - m_value = value; - return pChange; -} - -class SettingChanges { - public: - SettingChanges() : m_settingChanges{} {} - SettingChanges(const SettingChanges&) = delete; - SettingChanges(SettingChanges&&) YAML_CPP_NOEXCEPT = default; - SettingChanges& operator=(const SettingChanges&) = delete; - SettingChanges& operator=(SettingChanges&& rhs) YAML_CPP_NOEXCEPT { - if (this == &rhs) - return *this; - - clear(); - std::swap(m_settingChanges, rhs.m_settingChanges); - - return *this; - } - ~SettingChanges() { clear(); } - - void clear() YAML_CPP_NOEXCEPT { - restore(); - m_settingChanges.clear(); - } - - void restore() YAML_CPP_NOEXCEPT { - for (const auto& setting : m_settingChanges) - setting->pop(); - } - - void push(std::unique_ptr pSettingChange) { - m_settingChanges.push_back(std::move(pSettingChange)); - } - - private: - using setting_changes = std::vector>; - setting_changes m_settingChanges; -}; -} // namespace YAML - -#endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/simplekey.cpp b/third/yaml-cpp/src/simplekey.cpp deleted file mode 100644 index 67c2d712..00000000 --- a/third/yaml-cpp/src/simplekey.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "scanner.h" -#include "token.h" - -namespace YAML { -struct Mark; - -Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_) - : mark(mark_), - flowLevel(flowLevel_), - pIndent(nullptr), - pMapStart(nullptr), - pKey(nullptr) {} - -void Scanner::SimpleKey::Validate() { - // Note: pIndent will *not* be garbage here; - // we "garbage collect" them so we can - // always refer to them - if (pIndent) - pIndent->status = IndentMarker::VALID; - if (pMapStart) - pMapStart->status = Token::VALID; - if (pKey) - pKey->status = Token::VALID; -} - -void Scanner::SimpleKey::Invalidate() { - if (pIndent) - pIndent->status = IndentMarker::INVALID; - if (pMapStart) - pMapStart->status = Token::INVALID; - if (pKey) - pKey->status = Token::INVALID; -} - -// CanInsertPotentialSimpleKey -bool Scanner::CanInsertPotentialSimpleKey() const { - if (!m_simpleKeyAllowed) - return false; - - return !ExistsActiveSimpleKey(); -} - -// ExistsActiveSimpleKey -// . Returns true if there's a potential simple key at our flow level -// (there's allowed at most one per flow level, i.e., at the start of the flow -// start token) -bool Scanner::ExistsActiveSimpleKey() const { - if (m_simpleKeys.empty()) - return false; - - const SimpleKey& key = m_simpleKeys.top(); - return key.flowLevel == GetFlowLevel(); -} - -// InsertPotentialSimpleKey -// . If we can, add a potential simple key to the queue, -// and save it on a stack. -void Scanner::InsertPotentialSimpleKey() { - if (!CanInsertPotentialSimpleKey()) - return; - - SimpleKey key(INPUT.mark(), GetFlowLevel()); - - // first add a map start, if necessary - if (InBlockContext()) { - key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP); - if (key.pIndent) { - key.pIndent->status = IndentMarker::UNKNOWN; - key.pMapStart = key.pIndent->pStartToken; - key.pMapStart->status = Token::UNVERIFIED; - } - } - - // then add the (now unverified) key - m_tokens.push(Token(Token::KEY, INPUT.mark())); - key.pKey = &m_tokens.back(); - key.pKey->status = Token::UNVERIFIED; - - m_simpleKeys.push(key); -} - -// InvalidateSimpleKey -// . Automatically invalidate the simple key in our flow level -void Scanner::InvalidateSimpleKey() { - if (m_simpleKeys.empty()) - return; - - // grab top key - SimpleKey& key = m_simpleKeys.top(); - if (key.flowLevel != GetFlowLevel()) - return; - - key.Invalidate(); - m_simpleKeys.pop(); -} - -// VerifySimpleKey -// . Determines whether the latest simple key to be added is valid, -// and if so, makes it valid. -bool Scanner::VerifySimpleKey() { - if (m_simpleKeys.empty()) - return false; - - // grab top key - SimpleKey key = m_simpleKeys.top(); - - // only validate if we're in the correct flow level - if (key.flowLevel != GetFlowLevel()) - return false; - - m_simpleKeys.pop(); - - bool isValid = true; - - // needs to be less than 1024 characters and inline - if (INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024) - isValid = false; - - // invalidate key - if (isValid) - key.Validate(); - else - key.Invalidate(); - - return isValid; -} - -void Scanner::PopAllSimpleKeys() { - while (!m_simpleKeys.empty()) - m_simpleKeys.pop(); -} -} // namespace YAML diff --git a/third/yaml-cpp/src/singledocparser.cpp b/third/yaml-cpp/src/singledocparser.cpp deleted file mode 100644 index 22913d19..00000000 --- a/third/yaml-cpp/src/singledocparser.cpp +++ /dev/null @@ -1,435 +0,0 @@ -#include -#include -#include - -#include "collectionstack.h" // IWYU pragma: keep -#include "scanner.h" -#include "singledocparser.h" -#include "tag.h" -#include "token.h" -#include "yaml-cpp/depthguard.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep -#include "yaml-cpp/mark.h" -#include "yaml-cpp/null.h" - -namespace YAML { -SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives) - : m_scanner(scanner), - m_directives(directives), - m_pCollectionStack(new CollectionStack), - m_anchors{}, - m_curAnchor(0) {} - -SingleDocParser::~SingleDocParser() = default; - -// HandleDocument -// . Handles the next document -// . Throws a ParserException on error. -void SingleDocParser::HandleDocument(EventHandler& eventHandler) { - assert(!m_scanner.empty()); // guaranteed that there are tokens - assert(!m_curAnchor); - - eventHandler.OnDocumentStart(m_scanner.peek().mark); - - // eat doc start - if (m_scanner.peek().type == Token::DOC_START) - m_scanner.pop(); - - // recurse! - HandleNode(eventHandler); - - eventHandler.OnDocumentEnd(); - - // and finally eat any doc ends we see - while (!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END) - m_scanner.pop(); -} - -void SingleDocParser::HandleNode(EventHandler& eventHandler) { - DepthGuard<500> depthguard(depth, m_scanner.mark(), ErrorMsg::BAD_FILE); - - // an empty node *is* a possibility - if (m_scanner.empty()) { - eventHandler.OnNull(m_scanner.mark(), NullAnchor); - return; - } - - // save location - Mark mark = m_scanner.peek().mark; - - // special case: a value node by itself must be a map, with no header - if (m_scanner.peek().type == Token::VALUE) { - eventHandler.OnMapStart(mark, "?", NullAnchor, EmitterStyle::Default); - HandleMap(eventHandler); - eventHandler.OnMapEnd(); - return; - } - - // special case: an alias node - if (m_scanner.peek().type == Token::ALIAS) { - eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value)); - m_scanner.pop(); - return; - } - - std::string tag; - std::string anchor_name; - anchor_t anchor; - ParseProperties(tag, anchor, anchor_name); - - if (!anchor_name.empty()) - eventHandler.OnAnchor(mark, anchor_name); - - // after parsing properties, an empty node is again a possibility - if (m_scanner.empty()) { - eventHandler.OnNull(mark, anchor); - return; - } - - const Token& token = m_scanner.peek(); - - // add non-specific tags - if (tag.empty()) - tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?"); - - if (token.type == Token::PLAIN_SCALAR - && tag.compare("?") == 0 && IsNullString(token.value)) { - eventHandler.OnNull(mark, anchor); - m_scanner.pop(); - return; - } - - // now split based on what kind of node we should be - switch (token.type) { - case Token::PLAIN_SCALAR: - case Token::NON_PLAIN_SCALAR: - eventHandler.OnScalar(mark, tag, anchor, token.value); - m_scanner.pop(); - return; - case Token::FLOW_SEQ_START: - eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Flow); - HandleSequence(eventHandler); - eventHandler.OnSequenceEnd(); - return; - case Token::BLOCK_SEQ_START: - eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Block); - HandleSequence(eventHandler); - eventHandler.OnSequenceEnd(); - return; - case Token::FLOW_MAP_START: - eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow); - HandleMap(eventHandler); - eventHandler.OnMapEnd(); - return; - case Token::BLOCK_MAP_START: - eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Block); - HandleMap(eventHandler); - eventHandler.OnMapEnd(); - return; - case Token::KEY: - // compact maps can only go in a flow sequence - if (m_pCollectionStack->GetCurCollectionType() == - CollectionType::FlowSeq) { - eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow); - HandleMap(eventHandler); - eventHandler.OnMapEnd(); - return; - } - break; - default: - break; - } - - if (tag == "?") - eventHandler.OnNull(mark, anchor); - else - eventHandler.OnScalar(mark, tag, anchor, ""); -} - -void SingleDocParser::HandleSequence(EventHandler& eventHandler) { - // split based on start token - switch (m_scanner.peek().type) { - case Token::BLOCK_SEQ_START: - HandleBlockSequence(eventHandler); - break; - case Token::FLOW_SEQ_START: - HandleFlowSequence(eventHandler); - break; - default: - break; - } -} - -void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) { - // eat start token - m_scanner.pop(); - m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq); - - while (true) { - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ); - - Token token = m_scanner.peek(); - if (token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END) - throw ParserException(token.mark, ErrorMsg::END_OF_SEQ); - - m_scanner.pop(); - if (token.type == Token::BLOCK_SEQ_END) - break; - - // check for null - if (!m_scanner.empty()) { - const Token& nextToken = m_scanner.peek(); - if (nextToken.type == Token::BLOCK_ENTRY || - nextToken.type == Token::BLOCK_SEQ_END) { - eventHandler.OnNull(nextToken.mark, NullAnchor); - continue; - } - } - - HandleNode(eventHandler); - } - - m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq); -} - -void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler) { - // eat start token - m_scanner.pop(); - m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq); - - while (true) { - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW); - - // first check for end - if (m_scanner.peek().type == Token::FLOW_SEQ_END) { - m_scanner.pop(); - break; - } - - // then read the node - HandleNode(eventHandler); - - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW); - - // now eat the separator (or could be a sequence end, which we ignore - but - // if it's neither, then it's a bad node) - Token& token = m_scanner.peek(); - if (token.type == Token::FLOW_ENTRY) - m_scanner.pop(); - else if (token.type != Token::FLOW_SEQ_END) - throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW); - } - - m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq); -} - -void SingleDocParser::HandleMap(EventHandler& eventHandler) { - // split based on start token - switch (m_scanner.peek().type) { - case Token::BLOCK_MAP_START: - HandleBlockMap(eventHandler); - break; - case Token::FLOW_MAP_START: - HandleFlowMap(eventHandler); - break; - case Token::KEY: - HandleCompactMap(eventHandler); - break; - case Token::VALUE: - HandleCompactMapWithNoKey(eventHandler); - break; - default: - break; - } -} - -void SingleDocParser::HandleBlockMap(EventHandler& eventHandler) { - // eat start token - m_scanner.pop(); - m_pCollectionStack->PushCollectionType(CollectionType::BlockMap); - - while (true) { - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP); - - Token token = m_scanner.peek(); - if (token.type != Token::KEY && token.type != Token::VALUE && - token.type != Token::BLOCK_MAP_END) - throw ParserException(token.mark, ErrorMsg::END_OF_MAP); - - if (token.type == Token::BLOCK_MAP_END) { - m_scanner.pop(); - break; - } - - // grab key (if non-null) - if (token.type == Token::KEY) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(token.mark, NullAnchor); - } - - // now grab value (optional) - if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(token.mark, NullAnchor); - } - } - - m_pCollectionStack->PopCollectionType(CollectionType::BlockMap); -} - -void SingleDocParser::HandleFlowMap(EventHandler& eventHandler) { - // eat start token - m_scanner.pop(); - m_pCollectionStack->PushCollectionType(CollectionType::FlowMap); - - while (true) { - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW); - - Token& token = m_scanner.peek(); - const Mark mark = token.mark; - // first check for end - if (token.type == Token::FLOW_MAP_END) { - m_scanner.pop(); - break; - } - - // grab key (if non-null) - if (token.type == Token::KEY) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(mark, NullAnchor); - } - - // now grab value (optional) - if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(mark, NullAnchor); - } - - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW); - - // now eat the separator (or could be a map end, which we ignore - but if - // it's neither, then it's a bad node) - Token& nextToken = m_scanner.peek(); - if (nextToken.type == Token::FLOW_ENTRY) - m_scanner.pop(); - else if (nextToken.type != Token::FLOW_MAP_END) - throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW); - } - - m_pCollectionStack->PopCollectionType(CollectionType::FlowMap); -} - -// . Single "key: value" pair in a flow sequence -void SingleDocParser::HandleCompactMap(EventHandler& eventHandler) { - m_pCollectionStack->PushCollectionType(CollectionType::CompactMap); - - // grab key - Mark mark = m_scanner.peek().mark; - m_scanner.pop(); - HandleNode(eventHandler); - - // now grab value (optional) - if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(mark, NullAnchor); - } - - m_pCollectionStack->PopCollectionType(CollectionType::CompactMap); -} - -// . Single ": value" pair in a flow sequence -void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler) { - m_pCollectionStack->PushCollectionType(CollectionType::CompactMap); - - // null key - eventHandler.OnNull(m_scanner.peek().mark, NullAnchor); - - // grab value - m_scanner.pop(); - HandleNode(eventHandler); - - m_pCollectionStack->PopCollectionType(CollectionType::CompactMap); -} - -// ParseProperties -// . Grabs any tag or anchor tokens and deals with them. -void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor, - std::string& anchor_name) { - tag.clear(); - anchor_name.clear(); - anchor = NullAnchor; - - while (true) { - if (m_scanner.empty()) - return; - - switch (m_scanner.peek().type) { - case Token::TAG: - ParseTag(tag); - break; - case Token::ANCHOR: - ParseAnchor(anchor, anchor_name); - break; - default: - return; - } - } -} - -void SingleDocParser::ParseTag(std::string& tag) { - Token& token = m_scanner.peek(); - if (!tag.empty()) - throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS); - - Tag tagInfo(token); - tag = tagInfo.Translate(m_directives); - m_scanner.pop(); -} - -void SingleDocParser::ParseAnchor(anchor_t& anchor, std::string& anchor_name) { - Token& token = m_scanner.peek(); - if (anchor) - throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS); - - anchor_name = token.value; - anchor = RegisterAnchor(token.value); - m_scanner.pop(); -} - -anchor_t SingleDocParser::RegisterAnchor(const std::string& name) { - if (name.empty()) - return NullAnchor; - - return m_anchors[name] = ++m_curAnchor; -} - -anchor_t SingleDocParser::LookupAnchor(const Mark& mark, - const std::string& name) const { - auto it = m_anchors.find(name); - if (it == m_anchors.end()) { - std::stringstream ss; - ss << ErrorMsg::UNKNOWN_ANCHOR << name; - throw ParserException(mark, ss.str()); - } - - return it->second; -} -} // namespace YAML diff --git a/third/yaml-cpp/src/singledocparser.h b/third/yaml-cpp/src/singledocparser.h deleted file mode 100644 index f484eb1f..00000000 --- a/third/yaml-cpp/src/singledocparser.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include - -#include "yaml-cpp/anchor.h" - -namespace YAML { -class CollectionStack; -template class DepthGuard; // depthguard.h -class EventHandler; -class Node; -class Scanner; -struct Directives; -struct Mark; -struct Token; - -class SingleDocParser { - public: - SingleDocParser(Scanner& scanner, const Directives& directives); - SingleDocParser(const SingleDocParser&) = delete; - SingleDocParser(SingleDocParser&&) = delete; - SingleDocParser& operator=(const SingleDocParser&) = delete; - SingleDocParser& operator=(SingleDocParser&&) = delete; - ~SingleDocParser(); - - void HandleDocument(EventHandler& eventHandler); - - private: - void HandleNode(EventHandler& eventHandler); - - void HandleSequence(EventHandler& eventHandler); - void HandleBlockSequence(EventHandler& eventHandler); - void HandleFlowSequence(EventHandler& eventHandler); - - void HandleMap(EventHandler& eventHandler); - void HandleBlockMap(EventHandler& eventHandler); - void HandleFlowMap(EventHandler& eventHandler); - void HandleCompactMap(EventHandler& eventHandler); - void HandleCompactMapWithNoKey(EventHandler& eventHandler); - - void ParseProperties(std::string& tag, anchor_t& anchor, - std::string& anchor_name); - void ParseTag(std::string& tag); - void ParseAnchor(anchor_t& anchor, std::string& anchor_name); - - anchor_t RegisterAnchor(const std::string& name); - anchor_t LookupAnchor(const Mark& mark, const std::string& name) const; - - private: - int depth = 0; - Scanner& m_scanner; - const Directives& m_directives; - std::unique_ptr m_pCollectionStack; - - using Anchors = std::map; - Anchors m_anchors; - - anchor_t m_curAnchor; -}; -} // namespace YAML - -#endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/stream.cpp b/third/yaml-cpp/src/stream.cpp deleted file mode 100644 index b1aa092f..00000000 --- a/third/yaml-cpp/src/stream.cpp +++ /dev/null @@ -1,446 +0,0 @@ -#include - -#include "stream.h" - -#ifndef YAML_PREFETCH_SIZE -#define YAML_PREFETCH_SIZE 2048 -#endif - -#define S_ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A))) -#define S_ARRAY_END(A) ((A) + S_ARRAY_SIZE(A)) - -#define CP_REPLACEMENT_CHARACTER (0xFFFD) - -namespace YAML { -enum UtfIntroState { - uis_start, - uis_utfbe_b1, - uis_utf32be_b2, - uis_utf32be_bom3, - uis_utf32be, - uis_utf16be, - uis_utf16be_bom1, - uis_utfle_bom1, - uis_utf16le_bom2, - uis_utf32le_bom3, - uis_utf16le, - uis_utf32le, - uis_utf8_imp, - uis_utf16le_imp, - uis_utf32le_imp3, - uis_utf8_bom1, - uis_utf8_bom2, - uis_utf8, - uis_error -}; - -enum UtfIntroCharType { - uict00, - uictBB, - uictBF, - uictEF, - uictFE, - uictFF, - uictAscii, - uictOther, - uictMax -}; - -static bool s_introFinalState[] = { - false, // uis_start - false, // uis_utfbe_b1 - false, // uis_utf32be_b2 - false, // uis_utf32be_bom3 - true, // uis_utf32be - true, // uis_utf16be - false, // uis_utf16be_bom1 - false, // uis_utfle_bom1 - false, // uis_utf16le_bom2 - false, // uis_utf32le_bom3 - true, // uis_utf16le - true, // uis_utf32le - false, // uis_utf8_imp - false, // uis_utf16le_imp - false, // uis_utf32le_imp3 - false, // uis_utf8_bom1 - false, // uis_utf8_bom2 - true, // uis_utf8 - true, // uis_error -}; - -static UtfIntroState s_introTransitions[][uictMax] = { - // uict00, uictBB, uictBF, uictEF, - // uictFE, uictFF, uictAscii, uictOther - {uis_utfbe_b1, uis_utf8, uis_utf8, uis_utf8_bom1, uis_utf16be_bom1, - uis_utfle_bom1, uis_utf8_imp, uis_utf8}, - {uis_utf32be_b2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf16be, uis_utf8}, - {uis_utf32be, uis_utf8, uis_utf8, uis_utf8, uis_utf32be_bom3, uis_utf8, - uis_utf8, uis_utf8}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf32be, uis_utf8, - uis_utf8}, - {uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, - uis_utf32be, uis_utf32be, uis_utf32be}, - {uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, - uis_utf16be, uis_utf16be, uis_utf16be}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8, - uis_utf8}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16le_bom2, uis_utf8, - uis_utf8, uis_utf8}, - {uis_utf32le_bom3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, - uis_utf32le, uis_utf32le, uis_utf32le}, - {uis_utf16le_imp, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf8, uis_utf8}, - {uis_utf32le_imp3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf8, uis_utf8_bom2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf8}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf8}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf8}, -}; - -static char s_introUngetCount[][uictMax] = { - // uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther - {0, 1, 1, 0, 0, 0, 0, 1}, {0, 2, 2, 2, 2, 2, 2, 2}, - {3, 3, 3, 3, 0, 3, 3, 3}, {4, 4, 4, 4, 4, 0, 4, 4}, - {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, - {2, 2, 2, 2, 2, 0, 2, 2}, {2, 2, 2, 2, 0, 2, 2, 2}, - {0, 1, 1, 1, 1, 1, 1, 1}, {0, 2, 2, 2, 2, 2, 2, 2}, - {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, - {0, 2, 2, 2, 2, 2, 2, 2}, {0, 3, 3, 3, 3, 3, 3, 3}, - {4, 4, 4, 4, 4, 4, 4, 4}, {2, 0, 2, 2, 2, 2, 2, 2}, - {3, 3, 0, 3, 3, 3, 3, 3}, {1, 1, 1, 1, 1, 1, 1, 1}, -}; - -inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) { - if (std::istream::traits_type::eof() == ch) { - return uictOther; - } - - switch (ch) { - case 0: - return uict00; - case 0xBB: - return uictBB; - case 0xBF: - return uictBF; - case 0xEF: - return uictEF; - case 0xFE: - return uictFE; - case 0xFF: - return uictFF; - } - - if ((ch > 0) && (ch < 0xFF)) { - return uictAscii; - } - - return uictOther; -} - -inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits, - unsigned char rshift) { - const unsigned char header = - static_cast(((1 << lead_bits) - 1) << (8 - lead_bits)); - const unsigned char mask = (0xFF >> (lead_bits + 1)); - return static_cast( - static_cast(header | ((ch >> rshift) & mask))); -} - -inline void QueueUnicodeCodepoint(std::deque& q, unsigned long ch) { - // We are not allowed to queue the Stream::eof() codepoint, so - // replace it with CP_REPLACEMENT_CHARACTER - if (static_cast(Stream::eof()) == ch) { - ch = CP_REPLACEMENT_CHARACTER; - } - - if (ch < 0x80) { - q.push_back(Utf8Adjust(ch, 0, 0)); - } else if (ch < 0x800) { - q.push_back(Utf8Adjust(ch, 2, 6)); - q.push_back(Utf8Adjust(ch, 1, 0)); - } else if (ch < 0x10000) { - q.push_back(Utf8Adjust(ch, 3, 12)); - q.push_back(Utf8Adjust(ch, 1, 6)); - q.push_back(Utf8Adjust(ch, 1, 0)); - } else { - q.push_back(Utf8Adjust(ch, 4, 18)); - q.push_back(Utf8Adjust(ch, 1, 12)); - q.push_back(Utf8Adjust(ch, 1, 6)); - q.push_back(Utf8Adjust(ch, 1, 0)); - } -} - -Stream::Stream(std::istream& input) - : m_input(input), - m_mark{}, - m_charSet{}, - m_readahead{}, - m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]), - m_nPrefetchedAvailable(0), - m_nPrefetchedUsed(0) { - using char_traits = std::istream::traits_type; - - if (!input) - return; - - // Determine (or guess) the character-set by reading the BOM, if any. See - // the YAML specification for the determination algorithm. - char_traits::int_type intro[4]{}; - int nIntroUsed = 0; - UtfIntroState state = uis_start; - for (; !s_introFinalState[state];) { - std::istream::int_type ch = input.get(); - intro[nIntroUsed++] = ch; - UtfIntroCharType charType = IntroCharTypeOf(ch); - UtfIntroState newState = s_introTransitions[state][charType]; - int nUngets = s_introUngetCount[state][charType]; - if (nUngets > 0) { - input.clear(); - for (; nUngets > 0; --nUngets) { - if (char_traits::eof() != intro[--nIntroUsed]) - input.putback(char_traits::to_char_type(intro[nIntroUsed])); - } - } - state = newState; - } - - switch (state) { - case uis_utf8: - m_charSet = utf8; - break; - case uis_utf16le: - m_charSet = utf16le; - break; - case uis_utf16be: - m_charSet = utf16be; - break; - case uis_utf32le: - m_charSet = utf32le; - break; - case uis_utf32be: - m_charSet = utf32be; - break; - default: - m_charSet = utf8; - break; - } - - ReadAheadTo(0); -} - -Stream::~Stream() { delete[] m_pPrefetched; } - -char Stream::peek() const { - if (m_readahead.empty()) { - return Stream::eof(); - } - - return m_readahead[0]; -} - -Stream::operator bool() const { - return m_input.good() || - (!m_readahead.empty() && m_readahead[0] != Stream::eof()); -} - -// get -// . Extracts a character from the stream and updates our position -char Stream::get() { - char ch = peek(); - AdvanceCurrent(); - m_mark.column++; - - if (ch == '\n') { - m_mark.column = 0; - m_mark.line++; - } - - return ch; -} - -// get -// . Extracts 'n' characters from the stream and updates our position -std::string Stream::get(int n) { - std::string ret; - if (n > 0) { - ret.reserve(static_cast(n)); - for (int i = 0; i < n; i++) - ret += get(); - } - return ret; -} - -// eat -// . Eats 'n' characters and updates our position. -void Stream::eat(int n) { - for (int i = 0; i < n; i++) - get(); -} - -void Stream::AdvanceCurrent() { - if (!m_readahead.empty()) { - m_readahead.pop_front(); - m_mark.pos++; - } - - ReadAheadTo(0); -} - -bool Stream::_ReadAheadTo(size_t i) const { - while (m_input.good() && (m_readahead.size() <= i)) { - switch (m_charSet) { - case utf8: - StreamInUtf8(); - break; - case utf16le: - StreamInUtf16(); - break; - case utf16be: - StreamInUtf16(); - break; - case utf32le: - StreamInUtf32(); - break; - case utf32be: - StreamInUtf32(); - break; - } - } - - // signal end of stream - if (!m_input.good()) - m_readahead.push_back(Stream::eof()); - - return m_readahead.size() > i; -} - -void Stream::StreamInUtf8() const { - unsigned char b = GetNextByte(); - if (m_input.good()) { - m_readahead.push_back(static_cast(b)); - } -} - -void Stream::StreamInUtf16() const { - unsigned long ch = 0; - unsigned char bytes[2]; - int nBigEnd = (m_charSet == utf16be) ? 0 : 1; - - bytes[0] = GetNextByte(); - bytes[1] = GetNextByte(); - if (!m_input.good()) { - return; - } - ch = (static_cast(bytes[nBigEnd]) << 8) | - static_cast(bytes[1 ^ nBigEnd]); - - if (ch >= 0xDC00 && ch < 0xE000) { - // Trailing (low) surrogate...ugh, wrong order - QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); - return; - } - - if (ch >= 0xD800 && ch < 0xDC00) { - // ch is a leading (high) surrogate - - // Four byte UTF-8 code point - - // Read the trailing (low) surrogate - for (;;) { - bytes[0] = GetNextByte(); - bytes[1] = GetNextByte(); - if (!m_input.good()) { - QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); - return; - } - unsigned long chLow = (static_cast(bytes[nBigEnd]) << 8) | - static_cast(bytes[1 ^ nBigEnd]); - if (chLow < 0xDC00 || chLow >= 0xE000) { - // Trouble...not a low surrogate. Dump a REPLACEMENT CHARACTER into the - // stream. - QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); - - // Deal with the next UTF-16 unit - if (chLow < 0xD800 || chLow >= 0xE000) { - // Easiest case: queue the codepoint and return - QueueUnicodeCodepoint(m_readahead, ch); - return; - } - // Start the loop over with the new high surrogate - ch = chLow; - continue; - } - - // Select the payload bits from the high surrogate - ch &= 0x3FF; - ch <<= 10; - - // Include bits from low surrogate - ch |= (chLow & 0x3FF); - - // Add the surrogacy offset - ch += 0x10000; - break; - } - } - - QueueUnicodeCodepoint(m_readahead, ch); -} - -inline char* ReadBuffer(unsigned char* pBuffer) { - return reinterpret_cast(pBuffer); -} - -unsigned char Stream::GetNextByte() const { - if (m_nPrefetchedUsed >= m_nPrefetchedAvailable) { - std::streambuf* pBuf = m_input.rdbuf(); - m_nPrefetchedAvailable = static_cast( - pBuf->sgetn(ReadBuffer(m_pPrefetched), YAML_PREFETCH_SIZE)); - m_nPrefetchedUsed = 0; - if (!m_nPrefetchedAvailable) { - m_input.setstate(std::ios_base::eofbit); - } - - if (0 == m_nPrefetchedAvailable) { - return 0; - } - } - - return m_pPrefetched[m_nPrefetchedUsed++]; -} - -void Stream::StreamInUtf32() const { - static int indexes[2][4] = {{3, 2, 1, 0}, {0, 1, 2, 3}}; - - unsigned long ch = 0; - unsigned char bytes[4]; - int* pIndexes = (m_charSet == utf32be) ? indexes[1] : indexes[0]; - - bytes[0] = GetNextByte(); - bytes[1] = GetNextByte(); - bytes[2] = GetNextByte(); - bytes[3] = GetNextByte(); - if (!m_input.good()) { - return; - } - - for (int i = 0; i < 4; ++i) { - ch <<= 8; - ch |= bytes[pIndexes[i]]; - } - - QueueUnicodeCodepoint(m_readahead, ch); -} -} // namespace YAML diff --git a/third/yaml-cpp/src/stream.h b/third/yaml-cpp/src/stream.h deleted file mode 100644 index 2bc7a152..00000000 --- a/third/yaml-cpp/src/stream.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/mark.h" -#include -#include -#include -#include -#include -#include - -namespace YAML { - -class StreamCharSource; - -class Stream { - public: - friend class StreamCharSource; - - Stream(std::istream& input); - Stream(const Stream&) = delete; - Stream(Stream&&) = delete; - Stream& operator=(const Stream&) = delete; - Stream& operator=(Stream&&) = delete; - ~Stream(); - - operator bool() const; - bool operator!() const { return !static_cast(*this); } - - char peek() const; - char get(); - std::string get(int n); - void eat(int n = 1); - - static char eof() { return 0x04; } - - const Mark mark() const { return m_mark; } - int pos() const { return m_mark.pos; } - int line() const { return m_mark.line; } - int column() const { return m_mark.column; } - void ResetColumn() { m_mark.column = 0; } - - private: - enum CharacterSet { utf8, utf16le, utf16be, utf32le, utf32be }; - - std::istream& m_input; - Mark m_mark; - - CharacterSet m_charSet; - mutable std::deque m_readahead; - unsigned char* const m_pPrefetched; - mutable size_t m_nPrefetchedAvailable; - mutable size_t m_nPrefetchedUsed; - - void AdvanceCurrent(); - char CharAt(size_t i) const; - bool ReadAheadTo(size_t i) const; - bool _ReadAheadTo(size_t i) const; - void StreamInUtf8() const; - void StreamInUtf16() const; - void StreamInUtf32() const; - unsigned char GetNextByte() const; -}; - -// CharAt -// . Unchecked access -inline char Stream::CharAt(size_t i) const { return m_readahead[i]; } - -inline bool Stream::ReadAheadTo(size_t i) const { - if (m_readahead.size() > i) - return true; - return _ReadAheadTo(i); -} -} // namespace YAML - -#endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/streamcharsource.h b/third/yaml-cpp/src/streamcharsource.h deleted file mode 100644 index 826ba534..00000000 --- a/third/yaml-cpp/src/streamcharsource.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/noexcept.h" -#include "stream.h" -#include - -namespace YAML { - -class StreamCharSource { - public: - StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {} - StreamCharSource(const StreamCharSource& source) = default; - StreamCharSource(StreamCharSource&&) YAML_CPP_NOEXCEPT = default; - StreamCharSource& operator=(const StreamCharSource&) = delete; - StreamCharSource& operator=(StreamCharSource&&) = delete; - ~StreamCharSource() = default; - - operator bool() const; - char operator[](std::size_t i) const { return m_stream.CharAt(m_offset + i); } - bool operator!() const { return !static_cast(*this); } - - const StreamCharSource operator+(int i) const; - - private: - std::size_t m_offset; - const Stream& m_stream; -}; - -inline StreamCharSource::operator bool() const { - return m_stream.ReadAheadTo(m_offset); -} - -inline const StreamCharSource StreamCharSource::operator+(int i) const { - StreamCharSource source(*this); - if (static_cast(source.m_offset) + i >= 0) - source.m_offset += static_cast(i); - else - source.m_offset = 0; - return source; -} -} // namespace YAML - -#endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/stringsource.h b/third/yaml-cpp/src/stringsource.h deleted file mode 100644 index 6fee44bb..00000000 --- a/third/yaml-cpp/src/stringsource.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -namespace YAML { -class StringCharSource { - public: - StringCharSource(const char* str, std::size_t size) - : m_str(str), m_size(size), m_offset(0) {} - - operator bool() const { return m_offset < m_size; } - char operator[](std::size_t i) const { return m_str[m_offset + i]; } - bool operator!() const { return !static_cast(*this); } - - const StringCharSource operator+(int i) const { - StringCharSource source(*this); - if (static_cast(source.m_offset) + i >= 0) - source.m_offset += i; - else - source.m_offset = 0; - return source; - } - - StringCharSource& operator++() { - ++m_offset; - return *this; - } - - StringCharSource& operator+=(std::size_t offset) { - m_offset += offset; - return *this; - } - - private: - const char* m_str; - std::size_t m_size; - std::size_t m_offset; -}; -} - -#endif // STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/tag.cpp b/third/yaml-cpp/src/tag.cpp deleted file mode 100644 index 35a1b465..00000000 --- a/third/yaml-cpp/src/tag.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include - -#include "directives.h" // IWYU pragma: keep -#include "tag.h" -#include "token.h" - -namespace YAML { -Tag::Tag(const Token& token) - : type(static_cast(token.data)), handle{}, value{} { - switch (type) { - case VERBATIM: - value = token.value; - break; - case PRIMARY_HANDLE: - value = token.value; - break; - case SECONDARY_HANDLE: - value = token.value; - break; - case NAMED_HANDLE: - handle = token.value; - value = token.params[0]; - break; - case NON_SPECIFIC: - break; - default: - assert(false); - } -} - -std::string Tag::Translate(const Directives& directives) { - switch (type) { - case VERBATIM: - return value; - case PRIMARY_HANDLE: - return directives.TranslateTagHandle("!") + value; - case SECONDARY_HANDLE: - return directives.TranslateTagHandle("!!") + value; - case NAMED_HANDLE: - return directives.TranslateTagHandle("!" + handle + "!") + value; - case NON_SPECIFIC: - // TODO: - return "!"; - default: - assert(false); - } - throw std::runtime_error("yaml-cpp: internal error, bad tag type"); -} -} // namespace YAML diff --git a/third/yaml-cpp/src/tag.h b/third/yaml-cpp/src/tag.h deleted file mode 100644 index c811f395..00000000 --- a/third/yaml-cpp/src/tag.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -namespace YAML { -struct Directives; -struct Token; - -struct Tag { - enum TYPE { - VERBATIM, - PRIMARY_HANDLE, - SECONDARY_HANDLE, - NAMED_HANDLE, - NON_SPECIFIC - }; - - Tag(const Token& token); - std::string Translate(const Directives& directives); - - TYPE type; - std::string handle, value; -}; -} - -#endif // TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/src/token.h b/third/yaml-cpp/src/token.h deleted file mode 100644 index 9c9a5b77..00000000 --- a/third/yaml-cpp/src/token.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/mark.h" -#include -#include -#include - -namespace YAML { -const std::string TokenNames[] = { - "DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START", - "BLOCK_MAP_START", "BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY", - "FLOW_SEQ_START", "FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END", - "FLOW_MAP_COMPACT", "FLOW_ENTRY", "KEY", "VALUE", - "ANCHOR", "ALIAS", "TAG", "SCALAR"}; - -struct Token { - // enums - enum STATUS { VALID, INVALID, UNVERIFIED }; - enum TYPE { - DIRECTIVE, - DOC_START, - DOC_END, - BLOCK_SEQ_START, - BLOCK_MAP_START, - BLOCK_SEQ_END, - BLOCK_MAP_END, - BLOCK_ENTRY, - FLOW_SEQ_START, - FLOW_MAP_START, - FLOW_SEQ_END, - FLOW_MAP_END, - FLOW_MAP_COMPACT, - FLOW_ENTRY, - KEY, - VALUE, - ANCHOR, - ALIAS, - TAG, - PLAIN_SCALAR, - NON_PLAIN_SCALAR - }; - - // data - Token(TYPE type_, const Mark& mark_) - : status(VALID), type(type_), mark(mark_), value{}, params{}, data(0) {} - - friend std::ostream& operator<<(std::ostream& out, const Token& token) { - out << TokenNames[token.type] << std::string(": ") << token.value; - for (const std::string& param : token.params) - out << std::string(" ") << param; - return out; - } - - STATUS status; - TYPE type; - Mark mark; - std::string value; - std::vector params; - int data; -}; -} // namespace YAML - -#endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/third/yaml-cpp/util/CMakeLists.txt b/third/yaml-cpp/util/CMakeLists.txt deleted file mode 100644 index 87ea4f91..00000000 --- a/third/yaml-cpp/util/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -add_executable(yaml-cpp-sandbox sandbox.cpp) -add_executable(yaml-cpp-parse parse.cpp) -add_executable(yaml-cpp-read read.cpp) - -target_link_libraries(yaml-cpp-sandbox PRIVATE yaml-cpp) -target_link_libraries(yaml-cpp-parse PRIVATE yaml-cpp) -target_link_libraries(yaml-cpp-read PRIVATE yaml-cpp) - -set_property(TARGET yaml-cpp-sandbox PROPERTY OUTPUT_NAME sandbox) -set_property(TARGET yaml-cpp-parse PROPERTY OUTPUT_NAME parse) -set_property(TARGET yaml-cpp-read PROPERTY OUTPUT_NAME read) - -set_target_properties(yaml-cpp-sandbox - PROPERTIES - CXX_STANDARD_REQUIRED ON - OUTPUT_NAME sandbox) - -set_target_properties(yaml-cpp-parse - PROPERTIES - CXX_STANDARD_REQUIRED ON - OUTPUT_NAME parse) - -set_target_properties(yaml-cpp-read - PROPERTIES - CXX_STANDARD_REQUIRED ON - OUTPUT_NAME read) - -if (NOT DEFINED CMAKE_CXX_STANDARD) - set_target_properties(yaml-cpp-sandbox yaml-cpp-parse yaml-cpp-read - PROPERTIES - CXX_STANDARD 11) -endif() diff --git a/third/yaml-cpp/util/api.cpp b/third/yaml-cpp/util/api.cpp deleted file mode 100644 index 8ae5ff29..00000000 --- a/third/yaml-cpp/util/api.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// a sketch of what the new API might look like - -#include "yaml-cpp/yaml.h" -#include - -int main() { - { - // test.yaml - // - foo - // - primes: [2, 3, 5, 7, 11] - // odds: [1, 3, 5, 7, 9, 11] - // - [x, y] - - // move-like semantics - YAML::Value root = YAML::Parse("test.yaml"); - - std::cout << root[0].as(); // "foo" - std::cout << str(root[0]); // "foo", shorthand? - std::cout << root[1]["primes"][3].as(); // "7" - std::cout << root[1]["odds"][6].as(); // throws? - - root[2].push_back(5); - root[3] = "Hello, World"; - root[0].reset(); - root[0]["key"] = "value"; - - std::cout << root; - // # not sure about formatting - // - {key: value} - // - primes: [2, 3, 5, 7, 11] - // odds: [1, 3, 5, 7, 9, 11] - // - [x, y, 5] - // - Hello, World - } - - { - // for all copy-like commands, think of python's "name/value" semantics - YAML::Value root = "Hello"; // Hello - root = YAML::Sequence(); // [] - root[0] = 0; // [0] - root[2] = "two"; // [0, ~, two] # forces root[1] to be initialized to null - - YAML::Value other = root; // both point to the same thing - other[0] = 5; // now root[0] is 0 also - other.push_back(root); // &1 [5, ~, two, *1] - other[3][0] = 0; // &1 [0, ~, two, *1] # since it's a true alias - other.push_back(Copy(root)); // &1 [0, ~, two, *1, &2 [0, ~, two, *2]] - other[4][0] = 5; // &1 [0, ~, two, *1, &2 [5, ~, two, *2]] # they're - // really different - } - - { - YAML::Value node; // ~ - node[0] = 1; // [1] # auto-construct a sequence - node["key"] = 5; // {0: 1, key: 5} # auto-turn it into a map - node.push_back(10); // error, can't turn a map into a sequence - node.erase("key"); // {0: 1} # still a map, even if we remove the key that - // caused the problem - node = "Hello"; // Hello # assignment overwrites everything, so it's now - // just a plain scalar - } - - { - YAML::Value map; // ~ - map[3] = 1; // {3: 1} # auto-constructs a map, *not* a sequence - - YAML::Value seq; // ~ - seq = YAML::Sequence(); // [] - seq[3] = 1; // [~, ~, ~, 1] - } - - { - YAML::Value node; // ~ - node[0] = node; // &1 [*1] # fun stuff - } - - { - YAML::Value node; - YAML::Value subnode = - node["key"]; // 'subnode' is not instantiated ('node' is still null) - subnode = "value"; // {key: value} # now it is - YAML::Value subnode2 = node["key2"]; - node["key3"] = subnode2; // subnode2 is still not instantiated, but - // node["key3"] is "pseudo" aliased to it - subnode2 = "monkey"; // {key: value, key2: &1 monkey, key3: *1} # bam! it - // instantiates both - } - - { - YAML::Value seq = YAML::Sequence(); - seq[0] = "zero"; // [zero] - seq[1] = seq[0]; // [&1 zero, *1] - seq[0] = seq[1]; // [&1 zero, *1] # no-op (they both alias the same thing, - // so setting them equal is nothing) - Is(seq[0], seq[1]); // true - seq[1] = "one"; // [&1 one, *1] - UnAlias(seq[1]); // [one, one] - Is(seq[0], seq[1]); // false - } - - { - YAML::Value root; - root.push_back("zero"); - root.push_back("one"); - root.push_back("two"); - YAML::Value two = root[2]; - root = "scalar"; // 'two' is still "two", even though 'root' is "scalar" - // (the sequence effectively no longer exists) - - // Note: in all likelihood, the memory for nodes "zero" and "one" is still - // allocated. How can it go away? Weak pointers? - } - - { - YAML::Value root; // ~ - root[0] = root; // &1 [*1] - root[0] = 5; // [5] - } - - { - YAML::Value root; - YAML::Value key; - key["key"] = "value"; - root[key] = key; // &1 {key: value}: *1 - } - - { - YAML::Value root; - root[0] = "hi"; - root[1][0] = "bye"; - root[1][1] = root; // &1 [hi, [bye, *1]] # root - YAML::Value sub = root[1]; // &1 [bye, [hi, *1]] # sub - root = "gone"; // [bye, gone] # sub - } - - return 0; -} diff --git a/third/yaml-cpp/util/parse.cpp b/third/yaml-cpp/util/parse.cpp deleted file mode 100644 index ea4295a6..00000000 --- a/third/yaml-cpp/util/parse.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include - -#include "yaml-cpp/eventhandler.h" -#include "yaml-cpp/yaml.h" // IWYU pragma: keep - -class NullEventHandler : public YAML::EventHandler { - public: - void OnDocumentStart(const YAML::Mark&) override {} - void OnDocumentEnd() override {} - - void OnNull(const YAML::Mark&, YAML::anchor_t) override {} - void OnAlias(const YAML::Mark&, YAML::anchor_t) override {} - void OnScalar(const YAML::Mark&, const std::string&, YAML::anchor_t, - const std::string&) override {} - - void OnSequenceStart(const YAML::Mark&, const std::string&, YAML::anchor_t, - YAML::EmitterStyle::value) override {} - void OnSequenceEnd() override {} - - void OnMapStart(const YAML::Mark&, const std::string&, YAML::anchor_t, - YAML::EmitterStyle::value) override {} - void OnMapEnd() override {} -}; - -void parse(std::istream& input) { - try { - YAML::Node doc = YAML::Load(input); - std::cout << doc << "\n"; - } catch (const YAML::Exception& e) { - std::cerr << e.what() << "\n"; - } -} - -int main(int argc, char** argv) { - if (argc > 1) { - std::ifstream fin; - fin.open(argv[1]); - parse(fin); - } else { - parse(std::cin); - } - - return 0; -} diff --git a/third/yaml-cpp/util/read.cpp b/third/yaml-cpp/util/read.cpp deleted file mode 100644 index 3455ea3c..00000000 --- a/third/yaml-cpp/util/read.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" -#include "yaml-cpp/yaml.h" // IWYU pragma: keep - -#include -#include -#include - -class NullEventHandler : public YAML::EventHandler { - public: - using Mark = YAML::Mark; - using anchor_t = YAML::anchor_t; - - NullEventHandler() = default; - - void OnDocumentStart(const Mark&) override {} - void OnDocumentEnd() override {} - void OnNull(const Mark&, anchor_t) override {} - void OnAlias(const Mark&, anchor_t) override {} - void OnScalar(const Mark&, const std::string&, anchor_t, - const std::string&) override {} - void OnSequenceStart(const Mark&, const std::string&, anchor_t, - YAML::EmitterStyle::value style) override {} - void OnSequenceEnd() override {} - void OnMapStart(const Mark&, const std::string&, anchor_t, - YAML::EmitterStyle::value style) override {} - void OnMapEnd() override {} -}; - -void run(std::istream& in) { - YAML::Parser parser(in); - NullEventHandler handler; - parser.HandleNextDocument(handler); -} - -void usage() { std::cerr << "Usage: read [-n N] [-c, --cache] [filename]\n"; } - -std::string read_stream(std::istream& in) { - return std::string((std::istreambuf_iterator(in)), - std::istreambuf_iterator()); -} - -int main(int argc, char** argv) { - int N = 1; - bool cache = false; - std::string filename; - for (int i = 1; i < argc; i++) { - std::string arg = argv[i]; - if (arg == "-n") { - i++; - if (i >= argc) { - usage(); - return -1; - } - N = std::atoi(argv[i]); - if (N <= 0) { - usage(); - return -1; - } - } else if (arg == "-c" || arg == "--cache") { - cache = true; - } else { - filename = argv[i]; - if (i + 1 != argc) { - usage(); - return -1; - } - } - } - - if (N > 1 && !cache && filename.empty()) { - usage(); - return -1; - } - - if (cache) { - std::string input; - if (!filename.empty()) { - std::ifstream in(filename); - input = read_stream(in); - } else { - input = read_stream(std::cin); - } - std::istringstream in(input); - for (int i = 0; i < N; i++) { - in.seekg(std::ios_base::beg); - run(in); - } - } else { - if (!filename.empty()) { - std::ifstream in(filename); - for (int i = 0; i < N; i++) { - in.seekg(std::ios_base::beg); - run(in); - } - } else { - for (int i = 0; i < N; i++) { - run(std::cin); - } - } - } - return 0; -} diff --git a/third/yaml-cpp/util/sandbox.cpp b/third/yaml-cpp/util/sandbox.cpp deleted file mode 100644 index f21490e7..00000000 --- a/third/yaml-cpp/util/sandbox.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include - -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" -#include "yaml-cpp/yaml.h" // IWYU pragma: keep - -class NullEventHandler : public YAML::EventHandler { - public: - using Mark = YAML::Mark; - using anchor_t = YAML::anchor_t; - - NullEventHandler() = default; - - void OnDocumentStart(const Mark&) override {} - void OnDocumentEnd() override {} - void OnNull(const Mark&, anchor_t) override {} - void OnAlias(const Mark&, anchor_t) override {} - void OnScalar(const Mark&, const std::string&, anchor_t, - const std::string&) override {} - void OnSequenceStart(const Mark&, const std::string&, anchor_t, - YAML::EmitterStyle::value style) override {} - void OnSequenceEnd() override {} - void OnMapStart(const Mark&, const std::string&, anchor_t, - YAML::EmitterStyle::value style) override {} - void OnMapEnd() override {} -}; - -int main() { - YAML::Node root; - - for (;;) { - YAML::Node node; - root = node; - } - return 0; -} diff --git a/third/yaml-cpp/yaml-cpp-config-version.cmake b/third/yaml-cpp/yaml-cpp-config-version.cmake deleted file mode 100644 index e5534e63..00000000 --- a/third/yaml-cpp/yaml-cpp-config-version.cmake +++ /dev/null @@ -1,37 +0,0 @@ -# This is a basic version file for the Config-mode of find_package(). -# It is used by write_basic_package_version_file() as input file for configure_file() -# to create a version-file which can be installed along a config.cmake file. -# -# The created file sets PACKAGE_VERSION_EXACT if the current version string and -# the requested version string are exactly the same and it sets -# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version. -# The variable CVF_VERSION must be set before calling configure_file(). - -set(PACKAGE_VERSION "0.8.0") - -if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) - set(PACKAGE_VERSION_COMPATIBLE FALSE) -else() - set(PACKAGE_VERSION_COMPATIBLE TRUE) - if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) - set(PACKAGE_VERSION_EXACT TRUE) - endif() -endif() - - -# if the installed project requested no architecture check, don't perform the check -if("FALSE") - return() -endif() - -# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") - return() -endif() - -# check that the installed version has the same 32/64bit-ness as the one which is currently searching: -if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") - math(EXPR installedBits "8 * 8") - set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif() diff --git a/third/yaml-cpp/yaml-cpp-config.cmake b/third/yaml-cpp/yaml-cpp-config.cmake deleted file mode 100644 index 1574e533..00000000 --- a/third/yaml-cpp/yaml-cpp-config.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# - Config file for the yaml-cpp package -# It defines the following variables -# YAML_CPP_INCLUDE_DIR - include directory -# YAML_CPP_LIBRARY_DIR - directory containing libraries -# YAML_CPP_SHARED_LIBS_BUILT - whether we have built shared libraries or not -# YAML_CPP_LIBRARIES - libraries to link against - - -####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### -####### Any changes to this file will be overwritten by the next CMake run #### -####### The input file was yaml-cpp-config.cmake.in ######## - -get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) - -macro(set_and_check _var _file) - set(${_var} "${_file}") - if(NOT EXISTS "${_file}") - message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") - endif() -endmacro() - -macro(check_required_components _NAME) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(NOT ${_NAME}_${comp}_FOUND) - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - endif() - endif() - endforeach() -endmacro() - -#################################################################################### - -set_and_check(YAML_CPP_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include") -set_and_check(YAML_CPP_LIBRARY_DIR "${PACKAGE_PREFIX_DIR}/lib") - -# Are we building shared libraries? -set(YAML_CPP_SHARED_LIBS_BUILT "${PACKAGE_PREFIX_DIR}/OFF") - -# Our library dependencies (contains definitions for IMPORTED targets) -include(${PACKAGE_PREFIX_DIR}/lib/cmake/yaml-cpp/yaml-cpp-targets.cmake) - -# These are IMPORTED targets created by yaml-cpp-targets.cmake -set(YAML_CPP_LIBRARIES "yaml-cpp") - -check_required_components(yaml-cpp) diff --git a/third/yaml-cpp/yaml-cpp-config.cmake.in b/third/yaml-cpp/yaml-cpp-config.cmake.in deleted file mode 100644 index 799b9b41..00000000 --- a/third/yaml-cpp/yaml-cpp-config.cmake.in +++ /dev/null @@ -1,22 +0,0 @@ -# - Config file for the yaml-cpp package -# It defines the following variables -# YAML_CPP_INCLUDE_DIR - include directory -# YAML_CPP_LIBRARY_DIR - directory containing libraries -# YAML_CPP_SHARED_LIBS_BUILT - whether we have built shared libraries or not -# YAML_CPP_LIBRARIES - libraries to link against - -@PACKAGE_INIT@ - -set_and_check(YAML_CPP_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") -set_and_check(YAML_CPP_LIBRARY_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@") - -# Are we building shared libraries? -set(YAML_CPP_SHARED_LIBS_BUILT "@PACKAGE_YAML_BUILD_SHARED_LIBS@") - -# Our library dependencies (contains definitions for IMPORTED targets) -include(@PACKAGE_CONFIG_EXPORT_DIR@/yaml-cpp-targets.cmake) - -# These are IMPORTED targets created by yaml-cpp-targets.cmake -set(YAML_CPP_LIBRARIES "@EXPORT_TARGETS@") - -check_required_components(@EXPORT_TARGETS@) diff --git a/third/yaml-cpp/yaml-cpp.pc b/third/yaml-cpp/yaml-cpp.pc deleted file mode 100644 index 6566e41a..00000000 --- a/third/yaml-cpp/yaml-cpp.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -includedir=/usr/local/include -libdir=/usr/local/lib - -Name: Yaml-cpp -Description: A YAML parser and emitter for C++ -Version: 0.8.0 -Requires: -Libs: -L${libdir} -lyaml-cpp -Cflags: -I${includedir} diff --git a/third/yaml-cpp/yaml-cpp.pc.in b/third/yaml-cpp/yaml-cpp.pc.in deleted file mode 100644 index d02dc9e5..00000000 --- a/third/yaml-cpp/yaml-cpp.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=${prefix} -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ - -Name: Yaml-cpp -Description: A YAML parser and emitter for C++ -Version: @YAML_CPP_VERSION@ -Requires: -Libs: -L${libdir} -lyaml-cpp -Cflags: -I${includedir}