diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b634d85 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.pdf filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index c18856a..07ba12f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,8 @@ pkg !.idea/codeStyles/ !.idea/runConfigurations/ !.idea/inspectionProfiles/ -*.iml \ No newline at end of file +*.iml + +.cache/ +compile_commands.json +*.db \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..fd8e2ba --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "modules/cpp-libraries"] + path = modules/cpp-libraries + url = ssh://git@192.168.1.101:2222/lukas/cpp-libraries.git diff --git a/.vscode/launch.json b/.vscode/launch.json index ab59233..9b87958 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,10 +2,10 @@ "version": "0.2.0", "configurations": [ { - "name": "Debug Server Admin Panel", - "type": "cppdbg", + "name": "Debug Shadowrun Server", + "type": "lldb", "request": "launch", - "program": "${workspaceFolder}/build/lf-server-admin-panel", + "program": "${workspaceFolder}/build/shadowrun-server", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/.vscode/settings.json b/.vscode/settings.json index bc67769..30f2371 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -99,5 +99,6 @@ "typeinfo": "cpp", "valarray": "cpp", "variant": "cpp" - } + }, + "C_Cpp.errorSquiggles": "disabled" } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index b6b51cc..2c7326f 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -9,6 +9,23 @@ "problemMatcher": [ "$gcc" ] + }, + { + "label": "build release", + "type": "shell", + "command": "cmake -S . -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build", + "group": "build", + "problemMatcher": [ + "$gcc" + ] + }, + { + "label": "build Frontend", + "type": "shell", + "command": "npm run build", + "options": { + "cwd": "frontend" + } } ] } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b5b63f..d61b64f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ project(CrowHTMX) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(TARGET_NAME lf-server-admin-panel ) +set(TARGET_NAME shadowrun-server ) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -20,57 +20,41 @@ if(NOT CMAKE_BUILD_TYPE IN_LIST SUPPORTED_BUILD_TYPES) endif() # Copy 'static' and 'templates' directories to build directory -file(GLOB_RECURSE STATIC_FILES "${CMAKE_SOURCE_DIR}/static/*") -file(GLOB_RECURSE TEMPLATE_FILES "${CMAKE_SOURCE_DIR}/templates/*") +file(GLOB_RECURSE ASSETS_FILES "${CMAKE_SOURCE_DIR}/assets/*") +file(GLOB_RECURSE FRONTEND_FILES "${CMAKE_SOURCE_DIR}/frontend/build/*") foreach(file IN LISTS STATIC_FILES) file(RELATIVE_PATH rel_path "${CMAKE_SOURCE_DIR}" "${file}") configure_file("${file}" "${CMAKE_BINARY_DIR}/${rel_path}" COPYONLY) endforeach() -foreach(file IN LISTS TEMPLATE_FILES) +foreach(file IN LISTS FRONTEND_FILES) file(RELATIVE_PATH rel_path "${CMAKE_SOURCE_DIR}" "${file}") configure_file("${file}" "${CMAKE_BINARY_DIR}/${rel_path}" COPYONLY) endforeach() -add_compile_options(-Wno-deprecated-declarations) -add_compile_options(-Wno-deprecated-literal-operator) - -# Use Crow from system include (installed via yay -S crow + asio) -include_directories(/usr/include src src/htmx src/shadowrun src/database src/login) +include_directories( + modules/cpp-libraries/include/ + src + src/shadowrun + src/database + src/login +) add_executable(${TARGET_NAME} + modules/cpp-libraries/src/sqlite3.c + modules/cpp-libraries/src/monocypher.c + src/main.cpp src/utils.hpp src/utils.cpp - src/htmx/HtmxTable.cpp - src/htmx/HtmxTable.h - src/systemd.cpp - src/systemd.h - src/json.hpp - src/htmx/HtmxTableRow.cpp - src/htmx/HtmxTableRow.h - src/htmx/HtmxObject.cpp - src/htmx/HtmxObject.h - src/htmx_helper.cpp - src/htmx_helper.h src/json_settings.cpp src/json_settings.h - src/json.hpp src/database/database.cpp src/database/database.hpp - src/database/sqlite_orm.h # Shadowrun - src/shadowrun/HtmxShItemList.cpp - src/shadowrun/HtmxShItemList.hpp - src/shadowrun/HtmxShAttributeList.cpp - src/shadowrun/HtmxShAttributeList.hpp - src/shadowrun/HtmxShCondition.cpp - src/shadowrun/HtmxShCondition.hpp - src/shadowrun/ShadowrunCharacterForm.hpp - src/shadowrun/ShadowrunCharacterForm.cpp src/shadowrun/ShadowrunApi.cpp src/shadowrun/ShadowrunApi.hpp src/shadowrun/ShadowrunDb.cpp @@ -79,12 +63,36 @@ add_executable(${TARGET_NAME} # login src/login/login.cpp src/login/login.hpp - + src/login/loginDb.cpp + src/login/Session.cpp + src/login/SessionHandler.cpp ) -target_compile_definitions(${TARGET_NAME} PRIVATE APPLICATION_NAME="${TARGET_NAME}") +# warnings to ignore +target_compile_options(${TARGET_NAME} PRIVATE + $<$: + -Wno-deprecated-literal-operator + -Wno-deprecated-declarations + > +) -target_link_libraries(${TARGET_NAME} pthread sqlite3 sodium) +# relase compiler options +target_compile_options(${TARGET_NAME} PRIVATE + $<$:-O3> + $<$:-flto=auto> +) + +# relase linker options +target_link_options(${TARGET_NAME} PRIVATE + $<$:-flto=auto> +) + +target_compile_definitions(${TARGET_NAME} PRIVATE + APPLICATION_NAME="${TARGET_NAME}" + SQLITE_THREADSAFE=1 +) + +target_link_libraries(${TARGET_NAME} pthread) # Optional: Print build type at configuration time message(STATUS "Configuring build type: ${CMAKE_BUILD_TYPE}") \ No newline at end of file diff --git a/README.md b/README.md index 35bacd5..e15b326 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,19 @@ run : F5 or Run → Start Debugging cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ``` +## Svelte +Inside the fronend directory + +### Install +``` +npm install -D @sveltejs/adapter-static +``` + +### Build +``` +npm run build +``` + ## Make Package 1. tar the source files to make it cleaner @@ -26,4 +39,11 @@ tar czf pkg/lf-server-admin-panel-0.1.1.tar.gz src/ static/ templates/ lf-server ``` makepkg -f -``` \ No newline at end of file +``` + +## Database + +### Attributes +| Character Id | Attribute | Value | + +### \ No newline at end of file diff --git a/static/htmx.min.js b/assets/htmx.min.js similarity index 100% rename from static/htmx.min.js rename to assets/htmx.min.js diff --git a/assets/settings.json b/assets/settings.json new file mode 100644 index 0000000..6bb46b7 --- /dev/null +++ b/assets/settings.json @@ -0,0 +1,3 @@ +{ + "httpPort" : 3010 +} \ No newline at end of file diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-full.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-full.pdf new file mode 100644 index 0000000..f88c8b9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-full.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ab98fa86ff0cd70c1935ad6adf8c1de2c70ebe7152ee5310f17612e00cba533 +size 205125803 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p1.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p1.pdf new file mode 100644 index 0000000..fd58d91 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p1.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a63a179b3a10bdae68326b430c2281c7a4b06f6bd3bc085e367f8ef669df3cee +size 4571342 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p10.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p10.pdf new file mode 100644 index 0000000..415fd29 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p10.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ea90805cde97aa979818e4620481f12cfbb5596d38fd4bda16137fd960df67e +size 505721 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p100.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p100.pdf new file mode 100644 index 0000000..ea69e66 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p100.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e1f606e6b95dc28a99957f262b2de829143ef4902c0621853e6fa101d78e25b +size 3498702 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p101.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p101.pdf new file mode 100644 index 0000000..0354bbc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p101.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:430c9d4f601cd86b6e0ab677fbfa45d2a83df9b7c17db25a7a5dda49eae34ba8 +size 3852846 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p102.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p102.pdf new file mode 100644 index 0000000..eff25a5 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p102.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe5784c9250f416c5745d0c713cbe9dc2d3c125f8145884458ade8868eb0560d +size 4316611 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p103.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p103.pdf new file mode 100644 index 0000000..2897f15 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p103.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:383aac1245323e21fd622e4e1d4b93917e2632919240e8c62bde87c33230753f +size 3668137 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p104.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p104.pdf new file mode 100644 index 0000000..19843dd --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p104.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecf1435eef7df2b99d6ea1ece80185204e87d222a87f35c136fcc62fd4ac2944 +size 3685575 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p105.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p105.pdf new file mode 100644 index 0000000..4df4a35 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p105.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:907db31bb6918a1dea8d32ec68c2c914ce7e3101231bab8597cdc3d8dfe77000 +size 3727671 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p106.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p106.pdf new file mode 100644 index 0000000..badd126 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p106.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0cdb6a93a39f89f0375e1e931064d9cab8ddb76decfdfbe1c5e363c9eb06ac76 +size 3825420 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p107.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p107.pdf new file mode 100644 index 0000000..4f24148 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p107.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a9e2d76b090f65ad7f0fd3f26320b6aefd9478cee1620743b0d0b62a6f0a86a +size 1204552 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p108.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p108.pdf new file mode 100644 index 0000000..6f20c96 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p108.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7d95ec1006198e417480d0b5012f861a0cbe0721f90d231372c477a1ccbda5b +size 251958 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p109.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p109.pdf new file mode 100644 index 0000000..1f6c7a4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p109.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1c6f6758bbe92d52adb6518b0c0e3c013e5eeeb28b874cca7cbf02702e48015 +size 1789776 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p11.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p11.pdf new file mode 100644 index 0000000..2b94d24 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p11.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe6be919a0508261ffa20dc615f4f0e4e731d839bc242752517a7bc88306c975 +size 274391 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p110.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p110.pdf new file mode 100644 index 0000000..73f2c8d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p110.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38531643abbdc7cf9a0b2b80ea5024d2faa34cce7caf243fed42d0b475b6c2f1 +size 529746 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p111.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p111.pdf new file mode 100644 index 0000000..4ad4f25 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p111.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57e8a103431e87c0c72ffaf6b257428d1ecdd86effade2a44614b6d3323c52af +size 635613 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p112.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p112.pdf new file mode 100644 index 0000000..90a5d30 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p112.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1aaf3c633c680b48ff49df7aa6e00724da414670941a5c4025901be6976c28fc +size 474938 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p113.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p113.pdf new file mode 100644 index 0000000..25fa669 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p113.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0747372ab76aa89c7e3de69d28ddfa4f05a88db66533b378e6d98de2abae7969 +size 531493 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p114.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p114.pdf new file mode 100644 index 0000000..ae8b6fc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p114.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1018e696176ef59ec505cf56895357af2f40c134e8b8b684421e794cf6d34caa +size 500725 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p115.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p115.pdf new file mode 100644 index 0000000..4eca7b0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p115.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cc824ea1d29c4a27938429dd021321e286110307e515f14425db457799fde4f +size 247696 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p116.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p116.pdf new file mode 100644 index 0000000..6dcd7f3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p116.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36464825ed88f4d03537aa7d17771956ad0d3d8950c7b5cd5f8c03c81815dd38 +size 245856 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p117.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p117.pdf new file mode 100644 index 0000000..40bae7a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p117.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9254195b0e22f8145c62255459b9a1d6d8bc36da1c04b4c27ab940b8f74a1de8 +size 719632 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p118.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p118.pdf new file mode 100644 index 0000000..2c1b59b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p118.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d5b415ddae71d839bbd998fab8a65c0ae093709124ccf5fdc86d8941b258ffb +size 531734 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p119.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p119.pdf new file mode 100644 index 0000000..83d16ad --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p119.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8a826bc168ccaaab9f79b49a580579d5f468caaa9782ff32a5f35abd31e9495 +size 784537 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p12.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p12.pdf new file mode 100644 index 0000000..4acabb6 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p12.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c7c4556b8dad656ec20dc3488649a06db5489c2ad18a2bce1a456c53213ef84 +size 450103 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p120.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p120.pdf new file mode 100644 index 0000000..48f8b27 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p120.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fe2f4a1a6e72e6edca84b6a6f85a62061ec4aaf4b239774d12221306e39c3d9 +size 703163 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p121.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p121.pdf new file mode 100644 index 0000000..db9be91 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p121.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30a3c746f11fce37b3e1b8c69aa6ef17a1c4e345165370addccb1a2ff3f62113 +size 514073 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p122.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p122.pdf new file mode 100644 index 0000000..ee4c487 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p122.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92c45ed6b1e32c7fd2bbe185935bedb18e377e2f0fd1eb3f23add7617e1a30d4 +size 248689 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p123.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p123.pdf new file mode 100644 index 0000000..7eca24a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p123.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a50a4e085fefea483ddfb7d1b11e8eaa20e5c1f1285500a19afc36fd0186c3b9 +size 962068 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p124.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p124.pdf new file mode 100644 index 0000000..1d3257b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p124.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9298d1d6852170ac24946e771dfec8b1806b29143aad26314809f2d694347761 +size 564447 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p125.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p125.pdf new file mode 100644 index 0000000..c44d200 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p125.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:accd1d3ea1615d6a1c00d950b2c81abd4b20f83cb4c6e209ffdd4e7bb88900c7 +size 244703 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p126.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p126.pdf new file mode 100644 index 0000000..663e5a2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p126.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:610dd766ea2166317fdf4a5fd1b54d05299d11dddf196c88dad8903cc6bc2ddd +size 244903 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p127.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p127.pdf new file mode 100644 index 0000000..d14d9b4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p127.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3734d2fec2f961cd1d47c5ef15ec50a1c299219c385193a4fe97983f63f8c5d +size 459703 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p128.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p128.pdf new file mode 100644 index 0000000..68e43e3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p128.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7489984c1f9c788a11db0ebe3825b0b141dc05fb53d6af1a9805f379535b0ffb +size 467841 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p129.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p129.pdf new file mode 100644 index 0000000..637e6f2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p129.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67ec8882dee05e9d9771f94ebd32d3475d8b35b1f40bc1ebf88b65854eb3ff57 +size 769888 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p13.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p13.pdf new file mode 100644 index 0000000..1e14002 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p13.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f0ec2ccdcafe93080d868349341e0a50915dbf3503f9db6bde03163fae66836 +size 233699 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p130.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p130.pdf new file mode 100644 index 0000000..1756225 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p130.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e44379b143ffd8470e526cf0219895f4b9121daad8a76bf7618d0c55a33d9d6a +size 538647 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p131.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p131.pdf new file mode 100644 index 0000000..a6a1a5d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p131.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1a13d1e0a925e36afbbb292e1380622d1d6ddc16afaf0cd18d7a6ce45d7a9ed +size 844356 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p132.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p132.pdf new file mode 100644 index 0000000..6a85b90 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p132.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf8a73c105eb1d02c74a2f1112d925e59a0b8d4e63244c01dd541b6c1d2fa609 +size 238410 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p133.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p133.pdf new file mode 100644 index 0000000..d50dabf --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p133.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c78748e011a8b37f107621009e68031e33b61c73009d726b5e134c3de5191cf5 +size 840145 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p134.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p134.pdf new file mode 100644 index 0000000..2e360cf --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p134.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d6ae69693e8772a6e02d60ad68e1e5376b2b0fdb75df0c3fc453acd7a79f673 +size 249913 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p135.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p135.pdf new file mode 100644 index 0000000..2dc2154 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p135.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a23cc13761c54f9870a09be36eb710e746a0033b8d19f00d0cd1240cc9c61717 +size 1718361 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p136.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p136.pdf new file mode 100644 index 0000000..bd51bc5 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p136.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:419c1260c860d38bb14b0b6cfd9c5cf782297920557ea7b2fe6acfed1b2889aa +size 238047 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p137.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p137.pdf new file mode 100644 index 0000000..984e721 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p137.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb884c91b9b1d63ed742fd36307688fe94b0ce6ba0ec816f99e412b9f192ecc0 +size 249106 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p138.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p138.pdf new file mode 100644 index 0000000..5745947 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p138.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fe3150dd67341ecf89b3117a9dec7dbd67fc055c431bc1086c00b8ee62408a6 +size 502245 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p139.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p139.pdf new file mode 100644 index 0000000..2687d82 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p139.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8430a79b7ffbecbfadd838ad22722d0d30e4f3b526bd2c39f9c297ee83c779e +size 470078 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p14.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p14.pdf new file mode 100644 index 0000000..bcf32d1 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p14.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce375f0aaf5baaf84451cd32ab2387885a7f373a4b328ca40753c9e47d3a349b +size 231760 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p140.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p140.pdf new file mode 100644 index 0000000..663619a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p140.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:921823102186218f7b737688fd97c056ac62e9b523cf99a9778cb36f15875da5 +size 541627 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p141.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p141.pdf new file mode 100644 index 0000000..f9e66c1 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p141.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c50d3f83d8872a57f3ff6afe76a0005f08078dc627ac5c7907d8dbda031d9fb9 +size 945054 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p142.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p142.pdf new file mode 100644 index 0000000..6f52d06 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p142.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac56794dcbca0438c9d768f6d25d0cc7ff52657c2e7855ccc7c1d4e823bb16a6 +size 532282 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p143.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p143.pdf new file mode 100644 index 0000000..b479299 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p143.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5934d90a8251904d5785f3a4bb1ee2a3afbf6b9582b00401e54d42b0acb4d17 +size 290310 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p144.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p144.pdf new file mode 100644 index 0000000..d11ba30 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p144.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c36ee55f2a268cd73f266e9366af4f755bbb49e54596a363f5f7398df563a210 +size 246123 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p145.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p145.pdf new file mode 100644 index 0000000..a051f31 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p145.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97ee893a7717f89870fc0421c1241d06d97d01e7f6908277910f19c0cd41ce35 +size 475493 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p146.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p146.pdf new file mode 100644 index 0000000..735e44d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p146.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9473ca15bd15419a1dad569eff35b0fad8ba71efbd77b148ab119b3c0d8bbb6d +size 249670 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p147.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p147.pdf new file mode 100644 index 0000000..abedf78 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p147.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04039bfb7044a7ba70de4c8070b241bfae2a0ceabc9cd65af5352399914c5188 +size 555033 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p148.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p148.pdf new file mode 100644 index 0000000..acb43bf --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p148.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:271e96f2af40955a339f56d215315543dc9801f020f407b4f34de45da353a2a8 +size 725437 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p149.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p149.pdf new file mode 100644 index 0000000..8328800 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p149.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f6f89918238f2675dafb8ec696ae2fe80bf1544f25bcac66c1ca2e17162a6b8 +size 349970 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p15.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p15.pdf new file mode 100644 index 0000000..9d8fa9f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p15.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9147df72982a527be429f7eca9ef37f2bced5a0284f77020db8fa80711d91afe +size 243079 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p150.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p150.pdf new file mode 100644 index 0000000..f86dd72 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p150.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce3a1f2c8cd0fefce16f2add4bd3574c9b7b1a4ba4fafa29fcd57ae3fd80b079 +size 482858 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p151.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p151.pdf new file mode 100644 index 0000000..940ed44 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p151.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7412fe0b3333ad698b5df69fc40d80b89d392ef9db3a51827ebf0951be90c5ed +size 460835 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p152.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p152.pdf new file mode 100644 index 0000000..d68d8e3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p152.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a06d74585e1e494c4e86037847cf3359e985f343cf18a83a29b5003a277c07ec +size 449499 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p153.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p153.pdf new file mode 100644 index 0000000..e4ca84c --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p153.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9a9dfb08d8364c9395c8cecc9c6116a8099439b410bd60ba4dea9866294d83b +size 472262 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p154.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p154.pdf new file mode 100644 index 0000000..9f79ace --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p154.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad4e83b68cb83db193dce565598c074473fec9558a0c66f86ea29f2ccc82208d +size 230183 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p155.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p155.pdf new file mode 100644 index 0000000..6af1ffc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p155.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1039e6c8502ad2e7b2f76fc2f36f14e4d1c9f657e8a762b77332ce5246675384 +size 233810 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p156.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p156.pdf new file mode 100644 index 0000000..0db6caf --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p156.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca5c82f0a1d5f11a8e7021733eb4b1fc7fed6802dfd7ce98f47402c504a21db3 +size 478341 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p157.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p157.pdf new file mode 100644 index 0000000..6083d03 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p157.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:753ec5d8ce0b71c0083ba934e89484124454512912f9e469bad016cf51d7003e +size 231201 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p158.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p158.pdf new file mode 100644 index 0000000..603f428 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p158.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12005e93704f9cbdc2ceb34c4d1be117fb828244a07f8c4c1b683d176fb94e2a +size 439410 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p159.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p159.pdf new file mode 100644 index 0000000..e71af85 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p159.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b682ece48463fda23b431db252e2362a89b7b4e2beada6b09fa1e5e524fd49b2 +size 513233 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p16.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p16.pdf new file mode 100644 index 0000000..7ef0983 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p16.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5de4132806ade197b060a74bed74eea53437b63eec20997e16f109d9285fa34 +size 2207418 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p160.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p160.pdf new file mode 100644 index 0000000..d96eb84 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p160.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9c9422a42986c474f04325d4b55a1474d0b0f0b6c8849a9a46554e1926ba0a1 +size 489178 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p161.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p161.pdf new file mode 100644 index 0000000..84af4dd --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p161.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:efeeb47770b120e2448d57c8acaf0adbc17e392b158506ca6e62c2c941167759 +size 787618 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p162.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p162.pdf new file mode 100644 index 0000000..8f1b9c5 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p162.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:512a1dbdad5f801acf02fe3d82c9b3a6555835476ad42783ee97dcf4a2b892ba +size 838895 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p163.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p163.pdf new file mode 100644 index 0000000..1d5aed4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p163.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:faebfd7d4de251aa772d71bf7abfbbfe5059873db2901a781bd6c6131a3970d5 +size 243208 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p164.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p164.pdf new file mode 100644 index 0000000..8aace24 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p164.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:995c612ccbe9708bc4b55ec88285632b43b3f9ec65459d3fca4c78221b0bca8a +size 439969 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p165.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p165.pdf new file mode 100644 index 0000000..7a5b317 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p165.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfb1989b6425a6380b88a7d69eefd26c0048f0d0b5ab8fda462af3fd0efff994 +size 910616 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p166.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p166.pdf new file mode 100644 index 0000000..be16d8a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p166.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c7dde504678471b7cc008fb0459fe37d725e3ffd28e91d1bda04786de3eb01e +size 298181 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p167.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p167.pdf new file mode 100644 index 0000000..7ab3679 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p167.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a407a66593ae6f8c329e2c85c08bcb649567b17f2d7e02a60f7e3e1ff3132a0 +size 1850221 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p168.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p168.pdf new file mode 100644 index 0000000..c79a583 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p168.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bec9adaf5ff73630e8c84db2779a829e794724955958a13198be23f1f001061 +size 843765 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p169.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p169.pdf new file mode 100644 index 0000000..ac26e33 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p169.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46a090a6347860d9e59fb0e00487e984faa12d89fa23d5a7dd7af1a118f04eff +size 247431 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p17.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p17.pdf new file mode 100644 index 0000000..e442ea9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p17.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c701f31edd866f9b47a7cf4c847877828cec5afc7f58f057ca2c9b877046179 +size 1774429 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p170.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p170.pdf new file mode 100644 index 0000000..8386995 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p170.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86f87b369c9989fc71f29ea7e0c764bf189f32d07d7a0d0046faaed234e65bab +size 217641 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p171.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p171.pdf new file mode 100644 index 0000000..ca1f9b0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p171.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a83c91f25f063c936b295a05cc8de7f3a25e04af9c73e63837e98654fe088b28 +size 434870 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p172.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p172.pdf new file mode 100644 index 0000000..54c8a1b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p172.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3eadc41e7ccaa1ac3eaaf63250050288ca8c7abb04bced02aaef30ad19b78abc +size 211112 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p173.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p173.pdf new file mode 100644 index 0000000..db79021 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p173.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7741be8cd3d2173157f7e4a695df39cb4d6d547d65cafedf5117ec688f24de72 +size 545762 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p174.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p174.pdf new file mode 100644 index 0000000..4dd7c7b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p174.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:134f832d3c477880c102105c2f75064d6ab28ca1d4dddcb7b3141085cbb0b874 +size 536172 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p175.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p175.pdf new file mode 100644 index 0000000..04b9bc3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p175.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d863323d7542023c3d9bbca1ca997190084d3e0e4ca4f44b92e30dfeaf1f588 +size 214887 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p176.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p176.pdf new file mode 100644 index 0000000..a327dea --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p176.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bdf96adb6a8376d59a77bb955c469f5110812ec0fbad9a1d2c3ab29357dfa80 +size 456333 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p177.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p177.pdf new file mode 100644 index 0000000..763ecd0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p177.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9b52586c2ee400d27c860227a523b486a0147cbc2088c46f7bbb7364e8b02ae +size 272884 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p178.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p178.pdf new file mode 100644 index 0000000..8a88d9f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p178.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c8e571c2d4c894eaa5d7fdec6f0f34a1a7b9d697ee73d0df50de7308a5d6325 +size 213667 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p179.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p179.pdf new file mode 100644 index 0000000..66bc32d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p179.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac791ff24a484c97220c3d3dacba4d6ea85c1887e33d06fec8bb46bf5400f184 +size 473533 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p18.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p18.pdf new file mode 100644 index 0000000..bcb9aa2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p18.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d67f111544a35c474b5b62133785d2f2015c091032b9c6f4e8090a255daed2a7 +size 231169 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p180.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p180.pdf new file mode 100644 index 0000000..d43cbb9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p180.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e58d1d61bf968d45b93f219111b43f9015d4c011cbc8d4f67dba74a45e7de421 +size 266516 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p181.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p181.pdf new file mode 100644 index 0000000..2997272 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p181.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71cf7ccd15e6cf005fb10348d321cabf8ff065d97fc20be537d2f1ffa38a55f2 +size 418607 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p182.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p182.pdf new file mode 100644 index 0000000..ccfbeca --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p182.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:155ebb7c45ac595728cbcea31d1d36913deea4580d518a71c394e7dc8649e417 +size 267037 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p183.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p183.pdf new file mode 100644 index 0000000..7f732af --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p183.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea97b677697347ab3abf83f026f4d4783185d693162011d5d09fb4e93b2e0723 +size 211843 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p184.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p184.pdf new file mode 100644 index 0000000..c003c85 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p184.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:268df72427d33516b4012b8ec04ef88d94909da1dee25e0ff738873fa01a81fd +size 351248 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p185.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p185.pdf new file mode 100644 index 0000000..38e89d1 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p185.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7332ee255a85726c1f6f263abd3ea257bb5a53fbbfbca89d45e1891cfdab3a6 +size 533405 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p186.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p186.pdf new file mode 100644 index 0000000..33c1828 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p186.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3ddfc394d5c81a6f27e926a71e42d27e9e8885e22814adb0beb1c1b5126f589 +size 499130 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p187.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p187.pdf new file mode 100644 index 0000000..4e17c13 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p187.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fb45724c198e9349622145f40ecce92675f27d49d6ed6dd4583fd55b11949cd +size 201354 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p188.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p188.pdf new file mode 100644 index 0000000..a6597be --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p188.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e46308e4617233ac335c6b70cc8edcdd6a66d579bc5df1157c2202265021b6dd +size 522434 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p189.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p189.pdf new file mode 100644 index 0000000..670e667 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p189.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47df73282ba3337a4afee272d87314fd065e515c24d932ca78c386ebdd3aa22c +size 210044 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p19.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p19.pdf new file mode 100644 index 0000000..22641e4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p19.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5aff3bdd27cc093b3d5195082cad435f1039e1f4ae9a5b5a9c72e9f1d215bc87 +size 231369 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p190.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p190.pdf new file mode 100644 index 0000000..817ddf1 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p190.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:904c605b8874b67ebe1236262411c2f0b466ee924b7fefa4bdafac2522f8467b +size 387370 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p191.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p191.pdf new file mode 100644 index 0000000..a156e9c --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p191.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4919ad711d7c3dd5d187861ecf6ae20653630ec8e42228ba3bee92841d6345b7 +size 215160 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p192.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p192.pdf new file mode 100644 index 0000000..45e243c --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p192.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02890cec362155a1b50e66ad827f55ffedc3ebb3b1841098087d38fd9784300d +size 532285 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p193.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p193.pdf new file mode 100644 index 0000000..f739a9c --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p193.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:baa633a513029311e3f1d0580977a62e6ed13e8f6d26507f3a282c532cbf59a8 +size 466631 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p194.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p194.pdf new file mode 100644 index 0000000..5805840 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p194.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03b1bb48650a1ccb5b0bf68402619cf374e5f5e47c2bef326237b5f0e1ee656c +size 446591 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p195.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p195.pdf new file mode 100644 index 0000000..53e1eec --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p195.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d94dbd17184ffd16af371dc1da270ed8e28364180c005d75c28c48075d63700 +size 197318 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p196.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p196.pdf new file mode 100644 index 0000000..455b196 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p196.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3ed3ef04ca1495681b7499198977558742fc7b36157bcb466bed91e82996f71 +size 196245 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p197.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p197.pdf new file mode 100644 index 0000000..438fc2e --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p197.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96d05d92243220864183e11710a3437fb028b19a141de4c066c611bb3ee194ff +size 262450 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p198.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p198.pdf new file mode 100644 index 0000000..66d367a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p198.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:246d0c0b6137309cf17eae8e6dc6743975b42c13174178f6f80e1213131fa440 +size 501646 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p199.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p199.pdf new file mode 100644 index 0000000..71eaf1b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p199.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1d5ead9f3bf8b4b2055e234a32fe109d74bf801103f21374ae39e019a9930f4 +size 485855 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p2.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p2.pdf new file mode 100644 index 0000000..878ab47 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p2.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3206274bbe200c2cbbf996e795251723e00e2f35f2c233f48172cf4ee1283ce7 +size 4571384 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p20.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p20.pdf new file mode 100644 index 0000000..58da159 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p20.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7eba81a71c173618cee58d44f676b09d10b7177f651432065367c37c5fb3d46c +size 500143 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p200.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p200.pdf new file mode 100644 index 0000000..5cb8adc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p200.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23dc11a21424f7e67a5c33695568f3b8f97ecd9fffc3738fa2140c035a327b04 +size 465479 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p201.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p201.pdf new file mode 100644 index 0000000..e2d5cdf --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p201.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e7a7007405bde08e0c6eb4836b2af1cde1440efb94d81205af332be7f28495b +size 409661 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p202.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p202.pdf new file mode 100644 index 0000000..8b86bd2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p202.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72a0c2e1f5a3c6e76348661890e95aff244581e7142f2defead68b91d9424218 +size 201535 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p203.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p203.pdf new file mode 100644 index 0000000..ffd7626 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p203.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b0ddc3b0af56dbf54fd3abf5358a732e021331944092734ac65fdef9f468c05 +size 622907 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p204.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p204.pdf new file mode 100644 index 0000000..f0a6eea --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p204.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20b53c318c481046d8abeb27b01f7c938e9b9267dd8b5052e63ec65294c7f1ad +size 211520 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p205.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p205.pdf new file mode 100644 index 0000000..ed42920 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p205.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:541ad56e6f8f2e78bebc808e6db86e99ba206d9c20f9b076c7f0d46293141fc8 +size 199618 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p206.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p206.pdf new file mode 100644 index 0000000..79c1cd9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p206.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28c1ef77d58e3617d4e21cb8864a108efc7d7d5eab6ae1a49ac70730bed62ae2 +size 200058 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p207.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p207.pdf new file mode 100644 index 0000000..491576d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p207.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e4c1607ed50d3395f28a14c34ec376887a51846886d432cc221b1f3d9cced9b +size 480846 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p208.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p208.pdf new file mode 100644 index 0000000..9bf6dea --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p208.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb60f733f503cdc36c8b5002491cd04ad4af266dcd6da8811ced5df02a1ae1ba +size 235001 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p209.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p209.pdf new file mode 100644 index 0000000..7bcbfc1 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p209.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ac38238b305c89ce3a2f8aa7369ee47da41f5bb2335e52be04502e6951e14a0 +size 1641650 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p21.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p21.pdf new file mode 100644 index 0000000..994b5e0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p21.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96bb31a7286627f7163aa7ae5f0dcb018a81d6bc79994d555d371833fb25ac34 +size 241077 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p210.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p210.pdf new file mode 100644 index 0000000..e15d8bb --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p210.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ce4559d26bf7a7632bcbda6c314842a024efa52edd813211989735096c0eda2 +size 277818 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p211.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p211.pdf new file mode 100644 index 0000000..78edab9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p211.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3dc98ff183ce1534dec6f0406d1163b41cfccfbb943527f2dc310d08916dfe1 +size 289450 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p212.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p212.pdf new file mode 100644 index 0000000..824efe9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p212.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99fd5054816ffada4a654cd28565f4f4fde7fa08cbf45733ed319a88e40c2d4e +size 279522 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p213.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p213.pdf new file mode 100644 index 0000000..0217776 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p213.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12ad8c649ba5d3c333b3860a7ef3ee4a12a63e9b41da55c315b4985bbd7340d3 +size 461968 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p214.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p214.pdf new file mode 100644 index 0000000..4d82f3c --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p214.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33968d4ad08920cbc23c85ad68524e197b987b538705b27fc3a9489243b5f684 +size 653306 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p215.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p215.pdf new file mode 100644 index 0000000..b221fe0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p215.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f668e9a2535b241e857fcb6b35be61698c5a496ef39afd53192524fc987354e +size 512559 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p216.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p216.pdf new file mode 100644 index 0000000..5e3030d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p216.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df3f40e226e0d334f0fd46d6e07f49594115bd4dd4486b46620bc22077a4622b +size 619448 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p217.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p217.pdf new file mode 100644 index 0000000..126cf31 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p217.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58e18cb41bae23722f46853a697410a8ffb2028b412d95bbba393a3231061eb1 +size 490244 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p218.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p218.pdf new file mode 100644 index 0000000..e29e7bb --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p218.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a6e6dc27f41f4cacdebe8a25030b385943419051b4f2e2951fefad3e29645cb +size 304229 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p219.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p219.pdf new file mode 100644 index 0000000..4260a57 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p219.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a44c62c1f9bae917e26ca9788119f6863b8112ff273c2b3f77594482c116066e +size 441431 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p22.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p22.pdf new file mode 100644 index 0000000..32c934f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p22.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ebd5abbd2a6b3abe2eaf1aeabe565a02a4b57a7c9e1fb3ba6e0f41f66027d09 +size 348080 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p220.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p220.pdf new file mode 100644 index 0000000..6800599 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p220.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78ce4d11a0f47793c703b7c22afd07e845ba704d932ce7b6e8f60742cbfa268d +size 312050 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p221.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p221.pdf new file mode 100644 index 0000000..f64c3dc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p221.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dea079736f3047972f79199cf966c0a457a6d6886475abdcb26458a3dabaae46 +size 289752 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p222.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p222.pdf new file mode 100644 index 0000000..b5fd012 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p222.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d092a1bdc8a5a6832f303d5343bd9661822193da87bddba7c550d29c834bab8 +size 665772 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p223.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p223.pdf new file mode 100644 index 0000000..b3276f6 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p223.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7831d1c7ba48e53a81a4a3922eb154cbf63a97a1d2a9ad4e20a82360ae71063 +size 243465 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p224.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p224.pdf new file mode 100644 index 0000000..b94d7d4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p224.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8de03142eb31cdbf1603c899f4ee1aca664d073d305d3a95cd68287e212071d7 +size 457622 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p225.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p225.pdf new file mode 100644 index 0000000..805dd1a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p225.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1543884089432c2937c1c35ff7057be1a6d6d4076b0d2eeb18f35b7f6f2b8dfc +size 561179 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p226.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p226.pdf new file mode 100644 index 0000000..ce4abee --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p226.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5044ded5063133846a41f64345885ffbea38dddc82f9a8ead3e521f39b4565ba +size 277725 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p227.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p227.pdf new file mode 100644 index 0000000..ef0b524 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p227.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83f7e9e1cb8f30cee6e08c174b308d41966111976088d355718019b5254ceec5 +size 233691 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p228.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p228.pdf new file mode 100644 index 0000000..a119eb9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p228.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8cc75f684539b54e31739dba3fe63c143f0bd9d2d8a08ac05faec7b63c1d7b6 +size 233816 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p229.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p229.pdf new file mode 100644 index 0000000..6a45a6f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p229.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f08f0e37402a12d7d69f4f353384d3d3a64e5a70404a30fe85621cfec04f210 +size 246675 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p23.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p23.pdf new file mode 100644 index 0000000..392ff32 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p23.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83a7f652dae82e0653f304706781a78136cddf419c7ba325ddc98b9aeb92e464 +size 238762 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p230.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p230.pdf new file mode 100644 index 0000000..c7da101 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p230.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3843f50a1814f36ae40a7815d6ffda4085c632f8f827f8a2da6e3901ae048dd +size 482718 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p231.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p231.pdf new file mode 100644 index 0000000..5283c00 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p231.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3615c1562fb976eaf79e0a9aa63daba32e577fa89cc89378b1ae75567e789b5 +size 234219 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p232.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p232.pdf new file mode 100644 index 0000000..c5fac3a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p232.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39262f88af9f7221d4bc24b8ebc4e1456ed14898d46dc6a5152fbafca75748c2 +size 447526 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p233.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p233.pdf new file mode 100644 index 0000000..4708227 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p233.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82d70cd5447e0ec8cde86cd5a30d8ae05af08c0de8521e0b70cb773218f76793 +size 287401 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p234.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p234.pdf new file mode 100644 index 0000000..53e5466 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p234.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:183a8f0f7ed994b705c8a7abb7ce997198ff76a7d0f1f334a266992feb4978b1 +size 437310 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p235.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p235.pdf new file mode 100644 index 0000000..fc00d87 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p235.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b78c740cd3efec3f385340ddf5047a832cb69d9128846788b40fb0ca64d787ec +size 555537 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p236.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p236.pdf new file mode 100644 index 0000000..df29c54 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p236.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:191fcb08223780f15bfad862f3ff535bc4bf0a249669876a1d8f32e404334dd1 +size 489376 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p237.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p237.pdf new file mode 100644 index 0000000..4b8987f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p237.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02fbaca4b6010abc52afd2a31e4e8c59468189ff974c0d82ad7114e5594e15ac +size 243471 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p238.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p238.pdf new file mode 100644 index 0000000..9d9c8fb --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p238.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc02eed2324cffbe8ff33f7c4eba61ac67f8e35e28ac3fc7ea4f5dfb8011784e +size 266109 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p239.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p239.pdf new file mode 100644 index 0000000..3d46ccc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p239.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbaab20af0929f1541f26f43f55580f033df060e04173047a1f967f01fed7fdd +size 219422 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p24.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p24.pdf new file mode 100644 index 0000000..22f3869 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p24.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6416a43c36e1042a336e4447fa450f188a994c2628d3487b1019def2a08832cd +size 1050316 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p240.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p240.pdf new file mode 100644 index 0000000..782faab --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p240.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:068c73b17b420a2c24df8a7fc6c73b20604e1aa9f7735f608b56fcb0bcc5a881 +size 247737 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p241.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p241.pdf new file mode 100644 index 0000000..3d8c1e2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p241.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a5078456194ee5d3069b4f7fc77efde83d727203c23c1e99778444779a3f221 +size 556097 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p242.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p242.pdf new file mode 100644 index 0000000..e300d29 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p242.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b1fad60d58b459d4339423069b29792c178f63cf4441796cce54417527fa9e6 +size 633368 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p243.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p243.pdf new file mode 100644 index 0000000..2bcdc6b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p243.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:181845dfe731804d6d0bd5d6b52f2eeac70e5ffe0e30bbcf8287cadfb3a32d3d +size 559887 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p244.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p244.pdf new file mode 100644 index 0000000..1ff74c2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p244.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4d8ae414a5f1256fcaf84faafd31b6540841095163b5b4aa07f9a3801d715fa +size 238200 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p245.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p245.pdf new file mode 100644 index 0000000..0ab774e --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p245.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c250f501a528c27e4e0917f81db463df4551e5b3a9c2307e826ddad91c69e8d0 +size 1760905 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p246.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p246.pdf new file mode 100644 index 0000000..cc2ab94 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p246.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a96c5c404170dc72a8216488be882a466c065796be51244398dde6af34ebd96 +size 456827 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p247.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p247.pdf new file mode 100644 index 0000000..c94b3b3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p247.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a1c603af44e67c4568b993d652d065b3b2831979e561cede646882346b6becf +size 497471 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p248.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p248.pdf new file mode 100644 index 0000000..a74d8f4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p248.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da4650533bdd9c1d77bab210f2b6746ca03fdf94647fc0a7833de4894a6e15c8 +size 248096 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p249.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p249.pdf new file mode 100644 index 0000000..667ed32 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p249.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c62a359dd9d589d2692d34092cdfd5346db3ea230f054b9fde17d6e1d9c739b8 +size 465206 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p25.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p25.pdf new file mode 100644 index 0000000..5b86f34 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p25.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df488efaac6447a87916b93b02077fd612d6c5565d7a17dd6f5f49aac18ba5a5 +size 1616519 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p250.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p250.pdf new file mode 100644 index 0000000..b63ded3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p250.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:084774658cf02421d54366452059727676483644943b2afd8bd87c9790c832fc +size 470395 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p251.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p251.pdf new file mode 100644 index 0000000..e02900d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p251.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:daa9e961baf03580726064c360775140eed68bcb80892c5332d87847ff9f7c79 +size 235763 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p252.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p252.pdf new file mode 100644 index 0000000..41b31b8 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p252.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a35b660c70b31ea58e3353b5079524963e2a01c60ac1021f5742c0b163b3df4d +size 238247 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p253.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p253.pdf new file mode 100644 index 0000000..f79da54 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p253.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96e2fa34f2a124ff7a85168f81ad53a6184d52d4a055d3e9d45600a2c4950dbf +size 333710 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p254.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p254.pdf new file mode 100644 index 0000000..0fed923 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p254.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a5894e5d33fd11b48834e739cc1442075bb607cac54cee756dc6b2b343a61cc +size 540183 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p255.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p255.pdf new file mode 100644 index 0000000..dce89c5 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p255.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca50e68b5c254afdc43c83f54cf6ea2fd8d1194e376dab4f8acddf986c7262b9 +size 252036 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p256.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p256.pdf new file mode 100644 index 0000000..9f7dddb --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p256.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd231aaa8e3c57f7700cc19073b38ecdd5c5ab1d440ccbca8992b1b665f4b455 +size 1011000 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p257.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p257.pdf new file mode 100644 index 0000000..792b76a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p257.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:050076eddac7d8f9b5657104c67403c611ea265de91a0a69a6268603a5f1fc46 +size 235626 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p258.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p258.pdf new file mode 100644 index 0000000..5147158 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p258.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:971c56ead46bf9bca1b67e09ca83a67b3acaa376b883695f42cf5b3579174a3a +size 237366 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p259.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p259.pdf new file mode 100644 index 0000000..cceb980 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p259.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9025f2e1eb0235a38354a1dd1c7c32490b057197766e6bddd466e4dcb8788ca +size 474089 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p26.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p26.pdf new file mode 100644 index 0000000..a962506 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p26.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:990d9befe1b55a3d2bd50e633dc78ffadd3d58e4edbc105b6c7900ab5f33bcda +size 220679 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p260.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p260.pdf new file mode 100644 index 0000000..07db396 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p260.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf8d8b6fc0b591e6588b865358329efc3b64973a1eaa4f91e128dc0b6fcc5e3a +size 234434 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p261.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p261.pdf new file mode 100644 index 0000000..2aae493 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p261.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:315d6615775aa6e39808c2c1d313cf5ccfd6c3be4f2e7ad665f4b3e0b6487129 +size 222382 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p262.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p262.pdf new file mode 100644 index 0000000..0a0c2c1 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p262.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cdeb9f93d58200205964052c08f847d2c163a7b30102df18b38f5baf4df4152 +size 732498 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p263.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p263.pdf new file mode 100644 index 0000000..de9b331 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p263.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58a8dc50dc0cda06782091bc369b539366fb0047f7297532e358a7ccf0bce450 +size 248167 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p264.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p264.pdf new file mode 100644 index 0000000..5214391 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p264.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cada9c793231b8d14e2b3fb71d30b6280160a935bf69fa2509f67ad8e64fddcf +size 433487 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p265.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p265.pdf new file mode 100644 index 0000000..837e239 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p265.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bb147eaa0fedf87bfe6864dc27f7e5394daa39b081cf68611d915783f41fe47 +size 422840 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p266.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p266.pdf new file mode 100644 index 0000000..008d5a3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p266.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:911bc1ad1b9c5d4906cdcee9ccad31569a555bee8057605d5e94d2c085c8898a +size 468959 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p267.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p267.pdf new file mode 100644 index 0000000..3c91b6c --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p267.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f208c86376764e5e48b7bb32ffc45a61ba6f2f525353aa9125765135430cf06e +size 233567 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p268.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p268.pdf new file mode 100644 index 0000000..361bb71 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p268.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f618e937efce13c7a116a906dee6203e68ae4dd39d3011078dc78584146af97 +size 235290 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p269.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p269.pdf new file mode 100644 index 0000000..dc83527 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p269.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f4fb5b6a3b8aa3cdc33c11efd8d1939ed6bfc1585b5de5524067dbbf4b7ae21 +size 248501 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p27.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p27.pdf new file mode 100644 index 0000000..5c51454 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p27.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cd6d7d9ef3a48976cc577047ed1fbda170f5fca520c787d0a2fd0ca529fd849 +size 219484 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p270.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p270.pdf new file mode 100644 index 0000000..8b9c990 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p270.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ef376c303df6fa495e538a40aa1d48fcd29b0143ec69c28862f293f83f54138 +size 245581 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p271.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p271.pdf new file mode 100644 index 0000000..8a0e952 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p271.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba2a72fd51704d78fc7b91549fcba3efcb2a29b4dea61902d328e78c9cb42c87 +size 235344 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p272.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p272.pdf new file mode 100644 index 0000000..56bc998 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p272.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1874983cea7f3f1796970597d5b0b14dc5cb8523df406dab88ed3f523459f90 +size 399958 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p273.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p273.pdf new file mode 100644 index 0000000..fc4ce12 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p273.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f25a26184f46b0afdddd67a34c689987b2b10bf2c45cf297499bd486b006b1c0 +size 606415 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p274.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p274.pdf new file mode 100644 index 0000000..9f20366 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p274.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d651cc823b80460d8d0769e351f3791fea543d818d31c8bfa8e7bd7d8132d66 +size 460871 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p275.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p275.pdf new file mode 100644 index 0000000..72565ec --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p275.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa1f72111accf41c5ee9a09de79dcbb57b6e4a0624087751ada859dad0f9143c +size 1769339 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p276.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p276.pdf new file mode 100644 index 0000000..5803629 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p276.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3f8a37cf32a2cb8f208381d5f584df3fe3a3efdc7ce8a25340a4187d3991a31 +size 465467 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p277.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p277.pdf new file mode 100644 index 0000000..db9ce08 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p277.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9e7ae55e337e903b1b643c7a579ebe8f84353fca30f77f611848b07e2c9db4b +size 246145 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p278.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p278.pdf new file mode 100644 index 0000000..a844011 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p278.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9bf24926e90fa0b69531a8b6f8e4655a8ea54285ed6171546966fb5cdfa7de5 +size 246927 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p279.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p279.pdf new file mode 100644 index 0000000..127f4af --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p279.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e20d651e964abdebf95038a26918703970124b2209c8c40f38a3bb130c1944c +size 519661 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p28.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p28.pdf new file mode 100644 index 0000000..c364ce6 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p28.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9779bd4c7616ae712dc5b59a749d411d587da5044068d06401d39b2921217d21 +size 438306 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p280.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p280.pdf new file mode 100644 index 0000000..4f41cf7 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p280.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7dfa1e4833dae81962ab9ef20701b7157f669c69ac32a071583bbdbe15e3b958 +size 538331 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p281.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p281.pdf new file mode 100644 index 0000000..97c41d3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p281.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22fa68c463741ed51a0b459f75314ccb9d6a964ee8bde182b80b80e6ee0df155 +size 480685 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p282.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p282.pdf new file mode 100644 index 0000000..5d0b87f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p282.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86e6075015fb7d7a70b6ac6b97671e0e7e80525a82964c08020febacdaeea18d +size 237590 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p283.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p283.pdf new file mode 100644 index 0000000..97789fd --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p283.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6284179f7634a05a568ff0bc7f22cb8b88d78e6281220903036fa172bdd82ac2 +size 489334 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p284.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p284.pdf new file mode 100644 index 0000000..656c22d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p284.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76dbf2fe68bff953b70b10779adb47ca3ba782d9d6ec027a618cf0a963870cba +size 270833 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p285.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p285.pdf new file mode 100644 index 0000000..66a35d8 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p285.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08d4a2f078006f66b0d7435e152d6e0ef2649d66276b8009fb266bedaa05d476 +size 273515 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p286.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p286.pdf new file mode 100644 index 0000000..fddada2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p286.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:594898e3f81d17df3dc53a9d19a23bed2ad89d5279f9d3e573a532fad152269d +size 269176 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p287.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p287.pdf new file mode 100644 index 0000000..89e68ce --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p287.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:559ef2d0baa37523f4d1199327a4ebc1c568cee2d48cf119f7269ad8b5d76fe7 +size 239189 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p288.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p288.pdf new file mode 100644 index 0000000..fa63259 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p288.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0576e97b6834d7d047eb80b254e74dd50ff7af2eb1733a7c9c774d39baa9d6f6 +size 249237 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p289.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p289.pdf new file mode 100644 index 0000000..76c6b9c --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p289.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdc1688f6733cd1875a65d97987a5cd563995d9c698bcdf9c297eb64b68b7488 +size 233230 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p29.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p29.pdf new file mode 100644 index 0000000..010aef9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p29.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be90daa0a8c6ac7494890fed242ce65af69f355c1fe2685cf725b8769ab017e4 +size 220127 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p290.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p290.pdf new file mode 100644 index 0000000..4428c15 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p290.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:295c9cfb5182f94d69337903b30a6c0db944232ba17c4e34b67af453dc4ec304 +size 248922 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p291.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p291.pdf new file mode 100644 index 0000000..b43814b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p291.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9153ac8efa8d762f71054e54c3eafc6921e6a5df8523eb37445a701e672a7569 +size 235044 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p292.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p292.pdf new file mode 100644 index 0000000..5fa8e85 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p292.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bb9367085d2166cc7d14d8dc40fe6356407ae58cf88269001ba273d1c1d87d3 +size 533576 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p293.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p293.pdf new file mode 100644 index 0000000..94f5030 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p293.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d4f558628ddbdfc466d040a7d06f759a4508b9c1b69d26430038a618bb753c0 +size 231955 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p294.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p294.pdf new file mode 100644 index 0000000..eb3093b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p294.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05e814e15976e697580665fd2375e25b34202c69afd93ef87224b9eb46eee4cf +size 262960 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p295.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p295.pdf new file mode 100644 index 0000000..837f045 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p295.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9de6435ed22edae84cff0038b593f77905da5442b658c18ea7f81265c4199c2c +size 270967 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p296.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p296.pdf new file mode 100644 index 0000000..03ba52d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p296.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa7de41650d847ec3fef61fe8f57d396c875f5ee9fd2184755c77802dc633106 +size 262342 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p297.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p297.pdf new file mode 100644 index 0000000..96cd8c1 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p297.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51be0207153385642450d5643a93cf84f6763a13476e44a1699199d729358c69 +size 280132 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p298.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p298.pdf new file mode 100644 index 0000000..54d3e4c --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p298.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:395de080278be4167b0d90867fc6495d9c38bb5ed240c14495c818e90c3776d0 +size 273390 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p299.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p299.pdf new file mode 100644 index 0000000..7f64700 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p299.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6be89aa38321edd871e586b35dec6d52733301c776bcdfc585d370a1f1c070f6 +size 276323 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p3.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p3.pdf new file mode 100644 index 0000000..6aa63db --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p3.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aad89403b1153fed6b14408f0de5fa3b13ebaab3f9cd33be6bfba65d7e15b52d +size 448669 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p30.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p30.pdf new file mode 100644 index 0000000..307953d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p30.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:163623bef7898cf00dbd9b8622d0b0e41acf1909065b25560f38492137074de7 +size 454113 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p300.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p300.pdf new file mode 100644 index 0000000..20ef52f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p300.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:723349db2237fa936395cf4b8d33e24e719fc721a8d4913d78242eb9f505d977 +size 1004191 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p301.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p301.pdf new file mode 100644 index 0000000..74bf3b6 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p301.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3c34745f5983489c312147c0c23a328b5c9b5376468b41e1f9be32926ac8249 +size 1797065 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p302.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p302.pdf new file mode 100644 index 0000000..6ee99d9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p302.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb0f17c00943e5d93e2de533d87c4d45882eeb89c0a7229f28f50457c9880929 +size 301772 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p303.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p303.pdf new file mode 100644 index 0000000..1ccd5fc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p303.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:053637cecf90c45bd19f9bec9b94f6466dcb336e8d8c1356da77e1e9585688db +size 282113 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p304.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p304.pdf new file mode 100644 index 0000000..9e6b97f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p304.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32d7e8cbc55789e187b13dfa7397e81449f4e8676f5266e5f13db1250da67693 +size 1114589 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p305.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p305.pdf new file mode 100644 index 0000000..989c950 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p305.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7583fa312306bee4fbd8eb668590ae906117e3c2e80d67b59d6b04c7f3dfb50 +size 733330 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p306.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p306.pdf new file mode 100644 index 0000000..4e74fa0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p306.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7039e6542b6a1e24a112cc714863de8f9883ef3d1727cd5024499833f0cfff3c +size 282517 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p307.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p307.pdf new file mode 100644 index 0000000..db58094 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p307.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cad86d34d5bc63f4e694fdf6b53b09c0ddd40ba7a27860b46df868474a574440 +size 293639 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p308.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p308.pdf new file mode 100644 index 0000000..b88399a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p308.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d61c1bf1652471dd3d258de383df524763292dd1a2ab3404caf03cdc5e5110c7 +size 251370 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p309.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p309.pdf new file mode 100644 index 0000000..701034f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p309.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8aeb174e7d5699f93c6d60081505b490fe9a8f25478062eaea011df71556993 +size 342767 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p31.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p31.pdf new file mode 100644 index 0000000..96ef211 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p31.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89a371abd592845c879b251a96bf822287264b23d44629b3382e27ea7c842cbc +size 219687 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p310.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p310.pdf new file mode 100644 index 0000000..c51a5aa --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p310.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8bd4201e2c5b677079ac233b28250982ff8e6493755f6dd86858a9ececc604fd +size 336424 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p311.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p311.pdf new file mode 100644 index 0000000..2b56009 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p311.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d1e51550c9e81702333e2a8db66b790286de2e118559878bf18986a166e191 +size 323017 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p312.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p312.pdf new file mode 100644 index 0000000..49b91bf --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p312.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5afd4e3884efb34577515d29ee5b1324dd8a31334d2fed8fa073f92a9df1e9c +size 271141 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p313.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p313.pdf new file mode 100644 index 0000000..b91f945 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p313.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81d7bc960d73ea5f149a430a768183b0108e583a42f76f8f22d5458bfb31f084 +size 250165 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p314.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p314.pdf new file mode 100644 index 0000000..a86fe39 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p314.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49f919af49119036f4b6b489eccb33713540fd448b5acb333f6d2d847478028d +size 532561 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p315.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p315.pdf new file mode 100644 index 0000000..e745ecb --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p315.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef8157f04f9ad4111e38aa32ad8358e7af2f9c29cf396f537346010a0ec80023 +size 318513 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p316.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p316.pdf new file mode 100644 index 0000000..e7db07d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p316.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a1c181e603536b883ebca7000e600b6fdf435667823905ec4ea645dbe51d4f6 +size 253347 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p317.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p317.pdf new file mode 100644 index 0000000..dc3f5a0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p317.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b607f40050bd9f9a3ebd44de9c37bb8f9568fdf965016d87e78f8f2076dd1065 +size 273513 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p318.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p318.pdf new file mode 100644 index 0000000..b4120d3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p318.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97e9806ffaf86016801fb6e4b81c7c2cf0bca1200a0bf84c7987208cfe2de63d +size 237348 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p319.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p319.pdf new file mode 100644 index 0000000..b77f64d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p319.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afa505d38835b123a97daa70e263d1e9a385dc939e541de96bb476549b25199e +size 280450 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p32.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p32.pdf new file mode 100644 index 0000000..f370936 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p32.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0ca47eebfd09e12437196ae381b5b15e372caebb068f035b13a23c1c42b8fa7 +size 220734 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p320.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p320.pdf new file mode 100644 index 0000000..529ca86 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p320.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11d222f0a7a083f0fac899d97295997f4cc07a50c16f55c05cd32b494c92f526 +size 273802 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p321.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p321.pdf new file mode 100644 index 0000000..2c9bac2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p321.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:633144ee6ed2487d869655b53f71f2b224370c1cafbf206a22d03d94d06bf423 +size 249072 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p322.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p322.pdf new file mode 100644 index 0000000..4517046 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p322.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ec90ed6c612128b914a16723368ebc06c9c38da723548daeed0e8704986f7ec +size 248653 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p323.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p323.pdf new file mode 100644 index 0000000..6ad5408 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p323.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26a7283ef0c1e3d2add6ed6a2675ad41af5352897a9808ac4938252f0399c475 +size 235330 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p324.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p324.pdf new file mode 100644 index 0000000..3fe737a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p324.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a6ec9837302461fb9813d33938ed0bcb93ca0ef3fbc675b9c9032c99b241462 +size 264190 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p325.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p325.pdf new file mode 100644 index 0000000..83ef57f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p325.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:512a194eb1405d869e3d37bf58b303b8144db35d86a2bd9bc55367248c0e3fee +size 319692 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p326.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p326.pdf new file mode 100644 index 0000000..a720c98 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p326.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f23c7d7f21ee5b1c332f6ca51b5d6ae577ba3397048b7331a01e22468f07ec92 +size 236884 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p327.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p327.pdf new file mode 100644 index 0000000..ccc9dd4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p327.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62081b56ce119d376230a20a6e80b3c851b23d127462c4c400778e3d7148dd6e +size 235364 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p328.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p328.pdf new file mode 100644 index 0000000..de100ec --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p328.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11cf4f2eade6249e2411522f5759d1522ca2f84e623e254a6ce654ce07127c06 +size 272325 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p329.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p329.pdf new file mode 100644 index 0000000..189d776 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p329.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecc6b118bffb15d385ca61dc0feec984b1907b0930bc445c9e12c1ee7ba1e9e4 +size 272907 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p33.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p33.pdf new file mode 100644 index 0000000..b376de6 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p33.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27c397c566c65471a8d1b771dc25e1ed041dc7867f35923eebb7e04894e581bb +size 221848 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p330.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p330.pdf new file mode 100644 index 0000000..a25c5a9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p330.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7615a67ea0969f21088a0483a9ca165be07f66438ab9c2044cc47e172ad6fed4 +size 269415 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p331.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p331.pdf new file mode 100644 index 0000000..a725139 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p331.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd4bd0edd68cb5590a7d34165b4d38f1793d516e836becccfdd43dfe061eb2e2 +size 332834 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p332.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p332.pdf new file mode 100644 index 0000000..e54d1a8 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p332.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1415518fa48a359b6938fa434177f5ad5353bd32e6073dd03d25070130c42df +size 250735 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p333.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p333.pdf new file mode 100644 index 0000000..1ded297 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p333.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a83559d84d8c49d696f947daa2addf0b3cea44686c8f750c05fa703c99e7ae51 +size 251544 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p334.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p334.pdf new file mode 100644 index 0000000..8a4b58f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p334.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ad54e07eb09f3684c1b1f0ba0f5364e392ededce4dea58cce319d3c68012104 +size 264742 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p335.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p335.pdf new file mode 100644 index 0000000..0c4c8e4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p335.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da6747e31def08b6db230a1c099e0bd73fecc604ee7244a73b43424b710e02ec +size 254207 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p336.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p336.pdf new file mode 100644 index 0000000..07c03fc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p336.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88d6b6af073cd8a174c13138a9e279567d54fb8ad0e710af6a6fcaf340ad6434 +size 254059 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p337.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p337.pdf new file mode 100644 index 0000000..3c06f67 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p337.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b622ad05355a3f1db373a4549f825d8dd4eee7a941d916dc7422a73b1861b673 +size 253535 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p338.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p338.pdf new file mode 100644 index 0000000..02b4f79 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p338.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d83807fb962dc705068e4e3cb01f0b4e0bb7f040500c1a99ddd1f5ca8730ce8e +size 279751 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p339.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p339.pdf new file mode 100644 index 0000000..afd6ae6 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p339.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8348df9d265cd206770b98c5dfd3c36008acee836624e79859b924d90c9437c1 +size 265784 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p34.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p34.pdf new file mode 100644 index 0000000..3f69b9b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p34.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea3d3994bd3ae448213c824fbd8a752d194a7cb275e5d9a7a218b51de6c890c9 +size 220901 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p340.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p340.pdf new file mode 100644 index 0000000..d486163 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p340.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2cb442535329d67be6c10d3aeedd26477e3b64a85e45017c9570dcc73bcc48f +size 247583 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p341.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p341.pdf new file mode 100644 index 0000000..d44172b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p341.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e28a726a22d57f149b029d96f9cd5bbcd6f5abee4ef85480c310d2233959cb8b +size 260227 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p342.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p342.pdf new file mode 100644 index 0000000..8cf2e09 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p342.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cc862a277d00c5ef38bba6b07363adef8b9dc332a40eb6503df3f9fc21d9ac7 +size 250004 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p343.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p343.pdf new file mode 100644 index 0000000..d780188 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p343.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c45d88923fe29c4c067867f532695dbd0a26d2a166409e784a9806d6b8bf101f +size 257181 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p344.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p344.pdf new file mode 100644 index 0000000..57c78d0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p344.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a23c04b8f892824b3b061b2c388439e74a64900491cffadd2e44d3d2d24704f +size 240879 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p345.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p345.pdf new file mode 100644 index 0000000..e271eaa --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p345.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:054ac5b701dc316a65cb79a8e6874f52e564a5c21cd7fc8be97e68170d923e3a +size 1181020 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p346.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p346.pdf new file mode 100644 index 0000000..e385f0a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p346.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11c6739fa47e82d2e481fb0d6e88117fbfc16696891f26b7bac44cb66d464f66 +size 223414 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p347.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p347.pdf new file mode 100644 index 0000000..b71cca4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p347.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a17d269ff9a1874e757b3167b28dcc2527a2fe41c2ec08375ba069ca7059db1e +size 223096 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p348.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p348.pdf new file mode 100644 index 0000000..d4262be --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p348.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:716af9d56af4cbb6d7f08d9e275e34616f97037b9e5500d6327162ebb1a89e83 +size 223952 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p349.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p349.pdf new file mode 100644 index 0000000..0d60788 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p349.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:827559bc0559837c74a36f98da681593b65f081597c40a17a107d195f5a5f49f +size 222831 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p35.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p35.pdf new file mode 100644 index 0000000..0213adc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p35.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48719f253cdb133a1511a2cfe1434ce708b304b815c79969eebf987d8e99c804 +size 556915 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p350.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p350.pdf new file mode 100644 index 0000000..d0d3421 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p350.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30db4a8071e362f75916522b3f35e6422b17a8f07b30030ba4f7b981b5e55b24 +size 651097 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p351.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p351.pdf new file mode 100644 index 0000000..7215557 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p351.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92eb87a6be8271c8f256822ff0053ae543511fea9c98287ec2e6dc75b2bf54e5 +size 696005 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p352.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p352.pdf new file mode 100644 index 0000000..25729f3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p352.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e458c70fb7822f203204c9f48b3963264297304f6774edd31f969caecd44924a +size 152107 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p353.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p353.pdf new file mode 100644 index 0000000..31ac87e --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p353.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ed4098f23febabf44b2e8c52df33433c22d8fb71d6c508bff89a53f8c745cfd +size 148296 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p354.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p354.pdf new file mode 100644 index 0000000..ab1ed9d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p354.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfcd10bfc9663eada4c04ee9c05308534400e6df430a467263725f667f3285ec +size 384278 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p36.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p36.pdf new file mode 100644 index 0000000..9f3306a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p36.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e98e76fced6ed4705d606330cb01303fcef8ee7248106d3de545aa2c5f0131ff +size 219442 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p37.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p37.pdf new file mode 100644 index 0000000..b49a5c8 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p37.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bca7f8293640bc16f8266a67a341a43734455d97b478fe30a7fe35c8dfe576e +size 798971 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p38.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p38.pdf new file mode 100644 index 0000000..3db3b44 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p38.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a776cfb163c179ac278737bd5e2731b1307fc24717143d06e87119dfdd786f7e +size 228769 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p39.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p39.pdf new file mode 100644 index 0000000..46276f0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p39.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bba84e1e83aa690858c3e3dd2b2927f7f5b89f3727113dc85b8a9dcbef133dc7 +size 1719192 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p4.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p4.pdf new file mode 100644 index 0000000..069678f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p4.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24cdb4f312d56e7e6a883b23a2521a12660a51743fbd393b61e548a251d593ad +size 553365 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p40.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p40.pdf new file mode 100644 index 0000000..c8baf46 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p40.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2189c828d4dbe483d0f4467496f8cd75fdb9db5e0fca8ab44e0349c6f12ba877 +size 228654 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p41.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p41.pdf new file mode 100644 index 0000000..9282295 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p41.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:edb30eb256aa42662a18ad033cd9a5b7c414f828b2ed8cb0467bb5515ca94e5a +size 227879 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p42.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p42.pdf new file mode 100644 index 0000000..eae953b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p42.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73d37ae45f60c561f2e69958b277150ca12e2679b221b793abab39887b5f4427 +size 228210 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p43.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p43.pdf new file mode 100644 index 0000000..b75ced7 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p43.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47ffd2d6071c5359aab4ed97da2003cff4cac4e6ae0bc751108c94cff4bc7039 +size 450123 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p44.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p44.pdf new file mode 100644 index 0000000..72c18fc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p44.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee7ea0bf2403a0495b93d4a90f23b81679ca7dc1b10edf42d8b9b71b80b66e9c +size 274348 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p45.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p45.pdf new file mode 100644 index 0000000..2d44715 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p45.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ffd79a9293a12087fd6c9ecd51c75bf98084e63a34c275ad6a779b7ddb03fb3 +size 267935 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p46.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p46.pdf new file mode 100644 index 0000000..8b2862a --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p46.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a60a399829d06709172d309739a767aef7244c037e8f3f77f037ea64aa7bbb6 +size 453325 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p47.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p47.pdf new file mode 100644 index 0000000..692e6e3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p47.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b1028625878e99c8a1ad258215d800c42c47e12015d91587d193b9647ea2259 +size 221523 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p48.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p48.pdf new file mode 100644 index 0000000..7be4fda --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p48.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c02a7cf5018c7cc2159300bcac994ddaca2f3dfac518dc4db4eae33a957e10af +size 1131645 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p49.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p49.pdf new file mode 100644 index 0000000..013ba48 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p49.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e80f63c2aebcb71dea64d6769020a7462d7a75bf4fabc0872f1cd56fd15c4cb4 +size 278589 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p5.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p5.pdf new file mode 100644 index 0000000..4f23cc0 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p5.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b5a1f20b4cbec2af85105043b6c2dddae98ab0c1d1bc7aa72710af950e9c4d5 +size 522489 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p50.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p50.pdf new file mode 100644 index 0000000..1816bc5 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p50.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abc1c972eadfa882defbed149c578d4ab7d7227c8289e9260e921873cc0a732b +size 457254 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p51.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p51.pdf new file mode 100644 index 0000000..64ed730 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p51.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c3f730959557ae6c6f6da350f637761d03ebe251c66005e2ffd38c02f921b35 +size 242863 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p52.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p52.pdf new file mode 100644 index 0000000..e7c7df8 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p52.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9450c745d9a29dfa251fd2d23a06cf5dbc5ee206d3fb83bdd5a3b8438e14a7c0 +size 228291 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p53.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p53.pdf new file mode 100644 index 0000000..ea0d6f3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p53.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44cc886d31d3989e3d8b925a9c920fb89dd9def22dcdcd1e6785e88a901adce6 +size 619121 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p54.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p54.pdf new file mode 100644 index 0000000..1cb2bd1 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p54.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:535e16b162fc24b85972ff3b85a6ffa4fcf90c6612e7b7e3f2854319c3c4d3a1 +size 294872 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p55.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p55.pdf new file mode 100644 index 0000000..9e944f2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p55.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98387a69b33cf8b38037cdc6ed9b948f0b4ae0d0e5b052b8f792ddc651aee03b +size 1641039 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p56.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p56.pdf new file mode 100644 index 0000000..f3412b9 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p56.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:675a9db50bc2840cdf819aff05c2ac305de93a9787fce31abb78ed04d956075d +size 255922 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p57.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p57.pdf new file mode 100644 index 0000000..5663a1d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p57.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:967fae453ca7910546478fb1c663e1acd4726dcdd18222f985e6b6413e74c390 +size 306111 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p58.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p58.pdf new file mode 100644 index 0000000..ec72f7d --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p58.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1476515c47d04181d8cfa391d80a4f84bc3c74dc8fc933d26ba5fd71a11c18a +size 688811 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p59.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p59.pdf new file mode 100644 index 0000000..ddfff42 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p59.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:170147296af0e8274d89b3080926f7e235f21352a429b122b1e48502fa779a79 +size 352039 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p6.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p6.pdf new file mode 100644 index 0000000..9318be4 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p6.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c80c3cd2148dd58782801609553a4bc794498980f556aebf6531f45c9539507 +size 284933 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p60.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p60.pdf new file mode 100644 index 0000000..298d720 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p60.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f495546c57385f7052b5bcab14025c6d9d721524c6eac6f3f49dea574ba583b2 +size 297156 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p61.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p61.pdf new file mode 100644 index 0000000..30a5c84 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p61.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:480a8fe606abb554ad563821cc48ad6b3f0d8ed1e866202bf792e6e58cdb91da +size 252669 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p62.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p62.pdf new file mode 100644 index 0000000..9e8b012 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p62.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd6649c8cfce1d60b03bd4fc75da7c29464aca1e7f322583ad3d5abb131f31f0 +size 249525 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p63.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p63.pdf new file mode 100644 index 0000000..3fdc2e7 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p63.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28aa89ddc4559ba2bf692e02e0f84c0bd32a65ce8aa753d59d8e7fbb375f3987 +size 1269115 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p64.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p64.pdf new file mode 100644 index 0000000..3986958 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p64.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad9f2ce780cfe98d7acefda5bf27a57049252637bd689d02d8c0530790ed8067 +size 538520 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p65.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p65.pdf new file mode 100644 index 0000000..62a8fbd --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p65.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ea34f4fc113054cc71ec8652e2e1205ee30b81345a2c103c04a44d3bbbccb14 +size 254451 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p66.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p66.pdf new file mode 100644 index 0000000..9edbc4e --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p66.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c224e62652abca0fa1390102fac2a0ee4d62737f1d272f02a815d45ad03a2e59 +size 250728 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p67.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p67.pdf new file mode 100644 index 0000000..8605573 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p67.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c981458c007fcf8606778e1b1629b8c53a7884df4a2c047f67d9c14ce93928a +size 547273 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p68.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p68.pdf new file mode 100644 index 0000000..566fbb8 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p68.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fa9cb4fffc81ef74cbb2db1c0a3c11e189548bd1ea0e79db30c6b7192fbe28c +size 606983 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p69.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p69.pdf new file mode 100644 index 0000000..9ad4891 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p69.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5863a1f96b99cd0f85d12a2c57752487e3f865cc21bfe73ccc4be4bd7707db4 +size 389560 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p7.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p7.pdf new file mode 100644 index 0000000..937f681 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p7.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fb23acb81182507e93d833c567e45d9e82efd5eaa0bcde4bfd0d6240333803e +size 1638792 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p70.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p70.pdf new file mode 100644 index 0000000..f684a96 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p70.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:308a0910925d7f782184a376df1af1d433451148c460795c90f9b8aab3ccfa79 +size 470434 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p71.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p71.pdf new file mode 100644 index 0000000..3a6279e --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p71.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51ecdaf73cad70c3075bed00570788a72367b1d34afa39573f1a35522e1a3368 +size 261846 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p72.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p72.pdf new file mode 100644 index 0000000..1d3ead3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p72.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c957a84478133020261e60da51c0590f6f961f4b398a1a5d6807207a74966e9d +size 1012526 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p73.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p73.pdf new file mode 100644 index 0000000..fa7ea86 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p73.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32a1c73615bf40ba83fadeb986eb9b906429d27bfb37ea4ff99addc7cffcb6d4 +size 1652472 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p74.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p74.pdf new file mode 100644 index 0000000..257174b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p74.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:385c4415cebd3b475cb80b5c567d4d6ddc53a1477410c4ee3a50e0cd00b946d0 +size 260770 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p75.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p75.pdf new file mode 100644 index 0000000..ef907c2 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p75.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e59af74319a9e64f7a9a22d475f8f73526d2ab16a2b7414c007b74fa3d9c1687 +size 437872 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p76.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p76.pdf new file mode 100644 index 0000000..44e40ed --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p76.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54354b6892f4d9525e9f7657210cfa86819e9dd04323a8e40c4ad466a47d24f0 +size 257342 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p77.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p77.pdf new file mode 100644 index 0000000..58097db --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p77.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d21b73bb2d3a716b1182f51a1e57256810799a9b9fe61121e9589655353ca17c +size 642074 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p78.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p78.pdf new file mode 100644 index 0000000..78a9de3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p78.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9ef74083022608779052c800493453e1e0d40c9e031b278042232419e816054 +size 301968 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p79.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p79.pdf new file mode 100644 index 0000000..8f73b85 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p79.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:efceca74710d91a08964ed5fbaa30854618cf048ff0e2ad7b0ff47bb83205bee +size 322782 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p8.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p8.pdf new file mode 100644 index 0000000..ad6b286 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p8.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e8becb9330d4ac01c63f2d87e295b9750563e315224d92d788a633d896f5615 +size 563590 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p80.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p80.pdf new file mode 100644 index 0000000..44ca794 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p80.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:284ffcb3f9ad2386066c43e078b088b12570bba3178ec9cde4f0926d8a070401 +size 253892 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p81.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p81.pdf new file mode 100644 index 0000000..ad19bc7 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p81.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8288c8c024014654c7a841b62e6ff049e3d46b48e5a3d7b868aa712f13c47643 +size 252698 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p82.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p82.pdf new file mode 100644 index 0000000..0a5abe8 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p82.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21e7f434f3ecafa5b590ed2e51b930af891b354adb5992e6bb80721a013c7341 +size 251901 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p83.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p83.pdf new file mode 100644 index 0000000..ac0b518 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p83.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:504896e75c31200f30a2adc1bd258501e7fdaa562047c61b765504b3dfbc45b1 +size 1604436 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p84.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p84.pdf new file mode 100644 index 0000000..edd2bbc --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p84.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cc957c67b995c9c1efe5e3b9996e6f2f1b6b6f14c9000358f34bc07718169c5 +size 449746 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p85.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p85.pdf new file mode 100644 index 0000000..9cfa4fd --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p85.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24f673d815294b03f9924a431522fc57a8dc6098bf1d421f4ff1361cf25edbf7 +size 253347 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p86.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p86.pdf new file mode 100644 index 0000000..9cbcb9e --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p86.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:108a67ce1f31136e4ed076c71b924f42877237c5f3c93f33f94254df9afdde1b +size 255378 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p87.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p87.pdf new file mode 100644 index 0000000..d3dc819 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p87.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08114085cb85ab95ee5b804ae89aaa09672bb09fb9bcc57e339f48b3a6704e59 +size 420190 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p88.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p88.pdf new file mode 100644 index 0000000..b84ea7b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p88.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d000409021932aa49c37ddd52dc6f25960772d3ba885fdfdd569069a9c8daf67 +size 577101 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p89.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p89.pdf new file mode 100644 index 0000000..4893ca6 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p89.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f214ff07051ba134a4b17d3edcb03cd65f10f0ac4809a711d4c67ab60c016e8 +size 465997 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p9.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p9.pdf new file mode 100644 index 0000000..1c6a595 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p9.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:749508564e300ebbee0eaa8b3ffc7e07459887ee4e5f70a36acce5b403c553fb +size 274521 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p90.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p90.pdf new file mode 100644 index 0000000..5a33a83 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p90.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:334924bece55bd7ca2be43e6a712e7b29396d7ddcf8b28ab0310613a390a730c +size 645948 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p91.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p91.pdf new file mode 100644 index 0000000..c5b09ed --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p91.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c79fa9af928948e35d117a24d8e56eda79c6ef6ea63b4c60eb7ae75fefe898e3 +size 4144910 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p92.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p92.pdf new file mode 100644 index 0000000..3ae2778 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p92.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5ee10f0d520b65c5c5c39371466394d4932513cfd511a37fc95e1bfb2efc14f +size 4104152 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p93.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p93.pdf new file mode 100644 index 0000000..18fec02 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p93.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe5abe71c858544d8a8da55df9ad9fd99bb936c65b1ec6ae015f3bc76eaf3fbd +size 3449839 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p94.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p94.pdf new file mode 100644 index 0000000..537c85b --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p94.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af5f86eb2749ebebe4c965b0bbf5043117856644c75f08a12be38a1385e8355c +size 3497545 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p95.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p95.pdf new file mode 100644 index 0000000..04305c3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p95.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f275d09ef09409bdfb6522af6bbd80b027ae34258332d8aef90b7a0d8c13e57 +size 3414825 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p96.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p96.pdf new file mode 100644 index 0000000..b6a9976 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p96.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ddb1d6a12fba79860d5ea949241522196804e50584a140e90b2f77d8cb5ec2c +size 3681129 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p97.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p97.pdf new file mode 100644 index 0000000..4247d6f --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p97.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf3b81e8c302fc7b1c461a10803cbcb23b132feef7d59fe24f0aa5f48982a5d8 +size 3964319 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p98.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p98.pdf new file mode 100644 index 0000000..d88f60c --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p98.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bdd1e4ad191eb8693416318fe7ee3044f1ac81faac0d1da18047f2504c45f4cf +size 3784510 diff --git a/assets/shadowrun/Shadowrun-4E-Corebook-p99.pdf b/assets/shadowrun/Shadowrun-4E-Corebook-p99.pdf new file mode 100644 index 0000000..3a1c5f3 --- /dev/null +++ b/assets/shadowrun/Shadowrun-4E-Corebook-p99.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2ce98cabb809cb109d5ad06b285e0a9d50c497c5421caa4f6e477abf0422731 +size 3376848 diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..3b462cb --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,23 @@ +node_modules + +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/frontend/.npmrc b/frontend/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/frontend/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..75842c4 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,38 @@ +# sv + +Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```sh +# create a new project in the current directory +npx sv create + +# create a new project in my-app +npx sv create my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```sh +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```sh +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..afce819 --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,1587 @@ +{ + "name": "frontend", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.0.1", + "devDependencies": { + "@sveltejs/adapter-auto": "^7.0.0", + "@sveltejs/adapter-static": "^3.0.10", + "@sveltejs/kit": "^2.47.1", + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "svelte": "^5.41.0", + "svelte-check": "^4.3.3", + "typescript": "^5.9.3", + "vite": "^7.1.10" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz", + "integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz", + "integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz", + "integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz", + "integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz", + "integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz", + "integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz", + "integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz", + "integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz", + "integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz", + "integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz", + "integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz", + "integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz", + "integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz", + "integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz", + "integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz", + "integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz", + "integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz", + "integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz", + "integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz", + "integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz", + "integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz", + "integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.7.tgz", + "integrity": "sha512-znp1A/Y1Jj4l/Zy7PX5DZKBE0ZNY+5QBngiE21NJkfSTyzzC5iKNWOtwFXKtIrn7MXEFBck4jD95iBNkGjK92Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@sveltejs/adapter-auto": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-7.0.0.tgz", + "integrity": "sha512-ImDWaErTOCkRS4Gt+5gZuymKFBobnhChXUZ9lhUZLahUgvA4OOvRzi3sahzYgbxGj5nkA6OV0GAW378+dl/gyw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.10.tgz", + "integrity": "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.48.5", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.48.5.tgz", + "integrity": "sha512-/rnwfSWS3qwUSzvHynUTORF9xSJi7PCR9yXkxUOnRrNqyKmCmh3FPHH+E9BbgqxXfTevGXBqgnlh9kMb+9T5XA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/cookie": "^0.6.0", + "acorn": "^8.14.1", + "cookie": "^0.6.0", + "devalue": "^5.3.2", + "esm-env": "^1.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "sade": "^1.8.1", + "set-cookie-parser": "^2.6.0", + "sirv": "^3.0.0" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + } + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.1.tgz", + "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", + "debug": "^4.4.1", + "deepmerge": "^4.3.1", + "magic-string": "^0.30.17", + "vitefu": "^1.1.1" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.1.tgz", + "integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.1" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/devalue": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.5.0.tgz", + "integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esrap": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.3.tgz", + "integrity": "sha512-T/Dhhv/QH+yYmiaLz9SA3PW+YyenlnRKDNdtlYJrSOBmNsH4nvPux+mTwx7p+wAedlJrGoZtXNI0a0MjQ2QkVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rollup": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz", + "integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.2", + "@rollup/rollup-android-arm64": "4.53.2", + "@rollup/rollup-darwin-arm64": "4.53.2", + "@rollup/rollup-darwin-x64": "4.53.2", + "@rollup/rollup-freebsd-arm64": "4.53.2", + "@rollup/rollup-freebsd-x64": "4.53.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.2", + "@rollup/rollup-linux-arm-musleabihf": "4.53.2", + "@rollup/rollup-linux-arm64-gnu": "4.53.2", + "@rollup/rollup-linux-arm64-musl": "4.53.2", + "@rollup/rollup-linux-loong64-gnu": "4.53.2", + "@rollup/rollup-linux-ppc64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-musl": "4.53.2", + "@rollup/rollup-linux-s390x-gnu": "4.53.2", + "@rollup/rollup-linux-x64-gnu": "4.53.2", + "@rollup/rollup-linux-x64-musl": "4.53.2", + "@rollup/rollup-openharmony-arm64": "4.53.2", + "@rollup/rollup-win32-arm64-msvc": "4.53.2", + "@rollup/rollup-win32-ia32-msvc": "4.53.2", + "@rollup/rollup-win32-x64-gnu": "4.53.2", + "@rollup/rollup-win32-x64-msvc": "4.53.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "dev": true, + "license": "MIT" + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "5.43.7", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.43.7.tgz", + "integrity": "sha512-S0NyuEEq5r205XqaWOMESHkqk1uQOo/e4qCKoaTCdELRFzUb+XVzuLQ4a7ushr7y/S3M5hjOBHlUq+xzi5Sy7g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/estree": "^1.0.5", + "acorn": "^8.12.1", + "aria-query": "^5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "esm-env": "^1.2.1", + "esrap": "^2.1.0", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte-check": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.4.tgz", + "integrity": "sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "chokidar": "^4.0.1", + "fdir": "^6.2.0", + "picocolors": "^1.0.0", + "sade": "^1.7.4" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": ">=5.0.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz", + "integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..7a94961 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,24 @@ +{ + "name": "frontend", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^7.0.0", + "@sveltejs/adapter-static": "^3.0.10", + "@sveltejs/kit": "^2.47.1", + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "svelte": "^5.41.0", + "svelte-check": "^4.3.3", + "typescript": "^5.9.3", + "vite": "^7.1.10" + } +} diff --git a/frontend/src/app.d.ts b/frontend/src/app.d.ts new file mode 100644 index 0000000..da08e6d --- /dev/null +++ b/frontend/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/frontend/src/app.html b/frontend/src/app.html new file mode 100644 index 0000000..f273cc5 --- /dev/null +++ b/frontend/src/app.html @@ -0,0 +1,11 @@ + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/frontend/src/lib/assets/favicon.svg b/frontend/src/lib/assets/favicon.svg new file mode 100644 index 0000000..cc5dc66 --- /dev/null +++ b/frontend/src/lib/assets/favicon.svg @@ -0,0 +1 @@ +svelte-logo \ No newline at end of file diff --git a/frontend/src/lib/common/autogrow.js b/frontend/src/lib/common/autogrow.js new file mode 100644 index 0000000..0dff45f --- /dev/null +++ b/frontend/src/lib/common/autogrow.js @@ -0,0 +1,18 @@ +import { tick } from "svelte"; + +export function autoGrow(node) { + function resize() { + node.style.height = "auto"; + node.style.height = node.scrollHeight + "px"; + } + + // wait until DOM updates to apply initial value + tick().then(resize); + node.addEventListener("input", resize); + + return { + destroy() { + node.removeEventListener("input", resize); + } + }; +} \ No newline at end of file diff --git a/frontend/src/lib/config.ts b/frontend/src/lib/config.ts new file mode 100644 index 0000000..44caf62 --- /dev/null +++ b/frontend/src/lib/config.ts @@ -0,0 +1 @@ +export const API_BASE = `http://${window.location.hostname}:3010`; \ No newline at end of file diff --git a/frontend/src/lib/index.ts b/frontend/src/lib/index.ts new file mode 100644 index 0000000..856f2b6 --- /dev/null +++ b/frontend/src/lib/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/frontend/src/lib/shadorwun/character.svelte b/frontend/src/lib/shadorwun/character.svelte new file mode 100644 index 0000000..1811dab --- /dev/null +++ b/frontend/src/lib/shadorwun/character.svelte @@ -0,0 +1,548 @@ + + + + +

Name: {currentCharacter.name}

+ +

Character Info

+
+{#each Object.entries(characterData.Info) as [key, value], i} +
+ + +
+{/each} +
+ +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AgilityBody CharismaEdge
EssenceInitiative IntuitionLogic
ReactionStrengthWillpower
+ +

Skills

+ + + + + + + + + + + + + + + {#each characterData.Skills as skill, i} + + + + + + + + + + {/each} + +
NameRatingAttributeDicePage
{skill.Rating + characterData.Attributes[skill.Attribute]}
+ + +

Contacts

+ + + + + + + + + + + {#each characterData.Connections as connection, i} + + + + + + + {/each} + +
NameLoyaltyConnection
+ + +

Ranged Weapons

+ + + + + + + + + + + + + + + + + + {#each characterData.RangedWeapons as weapon, i} + + + + + + + + + + + + + + {/each} + +
WeaponDamageTypeAPModeRCAmmoAvailabiliyPage
+ + +

Melee Weapons

+ + + + + + + + + + + + + + + + + {#each characterData.MeleeWeapons as weapon, i} + + + + + + + + + + + + + {/each} + +
WeaponReachDamageTypeMultiplierCal.DmgAPPage
{(weapon["Strength Multiplier"] * characterData.Attributes.Strength) + weapon.Damage }
+ + +

Armor

+ + + + + + + + + + + + + {#each characterData.Armor as armor, i} + + + + + + + + + {/each} + +
ArmorBallisticImpactPage
+ + +

Cyberware

+ + + + + + + + + + + + + + {#each characterData.Cyberware as Cyberware, i} + + + + + + + + + + {/each} + +
CyberwareRatingEssenceNotesPage
+ + +

Bioware

+ + + + + + + + + + + + + + {#each characterData.Bioware as Bioware, i} + + + + + + + + + + {/each} + +
BiowareRatingEssenceNotesPage
+ + +

Qualities

+ +

Positive

+ + + + + + + + + + + {#each characterData.PositiveQualities as qualitiy, i} + + + + + + + {/each} + +
QualityPage
+ + +

Negative

+ + + + + + + + + + + {#each characterData.NegativeQualities as qualitiy, i} + + + + + + + {/each} + +
QualityPage
+ + +

Pysical Condition

+ + + {#each characterData.PysicalCondition as row, rowIndex} + + {#each row as cell, colIndex} + + {/each} + + {/each} + +
+ +
+ +

Stun Condition

+ + + {#each characterData.StunCondition as row, rowIndex} + + {#each row as cell, colIndex} + + {/each} + + {/each} + +
+ +
+ +

Notes

+
+ + + + + {#if selectedDate !== null} + + {/if} +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/frontend/src/lib/shadorwun/defaults.svelte b/frontend/src/lib/shadorwun/defaults.svelte new file mode 100644 index 0000000..38c98c1 --- /dev/null +++ b/frontend/src/lib/shadorwun/defaults.svelte @@ -0,0 +1,102 @@ + diff --git a/frontend/src/lib/shadorwun/types.svelte b/frontend/src/lib/shadorwun/types.svelte new file mode 100644 index 0000000..44496c7 --- /dev/null +++ b/frontend/src/lib/shadorwun/types.svelte @@ -0,0 +1,42 @@ + diff --git a/frontend/src/routes/+layout.js b/frontend/src/routes/+layout.js new file mode 100644 index 0000000..91727a0 --- /dev/null +++ b/frontend/src/routes/+layout.js @@ -0,0 +1,2 @@ + export const ssr = false; + export const prerender = true; \ No newline at end of file diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte new file mode 100644 index 0000000..b9d6093 --- /dev/null +++ b/frontend/src/routes/+layout.svelte @@ -0,0 +1,12 @@ + + + + + + + +{@render children()} diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte new file mode 100644 index 0000000..721f701 --- /dev/null +++ b/frontend/src/routes/+page.svelte @@ -0,0 +1,76 @@ + + + + + + + + \ No newline at end of file diff --git a/frontend/src/routes/shadowrun/+page.svelte b/frontend/src/routes/shadowrun/+page.svelte new file mode 100644 index 0000000..99451fd --- /dev/null +++ b/frontend/src/routes/shadowrun/+page.svelte @@ -0,0 +1,88 @@ + + +{#if !currentCharacter} +

Shadowrun Character Manager

+ +
+

Load Existing Character

+ {#if characters.length === 0} +

No characters found.

+ {:else} + + + {/if} +
+ +
+

Create New Character

+ + +
+{:else} + +{/if} diff --git a/frontend/static/robots.txt b/frontend/static/robots.txt new file mode 100644 index 0000000..b6dd667 --- /dev/null +++ b/frontend/static/robots.txt @@ -0,0 +1,3 @@ +# allow crawling everything by default +User-agent: * +Disallow: diff --git a/frontend/svelte.config.js b/frontend/svelte.config.js new file mode 100644 index 0000000..ee7fb27 --- /dev/null +++ b/frontend/svelte.config.js @@ -0,0 +1,8 @@ +import adapter from '@sveltejs/adapter-static'; + +export default { + kit: { + adapter: adapter(), + paths: { base: '', assets: '' } + } +}; \ No newline at end of file diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..5a3b413 --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // To make changes to top-level options such as include and exclude, we recommend extending + // the generated config; see https://svelte.dev/docs/kit/configuration#typescript +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts new file mode 100644 index 0000000..bbf8c7d --- /dev/null +++ b/frontend/vite.config.ts @@ -0,0 +1,6 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [sveltekit()] +}); diff --git a/lf-server-admin-panel.service b/lf-server-admin-panel.service deleted file mode 100644 index c96049d..0000000 --- a/lf-server-admin-panel.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=lf-server-admin-panel Service -After=network.target - -[Service] -Type=simple -WorkingDirectory=/usr/share/lf-server-admin-panel -ExecStart=/usr/bin/lf-server-admin-panel -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target \ No newline at end of file diff --git a/modules/cpp-libraries b/modules/cpp-libraries new file mode 160000 index 0000000..238108b --- /dev/null +++ b/modules/cpp-libraries @@ -0,0 +1 @@ +Subproject commit 238108b69a88c225694d5024e991e133d0a72759 diff --git a/shadowrun-server.service b/shadowrun-server.service new file mode 100644 index 0000000..72b6fa4 --- /dev/null +++ b/shadowrun-server.service @@ -0,0 +1,13 @@ +[Unit] +Description=shadowrun server Service +After=network.target + +[Service] +Type=simple +WorkingDirectory=/usr/share/shadowrun-server +ExecStart=/usr/bin/shadowrun-server +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/src/database/database.cpp b/src/database/database.cpp index 7bd3a28..4680b36 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -1,122 +1,3 @@ -#include "utils.hpp" #include "databasepool.h" -#include - -using namespace std; - -Database::Database() : - m_db(nullptr) -{} - -Database::~Database() { - sqlite3_close(m_db); -} - -string Database::currentTime(){ - auto now = std::chrono::system_clock::now(); - std::time_t t = std::chrono::system_clock::to_time_t(now); - std::stringstream ss; - ss << std::put_time(std::gmtime(&t), "%Y-%m-%d %H:%M:%S"); - return ss.str(); -} - -sqlite3_stmt* Database::prepareStmt(const string& sql){ - sqlite3_stmt* stmt = nullptr; - if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { - CROW_LOG_ERROR << "Failed to prepare statement: " << sqlite3_errmsg(m_db); - return nullptr; - } - return stmt; -} - -bool Database::exec(const char* sqlQuery) { - char* errmsg = nullptr; - int rc = sqlite3_exec(m_db, sqlQuery, nullptr, nullptr, &errmsg); - if (rc != SQLITE_OK) { - CROW_LOG_ERROR << "SQL error: " << errmsg; - sqlite3_free(errmsg); - return false; - } - return true; -} - -bool Database::exec(const std::string& sqlQuery){ - return exec(sqlQuery.c_str()); -} - -sqlite3_stmt* Database::bind(const std::string sql, const Database::QueryData& data) { - sqlite3_stmt* stmt = nullptr; - if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { - CROW_LOG_ERROR << "Failed to prepare statement: " << sqlite3_errmsg(m_db); - return nullptr; - } - for (int i = 0; i < data.size(); i++) { - std::visit([stmt, i](auto&& val) { - using T = std::decay_t; - if constexpr (std::is_same_v) - sqlite3_bind_int64(stmt, i + 1, val); - else if constexpr (std::is_same_v) - sqlite3_bind_double(stmt, i + 1, val); - else if constexpr (std::is_same_v) - sqlite3_bind_text(stmt, i + 1, val.c_str(), -1, SQLITE_TRANSIENT); - }, data[i]); - } - return stmt; -} - -map Database::getStrMap(const std::string sql, const Database::QueryData& data){ - map map; - sqlite3_stmt* stmt = bind(sql, data); - if (stmt == nullptr) - return map; - - while (sqlite3_step(stmt) == SQLITE_ROW) { - string key = reinterpret_cast(sqlite3_column_text(stmt, 0)); - string value = reinterpret_cast(sqlite3_column_text(stmt, 1)); - map[key] = utils::urlDecode(value); - } - - sqlite3_finalize(stmt); - return map; -} - -set Database::getStrSet(const string& sql){ - sqlite3_stmt* stmt = prepareStmt(sql); - set vec; - if (stmt == nullptr) - return vec; - - while (sqlite3_step(stmt) == SQLITE_ROW) { - string s = reinterpret_cast(sqlite3_column_text(stmt, 0)); - vec.insert(s); - } - - sqlite3_finalize(stmt); - return vec; -} - -std::optional Database::insert(const std::string& sql) { - sqlite3_stmt* stmt = prepareStmt(sql); - if (stmt == nullptr) - return {}; - - if (sqlite3_step(stmt) != SQLITE_DONE) { - CROW_LOG_ERROR << "Insert failed: " << sqlite3_errmsg(m_db); - sqlite3_finalize(stmt); - return {}; - } - - sqlite3_finalize(stmt); - return sqlite3_last_insert_rowid(m_db); -} - -bool Database::open(){ - int rc = sqlite3_open("app.db", &m_db); - if (rc) { - CROW_LOG_ERROR << "Can't open database: " << sqlite3_errmsg(m_db); - return false; - } - return true; -} DatabasePool dbpool(std::thread::hardware_concurrency()); \ No newline at end of file diff --git a/src/database/database.hpp b/src/database/database.hpp index fc48708..94bce4b 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -1,105 +1,40 @@ #ifndef __DATABASE_H__ #define __DATABASE_H__ -#include "sqlite3.h" #include -#include -#include -#include -#include -#include -#include "crow.h" #include "sqlite_orm.h" #include "ShadowrunDb.hpp" +#include "loginDb.hpp" -class Database { - - typedef std::vector> QueryData; - -public: - static constexpr std::string dbFile = "test.db"; - - Database(); - ~Database(); - - bool open(); - bool exec(const char* sqlQuery); - bool exec(const std::string& sqlQuery); - - std::optional insert(const std::string& sql); - - std::set getStrSet(const std::string& sql); - - static std::string currentTime(); - - template - std::optional getSqlData(sqlite3_stmt* stmt, int i) - { - if (stmt == nullptr) - return {}; - - if constexpr (std::is_same_v) { - return sqlite3_column_int64(stmt, i); - } - else if constexpr (std::is_same_v){ - return reinterpret_cast(sqlite3_column_text(stmt, i)); - } - } - - template - std::optional get(const std::string sql, const QueryData& data){ - sqlite3_stmt* stmt = bind(sql, data); - - std::optional ret = getSqlData(stmt, 0); - sqlite3_finalize(stmt); - return ret; - } - - template - std::optional> get(const std::string sql, const QueryData& data){ - sqlite3_stmt* stmt = bind(sql, data); - if ( (stmt == nullptr) || (sqlite3_step(stmt) != SQLITE_ROW ) ) { - CROW_LOG_ERROR << "Failed to run statement: " << sqlite3_errmsg(m_db); - return {}; - } - std::optional v1 = getSqlData(stmt, 0); - std::optional v2 = getSqlData(stmt, 1); - - if (!v1.has_value() || !v2.has_value()) - return {}; - - sqlite3_finalize(stmt); - return std::make_pair(v1.value(), v2.value()); - } - - sqlite3_stmt* bind(const std::string sql, const QueryData& data); - - std::map getStrMap(const std::string sql, const QueryData& data); - -private: - sqlite3_stmt* prepareStmt(const std::string& sql); - - sqlite3* m_db; - -}; - +namespace Database { + static constexpr std::string dbFile = "shadowrun.db"; +} inline auto make_database() { - return sqlite_orm::make_storage(Database::dbFile, + auto storage = sqlite_orm::make_storage(Database::dbFile, + sqlite_orm::make_table("users", + sqlite_orm::make_column("id", &login::User::id, sqlite_orm::primary_key()), + sqlite_orm::make_column("username", &login::User::username, sqlite_orm::unique() ), + sqlite_orm::make_column("salt", &login::User::salt, sqlite_orm::not_null()), + sqlite_orm::make_column("password_hash", &login::User::password_hash, sqlite_orm::not_null()), + sqlite_orm::make_column("created_at", &login::User::created_at, sqlite_orm::default_value("CURRENT_TIMESTAMP")) + ), sqlite_orm::make_table("shadowrun_characters", sqlite_orm::make_column("id", &shadowrun::ShadowrunCharacter::id, sqlite_orm::primary_key()), sqlite_orm::make_column("name", &shadowrun::ShadowrunCharacter::name, sqlite_orm::not_null()), sqlite_orm::make_column("created_at", &shadowrun::ShadowrunCharacter::created_at, sqlite_orm::default_value("CURRENT_TIMESTAMP")) ), - sqlite_orm::make_table("shadowrun_data", - sqlite_orm::make_column("id", &shadowrun::ShadowrunData::id, sqlite_orm::primary_key()), - sqlite_orm::make_column("character_id", &shadowrun::ShadowrunData::character_id, sqlite_orm::not_null()), - sqlite_orm::make_column("name", &shadowrun::ShadowrunData::name, sqlite_orm::not_null()), - sqlite_orm::make_column("value", &shadowrun::ShadowrunData::value), - sqlite_orm::make_column("created_at", &shadowrun::ShadowrunData::created_at, sqlite_orm::default_value("CURRENT_TIMESTAMP")), - sqlite_orm::make_column("updated_at", &shadowrun::ShadowrunData::updated_at, sqlite_orm::default_value("CURRENT_TIMESTAMP")), - sqlite_orm::foreign_key(&shadowrun::ShadowrunData::character_id).references(&shadowrun::ShadowrunCharacter::id).on_delete.cascade() + sqlite_orm::make_table("shadowrun_characters_data", + sqlite_orm::make_column("id", &shadowrun::ShadowrunCharacterData::id, sqlite_orm::primary_key()), + sqlite_orm::make_column("character_id", &shadowrun::ShadowrunCharacterData::character_id, sqlite_orm::not_null()), + sqlite_orm::make_column("type", &shadowrun::ShadowrunCharacterData::type, sqlite_orm::not_null()), + sqlite_orm::make_column("json", &shadowrun::ShadowrunCharacterData::json), + sqlite_orm::make_column("created_at", &shadowrun::ShadowrunCharacterData::created_at, sqlite_orm::default_value("CURRENT_TIMESTAMP")), + sqlite_orm::make_column("updated_at", &shadowrun::ShadowrunCharacterData::updated_at, sqlite_orm::default_value("CURRENT_TIMESTAMP")), + sqlite_orm::foreign_key(&shadowrun::ShadowrunCharacterData::character_id).references(&shadowrun::ShadowrunCharacter::id).on_delete.cascade() )); + + return storage; } #endif // __DATABASE_H__ \ No newline at end of file diff --git a/src/database/databasepool.h b/src/database/databasepool.h index c783763..0b34b47 100644 --- a/src/database/databasepool.h +++ b/src/database/databasepool.h @@ -1,13 +1,17 @@ #include #include -#include #include +#include #include #include "database.hpp" class DatabasePool { public: DatabasePool(size_t size) { + // allow multithreaded access to database + assert(sqlite3_config(SQLITE_CONFIG_MULTITHREAD) == SQLITE_OK); + assert(sqlite3_initialize() == SQLITE_OK); + for (size_t i = 0; i < size; ++i){ auto db = std::make_shared(make_database()); db->sync_schema(); @@ -36,5 +40,4 @@ private: std::condition_variable cv; }; - extern DatabasePool dbpool; \ No newline at end of file diff --git a/src/database/sqlite_orm.h b/src/database/sqlite_orm.h deleted file mode 100644 index a4dac20..0000000 --- a/src/database/sqlite_orm.h +++ /dev/null @@ -1,24841 +0,0 @@ -#pragma once - -#if defined(_MSC_VER) -__pragma(push_macro("min")) -#undef min -__pragma(push_macro("max")) -#undef max -#endif // defined(_MSC_VER) -#pragma once - -#include -#pragma once - -// #include "cxx_universal.h" - -/* - * This header makes central C++ functionality on which sqlite_orm depends universally available: - * - alternative operator representations - * - ::size_t, ::ptrdiff_t, ::nullptr_t - * - C++ core language feature macros - * - macros for dealing with compiler quirks - */ - -#include // alternative operator representations -#include // sqlite_orm is using size_t, ptrdiff_t, nullptr_t everywhere, pull it in early - -// earlier clang versions didn't make nullptr_t available in the global namespace via stddef.h, -// though it should have according to C++ documentation (see https://en.cppreference.com/w/cpp/types/nullptr_t#Notes). -// actually it should be available when including stddef.h -using std::nullptr_t; - -// #include "cxx_core_features.h" - -/* - * This header detects core C++ language features on which sqlite_orm depends. - * May be updated/overwritten by cxx_compiler_quirks.h - */ - -#ifdef __has_cpp_attribute -#define SQLITE_ORM_HAS_CPP_ATTRIBUTE(attr) __has_cpp_attribute(attr) -#else -#define SQLITE_ORM_HAS_CPP_ATTRIBUTE(attr) 0L -#endif - -#ifdef __has_include -#define SQLITE_ORM_HAS_INCLUDE(file) __has_include(file) -#else -#define SQLITE_ORM_HAS_INCLUDE(file) 0L -#endif - -#if __cpp_aggregate_nsdmi >= 201304L -#define SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED -#endif - -#if __cpp_constexpr >= 201304L -#define SQLITE_ORM_RELAXED_CONSTEXPR_SUPPORTED -#endif - -#if __cpp_noexcept_function_type >= 201510L -#define SQLITE_ORM_NOTHROW_ALIASES_SUPPORTED -#endif - -#if __cpp_aggregate_bases >= 201603L -#define SQLITE_ORM_AGGREGATE_BASES_SUPPORTED -#endif - -#if __cpp_fold_expressions >= 201603L -#define SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED -#endif - -#if __cpp_constexpr >= 201603L -#define SQLITE_ORM_CONSTEXPR_LAMBDAS_SUPPORTED -#endif - -#if __cpp_range_based_for >= 201603L -#define SQLITE_ORM_SENTINEL_BASED_FOR_SUPPORTED -#endif - -#if __cpp_if_constexpr >= 201606L -#define SQLITE_ORM_IF_CONSTEXPR_SUPPORTED -#endif - -#if __cpp_inline_variables >= 201606L -#define SQLITE_ORM_INLINE_VARIABLES_SUPPORTED -#endif - -#if __cpp_structured_bindings >= 201606L -#define SQLITE_ORM_STRUCTURED_BINDINGS_SUPPORTED -#endif - -#if __cpp_generic_lambdas >= 201707L -#define SQLITE_ORM_EXPLICIT_GENERIC_LAMBDA_SUPPORTED -#else -#endif - -#if __cpp_init_captures >= 201803L -#define SQLITE_ORM_PACK_EXPANSION_IN_INIT_CAPTURE_SUPPORTED -#endif - -#if __cpp_consteval >= 201811L -#define SQLITE_ORM_CONSTEVAL_SUPPORTED -#endif - -#if __cpp_char8_t >= 201811L -#define SQLITE_ORM_CHAR8T_SUPPORTED -#endif - -#if __cpp_aggregate_paren_init >= 201902L -#define SQLITE_ORM_AGGREGATE_PAREN_INIT_SUPPORTED -#endif - -#if __cpp_concepts >= 201907L -#define SQLITE_ORM_CONCEPTS_SUPPORTED -#endif - -#if __cpp_nontype_template_args >= 201911L -#define SQLITE_ORM_CLASSTYPE_TEMPLATE_ARGS_SUPPORTED -#endif - -#if __cpp_nontype_template_args >= 201911L -#define SQLITE_ORM_CLASSTYPE_TEMPLATE_ARGS_SUPPORTED -#endif - -#if __cpp_pack_indexing >= 202311L -#define SQLITE_ORM_PACK_INDEXING_SUPPORTED -#endif - -#if __cplusplus >= 202002L -#define SQLITE_ORM_DEFAULT_COMPARISONS_SUPPORTED -#endif - -// #include "cxx_compiler_quirks.h" - -/* - * This header defines macros for circumventing compiler quirks on which sqlite_orm depends. - * May amend cxx_core_features.h - */ - -#ifdef __clang__ -#define SQLITE_ORM_DO_PRAGMA(...) _Pragma(#__VA_ARGS__) -#endif - -#ifdef __clang__ -#define SQLITE_ORM_CLANG_SUPPRESS(warnoption, ...) \ - SQLITE_ORM_DO_PRAGMA(clang diagnostic push) \ - SQLITE_ORM_DO_PRAGMA(clang diagnostic ignored warnoption) \ - __VA_ARGS__ \ - SQLITE_ORM_DO_PRAGMA(clang diagnostic pop) - -#else -#define SQLITE_ORM_CLANG_SUPPRESS(warnoption, ...) __VA_ARGS__ -#endif - -// clang has the bad habit of diagnosing missing brace-init-lists when constructing aggregates with base classes. -// This is a false positive, since the C++ standard is quite clear that braces for nested or base objects may be omitted, -// see https://en.cppreference.com/w/cpp/language/aggregate_initialization: -// "The braces around the nested initializer lists may be elided (omitted), -// in which case as many initializer clauses as necessary are used to initialize every member or element of the corresponding subaggregate, -// and the subsequent initializer clauses are used to initialize the following members of the object." -// In this sense clang should only warn about missing field initializers. -// Because we know what we are doing, we suppress the diagnostic message -#define SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES(...) SQLITE_ORM_CLANG_SUPPRESS("-Wmissing-braces", __VA_ARGS__) - -#if defined(_MSC_VER) && (_MSC_VER < 1920) -#define SQLITE_ORM_BROKEN_VARIADIC_PACK_EXPANSION -// Type replacement may fail if an alias template has a non-type template parameter from a dependent expression in it, -// `e.g. template using is_something = std::bool_constant>;` -// Remedy, e.g.: use a derived struct: `template struct is_somthing : std::bool_constant>;` -#define SQLITE_ORM_BROKEN_ALIAS_TEMPLATE_DEPENDENT_NTTP_EXPR -#endif - -// These compilers are known to have problems with alias templates in SFINAE contexts: -// clang 3.5 -// gcc 8.3 -// msvc 15.9 -// Type replacement may fail if an alias template has dependent expression or decltype in it. -// In these cases we have to use helper structures to break down the type alias. -// Note that the detection of specific compilers is so complicated because some compilers emulate other compilers, -// so we simply exclude all compilers that do not support C++20, even though this test is actually inaccurate. -#if (defined(_MSC_VER) && (_MSC_VER < 1920)) || (!defined(_MSC_VER) && (__cplusplus < 202002L)) -#define SQLITE_ORM_BROKEN_ALIAS_TEMPLATE_DEPENDENT_EXPR_SFINAE -#endif - -// overwrite SQLITE_ORM_CLASSTYPE_TEMPLATE_ARGS_SUPPORTED -#if (__cpp_nontype_template_args < 201911L) && \ - (defined(__clang__) && (__clang_major__ >= 12) && (__cplusplus >= 202002L)) -#define SQLITE_ORM_CLASSTYPE_TEMPLATE_ARGS_SUPPORTED -#endif - -// clang 10 chokes on concepts that don't depend on template parameters; -// when it tries to instantiate an expression in a requires expression, which results in an error, -// the compiler reports an error instead of dismissing the templated function. -#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && (defined(__clang__) && (__clang_major__ == 10)) -#define SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS -#endif - -#if SQLITE_ORM_HAS_INCLUDE() -#include -#endif - -#ifdef SQLITE_ORM_CONSTEXPR_LAMBDAS_SUPPORTED -#define SQLITE_ORM_CONSTEXPR_LAMBDA_CPP17 constexpr -#else -#define SQLITE_ORM_CONSTEXPR_LAMBDA_CPP17 -#endif - -#ifdef SQLITE_ORM_INLINE_VARIABLES_SUPPORTED -#define SQLITE_ORM_INLINE_VAR inline -#else -#define SQLITE_ORM_INLINE_VAR -#endif - -#ifdef SQLITE_ORM_IF_CONSTEXPR_SUPPORTED -#define SQLITE_ORM_CONSTEXPR_IF constexpr -#else -#define SQLITE_ORM_CONSTEXPR_IF -#endif - -#if __cpp_lib_constexpr_functional >= 201907L -#define SQLITE_ORM_CONSTEXPR_CPP20 constexpr -#else -#define SQLITE_ORM_CONSTEXPR_CPP20 -#endif - -#if SQLITE_ORM_HAS_CPP_ATTRIBUTE(no_unique_address) >= 201803L -#define SQLITE_ORM_NOUNIQUEADDRESS [[no_unique_address]] -#else -#define SQLITE_ORM_NOUNIQUEADDRESS -#endif - -#if SQLITE_ORM_HAS_CPP_ATTRIBUTE(likely) >= 201803L -#define SQLITE_ORM_CPP_LIKELY [[likely]] -#define SQLITE_ORM_CPP_UNLIKELY [[unlikely]] -#else -#define SQLITE_ORM_CPP_LIKELY -#define SQLITE_ORM_CPP_UNLIKELY -#endif - -#ifdef SQLITE_ORM_CONSTEVAL_SUPPORTED -#define SQLITE_ORM_CONSTEVAL consteval -#else -#define SQLITE_ORM_CONSTEVAL constexpr -#endif - -#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && __cpp_lib_concepts >= 202002L -#define SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED -#endif - -#if __cpp_lib_ranges >= 201911L -#define SQLITE_ORM_CPP20_RANGES_SUPPORTED -#endif - -// C++20 or later (unfortunately there's no feature test macro). -// Stupidly, clang says C++20, but `std::default_sentinel_t` was only implemented in libc++ 13 and libstd++-v3 10 -// (the latter is used on Linux). -// gcc got it right and reports C++20 only starting with v10. -// The check here doesn't care and checks the library versions in use. -// -// Another way of detection might be the feature-test macro __cpp_lib_concepts -#if (__cplusplus >= 202002L) && \ - ((!_LIBCPP_VERSION || _LIBCPP_VERSION >= 13000) && (!_GLIBCXX_RELEASE || _GLIBCXX_RELEASE >= 10)) -#define SQLITE_ORM_STL_HAS_DEFAULT_SENTINEL -#endif - -#if (defined(SQLITE_ORM_CLASSTYPE_TEMPLATE_ARGS_SUPPORTED) && defined(SQLITE_ORM_INLINE_VARIABLES_SUPPORTED) && \ - defined(SQLITE_ORM_CONSTEVAL_SUPPORTED)) && \ - (defined(SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED)) -#define SQLITE_ORM_WITH_CPP20_ALIASES -#endif - -#if defined(SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED) && defined(SQLITE_ORM_IF_CONSTEXPR_SUPPORTED) -#define SQLITE_ORM_WITH_CTE -#endif - -// define the inline namespace "literals" so that it is available even if it was not introduced by a feature -namespace sqlite_orm { - inline namespace literals {} -} -#pragma once - -#include -#include // std::unique_ptr/shared_ptr, std::make_unique -#include // std::system_error -#include // std::string -#include // std::remove_reference, std::remove_cvref, std::decay -#include // std::identity -#include // std::stringstream -#include // std::flush -#include // std::map -#include // std::vector -#include // std::tuple_size, std::tuple, std::make_tuple, std::tie -#include // std::forward, std::pair -#include // std::for_each, std::ranges::for_each -// #include "functional/cxx_optional.h" - -// #include "cxx_core_features.h" - -#if SQLITE_ORM_HAS_INCLUDE() -#include -#endif - -#if __cpp_lib_optional >= 201606L -#define SQLITE_ORM_OPTIONAL_SUPPORTED -#endif - -// #include "functional/cxx_type_traits_polyfill.h" - -#include - -// #include "mpl/conditional.h" - -namespace sqlite_orm { - namespace internal { - namespace mpl { - - /* - * Binary quoted metafunction equivalent to `std::conditional`, - * using an improved implementation in respect to memoization. - * - * Because `conditional` is only typed on a single bool non-type template parameter, - * the compiler only ever needs to memoize 2 instances of this class template. - * The type selection is a nested cheap alias template. - */ - template - struct conditional { - template - using fn = A; - }; - - template<> - struct conditional { - template - using fn = B; - }; - - // directly invoke `conditional` - template - using conditional_t = typename conditional::template fn; - } - } - - namespace mpl = internal::mpl; -} - -namespace sqlite_orm { - namespace internal { - namespace polyfill { -#if __cpp_lib_void_t >= 201411L - using std::void_t; -#else - /* - * Implementation note: Conservative implementation due to CWG issue 1558 (Unused arguments in alias template specializations). - */ - template - struct always_void { - using type = void; - }; - template - using void_t = typename always_void::type; -#endif - -#if __cpp_lib_bool_constant >= 201505L - using std::bool_constant; -#else - template - using bool_constant = std::integral_constant; -#endif - -#if __cpp_lib_logical_traits >= 201510L && __cpp_lib_type_trait_variable_templates >= 201510L - using std::conjunction; - using std::conjunction_v; - using std::disjunction; - using std::disjunction_v; - using std::negation; - using std::negation_v; -#else - template - struct conjunction : std::true_type {}; - template - struct conjunction : B1 {}; - template - struct conjunction : mpl::conditional_t, B1> {}; - template - SQLITE_ORM_INLINE_VAR constexpr bool conjunction_v = conjunction::value; - - template - struct disjunction : std::false_type {}; - template - struct disjunction : B1 {}; - template - struct disjunction : mpl::conditional_t> {}; - template - SQLITE_ORM_INLINE_VAR constexpr bool disjunction_v = disjunction::value; - - template - struct negation : bool_constant {}; - template - SQLITE_ORM_INLINE_VAR constexpr bool negation_v = negation::value; -#endif - -#if __cpp_lib_remove_cvref >= 201711L - using std::remove_cvref, std::remove_cvref_t; -#else - template - struct remove_cvref : std::remove_cv> {}; - - template - using remove_cvref_t = typename remove_cvref::type; -#endif - -#if __cpp_lib_type_identity >= 201806L - using std::type_identity, std::type_identity_t; -#else - template - struct type_identity { - using type = T; - }; - - template - using type_identity_t = typename type_identity::type; -#endif - -#if 0 // __cpp_lib_detect >= 0L // library fundamentals TS v2, [meta.detect] - using std::nonesuch; - using std::detector; - using std::is_detected, std::is_detected_v; - using std::detected, std::detected_t; - using std::detected_or, std::detected_or_t; -#else - struct nonesuch { - ~nonesuch() = delete; - nonesuch(const nonesuch&) = delete; - void operator=(const nonesuch&) = delete; - }; - - template class Op, class... Args> - struct detector { - using value_t = std::false_type; - using type = Default; - }; - - template class Op, class... Args> - struct detector>, Op, Args...> { - using value_t = std::true_type; - using type = Op; - }; - - template class Op, class... Args> - using is_detected = typename detector::value_t; - - template class Op, class... Args> - using detected = detector; - - template class Op, class... Args> - using detected_t = typename detector::type; - - template class Op, class... Args> - using detected_or = detector; - - template class Op, class... Args> - using detected_or_t = typename detected_or::type; - - template class Op, class... Args> - SQLITE_ORM_INLINE_VAR constexpr bool is_detected_v = is_detected::value; -#endif - -#if 0 // proposed but not pursued - using std::is_specialization_of, std::is_specialization_of_t, std::is_specialization_of_v; -#else - // is_specialization_of: https://github.com/cplusplus/papers/issues/812 - - template class Primary> - SQLITE_ORM_INLINE_VAR constexpr bool is_specialization_of_v = false; - - template class Primary, class... Types> - SQLITE_ORM_INLINE_VAR constexpr bool is_specialization_of_v, Primary> = true; - - template class Primary> - struct is_specialization_of : bool_constant> {}; -#endif - - template - SQLITE_ORM_INLINE_VAR constexpr bool always_false_v = false; - - template - using index_constant = std::integral_constant; - } - } - - namespace polyfill = internal::polyfill; -} - -// #include "functional/cxx_functional_polyfill.h" - -#include -#if __cpp_lib_invoke < 201411L -#include // std::enable_if, std::is_member_object_pointer, std::is_member_function_pointer -#endif -#include // std::forward - -// #include "cxx_type_traits_polyfill.h" - -// #include "../member_traits/member_traits.h" - -#include // std::enable_if, std::is_function, std::true_type, std::false_type - -// #include "../functional/cxx_type_traits_polyfill.h" - -namespace sqlite_orm { - namespace internal { - // SFINAE friendly trait to get a member object pointer's field type - template - struct object_field_type {}; - - template - using object_field_type_t = typename object_field_type::type; - - template - struct object_field_type : std::enable_if::value, F> {}; - - // SFINAE friendly trait to get a member function pointer's field type (i.e. unqualified return type) - template - struct getter_field_type {}; - - template - using getter_field_type_t = typename getter_field_type::type; - - template - struct getter_field_type : getter_field_type {}; - - template - struct getter_field_type : polyfill::remove_cvref {}; - - template - struct getter_field_type : polyfill::remove_cvref {}; - -#ifdef SQLITE_ORM_NOTHROW_ALIASES_SUPPORTED - template - struct getter_field_type : polyfill::remove_cvref {}; - - template - struct getter_field_type : polyfill::remove_cvref {}; -#endif - - // SFINAE friendly trait to get a member function pointer's field type (i.e. unqualified parameter type) - template - struct setter_field_type {}; - - template - using setter_field_type_t = typename setter_field_type::type; - - template - struct setter_field_type : setter_field_type {}; - - template - struct setter_field_type : polyfill::remove_cvref {}; - -#ifdef SQLITE_ORM_NOTHROW_ALIASES_SUPPORTED - template - struct setter_field_type : polyfill::remove_cvref {}; -#endif - - template - struct is_getter : std::false_type {}; - template - struct is_getter>> : std::true_type {}; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_getter_v = is_getter::value; - - template - struct is_setter : std::false_type {}; - template - struct is_setter>> : std::true_type {}; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_setter_v = is_setter::value; - - template - struct member_field_type : object_field_type, getter_field_type, setter_field_type {}; - - template - using member_field_type_t = typename member_field_type::type; - - template - struct member_object_type {}; - - template - struct member_object_type : polyfill::type_identity {}; - - template - using member_object_type_t = typename member_object_type::type; - } -} - -namespace sqlite_orm { - namespace internal { - namespace polyfill { - // C++20 or later (unfortunately there's no feature test macro). - // Stupidly, clang says C++20, but `std::identity` was only implemented in libc++ 13 and libstd++-v3 10 - // (the latter is used on Linux). - // gcc got it right and reports C++20 only starting with v10. - // The check here doesn't care and checks the library versions in use. - // - // Another way of detection would be the constrained algorithms feature-test macro __cpp_lib_ranges -#if (__cplusplus >= 202002L) && \ - ((!_LIBCPP_VERSION || _LIBCPP_VERSION >= 13000) && (!_GLIBCXX_RELEASE || _GLIBCXX_RELEASE >= 10)) - using std::identity; -#else - struct identity { - template - constexpr T&& operator()(T&& v) const noexcept { - return std::forward(v); - } - - using is_transparent = int; - }; -#endif - -#if __cpp_lib_invoke >= 201411L - using std::invoke; -#else - // pointer-to-data-member+object - template, - std::enable_if_t::value, bool> = true> - decltype(auto) invoke(Callable&& callable, Object&& object, Args&&... args) { - return std::forward(object).*callable; - } - - // pointer-to-member-function+object - template, - std::enable_if_t::value, bool> = true> - decltype(auto) invoke(Callable&& callable, Object&& object, Args&&... args) { - return (std::forward(object).*callable)(std::forward(args)...); - } - - // pointer-to-member+reference-wrapped object (expect `reference_wrapper::*`) - template>, - std::reference_wrapper>>::value, - bool> = true> - decltype(auto) invoke(Callable&& callable, std::reference_wrapper wrapper, Args&&... args) { - return invoke(std::forward(callable), wrapper.get(), std::forward(args)...); - } - - // functor - template - decltype(auto) invoke(Callable&& callable, Args&&... args) { - return std::forward(callable)(std::forward(args)...); - } -#endif - } - } - - namespace polyfill = internal::polyfill; -} - -// #include "functional/static_magic.h" - -#ifndef SQLITE_ORM_IF_CONSTEXPR_SUPPORTED -#include // std::false_type, std::true_type, std::integral_constant -#endif -#include // std::forward - -namespace sqlite_orm { - - // got from here - // https://stackoverflow.com/questions/37617677/implementing-a-compile-time-static-if-logic-for-different-string-types-in-a-co - namespace internal { - - // note: this is a class template accompanied with a variable template because older compilers (e.g. VC 2017) - // cannot handle a static lambda variable inside a template function - template - struct empty_callable_t { - template - R operator()(Args&&...) const { - return R(); - } - }; - template - constexpr empty_callable_t empty_callable{}; - -#ifdef SQLITE_ORM_IF_CONSTEXPR_SUPPORTED - template - decltype(auto) static_if([[maybe_unused]] T&& trueFn, [[maybe_unused]] F&& falseFn) { - if constexpr (B) { - return std::forward(trueFn); - } else { - return std::forward(falseFn); - } - } - - template - decltype(auto) static_if([[maybe_unused]] T&& trueFn) { - if constexpr (B) { - return std::forward(trueFn); - } else { - return empty_callable<>; - } - } - - template - void call_if_constexpr([[maybe_unused]] L&& lambda, [[maybe_unused]] Args&&... args) { - if constexpr (B) { - lambda(std::forward(args)...); - } - } -#else - template - decltype(auto) static_if(std::true_type, T&& trueFn, const F&) { - return std::forward(trueFn); - } - - template - decltype(auto) static_if(std::false_type, const T&, F&& falseFn) { - return std::forward(falseFn); - } - - template - decltype(auto) static_if(T&& trueFn, F&& falseFn) { - return static_if(std::integral_constant{}, std::forward(trueFn), std::forward(falseFn)); - } - - template - decltype(auto) static_if(T&& trueFn) { - return static_if(std::integral_constant{}, std::forward(trueFn), empty_callable<>); - } - - template - void call_if_constexpr(L&& lambda, Args&&... args) { - static_if(std::forward(lambda))(std::forward(args)...); - } -#endif - } - -} - -// #include "functional/mpl.h" - -/* - * Symbols for 'template metaprogramming' (compile-time template programming), - * inspired by the MPL of Aleksey Gurtovoy and David Abrahams, and the Mp11 of Peter Dimov and Bjorn Reese. - * - * Currently, the focus is on facilitating advanced type filtering, - * such as filtering columns by constraints having various traits. - * Hence it contains only a very small subset of a full MPL. - * - * Three key concepts are critical to understanding: - * 1. A 'trait' is a class template with a nested `type` typename. - * The term 'trait' might be too narrow or not entirely accurate, however in the STL those class templates are summarized as "Type transformations". - * hence being "transformation type traits". - * It was the traditional way of transforming types before the arrival of alias templates. - * E.g. `template struct x { using type = T; };` - * They are of course still available today, but are rather used as building blocks. - * 2. A 'metafunction' is an alias template for a class template or a nested template expression, whose instantiation yields a type. - * E.g. `template using alias_op_t = typename x::type` - * 3. A 'quoted metafunction' (aka 'metafunction class') is a certain form of metafunction representation that enables higher-order metaprogramming. - * More precisely, it's a class with a nested metafunction called "fn". - * Correspondingly, a quoted metafunction invocation is defined as invocation of its nested "fn" metafunction. - * - * Conventions: - * - "Fn" is the name of a template template parameter for a metafunction. - * - "Q" is the name of class template parameter for a quoted metafunction. - * - "_fn" is a suffix for a class or alias template that accepts metafunctions and turns them into quoted metafunctions. - * - "higher order" denotes a metafunction that operates on another metafunction (i.e. takes it as an argument). - */ - -#include // std::true_type, std::false_type, std::is_same, std::negation, std::conjunction, std::disjunction -#ifdef SQLITE_ORM_RELAXED_CONSTEXPR_SUPPORTED -#include -#else -#include -#endif - -// #include "cxx_type_traits_polyfill.h" - -// #include "mpl/conditional.h" - -namespace sqlite_orm { - namespace internal { - namespace mpl { - template class Fn> - struct indirectly_test_metafunction; - - /* - * Determines whether a class template has a nested metafunction `fn`. - * - * Implementation note: the technique of specialiazing on the inline variable must come first because - * of older compilers having problems with the detection of dependent templates [SQLITE_ORM_BROKEN_ALIAS_TEMPLATE_DEPENDENT_EXPR_SFINAE]. - */ - template - SQLITE_ORM_INLINE_VAR constexpr bool is_quoted_metafuntion_v = false; - template - SQLITE_ORM_INLINE_VAR constexpr bool - is_quoted_metafuntion_v>> = true; - - template - struct is_quoted_metafuntion : polyfill::bool_constant> {}; - - /* - * Type pack. - */ - template - struct pack {}; - - /* - * The indirection through `defer_fn` works around the language inability - * to expand `Args...` into a fixed parameter list of an alias template. - * - * Also, legacy compilers need an extra layer of indirection, otherwise type replacement may fail - * if alias template `Fn` has a dependent expression in it. - */ - template class Fn, class... Args> - struct defer_fn { - using type = Fn; - }; - - /* - * The indirection through `defer` works around the language inability - * to expand `Args...` into a fixed parameter list of an alias template. - */ - template - struct defer { - using type = typename Q::template fn; - }; - - /* - * Invoke metafunction. - */ - template class Fn, class... Args> - using invoke_fn_t = typename defer_fn::type; - - /* - * Invoke quoted metafunction by invoking its nested metafunction. - */ - template - using invoke_t = typename defer::type; - - /* - * Turn metafunction into a quoted metafunction. - * - * Invocation of the nested metafunction `fn` is SFINAE-friendly (detection idiom). - * This is necessary because `fn` is a proxy to the originally quoted metafunction, - * and the instantiation of the metafunction might be an invalid expression. - */ - template class Fn> - struct quote_fn { - template class, class...> - struct invoke_this_fn { - // error N: 'type': is not a member of any direct or indirect base class of 'quote_fn::invoke_this_fn' - // means that the metafunction cannot be called with the passed arguments. - }; - - template class F, class... Args> - struct invoke_this_fn>, F, Args...> { - using type = F; - }; - - template - using fn = typename invoke_this_fn::type; - }; - - /* - * Indirection wrapper for higher-order metafunctions, - * specialized on the argument indexes where metafunctions appear. - */ - template - struct higherorder; - - template<> - struct higherorder<0u> { - template class Fn, class... Args2> class HigherFn, class Q, class... Args> - struct defer_higher_fn { - using type = HigherFn; - }; - - /* - * Turn higher-order metafunction into a quoted metafunction. - */ - template class Fn, class... Args2> class HigherFn> - struct quote_fn { - template - using fn = typename defer_higher_fn::type; - }; - }; - - /* - * Quoted metafunction that extracts the nested metafunction of its quoted metafunction argument, - * quotes the extracted metafunction and passes it on to the next quoted metafunction - * (kind of the inverse of quoting). - */ - template - struct pass_extracted_fn_to { - template - struct invoke_this_fn { - using type = typename Q::template fn; - }; - - // extract class template, quote, pass on - template class Fn, class... T> - struct invoke_this_fn> { - using type = typename Q::template fn>; - }; - - template - using fn = typename invoke_this_fn::type; - }; - - /* - * Quoted metafunction that invokes the specified quoted metafunctions, - * and passes their results on to the next quoted metafunction. - */ - template - struct pass_result_of { - // invoke `Fn`, pass on their result - template - using fn = typename Q::template fn::type...>; - }; - - /* - * Quoted metafunction that invokes the specified metafunctions, - * and passes their results on to the next quoted metafunction. - */ - template class... Fn> - using pass_result_of_fn = pass_result_of...>; - - /* - * Bind arguments at the front of a quoted metafunction. - */ - template - struct bind_front { - template - using fn = typename Q::template fn; - }; - - /* - * Bind arguments at the back of a quoted metafunction. - */ - template - struct bind_back { - template - using fn = typename Q::template fn; - }; - - /* - * Quoted metafunction equivalent to `polyfill::always_false`. - * It ignores arguments passed to the metafunction, and always returns the specified type. - */ - template - struct always { - template - using fn = T; - }; - - /* - * Unary quoted metafunction equivalent to `std::type_identity_t`. - */ - using identity = quote_fn; - - /* - * Quoted metafunction equivalent to `std::negation`. - */ - template - using not_ = pass_result_of, TraitQ>; - - /* - * Quoted metafunction equivalent to `std::conjunction`. - */ - template - struct conjunction { - template - using fn = std::true_type; - }; - - template - struct conjunction { - // match last or `std::false_type` - template - struct invoke_this_fn { - static_assert(std::is_same::value || - std::is_same::value, - "Resulting trait must be a std::bool_constant"); - using type = ResultTrait; - }; - - // match `std::true_type` and one or more remaining - template - struct invoke_this_fn, std::true_type, NextQ, RestQ...> - : invoke_this_fn, - // access resulting trait::type - typename defer::type::type, - RestQ...> {}; - - template - using fn = typename invoke_this_fn, - // access resulting trait::type - typename defer::type::type, - TraitQ...>::type; - }; - - /* - * Quoted metafunction equivalent to `std::disjunction`. - */ - template - struct disjunction { - template - using fn = std::false_type; - }; - - template - struct disjunction { - // match last or `std::true_type` - template - struct invoke_this_fn { - static_assert(std::is_same::value || - std::is_same::value, - "Resulting trait must be a std::bool_constant"); - using type = ResultTrait; - }; - - // match `std::false_type` and one or more remaining - template - struct invoke_this_fn, std::false_type, NextQ, RestQ...> - : invoke_this_fn, - // access resulting trait::type - typename defer::type::type, - RestQ...> {}; - - template - using fn = typename invoke_this_fn, - // access resulting trait::type - typename defer::type::type, - TraitQ...>::type; - }; - - /* - * Metafunction equivalent to `std::conjunction`. - */ - template class... TraitFn> - using conjunction_fn = pass_result_of_fn, TraitFn...>; - - /* - * Metafunction equivalent to `std::disjunction`. - */ - template class... TraitFn> - using disjunction_fn = pass_result_of_fn, TraitFn...>; - - /* - * Metafunction equivalent to `std::negation`. - */ - template class Fn> - using not_fn = pass_result_of_fn, Fn>; - - /* - * Bind arguments at the front of a metafunction. - */ - template class Fn, class... Bound> - using bind_front_fn = bind_front, Bound...>; - - /* - * Bind arguments at the back of a metafunction. - */ - template class Fn, class... Bound> - using bind_back_fn = bind_back, Bound...>; - - /* - * Bind a metafunction and arguments at the front of a higher-order metafunction. - */ - template class Fn, class... Args2> class HigherFn, - template class BoundFn, - class... Bound> - using bind_front_higherorder_fn = - bind_front::quote_fn, quote_fn, Bound...>; - -#ifdef SQLITE_ORM_RELAXED_CONSTEXPR_SUPPORTED - constexpr size_t find_first_true_helper(std::initializer_list values) { - size_t i = 0; - for (auto first = values.begin(); first != values.end() && !*first; ++first) { - ++i; - } - return i; - } - - constexpr size_t count_true_helper(std::initializer_list values) { - size_t n = 0; - for (auto first = values.begin(); first != values.end(); ++first) { - n += *first; - } - return n; - } -#else - template - constexpr size_t find_first_true_helper(const std::array& values, size_t i = 0) { - return i == N || values[i] ? 0 : 1 + find_first_true_helper(values, i + 1); - } - - template - constexpr size_t count_true_helper(const std::array& values, size_t i = 0) { - return i == N ? 0 : values[i] + count_true_helper(values, i + 1); - } -#endif - - /* - * Quoted metafunction that invokes the specified quoted predicate metafunction on each element of a type list, - * and returns the index constant of the first element for which the predicate returns true. - */ - template - struct finds { - template - struct invoke_this_fn { - static_assert(polyfill::always_false_v, - "`finds` must be invoked with a type list as first argument."); - }; - - template class Pack, class... T, class ProjectQ> - struct invoke_this_fn, ProjectQ> { - // hoist result into `value` [SQLITE_ORM_BROKEN_ALIAS_TEMPLATE_DEPENDENT_NTTP_EXPR] - static constexpr size_t value = find_first_true_helper -#ifndef SQLITE_ORM_RELAXED_CONSTEXPR_SUPPORTED - -#endif - ({PredicateQ::template fn>::value...}); - using type = polyfill::index_constant; - }; - - template - using fn = typename invoke_this_fn::type; - }; - - template class PredicateFn> - using finds_fn = finds>; - - /* - * Quoted metafunction that invokes the specified quoted predicate metafunction on each element of a type list, - * and returns the index constant of the first element for which the predicate returns true. - */ - template - struct counts { - template - struct invoke_this_fn { - static_assert(polyfill::always_false_v, - "`counts` must be invoked with a type list as first argument."); - }; - - template class Pack, class... T, class ProjectQ> - struct invoke_this_fn, ProjectQ> { - // hoist result into `value` [SQLITE_ORM_BROKEN_ALIAS_TEMPLATE_DEPENDENT_NTTP_EXPR] - static constexpr size_t value = count_true_helper -#ifndef SQLITE_ORM_RELAXED_CONSTEXPR_SUPPORTED - -#endif - ({PredicateQ::template fn>::value...}); - using type = polyfill::index_constant; - }; - - template - using fn = typename invoke_this_fn::type; - }; - - template class PredicateFn> - using counts_fn = counts>; - - /* - * Quoted metafunction that invokes the specified quoted predicate metafunction on each element of a type list, - * and returns the index constant of the first element for which the predicate returns true. - */ - template - struct contains { - template - struct invoke_this_fn { - static_assert(polyfill::always_false_v, - "`contains` must be invoked with a type list as first argument."); - }; - - template class Pack, class... T, class ProjectQ> - struct invoke_this_fn, ProjectQ> { - // hoist result into `value` [SQLITE_ORM_BROKEN_ALIAS_TEMPLATE_DEPENDENT_NTTP_EXPR] - static constexpr size_t value = - static_cast(count_true_helper -#ifndef SQLITE_ORM_RELAXED_CONSTEXPR_SUPPORTED - -#endif - ({TraitQ::template fn>::value...})); - using type = polyfill::bool_constant; - }; - - template - using fn = typename invoke_this_fn::type; - }; - - template class TraitFn> - using contains_fn = contains>; - } - } - - namespace mpl = internal::mpl; - - // convenience quoted metafunctions - namespace internal { - /* - * Quoted trait metafunction that checks if a type has the specified trait. - */ - template class TraitFn, class... Bound> - using check_if = - mpl::conditional_t, mpl::bind_front_fn>; - - /* - * Quoted trait metafunction that checks if a type doesn't have the specified trait. - */ - template class TraitFn> - using check_if_not = mpl::not_fn; - - /* - * Quoted trait metafunction that checks if a type is the same as the specified type. - * Commonly used named abbreviation for `check_if`. - */ - template - using check_if_is_type = mpl::bind_front_fn; - - /* - * Quoted trait metafunction that checks if a type's template matches the specified template - * (similar to `is_specialization_of`). - */ - template class Template> - using check_if_is_template = - mpl::pass_extracted_fn_to>>; - - /* - * Quoted metafunction that finds the index of the given type in a tuple. - */ - template - using finds_if_has_type = mpl::finds>; - - /* - * Quoted metafunction that finds the index of the given class template in a tuple. - */ - template class Template> - using finds_if_has_template = mpl::finds>; - - /* - * Quoted trait metafunction that counts tuple elements having a given trait. - */ - template class TraitFn> - using counts_if_has = mpl::counts_fn; - - /* - * Quoted trait metafunction that checks whether a tuple contains a type with given trait. - */ - template class TraitFn> - using check_if_has = mpl::contains_fn; - - /* - * Quoted trait metafunction that checks whether a tuple doesn't contain a type with given trait. - */ - template class TraitFn> - using check_if_has_not = mpl::not_>; - - /* - * Quoted metafunction that checks whether a tuple contains given type. - */ - template - using check_if_has_type = mpl::contains>; - - /* - * Quoted metafunction that checks whether a tuple contains a given template. - * - * Note: we are using 2 small tricks: - * 1. A template template parameter can be treated like a metafunction, so we can just "quote" a 'primary' - * template into the MPL system (e.g. `std::vector`). - * 2. This quoted metafunction does the opposite of the trait metafunction `is_specialization`: - * `is_specialization` tries to instantiate the primary template template parameter using the - * template parameters of a template type, then compares both instantiated types. - * Here instead, `pass_extracted_fn_to` extracts the template template parameter from a template type, - * then compares the resulting template template parameters. - */ - template class Template> - using check_if_has_template = mpl::contains>; - } -} - -// #include "tuple_helper/tuple_traits.h" - -// #include "../functional/cxx_type_traits_polyfill.h" - -// #include "../functional/mpl.h" - -namespace sqlite_orm { - // convenience metafunction algorithms - namespace internal { - /* - * Higher-order trait metafunction that checks whether a tuple contains a type with given trait (possibly projected). - * - * `ProjOp` is a metafunction - */ - template class TraitFn, - template class ProjOp = polyfill::type_identity_t> - using tuple_has = mpl::invoke_t, Pack, mpl::quote_fn>; - - /* - * Higher-order trait metafunction that checks whether a tuple contains the specified type (possibly projected). - * - * `ProjOp` is a metafunction - */ - template class ProjOp = polyfill::type_identity_t> - using tuple_has_type = mpl::invoke_t, Pack, mpl::quote_fn>; - - /* - * Higher-order trait metafunction that checks whether a tuple contains the specified class template (possibly projected). - * - * `ProjOp` is a metafunction - */ - template class Template, - template class ProjOp = polyfill::type_identity_t> - using tuple_has_template = mpl::invoke_t, Pack, mpl::quote_fn>; - - /* - * Higher-order metafunction returning the first index constant of the desired type in a tuple (possibly projected). - */ - template class ProjOp = polyfill::type_identity_t> - using find_tuple_type = mpl::invoke_t, Pack, mpl::quote_fn>; - - /* - * Higher-order metafunction returning the first index constant of the desired class template in a tuple (possibly projected). - * - * `ProjOp` is a metafunction - */ - template class Template, - template class ProjOp = polyfill::type_identity_t> - using find_tuple_template = mpl::invoke_t, Pack, mpl::quote_fn>; - - /* - * Higher-order trait metafunction that counts the types having the specified trait in a tuple (possibly projected). - * - * `Pred` is a predicate metafunction with a nested bool member named `value` - * `ProjOp` is a metafunction - */ - template class Pred, template class ProjOp = polyfill::type_identity_t> - using count_tuple = mpl::invoke_t, Pack, mpl::quote_fn>; - } -} - -// #include "tuple_helper/tuple_filter.h" - -#include // std::integral_constant, std::index_sequence, std::conditional, std::declval -#include // std::tuple, std::tuple_cat, std::tuple_element - -// #include "../functional/mpl/conditional.h" - -// #include "../functional/index_sequence_util.h" - -#include // std::index_sequence - -namespace sqlite_orm { - namespace internal { -#if defined(SQLITE_ORM_PACK_INDEXING_SUPPORTED) - /** - * Get the index value of an `index_sequence` at a specific position. - */ - template - SQLITE_ORM_CONSTEVAL auto index_sequence_value_at(std::index_sequence) { - return Idx...[Pos]; - } -#elif defined(SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED) - /** - * Get the index value of an `index_sequence` at a specific position. - */ - template - SQLITE_ORM_CONSTEVAL size_t index_sequence_value_at(std::index_sequence) { - static_assert(Pos < sizeof...(Idx)); -#ifdef SQLITE_ORM_CONSTEVAL_SUPPORTED - size_t result; -#else - size_t result = 0; -#endif - size_t i = 0; - // note: `(void)` cast silences warning 'expression result unused' - (void)((result = Idx, i++ == Pos) || ...); - return result; - } -#else - /** - * Get the index value of an `index_sequence` at a specific position. - * `Pos` must always be `0`. - */ - template - SQLITE_ORM_CONSTEVAL size_t index_sequence_value_at(std::index_sequence) { - static_assert(Pos == 0, ""); - return I; - } -#endif - - template - struct flatten_idxseq { - using type = std::index_sequence<>; - }; - - template - struct flatten_idxseq> { - using type = std::index_sequence; - }; - - template - struct flatten_idxseq, std::index_sequence, Seq...> - : flatten_idxseq, Seq...> {}; - - template - using flatten_idxseq_t = typename flatten_idxseq::type; - } -} - -namespace sqlite_orm { - namespace internal { - - template - using tuple_cat_t = decltype(std::tuple_cat(std::declval()...)); - - template - struct conc_tuple { - using type = tuple_cat_t; - }; - - template - struct tuple_from_index_sequence; - - template - struct tuple_from_index_sequence> { - using type = std::tuple...>; - }; - - template - using tuple_from_index_sequence_t = typename tuple_from_index_sequence::type; - - template class Pred, template class Proj, class Seq> - struct filter_tuple_sequence; - -#ifndef SQLITE_ORM_BROKEN_VARIADIC_PACK_EXPANSION - template class Pred, template class Proj, size_t... Idx> - struct filter_tuple_sequence> - : flatten_idxseq>>::value, - std::index_sequence, - std::index_sequence<>>...> {}; -#else - template class Pred, class SFINAE = void> - struct tuple_seq_single { - using type = std::index_sequence<>; - }; - - template class Pred> - struct tuple_seq_single::value>> { - using type = std::index_sequence; - }; - - template class Pred, template class Proj, size_t... Idx> - struct filter_tuple_sequence> - : flatten_idxseq>, - Pred>::type...> {}; -#endif - - /* - * `Pred` is a metafunction that defines a bool member named `value` - * `FilterProj` is a metafunction - */ - template class Pred, - template class FilterProj = polyfill::type_identity_t, - class Seq = std::make_index_sequence::value>> - using filter_tuple_sequence_t = typename filter_tuple_sequence::type; - - /* - * `Pred` is a metafunction that defines a bool member named `value` - * `FilterProj` is a metafunction - */ - template class Pred, - template class FilterProj = polyfill::type_identity_t, - class Seq = std::make_index_sequence::value>> - using filter_tuple_t = tuple_from_index_sequence_t>; - - /* - * Count a tuple, picking only those elements specified in the index sequence. - * - * `Pred` is a metafunction that defines a bool member named `value` - * `FilterProj` is a metafunction - * - * Implementation note: must be distinct from a `count_tuple` w/o index sequence parameter because legacy compilers have problems - * with a default Sequence in function template parameters [SQLITE_ORM_BROKEN_VARIADIC_PACK_EXPANSION]. - */ - template class Pred, - class Seq, - template class FilterProj = polyfill::type_identity_t> - struct count_filtered_tuple - : std::integral_constant::size()> {}; - } -} - -// #include "tuple_helper/tuple_transformer.h" - -#include // std::remove_reference, std::common_type, std::index_sequence, std::make_index_sequence, std::forward, std::move, std::integral_constant, std::declval -#include // std::tuple_size, std::get - -// #include "../functional/cxx_type_traits_polyfill.h" - -// #include "../functional/cxx_functional_polyfill.h" - -// #include "../functional/mpl.h" - -namespace sqlite_orm { - namespace internal { - - template class Op> - struct tuple_transformer; - - template class Pack, class... Types, template class Op> - struct tuple_transformer, Op> { - using type = Pack...>; - }; - - /* - * Transform specified tuple. - * - * `Op` is a metafunction. - */ - template class Op> - using transform_tuple_t = typename tuple_transformer::type; - - // note: applying a combiner like `plus_fold_integrals` needs fold expressions -#if defined(SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED) - /* - * Apply a projection to a tuple's elements filtered by the specified indexes, and combine the results. - * - * @note It's a glorified version of `std::apply()` and a variant of `std::accumulate()`. - * It combines filtering the tuple (indexes), transforming the elements (projection) and finally applying the callable (combine). - * - * @note `project` is called using `std::invoke`, which is `constexpr` since C++20. - */ - template - SQLITE_ORM_CONSTEXPR_CPP20 auto recombine_tuple(CombineOp combine, - const Tpl& tpl, - std::index_sequence, - Projector project, - Init initial) { - return combine(initial, polyfill::invoke(project, std::get(tpl))...); - } - - /* - * Apply a projection to a tuple's elements, and combine the results. - * - * @note It's a glorified version of `std::apply()` and a variant of `std::accumulate()`. - * It combines filtering the tuple (indexes), transforming the elements (projection) and finally applying the callable (combine). - * - * @note `project` is called using `std::invoke`, which is `constexpr` since C++20. - */ - template - SQLITE_ORM_CONSTEXPR_CPP20 auto - recombine_tuple(CombineOp combine, const Tpl& tpl, Projector project, Init initial) { - return recombine_tuple(std::move(combine), - std::forward(tpl), - std::make_index_sequence::value>{}, - std::move(project), - std::move(initial)); - } - - /* - * Function object that takes integral constants and returns the sum of their values as an integral constant. - * Because it's a "transparent" functor, it must be called with at least one argument, otherwise it cannot deduce the integral constant type. - */ - struct plus_fold_integrals { - template - constexpr auto operator()(const Integrals&...) const { - using integral_type = std::common_type_t; - return std::integral_constant{}; - } - }; - - /* - * Function object that takes a type, applies a projection on it, and returns the tuple size of the projected type (as an integral constant). - * The projection is applied on the argument type, not the argument value/object. - */ - template class NestedProject> - struct project_nested_tuple_size { - template - constexpr auto operator()(const T&) const { - return typename std::tuple_size>::type{}; - } - }; - - template class NestedProject, class Tpl, class IdxSeq> - using nested_tuple_size_for_t = decltype(recombine_tuple(plus_fold_integrals{}, - std::declval(), - IdxSeq{}, - project_nested_tuple_size{}, - std::integral_constant{})); -#endif - - template - constexpr R create_from_tuple(Tpl&& tpl, std::index_sequence, Projection project = {}) { - return R{polyfill::invoke(project, std::get(std::forward(tpl)))...}; - } - - /* - * Like `std::make_from_tuple`, but using a projection on the tuple elements. - */ - template - constexpr R create_from_tuple(Tpl&& tpl, Projection project = {}) { - return create_from_tuple( - std::forward(tpl), - std::make_index_sequence>::value>{}, - std::forward(project)); - } - } -} - -// #include "tuple_helper/tuple_iteration.h" - -#include // std::get, std::tuple_element, std::tuple_size -#include // std::index_sequence, std::make_index_sequence -#include // std::forward, std::move - -namespace sqlite_orm { - namespace internal { -#if defined(SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED) && defined(SQLITE_ORM_IF_CONSTEXPR_SUPPORTED) - template - constexpr void iterate_tuple(Tpl& tpl, std::index_sequence, L&& lambda) { - if constexpr (reversed) { - // nifty fold expression trick: make use of guaranteed right-to-left evaluation order when folding over operator= - int sink; - // note: `(void)` cast silences warning 'expression result unused' - (void)((lambda(std::get(tpl)), sink) = ... = 0); - } else { - (lambda(std::get(tpl)), ...); - } - } -#else - template - void iterate_tuple(Tpl& /*tpl*/, std::index_sequence<>, L&& /*lambda*/) {} - - template - void iterate_tuple(Tpl& tpl, std::index_sequence, L&& lambda) { - if SQLITE_ORM_CONSTEXPR_IF (reversed) { - iterate_tuple(tpl, std::index_sequence{}, std::forward(lambda)); - lambda(std::get(tpl)); - } else { - lambda(std::get(tpl)); - iterate_tuple(tpl, std::index_sequence{}, std::forward(lambda)); - } - } -#endif - template - constexpr void iterate_tuple(Tpl&& tpl, L&& lambda) { - iterate_tuple(tpl, - std::make_index_sequence>::value>{}, - std::forward(lambda)); - } - -#ifdef SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED - template - void iterate_tuple(std::index_sequence, L&& lambda) { - (lambda((std::tuple_element_t*)nullptr), ...); - } -#else - template - void iterate_tuple(std::index_sequence, L&& lambda) { - using Sink = int[sizeof...(Idx)]; - (void)Sink{(lambda((std::tuple_element_t*)nullptr), 0)...}; - } -#endif - template - void iterate_tuple(L&& lambda) { - iterate_tuple(std::make_index_sequence::value>{}, std::forward(lambda)); - } - - template class Base, class L> - struct lambda_as_template_base : L { -#ifndef SQLITE_ORM_AGGREGATE_BASES_SUPPORTED - lambda_as_template_base(L&& lambda) : L{std::move(lambda)} {} -#endif - template - decltype(auto) operator()(const Base& object) { - return L::operator()(object); - } - }; - - /* - * This method wraps the specified callable in another function object, - * which in turn implicitly casts its single argument to the specified template base class, - * then passes the converted argument to the lambda. - * - * Note: This method is useful for reducing combinatorial instantiation of template lambdas, - * as long as this library supports compilers that do not implement - * explicit template parameters in generic lambdas [SQLITE_ORM_EXPLICIT_GENERIC_LAMBDA_SUPPORTED]. - * Unfortunately it doesn't work with user-defined conversion operators in order to extract - * parts of a class. In other words, the destination type must be a direct template base class. - */ - template class Base, class L> - lambda_as_template_base call_as_template_base(L lambda) { - return {std::move(lambda)}; - } - } -} - -// #include "type_traits.h" - -#include // std::enable_if, std::is_same, std::is_empty, std::is_aggregate -#if __cpp_lib_unwrap_ref >= 201811L -#include // std::reference_wrapper -#else -#include // std::reference_wrapper -#endif - -// #include "functional/cxx_core_features.h" - -// #include "functional/cxx_type_traits_polyfill.h" - -namespace sqlite_orm { - // C++ generic traits used throughout the library - namespace internal { - template - using is_any_of = polyfill::disjunction...>; - - template - struct value_unref_type : polyfill::remove_cvref {}; - - template - struct value_unref_type> : std::remove_const {}; - - template - using value_unref_type_t = typename value_unref_type::type; - - template - using is_eval_order_garanteed = -#if __cpp_lib_is_aggregate >= 201703L - std::is_aggregate; -#else - std::is_pod; -#endif - - // enable_if for types - template class Op, class... Args> - using match_if = std::enable_if_t::value>; - - // enable_if for types - template class Op, class... Args> - using match_if_not = std::enable_if_t>::value>; - - // enable_if for types - template class Primary> - using match_specialization_of = std::enable_if_t::value>; - - // enable_if for functions - template class Op, class... Args> - using satisfies = std::enable_if_t::value, bool>; - - // enable_if for functions - template class Op, class... Args> - using satisfies_not = std::enable_if_t>::value, bool>; - - // enable_if for functions - template class Primary> - using satisfies_is_specialization_of = - std::enable_if_t::value, bool>; - } - - // type name template aliases for syntactic sugar - namespace internal { - template - using type_t = typename T::type; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - using auto_type_t = typename decltype(a)::type; -#endif - - template - using value_type_t = typename T::value_type; - - template - using field_type_t = typename T::field_type; - - template - using constraints_type_t = typename T::constraints_type; - - template - using columns_tuple_t = typename T::columns_tuple; - - template - using object_type_t = typename T::object_type; - - template - using elements_type_t = typename T::elements_type; - - template - using table_type_t = typename T::table_type; - - template - using target_type_t = typename T::target_type; - - template - using left_type_t = typename T::left_type; - - template - using right_type_t = typename T::right_type; - - template - using on_type_t = typename T::on_type; - - template - using expression_type_t = typename T::expression_type; - - template - using alias_type_t = typename As::alias_type; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - using udf_type_t = typename T::udf_type; - - template - using auto_udf_type_t = typename decltype(a)::udf_type; -#endif - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - template - using cte_moniker_type_t = typename T::cte_moniker_type; - - template - using cte_mapper_type_t = typename T::cte_mapper_type; - - // T::alias_type or nonesuch - template - using alias_holder_type_or_none = polyfill::detected; - - template - using alias_holder_type_or_none_t = typename alias_holder_type_or_none::type; -#endif - -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - template - concept stateless = std::is_empty_v; -#endif - } - -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - template - concept orm_names_type = requires { typename T::type; }; -#endif -} - -// #include "alias.h" - -#include // std::enable_if, std::is_same -#include // std::make_index_sequence, std::move -#include // std::string -#include // std::stringstream -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -#include -#endif - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "functional/mpl/conditional.h" - -// #include "functional/cstring_literal.h" - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES -#include // std::index_sequence -#include // std::copy_n -#endif - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES -namespace sqlite_orm::internal { - /* - * Wraps a C string of fixed size. - * Its main purpose is to enable the user-defined string literal operator template. - */ - template - struct cstring_literal { - static constexpr size_t size() { - return N - 1; - } - - constexpr cstring_literal(const char (&cstr)[N]) { - std::copy_n(cstr, N, this->cstr); - } - - char cstr[N]; - }; - - template class Template, cstring_literal literal, size_t... Idx> - consteval auto explode_into(std::index_sequence) { - return Template{}; - } -} -#endif - -// #include "type_traits.h" - -// #include "alias_traits.h" - -#include // std::is_base_of, std::is_same -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES -#include -#endif - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "type_traits.h" - -// #include "table_reference.h" - -#include // std::remove_const, std::type_identity - -// #include "functional/cxx_type_traits_polyfill.h" - -namespace sqlite_orm { - namespace internal { - /* - * Identity wrapper around a mapped object, facilitating uniform column pointer expressions. - */ - template - struct table_reference : polyfill::type_identity {}; - - template - struct decay_table_ref : std::remove_const {}; - template - struct decay_table_ref> : polyfill::type_identity {}; - template - struct decay_table_ref> : polyfill::type_identity {}; - - template - using decay_table_ref_t = typename decay_table_ref::type; -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - using auto_decay_table_ref_t = typename decay_table_ref::type; -#endif - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_table_reference_v = - polyfill::is_specialization_of_v, table_reference>; - - template - struct is_table_reference : polyfill::bool_constant> {}; - } - -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - /** @short Specifies that a type is a reference of a concrete table, especially of a derived class. - * - * A concrete table reference has the following traits: - * - specialization of `table_reference`, whose `type` typename references a mapped object. - */ - template - concept orm_table_reference = polyfill::is_specialization_of_v, internal::table_reference>; -#endif -} - -namespace sqlite_orm { - - /** @short Base class for a custom table alias, column alias or expression alias. - */ - struct alias_tag {}; - - namespace internal { - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_alias_v = std::is_base_of::value; - - template - struct is_alias : polyfill::bool_constant> {}; - - /** @short Alias of a column in a record set, see `orm_column_alias`. - */ - template - SQLITE_ORM_INLINE_VAR constexpr bool is_column_alias_v = - polyfill::conjunction, polyfill::negation>>::value; - - template - struct is_column_alias : is_alias {}; - - /** @short Alias of any type of record set, see `orm_recordset_alias`. - */ - template - SQLITE_ORM_INLINE_VAR constexpr bool is_recordset_alias_v = - polyfill::conjunction, polyfill::is_detected>::value; - - template - struct is_recordset_alias : polyfill::bool_constant> {}; - - /** @short Alias of a concrete table, see `orm_table_alias`. - */ - template - SQLITE_ORM_INLINE_VAR constexpr bool is_table_alias_v = polyfill::conjunction< - is_recordset_alias, - polyfill::negation, std::remove_const_t>>>::value; - - template - struct is_table_alias : polyfill::bool_constant> {}; - - /** @short Moniker of a CTE, see `orm_cte_moniker`. - */ - template - SQLITE_ORM_INLINE_VAR constexpr bool is_cte_moniker_v = -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - polyfill::conjunction_v, - std::is_same, std::remove_const_t>>; -#else - false; -#endif - - template - using is_cte_moniker = polyfill::bool_constant>; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - concept orm_alias = std::derived_from; - - /** @short Specifies that a type is an alias of a column in a record set. - * - * A column alias has the following traits: - * - is derived from `alias_tag` - * - must not have a nested `type` typename - */ - template - concept orm_column_alias = (orm_alias && !orm_names_type); - - /** @short Specifies that a type is an alias of any type of record set. - * - * A record set alias has the following traits: - * - is derived from `alias_tag`. - * - has a nested `type` typename, which refers to a mapped object. - */ - template - concept orm_recordset_alias = (orm_alias && orm_names_type); - - /** @short Specifies that a type is an alias of a concrete table. - * - * A concrete table alias has the following traits: - * - is derived from `alias_tag`. - * - has a `type` typename, which refers to another mapped object (i.e. doesn't refer to itself). - */ - template - concept orm_table_alias = (orm_recordset_alias && !std::same_as>); - - /** @short Moniker of a CTE. - * - * A CTE moniker has the following traits: - * - is derived from `alias_tag`. - * - has a `type` typename, which refers to itself. - */ - template - concept orm_cte_moniker = (orm_recordset_alias && std::same_as>); - - /** @short Specifies that a type refers to a mapped table (possibly aliased). - */ - template - concept orm_refers_to_table = (orm_table_reference || orm_table_alias); - - /** @short Specifies that a type refers to a recordset. - */ - template - concept orm_refers_to_recordset = (orm_table_reference || orm_recordset_alias); - - /** @short Specifies that a type is a mapped recordset (table reference). - */ - template - concept orm_mapped_recordset = (orm_table_reference || orm_cte_moniker); -#endif -} - -// #include "table_type_of.h" - -#include // std::enable_if, std::is_convertible - -namespace sqlite_orm { - - namespace internal { - - template - struct column_pointer; - - template - struct indexed_column_t; - - /** - * Trait class used to define table mapped type by setter/getter/member - * T - member pointer - * `type` is a type which is mapped. - * E.g. - * - `table_type_of::type` is `User` - * - `table_type_of::type` is `User` - * - `table_type_of::type` is `User` - * - `table_type_of(&User::id))>::type` is `User` - * - `table_type_of*&User::id)>::type` is `User` - */ - template - struct table_type_of; - - template - struct table_type_of { - using type = O; - }; - - template - struct table_type_of> { - using type = T; - }; - - template - struct table_type_of> : table_type_of {}; - - template - using table_type_of_t = typename table_type_of::type; - - /* - * This trait can be used to check whether the object type of a member pointer or column pointer matches the target type. - * - * One use case is the ability to create column reference to an aliased table column of a derived object field without explicitly using a column pointer. - * E.g. - * regular: `alias_column>(column(&Base::field))` - * short: `alias_column>(&Base::field)` - */ - template - SQLITE_ORM_INLINE_VAR constexpr bool is_field_of_v = false; - - /* - * `true` if a pointer-to-member of Base is convertible to a pointer-to-member of Derived. - */ - template - SQLITE_ORM_INLINE_VAR constexpr bool - is_field_of_v::value>> = true; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_field_of_v, T, void> = true; - } -} - -// #include "tags.h" - -// #include "functional/cxx_functional_polyfill.h" - -namespace sqlite_orm { - namespace internal { - struct negatable_t {}; - - /** - * Inherit from this class to support arithmetic types overloading - */ - struct arithmetic_t {}; - - /** - * Inherit from this class if target class can be chained with other conditions with '&&' and '||' operators - */ - struct condition_t {}; - - /** - * Specialize if a type participates as an argument to overloaded operators (arithmetic, conditional, negation, chaining) - */ - template - SQLITE_ORM_INLINE_VAR constexpr bool is_operator_argument_v = false; - - template - using is_operator_argument = polyfill::bool_constant>; - } -} - -// #include "column_pointer.h" - -#include // std::enable_if, std::is_convertible -#include // std::move - -// #include "functional/cxx_core_features.h" - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "type_traits.h" - -// #include "table_reference.h" - -// #include "alias_traits.h" - -// #include "tags.h" - -namespace sqlite_orm { - namespace internal { - /** - * This class is used to store explicit mapped type T and its column descriptor (member pointer/getter/setter). - * Is useful when mapped type is derived from other type and base class has members mapped to a storage. - */ - template - struct column_pointer { - using type = T; - using field_type = F; - - field_type field; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_column_pointer_v = - polyfill::is_specialization_of::value; - - template - struct is_column_pointer : polyfill::bool_constant> {}; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_operator_argument_v::value>> = - true; - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - template - struct alias_holder; -#endif - } - - /** - * Explicitly refer to a column, used in contexts - * where the automatic object mapping deduction needs to be overridden. - * - * Example: - * struct BaseType : { int64 id; }; - * struct MyType : BaseType { ... }; - * storage.select(column(&BaseType::id)); - */ - template = true> - constexpr internal::column_pointer column(F Base::* field) { - static_assert(std::is_convertible::value, "Field must be from derived class"); - return {field}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Explicitly refer to a column. - */ - template - constexpr auto column(F O::* field) { - return column>(field); - } - - // Intentionally place pointer-to-member operator for table references in the internal namespace - // to facilitate ADL (Argument Dependent Lookup) - namespace internal { - /** - * Explicitly refer to a column. - */ - template - constexpr auto operator->*(const R& /*table*/, F O::* field) { - return column(field); - } - } - - /** - * Make a table reference. - */ - template - requires (!orm_recordset_alias) - consteval internal::table_reference column() { - return {}; - } - - /** - * Make a table reference. - */ - template - requires (!orm_recordset_alias) - consteval internal::table_reference c() { - return {}; - } -#endif - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - /** - * Explicitly refer to a column alias mapped into a CTE or subquery. - * - * Example: - * struct Object { ... }; - * using cte_1 = decltype(1_ctealias); - * storage.with(cte()(select(&Object::id)), select(column(&Object::id))); - * storage.with(cte()(select(&Object::id)), select(column(1_colalias))); - * storage.with(cte()(select(as(&Object::id))), select(column(colalias_a{}))); - * storage.with(cte(colalias_a{})(select(&Object::id)), select(column(colalias_a{}))); - * storage.with(cte()(select(as(&Object::id))), select(column(get()))); - */ - template = true> - constexpr auto column(F field) { - using namespace ::sqlite_orm::internal; - - static_assert(is_cte_moniker_v, "`Moniker' must be a CTE moniker"); - - if constexpr (polyfill::is_specialization_of_v) { - static_assert(is_column_alias_v>); - return column_pointer{{}}; - } else if constexpr (is_column_alias_v) { - return column_pointer>{{}}; - } else { - return column_pointer{std::move(field)}; - } - (void)field; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Explicitly refer to a column mapped into a CTE or subquery. - * - * Example: - * struct Object { ... }; - * storage.with(cte<"z"_cte>()(select(&Object::id)), select(column<"z"_cte>(&Object::id))); - * storage.with(cte<"z"_cte>()(select(&Object::id)), select(column<"z"_cte>(1_colalias))); - */ - template - constexpr auto column(F field) { - using Moniker = std::remove_const_t; - return column(std::forward(field)); - } - - /** - * Explicitly refer to a column mapped into a CTE or subquery. - * - * @note (internal) Intentionally place in the sqlite_orm namespace for ADL (Argument Dependent Lookup) - * because recordset aliases are derived from `sqlite_orm::alias_tag` - * - * Example: - * struct Object { ... }; - * using cte_1 = decltype(1_ctealias); - * storage.with(cte()(select(&Object::id)), select(1_ctealias->*&Object::id)); - * storage.with(cte()(select(&Object::id)), select(1_ctealias->*1_colalias)); - */ - template - constexpr auto operator->*(const Moniker& /*moniker*/, F field) { - return column(std::forward(field)); - } -#endif -#endif -} - -namespace sqlite_orm { - - namespace internal { -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - inline constexpr bool is_operator_argument_v>> = true; -#endif - - /** - * This is a common built-in class used for character based table aliases. - * For convenience there exist public type aliases `alias_a`, `alias_b`, ... - * The easiest way to create a table alias is using `"z"_alias.for_()`. - */ - template - struct recordset_alias : alias_tag { - using type = T; - - static std::string get() { - return {A, X...}; - } - }; - - /** - * Column expression with table alias attached like 'C.ID'. This is not a column alias - */ - template - struct alias_column_t { - using alias_type = T; - using column_type = C; - - column_type column; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool - is_operator_argument_v::value>> = - true; - - struct basic_table; - - /* - * Encapsulates extracting the alias identifier of a non-alias. - * - * `extract()` always returns the empty string. - * `as_alias()` is used in contexts where a table might be aliased, and the empty string is returned. - * `as_qualifier()` is used in contexts where a table might be aliased, and the given table's name is returned. - */ - template - struct alias_extractor { - static std::string extract() { - return {}; - } - - static std::string as_alias() { - return {}; - } - - template - static const std::string& as_qualifier(const X& table) { - return table.name; - } - }; - - /* - * Encapsulates extracting the alias identifier of an alias. - * - * `extract()` always returns the alias identifier or CTE moniker. - * `as_alias()` is used in contexts where a recordset is aliased, and the alias identifier is returned. - * `as_qualifier()` is used in contexts where a table is aliased, and the alias identifier is returned. - */ - template - struct alias_extractor> { - static std::string extract() { - std::stringstream ss; - ss << A::get(); - return ss.str(); - } - - // for column and regular table aliases -> alias identifier - template, A> = true> - static std::string as_alias() { - return alias_extractor::extract(); - } - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - // for CTE monikers -> empty - template, A> = true> - static std::string as_alias() { - return {}; - } -#endif - - // for regular table aliases -> alias identifier - template = true> - static std::string as_qualifier(const basic_table&) { - return alias_extractor::extract(); - } - }; - - /** - * Used to store alias for expression - */ - template - struct as_t { - using alias_type = T; - using expression_type = E; - - expression_type expression; - }; - - /** - * Built-in column alias. - * For convenience there exist type aliases `colalias_a`, `colalias_b`, ... - * The easiest way to create a column alias is using `"xyz"_col`. - */ - template - struct column_alias : alias_tag { - static std::string get() { - return {A, X...}; - } - }; - - template - struct alias_holder { - using type = T; - - alias_holder() = default; - // CTE feature needs it to implicitly convert a column alias to an alias_holder; see `cte()` factory function - alias_holder(const T&) noexcept {} - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool - is_operator_argument_v::value>> = true; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - struct recordset_alias_builder { - template - [[nodiscard]] consteval recordset_alias for_() const { - return {}; - } - - template - [[nodiscard]] consteval auto for_() const { - using T = std::remove_const_t; - return recordset_alias{}; - } - }; -#endif - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - template - SQLITE_ORM_CONSTEVAL auto n_to_colalias() { - constexpr column_alias<'1' + n % 10, C...> colalias{}; - if constexpr (n > 10) { - return n_to_colalias(); - } else { - return colalias; - } - } - - template - inline constexpr bool is_builtin_numeric_column_alias_v = false; - template - inline constexpr bool is_builtin_numeric_column_alias_v> = ((C >= '0' && C <= '9') && ...); -#endif - } - - /** - * Using a column pointer, create a column reference to an aliased table column. - * - * Example: - * using als = alias_u; - * select(alias_column(column(&User::id))) - */ - template, - polyfill::negation>>>::value, - bool> = true> - constexpr auto alias_column(C field) { - using namespace ::sqlite_orm::internal; - using aliased_type = type_t; - static_assert(is_field_of_v, "Column must be from aliased table"); - - return alias_column_t{std::move(field)}; - } - - /** - * Using an object member field, create a column reference to an aliased table column. - * - * @note The object member pointer can be from a derived class without explicitly forming a column pointer. - * - * Example: - * using als = alias_u; - * select(alias_column(&User::id)) - */ - template, - polyfill::negation>>>::value, - bool> = true> - constexpr auto alias_column(F O::* field) { - using namespace ::sqlite_orm::internal; - using aliased_type = type_t; - static_assert(is_field_of_v, "Column must be from aliased table"); - - using C1 = - mpl::conditional_t::value, F O::*, column_pointer>; - return alias_column_t{C1{field}}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a column reference to an aliased table column. - * - * @note An object member pointer can be from a derived class without explicitly forming a column pointer. - * - * Example: - * constexpr orm_table_alias auto als = "u"_alias.for_(); - * select(alias_column(&User::id)) - */ - template - requires (!orm_cte_moniker>) - constexpr auto alias_column(C field) { - using namespace ::sqlite_orm::internal; - using A = decltype(als); - using aliased_type = type_t; - static_assert(is_field_of_v, "Column must be from aliased table"); - - if constexpr (is_column_pointer_v) { - return alias_column_t{std::move(field)}; - } else if constexpr (std::is_same_v, aliased_type>) { - return alias_column_t{field}; - } else { - // wrap in column_pointer - using C1 = column_pointer; - return alias_column_t{{field}}; - } - } - - /** - * Create a column reference to an aliased table column. - * - * @note An object member pointer can be from a derived class without explicitly forming a column pointer. - * - * @note (internal) Intentionally place in the sqlite_orm namespace for ADL (Argument Dependent Lookup) - * because recordset aliases are derived from `sqlite_orm::alias_tag` - * - * Example: - * constexpr auto als = "u"_alias.for_(); - * select(als->*&User::id) - */ - template - requires (!orm_cte_moniker>) - constexpr auto operator->*(const A& /*tableAlias*/, F field) { - return alias_column(std::move(field)); - } -#endif - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - /** - * Create a column reference to an aliased CTE column. - */ - template, internal::is_cte_moniker>>, - bool> = true> - constexpr auto alias_column(C c) { - using namespace ::sqlite_orm::internal; - using cte_moniker_t = type_t; - - if constexpr (is_column_pointer_v) { - static_assert(std::is_same, cte_moniker_t>::value, - "Column pointer must match aliased CTE"); - return alias_column_t{c}; - } else { - auto cp = column(c); - return alias_column_t{std::move(cp)}; - } - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a column reference to an aliased CTE column. - * - * @note (internal) Intentionally place in the sqlite_orm namespace for ADL (Argument Dependent Lookup) - * because recordset aliases are derived from `sqlite_orm::alias_tag` - */ - template - requires (orm_cte_moniker>) - constexpr auto operator->*(const A& /*tableAlias*/, C c) { - return alias_column(std::move(c)); - } - - /** - * Create a column reference to an aliased CTE column. - */ - template - requires (orm_cte_moniker>) - constexpr auto alias_column(C c) { - using A = std::remove_const_t; - return alias_column(std::move(c)); - } -#endif -#endif - - /** - * Alias a column expression. - */ - template = true> - internal::as_t as(E expression) { - return {std::move(expression)}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Alias a column expression. - */ - template - auto as(E expression) { - return internal::as_t{std::move(expression)}; - } - - /** - * Alias a column expression. - */ - template - internal::as_t operator>>=(E expression, const A&) { - return {std::move(expression)}; - } -#else - /** - * Alias a column expression. - */ - template = true> - internal::as_t operator>>=(E expression, const A&) { - return {std::move(expression)}; - } -#endif - - /** - * Wrap a column alias in an alias holder. - */ - template - internal::alias_holder get() { - static_assert(internal::is_column_alias_v, ""); - return {}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - auto get() { - return internal::alias_holder{}; - } -#endif - - template - using alias_a = internal::recordset_alias; - template - using alias_b = internal::recordset_alias; - template - using alias_c = internal::recordset_alias; - template - using alias_d = internal::recordset_alias; - template - using alias_e = internal::recordset_alias; - template - using alias_f = internal::recordset_alias; - template - using alias_g = internal::recordset_alias; - template - using alias_h = internal::recordset_alias; - template - using alias_i = internal::recordset_alias; - template - using alias_j = internal::recordset_alias; - template - using alias_k = internal::recordset_alias; - template - using alias_l = internal::recordset_alias; - template - using alias_m = internal::recordset_alias; - template - using alias_n = internal::recordset_alias; - template - using alias_o = internal::recordset_alias; - template - using alias_p = internal::recordset_alias; - template - using alias_q = internal::recordset_alias; - template - using alias_r = internal::recordset_alias; - template - using alias_s = internal::recordset_alias; - template - using alias_t = internal::recordset_alias; - template - using alias_u = internal::recordset_alias; - template - using alias_v = internal::recordset_alias; - template - using alias_w = internal::recordset_alias; - template - using alias_x = internal::recordset_alias; - template - using alias_y = internal::recordset_alias; - template - using alias_z = internal::recordset_alias; - - using colalias_a = internal::column_alias<'a'>; - using colalias_b = internal::column_alias<'b'>; - using colalias_c = internal::column_alias<'c'>; - using colalias_d = internal::column_alias<'d'>; - using colalias_e = internal::column_alias<'e'>; - using colalias_f = internal::column_alias<'f'>; - using colalias_g = internal::column_alias<'g'>; - using colalias_h = internal::column_alias<'h'>; - using colalias_i = internal::column_alias<'i'>; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** @short Create a table alias. - * - * Examples: - * constexpr orm_table_alias auto z_alias = alias<'z'>.for_(); - */ - template - inline constexpr internal::recordset_alias_builder alias{}; - - inline namespace literals { - /** @short Create a table alias. - * - * Examples: - * constexpr orm_table_alias auto z_alias = "z"_alias.for_(); - */ - template - [[nodiscard]] consteval auto operator"" _alias() { - return internal::explode_into( - std::make_index_sequence{}); - } - - /** @short Create a column alias. - * column_alias<'a'[, ...]> from a string literal. - * E.g. "a"_col, "b"_col - */ - template - [[nodiscard]] consteval auto operator"" _col() { - return internal::explode_into(std::make_index_sequence{}); - } - } -#endif - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - inline namespace literals { - /** - * column_alias<'1'[, ...]> from a numeric literal. - * E.g. 1_colalias, 2_colalias - */ - template - [[nodiscard]] SQLITE_ORM_CONSTEVAL auto operator"" _colalias() { - // numeric identifiers are used for automatically assigning implicit aliases to unaliased column expressions, - // which start at "1". - static_assert(std::array{Chars...}[0] > '0'); - return internal::column_alias{}; - } - } -#endif -} - -// #include "error_code.h" - -#include -#include // std::error_code, std::system_error -#include // std::string -#include -#include // std::ostringstream -#include - -namespace sqlite_orm { - - /** @short Enables classifying sqlite error codes. - - @note We don't bother listing all possible values; - this also allows for compatibility with - 'Construction rules for enum class values (P0138R2)' - */ - enum class sqlite_errc {}; - - enum class orm_error_code { - not_found = 1, - type_is_not_mapped_to_storage, - trying_to_dereference_null_iterator, - too_many_tables_specified, - incorrect_set_fields_specified, - column_not_found, - table_has_no_primary_key_column, - cannot_start_a_transaction_within_a_transaction, - no_active_transaction, - incorrect_journal_mode_string, - incorrect_locking_mode_string, - invalid_collate_argument_enum, - failed_to_init_a_backup, - unknown_member_value, - incorrect_order, - cannot_use_default_value, - arguments_count_does_not_match, - function_not_found, - index_is_out_of_bounds, - value_is_null, - no_tables_specified, - }; -} - -namespace std { - template<> - struct is_error_code_enum<::sqlite_orm::sqlite_errc> : true_type {}; - - template<> - struct is_error_code_enum<::sqlite_orm::orm_error_code> : true_type {}; -} - -namespace sqlite_orm { - - class orm_error_category : public std::error_category { - public: - const char* name() const noexcept override final { - return "ORM error"; - } - - std::string message(int c) const override final { - switch (static_cast(c)) { - case orm_error_code::not_found: - return "Not found"; - case orm_error_code::type_is_not_mapped_to_storage: - return "Type is not mapped to storage"; - case orm_error_code::trying_to_dereference_null_iterator: - return "Trying to dereference null iterator"; - case orm_error_code::too_many_tables_specified: - return "Too many tables specified"; - case orm_error_code::incorrect_set_fields_specified: - return "Incorrect set fields specified"; - case orm_error_code::column_not_found: - return "Column not found"; - case orm_error_code::table_has_no_primary_key_column: - return "Table has no primary key column"; - case orm_error_code::cannot_start_a_transaction_within_a_transaction: - return "Cannot start a transaction within a transaction"; - case orm_error_code::no_active_transaction: - return "No active transaction"; - case orm_error_code::invalid_collate_argument_enum: - return "Invalid collate_argument enum"; - case orm_error_code::failed_to_init_a_backup: - return "Failed to init a backup"; - case orm_error_code::unknown_member_value: - return "Unknown member value"; - case orm_error_code::incorrect_order: - return "Incorrect order"; - case orm_error_code::cannot_use_default_value: - return "The statement 'INSERT INTO * DEFAULT VALUES' can be used with only one row"; - case orm_error_code::arguments_count_does_not_match: - return "Arguments count does not match"; - case orm_error_code::function_not_found: - return "Function not found"; - case orm_error_code::index_is_out_of_bounds: - return "Index is out of bounds"; - case orm_error_code::value_is_null: - return "Value is null"; - case orm_error_code::no_tables_specified: - return "No tables specified"; - default: - return "unknown error"; - } - } - }; - - class sqlite_error_category : public std::error_category { - public: - const char* name() const noexcept override final { - return "SQLite error"; - } - - std::string message(int c) const override final { - return sqlite3_errstr(c); - } - }; - - inline const orm_error_category& get_orm_error_category() { - static orm_error_category res; - return res; - } - - inline const sqlite_error_category& get_sqlite_error_category() { - static sqlite_error_category res; - return res; - } - - inline std::error_code make_error_code(sqlite_errc ev) noexcept { - return {static_cast(ev), get_sqlite_error_category()}; - } - - inline std::error_code make_error_code(orm_error_code ev) noexcept { - return {static_cast(ev), get_orm_error_category()}; - } - - template - std::string get_error_message(sqlite3* db, T&&... args) { - std::ostringstream stream; - using unpack = int[]; - (void)unpack{0, (stream << args, 0)...}; - stream << sqlite3_errmsg(db); - return stream.str(); - } - - template - [[noreturn]] void throw_error(sqlite3* db, T&&... args) { - throw std::system_error{sqlite_errc(sqlite3_errcode(db)), get_error_message(db, std::forward(args)...)}; - } - - inline std::system_error sqlite_to_system_error(int ev) { - return {sqlite_errc(ev)}; - } - - inline std::system_error sqlite_to_system_error(sqlite3* db) { - return {sqlite_errc(sqlite3_errcode(db)), sqlite3_errmsg(db)}; - } - - [[noreturn]] inline void throw_translated_sqlite_error(int ev) { - throw sqlite_to_system_error(ev); - } - - [[noreturn]] inline void throw_translated_sqlite_error(sqlite3* db) { - throw sqlite_to_system_error(db); - } - - [[noreturn]] inline void throw_translated_sqlite_error(sqlite3_stmt* stmt) { - throw sqlite_to_system_error(sqlite3_db_handle(stmt)); - } -} - -// #include "type_printer.h" - -#include // std::string -#include // std::shared_ptr, std::unique_ptr -#include // std::vector -// #include "functional/cxx_optional.h" - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "type_traits.h" - -// #include "is_std_ptr.h" - -#include -#include - -namespace sqlite_orm { - - /** - * Specialization for optional type (std::shared_ptr / std::unique_ptr). - */ - template - struct is_std_ptr : std::false_type {}; - - template - struct is_std_ptr> : std::true_type { - using element_type = typename std::shared_ptr::element_type; - - static std::shared_ptr make(std::remove_cv_t&& v) { - return std::make_shared(std::move(v)); - } - }; - - template - struct is_std_ptr> : std::true_type { - using element_type = typename std::unique_ptr::element_type; - - static auto make(std::remove_cv_t&& v) { - return std::make_unique(std::move(v)); - } - }; -} - -namespace sqlite_orm { - - /** - * This class transforms a C++ type to a sqlite type name (int -> INTEGER, ...) - */ - template - struct type_printer {}; - - struct integer_printer { - const std::string& print() const { - static const std::string res = "INTEGER"; - return res; - } - }; - - struct text_printer { - const std::string& print() const { - static const std::string res = "TEXT"; - return res; - } - }; - - struct real_printer { - const std::string& print() const { - static const std::string res = "REAL"; - return res; - } - }; - - struct blob_printer { - const std::string& print() const { - static const std::string res = "BLOB"; - return res; - } - }; - - // Note: char, unsigned/signed char are used for storing integer values, not char values. - template - struct type_printer>, - std::is_integral>::value>> : integer_printer { - }; - - template - struct type_printer::value>> : real_printer {}; - - template - struct type_printer, - std::is_base_of, - std::is_base_of>::value>> - : text_printer {}; - - template - struct type_printer::value>> : type_printer {}; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct type_printer>> - : type_printer {}; -#endif - - template<> - struct type_printer, void> : blob_printer {}; -} - -// #include "constraints.h" - -#include // std::is_base_of, std::false_type, std::true_type -#include // std::system_error -#include // std::ostream -#include // std::string -#include // std::tuple - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "functional/mpl.h" - -// #include "tuple_helper/same_or_void.h" - -#include // std::common_type - -namespace sqlite_orm { - namespace internal { - - /** - * Accepts any number of arguments and evaluates a nested `type` typename as `T` if all arguments are the same, otherwise `void`. - */ - template - struct same_or_void { - using type = void; - }; - - template - struct same_or_void { - using type = A; - }; - - template - struct same_or_void { - using type = A; - }; - - template - using same_or_void_t = typename same_or_void::type; - - template - struct same_or_void : same_or_void {}; - - template - struct common_type_of; - - template class Pack, class... Types> - struct common_type_of> : std::common_type {}; - - /** - * Accepts a pack of types and defines a nested `type` typename to a common type if possible, otherwise nonexistent. - * - * @note: SFINAE friendly like `std::common_type`. - */ - template - using common_type_of_t = typename common_type_of::type; - } -} - -// #include "tuple_helper/tuple_traits.h" - -// #include "tuple_helper/tuple_filter.h" - -// #include "type_traits.h" - -// #include "collate_argument.h" - -namespace sqlite_orm { - - namespace internal { - - enum class collate_argument { - binary, - nocase, - rtrim, - }; - } -} - -// #include "error_code.h" - -// #include "table_type_of.h" - -// #include "type_printer.h" - -// #include "column_pointer.h" - -namespace sqlite_orm { - - namespace internal { - - enum class conflict_clause_t { - rollback, - abort, - fail, - ignore, - replace, - }; - - struct primary_key_base { - enum class order_by { - unspecified, - ascending, - descending, - }; - struct { - order_by asc_option = order_by::unspecified; - conflict_clause_t conflict_clause = conflict_clause_t::rollback; - bool conflict_clause_is_on = false; - } options; - }; - - template - struct primary_key_with_autoincrement : T { - using primary_key_type = T; - - const primary_key_type& as_base() const { - return *this; - } -#ifndef SQLITE_ORM_AGGREGATE_BASES_SUPPORTED - primary_key_with_autoincrement(primary_key_type primary_key) : primary_key_type{primary_key} {} -#endif - }; - - /** - * PRIMARY KEY constraint class. - * Cs is parameter pack which contains columns (member pointers and/or function pointers). Can be empty when - * used within `make_column` function. - */ - template - struct primary_key_t : primary_key_base { - using self = primary_key_t; - using order_by = primary_key_base::order_by; - using columns_tuple = std::tuple; - - columns_tuple columns; - - primary_key_t(columns_tuple columns) : columns(std::move(columns)) {} - - self asc() const { - auto res = *this; - res.options.asc_option = order_by::ascending; - return res; - } - - self desc() const { - auto res = *this; - res.options.asc_option = order_by::descending; - return res; - } - - primary_key_with_autoincrement autoincrement() const { - return {*this}; - } - - self on_conflict_rollback() const { - auto res = *this; - res.options.conflict_clause_is_on = true; - res.options.conflict_clause = conflict_clause_t::rollback; - return res; - } - - self on_conflict_abort() const { - auto res = *this; - res.options.conflict_clause_is_on = true; - res.options.conflict_clause = conflict_clause_t::abort; - return res; - } - - self on_conflict_fail() const { - auto res = *this; - res.options.conflict_clause_is_on = true; - res.options.conflict_clause = conflict_clause_t::fail; - return res; - } - - self on_conflict_ignore() const { - auto res = *this; - res.options.conflict_clause_is_on = true; - res.options.conflict_clause = conflict_clause_t::ignore; - return res; - } - - self on_conflict_replace() const { - auto res = *this; - res.options.conflict_clause_is_on = true; - res.options.conflict_clause = conflict_clause_t::replace; - return res; - } - }; - - struct unique_base { - operator std::string() const { - return "UNIQUE"; - } - }; - - /** - * UNIQUE constraint class. - */ - template - struct unique_t : unique_base { - using columns_tuple = std::tuple; - - columns_tuple columns; - - unique_t(columns_tuple columns_) : columns(std::move(columns_)) {} - }; - - struct unindexed_t {}; - - template - struct prefix_t { - using value_type = T; - - value_type value; - }; - - template - struct tokenize_t { - using value_type = T; - - value_type value; - }; - - template - struct content_t { - using value_type = T; - - value_type value; - }; - - template - struct table_content_t { - using mapped_type = T; - }; - - /** - * DEFAULT constraint class. - * T is a value type. - */ - template - struct default_t { - using value_type = T; - - value_type value; - - operator std::string() const { - return "DEFAULT"; - } - }; - -#if SQLITE_VERSION_NUMBER >= 3006019 - /** - * FOREIGN KEY constraint class. - * Cs are columns which has foreign key - * Rs are column which C references to - * Available in SQLite 3.6.19 or higher - */ - - template - struct foreign_key_t; - - enum class foreign_key_action { - none, // not specified - no_action, - restrict_, - set_null, - set_default, - cascade, - }; - - inline std::ostream& operator<<(std::ostream& os, foreign_key_action action) { - switch (action) { - case foreign_key_action::no_action: - os << "NO ACTION"; - break; - case foreign_key_action::restrict_: - os << "RESTRICT"; - break; - case foreign_key_action::set_null: - os << "SET NULL"; - break; - case foreign_key_action::set_default: - os << "SET DEFAULT"; - break; - case foreign_key_action::cascade: - os << "CASCADE"; - break; - case foreign_key_action::none: - break; - } - return os; - } - - struct on_update_delete_base { - const bool update; // true if update and false if delete - - operator std::string() const { - if (this->update) { - return "ON UPDATE"; - } else { - return "ON DELETE"; - } - } - }; - - /** - * F - foreign key class - */ - template - struct on_update_delete_t : on_update_delete_base { - using foreign_key_type = F; - - const foreign_key_type& fk; - - on_update_delete_t(decltype(fk) fk_, decltype(update) update_, foreign_key_action action_) : - on_update_delete_base{update_}, fk(fk_), _action(action_) {} - - foreign_key_action _action = foreign_key_action::none; - - foreign_key_type no_action() const { - auto res = this->fk; - if (update) { - res.on_update._action = foreign_key_action::no_action; - } else { - res.on_delete._action = foreign_key_action::no_action; - } - return res; - } - - foreign_key_type restrict_() const { - auto res = this->fk; - if (update) { - res.on_update._action = foreign_key_action::restrict_; - } else { - res.on_delete._action = foreign_key_action::restrict_; - } - return res; - } - - foreign_key_type set_null() const { - auto res = this->fk; - if (update) { - res.on_update._action = foreign_key_action::set_null; - } else { - res.on_delete._action = foreign_key_action::set_null; - } - return res; - } - - foreign_key_type set_default() const { - auto res = this->fk; - if (update) { - res.on_update._action = foreign_key_action::set_default; - } else { - res.on_delete._action = foreign_key_action::set_default; - } - return res; - } - - foreign_key_type cascade() const { - auto res = this->fk; - if (update) { - res.on_update._action = foreign_key_action::cascade; - } else { - res.on_delete._action = foreign_key_action::cascade; - } - return res; - } - - operator bool() const { - return this->_action != foreign_key_action::none; - } - }; - - template - bool operator==(const on_update_delete_t& lhs, const on_update_delete_t& rhs) { - return lhs._action == rhs._action; - } - - template - struct foreign_key_t, std::tuple> { - using columns_type = std::tuple; - using references_type = std::tuple; - using self = foreign_key_t; - - /** - * Holds obect type of all referenced columns. - */ - using target_type = same_or_void_t...>; - - /** - * Holds obect type of all source columns. - */ - using source_type = same_or_void_t...>; - - columns_type columns; - references_type references; - - on_update_delete_t on_update; - on_update_delete_t on_delete; - - static_assert(std::tuple_size::value == std::tuple_size::value, - "Columns size must be equal to references tuple"); - static_assert(!std::is_same::value, "All references must have the same type"); - - foreign_key_t(columns_type columns_, references_type references_) : - columns(std::move(columns_)), references(std::move(references_)), - on_update(*this, true, foreign_key_action::none), on_delete(*this, false, foreign_key_action::none) {} - - foreign_key_t(const self& other) : - columns(other.columns), references(other.references), on_update(*this, true, other.on_update._action), - on_delete(*this, false, other.on_delete._action) {} - - self& operator=(const self& other) { - this->columns = other.columns; - this->references = other.references; - this->on_update = {*this, true, other.on_update._action}; - this->on_delete = {*this, false, other.on_delete._action}; - return *this; - } - }; - - template - bool operator==(const foreign_key_t& lhs, const foreign_key_t& rhs) { - return lhs.columns == rhs.columns && lhs.references == rhs.references && lhs.on_update == rhs.on_update && - lhs.on_delete == rhs.on_delete; - } - - /** - * Cs can be a class member pointer, a getter function member pointer or setter - * func member pointer - * Available in SQLite 3.6.19 or higher - */ - template - struct foreign_key_intermediate_t { - using tuple_type = std::tuple; - - tuple_type columns; - - template - foreign_key_t, std::tuple> references(Rs... refs) { - return {std::move(this->columns), {std::forward(refs)...}}; - } - - template - foreign_key_t, std::tuple...>> references(Rs... refs) { - return {std::move(this->columns), {sqlite_orm::column(refs)...}}; - } - }; -#endif - - struct collate_constraint_t { - collate_argument argument = collate_argument::binary; -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - collate_constraint_t(collate_argument argument) : argument{argument} {} -#endif - - operator std::string() const { - return "COLLATE " + this->string_from_collate_argument(this->argument); - } - - static std::string string_from_collate_argument(collate_argument argument) { - switch (argument) { - case collate_argument::binary: - return "BINARY"; - case collate_argument::nocase: - return "NOCASE"; - case collate_argument::rtrim: - return "RTRIM"; - } - throw std::system_error{orm_error_code::invalid_collate_argument_enum}; - } - }; - - template - struct check_t { - using expression_type = T; - - expression_type expression; - }; - - struct basic_generated_always { - enum class storage_type { - not_specified, - virtual_, - stored, - }; - -#if SQLITE_VERSION_NUMBER >= 3031000 - bool full = true; - storage_type storage = storage_type::not_specified; -#endif - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - basic_generated_always(bool full, storage_type storage) : full{full}, storage{storage} {} -#endif - }; - -#if SQLITE_VERSION_NUMBER >= 3031000 - template - struct generated_always_t : basic_generated_always { - using expression_type = T; - - expression_type expression; - - generated_always_t(expression_type expression_, bool full, storage_type storage) : - basic_generated_always{full, storage}, expression(std::move(expression_)) {} - - generated_always_t virtual_() { - return {std::move(this->expression), this->full, storage_type::virtual_}; - } - - generated_always_t stored() { - return {std::move(this->expression), this->full, storage_type::stored}; - } - }; -#endif - - struct null_t {}; - - struct not_null_t {}; - } - - namespace internal { - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_foreign_key_v = -#if SQLITE_VERSION_NUMBER >= 3006019 - polyfill::is_specialization_of::value; -#else - false; -#endif - - template - struct is_foreign_key : polyfill::bool_constant> {}; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_primary_key_v = std::is_base_of::value; - - template - struct is_primary_key : polyfill::bool_constant> {}; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_generated_always_v = -#if SQLITE_VERSION_NUMBER >= 3031000 - polyfill::is_specialization_of::value; -#else - false; -#endif - - template - struct is_generated_always : polyfill::bool_constant> {}; - - /** - * PRIMARY KEY INSERTABLE traits. - */ - template - struct is_primary_key_insertable - : polyfill::disjunction< - mpl::invoke_t, - check_if_has_template>, - constraints_type_t>, - std::is_base_of>>> { - - static_assert(tuple_has, is_primary_key>::value, - "an unexpected type was passed"); - }; - - template - using is_column_constraint = mpl::invoke_t>, - check_if_is_type, - check_if_is_type, - check_if_is_type>, - check_if_is_template, - check_if_is_template, - check_if_is_type, - check_if, - check_if_is_type>, - T>; - } - -#if SQLITE_VERSION_NUMBER >= 3031000 - template - internal::generated_always_t generated_always_as(T expression) { - return {std::move(expression), true, internal::basic_generated_always::storage_type::not_specified}; - } - - template - internal::generated_always_t as(T expression) { - return {std::move(expression), false, internal::basic_generated_always::storage_type::not_specified}; - } -#endif - -#if SQLITE_VERSION_NUMBER >= 3006019 - /** - * FOREIGN KEY constraint construction function that takes member pointer as argument - * Available in SQLite 3.6.19 or higher - */ - template - internal::foreign_key_intermediate_t foreign_key(Cs... columns) { - return {{std::forward(columns)...}}; - } -#endif - - /** - * UNIQUE table constraint builder function. - */ - template - internal::unique_t unique(Args... args) { - return {{std::forward(args)...}}; - } - - /** - * UNIQUE column constraint builder function. - */ - inline internal::unique_t<> unique() { - return {{}}; - } - -#if SQLITE_VERSION_NUMBER >= 3009000 - /** - * UNINDEXED column constraint builder function. Used in FTS virtual tables. - * - * https://www.sqlite.org/fts5.html#the_unindexed_column_option - */ - inline internal::unindexed_t unindexed() { - return {}; - } - - /** - * prefix=N table constraint builder function. Used in FTS virtual tables. - * - * https://www.sqlite.org/fts5.html#prefix_indexes - */ - template - internal::prefix_t prefix(T value) { - return {std::move(value)}; - } - - /** - * tokenize='...'' table constraint builder function. Used in FTS virtual tables. - * - * https://www.sqlite.org/fts5.html#tokenizers - */ - template - internal::tokenize_t tokenize(T value) { - return {std::move(value)}; - } - - /** - * content='' table constraint builder function. Used in FTS virtual tables. - * - * https://www.sqlite.org/fts5.html#contentless_tables - */ - template - internal::content_t content(T value) { - return {std::move(value)}; - } - - /** - * content='table' table constraint builder function. Used in FTS virtual tables. - * - * https://www.sqlite.org/fts5.html#external_content_tables - */ - template - internal::table_content_t content() { - return {}; - } -#endif - - /** - * PRIMARY KEY table constraint builder function. - */ - template - internal::primary_key_t primary_key(Cs... cs) { - return {{std::forward(cs)...}}; - } - - /** - * PRIMARY KEY column constraint builder function. - */ - inline internal::primary_key_t<> primary_key() { - return {{}}; - } - - template - internal::default_t default_value(T t) { - return {std::move(t)}; - } - - inline internal::collate_constraint_t collate_nocase() { - return {internal::collate_argument::nocase}; - } - - inline internal::collate_constraint_t collate_binary() { - return {internal::collate_argument::binary}; - } - - inline internal::collate_constraint_t collate_rtrim() { - return {internal::collate_argument::rtrim}; - } - - template - internal::check_t check(T t) { - return {std::move(t)}; - } - - inline internal::null_t null() { - return {}; - } - - inline internal::not_null_t not_null() { - return {}; - } -} - -// #include "field_printer.h" - -#include // std::string -#include // std::stringstream -#include // std::vector -#include // std::shared_ptr, std::unique_ptr -#ifndef SQLITE_ORM_OMITS_CODECVT -#include // std::wstring_convert -#include // std::codecvt_utf8_utf16 -#endif -// #include "functional/cxx_optional.h" - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "is_std_ptr.h" - -// #include "type_traits.h" - -namespace sqlite_orm { - - /** - * Is used to print members mapped to objects in storage_t::dump member function. - * Other developers can create own specialization to map custom types - */ - template - struct field_printer; - - namespace internal { - /* - * Implementation note: the technique of indirect expression testing is because - * of older compilers having problems with the detection of dependent templates [SQLITE_ORM_BROKEN_ALIAS_TEMPLATE_DEPENDENT_EXPR_SFINAE]. - * It must also be a type that differs from those for `is_preparable_v`, `is_bindable_v`. - */ - template - struct indirectly_test_printable; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_printable_v = false; - template - SQLITE_ORM_INLINE_VAR constexpr bool - is_printable_v{})>>> = true; - - template - struct is_printable : polyfill::bool_constant> {}; - } - - template - struct field_printer> { - std::string operator()(const T& t) const { - std::stringstream ss; - ss << t; - return ss.str(); - } - }; - - /** - * Upgrade to integer is required when using unsigned char(uint8_t) - */ - template<> - struct field_printer { - std::string operator()(const unsigned char& t) const { - std::stringstream ss; - ss << +t; - return ss.str(); - } - }; - - /** - * Upgrade to integer is required when using signed char(int8_t) - */ - template<> - struct field_printer { - std::string operator()(const signed char& t) const { - std::stringstream ss; - ss << +t; - return ss.str(); - } - }; - - /** - * char is neither signed char nor unsigned char so it has its own specialization - */ - template<> - struct field_printer { - std::string operator()(const char& t) const { - std::stringstream ss; - ss << +t; - return ss.str(); - } - }; - - template - struct field_printer> { - std::string operator()(std::string string) const { - return string; - } - }; - - template<> - struct field_printer, void> { - std::string operator()(const std::vector& t) const { - std::stringstream ss; - ss << std::hex; - for (auto c: t) { - ss << c; - } - return ss.str(); - } - }; -#ifndef SQLITE_ORM_OMITS_CODECVT - /** - * Specialization for std::wstring (UTF-16 assumed). - */ - template - struct field_printer> { - std::string operator()(const std::wstring& wideString) const { - std::wstring_convert> converter; - return converter.to_bytes(wideString); - } - }; -#endif // SQLITE_ORM_OMITS_CODECVT - template<> - struct field_printer { - std::string operator()(const nullptr_t&) const { - return "NULL"; - } - }; -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template<> - struct field_printer { - std::string operator()(const std::nullopt_t&) const { - return "NULL"; - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct field_printer, - internal::is_printable>>::value>> { - using unqualified_type = std::remove_cv_t; - - std::string operator()(const T& t) const { - if (t) { - return field_printer()(*t); - } else { - return field_printer{}(nullptr); - } - } - }; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct field_printer< - T, - std::enable_if_t, - internal::is_printable>>>> { - using unqualified_type = std::remove_cv_t; - - std::string operator()(const T& t) const { - if (t.has_value()) { - return field_printer()(*t); - } else { - return field_printer{}(std::nullopt); - } - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED -} - -// #include "rowid.h" - -#include // std::string - -namespace sqlite_orm { - - namespace internal { - - struct rowid_t { - operator std::string() const { - return "rowid"; - } - }; - - struct oid_t { - operator std::string() const { - return "oid"; - } - }; - - struct _rowid_t { - operator std::string() const { - return "_rowid_"; - } - }; - - template - struct table_rowid_t : public rowid_t { - using type = T; - }; - - template - struct table_oid_t : public oid_t { - using type = T; - }; - template - struct table__rowid_t : public _rowid_t { - using type = T; - }; - - } - - inline internal::rowid_t rowid() { - return {}; - } - - inline internal::oid_t oid() { - return {}; - } - - inline internal::_rowid_t _rowid_() { - return {}; - } - - template - internal::table_rowid_t rowid() { - return {}; - } - - template - internal::table_oid_t oid() { - return {}; - } - - template - internal::table__rowid_t _rowid_() { - return {}; - } -} - -// #include "operators.h" - -#include // std::false_type, std::true_type -#include // std::move - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "is_base_of_template.h" - -#include // std::true_type, std::false_type, std::declval - -namespace sqlite_orm { - - namespace internal { - - /* - * This is because of bug in MSVC, for more information, please visit - * https://stackoverflow.com/questions/34672441/stdis-base-of-for-template-classes/34672753#34672753 - */ -#ifdef SQLITE_ORM_BROKEN_VARIADIC_PACK_EXPANSION - template class Base> - struct is_base_of_template_impl { - template - static constexpr std::true_type test(const Base&); - - static constexpr std::false_type test(...); - }; - - template class C> - using is_base_of_template = decltype(is_base_of_template_impl::test(std::declval())); -#else - template class C, typename... Ts> - std::true_type is_base_of_template_impl(const C&); - - template class C> - std::false_type is_base_of_template_impl(...); - - template class C> - using is_base_of_template = decltype(is_base_of_template_impl(std::declval())); -#endif - - template class C> - SQLITE_ORM_INLINE_VAR constexpr bool is_base_of_template_v = is_base_of_template::value; - } -} - -// #include "tags.h" - -// #include "serialize_result_type.h" - -// #include "functional/cxx_string_view.h" - -// #include "cxx_core_features.h" - -#if SQLITE_ORM_HAS_INCLUDE() -#include -#endif - -#if __cpp_lib_string_view >= 201606L -#define SQLITE_ORM_STRING_VIEW_SUPPORTED -#endif - -#ifndef SQLITE_ORM_STRING_VIEW_SUPPORTED -#include // std::string -#endif - -namespace sqlite_orm { - namespace internal { -#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED - using serialize_result_type = std::string_view; - using serialize_arg_type = std::string_view; -#else - using serialize_result_type = std::string; - using serialize_arg_type = const std::string&; -#endif - } -} - -namespace sqlite_orm { - - namespace internal { - - template - struct binary_operator : Ds... { - using left_type = L; - using right_type = R; - - left_type lhs; - right_type rhs; - - constexpr binary_operator(left_type lhs_, right_type rhs_) : lhs(std::move(lhs_)), rhs(std::move(rhs_)) {} - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_binary_operator_v = is_base_of_template::value; - - template - using is_binary_operator = polyfill::bool_constant>; - - struct conc_string { - serialize_result_type serialize() const { - return "||"; - } - }; - - /** - * Result of concatenation || operator - */ - template - using conc_t = binary_operator; - - struct unary_minus_string { - serialize_result_type serialize() const { - return "-"; - } - }; - - /** - * Result of unary minus - operator - */ - template - struct unary_minus_t : unary_minus_string, arithmetic_t, negatable_t { - using argument_type = T; - - argument_type argument; - - unary_minus_t(argument_type argument_) : argument(std::move(argument_)) {} - }; - - struct add_string { - serialize_result_type serialize() const { - return "+"; - } - }; - - /** - * Result of addition + operator - */ - template - using add_t = binary_operator; - - struct sub_string { - serialize_result_type serialize() const { - return "-"; - } - }; - - /** - * Result of substraction - operator - */ - template - using sub_t = binary_operator; - - struct mul_string { - serialize_result_type serialize() const { - return "*"; - } - }; - - /** - * Result of multiply * operator - */ - template - using mul_t = binary_operator; - - struct div_string { - serialize_result_type serialize() const { - return "/"; - } - }; - - /** - * Result of divide / operator - */ - template - using div_t = binary_operator; - - struct mod_operator_string { - serialize_result_type serialize() const { - return "%"; - } - }; - - /** - * Result of mod % operator - */ - template - using mod_t = binary_operator; - - struct bitwise_shift_left_string { - serialize_result_type serialize() const { - return "<<"; - } - }; - - /** - * Result of bitwise shift left << operator - */ - template - using bitwise_shift_left_t = binary_operator; - - struct bitwise_shift_right_string { - serialize_result_type serialize() const { - return ">>"; - } - }; - - /** - * Result of bitwise shift right >> operator - */ - template - using bitwise_shift_right_t = binary_operator; - - struct bitwise_and_string { - serialize_result_type serialize() const { - return "&"; - } - }; - - /** - * Result of bitwise and & operator - */ - template - using bitwise_and_t = binary_operator; - - struct bitwise_or_string { - serialize_result_type serialize() const { - return "|"; - } - }; - - /** - * Result of bitwise or | operator - */ - template - using bitwise_or_t = binary_operator; - - struct bitwise_not_string { - serialize_result_type serialize() const { - return "~"; - } - }; - - /** - * Result of bitwise not ~ operator - */ - template - struct bitwise_not_t : bitwise_not_string, arithmetic_t, negatable_t { - using argument_type = T; - - argument_type argument; - - bitwise_not_t(argument_type argument_) : argument(std::move(argument_)) {} - }; - - struct assign_string { - serialize_result_type serialize() const { - return "="; - } - }; - - /** - * Result of assign = operator - */ - template - using assign_t = binary_operator; - - /** - * Assign operator traits. Common case - */ - template - struct is_assign_t : public std::false_type {}; - - /** - * Assign operator traits. Specialized case - */ - template - struct is_assign_t> : public std::true_type {}; - } - - /** - * Public interface for || concatenation operator. Example: `select(conc(&User::name, "@gmail.com"));` => SELECT - * name || '@gmail.com' FROM users - */ - template - constexpr internal::conc_t conc(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::unary_minus_t minus(T t) { - return {std::move(t)}; - } - - /** - * Public interface for + operator. Example: `select(add(&User::age, 100));` => SELECT age + 100 FROM users - */ - template - constexpr internal::add_t add(L l, R r) { - return {std::move(l), std::move(r)}; - } - - /** - * Public interface for - operator. Example: `select(sub(&User::age, 1));` => SELECT age - 1 FROM users - */ - template - constexpr internal::sub_t sub(L l, R r) { - return {std::move(l), std::move(r)}; - } - - /** - * Public interface for * operator. Example: `select(mul(&User::salary, 2));` => SELECT salary * 2 FROM users - */ - template - constexpr internal::mul_t mul(L l, R r) { - return {std::move(l), std::move(r)}; - } - - /** - * Public interface for / operator. Example: `select(div(&User::salary, 3));` => SELECT salary / 3 FROM users - * @note Please notice that ::div function already exists in pure C standard library inside header. - * If you use `using namespace sqlite_orm` directive you an specify which `div` you call explicitly using `::div` or `sqlite_orm::div` statements. - */ - template - constexpr internal::div_t div(L l, R r) { - return {std::move(l), std::move(r)}; - } - - /** - * Public interface for % operator. Example: `select(mod(&User::age, 5));` => SELECT age % 5 FROM users - */ - template - constexpr internal::mod_t mod(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::bitwise_shift_left_t bitwise_shift_left(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::bitwise_shift_right_t bitwise_shift_right(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::bitwise_and_t bitwise_and(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::bitwise_or_t bitwise_or(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::bitwise_not_t bitwise_not(T t) { - return {std::move(t)}; - } - - template - internal::assign_t assign(L l, R r) { - return {std::move(l), std::move(r)}; - } -} - -// #include "select_constraints.h" - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES -#include -#endif -#include // std::enable_if, std::remove_cvref, std::is_convertible, std::is_same, std::is_member_pointer -#include // std::string -#include // std::move -#include // std::tuple, std::get, std::tuple_size -// #include "functional/cxx_optional.h" - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "is_base_of_template.h" - -// #include "tuple_helper/tuple_traits.h" - -// #include "tuple_helper/tuple_transformer.h" - -// #include "tuple_helper/tuple_iteration.h" - -// #include "optional_container.h" - -namespace sqlite_orm { - - namespace internal { - - /** - * This is a cute class which allows storing something or nothing - * depending on template argument. Useful for optional class members - */ - template - struct optional_container { - using type = T; - - type field; - - template - void apply(const L& l) const { - l(this->field); - } - }; - - template<> - struct optional_container { - using type = void; - - template - void apply(const L&) const { - //.. - } - }; - } -} - -// #include "ast/where.h" - -#include // std::false_type, std::true_type -#include // std::move - -// #include "../functional/cxx_type_traits_polyfill.h" - -// #include "../serialize_result_type.h" - -namespace sqlite_orm { - namespace internal { - - struct where_string { - serialize_result_type serialize() const { - return "WHERE"; - } - }; - - /** - * WHERE argument holder. - * C is expression type. Can be any expression like: is_equal_t, is_null_t, exists_t etc - * Don't construct it manually. Call `where(...)` function instead. - */ - template - struct where_t : where_string { - using expression_type = C; - - expression_type expression; - - constexpr where_t(expression_type expression_) : expression(std::move(expression_)) {} - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_where_v = polyfill::is_specialization_of::value; - - template - struct is_where : polyfill::bool_constant> {}; - } - - /** - * WHERE clause. Use it to add WHERE conditions wherever you like. - * C is expression type. Can be any expression like: is_equal_t, is_null_t, exists_t etc - * @example - * // SELECT name - * // FROM letters - * // WHERE id > 3 - * auto rows = storage.select(&Letter::name, where(greater_than(&Letter::id, 3))); - */ - template - constexpr internal::where_t where(C expression) { - return {std::move(expression)}; - } -} - -// #include "ast/group_by.h" - -#include // std::tuple, std::make_tuple -#include // std::true_type, std::false_type -#include // std::forward, std::move - -// #include "../functional/cxx_type_traits_polyfill.h" - -namespace sqlite_orm { - namespace internal { - - template - struct group_by_with_having { - using args_type = std::tuple; - using expression_type = T; - - args_type args; - expression_type expression; - }; - - /** - * GROUP BY pack holder. - */ - template - struct group_by_t { - using args_type = std::tuple; - - args_type args; - - template - group_by_with_having having(T expression) { - return {std::move(this->args), std::move(expression)}; - } - }; - - template - using is_group_by = polyfill::disjunction, - polyfill::is_specialization_of>; - } - - /** - * GROUP BY column. - * Example: storage.get_all(group_by(&Employee::name)) - */ - template - internal::group_by_t group_by(Args... args) { - return {{std::forward(args)...}}; - } -} - -// #include "core_functions.h" - -#include // std::string -#include // std::make_tuple, std::tuple_size -#include // std::forward, std::is_base_of, std::enable_if -#include // std::unique_ptr -#include // std::vector - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "functional/mpl/conditional.h" - -// #include "is_base_of_template.h" - -// #include "tuple_helper/tuple_traits.h" - -// #include "conditions.h" - -#include // std::string -#include // std::enable_if, std::is_same, std::remove_const -#include // std::vector -#include // std::tuple -#include // std::move, std::forward -#include // std::stringstream -#include // std::flush - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "is_base_of_template.h" - -// #include "type_traits.h" - -// #include "collate_argument.h" - -// #include "constraints.h" - -// #include "optional_container.h" - -// #include "serializer_context.h" - -namespace sqlite_orm { - - namespace internal { - - struct serializer_context_base { - bool replace_bindable_with_question = false; - bool skip_table_name = true; - bool use_parentheses = true; - bool fts5_columns = false; - }; - - template - struct serializer_context : serializer_context_base { - using db_objects_type = DBOs; - - const db_objects_type& db_objects; - - serializer_context(const db_objects_type& dbObjects) : db_objects{dbObjects} {} - }; - - template - struct serializer_context_builder { - using storage_type = S; - using db_objects_type = typename storage_type::db_objects_type; - - serializer_context_builder(const storage_type& storage_) : storage{storage_} {} - - serializer_context operator()() const { - return {obtain_db_objects(this->storage)}; - } - - const storage_type& storage; - }; - } - -} - -// #include "serialize_result_type.h" - -// #include "tags.h" - -// #include "table_reference.h" - -// #include "alias_traits.h" - -// #include "expression.h" - -#include -#include // std::enable_if -#include // std::move, std::forward, std::declval -// #include "functional/cxx_optional.h" - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "tags.h" - -// #include "operators.h" - -namespace sqlite_orm { - - namespace internal { - - template - struct in_t; - - template - struct and_condition_t; - - template - struct or_condition_t; - - /** - * Result of c(...) function. Has operator= overloaded which returns assign_t - */ - template - struct expression_t { - T value; - - template - assign_t operator=(R r) const { - return {this->value, std::move(r)}; - } - - assign_t operator=(nullptr_t) const { - return {this->value, nullptr}; - } -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - assign_t operator=(std::nullopt_t) const { - return {this->value, std::nullopt}; - } -#endif - template - in_t in(Args... args) const { - return {this->value, {std::forward(args)...}, false}; - } - - template - in_t not_in(Args... args) const { - return {this->value, {std::forward(args)...}, true}; - } - - template - and_condition_t and_(R right) const { - return {this->value, std::move(right)}; - } - - template - or_condition_t or_(R right) const { - return {this->value, std::move(right)}; - } - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool - is_operator_argument_v::value>> = true; - - template - constexpr T get_from_expression(T&& value) { - return std::move(value); - } - - template - constexpr const T& get_from_expression(const T& value) { - return value; - } - - template - constexpr T get_from_expression(expression_t&& expression) { - return std::move(expression.value); - } - - template - constexpr const T& get_from_expression(const expression_t& expression) { - return expression.value; - } - - template - using unwrap_expression_t = decltype(get_from_expression(std::declval())); - } - - /** - * Public interface for syntax sugar for columns. Example: `where(c(&User::id) == 5)` or - * `storage.update(set(c(&User::name) = "Dua Lipa")); - */ - template - constexpr internal::expression_t c(T value) { - return {std::move(value)}; - } -} - -// #include "column_pointer.h" - -// #include "tags.h" - -// #include "type_printer.h" - -// #include "literal.h" - -namespace sqlite_orm { - namespace internal { - - /* - * Protect an otherwise bindable element so that it is always serialized as a literal value. - */ - template - struct literal_holder { - using type = T; - - type value; - }; - - } -} - -namespace sqlite_orm { - - namespace internal { - - struct limit_string { - operator std::string() const { - return "LIMIT"; - } - }; - - /** - * Stores LIMIT/OFFSET info - */ - template - struct limit_t : limit_string { - T lim; - optional_container off; - - limit_t() = default; - - limit_t(decltype(lim) lim_) : lim(std::move(lim_)) {} - - limit_t(decltype(lim) lim_, decltype(off) off_) : lim(std::move(lim_)), off(std::move(off_)) {} - }; - - template - struct is_limit : std::false_type {}; - - template - struct is_limit> : std::true_type {}; - - /** - * Stores OFFSET only info - */ - template - struct offset_t { - T off; - }; - - template - using is_offset = polyfill::is_specialization_of; - - /** - * Collated something - */ - template - struct collate_t : public condition_t { - T expr; - collate_argument argument; - - collate_t(T expr_, collate_argument argument_) : expr(std::move(expr_)), argument(argument_) {} - - operator std::string() const { - return collate_constraint_t{this->argument}; - } - }; - - struct named_collate_base { - std::string name; - - operator std::string() const { - return "COLLATE " + this->name; - } - }; - - /** - * Collated something with custom collate function - */ - template - struct named_collate : named_collate_base { - T expr; - - named_collate(T expr_, std::string name_) : named_collate_base{std::move(name_)}, expr(std::move(expr_)) {} - }; - - struct negated_condition_string { - operator std::string() const { - return "NOT"; - } - }; - - /** - * Result of not operator - */ - template - struct negated_condition_t : condition_t, negated_condition_string { - using argument_type = C; - - argument_type c; - - constexpr negated_condition_t(argument_type arg) : c(std::move(arg)) {} - }; - - /** - * Base class for binary conditions - * L is left argument type - * R is right argument type - * S is 'string' class (a class which has cast to `std::string` operator) - * Res is result type - */ - template - struct binary_condition : condition_t, S { - using left_type = L; - using right_type = R; - using result_type = Res; - - left_type lhs; - right_type rhs; - - constexpr binary_condition() = default; - - constexpr binary_condition(left_type l_, right_type r_) : lhs(std::move(l_)), rhs(std::move(r_)) {} - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_binary_condition_v = is_base_of_template_v; - - template - struct is_binary_condition : polyfill::bool_constant> {}; - - struct and_condition_string { - serialize_result_type serialize() const { - return "AND"; - } - }; - - /** - * Result of and operator - */ - template - struct and_condition_t : binary_condition, negatable_t { - using super = binary_condition; - - using super::super; - }; - - struct or_condition_string { - serialize_result_type serialize() const { - return "OR"; - } - }; - - /** - * Result of or operator - */ - template - struct or_condition_t : binary_condition, negatable_t { - using super = binary_condition; - - using super::super; - }; - - struct is_equal_string { - serialize_result_type serialize() const { - return "="; - } - }; - - /** - * = and == operators object - */ - template - struct is_equal_t : binary_condition, negatable_t { - using self = is_equal_t; - - using binary_condition::binary_condition; - - collate_t collate_binary() const { - return {*this, collate_argument::binary}; - } - - collate_t collate_nocase() const { - return {*this, collate_argument::nocase}; - } - - collate_t collate_rtrim() const { - return {*this, collate_argument::rtrim}; - } - - named_collate collate(std::string name) const { - return {*this, std::move(name)}; - } - - template - named_collate collate() const { - std::stringstream ss; - ss << C::name() << std::flush; - return {*this, ss.str()}; - } - }; - - template - struct is_equal_with_table_t : negatable_t { - using left_type = L; - using right_type = R; - - right_type rhs; - - is_equal_with_table_t(right_type rhs) : rhs(std::move(rhs)) {} - }; - - struct is_not_equal_string { - serialize_result_type serialize() const { - return "!="; - } - }; - - /** - * != operator object - */ - template - struct is_not_equal_t : binary_condition, negatable_t { - using self = is_not_equal_t; - - using binary_condition::binary_condition; - - collate_t collate_binary() const { - return {*this, collate_argument::binary}; - } - - collate_t collate_nocase() const { - return {*this, collate_argument::nocase}; - } - - collate_t collate_rtrim() const { - return {*this, collate_argument::rtrim}; - } - }; - - struct greater_than_string { - serialize_result_type serialize() const { - return ">"; - } - }; - - /** - * > operator object. - */ - template - struct greater_than_t : binary_condition, negatable_t { - using self = greater_than_t; - - using binary_condition::binary_condition; - - collate_t collate_binary() const { - return {*this, collate_argument::binary}; - } - - collate_t collate_nocase() const { - return {*this, collate_argument::nocase}; - } - - collate_t collate_rtrim() const { - return {*this, collate_argument::rtrim}; - } - }; - - struct greater_or_equal_string { - serialize_result_type serialize() const { - return ">="; - } - }; - - /** - * >= operator object. - */ - template - struct greater_or_equal_t : binary_condition, negatable_t { - using self = greater_or_equal_t; - - using binary_condition::binary_condition; - - collate_t collate_binary() const { - return {*this, collate_argument::binary}; - } - - collate_t collate_nocase() const { - return {*this, collate_argument::nocase}; - } - - collate_t collate_rtrim() const { - return {*this, collate_argument::rtrim}; - } - }; - - struct less_than_string { - serialize_result_type serialize() const { - return "<"; - } - }; - - /** - * < operator object. - */ - template - struct less_than_t : binary_condition, negatable_t { - using self = less_than_t; - - using binary_condition::binary_condition; - - collate_t collate_binary() const { - return {*this, collate_argument::binary}; - } - - collate_t collate_nocase() const { - return {*this, collate_argument::nocase}; - } - - collate_t collate_rtrim() const { - return {*this, collate_argument::rtrim}; - } - }; - - struct less_or_equal_string { - serialize_result_type serialize() const { - return "<="; - } - }; - - /** - * <= operator object. - */ - template - struct less_or_equal_t : binary_condition, negatable_t { - using self = less_or_equal_t; - - using binary_condition::binary_condition; - - collate_t collate_binary() const { - return {*this, collate_argument::binary}; - } - - collate_t collate_nocase() const { - return {*this, collate_argument::nocase}; - } - - collate_t collate_rtrim() const { - return {*this, collate_argument::rtrim}; - } - }; - - struct in_base { - bool negative = false; // used in not_in - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - in_base(bool negative) : negative{negative} {} -#endif - }; - - /** - * IN operator object. - */ - template - struct dynamic_in_t : condition_t, in_base, negatable_t { - using self = dynamic_in_t; - - L left; // left expression - A argument; // in arg - - dynamic_in_t(L left_, A argument_, bool negative_) : - in_base{negative_}, left(std::move(left_)), argument(std::move(argument_)) {} - }; - - template - struct in_t : condition_t, in_base, negatable_t { - L left; - std::tuple argument; - - in_t(L left_, decltype(argument) argument_, bool negative_) : - in_base{negative_}, left(std::move(left_)), argument(std::move(argument_)) {} - }; - - struct is_null_string { - operator std::string() const { - return "IS NULL"; - } - }; - - /** - * IS NULL operator object. - */ - template - struct is_null_t : is_null_string, negatable_t { - using self = is_null_t; - - T t; - - is_null_t(T t_) : t(std::move(t_)) {} - }; - - struct is_not_null_string { - operator std::string() const { - return "IS NOT NULL"; - } - }; - - /** - * IS NOT NULL operator object. - */ - template - struct is_not_null_t : is_not_null_string, negatable_t { - using self = is_not_null_t; - - T t; - - is_not_null_t(T t_) : t(std::move(t_)) {} - }; - - struct order_by_base { - int asc_desc = 0; // 1: asc, -1: desc - std::string _collate_argument; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - order_by_base() = default; - - order_by_base(decltype(asc_desc) asc_desc_, decltype(_collate_argument) _collate_argument_) : - asc_desc(asc_desc_), _collate_argument(std::move(_collate_argument_)) {} -#endif - }; - - struct order_by_string { - operator std::string() const { - return "ORDER BY"; - } - }; - - /** - * ORDER BY argument holder. - */ - template - struct order_by_t : order_by_base, order_by_string { - using expression_type = O; - using self = order_by_t; - - expression_type expression; - - order_by_t(expression_type expression_) : order_by_base(), expression(std::move(expression_)) {} - - self asc() const { - auto res = *this; - res.asc_desc = 1; - return res; - } - - self desc() const { - auto res = *this; - res.asc_desc = -1; - return res; - } - - self collate_binary() const { - auto res = *this; - res._collate_argument = collate_constraint_t::string_from_collate_argument(collate_argument::binary); - return res; - } - - self collate_nocase() const { - auto res = *this; - res._collate_argument = collate_constraint_t::string_from_collate_argument(collate_argument::nocase); - return res; - } - - self collate_rtrim() const { - auto res = *this; - res._collate_argument = collate_constraint_t::string_from_collate_argument(collate_argument::rtrim); - return res; - } - - self collate(std::string name) const { - auto res = *this; - res._collate_argument = std::move(name); - return res; - } - - template - self collate() const { - std::stringstream ss; - ss << C::name() << std::flush; - return this->collate(ss.str()); - } - }; - - /** - * ORDER BY pack holder. - */ - template - struct multi_order_by_t : order_by_string { - using args_type = std::tuple; - - args_type args; - - multi_order_by_t(args_type args_) : args{std::move(args_)} {} - }; - - struct dynamic_order_by_entry_t : order_by_base { - std::string name; - - dynamic_order_by_entry_t(decltype(name) name_, int asc_desc_, std::string collate_argument_) : - order_by_base{asc_desc_, std::move(collate_argument_)}, name(std::move(name_)) {} - }; - - /** - * C - serializer context class - */ - template - struct dynamic_order_by_t : order_by_string { - using context_t = C; - using entry_t = dynamic_order_by_entry_t; - using const_iterator = typename std::vector::const_iterator; - - dynamic_order_by_t(const context_t& context_) : context(context_) {} - - template - void push_back(order_by_t order_by) { - auto newContext = this->context; - newContext.skip_table_name = false; - auto columnName = serialize(order_by.expression, newContext); - this->entries.emplace_back(std::move(columnName), - order_by.asc_desc, - std::move(order_by._collate_argument)); - } - - const_iterator begin() const { - return this->entries.begin(); - } - - const_iterator end() const { - return this->entries.end(); - } - - void clear() { - this->entries.clear(); - } - - protected: - std::vector entries; - context_t context; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_order_by_v = - polyfill::disjunction, - polyfill::is_specialization_of, - polyfill::is_specialization_of>::value; - - template - struct is_order_by : polyfill::bool_constant> {}; - - struct between_string { - operator std::string() const { - return "BETWEEN"; - } - }; - - /** - * BETWEEN operator object. - */ - template - struct between_t : condition_t, between_string { - using expression_type = A; - using lower_type = T; - using upper_type = T; - - expression_type expr; - lower_type b1; - upper_type b2; - - between_t(expression_type expr_, lower_type b1_, upper_type b2_) : - expr(std::move(expr_)), b1(std::move(b1_)), b2(std::move(b2_)) {} - }; - - struct like_string { - operator std::string() const { - return "LIKE"; - } - }; - - /** - * LIKE operator object. - */ - template - struct like_t : condition_t, like_string, negatable_t { - using self = like_t; - using arg_t = A; - using pattern_t = T; - using escape_t = E; - - arg_t arg; - pattern_t pattern; - optional_container arg3; // not escape cause escape exists as a function here - - like_t(arg_t arg_, pattern_t pattern_, optional_container escape_) : - arg(std::move(arg_)), pattern(std::move(pattern_)), arg3(std::move(escape_)) {} - - template - like_t escape(C c) const { - optional_container newArg3{std::move(c)}; - return {std::move(this->arg), std::move(this->pattern), std::move(newArg3)}; - } - }; - - struct glob_string { - operator std::string() const { - return "GLOB"; - } - }; - - template - struct glob_t : condition_t, glob_string, negatable_t { - using self = glob_t; - using arg_t = A; - using pattern_t = T; - - arg_t arg; - pattern_t pattern; - - glob_t(arg_t arg_, pattern_t pattern_) : arg(std::move(arg_)), pattern(std::move(pattern_)) {} - }; - - struct cross_join_string { - operator std::string() const { - return "CROSS JOIN"; - } - }; - - /** - * CROSS JOIN holder. - * T is joined type which represents any mapped table. - */ - template - struct cross_join_t : cross_join_string { - using type = T; - }; - - struct natural_join_string { - operator std::string() const { - return "NATURAL JOIN"; - } - }; - - /** - * NATURAL JOIN holder. - * T is joined type which represents any mapped table. - */ - template - struct natural_join_t : natural_join_string { - using type = T; - }; - - struct left_join_string { - operator std::string() const { - return "LEFT JOIN"; - } - }; - - /** - * LEFT JOIN holder. - * T is joined type which represents any mapped table. - * O is on(...) argument type. - */ - template - struct left_join_t : left_join_string { - using type = T; - using on_type = O; - - on_type constraint; - - left_join_t(on_type constraint_) : constraint(std::move(constraint_)) {} - }; - - struct join_string { - operator std::string() const { - return "JOIN"; - } - }; - - /** - * Simple JOIN holder. - * T is joined type which represents any mapped table. - * O is on(...) argument type. - */ - template - struct join_t : join_string { - using type = T; - using on_type = O; - - on_type constraint; - - join_t(on_type constraint_) : constraint(std::move(constraint_)) {} - }; - - struct left_outer_join_string { - operator std::string() const { - return "LEFT OUTER JOIN"; - } - }; - - /** - * LEFT OUTER JOIN holder. - * T is joined type which represents any mapped table. - * O is on(...) argument type. - */ - template - struct left_outer_join_t : left_outer_join_string { - using type = T; - using on_type = O; - - on_type constraint; - - left_outer_join_t(on_type constraint_) : constraint(std::move(constraint_)) {} - }; - - struct on_string { - operator std::string() const { - return "ON"; - } - }; - - /** - * on(...) argument holder used for JOIN, LEFT JOIN, LEFT OUTER JOIN and INNER JOIN - * T is on type argument. - */ - template - struct on_t : on_string { - using arg_type = T; - - arg_type arg; - - on_t(arg_type arg_) : arg(std::move(arg_)) {} - }; - - /** - * USING argument holder. - */ - template - struct using_t { - column_pointer column; - - operator std::string() const { - return "USING"; - } - }; - - struct inner_join_string { - operator std::string() const { - return "INNER JOIN"; - } - }; - - /** - * INNER JOIN holder. - * T is joined type which represents any mapped table. - * O is on(...) argument type. - */ - template - struct inner_join_t : inner_join_string { - using type = T; - using on_type = O; - - on_type constraint; - - inner_join_t(on_type constraint_) : constraint(std::move(constraint_)) {} - }; - - struct cast_string { - operator std::string() const { - return "CAST"; - } - }; - - /** - * CAST holder. - * T is a type to cast to - * E is an expression type - * Example: cast(&User::id) - */ - template - struct cast_t : cast_string { - using to_type = T; - using expression_type = E; - - expression_type expression; - - cast_t(expression_type expression_) : expression(std::move(expression_)) {} - }; - - template - struct from_t { - using tuple_type = std::tuple; - }; - - template - using is_from = polyfill::is_specialization_of; - - template - using is_constrained_join = polyfill::is_detected; - } - - /** - * Explicit FROM function. Usage: - * `storage.select(&User::id, from());` - */ - template - internal::from_t from() { - static_assert(sizeof...(Tables) > 0, ""); - return {}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Explicit FROM function. Usage: - * `storage.select(&User::id, from<"a"_alias.for_>());` - */ - template - auto from() { - return from...>(); - } -#endif - - // Intentionally place operators for types classified as arithmetic or general operator arguments in the internal namespace - // to facilitate ADL (Argument Dependent Lookup) - namespace internal { - template< - class T, - std::enable_if_t, is_operator_argument>::value, - bool> = true> - constexpr negated_condition_t operator!(T arg) { - return {std::move(arg)}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr less_than_t, unwrap_expression_t> operator<(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr less_or_equal_t, unwrap_expression_t> operator<=(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr greater_than_t, unwrap_expression_t> operator>(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr greater_or_equal_t, unwrap_expression_t> operator>=(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - std::is_base_of, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr is_equal_t, unwrap_expression_t> operator==(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - std::is_base_of, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr is_not_equal_t, unwrap_expression_t> operator!=(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr and_condition_t, unwrap_expression_t> operator&&(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, std::is_base_of>::value, - bool> = true> - constexpr or_condition_t, unwrap_expression_t> operator||(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template< - class L, - class R, - std::enable_if_t, - std::is_base_of, - is_operator_argument, - is_operator_argument>, - // exclude conditions - polyfill::negation, - std::is_base_of>>>::value, - bool> = true> - constexpr conc_t, unwrap_expression_t> operator||(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - } - - template - internal::using_t using_(F O::* field) { - return {field}; - } - template - internal::using_t using_(internal::column_pointer field) { - return {std::move(field)}; - } - - template - internal::on_t on(T t) { - return {std::move(t)}; - } - - template - internal::cross_join_t cross_join() { - return {}; - } - - template - internal::natural_join_t natural_join() { - return {}; - } - - template - internal::left_join_t left_join(O o) { - return {std::move(o)}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - auto left_join(On on) { - return left_join, On>(std::move(on)); - } -#endif - - template - internal::join_t join(O o) { - return {std::move(o)}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - auto join(On on) { - return join, On>(std::move(on)); - } -#endif - - template - internal::left_outer_join_t left_outer_join(O o) { - return {std::move(o)}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - auto left_outer_join(On on) { - return left_outer_join, On>(std::move(on)); - } -#endif - - template - internal::inner_join_t inner_join(O o) { - return {std::move(o)}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - auto inner_join(On on) { - return inner_join, On>(std::move(on)); - } -#endif - - template - internal::offset_t offset(T off) { - return {std::move(off)}; - } - - template - internal::limit_t limit(T lim) { - return {std::move(lim)}; - } - - template = true> - internal::limit_t limit(O off, T lim) { - return {std::move(lim), {std::move(off)}}; - } - - template - internal::limit_t limit(T lim, internal::offset_t offt) { - return {std::move(lim), {std::move(offt.off)}}; - } - - template - constexpr auto and_(L l, R r) { - using namespace ::sqlite_orm::internal; - return and_condition_t, unwrap_expression_t>{get_from_expression(std::forward(l)), - get_from_expression(std::forward(r))}; - } - - template - constexpr auto or_(L l, R r) { - using namespace ::sqlite_orm::internal; - return or_condition_t, unwrap_expression_t>{get_from_expression(std::forward(l)), - get_from_expression(std::forward(r))}; - } - - template - internal::is_not_null_t is_not_null(T t) { - return {std::move(t)}; - } - - template - internal::is_null_t is_null(T t) { - return {std::move(t)}; - } - - template - internal::dynamic_in_t> in(L l, std::vector values) { - return {std::move(l), std::move(values), false}; - } - - template - internal::dynamic_in_t> in(L l, std::initializer_list values) { - return {std::move(l), std::move(values), false}; - } - - template - internal::dynamic_in_t in(L l, A arg) { - return {std::move(l), std::move(arg), false}; - } - - template - internal::dynamic_in_t> not_in(L l, std::vector values) { - return {std::move(l), std::move(values), true}; - } - - template - internal::dynamic_in_t> not_in(L l, std::initializer_list values) { - return {std::move(l), std::move(values), true}; - } - - template - internal::dynamic_in_t not_in(L l, A arg) { - return {std::move(l), std::move(arg), true}; - } - - template - constexpr internal::is_equal_t is_equal(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::is_equal_t eq(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::is_equal_with_table_t is_equal(R rhs) { - return {std::move(rhs)}; - } - - template - constexpr internal::is_not_equal_t is_not_equal(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::is_not_equal_t ne(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::greater_than_t greater_than(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::greater_than_t gt(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::greater_or_equal_t greater_or_equal(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::greater_or_equal_t ge(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::less_than_t less_than(L l, R r) { - return {std::move(l), std::move(r)}; - } - - /** - * [Deprecation notice] This function is deprecated and will be removed in v1.10. Use the accurately named function `less_than(...)` instead. - */ - template - [[deprecated("Use the accurately named function `less_than(...)` instead")]] internal::less_than_t - lesser_than(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::less_than_t lt(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::less_or_equal_t less_or_equal(L l, R r) { - return {std::move(l), std::move(r)}; - } - - /** - * [Deprecation notice] This function is deprecated and will be removed in v1.10. Use the accurately named function `less_or_equal(...)` instead. - */ - template - [[deprecated("Use the accurately named function `less_or_equal(...)` instead")]] internal::less_or_equal_t - lesser_or_equal(L l, R r) { - return {std::move(l), std::move(r)}; - } - - template - constexpr internal::less_or_equal_t le(L l, R r) { - return {std::move(l), std::move(r)}; - } - - /** - * ORDER BY column, column alias or expression - * - * Examples: - * storage.select(&User::name, order_by(&User::id)) - * storage.select(as(&User::name), order_by(get())) - */ - template> = true> - internal::order_by_t order_by(O o) { - return {std::move(o)}; - } - - /** - * ORDER BY positional ordinal - * - * Examples: - * storage.select(&User::name, order_by(1)) - */ - template> = true> - internal::order_by_t> order_by(O o) { - return {{std::move(o)}}; - } - - /** - * ORDER BY column1, column2 - * Example: storage.get_all(multi_order_by(order_by(&Singer::name).asc(), order_by(&Singer::gender).desc()) - */ - template - internal::multi_order_by_t multi_order_by(Args... args) { - return {{std::forward(args)...}}; - } - - /** - * ORDER BY column1, column2 - * Difference from `multi_order_by` is that `dynamic_order_by` can be changed at runtime using `push_back` member - * function Example: - * auto orderBy = dynamic_order_by(storage); - * if(someCondition) { - * orderBy.push_back(&User::id); - * } else { - * orderBy.push_back(&User::name); - * orderBy.push_back(&User::birthDate); - * } - */ - template - internal::dynamic_order_by_t> - dynamic_order_by(const S& storage) { - internal::serializer_context_builder builder(storage); - return builder(); - } - - /** - * X BETWEEN Y AND Z - * Example: storage.select(between(&User::id, 10, 20)) - */ - template - internal::between_t between(A expr, T b1, T b2) { - return {std::move(expr), std::move(b1), std::move(b2)}; - } - - /** - * X LIKE Y - * Example: storage.select(like(&User::name, "T%")) - */ - template - internal::like_t like(A a, T t) { - return {std::move(a), std::move(t), {}}; - } - - /** - * X GLOB Y - * Example: storage.select(glob(&User::name, "*S")) - */ - template - internal::glob_t glob(A a, T t) { - return {std::move(a), std::move(t)}; - } - - /** - * X LIKE Y ESCAPE Z - * Example: storage.select(like(&User::name, "T%", "%")) - */ - template - internal::like_t like(A a, T t, E e) { - return {std::move(a), std::move(t), {std::move(e)}}; - } - - /** - * CAST(X AS type). - * Example: cast(&User::id) - */ - template - internal::cast_t cast(E e) { - return {std::move(e)}; - } -} - -// #include "serialize_result_type.h" - -// #include "operators.h" - -// #include "tags.h" - -// #include "table_reference.h" - -// #include "ast/into.h" - -// #include "../functional/cxx_type_traits_polyfill.h" - -namespace sqlite_orm { - namespace internal { - - template - struct into_t { - using type = T; - }; - - template - using is_into = polyfill::is_specialization_of; - } - - template - internal::into_t into() { - return {}; - } -} - -namespace sqlite_orm { - - using int64 = sqlite_int64; - using uint64 = sqlite_uint64; - - namespace internal { - - template - struct unique_ptr_result_of {}; - - /** - * Base class for operator overloading - * R - return type - * S - class with operator std::string - * Args - function arguments types - */ - template - struct built_in_function_t : S, arithmetic_t { - using return_type = R; - using string_type = S; - using args_type = std::tuple; - - static constexpr size_t args_size = std::tuple_size::value; - - args_type args; - - built_in_function_t(args_type&& args_) : args(std::move(args_)) {} - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_built_in_function_v = - is_base_of_template::value; - - template - struct is_built_in_function : polyfill::bool_constant> {}; - - template - struct filtered_aggregate_function { - using function_type = F; - using where_expression = W; - - function_type function; - where_expression where; - }; - - template - struct where_t; - - template - struct built_in_aggregate_function_t : built_in_function_t { - using super = built_in_function_t; - - using super::super; - - template - filtered_aggregate_function, W> filter(where_t wh) { - return {*this, std::move(wh.expression)}; - } - }; - - struct typeof_string { - serialize_result_type serialize() const { - return "TYPEOF"; - } - }; - - struct unicode_string { - serialize_result_type serialize() const { - return "UNICODE"; - } - }; - - struct length_string { - serialize_result_type serialize() const { - return "LENGTH"; - } - }; - - struct abs_string { - serialize_result_type serialize() const { - return "ABS"; - } - }; - - struct lower_string { - serialize_result_type serialize() const { - return "LOWER"; - } - }; - - struct upper_string { - serialize_result_type serialize() const { - return "UPPER"; - } - }; - - struct last_insert_rowid_string { - serialize_result_type serialize() const { - return "LAST_INSERT_ROWID"; - } - }; - - struct total_changes_string { - serialize_result_type serialize() const { - return "TOTAL_CHANGES"; - } - }; - - struct changes_string { - serialize_result_type serialize() const { - return "CHANGES"; - } - }; - - struct trim_string { - serialize_result_type serialize() const { - return "TRIM"; - } - }; - - struct ltrim_string { - serialize_result_type serialize() const { - return "LTRIM"; - } - }; - - struct rtrim_string { - serialize_result_type serialize() const { - return "RTRIM"; - } - }; - - struct hex_string { - serialize_result_type serialize() const { - return "HEX"; - } - }; - - struct quote_string { - serialize_result_type serialize() const { - return "QUOTE"; - } - }; - - struct randomblob_string { - serialize_result_type serialize() const { - return "RANDOMBLOB"; - } - }; - - struct instr_string { - serialize_result_type serialize() const { - return "INSTR"; - } - }; - - struct replace_string { - serialize_result_type serialize() const { - return "REPLACE"; - } - }; - - struct round_string { - serialize_result_type serialize() const { - return "ROUND"; - } - }; - -#if SQLITE_VERSION_NUMBER >= 3007016 - struct char_string { - serialize_result_type serialize() const { - return "CHAR"; - } - }; - - struct random_string { - serialize_result_type serialize() const { - return "RANDOM"; - } - }; - -#endif - - struct coalesce_string { - serialize_result_type serialize() const { - return "COALESCE"; - } - }; - - struct ifnull_string { - serialize_result_type serialize() const { - return "IFNULL"; - } - }; - - struct nullif_string { - serialize_result_type serialize() const { - return "NULLIF"; - } - }; - - struct date_string { - serialize_result_type serialize() const { - return "DATE"; - } - }; - - struct time_string { - serialize_result_type serialize() const { - return "TIME"; - } - }; - - struct datetime_string { - serialize_result_type serialize() const { - return "DATETIME"; - } - }; - - struct julianday_string { - serialize_result_type serialize() const { - return "JULIANDAY"; - } - }; - - struct strftime_string { - serialize_result_type serialize() const { - return "STRFTIME"; - } - }; - - struct zeroblob_string { - serialize_result_type serialize() const { - return "ZEROBLOB"; - } - }; - - struct substr_string { - serialize_result_type serialize() const { - return "SUBSTR"; - } - }; -#ifdef SQLITE_SOUNDEX - struct soundex_string { - serialize_result_type serialize() const { - return "SOUNDEX"; - } - }; -#endif - struct total_string { - serialize_result_type serialize() const { - return "TOTAL"; - } - }; - - struct sum_string { - serialize_result_type serialize() const { - return "SUM"; - } - }; - - struct count_string { - serialize_result_type serialize() const { - return "COUNT"; - } - }; - - /** - * T is use to specify type explicitly for queries like - * SELECT COUNT(*) FROM table_name; - * T can be omitted with void. - */ - template - struct count_asterisk_t : count_string { - using type = T; - - template - filtered_aggregate_function, W> filter(where_t wh) { - return {*this, std::move(wh.expression)}; - } - }; - - /** - * The same thing as count() but without T arg. - * Is used in cases like this: - * SELECT cust_code, cust_name, cust_city, grade - * FROM customer - * WHERE grade=2 AND EXISTS - * (SELECT COUNT(*) - * FROM customer - * WHERE grade=2 - * GROUP BY grade - * HAVING COUNT(*)>2); - * `c++` - * auto rows = - * storage.select(columns(&Customer::code, &Customer::name, &Customer::city, &Customer::grade), - * where(is_equal(&Customer::grade, 2) - * and exists(select(count(), - * where(is_equal(&Customer::grade, 2)), - * group_by(&Customer::grade), - * having(greater_than(count(), 2)))))); - */ - struct count_asterisk_without_type : count_string {}; - - struct avg_string { - serialize_result_type serialize() const { - return "AVG"; - } - }; - - struct max_string { - serialize_result_type serialize() const { - return "MAX"; - } - }; - - struct min_string { - serialize_result_type serialize() const { - return "MIN"; - } - }; - - struct group_concat_string { - serialize_result_type serialize() const { - return "GROUP_CONCAT"; - } - }; -#ifdef SQLITE_ENABLE_MATH_FUNCTIONS - struct acos_string { - serialize_result_type serialize() const { - return "ACOS"; - } - }; - - struct acosh_string { - serialize_result_type serialize() const { - return "ACOSH"; - } - }; - - struct asin_string { - serialize_result_type serialize() const { - return "ASIN"; - } - }; - - struct asinh_string { - serialize_result_type serialize() const { - return "ASINH"; - } - }; - - struct atan_string { - serialize_result_type serialize() const { - return "ATAN"; - } - }; - - struct atan2_string { - serialize_result_type serialize() const { - return "ATAN2"; - } - }; - - struct atanh_string { - serialize_result_type serialize() const { - return "ATANH"; - } - }; - - struct ceil_string { - serialize_result_type serialize() const { - return "CEIL"; - } - }; - - struct ceiling_string { - serialize_result_type serialize() const { - return "CEILING"; - } - }; - - struct cos_string { - serialize_result_type serialize() const { - return "COS"; - } - }; - - struct cosh_string { - serialize_result_type serialize() const { - return "COSH"; - } - }; - - struct degrees_string { - serialize_result_type serialize() const { - return "DEGREES"; - } - }; - - struct exp_string { - serialize_result_type serialize() const { - return "EXP"; - } - }; - - struct floor_string { - serialize_result_type serialize() const { - return "FLOOR"; - } - }; - - struct ln_string { - serialize_result_type serialize() const { - return "LN"; - } - }; - - struct log_string { - serialize_result_type serialize() const { - return "LOG"; - } - }; - - struct log10_string { - serialize_result_type serialize() const { - return "LOG10"; - } - }; - - struct log2_string { - serialize_result_type serialize() const { - return "LOG2"; - } - }; - - struct mod_string { - serialize_result_type serialize() const { - return "MOD"; - } - }; - - struct pi_string { - serialize_result_type serialize() const { - return "PI"; - } - }; - - struct pow_string { - serialize_result_type serialize() const { - return "POW"; - } - }; - - struct power_string { - serialize_result_type serialize() const { - return "POWER"; - } - }; - - struct radians_string { - serialize_result_type serialize() const { - return "RADIANS"; - } - }; - - struct sin_string { - serialize_result_type serialize() const { - return "SIN"; - } - }; - - struct sinh_string { - serialize_result_type serialize() const { - return "SINH"; - } - }; - - struct sqrt_string { - serialize_result_type serialize() const { - return "SQRT"; - } - }; - - struct tan_string { - serialize_result_type serialize() const { - return "TAN"; - } - }; - - struct tanh_string { - serialize_result_type serialize() const { - return "TANH"; - } - }; - - struct trunc_string { - serialize_result_type serialize() const { - return "TRUNC"; - } - }; - -#endif // SQLITE_ENABLE_MATH_FUNCTIONS -#ifdef SQLITE_ENABLE_JSON1 - struct json_string { - serialize_result_type serialize() const { - return "JSON"; - } - }; - - struct json_array_string { - serialize_result_type serialize() const { - return "JSON_ARRAY"; - } - }; - - struct json_array_length_string { - serialize_result_type serialize() const { - return "JSON_ARRAY_LENGTH"; - } - }; - - struct json_extract_string { - serialize_result_type serialize() const { - return "JSON_EXTRACT"; - } - }; - - struct json_insert_string { - serialize_result_type serialize() const { - return "JSON_INSERT"; - } - }; - - struct json_replace_string { - serialize_result_type serialize() const { - return "JSON_REPLACE"; - } - }; - - struct json_set_string { - serialize_result_type serialize() const { - return "JSON_SET"; - } - }; - - struct json_object_string { - serialize_result_type serialize() const { - return "JSON_OBJECT"; - } - }; - - struct json_patch_string { - serialize_result_type serialize() const { - return "JSON_PATCH"; - } - }; - - struct json_remove_string { - serialize_result_type serialize() const { - return "JSON_REMOVE"; - } - }; - - struct json_type_string { - serialize_result_type serialize() const { - return "JSON_TYPE"; - } - }; - - struct json_valid_string { - serialize_result_type serialize() const { - return "JSON_VALID"; - } - }; - - struct json_quote_string { - serialize_result_type serialize() const { - return "JSON_QUOTE"; - } - }; - - struct json_group_array_string { - serialize_result_type serialize() const { - return "JSON_GROUP_ARRAY"; - } - }; - - struct json_group_object_string { - serialize_result_type serialize() const { - return "JSON_GROUP_OBJECT"; - } - }; -#endif // SQLITE_ENABLE_JSON1 - - template - using field_type_or_type_t = polyfill::detected_or_t>; - - template - struct highlight_t { - using table_type = T; - using argument0_type = X; - using argument1_type = Y; - using argument2_type = Z; - - argument0_type argument0; - argument1_type argument1; - argument2_type argument2; - - highlight_t(argument0_type argument0, argument1_type argument1, argument2_type argument2) : - argument0(std::move(argument0)), argument1(std::move(argument1)), argument2(std::move(argument2)) {} - }; - } - -#ifdef SQLITE_ENABLE_MATH_FUNCTIONS - - /** - * ACOS(X) function https://www.sqlite.org/lang_mathfunc.html#acos - * - * Example: - * - * auto rows = storage.select(sqlite_orm::acos(&Triangle::cornerA)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t acos(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ACOS(X) function https://www.sqlite.org/lang_mathfunc.html#acos - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::acos>(&Triangle::cornerA)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t acos(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ACOSH(X) function https://www.sqlite.org/lang_mathfunc.html#acosh - * - * Example: - * - * auto rows = storage.select(sqlite_orm::acosh(&Triangle::cornerA)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t acosh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ACOSH(X) function https://www.sqlite.org/lang_mathfunc.html#acosh - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::acosh>(&Triangle::cornerA)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t acosh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ASIN(X) function https://www.sqlite.org/lang_mathfunc.html#asin - * - * Example: - * - * auto rows = storage.select(sqlite_orm::asin(&Triangle::cornerA)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t asin(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ASIN(X) function https://www.sqlite.org/lang_mathfunc.html#asin - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::asin>(&Triangle::cornerA)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t asin(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ASINH(X) function https://www.sqlite.org/lang_mathfunc.html#asinh - * - * Example: - * - * auto rows = storage.select(sqlite_orm::asinh(&Triangle::cornerA)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t asinh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ASINH(X) function https://www.sqlite.org/lang_mathfunc.html#asinh - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::asinh>(&Triangle::cornerA)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t asinh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ATAN(X) function https://www.sqlite.org/lang_mathfunc.html#atan - * - * Example: - * - * auto rows = storage.select(sqlite_orm::atan(1)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t atan(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ATAN(X) function https://www.sqlite.org/lang_mathfunc.html#atan - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::atan>(1)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t atan(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ATAN2(X, Y) function https://www.sqlite.org/lang_mathfunc.html#atan2 - * - * Example: - * - * auto rows = storage.select(sqlite_orm::atan2(1, 3)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t atan2(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * ATAN2(X, Y) function https://www.sqlite.org/lang_mathfunc.html#atan2 - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::atan2>(1, 3)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t atan2(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * ATANH(X) function https://www.sqlite.org/lang_mathfunc.html#atanh - * - * Example: - * - * auto rows = storage.select(sqlite_orm::atanh(1)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t atanh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ATANH(X) function https://www.sqlite.org/lang_mathfunc.html#atanh - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::atanh>(1)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t atanh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * CEIL(X) function https://www.sqlite.org/lang_mathfunc.html#ceil - * - * Example: - * - * auto rows = storage.select(sqlite_orm::ceil(&User::rating)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t ceil(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * CEIL(X) function https://www.sqlite.org/lang_mathfunc.html#ceil - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::ceil>(&User::rating)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t ceil(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * CEILING(X) function https://www.sqlite.org/lang_mathfunc.html#ceil - * - * Example: - * - * auto rows = storage.select(sqlite_orm::ceiling(&User::rating)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t ceiling(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * CEILING(X) function https://www.sqlite.org/lang_mathfunc.html#ceil - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::ceiling>(&User::rating)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t ceiling(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * COS(X) function https://www.sqlite.org/lang_mathfunc.html#cos - * - * Example: - * - * auto rows = storage.select(sqlite_orm::cos(&Triangle::cornerB)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t cos(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * COS(X) function https://www.sqlite.org/lang_mathfunc.html#cos - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::cos>(&User::rating)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t cos(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * COSH(X) function https://www.sqlite.org/lang_mathfunc.html#cosh - * - * Example: - * - * auto rows = storage.select(sqlite_orm::cosh(&Triangle::cornerB)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t cosh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * COSH(X) function https://www.sqlite.org/lang_mathfunc.html#cosh - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::cosh>(&User::rating)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t cosh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * DEGREES(X) function https://www.sqlite.org/lang_mathfunc.html#degrees - * - * Example: - * - * auto rows = storage.select(sqlite_orm::degrees(&Triangle::cornerB)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t degrees(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * DEGREES(X) function https://www.sqlite.org/lang_mathfunc.html#degrees - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::degrees>(&User::rating)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t degrees(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * EXP(X) function https://www.sqlite.org/lang_mathfunc.html#exp - * - * Example: - * - * auto rows = storage.select(sqlite_orm::exp(&Triangle::cornerB)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t exp(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * EXP(X) function https://www.sqlite.org/lang_mathfunc.html#exp - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::exp>(&User::rating)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t exp(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * FLOOR(X) function https://www.sqlite.org/lang_mathfunc.html#floor - * - * Example: - * - * auto rows = storage.select(sqlite_orm::floor(&User::rating)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t floor(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * FLOOR(X) function https://www.sqlite.org/lang_mathfunc.html#floor - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::floor>(&User::rating)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t floor(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * LN(X) function https://www.sqlite.org/lang_mathfunc.html#ln - * - * Example: - * - * auto rows = storage.select(sqlite_orm::ln(200)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t ln(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * LN(X) function https://www.sqlite.org/lang_mathfunc.html#ln - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::ln>(200)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t ln(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * LOG(X) function https://www.sqlite.org/lang_mathfunc.html#log - * - * Example: - * - * auto rows = storage.select(sqlite_orm::log(100)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t log(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * LOG(X) function https://www.sqlite.org/lang_mathfunc.html#log - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::log>(100)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t log(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * LOG10(X) function https://www.sqlite.org/lang_mathfunc.html#log - * - * Example: - * - * auto rows = storage.select(sqlite_orm::log10(100)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t log10(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * LOG10(X) function https://www.sqlite.org/lang_mathfunc.html#log - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::log10>(100)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t log10(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * LOG(B, X) function https://www.sqlite.org/lang_mathfunc.html#log - * - * Example: - * - * auto rows = storage.select(sqlite_orm::log(10, 100)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t log(B b, X x) { - return {std::tuple{std::forward(b), std::forward(x)}}; - } - - /** - * LOG(B, X) function https://www.sqlite.org/lang_mathfunc.html#log - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::log>(10, 100)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t log(B b, X x) { - return {std::tuple{std::forward(b), std::forward(x)}}; - } - - /** - * LOG2(X) function https://www.sqlite.org/lang_mathfunc.html#log2 - * - * Example: - * - * auto rows = storage.select(sqlite_orm::log2(64)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t log2(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * LOG2(X) function https://www.sqlite.org/lang_mathfunc.html#log2 - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::log2>(64)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t log2(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * MOD(X, Y) function https://www.sqlite.org/lang_mathfunc.html#mod - * - * Example: - * - * auto rows = storage.select(sqlite_orm::mod_f(6, 5)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t mod_f(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * MOD(X, Y) function https://www.sqlite.org/lang_mathfunc.html#mod - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::mod_f>(6, 5)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t mod_f(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * PI() function https://www.sqlite.org/lang_mathfunc.html#pi - * - * Example: - * - * auto rows = storage.select(sqlite_orm::pi()); // decltype(rows) is std::vector - */ - inline internal::built_in_function_t pi() { - return {{}}; - } - - /** - * PI() function https://www.sqlite.org/lang_mathfunc.html#pi - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, etc. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::pi()); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t pi() { - return {{}}; - } - - /** - * POW(X, Y) function https://www.sqlite.org/lang_mathfunc.html#pow - * - * Example: - * - * auto rows = storage.select(sqlite_orm::pow(2, 5)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t pow(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * POW(X, Y) function https://www.sqlite.org/lang_mathfunc.html#pow - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::pow>(2, 5)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t pow(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * POWER(X, Y) function https://www.sqlite.org/lang_mathfunc.html#pow - * - * Example: - * - * auto rows = storage.select(sqlite_orm::power(2, 5)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t power(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * POWER(X, Y) function https://www.sqlite.org/lang_mathfunc.html#pow - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::power>(2, 5)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t power(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * RADIANS(X) function https://www.sqlite.org/lang_mathfunc.html#radians - * - * Example: - * - * auto rows = storage.select(sqlite_orm::radians(&Triangle::cornerAInDegrees)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t radians(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * RADIANS(X) function https://www.sqlite.org/lang_mathfunc.html#radians - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::radians>(&Triangle::cornerAInDegrees)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t radians(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * SIN(X) function https://www.sqlite.org/lang_mathfunc.html#sin - * - * Example: - * - * auto rows = storage.select(sqlite_orm::sin(&Triangle::cornerA)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t sin(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * SIN(X) function https://www.sqlite.org/lang_mathfunc.html#sin - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::sin>(&Triangle::cornerA)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t sin(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * SINH(X) function https://www.sqlite.org/lang_mathfunc.html#sinh - * - * Example: - * - * auto rows = storage.select(sqlite_orm::sinh(&Triangle::cornerA)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t sinh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * SINH(X) function https://www.sqlite.org/lang_mathfunc.html#sinh - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::sinh>(&Triangle::cornerA)); // decltype(rows) is std::vector> - */ - template - internal::built_in_function_t sinh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * SQRT(X) function https://www.sqlite.org/lang_mathfunc.html#sqrt - * - * Example: - * - * auto rows = storage.select(sqlite_orm::sqrt(25)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t sqrt(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * SQRT(X) function https://www.sqlite.org/lang_mathfunc.html#sqrt - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::sqrt(25)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t sqrt(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * TAN(X) function https://www.sqlite.org/lang_mathfunc.html#tan - * - * Example: - * - * auto rows = storage.select(sqlite_orm::tan(&Triangle::cornerC)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t tan(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * TAN(X) function https://www.sqlite.org/lang_mathfunc.html#tan - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::tan(&Triangle::cornerC)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t tan(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * TANH(X) function https://www.sqlite.org/lang_mathfunc.html#tanh - * - * Example: - * - * auto rows = storage.select(sqlite_orm::tanh(&Triangle::cornerC)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t tanh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * TANH(X) function https://www.sqlite.org/lang_mathfunc.html#tanh - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::tanh(&Triangle::cornerC)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t tanh(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * TRUNC(X) function https://www.sqlite.org/lang_mathfunc.html#trunc - * - * Example: - * - * auto rows = storage.select(sqlite_orm::trunc(5.5)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t trunc(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * TRUNC(X) function https://www.sqlite.org/lang_mathfunc.html#trunc - * - * Difference with the previous function is that previous override has `double` as return type but this - * override accepts return type from you as a template argument. You can use any bindable type: - * `float`, `int`, `std::optional` etc. This override is handy when you expect `null` as result. - * - * Example: - * - * auto rows = storage.select(sqlite_orm::trunc(5.5)); // decltype(rows) is std::vector - */ - template - internal::built_in_function_t trunc(X x) { - return {std::tuple{std::forward(x)}}; - } -#endif // SQLITE_ENABLE_MATH_FUNCTIONS - /** - * TYPEOF(x) function https://sqlite.org/lang_corefunc.html#typeof - */ - template - internal::built_in_function_t typeof_(T t) { - return {std::tuple{std::forward(t)}}; - } - - /** - * UNICODE(x) function https://sqlite.org/lang_corefunc.html#unicode - */ - template - internal::built_in_function_t unicode(T t) { - return {std::tuple{std::forward(t)}}; - } - - /** - * LENGTH(x) function https://sqlite.org/lang_corefunc.html#length - */ - template - internal::built_in_function_t length(T t) { - return {std::tuple{std::forward(t)}}; - } - - /** - * ABS(x) function https://sqlite.org/lang_corefunc.html#abs - */ - template - internal::built_in_function_t, internal::abs_string, T> abs(T t) { - return {std::tuple{std::forward(t)}}; - } - - /** - * LOWER(x) function https://sqlite.org/lang_corefunc.html#lower - */ - template - internal::built_in_function_t lower(T t) { - return {std::tuple{std::forward(t)}}; - } - - /** - * UPPER(x) function https://sqlite.org/lang_corefunc.html#upper - */ - template - internal::built_in_function_t upper(T t) { - return {std::tuple{std::forward(t)}}; - } - - /** - * LAST_INSERT_ROWID(x) function https://www.sqlite.org/lang_corefunc.html#last_insert_rowid - */ - inline internal::built_in_function_t last_insert_rowid() { - return {{}}; - } - - /** - * TOTAL_CHANGES() function https://sqlite.org/lang_corefunc.html#total_changes - */ - inline internal::built_in_function_t total_changes() { - return {{}}; - } - - /** - * CHANGES() function https://sqlite.org/lang_corefunc.html#changes - */ - inline internal::built_in_function_t changes() { - return {{}}; - } - - /** - * TRIM(X) function https://sqlite.org/lang_corefunc.html#trim - */ - template - internal::built_in_function_t trim(T t) { - return {std::tuple{std::forward(t)}}; - } - - /** - * TRIM(X,Y) function https://sqlite.org/lang_corefunc.html#trim - */ - template - internal::built_in_function_t trim(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * LTRIM(X) function https://sqlite.org/lang_corefunc.html#ltrim - */ - template - internal::built_in_function_t ltrim(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * LTRIM(X,Y) function https://sqlite.org/lang_corefunc.html#ltrim - */ - template - internal::built_in_function_t ltrim(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * RTRIM(X) function https://sqlite.org/lang_corefunc.html#rtrim - */ - template - internal::built_in_function_t rtrim(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * RTRIM(X,Y) function https://sqlite.org/lang_corefunc.html#rtrim - */ - template - internal::built_in_function_t rtrim(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * HEX(X) function https://sqlite.org/lang_corefunc.html#hex - */ - template - internal::built_in_function_t hex(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * QUOTE(X) function https://sqlite.org/lang_corefunc.html#quote - */ - template - internal::built_in_function_t quote(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * RANDOMBLOB(X) function https://sqlite.org/lang_corefunc.html#randomblob - */ - template - internal::built_in_function_t, internal::randomblob_string, X> randomblob(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * INSTR(X) function https://sqlite.org/lang_corefunc.html#instr - */ - template - internal::built_in_function_t instr(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * REPLACE(X) function https://sqlite.org/lang_corefunc.html#replace - */ - template, internal::is_into>::value == 0, bool> = true> - internal::built_in_function_t replace(X x, Y y, Z z) { - return {std::tuple{std::forward(x), std::forward(y), std::forward(z)}}; - } - - /** - * ROUND(X) function https://sqlite.org/lang_corefunc.html#round - */ - template - internal::built_in_function_t round(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * ROUND(X, Y) function https://sqlite.org/lang_corefunc.html#round - */ - template - internal::built_in_function_t round(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - -#if SQLITE_VERSION_NUMBER >= 3007016 - /** - * CHAR(X1,X2,...,XN) function https://sqlite.org/lang_corefunc.html#char - */ - template - internal::built_in_function_t char_(Args... args) { - return {std::make_tuple(std::forward(args)...)}; - } - - /** - * RANDOM() function https://www.sqlite.org/lang_corefunc.html#random - */ - inline internal::built_in_function_t random() { - return {{}}; - } -#endif - - /** - * COALESCE(X,Y,...) function https://www.sqlite.org/lang_corefunc.html#coalesce - */ - template - auto coalesce(Args... args) - -> internal::built_in_function_t::value, - std::common_type...>, - polyfill::type_identity>::type, - internal::coalesce_string, - Args...> { - return {std::make_tuple(std::forward(args)...)}; - } - - /** - * IFNULL(X,Y) function https://www.sqlite.org/lang_corefunc.html#ifnull - */ - template - auto ifnull(X x, Y y) -> internal::built_in_function_t< - typename mpl::conditional_t< // choose R or common type - std::is_void::value, - std::common_type, internal::field_type_or_type_t>, - polyfill::type_identity>::type, - internal::ifnull_string, - X, - Y> { - return {std::make_tuple(std::move(x), std::move(y))}; - } - - /** - * NULLIF(X,Y) function https://www.sqlite.org/lang_corefunc.html#nullif - */ -#if defined(SQLITE_ORM_OPTIONAL_SUPPORTED) && defined(SQLITE_ORM_IF_CONSTEXPR_SUPPORTED) - /** - * NULLIF(X,Y) using common return type of X and Y - */ - template>, - polyfill::is_detected, - internal::field_type_or_type_t>>, - bool> = true> - auto nullif(X x, Y y) { - if constexpr (std::is_void_v) { - using F = internal::built_in_function_t< - std::optional, internal::field_type_or_type_t>>, - internal::nullif_string, - X, - Y>; - - return F{std::make_tuple(std::move(x), std::move(y))}; - } else { - using F = internal::built_in_function_t; - - return F{std::make_tuple(std::move(x), std::move(y))}; - } - } -#else - template - internal::built_in_function_t nullif(X x, Y y) { - return {std::make_tuple(std::move(x), std::move(y))}; - } -#endif - - /** - * DATE(timestring, modifier, modifier, ...) function https://www.sqlite.org/lang_datefunc.html - */ - template - internal::built_in_function_t date(Args... args) { - return {std::tuple{std::forward(args)...}}; - } - - /** - * TIME(timestring, modifier, modifier, ...) function https://www.sqlite.org/lang_datefunc.html - */ - template - internal::built_in_function_t time(Args... args) { - return {std::tuple{std::forward(args)...}}; - } - - /** - * DATETIME(timestring, modifier, modifier, ...) function https://www.sqlite.org/lang_datefunc.html - */ - template - internal::built_in_function_t datetime(Args... args) { - return {std::tuple{std::forward(args)...}}; - } - - /** - * JULIANDAY(timestring, modifier, modifier, ...) function https://www.sqlite.org/lang_datefunc.html - */ - template - internal::built_in_function_t julianday(Args... args) { - return {std::tuple{std::forward(args)...}}; - } - - /** - * STRFTIME(timestring, modifier, modifier, ...) function https://www.sqlite.org/lang_datefunc.html - */ - template - internal::built_in_function_t strftime(Args... args) { - return {std::tuple{std::forward(args)...}}; - } - - /** - * ZEROBLOB(N) function https://www.sqlite.org/lang_corefunc.html#zeroblob - */ - template - internal::built_in_function_t, internal::zeroblob_string, N> zeroblob(N n) { - return {std::tuple{std::forward(n)}}; - } - - /** - * SUBSTR(X,Y) function https://www.sqlite.org/lang_corefunc.html#substr - */ - template - internal::built_in_function_t substr(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - /** - * SUBSTR(X,Y,Z) function https://www.sqlite.org/lang_corefunc.html#substr - */ - template - internal::built_in_function_t substr(X x, Y y, Z z) { - return {std::tuple{std::forward(x), std::forward(y), std::forward(z)}}; - } - -#ifdef SQLITE_SOUNDEX - /** - * SOUNDEX(X) function https://www.sqlite.org/lang_corefunc.html#soundex - */ - template - internal::built_in_function_t soundex(X x) { - return {std::tuple{std::forward(x)}}; - } -#endif - - /** - * TOTAL(X) aggregate function. - */ - template - internal::built_in_aggregate_function_t total(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * SUM(X) aggregate function. - */ - template - internal::built_in_aggregate_function_t, internal::sum_string, X> sum(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * COUNT(X) aggregate function. - */ - template - internal::built_in_aggregate_function_t count(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * COUNT(*) without FROM function. - */ - inline internal::count_asterisk_without_type count() { - return {}; - } - - /** - * COUNT(*) with FROM function. Specified type T will be serialized as - * a from argument. - */ - template - internal::count_asterisk_t count() { - return {}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * COUNT(*) with FROM function. Specified recordset will be serialized as - * a from argument. - */ - template - auto count() { - return count>(); - } -#endif - - /** - * AVG(X) aggregate function. - */ - template - internal::built_in_aggregate_function_t avg(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * MAX(X) aggregate function. - */ - template - internal::built_in_aggregate_function_t, internal::max_string, X> max(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * MIN(X) aggregate function. - */ - template - internal::built_in_aggregate_function_t, internal::min_string, X> min(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * MAX(X, Y, ...) scalar function. - * The return type is the type of the first argument. - */ - template - internal::built_in_function_t, internal::max_string, X, Y, Rest...> - max(X x, Y y, Rest... rest) { - return {std::tuple{std::forward(x), std::forward(y), std::forward(rest)...}}; - } - - /** - * MIN(X, Y, ...) scalar function. - * The return type is the type of the first argument. - */ - template - internal::built_in_function_t, internal::min_string, X, Y, Rest...> - min(X x, Y y, Rest... rest) { - return {std::tuple{std::forward(x), std::forward(y), std::forward(rest)...}}; - } - - /** - * GROUP_CONCAT(X) aggregate function. - */ - template - internal::built_in_aggregate_function_t group_concat(X x) { - return {std::tuple{std::forward(x)}}; - } - - /** - * GROUP_CONCAT(X, Y) aggregate function. - */ - template - internal::built_in_aggregate_function_t group_concat(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } -#ifdef SQLITE_ENABLE_JSON1 - template - internal::built_in_function_t json(X x) { - return {std::tuple{std::forward(x)}}; - } - - template - internal::built_in_function_t json_array(Args... args) { - return {std::tuple{std::forward(args)...}}; - } - - template - internal::built_in_function_t json_array_length(X x) { - return {std::tuple{std::forward(x)}}; - } - - template - internal::built_in_function_t json_array_length(X x) { - return {std::tuple{std::forward(x)}}; - } - - template - internal::built_in_function_t json_array_length(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - template - internal::built_in_function_t json_array_length(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - template - internal::built_in_function_t json_extract(X x, Args... args) { - return {std::tuple{std::forward(x), std::forward(args)...}}; - } - - template - internal::built_in_function_t json_insert(X x, - Args... args) { - static_assert(std::tuple_size>::value % 2 == 0, - "number of arguments in json_insert must be odd"); - return {std::tuple{std::forward(x), std::forward(args)...}}; - } - - template - internal::built_in_function_t json_replace(X x, - Args... args) { - static_assert(std::tuple_size>::value % 2 == 0, - "number of arguments in json_replace must be odd"); - return {std::tuple{std::forward(x), std::forward(args)...}}; - } - - template - internal::built_in_function_t json_set(X x, Args... args) { - static_assert(std::tuple_size>::value % 2 == 0, - "number of arguments in json_set must be odd"); - return {std::tuple{std::forward(x), std::forward(args)...}}; - } - - template - internal::built_in_function_t json_object(Args... args) { - static_assert(std::tuple_size>::value % 2 == 0, - "number of arguments in json_object must be even"); - return {std::tuple{std::forward(args)...}}; - } - - template - internal::built_in_function_t json_patch(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - template - internal::built_in_function_t json_remove(X x, - Args... args) { - return {std::tuple{std::forward(x), std::forward(args)...}}; - } - - template - internal::built_in_function_t json_remove(X x, Args... args) { - return {std::tuple{std::forward(x), std::forward(args)...}}; - } - - template - internal::built_in_function_t json_type(X x) { - return {std::tuple{std::forward(x)}}; - } - - template - internal::built_in_function_t json_type(X x) { - return {std::tuple{std::forward(x)}}; - } - - template - internal::built_in_function_t json_type(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - template - internal::built_in_function_t json_type(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } - - template - internal::built_in_function_t json_valid(X x) { - return {std::tuple{std::forward(x)}}; - } - - template - internal::built_in_function_t json_quote(X x) { - return {std::tuple{std::forward(x)}}; - } - - template - internal::built_in_function_t json_group_array(X x) { - return {std::tuple{std::forward(x)}}; - } - - template - internal::built_in_function_t json_group_object(X x, Y y) { - return {std::tuple{std::forward(x), std::forward(y)}}; - } -#endif // SQLITE_ENABLE_JSON1 - - // Intentionally place operators for types classified as arithmetic or general operator arguments in the internal namespace - // to facilitate ADL (Argument Dependent Lookup) - namespace internal { - template< - class T, - std::enable_if_t, is_operator_argument>::value, - bool> = true> - constexpr unary_minus_t> operator-(T arg) { - return {get_from_expression(std::forward(arg))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr add_t, unwrap_expression_t> operator+(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr sub_t, unwrap_expression_t> operator-(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr mul_t, unwrap_expression_t> operator*(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr div_t, unwrap_expression_t> operator/(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr mod_t, unwrap_expression_t> operator%(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template< - class T, - std::enable_if_t, is_operator_argument>::value, - bool> = true> - constexpr bitwise_not_t> operator~(T arg) { - return {get_from_expression(std::forward(arg))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr bitwise_shift_left_t, unwrap_expression_t> operator<<(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr bitwise_shift_right_t, unwrap_expression_t> operator>>(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr bitwise_and_t, unwrap_expression_t> operator&(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - - template, - std::is_base_of, - is_operator_argument, - is_operator_argument>::value, - bool> = true> - constexpr bitwise_or_t, unwrap_expression_t> operator|(L l, R r) { - return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; - } - } - - template - internal::highlight_t highlight(X x, Y y, Z z) { - return {std::move(x), std::move(y), std::move(z)}; - } -} - -// #include "alias_traits.h" - -// #include "cte_moniker.h" - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES -#include -#include // std::make_index_sequence -#endif -#include // std::enable_if, std::is_member_pointer, std::is_same, std::is_convertible -#include // std::ignore -#include -#endif - -// #include "functional/cstring_literal.h" - -// #include "alias.h" - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -namespace sqlite_orm { - - namespace internal { - /** - * A special record set alias that is both, a storage lookup type (mapping type) and an alias. - */ - template - struct cte_moniker - : recordset_alias< - cte_moniker /* refer to self, since a moniker is both, an alias and a mapped type */, - A, - X...> { - /** - * Introduce the construction of a common table expression using this moniker. - * - * The list of explicit columns is optional; - * if provided the number of columns must match the number of columns of the subselect. - * The column names will be merged with the subselect: - * 1. column names of subselect - * 2. explicit columns - * 3. fill in empty column names with column index - * - * Example: - * 1_ctealias()(select(&Object::id)); - * 1_ctealias(&Object::name)(select("object")); - * - * @return A `cte_builder` instance. - * @note (internal): Defined in select_constraints.h in order to keep this member function in the same place as the named factory function `cte()`, - * and to keep the actual creation of the builder in one place. - */ -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - requires ((is_column_alias_v || std::is_member_pointer_v || - std::same_as> || - std::convertible_to) && - ...) - constexpr auto operator()(ExplicitCols... explicitColumns) const; -#else - template, - std::is_member_pointer, - std::is_same>, - std::is_convertible>...>, - bool> = true> - constexpr auto operator()(ExplicitCols... explicitColumns) const; -#endif - }; - } - - inline namespace literals { - /** - * cte_moniker<'n'> from a numeric literal. - * E.g. 1_ctealias, 2_ctealias - */ - template - [[nodiscard]] SQLITE_ORM_CONSTEVAL auto operator"" _ctealias() { - return internal::cte_moniker{}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * cte_moniker<'1'[, ...]> from a string literal. - * E.g. "1"_cte, "2"_cte - */ - template - [[nodiscard]] consteval auto operator"" _cte() { - return internal::explode_into(std::make_index_sequence{}); - } -#endif - } -} -#endif - -// #include "schema/column.h" - -#include // std::tuple -#include // std::string -#include // std::unique_ptr -#include // std::is_same, std::is_member_object_pointer -#include // std::move - -// #include "../functional/cxx_type_traits_polyfill.h" - -// #include "../tuple_helper/tuple_traits.h" - -// #include "../tuple_helper/tuple_filter.h" - -// #include "../type_traits.h" - -// #include "../member_traits/member_traits.h" - -// #include "../type_is_nullable.h" - -#include // std::false_type, std::true_type, std::enable_if -#include // std::shared_ptr, std::unique_ptr -// #include "functional/cxx_optional.h" - -// #include "functional/cxx_type_traits_polyfill.h" - -namespace sqlite_orm { - - /** - * This is class that tells `sqlite_orm` that type is nullable. Nullable types - * are mapped to sqlite database as `NULL` and not-nullable are mapped as `NOT NULL`. - * Default nullability status for all types is `NOT NULL`. So if you want to map - * custom type as `NULL` (for example: boost::optional) you have to create a specialization - * of `type_is_nullable` for your type and derive from `std::true_type`. - */ - template - struct type_is_nullable : std::false_type { - bool operator()(const T&) const { - return true; - } - }; - - /** - * This is a specialization for std::shared_ptr, std::unique_ptr, std::optional, which are nullable in sqlite_orm. - */ - template - struct type_is_nullable, -#endif - polyfill::is_specialization_of, - polyfill::is_specialization_of>::value>> : std::true_type { - bool operator()(const T& t) const { - return static_cast(t); - } - }; -} - -// #include "../constraints.h" - -namespace sqlite_orm { - - namespace internal { - - struct column_identifier { - - /** - * Column name. - */ - std::string name; - }; - - struct empty_setter {}; - - /* - * Encapsulates object member pointers that are used as column fields, - * and whose object is mapped to storage. - * - * G is a member object pointer or member function pointer - * S is a member function pointer or `empty_setter` - */ - template - struct column_field { - using member_pointer_t = G; - using setter_type = S; - using object_type = member_object_type_t; - using field_type = member_field_type_t; - - /** - * Member pointer used to read a field value. - * If it is a object member pointer it is also used to write a field value. - */ - const member_pointer_t member_pointer; - - /** - * Setter member function to write a field value - */ - SQLITE_ORM_NOUNIQUEADDRESS - const setter_type setter; - - /** - * Simplified interface for `NOT NULL` constraint - */ - constexpr bool is_not_null() const { - return !type_is_nullable::value; - } - }; - - /* - * Encapsulates a tuple of column constraints. - * - * Op... is a constraints pack, e.g. primary_key_t, unique_t etc - */ - template - struct column_constraints { - using constraints_type = std::tuple; - - SQLITE_ORM_NOUNIQUEADDRESS - constraints_type constraints; - - /** - * Checks whether contraints contain specified type. - */ - template class Trait> - constexpr static bool is() { - return tuple_has::value; - } - - /** - * Simplified interface for `DEFAULT` constraint - * @return string representation of default value if it exists otherwise nullptr - */ - std::unique_ptr default_value() const; - }; - - /** - * Column definition. - * - * It is a composition of orthogonal information stored in different base classes. - */ - template - struct column_t : column_identifier, column_field, column_constraints { -#ifndef SQLITE_ORM_AGGREGATE_BASES_SUPPORTED - column_t(std::string name, G memberPointer, S setter, std::tuple op) : - column_identifier{std::move(name)}, column_field{memberPointer, setter}, - column_constraints{std::move(op)} {} -#endif - }; - - template - struct column_field_expression { - using type = void; - }; - - template - struct column_field_expression, void> { - using type = typename column_t::member_pointer_t; - }; - - template - using column_field_expression_t = typename column_field_expression::type; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_column_v = polyfill::is_specialization_of::value; - - template - using is_column = polyfill::bool_constant>; - - template - using col_index_sequence_with_field_type = - filter_tuple_sequence_t::template fn, - field_type_t, - filter_tuple_sequence_t>; - - template class TraitFn> - using col_index_sequence_with = filter_tuple_sequence_t::template fn, - constraints_type_t, - filter_tuple_sequence_t>; - - template class TraitFn> - using col_index_sequence_excluding = filter_tuple_sequence_t::template fn, - constraints_type_t, - filter_tuple_sequence_t>; - } - - /** - * Factory function for a column definition from a member object pointer of the object to be mapped. - */ - template = true> - internal::column_t - make_column(std::string name, M memberPointer, Op... constraints) { - static_assert(polyfill::conjunction_v...>, "Incorrect constraints pack"); - - // attention: do not use `std::make_tuple()` for constructing the tuple member `[[no_unique_address]] column_constraints::constraints`, - // as this will lead to UB with Clang on MinGW! - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES( - return {std::move(name), memberPointer, {}, std::tuple{std::move(constraints)...}}); - } - - /** - * Factory function for a column definition from "setter" and "getter" member function pointers of the object to be mapped. - */ - template = true, - internal::satisfies = true> - internal::column_t make_column(std::string name, S setter, G getter, Op... constraints) { - static_assert(std::is_same, internal::getter_field_type_t>::value, - "Getter and setter must get and set same data type"); - static_assert(polyfill::conjunction_v...>, "Incorrect constraints pack"); - - // attention: do not use `std::make_tuple()` for constructing the tuple member `[[no_unique_address]] column_constraints::constraints`, - // as this will lead to UB with Clang on MinGW! - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES( - return {std::move(name), getter, setter, std::tuple{std::move(constraints)...}}); - } - - /** - * Factory function for a column definition from "getter" and "setter" member function pointers of the object to be mapped. - */ - template = true, - internal::satisfies = true> - internal::column_t make_column(std::string name, G getter, S setter, Op... constraints) { - static_assert(std::is_same, internal::getter_field_type_t>::value, - "Getter and setter must get and set same data type"); - static_assert(polyfill::conjunction_v...>, "Incorrect constraints pack"); - - // attention: do not use `std::make_tuple()` for constructing the tuple member `[[no_unique_address]] column_constraints::constraints`, - // as this will lead to UB with Clang on MinGW! - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES( - return {std::move(name), getter, setter, std::tuple{std::move(constraints)...}}); - } -} - -namespace sqlite_orm { - - namespace internal { -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct as_optional_t { - using expression_type = T; - - expression_type expression; - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - struct distinct_string { - operator std::string() const { - return "DISTINCT"; - } - }; - - /** - * DISCTINCT generic container. - */ - template - struct distinct_t : distinct_string { - using expression_type = T; - - expression_type expression; - - distinct_t(expression_type expression) : expression(std::move(expression)) {} - }; - - struct all_string { - operator std::string() const { - return "ALL"; - } - }; - - /** - * ALL generic container. - */ - template - struct all_t : all_string { - using expression_type = T; - - expression_type expression; - - all_t(expression_type expression) : expression(std::move(expression)) {} - }; - - /** - * Whether a type represents a keyword for a result set modifier (as part of a simple select expression). - */ - template - SQLITE_ORM_INLINE_VAR constexpr bool is_rowset_deduplicator_v = - polyfill::disjunction, - polyfill::is_specialization_of>::value; - - template - struct is_rowset_deduplicator : polyfill::bool_constant> {}; - - template - struct columns_t { - using columns_type = std::tuple; - - columns_type columns; - - static constexpr int count = std::tuple_size::value; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - columns_t(columns_type columns) : columns{std::move(columns)} {} -#endif - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_columns_v = polyfill::is_specialization_of::value; - - template - using is_columns = polyfill::bool_constant>; - - /* - * Captures the type of an aggregate/structure/object and column expressions, such that - * `T` can be constructed in-place as part of a result row. - * `T` must be constructible using direct-list-initialization. - */ - template - struct struct_t { - using columns_type = std::tuple; - - columns_type columns; - - static constexpr int count = std::tuple_size::value; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - struct_t(columns_type columns) : columns{std::move(columns)} {} -#endif - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_struct_v = polyfill::is_specialization_of::value; - - template - using is_struct = polyfill::bool_constant>; - - /** - * Subselect object type. - */ - template - struct select_t { - using return_type = T; - using conditions_type = std::tuple; - - return_type col; - conditions_type conditions; - bool highest_level = false; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - select_t(return_type col, conditions_type conditions) : - col{std::move(col)}, conditions{std::move(conditions)} {} -#endif - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_select_v = polyfill::is_specialization_of::value; - - template - using is_select = polyfill::bool_constant>; - - /** - * Base for UNION, UNION ALL, EXCEPT and INTERSECT - */ - template - struct compound_operator { - using expressions_tuple = std::tuple; - - expressions_tuple compound; - - constexpr compound_operator(expressions_tuple compound) : compound{std::move(compound)} { - iterate_tuple(this->compound, [](auto& expression) { - expression.highest_level = true; - }); - } - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_compound_operator_v = is_base_of_template::value; - - template - using is_compound_operator = polyfill::bool_constant>; - - struct union_base { - bool all = false; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - union_base(bool all) : all{all} {} -#endif - - operator std::string() const { - if (!this->all) { - return "UNION"; - } else { - return "UNION ALL"; - } - } - }; - - /** - * UNION object type. - */ - template - struct union_t : public compound_operator, union_base { - using typename compound_operator::expressions_tuple; - - constexpr union_t(expressions_tuple compound, bool all) : - compound_operator{std::move(compound)}, union_base{all} {} - }; - - struct except_string { - operator std::string() const { - return "EXCEPT"; - } - }; - - /** - * EXCEPT object type. - */ - template - struct except_t : compound_operator, except_string { - using super = compound_operator; - - using super::super; - }; - - struct intersect_string { - operator std::string() const { - return "INTERSECT"; - } - }; - /** - * INTERSECT object type. - */ - template - struct intersect_t : compound_operator, intersect_string { - using super = compound_operator; - - using super::super; - }; - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - /* - * Turn explicit columns for a CTE into types that the CTE backend understands - */ - template - struct decay_explicit_column { - using type = T; - }; - template - struct decay_explicit_column> { - using type = alias_holder; - }; - template - struct decay_explicit_column> { - using type = std::string; - }; - template - using decay_explicit_column_t = typename decay_explicit_column::type; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /* - * Materialization hint to instruct SQLite to materialize the select statement of a CTE into an ephemeral table as an "optimization fence". - */ - struct materialized_t {}; - - /* - * Materialization hint to instruct SQLite to substitute a CTE's select statement as a subquery subject to optimization. - */ - struct not_materialized_t {}; -#endif - - /** - * Monikered (aliased) CTE expression. - */ - template - struct common_table_expression { - using cte_moniker_type = Moniker; - using expression_type = Select; - using explicit_colrefs_tuple = ExplicitCols; - using hints_tuple = Hints; - static constexpr size_t explicit_colref_count = std::tuple_size_v; - - SQLITE_ORM_NOUNIQUEADDRESS hints_tuple hints; - explicit_colrefs_tuple explicitColumns; - expression_type subselect; - - constexpr common_table_expression(explicit_colrefs_tuple explicitColumns, expression_type subselect) : - explicitColumns{std::move(explicitColumns)}, subselect{std::move(subselect)} { - this->subselect.highest_level = true; - } - }; - - template - using common_table_expressions = std::tuple; - - template - struct cte_builder { - ExplicitCols explicitColumns; - -#if SQLITE_VERSION_NUMBER >= 3035000 && defined(SQLITE_ORM_WITH_CPP20_ALIASES) - template = true> - constexpr common_table_expression, Select> - as(Select sel) && { - return {std::move(this->explicitColumns), std::move(sel)}; - } - - template = true> - constexpr common_table_expression, select_t> - as(Compound sel) && { - return {std::move(this->explicitColumns), {std::move(sel)}}; - } -#else - template = true> - constexpr common_table_expression, Select> as(Select sel) && { - return {std::move(this->explicitColumns), std::move(sel)}; - } - - template = true> - constexpr common_table_expression, select_t> - as(Compound sel) && { - return {std::move(this->explicitColumns), {std::move(sel)}}; - } -#endif - }; - - /** - * WITH object type - expression with prepended CTEs. - */ - template - struct with_t { - using cte_type = common_table_expressions; - using expression_type = E; - - bool recursiveIndicated; - cte_type cte; - expression_type expression; - - with_t(bool recursiveIndicated, cte_type cte, expression_type expression) : - recursiveIndicated{recursiveIndicated}, cte{std::move(cte)}, expression{std::move(expression)} { - if constexpr (is_select_v) { - this->expression.highest_level = true; - } - } - }; -#endif - - template - struct asterisk_t { - using type = T; - - bool defined_order = false; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - asterisk_t(bool definedOrder) : defined_order{definedOrder} {} -#endif - }; - - template - struct object_t { - using type = T; - - bool defined_order = false; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - object_t(bool definedOrder) : defined_order{definedOrder} {} -#endif - }; - - template - struct then_t { - using expression_type = T; - - expression_type expression; - }; - - template - struct simple_case_t { - using return_type = R; - using case_expression_type = T; - using args_type = std::tuple; - using else_expression_type = E; - - optional_container case_expression; - args_type args; - optional_container else_expression; - }; - - /** - * T is a case expression type - * E is else type (void is ELSE is omitted) - * Args... is a pack of WHEN expressions - */ - template - struct simple_case_builder { - using return_type = R; - using case_expression_type = T; - using args_type = std::tuple; - using else_expression_type = E; - - optional_container case_expression; - args_type args; - optional_container else_expression; - - template - simple_case_builder> when(W w, then_t t) { - using result_args_type = std::tuple>; - std::pair newPair{std::move(w), std::move(t.expression)}; - result_args_type result_args = std::tuple_cat(std::move(this->args), std::make_tuple(newPair)); - std::get::value - 1>(result_args) = std::move(newPair); - return {std::move(this->case_expression), std::move(result_args), std::move(this->else_expression)}; - } - - simple_case_t end() { - return {std::move(this->case_expression), std::move(args), std::move(this->else_expression)}; - } - - template - simple_case_builder else_(El el) { - return {{std::move(this->case_expression)}, std::move(args), {std::move(el)}}; - } - }; - - template, bool> = true> - const T& access_column_expression(const T& expression) { - return expression; - } - - /* - * Access a column expression prefixed by a result set deduplicator (as part of a simple select expression, i.e. distinct, all) - */ - template, bool> = true> - const typename D::expression_type& access_column_expression(const D& modifier) { - return modifier.expression; - } - - template - constexpr void validate_conditions() { - static_assert(count_tuple::value <= 1, "a single query cannot contain > 1 WHERE blocks"); - static_assert(count_tuple::value <= 1, "a single query cannot contain > 1 GROUP BY blocks"); - static_assert(count_tuple::value <= 1, "a single query cannot contain > 1 ORDER BY blocks"); - static_assert(count_tuple::value <= 1, "a single query cannot contain > 1 LIMIT blocks"); - static_assert(count_tuple::value <= 1, "a single query cannot contain > 1 FROM blocks"); - } - } - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - internal::as_optional_t as_optional(T value) { - return {std::move(value)}; - } -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template - internal::then_t then(T t) { - return {std::move(t)}; - } - - template - internal::simple_case_builder case_(T t) { - return {{std::move(t)}}; - } - - template - internal::simple_case_builder case_() { - return {}; - } - - template - internal::distinct_t distinct(T t) { - return {std::move(t)}; - } - - template - internal::all_t all(T t) { - return {std::move(t)}; - } - - /* - * Combine multiple columns in a tuple. - */ - template - constexpr internal::columns_t columns(Args... args) { - return {{std::forward(args)...}}; - } - - /* - * Construct an unmapped structure ad-hoc from multiple columns. - * `T` must be constructible from the column results using direct-list-initialization. - */ - template - constexpr internal::struct_t struct_(Args... args) { - return {{std::forward(args)...}}; - } - - /** - * Public function for subselect query. Is useful in UNION queries. - */ - template - constexpr internal::select_t select(T t, Args... args) { - using args_tuple = std::tuple; - internal::validate_conditions(); - return {std::move(t), {std::forward(args)...}}; - } - - /** - * Public function for UNION operator. - * Expressions are subselect objects. - * Look through example in examples/union.cpp - */ - template - constexpr internal::union_t union_(E... expressions) { - static_assert(sizeof...(E) >= 2, "Compound operators must have at least 2 select statements"); - return {{std::forward(expressions)...}, false}; - } - - /** - * Public function for UNION ALL operator. - * Expressions are subselect objects. - * Look through example in examples/union.cpp - */ - template - constexpr internal::union_t union_all(E... expressions) { - static_assert(sizeof...(E) >= 2, "Compound operators must have at least 2 select statements"); - return {{std::forward(expressions)...}, true}; - } - - /** - * Public function for EXCEPT operator. - * Expressions are subselect objects. - * Look through example in examples/except.cpp - */ - template - constexpr internal::except_t except(E... expressions) { - static_assert(sizeof...(E) >= 2, "Compound operators must have at least 2 select statements"); - return {{std::forward(expressions)...}}; - } - - template - constexpr internal::intersect_t intersect(E... expressions) { - static_assert(sizeof...(E) >= 2, "Compound operators must have at least 2 select statements"); - return {{std::forward(expressions)...}}; - } - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -#if SQLITE_VERSION_NUMBER >= 3035003 -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /* - * Materialization hint to instruct SQLite to materialize the select statement of a CTE into an ephemeral table as an "optimization fence". - * - * Example: - * 1_ctealias().as(select(1)); - */ - consteval internal::materialized_t materialized() { - return {}; - } - - /* - * Materialization hint to instruct SQLite to substitute a CTE's select statement as a subquery subject to optimization. - * - * Example: - * 1_ctealias().as(select(1)); - */ - consteval internal::not_materialized_t not_materialized() { - return {}; - } -#endif -#endif - - /** - * Introduce the construction of a common table expression using the specified moniker. - * - * The list of explicit columns is optional; - * if provided the number of columns must match the number of columns of the subselect. - * The column names will be merged with the subselect: - * 1. column names of subselect - * 2. explicit columns - * 3. fill in empty column names with column index - * - * Example: - * using cte_1 = decltype(1_ctealias); - * cte()(select(&Object::id)); - * cte(&Object::name)(select("object")); - */ - template, - std::is_member_pointer, - internal::is_column, - std::is_same>, - std::is_convertible>...>, - bool> = true> - constexpr auto cte(ExplicitCols... explicitColumns) { - using namespace ::sqlite_orm::internal; - static_assert(is_cte_moniker_v, "Moniker must be a CTE moniker"); - static_assert((!is_builtin_numeric_column_alias_v && ...), - "Numeric column aliases are reserved for referencing columns locally within a single CTE."); - - using builder_type = - cte_builder, decay_explicit_column_t>>; - return builder_type{{std::move(explicitColumns)...}}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - requires ((internal::is_column_alias_v || std::is_member_pointer_v || - internal::is_column_v || - std::same_as> || - std::convertible_to) && - ...) - constexpr auto cte(ExplicitCols... explicitColumns) { - using namespace ::sqlite_orm::internal; - static_assert((!is_builtin_numeric_column_alias_v && ...), - "Numeric column aliases are reserved for referencing columns locally within a single CTE."); - - using builder_type = - cte_builder, decay_explicit_column_t>>; - return builder_type{{std::move(explicitColumns)...}}; - } -#endif - - namespace internal { -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - template - requires ((is_column_alias_v || std::is_member_pointer_v || - std::same_as> || - std::convertible_to) && - ...) - constexpr auto cte_moniker::operator()(ExplicitCols... explicitColumns) const { - return cte>(std::forward(explicitColumns)...); - } -#else - template - template, - std::is_member_pointer, - std::is_same>, - std::is_convertible>...>, - bool>> - constexpr auto cte_moniker::operator()(ExplicitCols... explicitColumns) const { - return cte>(std::forward(explicitColumns)...); - } -#endif - } - - /** - * With-clause for a tuple of ordinary CTEs. - * - * Despite the missing RECURSIVE keyword, the CTEs can be recursive. - */ - template = true> - internal::with_t with(internal::common_table_expressions ctes, E expression) { - return {false, std::move(ctes), std::move(expression)}; - } - - /** - * With-clause for a tuple of ordinary CTEs. - * - * Despite the missing RECURSIVE keyword, the CTEs can be recursive. - */ - template = true> - internal::with_t, CTEs...> with(internal::common_table_expressions ctes, - Compound sel) { - return {false, std::move(ctes), sqlite_orm::select(std::move(sel))}; - } - - /** - * With-clause for a single ordinary CTE. - * - * Despite the missing `RECURSIVE` keyword, the CTE can be recursive. - * - * Example: - * constexpr orm_cte_moniker auto cte_1 = 1_ctealias; - * with(cte_1().as(select(&Object::id)), select(cte_1->*1_colalias)); - */ - template = true, - internal::satisfies_not = true> - internal::with_t with(CTE cte, E expression) { - return {false, {std::move(cte)}, std::move(expression)}; - } - - /** - * With-clause for a single ordinary CTE. - * - * Despite the missing `RECURSIVE` keyword, the CTE can be recursive. - * - * Example: - * constexpr orm_cte_moniker auto cte_1 = 1_ctealias; - * with(cte_1().as(select(&Object::id)), select(cte_1->*1_colalias)); - */ - template = true, - internal::satisfies = true> - internal::with_t, CTE> with(CTE cte, Compound sel) { - return {false, {std::move(cte)}, sqlite_orm::select(std::move(sel))}; - } - - /** - * With-clause for a tuple of potentially recursive CTEs. - * - * @note The use of RECURSIVE does not force common table expressions to be recursive. - */ - template = true> - internal::with_t with_recursive(internal::common_table_expressions ctes, E expression) { - return {true, std::move(ctes), std::move(expression)}; - } - - /** - * With-clause for a tuple of potentially recursive CTEs. - * - * @note The use of RECURSIVE does not force common table expressions to be recursive. - */ - template = true> - internal::with_t, CTEs...> - with_recursive(internal::common_table_expressions ctes, Compound sel) { - return {true, std::move(ctes), sqlite_orm::select(std::move(sel))}; - } - - /** - * With-clause for a single potentially recursive CTE. - * - * @note The use of RECURSIVE does not force common table expressions to be recursive. - * - * Example: - * constexpr orm_cte_moniker auto cte_1 = 1_ctealias; - * with_recursive(cte_1().as(select(&Object::id)), select(cte_1->*1_colalias)); - */ - template = true, - internal::satisfies_not = true> - internal::with_t with_recursive(CTE cte, E expression) { - return {true, {std::move(cte)}, std::move(expression)}; - } - - /** - * With-clause for a single potentially recursive CTE. - * - * @note The use of RECURSIVE does not force common table expressions to be recursive. - * - * Example: - * constexpr orm_cte_moniker auto cte_1 = 1_ctealias; - * with_recursive(cte_1().as(select(&Object::id)), select(cte_1->*1_colalias)); - */ - template = true, - internal::satisfies = true> - internal::with_t, CTE> with_recursive(CTE cte, Compound sel) { - return {true, {std::move(cte)}, sqlite_orm::select(std::move(sel))}; - } -#endif - - /** - * `SELECT * FROM T` expression that fetches results as tuples. - * T is a type mapped to a storage, or an alias of it. - * The `definedOrder` parameter denotes the expected order of result columns. - * The default is the implicit order as returned by SQLite, which may differ from the defined order - * if the schema of a table has been changed. - * By specifying the defined order, the columns are written out in the resulting select SQL string. - * - * In pseudo code: - * select(asterisk(false)) -> SELECT * from User - * select(asterisk(true)) -> SELECT id, name from User - * - * Example: auto rows = storage.select(asterisk()); - * // decltype(rows) is std::vector> - * Example: auto rows = storage.select(asterisk(true)); - * // decltype(rows) is std::vector> - * - * If you need to fetch results as objects instead of tuples please use `object()`. - */ - template - constexpr internal::asterisk_t asterisk(bool definedOrder = false) { - return {definedOrder}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Example: - * constexpr orm_table_alias auto m = "m"_alias.for_(); - * auto reportingTo = - * storage.select(asterisk(), inner_join(on(m->*&Employee::reportsTo == &Employee::employeeId))); - */ - template - constexpr auto asterisk(bool definedOrder = false) { - return asterisk>(definedOrder); - } -#endif - - /** - * `SELECT * FROM T` expression that fetches results as objects of type T. - * T is a type mapped to a storage, or an alias of it. - * - * Example: auto rows = storage.select(object()); - * // decltype(rows) is std::vector, where the User objects are constructed from columns in implicitly stored order - * Example: auto rows = storage.select(object(true)); - * // decltype(rows) is std::vector, where the User objects are constructed from columns in declared make_table order - * - * If you need to fetch results as tuples instead of objects please use `asterisk()`. - */ - template - constexpr internal::object_t object(bool definedOrder = false) { - return {definedOrder}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - constexpr auto object(bool definedOrder = false) { - return object>(definedOrder); - } -#endif -} - -// #include "core_functions.h" - -// #include "conditions.h" - -// #include "statement_binder.h" - -#include -#include // std::enable_if_t, std::is_arithmetic, std::is_same, std::true_type, std::false_type, std::make_index_sequence, std::index_sequence -#include // std::default_delete -#include // std::string, std::wstring -#include // std::vector -#include // strncpy, strlen -// #include "functional/cxx_string_view.h" - -#ifndef SQLITE_ORM_STRING_VIEW_SUPPORTED -#include // wcsncpy, wcslen -#endif -#ifndef SQLITE_ORM_OMITS_CODECVT -#include // std::wstring_convert -#include // std::codecvt_utf8_utf16 -#endif - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "functional/cxx_functional_polyfill.h" - -// #include "is_std_ptr.h" - -// #include "tuple_helper/tuple_filter.h" - -// #include "type_traits.h" - -// #include "error_code.h" - -// #include "arithmetic_tag.h" - -#include // std::is_integral - -// #include "functional/mpl/conditional.h" - -namespace sqlite_orm { - - /** - * Helper classes used by statement_binder and row_extractor. - */ - struct int_or_smaller_tag {}; - struct bigint_tag {}; - struct real_tag {}; - - template - using arithmetic_tag_t = - mpl::conditional_t::value, - // Integer class - mpl::conditional_t, - // Floating-point class - real_tag>; -} - -// #include "xdestroy_handling.h" - -#include // std::integral_constant -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED -#include -#endif - -// #include "functional/cxx_type_traits_polyfill.h" - -namespace sqlite_orm { - - using xdestroy_fn_t = void (*)(void*); - using null_xdestroy_t = std::integral_constant; - SQLITE_ORM_INLINE_VAR constexpr null_xdestroy_t null_xdestroy_f{}; -} - -namespace sqlite_orm { - namespace internal { -#ifdef SQLITE_ORM_CONCEPTS_SUPPORTED - /** - * Constrains a deleter to be state-less. - */ - template - concept stateless_deleter = std::is_empty_v && std::is_default_constructible_v; - - /** - * Constrains a deleter to be an integral function constant. - */ - template - concept integral_fp_c = requires { - typename D::value_type; - D::value; - requires std::is_function_v>; - }; - - /** - * Constrains a deleter to be or to yield a function pointer. - */ - template - concept yields_fp = requires(D d) { - // yielding function pointer by using the plus trick - { +d }; - requires std::is_function_v>; - }; -#endif - -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - /** - * Yield a deleter's function pointer. - */ - template - struct yield_fp_of { - using type = decltype(+std::declval()); - }; -#else - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_stateless_deleter_v = - std::is_empty::value && std::is_default_constructible::value; - - template - struct is_integral_fp_c : std::false_type {}; - template - struct is_integral_fp_c< - D, - polyfill::void_t>::value>>> - : std::true_type {}; - template - SQLITE_ORM_INLINE_VAR constexpr bool is_integral_fp_c_v = is_integral_fp_c::value; - - template - struct can_yield_fp : std::false_type {}; - template - struct can_yield_fp< - D, - polyfill::void_t< - decltype(+std::declval()), - std::enable_if_t())>>::value>>> - : std::true_type {}; - template - SQLITE_ORM_INLINE_VAR constexpr bool can_yield_fp_v = can_yield_fp::value; - - template> - struct yield_fp_of { - using type = void; - }; - template - struct yield_fp_of { - using type = decltype(+std::declval()); - }; -#endif - template - using yielded_fn_t = typename yield_fp_of::type; - -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - template - concept is_unusable_for_xdestroy = - (!stateless_deleter && (yields_fp && !std::convertible_to, xdestroy_fn_t>)); - - /** - * This concept tests whether a deleter yields a function pointer, which is convertible to an xdestroy function pointer. - * Note: We are using 'is convertible' rather than 'is same' because of any exception specification. - */ - template - concept yields_xdestroy = yields_fp && std::convertible_to, xdestroy_fn_t>; - - template - concept needs_xdestroy_proxy = - (stateless_deleter && (!yields_fp || !std::convertible_to, xdestroy_fn_t>)); - - /** - * xDestroy function that constructs and invokes the stateless deleter. - * - * Requires that the deleter can be called with the q-qualified pointer argument; - * it doesn't check so explicitly, but a compiler error will occur. - */ - template - requires (!integral_fp_c) - void xdestroy_proxy(void* p) noexcept { - // C-casting `void* -> P*` like statement_binder> - auto o = (P*)p; - // ignoring return code - (void)D{}(o); - } - - /** - * xDestroy function that invokes the integral function pointer constant. - * - * Performs a const-cast of the argument pointer in order to allow for C API functions - * that take a non-const parameter, but user code passes a pointer to a const object. - */ - template - void xdestroy_proxy(void* p) noexcept { - // C-casting `void* -> P*` like statement_binder>, - auto o = (std::remove_cv_t

*)(P*)p; - // ignoring return code - (void)D{}(o); - } -#else - template - SQLITE_ORM_INLINE_VAR constexpr bool is_unusable_for_xdestroy_v = - !is_stateless_deleter_v && - (can_yield_fp_v && !std::is_convertible, xdestroy_fn_t>::value); - - template - SQLITE_ORM_INLINE_VAR constexpr bool can_yield_xdestroy_v = - can_yield_fp_v && std::is_convertible, xdestroy_fn_t>::value; - - template - SQLITE_ORM_INLINE_VAR constexpr bool needs_xdestroy_proxy_v = - is_stateless_deleter_v && - (!can_yield_fp_v || !std::is_convertible, xdestroy_fn_t>::value); - - template, bool> = true> - void xdestroy_proxy(void* p) noexcept { - // C-casting `void* -> P*` like statement_binder> - auto o = (P*)p; - // ignoring return code - (void)D{}(o); - } - - template, bool> = true> - void xdestroy_proxy(void* p) noexcept { - // C-casting `void* -> P*` like statement_binder>, - auto o = (std::remove_cv_t

*)(P*)p; - // ignoring return code - (void)D{}(o); - } -#endif - } -} - -namespace sqlite_orm { - -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - /** - * Prohibits using a yielded function pointer, which is not of type xdestroy_fn_t. - * - * Explicitly declared for better error messages. - */ - template - constexpr xdestroy_fn_t obtain_xdestroy_for(D, P* = nullptr) noexcept - requires (internal::is_unusable_for_xdestroy) - { - static_assert(polyfill::always_false_v, - "A function pointer, which is not of type xdestroy_fn_t, is prohibited."); - return nullptr; - } - - /** - * Obtains a proxy 'xDestroy' function pointer [of type void(*)(void*)] - * for a deleter in a type-safe way. - * - * The deleter can be one of: - * - integral function constant - * - state-less (empty) deleter - * - non-capturing lambda - * - * Type-safety is garanteed by checking whether the deleter or yielded function pointer - * is invocable with the non-q-qualified pointer value. - */ - template - constexpr xdestroy_fn_t obtain_xdestroy_for(D, P* = nullptr) noexcept - requires (internal::needs_xdestroy_proxy) - { - return internal::xdestroy_proxy; - } - - /** - * Directly obtains a 'xDestroy' function pointer [of type void(*)(void*)] - * from a deleter in a type-safe way. - * - * The deleter can be one of: - * - function pointer of type xdestroy_fn_t - * - structure holding a function pointer - * - integral function constant - * - non-capturing lambda - * ... and yield a function pointer of type xdestroy_fn_t. - * - * Type-safety is garanteed by checking whether the deleter or yielded function pointer - * is invocable with the non-q-qualified pointer value. - */ - template - constexpr xdestroy_fn_t obtain_xdestroy_for(D d, P* = nullptr) noexcept - requires (internal::yields_xdestroy) - { - return d; - } -#else - template, bool> = true> - constexpr xdestroy_fn_t obtain_xdestroy_for(D, P* = nullptr) { - static_assert(polyfill::always_false_v, - "A function pointer, which is not of type xdestroy_fn_t, is prohibited."); - return nullptr; - } - - template, bool> = true> - constexpr xdestroy_fn_t obtain_xdestroy_for(D, P* = nullptr) noexcept { - return internal::xdestroy_proxy; - } - - template, bool> = true> - constexpr xdestroy_fn_t obtain_xdestroy_for(D d, P* = nullptr) noexcept { - return d; - } -#endif -} - -// #include "pointer_value.h" - -#if SQLITE_VERSION_NUMBER >= 3020000 -#include -#include -#include -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES -#include -#endif -#endif - -// #include "functional/cstring_literal.h" - -// #include "xdestroy_handling.h" - -#if SQLITE_VERSION_NUMBER >= 3020000 -namespace sqlite_orm { -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - namespace internal { - template - struct pointer_type { - using value_type = const char[sizeof...(C) + 1]; - static inline constexpr value_type value = {C..., '\0'}; - }; - } - - inline namespace literals { - template - [[nodiscard]] consteval auto operator"" _pointer_type() { - return internal::explode_into(std::make_index_sequence{}); - } - } - - /** @short Specifies that a type is an integral constant string usable as a pointer type. - */ - template - concept orm_pointer_type = requires { - typename T::value_type; - { T::value } -> std::convertible_to; - }; -#endif - - /** - * Wraps a pointer and tags it with a pointer type, - * used for accepting function parameters, - * facilitating the 'pointer-passing interface'. - * - * Template parameters: - * - P: The value type, possibly const-qualified. - * - T: An integral constant string denoting the pointer type, e.g. `"carray"_pointer_type`. - * - */ - template - struct pointer_arg { - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - // note (internal): this is currently a static assertion instead of a type constraint because - // of forward declarations in other places (e.g. function.h) - static_assert(orm_pointer_type, "T must be a pointer type (tag)"); -#else - static_assert(std::is_convertible::value, - "The pointer type (tag) must be convertible to `const char*`"); -#endif - - using tag = T; - using qualified_type = P; - - P* p_; - - P* ptr() const noexcept { - return p_; - } - - operator P*() const noexcept { - return p_; - } - }; - - /** - * Pointer value with associated deleter function, - * used for returning or binding pointer values - * as part of facilitating the 'pointer-passing interface'. - * - * Template parameters: - * - P: The value type, possibly const-qualified. - * - T: An integral constant string denoting the pointer type, e.g. `carray_pointer_type`. - * - D: The deleter for the pointer value; - * can be one of: - * - function pointer - * - integral function pointer constant - * - state-less (empty) deleter - * - non-capturing lambda - * - structure implicitly yielding a function pointer - * - * @note Use one of the factory functions to create a pointer binding, - * e.g. bindable_carray_pointer or statically_bindable_carray_pointer(). - * - * @example - * ``` - * int64 rememberedId; - * storage.select(func(&Object::id, statically_bindable_carray_pointer(&rememberedId))); - * ``` - */ - template - class pointer_binding { - - P* p_; - SQLITE_ORM_NOUNIQUEADDRESS - D d_; - - protected: - // Constructing pointer bindings must go through bind_pointer() - template - friend auto bind_pointer(P2*, D2) noexcept -> pointer_binding; -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - // Constructing pointer bindings must go through bind_pointer() - template - friend auto bind_pointer(P2*, D2) noexcept -> pointer_binding; -#endif - template - friend B bind_pointer(typename B::qualified_type*, typename B::deleter_type) noexcept; - - // Construct from pointer and deleter. - // Transfers ownership of the passed in object. - pointer_binding(P* p, D d = {}) noexcept : p_{p}, d_{std::move(d)} {} - - public: - using qualified_type = P; - using tag = T; - using deleter_type = D; - - pointer_binding(const pointer_binding&) = delete; - pointer_binding& operator=(const pointer_binding&) = delete; - pointer_binding& operator=(pointer_binding&&) = delete; - - pointer_binding(pointer_binding&& other) noexcept : - p_{std::exchange(other.p_, nullptr)}, d_{std::move(other.d_)} {} - - ~pointer_binding() { - if (p_) { - if (auto xDestroy = get_xdestroy()) { - // note: C-casting `P* -> void*` like statement_binder> - xDestroy((void*)p_); - } - } - } - - P* ptr() const noexcept { - return p_; - } - - P* take_ptr() noexcept { - return std::exchange(p_, nullptr); - } - - xdestroy_fn_t get_xdestroy() const noexcept { - return obtain_xdestroy_for(d_, p_); - } - }; - - /** - * Alias template for a static pointer value binding. - * 'Static' means that ownership won't be transferred to sqlite, - * sqlite doesn't delete it, and sqlite assumes the object - * pointed to is valid throughout the lifetime of a statement. - */ - template - using static_pointer_binding = pointer_binding; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - using pointer_arg_t = pointer_arg; - - template - using pointer_binding_t = pointer_binding; - - /** - * Alias template for a static pointer value binding. - * 'Static' means that ownership won't be transferred to sqlite, - * sqlite doesn't delete it, and sqlite assumes the object - * pointed to is valid throughout the lifetime of a statement. - */ - template - using static_pointer_binding_t = pointer_binding_t; -#endif -} - -namespace sqlite_orm { - /** - * Wrap a pointer, its type and its deleter function for binding it to a statement. - * - * Unless the deleter yields a nullptr 'xDestroy' function the ownership of the pointed-to-object - * is transferred to the pointer binding, which will delete it through - * the deleter when the statement finishes. - */ - template - auto bind_pointer(P* p, D d) noexcept -> pointer_binding { - return {p, std::move(d)}; - } - - template - auto bind_pointer(std::unique_ptr p) noexcept -> pointer_binding { - return bind_pointer(p.release(), p.get_deleter()); - } - - template - auto bind_pointer(typename B::qualified_type* p, typename B::deleter_type d = {}) noexcept -> B { - return B{p, std::move(d)}; - } - - template - [[deprecated("Use the better named function `bind_pointer(...)`")]] pointer_binding - bindable_pointer(P* p, D d) noexcept { - return bind_pointer(p, std::move(d)); - } - - template - [[deprecated("Use the better named function `bind_pointer(...)`")]] pointer_binding - bindable_pointer(std::unique_ptr p) noexcept { - return bind_pointer(p.release(), p.get_deleter()); - } - - template - [[deprecated("Use the better named function `bind_pointer(...)`")]] B - bindable_pointer(typename B::qualified_type* p, typename B::deleter_type d = {}) noexcept { - return bind_pointer(p, std::move(d)); - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Wrap a pointer, its type (tag) and its deleter function for binding it to a statement. - * - * Unless the deleter yields a nullptr 'xDestroy' function the ownership of the pointed-to-object - * is transferred to the pointer binding, which will delete it through - * the deleter when the statement finishes. - */ - template - auto bind_pointer(P* p, D d) noexcept -> pointer_binding { - return {p, std::move(d)}; - } - - template - auto bind_pointer(std::unique_ptr p) noexcept -> pointer_binding { - return bind_pointer(p.release(), p.get_deleter()); - } -#endif - - /** - * Wrap a pointer and its type for binding it to a statement. - * - * Note: 'Static' means that ownership of the pointed-to-object won't be transferred - * and sqlite assumes the object pointed to is valid throughout the lifetime of a statement. - */ - template - auto bind_pointer_statically(P* p) noexcept -> static_pointer_binding { - return bind_pointer(p, null_xdestroy_f); - } - - template - B bind_pointer_statically(typename B::qualified_type* p, - typename B::deleter_type* /*exposition*/ = nullptr) noexcept { - return bind_pointer(p); - } - - template - [[deprecated("Use the better named function `bind_pointer_statically(...)`")]] static_pointer_binding - statically_bindable_pointer(P* p) noexcept { - return bind_pointer(p, null_xdestroy_f); - } - - template - [[deprecated("Use the better named function `bind_pointer_statically(...)`")]] B - statically_bindable_pointer(typename B::qualified_type* p, - typename B::deleter_type* /*exposition*/ = nullptr) noexcept { - return bind_pointer(p); - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Wrap a pointer and its type (tag) for binding it to a statement. - * - * Note: 'Static' means that ownership of the pointed-to-object won't be transferred - * and sqlite assumes the object pointed to is valid throughout the lifetime of a statement. - */ - template - auto bind_pointer_statically(P* p) noexcept -> static_pointer_binding { - return bind_pointer(p, null_xdestroy_f); - } -#endif - - /** - * Forward a pointer value from an argument. - */ - template - auto rebind_statically(const pointer_arg& pv) noexcept -> static_pointer_binding { - return bind_pointer_statically(pv.ptr()); - } -} -#endif - -namespace sqlite_orm { - - /** - * Helper class used for binding fields to sqlite3 statements. - */ - template - struct statement_binder; - - namespace internal { - /* - * Implementation note: the technique of indirect expression testing is because - * of older compilers having problems with the detection of dependent templates [SQLITE_ORM_BROKEN_ALIAS_TEMPLATE_DEPENDENT_EXPR_SFINAE]. - * It must also be a type that differs from those for `is_printable_v`, `is_preparable_v`. - */ - template - struct indirectly_test_bindable; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_bindable_v = false; - template - SQLITE_ORM_INLINE_VAR constexpr bool - is_bindable_v{})>>> = true; - - template - struct is_bindable : polyfill::bool_constant> {}; - } - -#if SQLITE_VERSION_NUMBER >= 3020000 - /** - * Specialization for pointer bindings (part of the 'pointer-passing interface'). - */ - template - struct statement_binder, void> { - using V = pointer_binding; - - // ownership of pointed-to-object is left untouched and remains at prepared statement's AST expression - int bind(sqlite3_stmt* stmt, int index, const V& value) const { - // note: C-casting `P* -> void*`, internal::xdestroy_proxy() does the inverse - return sqlite3_bind_pointer(stmt, index, (void*)value.ptr(), T::value, null_xdestroy_f); - } - - // ownership of pointed-to-object is transferred to sqlite - void result(sqlite3_context* context, V& value) const { - // note: C-casting `P* -> void*`, - // row_extractor>::extract() and internal::xdestroy_proxy() do the inverse - sqlite3_result_pointer(context, (void*)value.take_ptr(), T::value, value.get_xdestroy()); - } - }; -#endif - - /** - * Specialization for arithmetic types. - */ - template - struct statement_binder> { - - int bind(sqlite3_stmt* stmt, int index, const V& value) const { - return this->bind(stmt, index, value, tag()); - } - - void result(sqlite3_context* context, const V& value) const { - this->result(context, value, tag()); - } - - private: - using tag = arithmetic_tag_t; - - int bind(sqlite3_stmt* stmt, int index, const V& value, int_or_smaller_tag) const { - return sqlite3_bind_int(stmt, index, static_cast(value)); - } - - void result(sqlite3_context* context, const V& value, int_or_smaller_tag) const { - sqlite3_result_int(context, static_cast(value)); - } - - int bind(sqlite3_stmt* stmt, int index, const V& value, bigint_tag) const { - return sqlite3_bind_int64(stmt, index, static_cast(value)); - } - - void result(sqlite3_context* context, const V& value, bigint_tag) const { - sqlite3_result_int64(context, static_cast(value)); - } - - int bind(sqlite3_stmt* stmt, int index, const V& value, real_tag) const { - return sqlite3_bind_double(stmt, index, static_cast(value)); - } - - void result(sqlite3_context* context, const V& value, real_tag) const { - sqlite3_result_double(context, static_cast(value)); - } - }; - - /** - * Specialization for std::string and C-string. - */ - template - struct statement_binder, - std::is_same -#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED - , - std::is_same -#endif - >::value>> { - - int bind(sqlite3_stmt* stmt, int index, const V& value) const { - auto stringData = this->string_data(value); - return sqlite3_bind_text(stmt, index, stringData.first, stringData.second, SQLITE_TRANSIENT); - } - - void result(sqlite3_context* context, const V& value) const { - auto stringData = this->string_data(value); - auto dataCopy = new char[stringData.second + 1]; - constexpr auto deleter = std::default_delete{}; - strncpy(dataCopy, stringData.first, stringData.second + 1); - sqlite3_result_text(context, dataCopy, stringData.second, obtain_xdestroy_for(deleter, dataCopy)); - } - - private: -#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED - std::pair string_data(const std::string_view& s) const { - return {s.data(), int(s.size())}; - } -#else - std::pair string_data(const std::string& s) const { - return {s.c_str(), int(s.size())}; - } - - std::pair string_data(const char* s) const { - return {s, int(strlen(s))}; - } -#endif - }; - -#ifndef SQLITE_ORM_OMITS_CODECVT - template - struct statement_binder, - std::is_same -#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED - , - std::is_same -#endif - >::value>> { - - int bind(sqlite3_stmt* stmt, int index, const V& value) const { - auto stringData = this->string_data(value); - std::wstring_convert> converter; - std::string utf8Str = converter.to_bytes(stringData.first, stringData.first + stringData.second); - return statement_binder().bind(stmt, index, utf8Str); - } - - void result(sqlite3_context* context, const V& value) const { - auto stringData = this->string_data(value); - sqlite3_result_text16(context, stringData.first, stringData.second, nullptr); - } - - private: -#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED - std::pair string_data(const std::wstring_view& s) const { - return {s.data(), int(s.size())}; - } -#else - std::pair string_data(const std::wstring& s) const { - return {s.c_str(), int(s.size())}; - } - - std::pair string_data(const wchar_t* s) const { - return {s, int(wcslen(s))}; - } -#endif - }; -#endif - - /** - * Specialization for nullptr_t. - */ - template<> - struct statement_binder { - int bind(sqlite3_stmt* stmt, int index, const nullptr_t&) const { - return sqlite3_bind_null(stmt, index); - } - - void result(sqlite3_context* context, const nullptr_t&) const { - sqlite3_result_null(context); - } - }; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - /** - * Specialization for std::nullopt_t. - */ - template<> - struct statement_binder { - int bind(sqlite3_stmt* stmt, int index, const std::nullopt_t&) const { - return sqlite3_bind_null(stmt, index); - } - - void result(sqlite3_context* context, const std::nullopt_t&) const { - sqlite3_result_null(context); - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template - struct statement_binder< - V, - std::enable_if_t::value && - internal::is_bindable>::value>> { - using unqualified_type = std::remove_cv_t; - - int bind(sqlite3_stmt* stmt, int index, const V& value) const { - if (value) { - return statement_binder().bind(stmt, index, *value); - } else { - return statement_binder().bind(stmt, index, nullptr); - } - } - }; - - /** - * Specialization for binary data (std::vector). - */ - template<> - struct statement_binder, void> { - int bind(sqlite3_stmt* stmt, int index, const std::vector& value) const { - if (!value.empty()) { - return sqlite3_bind_blob(stmt, index, (const void*)&value.front(), int(value.size()), SQLITE_TRANSIENT); - } else { - return sqlite3_bind_blob(stmt, index, "", 0, SQLITE_TRANSIENT); - } - } - - void result(sqlite3_context* context, const std::vector& value) const { - if (!value.empty()) { - sqlite3_result_blob(context, (const void*)&value.front(), int(value.size()), nullptr); - } else { - sqlite3_result_blob(context, "", 0, nullptr); - } - } - }; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct statement_binder && - internal::is_bindable_v>>> { - using unqualified_type = std::remove_cv_t; - - int bind(sqlite3_stmt* stmt, int index, const V& value) const { - if (value) { - return statement_binder().bind(stmt, index, *value); - } else { - return statement_binder().bind(stmt, index, std::nullopt); - } - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - namespace internal { - - struct conditional_binder { - sqlite3_stmt* stmt = nullptr; - int index = 1; - - explicit conditional_binder(sqlite3_stmt* stmt) : stmt{stmt} {} - - template = true> - void operator()(const T& t) { - int rc = statement_binder{}.bind(this->stmt, this->index++, t); - if (SQLITE_OK != rc) { - throw_translated_sqlite_error(this->stmt); - } - } - - template = true> - void operator()(const T&) const {} - }; - - struct field_value_binder : conditional_binder { - using conditional_binder::conditional_binder; - using conditional_binder::operator(); - - template = true> - void operator()(const T&) const = delete; - - template - void operator()(const T* value) { - if (!value) { - throw std::system_error{orm_error_code::value_is_null}; - } - (*this)(*value); - } - }; - - struct tuple_value_binder { - sqlite3_stmt* stmt = nullptr; - - explicit tuple_value_binder(sqlite3_stmt* stmt) : stmt{stmt} {} - - template - void operator()(const Tpl& tpl, Projection project) const { - (*this)(tpl, - std::make_index_sequence::value>{}, - std::forward(project)); - } - - private: -#ifdef SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED - template - void operator()(const Tpl& tpl, std::index_sequence, Projection project) const { - (this->bind(polyfill::invoke(project, std::get(tpl)), Idx), ...); - } -#else - template - void operator()(const Tpl& tpl, std::index_sequence, Projection project) const { - using Sink = int[sizeof...(Idx)]; - (void)Sink{(this->bind(polyfill::invoke(project, std::get(tpl)), Idx), 0)...}; - } -#endif - - template - void bind(const T& t, size_t idx) const { - int rc = statement_binder{}.bind(this->stmt, int(idx + 1), t); - if (SQLITE_OK != rc) { - throw_translated_sqlite_error(this->stmt); - } - } - - template - void bind(const T* value, size_t idx) const { - if (!value) { - throw std::system_error{orm_error_code::value_is_null}; - } - (*this)(*value, idx); - } - }; - - template - using bindable_filter_t = filter_tuple_t; - } -} - -// #include "column_result.h" - -#include // std::enable_if, std::is_same, std::decay, std::is_arithmetic, std::is_base_of -#include // std::reference_wrapper - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "functional/mpl.h" - -// #include "tuple_helper/tuple_traits.h" - -// #include "tuple_helper/tuple_fy.h" - -#include - -namespace sqlite_orm { - - namespace internal { - - template - struct tuplify { - using type = std::tuple; - }; - template - struct tuplify> { - using type = std::tuple; - }; - - template - using tuplify_t = typename tuplify::type; - } -} - -// #include "tuple_helper/tuple_filter.h" - -// #include "tuple_helper/tuple_transformer.h" - -// #include "tuple_helper/same_or_void.h" - -// #include "type_traits.h" - -// #include "member_traits/member_traits.h" - -// #include "mapped_type_proxy.h" - -#include // std::remove_const - -// #include "type_traits.h" - -// #include "table_reference.h" - -// #include "alias_traits.h" - -namespace sqlite_orm { - - namespace internal { - - /** - * If T is a table reference or recordset alias then the typename mapped_type_proxy::type is the unqualified aliased type, - * otherwise unqualified T. - */ - template - struct mapped_type_proxy : std::remove_const {}; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - struct mapped_type_proxy : R {}; -#endif - - template - struct mapped_type_proxy> : std::remove_const> {}; - - template - using mapped_type_proxy_t = typename mapped_type_proxy::type; - } -} - -// #include "core_functions.h" - -// #include "select_constraints.h" - -// #include "operators.h" - -// #include "rowid.h" - -// #include "column_result_proxy.h" - -// #include "type_traits.h" - -// #include "table_reference.h" - -namespace sqlite_orm { - namespace internal { - - /* - * Holder for the type of an unmapped aggregate/structure/object to be constructed ad-hoc from column results. - * `T` must be constructible using direct-list-initialization. - */ - template - struct structure { - using type = T; - }; - } -} - -namespace sqlite_orm { - namespace internal { - - template - struct column_result_proxy : std::remove_const {}; - - /* - * Unwrap `table_reference` - */ - template - struct column_result_proxy> : decay_table_ref

{}; - - /* - * Pass through `structure` - */ - template - struct column_result_proxy> : P {}; - - template - using column_result_proxy_t = typename column_result_proxy::type; - } -} - -// #include "alias.h" - -// #include "cte_types.h" - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -#include -#include -#endif - -// #include "functional/cxx_core_features.h" - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "tuple_helper/tuple_fy.h" - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -namespace sqlite_orm { - - namespace internal { - - /** - * Aliased column expression mapped into a CTE, stored as a field in a table column. - */ - template - struct aliased_field { - ~aliased_field() = delete; - aliased_field(const aliased_field&) = delete; - void operator=(const aliased_field&) = delete; - - F field; - }; - - /** - * This class captures various properties and aspects of a subselect's column expression, - * and is used as a proxy in table_t<>. - */ - template - class subselect_mapper { - public: - subselect_mapper() = delete; - - // this type name is used to detect the mapping from moniker to object - using cte_moniker_type = Moniker; - using fields_type = std::tuple; - // this type captures the expressions forming the columns in a subselect; - // it is currently unused, however proves to be useful in compilation errors, - // as it simplifies recognizing errors in column expressions - using expressions_tuple = tuplify_t; - // this type captures column reference expressions specified at CTE construction; - // those are: member pointers, alias holders - using explicit_colrefs_tuple = ExplicitColRefs; - // this type captures column reference expressions from the subselect; - // those are: member pointers, alias holders - using subselect_colrefs_tuple = SubselectColRefs; - // this type captures column reference expressions merged from SubselectColRefs and ExplicitColRefs - using final_colrefs_tuple = FinalColRefs; - }; - } -} -#endif - -// #include "storage_traits.h" - -#include // std::tuple - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "tuple_helper/tuple_filter.h" - -// #include "tuple_helper/tuple_transformer.h" - -// #include "type_traits.h" - -// #include "storage_lookup.h" - -#include // std::true_type, std::false_type, std::remove_const, std::enable_if, std::is_base_of, std::is_void -#include -#include // std::index_sequence, std::make_index_sequence - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "type_traits.h" - -namespace sqlite_orm { - namespace internal { - - template - struct storage_t; - - template - using db_objects_tuple = std::tuple; - - struct basic_table; - struct index_base; - struct base_trigger; - - template - struct is_storage : std::false_type {}; - - template - struct is_storage> : std::true_type {}; - template - struct is_storage> : std::true_type {}; - - template - struct is_db_objects : std::false_type {}; - - template - struct is_db_objects> : std::true_type {}; - // note: cannot use `db_objects_tuple` alias template because older compilers have problems - // to match `const db_objects_tuple`. - template - struct is_db_objects> : std::true_type {}; - - /** - * `std::true_type` if given object is mapped, `std::false_type` otherwise. - * - * Note: unlike table_t<>, index_t<>::object_type and trigger_t<>::object_type is always void. - */ - template - struct object_type_matches : polyfill::conjunction>>, - std::is_same>> {}; - - /** - * `std::true_type` if given lookup type (object or moniker) is mapped, `std::false_type` otherwise. - */ - template - using lookup_type_matches = object_type_matches; - } - - // pick/lookup metafunctions - namespace internal { - - /** - * Indirect enabler for DBO, accepting an index to disambiguate non-unique DBOs - */ - template - struct enable_found_table : std::enable_if::value, DBO> {}; - - /** - * SFINAE friendly facility to pick a table definition (`table_t`) from a tuple of database objects. - * - * Lookup - mapped data type - * Seq - index sequence matching the number of DBOs - * DBOs - db_objects_tuple type - */ - template - struct storage_pick_table; - - template - struct storage_pick_table, db_objects_tuple> - : enable_found_table... {}; - - /** - * SFINAE friendly facility to pick a table definition (`table_t`) from a tuple of database objects. - * - * Lookup - 'table' type, mapped data type - * DBOs - db_objects_tuple type, possibly const-qualified - */ - template - using storage_pick_table_t = typename storage_pick_table::value>, - std::remove_const_t>::type; - - /** - * Find a table definition (`table_t`) from a tuple of database objects; - * `std::nonesuch` if not found. - * - * DBOs - db_objects_tuple type - * Lookup - mapped data type - */ - template - struct storage_find_table : polyfill::detected {}; - - /** - * Find a table definition (`table_t`) from a tuple of database objects; - * `std::nonesuch` if not found. - * - * DBOs - db_objects_tuple type, possibly const-qualified - * Lookup - mapped data type - */ - template - using storage_find_table_t = typename storage_find_table>::type; - -#ifndef SQLITE_ORM_BROKEN_VARIADIC_PACK_EXPANSION - template - struct is_mapped : std::false_type {}; - template - struct is_mapped>> : std::true_type {}; -#else - template> - struct is_mapped : std::true_type {}; - template - struct is_mapped : std::false_type {}; -#endif - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_mapped_v = is_mapped::value; - } -} - -// runtime lookup functions -namespace sqlite_orm { - namespace internal { - /** - * Pick the table definition for the specified lookup type from the given tuple of schema objects. - * - * Note: This function requires Lookup to be mapped, otherwise it is removed from the overload resolution set. - */ - template = true> - auto& pick_table(DBOs& dbObjects) { - using table_type = storage_pick_table_t; - return std::get(dbObjects); - } - - /** - * Return passed in DBOs. - */ - template = true> - decltype(auto) db_objects_for_expression(DBOs& dbObjects, const E&) { - return dbObjects; - } - - template = true> - decltype(auto) lookup_table_name(const DBOs& dbObjects); - } -} - -// #include "schema/column.h" - -namespace sqlite_orm { - namespace internal { - - namespace storage_traits { - - /** - * DBO - db object (table) - */ - template - struct storage_mapped_columns_impl - : tuple_transformer, is_column>, field_type_t> {}; - - template<> - struct storage_mapped_columns_impl { - using type = std::tuple<>; - }; - - /** - * DBOs - db_objects_tuple type - * Lookup - mapped or unmapped data type - */ - template - struct storage_mapped_columns : storage_mapped_columns_impl> {}; - - /** - * DBO - db object (table) - */ - template - struct storage_mapped_column_expressions_impl - : tuple_transformer, is_column>, column_field_expression_t> {}; - - template<> - struct storage_mapped_column_expressions_impl { - using type = std::tuple<>; - }; - - /** - * DBOs - db_objects_tuple type - * Lookup - mapped or unmapped data type - */ - template - struct storage_mapped_column_expressions - : storage_mapped_column_expressions_impl> {}; - } - } -} - -// #include "function.h" - -#include // std::enable_if, std::is_member_function_pointer, std::is_function, std::remove_const, std::decay, std::is_convertible, std::is_same, std::false_type, std::true_type -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED -#include // std::copy_constructible -#endif -#include // std::tuple, std::tuple_size, std::tuple_element -#include // std::min, std::copy_n -#include // std::move, std::forward - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "functional/cstring_literal.h" - -// #include "functional/function_traits.h" - -// #include "cxx_type_traits_polyfill.h" - -// #include "mpl.h" - -namespace sqlite_orm { - namespace internal { - /* - * Define nested typenames: - * - return_type - * - arguments_tuple - * - signature_type - */ - template - struct function_traits; - - /* - * A function's return type - */ - template - using function_return_type_t = typename function_traits::return_type; - - /* - * A function's arguments tuple - */ - template class Tuple, - template class ProjectOp = polyfill::type_identity_t> - using function_arguments = typename function_traits::template arguments_tuple; - - /* - * A function's signature - */ - template - using function_signature_type_t = typename function_traits::signature_type; - - template - struct function_traits { - using return_type = R; - - template class Tuple, template class ProjectOp> - using arguments_tuple = Tuple...>; - - using signature_type = R(Args...); - }; - - // non-exhaustive partial specializations of `function_traits` - - template - struct function_traits : function_traits { - using signature_type = R(Args...) const; - }; - -#ifdef SQLITE_ORM_NOTHROW_ALIASES_SUPPORTED - template - struct function_traits : function_traits { - using signature_type = R(Args...) noexcept; - }; - - template - struct function_traits : function_traits { - using signature_type = R(Args...) const noexcept; - }; -#endif - - /* - * Pick signature of function pointer - */ - template - struct function_traits : function_traits {}; - - /* - * Pick signature of function reference - */ - template - struct function_traits : function_traits {}; - - /* - * Pick signature of pointer-to-member function - */ - template - struct function_traits : function_traits {}; - } -} - -// #include "type_traits.h" - -// #include "tags.h" - -namespace sqlite_orm { - - struct arg_values; - - // note (internal): forward declare even if `SQLITE_VERSION_NUMBER < 3020000` in order to simplify coding below - template - struct pointer_arg; - // note (internal): forward declare even if `SQLITE_VERSION_NUMBER < 3020000` in order to simplify coding below - template - class pointer_binding; - - namespace internal { - template - using scalar_call_function_t = decltype(&F::operator()); - - template - using aggregate_step_function_t = decltype(&F::step); - - template - using aggregate_fin_function_t = decltype(&F::fin); - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_scalar_udf_v = false; - template - SQLITE_ORM_INLINE_VAR constexpr bool is_scalar_udf_v>> = true; - - template - struct is_scalar_udf : polyfill::bool_constant> {}; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_aggregate_udf_v = false; - template - SQLITE_ORM_INLINE_VAR constexpr bool is_aggregate_udf_v< - F, - polyfill::void_t, - aggregate_fin_function_t, - std::enable_if_t>::value>, - std::enable_if_t>::value>>> = - true; - - template - struct is_aggregate_udf : polyfill::bool_constant> {}; - - template - struct function; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** @short Specifies that a type is a function signature (i.e. a function in the C++ type system). - */ - template - concept orm_function_sig = std::is_function_v; - - /** @short Specifies that a type is a classic function object. - * - * A classic function object meets the following requirements: - * - defines a single call operator `F::operator()` - * - isn't a traditional sqlite_orm scalar function (having a static `F::name()` function - */ - template - concept orm_classic_function_object = - ((!requires { typename F::is_transparent; }) && (requires { &F::operator(); }) && - /*rule out sqlite_orm scalar function*/ - (!requires { F::name(); })); - - /** @short Specifies that a type is a user-defined scalar function. - * - * `UDF` must meet the following requirements: - * - `UDF::name()` static function - * - `UDF::operator()()` call operator - */ - template - concept orm_scalar_udf = requires { - UDF::name(); - typename internal::scalar_call_function_t; - }; - - /** @short Specifies that a type is a user-defined aggregate function. - * - * `UDF` must meet the following requirements: - * - `UDF::name()` static function - * - `UDF::step()` member function - * - `UDF::fin()` member function - */ - template - concept orm_aggregate_udf = requires { - UDF::name(); - typename internal::aggregate_step_function_t; - typename internal::aggregate_fin_function_t; - requires std::is_member_function_pointer_v>; - requires std::is_member_function_pointer_v>; - }; - - /** @short Specifies that a type is a framed user-defined scalar function. - */ - template - concept orm_scalar_function = (polyfill::is_specialization_of_v, internal::function> && - orm_scalar_udf); - - /** @short Specifies that a type is a framed user-defined aggregate function. - */ - template - concept orm_aggregate_function = (polyfill::is_specialization_of_v, internal::function> && - orm_aggregate_udf); - - /** @short Specifies that a type is a framed and quoted user-defined scalar function. - */ - template - concept orm_quoted_scalar_function = requires(const Q& quotedF) { - quotedF.name(); - quotedF.callable(); - }; -#endif - - namespace internal { - template - struct callable_arguments_impl; - - template - struct callable_arguments_impl> { - using args_tuple = function_arguments, std::tuple, std::decay_t>; - using return_type = function_return_type_t>; - }; - - template - struct callable_arguments_impl> { - using args_tuple = function_arguments, std::tuple, std::decay_t>; - using return_type = function_return_type_t>; - }; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - requires (std::is_function_v) - struct callable_arguments_impl { - using args_tuple = function_arguments; - using return_type = std::decay_t>; - }; -#endif - - template - struct callable_arguments : callable_arguments_impl {}; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /* - * Bundle of type and name of a quoted user-defined function. - */ - template - struct udf_holder : private std::string { - using udf_type = UDF; - - using std::string::basic_string; - - const std::string& operator()() const { - return *this; - } - }; -#endif - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /* - * Bundle of type and name of a traditional sqlite_orm user-defined function. - */ - template - requires (requires { UDF::name(); }) - struct udf_holder -#else - /* - * Bundle of type and name of a traditional sqlite_orm user-defined function. - */ - template - struct udf_holder -#endif - { - using udf_type = UDF; - - template>::value, bool> = true> - decltype(auto) operator()() const { - return UDF::name(); - } - - template::value, bool> = true> - std::string operator()() const { - return std::string{UDF::name()}; - } - }; - - /* - * Represents a call of a user-defined function. - */ - template - struct function_call { - using udf_type = UDF; - using args_tuple = std::tuple; - - udf_holder name; - args_tuple callArgs; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool - is_operator_argument_v::value>> = true; - - template - struct unpacked_arg { - using type = T; - }; - template - struct unpacked_arg> { - using type = typename callable_arguments::return_type; - }; - template - using unpacked_arg_t = typename unpacked_arg::type; - - template - SQLITE_ORM_CONSTEVAL bool expected_pointer_value() { - static_assert(polyfill::always_false_v, "Expected a pointer value for I-th argument"); - return false; - } - - template - constexpr bool is_same_pvt_v = expected_pointer_value(); - - // Always allow binding nullptr to a pointer argument - template - constexpr bool is_same_pvt_v> = true; - // Always allow binding nullptr to a pointer argument - template - constexpr bool is_same_pvt_v, pointer_binding, void> = true; - - template - SQLITE_ORM_CONSTEVAL bool assert_same_pointer_data_type() { - constexpr bool valid = std::is_convertible::value; - static_assert(valid, "Pointer data types of I-th argument do not match"); - return valid; - } - -#if __cplusplus >= 201703L // C++17 or later - template - SQLITE_ORM_CONSTEVAL bool assert_same_pointer_tag() { - constexpr bool valid = Binding == PointerArg; - static_assert(valid, "Pointer types (tags) of I-th argument do not match"); - return valid; - } - template - constexpr bool - is_same_pvt_v> = - assert_same_pointer_tag() && - assert_same_pointer_data_type(); -#else - template - constexpr bool assert_same_pointer_tag() { - constexpr bool valid = Binding::value == PointerArg::value; - static_assert(valid, "Pointer types (tags) of I-th argument do not match"); - return valid; - } - - template - constexpr bool - is_same_pvt_v> = - assert_same_pointer_tag(); -#endif - - // not a pointer value, currently leave it unchecked - template - SQLITE_ORM_CONSTEVAL bool validate_pointer_value_type(std::false_type) { - return true; - } - - // check the type of pointer values - template - SQLITE_ORM_CONSTEVAL bool validate_pointer_value_type(std::true_type) { - return is_same_pvt_v; - } - - template - SQLITE_ORM_CONSTEVAL bool validate_pointer_value_types(polyfill::index_constant) { - return true; - } - template - SQLITE_ORM_CONSTEVAL bool validate_pointer_value_types(polyfill::index_constant) { - using func_param_type = std::tuple_element_t; - using call_arg_type = unpacked_arg_t>; - -#ifdef SQLITE_ORM_RELAXED_CONSTEXPR_SUPPORTED - constexpr bool valid = validate_pointer_value_type, - unpacked_arg_t>>( - polyfill::bool_constant < (polyfill::is_specialization_of_v) || - (polyfill::is_specialization_of_v) > {}); - - return validate_pointer_value_types(polyfill::index_constant{}) && valid; -#else - return validate_pointer_value_types(polyfill::index_constant{}) && - validate_pointer_value_type, - unpacked_arg_t>>( - polyfill::bool_constant < (polyfill::is_specialization_of_v) || - (polyfill::is_specialization_of_v) > {}); -#endif - } - - /* - * Note: Currently the number of call arguments is checked and whether the types of pointer values match, - * but other call argument types are not checked against the parameter types of the function. - */ - template -#ifdef SQLITE_ORM_RELAXED_CONSTEXPR_SUPPORTED - SQLITE_ORM_CONSTEVAL void check_function_call() { -#else - void check_function_call() { -#endif - using call_args_tuple = std::tuple; - using function_params_tuple = typename callable_arguments::args_tuple; - constexpr size_t callArgsCount = std::tuple_size::value; - constexpr size_t functionParamsCount = std::tuple_size::value; - static_assert(std::is_same>::value || - (callArgsCount == functionParamsCount && - validate_pointer_value_types( - polyfill::index_constant{})), - "Check the number and types of the function call arguments"); - } - - /* - * Generator of a user-defined function call in a sql query expression. - * - * Use the variable template `func<>` to instantiate. - * - * Calling the function captures the parameters in a `function_call` node. - */ - template - struct function { - using udf_type = UDF; - using callable_type = UDF; - - /* - * Generates the SQL function call. - */ - template - function_call operator()(CallArgs... callArgs) const { - check_function_call(); - return {this->udf_holder(), {std::forward(callArgs)...}}; - } - - constexpr auto udf_holder() const { - return internal::udf_holder{}; - } - - // returns a character range - constexpr auto name() const { - return this->udf_holder()(); - } - }; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /* - * Generator of a user-defined function call in a sql query expression. - * - * Use the string literal operator template `""_scalar.quote()` to quote - * a freestanding function, stateless lambda or function object. - * - * Calling the function captures the parameters in a `function_call` node. - * - * Internal note: - * 1. Captures and represents a function [pointer or object], especially one without side effects. - * If `F` is a stateless function object, `quoted_scalar_function::callable()` returns the original function object, - * otherwise it is assumed to have possibe side-effects and `quoted_scalar_function::callable()` returns a copy. - * 2. The nested `udf_type` typename is deliberately chosen to be the function signature, - * and will be the abstracted version of the user-defined function. - */ - template - struct quoted_scalar_function { - using udf_type = Sig; - using callable_type = F; - - /* - * Generates the SQL function call. - */ - template - function_call operator()(CallArgs... callArgs) const { - check_function_call(); - return {this->udf_holder(), {std::forward(callArgs)...}}; - } - - /* - * Return original `udf` if stateless or a copy of it otherwise - */ - constexpr decltype(auto) callable() const { - if constexpr (stateless) { - return (this->udf); - } else { - // non-const copy - return F(this->udf); - } - } - - constexpr auto udf_holder() const { - return internal::udf_holder{this->name()}; - } - - constexpr auto name() const { - return this->nme; - } - - template - consteval quoted_scalar_function(const char (&name)[N], Args&&... constructorArgs) : - udf(std::forward(constructorArgs)...) { - std::copy_n(name, N, this->nme); - } - - F udf; - char nme[N]; - }; - - template - struct quoted_function_builder : cstring_literal { - using cstring_literal::cstring_literal; - - /* - * From a freestanding function, possibly overloaded. - */ - template - [[nodiscard]] consteval auto quote(F* callable) const { - return quoted_scalar_function{this->cstr, std::move(callable)}; - } - - /* - * From a classic function object instance. - */ - template - requires (orm_classic_function_object && (stateless || std::copy_constructible)) - [[nodiscard]] consteval auto quote(F callable) const { - using Sig = function_signature_type_t; - // detect whether overloaded call operator can be picked using `Sig` - using call_operator_type = decltype(static_cast(&F::operator())); - return quoted_scalar_function{this->cstr, std::move(callable)}; - } - - /* - * From a function object instance, picking the overloaded call operator. - */ - template - requires ((stateless || std::copy_constructible)) - [[nodiscard]] consteval auto quote(F callable) const { - // detect whether overloaded call operator can be picked using `Sig` - using call_operator_type = decltype(static_cast(&F::operator())); - return quoted_scalar_function{this->cstr, std::move(callable)}; - } - - /* - * From a classic function object type. - */ - template - requires (stateless || std::copy_constructible) - [[nodiscard]] consteval auto quote(Args&&... constructorArgs) const { - using Sig = function_signature_type_t; - return quoted_scalar_function{this->cstr, std::forward(constructorArgs)...}; - } - - /* - * From a function object type, picking the overloaded call operator. - */ - template - requires ((stateless || std::copy_constructible)) - [[nodiscard]] consteval auto quote(Args&&... constructorArgs) const { - // detect whether overloaded call operator can be picked using `Sig` - using call_operator_type = decltype(static_cast(&F::operator())); - return quoted_scalar_function{this->cstr, std::forward(constructorArgs)...}; - } - }; -#endif - } - - /** @short Call a user-defined function. - * - * Note: Currently the number of call arguments is checked and whether the types of pointer values match, - * but other call argument types are not checked against the parameter types of the function. - * - * Example: - * struct IdFunc { int oeprator(int arg)() const { return arg; } }; - * // inline: - * select(func(42)); - * // As this is a variable template, you can frame the user-defined function and define a variable for syntactic sugar and legibility: - * inline constexpr orm_scalar_function auto idfunc = func; - * select(idfunc(42)); - * - */ - template -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - requires (orm_scalar_udf || orm_aggregate_udf) -#endif - SQLITE_ORM_INLINE_VAR constexpr internal::function func{}; - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - inline namespace literals { - /* @short Create a scalar function from a freestanding function, stateless lambda or function object, - * and call such a user-defined function. - * - * If you need to pick a function or method from an overload set, or pick a template function you can - * specify an explicit function signature in the call to `from()`. - * - * Examples: - * // freestanding function from a library - * constexpr orm_quoted_scalar_function auto clamp_int_f = "clamp_int"_scalar.quote(std::clamp); - * // stateless lambda - * constexpr orm_quoted_scalar_function auto is_fatal_error_f = "IS_FATAL_ERROR"_scalar.quote([](unsigned long errcode) { - * return errcode != 0; - * }); - * // function object instance - * constexpr orm_quoted_scalar_function auto equal_to_int_f = "equal_to"_scalar.quote(std::equal_to{}); - * // function object - * constexpr orm_quoted_scalar_function auto equal_to_int_2_f = "equal_to"_scalar.quote>(); - * // pick function object's template call operator - * constexpr orm_quoted_scalar_function auto equal_to_int_3_f = "equal_to"_scalar.quote(std::equal_to{}); - * - * storage.create_scalar_function(); - * storage.create_scalar_function(); - * storage.create_scalar_function(); - * storage.create_scalar_function(); - * storage.create_scalar_function(); - * - * auto rows = storage.select(clamp_int_f(0, 1, 1)); - * auto rows = storage.select(is_fatal_error_f(1)); - * auto rows = storage.select(equal_to_int_f(1, 1)); - * auto rows = storage.select(equal_to_int_2_f(1, 1)); - * auto rows = storage.select(equal_to_int_3_f(1, 1)); - */ - template - [[nodiscard]] consteval auto operator"" _scalar() { - return builder; - } - } -#endif -} - -// #include "ast/special_keywords.h" - -namespace sqlite_orm { - namespace internal { - struct current_time_t {}; - struct current_date_t {}; - struct current_timestamp_t {}; - } - - inline internal::current_time_t current_time() { - return {}; - } - - inline internal::current_date_t current_date() { - return {}; - } - - inline internal::current_timestamp_t current_timestamp() { - return {}; - } -} - -namespace sqlite_orm { - - namespace internal { - - /** - * Obtains the result type of expressions that form the columns of a select statement. - * - * This is a proxy class used to define what type must have result type depending on select - * arguments (member pointer, aggregate functions, etc). Below you can see specializations - * for different types. E.g. specialization for internal::length_t has `type` int cause - * LENGTH returns INTEGER in sqlite. Every column_result_t must have `type` type that equals - * c++ SELECT return type for T - * DBOs - db_objects_tuple type - * T - C++ type - * SFINAE - sfinae argument - */ - template - struct column_result_t { -#ifdef __FUNCTION__ - // produce an error message that reveals `T` and `DBOs` - static constexpr bool reveal() { - static_assert(polyfill::always_false_v, "T not found in DBOs - " __FUNCTION__); - } - static constexpr bool trigger = reveal(); -#endif - }; - - template - using column_result_of_t = typename column_result_t::type; - - template - using column_result_for_tuple_t = - transform_tuple_t::template fn>; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct column_result_t, void> { - using type = std::optional>; - }; - - template - struct column_result_t, void> { - using type = std::optional; - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template - struct column_result_t, void> { - using type = bool; - }; - - template - struct column_result_t, void> { - using type = bool; - }; - - template - struct column_result_t { - using type = std::string; - }; - - template - struct column_result_t { - using type = std::string; - }; - - template - struct column_result_t { - using type = std::string; - }; - - template - struct column_result_t> : member_field_type {}; - - template - struct column_result_t, void> { - using type = R; - }; - - template - struct column_result_t, void> { - using type = R; - }; - - template - struct column_result_t, void> { - using type = typename callable_arguments::return_type; - }; - - template - struct column_result_t, S, X, Rest...>, void> { - using type = std::unique_ptr>; - }; - - template - struct column_result_t, S, X>, void> { - using type = std::unique_ptr>; - }; - - template - struct column_result_t, void> { - using type = int; - }; - - template - struct column_result_t { - using type = nullptr_t; - }; - - template - struct column_result_t { - using type = int; - }; - - template - struct column_result_t, void> : column_result_t {}; - - template - struct column_result_t, void> : column_result_t {}; - - template - struct column_result_t, void> { - using type = std::string; - }; - - template - struct column_result_t, void> { - using type = double; - }; - - template - struct column_result_t, void> { - using type = double; - }; - - template - struct column_result_t, void> { - using type = double; - }; - - template - struct column_result_t, void> { - using type = double; - }; - - template - struct column_result_t, void> { - using type = double; - }; - - template - struct column_result_t, void> { - using type = double; - }; - - template - struct column_result_t, void> { - using type = int; - }; - - template - struct column_result_t, void> { - using type = int; - }; - - template - struct column_result_t, void> { - using type = int; - }; - - template - struct column_result_t, void> { - using type = int; - }; - - template - struct column_result_t, void> { - using type = int; - }; - - template - struct column_result_t { - using type = int64; - }; - - template - struct column_result_t { - using type = int64; - }; - - template - struct column_result_t { - using type = int64; - }; - - template - struct column_result_t, void> { - using type = int64; - }; - - template - struct column_result_t, void> { - using type = int64; - }; - - template - struct column_result_t, void> { - using type = int64; - }; - - template - struct column_result_t, void> : column_result_t {}; - - template - struct column_result_t, void> : column_result_t {}; - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - template - struct column_result_t>, void> { - using table_type = storage_pick_table_t; - using cte_mapper_type = cte_mapper_type_t; - - // lookup ColAlias in the final column references - using colalias_index = - find_tuple_type>; - static_assert(colalias_index::value < std::tuple_size_v, - "No such column mapped into the CTE."); - using type = std::tuple_element_t; - }; -#endif - - template - struct column_result_t, void> - : conc_tuple>>...> {}; - - template - struct column_result_t, void> { - using type = structure>>...>>; - }; - - template - struct column_result_t> : column_result_t {}; - - template - struct column_result_t> { - using type = - polyfill::detected_t>; - static_assert(!std::is_same::value, - "Compound select statements must return a common type"); - }; - - template - struct column_result_t> { - using type = typename T::result_type; - }; - - template - struct column_result_t, void> { - using type = std::string; - }; - - /** - * Result for the most simple queries like `SELECT 1` - */ - template - struct column_result_t> { - using type = T; - }; - - /** - * Result for the most simple queries like `SELECT 'ototo'` - */ - template - struct column_result_t { - using type = std::string; - }; - - template - struct column_result_t { - using type = std::string; - }; - - template - struct column_result_t, void> : column_result_t> {}; - - template - struct column_result_t, void> - : storage_traits::storage_mapped_columns> {}; - - template - struct column_result_t, void> { - using type = table_reference; - }; - - template - struct column_result_t, void> { - using type = T; - }; - - template - struct column_result_t, void> { - using type = R; - }; - - template - struct column_result_t, void> { - using type = bool; - }; - - template - struct column_result_t, void> { - using type = bool; - }; - - template - struct column_result_t, void> { - using type = bool; - }; - - template - struct column_result_t, void> : column_result_t {}; - } -} - -// #include "mapped_type_proxy.h" - -// #include "sync_schema_result.h" - -#include - -namespace sqlite_orm { - - enum class sync_schema_result { - - /** - * created new table, table with the same tablename did not exist - */ - new_table_created, - - /** - * table schema is the same as storage, nothing to be done - */ - already_in_sync, - - /** - * removed excess columns in table (than storage) without dropping a table - */ - old_columns_removed, - - /** - * lacking columns in table (than storage) added without dropping a table - */ - new_columns_added, - - /** - * both old_columns_removed and new_columns_added - */ - new_columns_added_and_old_columns_removed, - - /** - * old table is dropped and new is recreated. Reasons : - * 1. delete excess columns in the table than storage if preseve = false - * 2. Lacking columns in the table cannot be added due to NULL and DEFAULT constraint - * 3. Reasons 1 and 2 both together - * 4. data_type mismatch between table and storage. - */ - dropped_and_recreated, - }; - - inline std::ostream& operator<<(std::ostream& os, sync_schema_result value) { - switch (value) { - case sync_schema_result::new_table_created: - return os << "new table created"; - case sync_schema_result::already_in_sync: - return os << "table and storage is already in sync."; - case sync_schema_result::old_columns_removed: - return os << "old excess columns removed"; - case sync_schema_result::new_columns_added: - return os << "new columns added"; - case sync_schema_result::new_columns_added_and_old_columns_removed: - return os << "old excess columns removed and new columns added"; - case sync_schema_result::dropped_and_recreated: - return os << "old table dropped and recreated"; - } - return os; - } -} - -// #include "table_info.h" - -#include // std::string - -namespace sqlite_orm { - - struct table_info { - int cid = 0; - std::string name; - std::string type; - bool notnull = false; - std::string dflt_value; - int pk = 0; - -#if !defined(SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED) || !defined(SQLITE_ORM_AGGREGATE_PAREN_INIT_SUPPORTED) - table_info(decltype(cid) cid_, - decltype(name) name_, - decltype(type) type_, - decltype(notnull) notnull_, - decltype(dflt_value) dflt_value_, - decltype(pk) pk_) : - cid(cid_), name(std::move(name_)), type(std::move(type_)), notnull(notnull_), - dflt_value(std::move(dflt_value_)), pk(pk_) {} -#endif - }; - - struct table_xinfo { - int cid = 0; - std::string name; - std::string type; - bool notnull = false; - std::string dflt_value; - int pk = 0; - int hidden = 0; // different than 0 => generated_always_as() - TODO verify - -#if !defined(SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED) || !defined(SQLITE_ORM_AGGREGATE_PAREN_INIT_SUPPORTED) - table_xinfo(decltype(cid) cid_, - decltype(name) name_, - decltype(type) type_, - decltype(notnull) notnull_, - decltype(dflt_value) dflt_value_, - decltype(pk) pk_, - decltype(hidden) hidden_) : - cid(cid_), name(std::move(name_)), type(std::move(type_)), notnull(notnull_), - dflt_value(std::move(dflt_value_)), pk(pk_), hidden{hidden_} {} -#endif - }; -} - -// #include "storage_impl.h" - -#include // std::string - -// #include "functional/static_magic.h" - -// #include "functional/index_sequence_util.h" - -// #include "tuple_helper/tuple_traits.h" - -// #include "tuple_helper/tuple_filter.h" - -// #include "tuple_helper/tuple_iteration.h" - -// #include "type_traits.h" - -// #include "select_constraints.h" - -// #include "cte_types.h" - -// #include "schema/column.h" - -// #include "schema/table.h" - -#include // std::string -#include // std::remove_const, std::is_member_pointer, std::true_type, std::false_type -#include // std::vector -#include // std::tuple_element -#include // std::forward, std::move - -// #include "../functional/cxx_type_traits_polyfill.h" - -// #include "../functional/cxx_functional_polyfill.h" - -// #include "../functional/static_magic.h" - -// #include "../functional/mpl.h" - -// #include "../functional/index_sequence_util.h" - -// #include "../tuple_helper/tuple_filter.h" - -// #include "../tuple_helper/tuple_traits.h" - -// #include "../tuple_helper/tuple_iteration.h" - -// #include "../tuple_helper/tuple_transformer.h" - -// #include "../member_traits/member_traits.h" - -// #include "../typed_comparator.h" - -namespace sqlite_orm { - - namespace internal { - - template - bool compare_any(const L& /*lhs*/, const R& /*rhs*/) { - return false; - } - template - bool compare_any(const O& lhs, const O& rhs) { - return lhs == rhs; - } - } -} - -// #include "../type_traits.h" - -// #include "../alias_traits.h" - -// #include "../constraints.h" - -// #include "../table_info.h" - -// #include "index.h" - -#include // std::tuple, std::make_tuple, std::declval, std::tuple_element_t -#include // std::string -#include // std::forward - -// #include "../tuple_helper/tuple_traits.h" - -// #include "../indexed_column.h" - -#include // std::string -#include // std::move - -// #include "ast/where.h" - -namespace sqlite_orm { - - namespace internal { - - template - struct indexed_column_t { - using column_type = C; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - indexed_column_t(column_type _column_or_expression) : - column_or_expression(std::move(_column_or_expression)) {} -#endif - - column_type column_or_expression; - std::string _collation_name; - int _order = 0; // -1 = desc, 1 = asc, 0 = not specified - - indexed_column_t collate(std::string name) { - auto res = std::move(*this); - res._collation_name = std::move(name); - return res; - } - - indexed_column_t asc() { - auto res = std::move(*this); - res._order = 1; - return res; - } - - indexed_column_t desc() { - auto res = std::move(*this); - res._order = -1; - return res; - } - }; - - template - indexed_column_t make_indexed_column(C col) { - return {std::move(col)}; - } - - template - where_t make_indexed_column(where_t wher) { - return std::move(wher); - } - - template - indexed_column_t make_indexed_column(indexed_column_t col) { - return std::move(col); - } - } - - /** - * Use this function to specify indexed column inside `make_index` function call. - * Example: make_index("index_name", indexed_column(&User::id).asc()) - */ - template - internal::indexed_column_t indexed_column(C column_or_expression) { - return {std::move(column_or_expression)}; - } -} - -// #include "../table_type_of.h" - -namespace sqlite_orm { - - namespace internal { - - struct index_base { - std::string name; - bool unique = false; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - index_base(std::string name, bool unique) : name{std::move(name)}, unique{unique} {} -#endif - }; - - template - struct index_t : index_base { - using elements_type = std::tuple; - using object_type = void; - using table_mapped_type = T; - -#ifndef SQLITE_ORM_AGGREGATE_BASES_SUPPORTED - index_t(std::string name_, bool unique_, elements_type elements_) : - index_base{std::move(name_), unique_}, elements(std::move(elements_)) {} -#endif - - elements_type elements; - }; - } - - template - internal::index_t()))...> make_index(std::string name, - Cols... cols) { - using cols_tuple = std::tuple; - static_assert(internal::count_tuple::value <= 1, - "amount of where arguments can be 0 or 1"); - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES( - return {std::move(name), false, std::make_tuple(internal::make_indexed_column(std::move(cols))...)}); - } - - template - internal::index_t>>, - decltype(internal::make_indexed_column(std::declval()))...> - make_index(std::string name, Cols... cols) { - using cols_tuple = std::tuple; - static_assert(internal::count_tuple::value <= 1, - "amount of where arguments can be 0 or 1"); - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES( - return {std::move(name), false, std::make_tuple(internal::make_indexed_column(std::move(cols))...)}); - } - - template - internal::index_t>>, - decltype(internal::make_indexed_column(std::declval()))...> - make_unique_index(std::string name, Cols... cols) { - using cols_tuple = std::tuple; - static_assert(internal::count_tuple::value <= 1, - "amount of where arguments can be 0 or 1"); - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES( - return {std::move(name), true, std::make_tuple(internal::make_indexed_column(std::move(cols))...)}); - } -} - -// #include "column.h" - -namespace sqlite_orm { - - namespace internal { - - template - using is_table_element_or_constraint = mpl::invoke_t, - check_if, - check_if, - check_if_is_template, - check_if_is_template, - check_if_is_template, - check_if_is_template, - check_if_is_template, - check_if_is_template, - check_if_is_template>, - T>; - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - /** - * A subselect mapper's CTE moniker, void otherwise. - */ - template - using moniker_of_or_void_t = polyfill::detected_or_t; - - /** - * If O is a subselect_mapper then returns its nested type name O::cte_moniker_type, - * otherwise O itself is a regular object type to be mapped. - */ - template - using mapped_object_type_for_t = polyfill::detected_or_t; -#endif - - struct basic_table { - - /** - * Table name. - */ - std::string name; - }; - - /** - * Table definition. - */ - template - struct table_t : basic_table { -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - // this typename is used in contexts where it is known that the 'table' holds a subselect_mapper - // instead of a regular object type - using cte_mapper_type = O; - using cte_moniker_type = moniker_of_or_void_t; - using object_type = mapped_object_type_for_t; -#else - using object_type = O; -#endif - using elements_type = std::tuple; - - static constexpr bool is_without_rowid_v = WithoutRowId; - - using is_without_rowid = polyfill::bool_constant; - - elements_type elements; - -#ifndef SQLITE_ORM_AGGREGATE_BASES_SUPPORTED - table_t(std::string name_, elements_type elements_) : - basic_table{std::move(name_)}, elements{std::move(elements_)} {} -#endif - - table_t without_rowid() const { - return {this->name, this->elements}; - } - - /* - * Returns the number of elements of the specified type. - */ - template class Trait> - static constexpr int count_of() { - using sequence_of = filter_tuple_sequence_t; - return int(sequence_of::size()); - } - - /* - * Returns the number of columns having the specified constraint trait. - */ - template class Trait> - static constexpr int count_of_columns_with() { - using filtered_index_sequence = col_index_sequence_with; - return int(filtered_index_sequence::size()); - } - - /* - * Returns the number of columns having the specified constraint trait. - */ - template class Trait> - static constexpr int count_of_columns_excluding() { - using excluded_col_index_sequence = col_index_sequence_excluding; - return int(excluded_col_index_sequence::size()); - } - - /** - * Function used to get field value from object by mapped member pointer/setter/getter. - * - * For a setter the corresponding getter has to be searched, - * so the method returns a pointer to the field as returned by the found getter. - * Otherwise the method invokes the member pointer and returns its result. - */ - template = true> - decltype(auto) object_field_value(const object_type& object, M memberPointer) const { - return polyfill::invoke(memberPointer, object); - } - - template = true> - const member_field_type_t* object_field_value(const object_type& object, M memberPointer) const { - using field_type = member_field_type_t; - const field_type* res = nullptr; - iterate_tuple(this->elements, - col_index_sequence_with_field_type{}, - call_as_template_base([&res, &memberPointer, &object](const auto& column) { - if (compare_any(column.setter, memberPointer)) { - res = &polyfill::invoke(column.member_pointer, object); - } - })); - return res; - } - - const basic_generated_always::storage_type* - find_column_generated_storage_type(const std::string& name) const { - const basic_generated_always::storage_type* result = nullptr; -#if SQLITE_VERSION_NUMBER >= 3031000 - iterate_tuple(this->elements, - col_index_sequence_with{}, - [&result, &name](auto& column) { - if (column.name != name) { - return; - } - using generated_op_index_sequence = - filter_tuple_sequence_t, - is_generated_always>; - constexpr size_t opIndex = index_sequence_value_at<0>(generated_op_index_sequence{}); - result = &std::get(column.constraints).storage; - }); -#else - (void)name; -#endif - return result; - } - - /** - * Call passed lambda with all defined primary keys. - */ - template - void for_each_primary_key(L&& lambda) const { - using pk_index_sequence = filter_tuple_sequence_t; - iterate_tuple(this->elements, pk_index_sequence{}, lambda); - } - - std::vector composite_key_columns_names() const { - std::vector res; - this->for_each_primary_key([this, &res](auto& primaryKey) { - res = this->composite_key_columns_names(primaryKey); - }); - return res; - } - - std::vector primary_key_column_names() const { - using pkcol_index_sequence = col_index_sequence_with; - - if (pkcol_index_sequence::size() > 0) { - return create_from_tuple>(this->elements, - pkcol_index_sequence{}, - &column_identifier::name); - } else { - return this->composite_key_columns_names(); - } - } - - template - void for_each_primary_key_column(L&& lambda) const { - iterate_tuple(this->elements, - col_index_sequence_with{}, - call_as_template_base([&lambda](const auto& column) { - lambda(column.member_pointer); - })); - this->for_each_primary_key([&lambda](auto& primaryKey) { - iterate_tuple(primaryKey.columns, lambda); - }); - } - - template - std::vector composite_key_columns_names(const primary_key_t& primaryKey) const { - return create_from_tuple>(primaryKey.columns, - [this, empty = std::string{}](auto& memberPointer) { - if (const std::string* columnName = - this->find_column_name(memberPointer)) { - return *columnName; - } else { - return empty; - } - }); - } - - /** - * Searches column name by class member pointer passed as the first argument. - * @return column name or empty string if nothing found. - */ - template = true> - const std::string* find_column_name(M m) const { - const std::string* res = nullptr; - using field_type = member_field_type_t; - iterate_tuple(this->elements, - col_index_sequence_with_field_type{}, - [&res, m](auto& c) { - if (compare_any(c.member_pointer, m) || compare_any(c.setter, m)) { - res = &c.name; - } - }); - return res; - } - - /** - * Call passed lambda with all defined foreign keys. - * @param lambda Lambda called for each column. Function signature: `void(auto& column)` - */ - template - void for_each_foreign_key(L&& lambda) const { - using fk_index_sequence = filter_tuple_sequence_t; - iterate_tuple(this->elements, fk_index_sequence{}, lambda); - } - - template - void for_each_foreign_key_to(L&& lambda) const { - using fk_index_sequence = filter_tuple_sequence_t; - using filtered_index_sequence = filter_tuple_sequence_t::template fn, - target_type_t, - fk_index_sequence>; - iterate_tuple(this->elements, filtered_index_sequence{}, lambda); - } - - /** - * Call passed lambda with all defined columns. - * @param lambda Lambda called for each column. Function signature: `void(auto& column)` - */ - template - void for_each_column(L&& lambda) const { - using col_index_sequence = filter_tuple_sequence_t; - iterate_tuple(this->elements, col_index_sequence{}, lambda); - } - - /** - * Call passed lambda with columns not having the specified constraint trait `OpTrait`. - * @param lambda Lambda called for each column. - */ - template class OpTraitFn, class L> - void for_each_column_excluding(L&& lambda) const { - iterate_tuple(this->elements, col_index_sequence_excluding{}, lambda); - } - - /** - * Call passed lambda with columns not having the specified constraint trait `OpTrait`. - * @param lambda Lambda called for each column. - */ - template = true> - void for_each_column_excluding(L&& lambda) const { - this->template for_each_column_excluding(lambda); - } - - std::vector get_table_info() const; - }; - - template - struct is_table : std::false_type {}; - - template - struct is_table> : std::true_type {}; - - template - struct virtual_table_t : basic_table { - using module_details_type = M; - using object_type = typename module_details_type::object_type; - using elements_type = typename module_details_type::columns_type; - - static constexpr bool is_without_rowid_v = false; - using is_without_rowid = polyfill::bool_constant; - - module_details_type module_details; - -#ifndef SQLITE_ORM_AGGREGATE_BASES_SUPPORTED - virtual_table_t(std::string name, module_details_type module_details) : - basic_table{std::move(name)}, module_details{std::move(module_details)} {} -#endif - - /** - * Call passed lambda with columns not having the specified constraint trait `OpTrait`. - * @param lambda Lambda called for each column. - */ - template class OpTraitFn, class L> - void for_each_column_excluding(L&& lambda) const { - this->module_details.template for_each_column_excluding(lambda); - } - - /** - * Call passed lambda with columns not having the specified constraint trait `OpTrait`. - * @param lambda Lambda called for each column. - */ - template = true> - void for_each_column_excluding(L&& lambda) const { - this->module_details.template for_each_column_excluding(lambda); - } - - /** - * Call passed lambda with all defined columns. - * @param lambda Lambda called for each column. Function signature: `void(auto& column)` - */ - template - void for_each_column(L&& lambda) const { - this->module_details.for_each_column(lambda); - } - }; - - template - struct is_virtual_table : std::false_type {}; - - template - struct is_virtual_table> : std::true_type {}; - -#if SQLITE_VERSION_NUMBER >= 3009000 - template - struct using_fts5_t { - using object_type = T; - using columns_type = std::tuple; - - columns_type columns; - - using_fts5_t(columns_type columns) : columns(std::move(columns)) {} - - /** - * Call passed lambda with columns not having the specified constraint trait `OpTrait`. - * @param lambda Lambda called for each column. - */ - template class OpTraitFn, class L> - void for_each_column_excluding(L&& lambda) const { - iterate_tuple(this->columns, col_index_sequence_excluding{}, lambda); - } - - /** - * Call passed lambda with columns not having the specified constraint trait `OpTrait`. - * @param lambda Lambda called for each column. - */ - template = true> - void for_each_column_excluding(L&& lambda) const { - this->template for_each_column_excluding(lambda); - } - - /** - * Call passed lambda with all defined columns. - * @param lambda Lambda called for each column. Function signature: `void(auto& column)` - */ - template - void for_each_column(L&& lambda) const { - using col_index_sequence = filter_tuple_sequence_t; - iterate_tuple(this->columns, col_index_sequence{}, lambda); - } - }; -#endif - - template - bool exists_in_composite_primary_key(const table_t& table, - const column_field& column) { - bool res = false; - table.for_each_primary_key([&column, &res](auto& primaryKey) { - using colrefs_tuple = decltype(primaryKey.columns); - using same_type_index_sequence = - filter_tuple_sequence_t>::template fn, - member_field_type_t>; - iterate_tuple(primaryKey.columns, same_type_index_sequence{}, [&res, &column](auto& memberPointer) { - if (compare_any(memberPointer, column.member_pointer) || - compare_any(memberPointer, column.setter)) { - res = true; - } - }); - }); - return res; - } - - template - bool exists_in_composite_primary_key(const virtual_table_t& /*virtualTable*/, - const column_field& /*column*/) { - return false; - } - } - -#if SQLITE_VERSION_NUMBER >= 3009000 - template>::object_type> - internal::using_fts5_t using_fts5(Cs... columns) { - static_assert(polyfill::conjunction_v...>, - "Incorrect table elements or constraints"); - - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES(return {std::make_tuple(std::forward(columns)...)}); - } - - template - internal::using_fts5_t using_fts5(Cs... columns) { - static_assert(polyfill::conjunction_v...>, - "Incorrect table elements or constraints"); - - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES(return {std::make_tuple(std::forward(columns)...)}); - } -#endif - - /** - * Factory function for a table definition. - * - * The mapped object type is determined implicitly from the first column definition. - */ - template>::object_type> - internal::table_t make_table(std::string name, Cs... args) { - static_assert(polyfill::conjunction_v...>, - "Incorrect table elements or constraints"); - - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES( - return {std::move(name), std::make_tuple(std::forward(args)...)}); - } - - /** - * Factory function for a table definition. - * - * The mapped object type is explicitly specified. - */ - template - internal::table_t make_table(std::string name, Cs... args) { - static_assert(polyfill::conjunction_v...>, - "Incorrect table elements or constraints"); - - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES( - return {std::move(name), std::make_tuple(std::forward(args)...)}); - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Factory function for a table definition. - * - * The mapped object type is explicitly specified. - */ - template - auto make_table(std::string name, Cs... args) { - return make_table>(std::move(name), std::forward(args)...); - } -#endif - - template - internal::virtual_table_t make_virtual_table(std::string name, M module_details) { - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES(return {std::move(name), std::move(module_details)}); - } -} - -// #include "storage_lookup.h" - -// interface functions -namespace sqlite_orm { - namespace internal { - - template - using tables_index_sequence = filter_tuple_sequence_t; - - template = true> - int foreign_keys_count(const DBOs& dbObjects) { - int res = 0; - iterate_tuple(dbObjects, tables_index_sequence{}, [&res](const auto& table) { - res += table.template count_of(); - }); - return res; - } - - template> - decltype(auto) lookup_table_name(const DBOs& dbObjects) { - return static_if::value>( - [](const auto& dbObjects) -> const std::string& { - return pick_table(dbObjects).name; - }, - empty_callable)(dbObjects); - } - - /** - * Find column name by its type and member pointer. - */ - template = true> - const std::string* find_column_name(const DBOs& dbObjects, F O::* field) { - return pick_table(dbObjects).find_column_name(field); - } - - /** - * Materialize column pointer: - * 1. by explicit object type and member pointer. - * 2. by moniker and member pointer. - */ - template = true> - constexpr decltype(auto) materialize_column_pointer(const DBOs&, const column_pointer& cp) { - return cp.field; - } - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - /** - * Materialize column pointer: - * 3. by moniker and alias_holder<>. - * - * internal note: there's an overload for `find_column_name()` that avoids going through `table_t<>::find_column_name()` - */ - template = true> - constexpr decltype(auto) materialize_column_pointer(const DBOs&, - const column_pointer>&) { - using table_type = storage_pick_table_t; - using cte_mapper_type = cte_mapper_type_t; - - // lookup ColAlias in the final column references - using colalias_index = - find_tuple_type>; - static_assert(colalias_index::value < std::tuple_size_v, - "No such column mapped into the CTE."); - - return &aliased_field< - ColAlias, - std::tuple_element_t>::field; - } -#endif - - /** - * Find column name by: - * 1. by explicit object type and member pointer. - * 2. by moniker and member pointer. - */ - template = true> - const std::string* find_column_name(const DBOs& dbObjects, const column_pointer& cp) { - auto field = materialize_column_pointer(dbObjects, cp); - return pick_table(dbObjects).find_column_name(field); - } - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - /** - * Find column name by: - * 3. by moniker and alias_holder<>. - */ - template = true> - constexpr decltype(auto) find_column_name(const DBOs& dboObjects, - const column_pointer>&) { - using table_type = storage_pick_table_t; - using cte_mapper_type = cte_mapper_type_t; - using column_index_sequence = filter_tuple_sequence_t, is_column>; - - // note: even though the columns contain the [`aliased_field<>::*`] we perform the lookup using the column references. - // lookup ColAlias in the final column references - using colalias_index = - find_tuple_type>; - static_assert(colalias_index::value < std::tuple_size_v, - "No such column mapped into the CTE."); - - // note: we could "materialize" the alias to an `aliased_field<>::*` and use the regular `table_t<>::find_column_name()` mechanism; - // however we have the column index already. - // lookup column in table_t<>'s elements - constexpr size_t ColIdx = index_sequence_value_at(column_index_sequence{}); - auto& table = pick_table(dboObjects); - return &std::get(table.elements).name; - } -#endif - } -} - -// #include "journal_mode.h" - -#include // std::array -#include // std::string -#include // std::pair -#include // std::ranges::transform -#include // std::toupper - -// #include "serialize_result_type.h" - -#if defined(_WINNT_) -// DELETE is a macro defined in the Windows SDK (winnt.h) -#pragma push_macro("DELETE") -#undef DELETE -#endif - -namespace sqlite_orm { - - /** - * Caps case because of: - * 1) delete keyword; - * 2) https://www.sqlite.org/pragma.html#pragma_journal_mode original spelling - */ - enum class journal_mode : signed char { - DELETE = 0, - // An alternate enumeration value when using the Windows SDK that defines DELETE as a macro. - DELETE_ = DELETE, - TRUNCATE = 1, - PERSIST = 2, - MEMORY = 3, - WAL = 4, - OFF = 5, - }; - - namespace internal { - - inline const serialize_result_type& journal_mode_to_string(journal_mode value) { -#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED - static constexpr std::array idx2str = { -#else - static const std::array idx2str = { -#endif - "DELETE", - "TRUNCATE", - "PERSIST", - "MEMORY", - "WAL", - "OFF", - }; - return idx2str.at(static_cast(value)); - } - - inline std::pair journal_mode_from_string(std::string string) { - static constexpr std::array journalModes = {{ - journal_mode::DELETE, - journal_mode::TRUNCATE, - journal_mode::PERSIST, - journal_mode::MEMORY, - journal_mode::WAL, - journal_mode::OFF, - }}; -#if __cpp_lib_ranges >= 201911L - std::ranges::transform(string, string.begin(), [](unsigned char c) noexcept { - return std::toupper(c); - }); - if (auto found = std::ranges::find(journalModes, string, journal_mode_to_string); - found != journalModes.end()) SQLITE_ORM_CPP_LIKELY { - return {true, *found}; - } -#else - std::transform(string.begin(), string.end(), string.begin(), [](unsigned char c) noexcept { - return std::toupper(c); - }); - for (auto journalMode: journalModes) { - if (journal_mode_to_string(journalMode) == string) { - return {true, journalMode}; - } - } -#endif - return {false, journal_mode::OFF}; - } - } -} - -#if defined(_WINNT_) -#pragma pop_macro("DELETE") -#endif - -// #include "mapped_view.h" - -#include -#include // std::forward, std::move - -// #include "row_extractor.h" - -#include -#include // std::enable_if_t, std::is_arithmetic, std::is_same, std::enable_if -#include // atof, atoi, atoll -#include // strlen -#include // std::system_error -#include // std::string, std::wstring -#ifndef SQLITE_ORM_OMITS_CODECVT -#include // std::wstring_convert -#include // std::codecvt_utf8_utf16 -#endif -#include // std::vector -#include // std::copy -#include // std::back_inserter -#include // std::tuple, std::tuple_size, std::tuple_element -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED -#include -#endif - -// #include "functional/cxx_functional_polyfill.h" - -// #include "functional/static_magic.h" - -// #include "tuple_helper/tuple_transformer.h" - -// #include "column_result_proxy.h" - -// #include "arithmetic_tag.h" - -// #include "pointer_value.h" - -// #include "journal_mode.h" - -// #include "locking_mode.h" - -#include // std::array -#include // std::string -#include // std::pair -#include // std::ranges::transform -#include // std::toupper - -// #include "serialize_result_type.h" - -namespace sqlite_orm { - enum class locking_mode : signed char { - NORMAL = 0, - EXCLUSIVE = 1, - }; - - namespace internal { - inline const serialize_result_type& locking_mode_to_string(locking_mode value) { -#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED - static constexpr std::array idx2str = { -#else - static const std::array idx2str = { -#endif - "NORMAL", - "EXCLUSIVE", - }; - return idx2str.at(static_cast(value)); - } - - inline std::pair locking_mode_from_string(std::string string) { - static constexpr std::array lockingModes = {{ - locking_mode::NORMAL, - locking_mode::EXCLUSIVE, - }}; - -#if __cpp_lib_ranges >= 201911L - std::ranges::transform(string, string.begin(), [](unsigned char c) noexcept { - return std::toupper(c); - }); - if (auto found = std::ranges::find(lockingModes, string, locking_mode_to_string); - found != lockingModes.end()) SQLITE_ORM_CPP_LIKELY { - return {true, *found}; - } -#else - std::transform(string.begin(), string.end(), string.begin(), [](unsigned char c) noexcept { - return std::toupper(c); - }); - for (auto lockingMode: lockingModes) { - if (locking_mode_to_string(lockingMode) == string) { - return {true, lockingMode}; - } - } -#endif - return {false, locking_mode::NORMAL}; - } - } -} -// #include "error_code.h" - -// #include "is_std_ptr.h" - -// #include "type_traits.h" - -namespace sqlite_orm { - - /** - * Helper for casting values originating from SQL to C++ typed values, usually from rows of a result set. - * - * sqlite_orm provides specializations for known C++ types, users may define their custom specialization - * of this helper. - * - * @note (internal): Since row extractors are used in certain contexts with only one purpose at a time - * (e.g., converting a row result set but not function values or column text), - * there are factory functions that perform conceptual checking that should be used - * instead of directly creating row extractors. - * - * - */ - template - struct row_extractor { - /* - * Called during one-step query execution (one result row) for each column of a result row. - */ - V extract(const char* columnText) const = delete; - - /* - * Called during multi-step query execution (result set) for each column of a result row. - */ - V extract(sqlite3_stmt* stmt, int columnIndex) const = delete; - - /* - * Called before invocation of user-defined scalar or aggregate functions, - * in order to unbox dynamically typed SQL function values into a tuple of C++ function arguments. - */ - V extract(sqlite3_value* value) const = delete; - }; - -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - template - concept orm_column_text_extractable = requires(const row_extractor& extractor, const char* columnText) { - { extractor.extract(columnText) } -> std::same_as; - }; - - template - concept orm_row_value_extractable = - requires(const row_extractor& extractor, sqlite3_stmt* stmt, int columnIndex) { - { extractor.extract(stmt, columnIndex) } -> std::same_as; - }; - - template - concept orm_boxed_value_extractable = requires(const row_extractor& extractor, sqlite3_value* value) { - { extractor.extract(value) } -> std::same_as; - }; -#endif - - namespace internal { - /* - * Make a row extractor to be used for casting SQL column text to a C++ typed value. - */ - template -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - requires (orm_column_text_extractable) -#endif - row_extractor column_text_extractor() { - return {}; - } - - /* - * Make a row extractor to be used for converting a value from a SQL result row set to a C++ typed value. - */ - template -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - requires (orm_row_value_extractable) -#endif - row_extractor row_value_extractor() { - return {}; - } - - /* - * Make a row extractor to be used for unboxing a dynamically typed SQL value to a C++ typed value. - */ - template -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - requires (orm_boxed_value_extractable) -#endif - row_extractor boxed_value_extractor() { - return {}; - } - } - - template - int extract_single_value(void* data, int argc, char** argv, char**) { - auto& res = *(R*)data; - if (argc) { - const auto rowExtractor = internal::column_text_extractor(); - res = rowExtractor.extract(argv[0]); - } - return 0; - } - -#if SQLITE_VERSION_NUMBER >= 3020000 - /** - * Specialization for the 'pointer-passing interface'. - * - * @note The 'pointer-passing' interface doesn't support (and in fact prohibits) - * extracting pointers from columns. - */ - template - struct row_extractor, void> { - using V = pointer_arg; - - V extract(const char* columnText) const = delete; - - V extract(sqlite3_stmt* stmt, int columnIndex) const = delete; - - V extract(sqlite3_value* value) const { - return {(P*)sqlite3_value_pointer(value, T::value)}; - } - }; - - /** - * Undefine using pointer_binding<> for querying values - */ - template - struct row_extractor, void>; -#endif - - /** - * Specialization for arithmetic types. - */ - template - struct row_extractor::value>> { - V extract(const char* columnText) const { - return this->extract(columnText, tag()); - } - - V extract(sqlite3_stmt* stmt, int columnIndex) const { - return this->extract(stmt, columnIndex, tag()); - } - - V extract(sqlite3_value* value) const { - return this->extract(value, tag()); - } - - private: - using tag = arithmetic_tag_t; - - V extract(const char* columnText, const int_or_smaller_tag&) const { - return static_cast(atoi(columnText)); - } - - V extract(sqlite3_stmt* stmt, int columnIndex, const int_or_smaller_tag&) const { - return static_cast(sqlite3_column_int(stmt, columnIndex)); - } - - V extract(sqlite3_value* value, const int_or_smaller_tag&) const { - return static_cast(sqlite3_value_int(value)); - } - - V extract(const char* columnText, const bigint_tag&) const { - return static_cast(atoll(columnText)); - } - - V extract(sqlite3_stmt* stmt, int columnIndex, const bigint_tag&) const { - return static_cast(sqlite3_column_int64(stmt, columnIndex)); - } - - V extract(sqlite3_value* value, const bigint_tag&) const { - return static_cast(sqlite3_value_int64(value)); - } - - V extract(const char* columnText, const real_tag&) const { - return static_cast(atof(columnText)); - } - - V extract(sqlite3_stmt* stmt, int columnIndex, const real_tag&) const { - return static_cast(sqlite3_column_double(stmt, columnIndex)); - } - - V extract(sqlite3_value* value, const real_tag&) const { - return static_cast(sqlite3_value_double(value)); - } - }; - - /** - * Specialization for std::string. - */ - template - struct row_extractor::value>> { - T extract(const char* columnText) const { - if (columnText) { - return columnText; - } else { - return {}; - } - } - - T extract(sqlite3_stmt* stmt, int columnIndex) const { - if (auto cStr = (const char*)sqlite3_column_text(stmt, columnIndex)) { - return cStr; - } else { - return {}; - } - } - - T extract(sqlite3_value* value) const { - if (auto cStr = (const char*)sqlite3_value_text(value)) { - return cStr; - } else { - return {}; - } - } - }; -#ifndef SQLITE_ORM_OMITS_CODECVT - /** - * Specialization for std::wstring. - */ - template<> - struct row_extractor { - std::wstring extract(const char* columnText) const { - if (columnText) { - std::wstring_convert> converter; - return converter.from_bytes(columnText); - } else { - return {}; - } - } - - std::wstring extract(sqlite3_stmt* stmt, int columnIndex) const { - auto cStr = (const char*)sqlite3_column_text(stmt, columnIndex); - if (cStr) { - std::wstring_convert> converter; - return converter.from_bytes(cStr); - } else { - return {}; - } - } - - std::wstring extract(sqlite3_value* value) const { - if (auto cStr = (const wchar_t*)sqlite3_value_text16(value)) { - return cStr; - } else { - return {}; - } - } - }; -#endif // SQLITE_ORM_OMITS_CODECVT - - template - struct row_extractor::value>> { - using unqualified_type = std::remove_cv_t; - - V extract(const char* columnText) const -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - requires (orm_column_text_extractable) -#endif - { - if (columnText) { - const row_extractor rowExtractor{}; - return is_std_ptr::make(rowExtractor.extract(columnText)); - } else { - return {}; - } - } - - V extract(sqlite3_stmt* stmt, int columnIndex) const -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - requires (orm_row_value_extractable) -#endif - { - auto type = sqlite3_column_type(stmt, columnIndex); - if (type != SQLITE_NULL) { - const row_extractor rowExtractor{}; - return is_std_ptr::make(rowExtractor.extract(stmt, columnIndex)); - } else { - return {}; - } - } - - V extract(sqlite3_value* value) const -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - requires (orm_boxed_value_extractable) -#endif - { - auto type = sqlite3_value_type(value); - if (type != SQLITE_NULL) { - const row_extractor rowExtractor{}; - return is_std_ptr::make(rowExtractor.extract(value)); - } else { - return {}; - } - } - }; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct row_extractor>> { - using unqualified_type = std::remove_cv_t; - - V extract(const char* columnText) const -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - requires (orm_column_text_extractable) -#endif - { - if (columnText) { - const row_extractor rowExtractor{}; - return std::make_optional(rowExtractor.extract(columnText)); - } else { - return std::nullopt; - } - } - - V extract(sqlite3_stmt* stmt, int columnIndex) const -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - requires (orm_row_value_extractable) -#endif - { - auto type = sqlite3_column_type(stmt, columnIndex); - if (type != SQLITE_NULL) { - const row_extractor rowExtractor{}; - return std::make_optional(rowExtractor.extract(stmt, columnIndex)); - } else { - return std::nullopt; - } - } - - V extract(sqlite3_value* value) const -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - requires (orm_boxed_value_extractable) -#endif - { - auto type = sqlite3_value_type(value); - if (type != SQLITE_NULL) { - const row_extractor rowExtractor{}; - return std::make_optional(rowExtractor.extract(value)); - } else { - return std::nullopt; - } - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template<> - struct row_extractor { - nullptr_t extract(const char* /*columnText*/) const { - return nullptr; - } - - nullptr_t extract(sqlite3_stmt*, int /*columnIndex*/) const { - return nullptr; - } - - nullptr_t extract(sqlite3_value*) const { - return nullptr; - } - }; - /** - * Specialization for std::vector. - */ - template<> - struct row_extractor, void> { - std::vector extract(const char* columnText) const { - return {columnText, columnText + (columnText ? strlen(columnText) : 0)}; - } - - std::vector extract(sqlite3_stmt* stmt, int columnIndex) const { - auto bytes = static_cast(sqlite3_column_blob(stmt, columnIndex)); - auto len = static_cast(sqlite3_column_bytes(stmt, columnIndex)); - return {bytes, bytes + len}; - } - - std::vector extract(sqlite3_value* value) const { - auto bytes = static_cast(sqlite3_value_blob(value)); - auto len = static_cast(sqlite3_value_bytes(value)); - return {bytes, bytes + len}; - } - }; - - /** - * Specialization for locking_mode. - */ - template<> - struct row_extractor { - locking_mode extract(const char* columnText) const { - if (columnText) { - auto resultPair = internal::locking_mode_from_string(columnText); - if (resultPair.first) { - return resultPair.second; - } else { - throw std::system_error{orm_error_code::incorrect_locking_mode_string}; - } - } else { - throw std::system_error{orm_error_code::incorrect_locking_mode_string}; - } - } - - locking_mode extract(sqlite3_stmt* stmt, int columnIndex) const { - auto cStr = (const char*)sqlite3_column_text(stmt, columnIndex); - return this->extract(cStr); - } - - locking_mode extract(sqlite3_value* value) const = delete; - }; - - /** - * Specialization for journal_mode. - */ - template<> - struct row_extractor { - journal_mode extract(const char* columnText) const { - if (columnText) { - auto resultPair = internal::journal_mode_from_string(columnText); - if (resultPair.first) { - return resultPair.second; - } else { - throw std::system_error{orm_error_code::incorrect_journal_mode_string}; - } - } else { - throw std::system_error{orm_error_code::incorrect_journal_mode_string}; - } - } - - journal_mode extract(sqlite3_stmt* stmt, int columnIndex) const { - auto cStr = (const char*)sqlite3_column_text(stmt, columnIndex); - return this->extract(cStr); - } - - journal_mode extract(sqlite3_value* value) const = delete; - }; - - namespace internal { - - /* - * Helper to extract a structure from a rowset. - */ - template - struct struct_extractor; - -#ifdef SQLITE_ORM_IF_CONSTEXPR_SUPPORTED - /* - * Returns a value-based row extractor for an unmapped type, - * returns a structure extractor for a table reference, tuple or named struct. - */ - template - auto make_row_extractor([[maybe_unused]] const DBOs& dbObjects) { - if constexpr (polyfill::is_specialization_of_v || - polyfill::is_specialization_of_v || is_table_reference_v) { - return struct_extractor{dbObjects}; - } else { - return row_value_extractor(); - } - } -#else - /* - * Overload for an unmapped type returns a common row extractor. - */ - template< - class R, - class DBOs, - std::enable_if_t, - polyfill::is_specialization_of, - is_table_reference>>::value, - bool> = true> - auto make_row_extractor(const DBOs& /*dbObjects*/) { - return row_value_extractor(); - } - - /* - * Overload for a table reference, tuple or aggregate of column results returns a structure extractor. - */ - template, - polyfill::is_specialization_of, - is_table_reference>::value, - bool> = true> - struct_extractor make_row_extractor(const DBOs& dbObjects) { - return {dbObjects}; - } -#endif - - /** - * Specialization for a tuple of top-level column results. - */ - template - struct struct_extractor, DBOs> { - const DBOs& db_objects; - - std::tuple extract(const char* columnText) const = delete; - - // note: expects to be called only from the top level, and therefore discards the index - std::tuple...> extract(sqlite3_stmt* stmt, - int&& /*nextColumnIndex*/ = 0) const { - int columnIndex = -1; - return {make_row_extractor(this->db_objects).extract(stmt, ++columnIndex)...}; - } - - // unused to date - std::tuple...> extract(sqlite3_stmt* stmt, int& columnIndex) const = delete; - - std::tuple extract(sqlite3_value* value) const = delete; - }; - - /** - * Specialization for an unmapped structure to be constructed ad-hoc from column results. - * - * This plays together with `column_result_of_t`, which returns `struct_t` as `structure` - */ - template - struct struct_extractor>, DBOs> { - const DBOs& db_objects; - - O extract(const char* columnText) const = delete; - - // note: expects to be called only from the top level, and therefore discards the index; - // note: brace-init-list initialization guarantees order of evaluation, but only for aggregates and variadic constructors it seems. - // see unit test tests/prepared_statement_tests/select.cpp/TEST_CASE("Prepared select")/SECTION("non-aggregate struct") - template = true> - O extract(sqlite3_stmt* stmt, int&& /*nextColumnIndex*/ = 0) const { - int columnIndex = -1; - return O{make_row_extractor(this->db_objects).extract(stmt, ++columnIndex)...}; - } - - template = true> - O extract(sqlite3_stmt* stmt, int&& /*nextColumnIndex*/ = 0) const { - int columnIndex = -1; - // note: brace-init-list initialization guarantees order of evaluation, but only for aggregates and variadic constructors it seems. - std::tuple t{make_row_extractor(this->db_objects).extract(stmt, ++columnIndex)...}; - return create_from_tuple(std::move(t), std::index_sequence_for{}); - } - - // note: brace-init-list initialization guarantees order of evaluation, but only for aggregates and variadic constructors it seems. - // see unit test tests/prepared_statement_tests/select.cpp/TEST_CASE("Prepared select")/SECTION("non-aggregate struct") - template = true> - O extract(sqlite3_stmt* stmt, int& columnIndex) const { - --columnIndex; - return O{make_row_extractor(this->db_objects).extract(stmt, ++columnIndex)...}; - } - - template = true> - O extract(sqlite3_stmt* stmt, int& columnIndex) const { - --columnIndex; - // note: brace-init-list initialization guarantees order of evaluation, but only for aggregates and variadic constructors it seems. - std::tuple t{make_row_extractor(this->db_objects).extract(stmt, ++columnIndex)...}; - return create_from_tuple(std::move(t), std::index_sequence_for{}); - } - - O extract(sqlite3_value* value) const = delete; - }; - } -} - -// #include "mapped_iterator.h" - -#include -#include // std::shared_ptr, std::make_shared -#include // std::move -#include // std::input_iterator_tag -#include // std::system_error -#include // std::bind - -// #include "statement_finalizer.h" - -#include -#include // std::unique_ptr -#include // std::integral_constant - -namespace sqlite_orm { - - /** - * Guard class which finalizes `sqlite3_stmt` in dtor - */ - using statement_finalizer = - std::unique_ptr>; -} - -// #include "error_code.h" - -// #include "object_from_column_builder.h" - -#include -#include // std::is_member_object_pointer -#include // std::move - -// #include "functional/static_magic.h" - -// #include "member_traits/member_traits.h" - -// #include "table_reference.h" - -// #include "row_extractor.h" - -// #include "schema/column.h" - -// #include "storage_lookup.h" - -namespace sqlite_orm { - - namespace internal { - - struct object_from_column_builder_base { - sqlite3_stmt* stmt = nullptr; - int columnIndex = -1; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - object_from_column_builder_base(sqlite3_stmt* stmt, int columnIndex = -1) : - stmt{stmt}, columnIndex{columnIndex} {} -#endif - }; - - /** - * Function object for building an object from a result row. - */ - template - struct object_from_column_builder : object_from_column_builder_base { - using object_type = O; - - object_type& object; - - object_from_column_builder(object_type& object_, sqlite3_stmt* stmt_, int nextColumnIndex = 0) : - object_from_column_builder_base{stmt_, nextColumnIndex - 1}, object(object_) {} - - template - void operator()(const column_field& column) { - const auto rowExtractor = row_value_extractor>(); - auto value = rowExtractor.extract(this->stmt, ++this->columnIndex); - static_if::value>( - [&value, &object = this->object](const auto& column) { - object.*column.member_pointer = std::move(value); - }, - [&value, &object = this->object](const auto& column) { - (object.*column.setter)(std::move(value)); - })(column); - } - }; - - /** - * Specialization for a table reference. - * - * This plays together with `column_result_of_t`, which returns `object_t` as `table_referenece` - */ - template - struct struct_extractor, DBOs> { - const DBOs& db_objects; - - O extract(const char* columnText) const = delete; - - // note: expects to be called only from the top level, and therefore discards the index - O extract(sqlite3_stmt* stmt, int&& /*nextColumnIndex*/ = 0) const { - int columnIndex = 0; - return this->extract(stmt, columnIndex); - } - - O extract(sqlite3_stmt* stmt, int& columnIndex) const { - O obj; - object_from_column_builder builder{obj, stmt, columnIndex}; - auto& table = pick_table(this->db_objects); - table.for_each_column(builder); - columnIndex = builder.columnIndex; - return obj; - } - - O extract(sqlite3_value* value) const = delete; - }; - } -} - -// #include "storage_lookup.h" - -// #include "util.h" - -#include -#include // std::string -#include // std::move - -// #include "error_code.h" - -namespace sqlite_orm { - - /** - * Escape the provided character in the given string by doubling it. - * @param str A copy of the original string - * @param char2Escape The character to escape - */ - inline std::string sql_escape(std::string str, char char2Escape) { - for (size_t pos = 0; (pos = str.find(char2Escape, pos)) != str.npos; pos += 2) { - str.replace(pos, 1, 2, char2Escape); - } - - return str; - } - - /** - * Quote the given string value using single quotes, - * escape containing single quotes by doubling them. - */ - inline std::string quote_string_literal(std::string v) { - constexpr char quoteChar = '\''; - return quoteChar + sql_escape(std::move(v), quoteChar) + quoteChar; - } - - /** - * Quote the given string value using single quotes, - * escape containing single quotes by doubling them. - */ - inline std::string quote_blob_literal(std::string v) { - constexpr char quoteChar = '\''; - return std::string{char('x'), quoteChar} + std::move(v) + quoteChar; - } - - /** - * Quote the given identifier using double quotes, - * escape containing double quotes by doubling them. - */ - inline std::string quote_identifier(std::string identifier) { - constexpr char quoteChar = '"'; - return quoteChar + sql_escape(std::move(identifier), quoteChar) + quoteChar; - } - - namespace internal { - // Wrapper to reduce boiler-plate code - inline sqlite3_stmt* reset_stmt(sqlite3_stmt* stmt) { - sqlite3_reset(stmt); - return stmt; - } - - // note: query is deliberately taken by value, such that it is thrown away early - inline sqlite3_stmt* prepare_stmt(sqlite3* db, std::string query) { - sqlite3_stmt* stmt; - if (sqlite3_prepare_v2(db, query.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { - throw_translated_sqlite_error(db); - } - return stmt; - } - - inline void perform_void_exec(sqlite3* db, const std::string& query) { - int rc = sqlite3_exec(db, query.c_str(), nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) { - throw_translated_sqlite_error(db); - } - } - - inline void perform_exec(sqlite3* db, - const char* query, - int (*callback)(void* data, int argc, char** argv, char**), - void* user_data) { - int rc = sqlite3_exec(db, query, callback, user_data, nullptr); - if (rc != SQLITE_OK) { - throw_translated_sqlite_error(db); - } - } - - inline void perform_exec(sqlite3* db, - const std::string& query, - int (*callback)(void* data, int argc, char** argv, char**), - void* user_data) { - return perform_exec(db, query.c_str(), callback, user_data); - } - - template - void perform_step(sqlite3_stmt* stmt) { - int rc = sqlite3_step(stmt); - if (rc != expected) { - throw_translated_sqlite_error(stmt); - } - } - - template - void perform_step(sqlite3_stmt* stmt, L&& lambda) { - switch (int rc = sqlite3_step(stmt)) { - case SQLITE_ROW: { - lambda(stmt); - } break; - case SQLITE_DONE: - break; - default: { - throw_translated_sqlite_error(stmt); - } - } - } - - template - void perform_steps(sqlite3_stmt* stmt, L&& lambda) { - int rc; - do { - switch (rc = sqlite3_step(stmt)) { - case SQLITE_ROW: { - lambda(stmt); - } break; - case SQLITE_DONE: - break; - default: { - throw_translated_sqlite_error(stmt); - } - } - } while (rc != SQLITE_DONE); - } - } -} - -namespace sqlite_orm { - namespace internal { - - /* - * (Legacy) Input iterator over a result set for a mapped object. - */ - template - class mapped_iterator { - public: - using db_objects_type = DBOs; - - using iterator_category = std::input_iterator_tag; - using difference_type = ptrdiff_t; - using value_type = O; - using reference = O&; - using pointer = O*; - - private: - /** - pointer to the db objects. - only null for the default constructed iterator. - */ - const db_objects_type* db_objects = nullptr; - - /** - * shared_ptr is used over unique_ptr here - * so that the iterator can be copyable. - */ - std::shared_ptr stmt; - - /** - * shared_ptr is used over unique_ptr here - * so that the iterator can be copyable. - */ - std::shared_ptr current; - - void extract_object() { - this->current = std::make_shared(); - object_from_column_builder builder{*this->current, this->stmt.get()}; - auto& table = pick_table(*this->db_objects); - table.for_each_column(builder); - } - - void step() { - perform_step(this->stmt.get(), std::bind(&mapped_iterator::extract_object, this)); - if (!this->current) { - this->stmt.reset(); - } - } - - void next() { - this->current.reset(); - this->step(); - } - - public: - mapped_iterator() = default; - - mapped_iterator(const db_objects_type& dbObjects, statement_finalizer stmt) : - db_objects{&dbObjects}, stmt{std::move(stmt)} { - this->step(); - } - - mapped_iterator(const mapped_iterator&) = default; - mapped_iterator& operator=(const mapped_iterator&) = default; - mapped_iterator(mapped_iterator&&) = default; - mapped_iterator& operator=(mapped_iterator&&) = default; - - value_type& operator*() const { - if (!this->stmt) SQLITE_ORM_CPP_UNLIKELY { - throw std::system_error{orm_error_code::trying_to_dereference_null_iterator}; - } - return *this->current; - } - - // note: should actually be only present for contiguous iterators - value_type* operator->() const { - return &(this->operator*()); - } - - mapped_iterator& operator++() { - next(); - return *this; - } - - mapped_iterator operator++(int) { - auto tmp = *this; - ++*this; - return tmp; - } - - friend bool operator==(const mapped_iterator& lhs, const mapped_iterator& rhs) { - return lhs.current == rhs.current; - } - -#ifndef SQLITE_ORM_DEFAULT_COMPARISONS_SUPPORTED - friend bool operator!=(const mapped_iterator& lhs, const mapped_iterator& rhs) { - return !(lhs == rhs); - } -#endif - }; - } -} - -// #include "ast_iterator.h" - -#include // std::vector -#include // std::reference_wrapper - -// #include "tuple_helper/tuple_iteration.h" - -// #include "type_traits.h" - -// #include "conditions.h" - -// #include "alias.h" - -// #include "select_constraints.h" - -// #include "operators.h" - -// #include "core_functions.h" - -// #include "prepared_statement.h" - -#include -#include // std::unique_ptr -#include // std::iterator_traits -#include // std::string -#include // std::integral_constant, std::declval -#include // std::move, std::forward, std::pair -#include // std::tuple - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "functional/cxx_functional_polyfill.h" - -// #include "tuple_helper/tuple_traits.h" - -// #include "connection_holder.h" - -#include -#include -#include // std::string - -// #include "error_code.h" - -namespace sqlite_orm { - - namespace internal { - - struct connection_holder { - - connection_holder(std::string filename_) : filename(std::move(filename_)) {} - - void retain() { - if (1 == ++this->_retain_count) { - auto rc = sqlite3_open(this->filename.c_str(), &this->db); - if (rc != SQLITE_OK) { - throw_translated_sqlite_error(db); - } - } - } - - void release() { - if (0 == --this->_retain_count) { - auto rc = sqlite3_close(this->db); - if (rc != SQLITE_OK) { - throw_translated_sqlite_error(db); - } - } - } - - sqlite3* get() const { - return this->db; - } - - int retain_count() const { - return this->_retain_count; - } - - const std::string filename; - - protected: - sqlite3* db = nullptr; - std::atomic_int _retain_count{}; - }; - - struct connection_ref { - connection_ref(connection_holder& holder) : holder(&holder) { - this->holder->retain(); - } - - connection_ref(const connection_ref& other) : holder(other.holder) { - this->holder->retain(); - } - - // rebind connection reference - connection_ref& operator=(const connection_ref& other) { - if (other.holder != this->holder) { - this->holder->release(); - this->holder = other.holder; - this->holder->retain(); - } - - return *this; - } - - ~connection_ref() { - this->holder->release(); - } - - sqlite3* get() const { - return this->holder->get(); - } - - private: - connection_holder* holder = nullptr; - }; - } -} - -// #include "select_constraints.h" - -// #include "values.h" - -#include // std::vector -#include // std::tuple -#include // std::forward, std::move - -// #include "functional/cxx_type_traits_polyfill.h" - -namespace sqlite_orm { - - namespace internal { - - template - struct values_t { - using args_tuple = std::tuple; - - args_tuple tuple; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_values_v = polyfill::is_specialization_of::value; - - template - using is_values = polyfill::bool_constant>; - - template - struct dynamic_values_t { - std::vector vector; - }; - - } - - template - internal::values_t values(Args... args) { - return {{std::forward(args)...}}; - } - - template - internal::dynamic_values_t values(std::vector vector) { - return {{std::move(vector)}}; - } -} - -// #include "table_reference.h" - -// #include "mapped_type_proxy.h" - -// #include "ast/upsert_clause.h" - -#if SQLITE_VERSION_NUMBER >= 3024000 -#include // std::tuple -#include // std::forward, std::move -#endif - -// #include "../functional/cxx_type_traits_polyfill.h" - -namespace sqlite_orm { - namespace internal { -#if SQLITE_VERSION_NUMBER >= 3024000 - template - struct upsert_clause; - - template - struct conflict_target { - using args_tuple = std::tuple; - - args_tuple args; - - upsert_clause> do_nothing() { - return {std::move(this->args), {}}; - } - - template - upsert_clause> do_update(ActionsArgs... actions) { - return {std::move(this->args), {std::forward(actions)...}}; - } - }; - - template - struct upsert_clause, std::tuple> { - using target_args_tuple = std::tuple; - using actions_tuple = std::tuple; - - target_args_tuple target_args; - - actions_tuple actions; - }; -#endif - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_upsert_clause_v = -#if SQLITE_VERSION_NUMBER >= 3024000 - polyfill::is_specialization_of::value; -#else - false; -#endif - - template - using is_upsert_clause = polyfill::bool_constant>; - } - -#if SQLITE_VERSION_NUMBER >= 3024000 - /** - * ON CONFLICT upsert clause builder function. - * @example - * storage.insert(into(), - * columns(&Employee::id, &Employee::name, &Employee::age, &Employee::address, &Employee::salary), - * values(std::make_tuple(3, "Sofia", 26, "Madrid", 15000.0), - * std::make_tuple(4, "Doja", 26, "LA", 25000.0)), - * on_conflict(&Employee::id).do_update(set(c(&Employee::name) = excluded(&Employee::name), - * c(&Employee::age) = excluded(&Employee::age), - * c(&Employee::address) = excluded(&Employee::address), - * c(&Employee::salary) = excluded(&Employee::salary)))); - */ - template - internal::conflict_target on_conflict(Args... args) { - return {{std::forward(args)...}}; - } -#endif -} - -// #include "ast/set.h" - -#include // std::tuple, std::tuple_size -#include // std::string -#include // std::vector -#include // std::stringstream -#include // std::false_type, std::true_type - -// #include "../tuple_helper/tuple_traits.h" - -// #include "../table_name_collector.h" - -#include // std::set -#include // std::string -#include // std::pair, std::move - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "type_traits.h" - -// #include "mapped_type_proxy.h" - -// #include "select_constraints.h" - -// #include "alias.h" - -// #include "core_functions.h" - -// #include "storage_lookup.h" - -namespace sqlite_orm { - - namespace internal { - - struct table_name_collector_base { - using table_name_set = std::set>; - - table_name_set table_names; - }; - - template - struct table_name_collector : table_name_collector_base { - using db_objects_type = DBOs; - - const db_objects_type& db_objects; - - table_name_collector() = default; - - table_name_collector(const db_objects_type& dbObjects) : db_objects{dbObjects} {} - - template - void operator()(const T&) const {} - - template - void operator()(F O::*) { - this->table_names.emplace(lookup_table_name(this->db_objects), ""); - } - - template - void operator()(const column_pointer&) { - auto tableName = lookup_table_name>(this->db_objects); - this->table_names.emplace(std::move(tableName), alias_extractor::as_alias()); - } - - template - void operator()(const alias_column_t&) { - // note: instead of accessing the column, we are interested in the type the column is aliased into - auto tableName = lookup_table_name>(this->db_objects); - this->table_names.emplace(std::move(tableName), alias_extractor::as_alias()); - } - - template - void operator()(const count_asterisk_t&) { - auto tableName = lookup_table_name(this->db_objects); - if (!tableName.empty()) { - this->table_names.emplace(std::move(tableName), ""); - } - } - - template - void operator()(const asterisk_t&) { - auto tableName = lookup_table_name>(this->db_objects); - table_names.emplace(std::move(tableName), alias_extractor::as_alias()); - } - - template - void operator()(const object_t&) { - this->table_names.emplace(lookup_table_name(this->db_objects), ""); - } - - template - void operator()(const table_rowid_t&) { - this->table_names.emplace(lookup_table_name(this->db_objects), ""); - } - - template - void operator()(const table_oid_t&) { - this->table_names.emplace(lookup_table_name(this->db_objects), ""); - } - - template - void operator()(const table__rowid_t&) { - this->table_names.emplace(lookup_table_name(this->db_objects), ""); - } - - template - void operator()(const highlight_t&) { - this->table_names.emplace(lookup_table_name(this->db_objects), ""); - } - }; - - template = true> - table_name_collector make_table_name_collector(const DBOs& dbObjects) { - return {dbObjects}; - } - - } - -} - -namespace sqlite_orm { - - namespace internal { - - template - void iterate_ast(const T& t, L&& lambda); - - template - struct set_t { - using assigns_type = std::tuple; - - assigns_type assigns; - }; - - template - struct is_set : std::false_type {}; - - template - struct is_set> : std::true_type {}; - - struct dynamic_set_entry { - std::string serialized_value; - }; - - template - struct dynamic_set_t { - using context_t = C; - using entry_t = dynamic_set_entry; - using const_iterator = typename std::vector::const_iterator; - - dynamic_set_t(const context_t& context_) : context(context_), collector(this->context.db_objects) {} - - dynamic_set_t(const dynamic_set_t& other) = default; - dynamic_set_t(dynamic_set_t&& other) = default; - dynamic_set_t& operator=(const dynamic_set_t& other) = default; - dynamic_set_t& operator=(dynamic_set_t&& other) = default; - - template - void push_back(assign_t assign) { - auto newContext = this->context; - newContext.skip_table_name = true; - // note: we are only interested in the table name on the left-hand side of the assignment operator expression - iterate_ast(assign.lhs, this->collector); - std::stringstream ss; - ss << serialize(assign.lhs, newContext) << ' ' << assign.serialize() << ' ' - << serialize(assign.rhs, context); - this->entries.push_back({ss.str()}); - } - - const_iterator begin() const { - return this->entries.begin(); - } - - const_iterator end() const { - return this->entries.end(); - } - - void clear() { - this->entries.clear(); - this->collector.table_names.clear(); - } - - std::vector entries; - context_t context; - table_name_collector collector; - }; - - template - struct is_set> : std::true_type {}; - - template - struct is_dynamic_set : std::false_type {}; - - template - struct is_dynamic_set> : std::true_type {}; - } - - /** - * SET keyword used in UPDATE ... SET queries. - * Args must have `assign_t` type. E.g. set(assign(&User::id, 5)) or set(c(&User::id) = 5) - */ - template - internal::set_t set(Args... args) { - using arg_tuple = std::tuple; - static_assert(std::tuple_size::value == - internal::count_tuple::value, - "set function accepts assign operators only"); - return {std::make_tuple(std::forward(args)...)}; - } - - /** - * SET keyword used in UPDATE ... SET queries. It is dynamic version. It means use can add amount of arguments now known at compilation time but known at runtime. - */ - template - internal::dynamic_set_t> dynamic_set(const S& storage) { - internal::serializer_context_builder builder(storage); - return builder(); - } -} - -namespace sqlite_orm { - - namespace internal { - - struct prepared_statement_base { - sqlite3_stmt* stmt = nullptr; - connection_ref con; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - prepared_statement_base(sqlite3_stmt* stmt, connection_ref con) : stmt{stmt}, con{std::move(con)} {} -#endif - - ~prepared_statement_base() { - sqlite3_finalize(this->stmt); - } - - std::string sql() const { - // note: sqlite3 internally checks for null before calling - // sqlite3_normalized_sql() or sqlite3_expanded_sql(), so check here, too, even if superfluous - if (const char* sql = sqlite3_sql(this->stmt)) { - return sql; - } else { - return {}; - } - } - -#if SQLITE_VERSION_NUMBER >= 3014000 - std::string expanded_sql() const { - // note: must check return value due to SQLITE_OMIT_TRACE - using char_ptr = std::unique_ptr>; - if (char_ptr sql{sqlite3_expanded_sql(this->stmt)}) { - return sql.get(); - } else { - return {}; - } - } -#endif -#if SQLITE_VERSION_NUMBER >= 3026000 and defined(SQLITE_ENABLE_NORMALIZE) - std::string normalized_sql() const { - if (const char* sql = sqlite3_normalized_sql(this->stmt)) { - return sql; - } else { - return {}; - } - } -#endif - -#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED - std::string_view column_name(int index) const { - return sqlite3_column_name(stmt, index); - } -#endif - }; - - template - struct prepared_statement_t : prepared_statement_base { - using expression_type = T; - - expression_type expression; - - prepared_statement_t(T expression_, sqlite3_stmt* stmt_, connection_ref con_) : - prepared_statement_base{stmt_, std::move(con_)}, expression(std::move(expression_)) {} - - prepared_statement_t(prepared_statement_t&& prepared_stmt) : - prepared_statement_base{prepared_stmt.stmt, std::move(prepared_stmt.con)}, - expression(std::move(prepared_stmt.expression)) { - prepared_stmt.stmt = nullptr; - } - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_prepared_statement_v = - polyfill::is_specialization_of::value; - - template - struct is_prepared_statement : polyfill::bool_constant> {}; - - /** - * T - type of object to obtain from a database - */ - template - struct get_all_t { - using type = T; - using return_type = R; - - using conditions_type = std::tuple; - - conditions_type conditions; - }; - - template - struct get_all_pointer_t { - using type = T; - using return_type = R; - - using conditions_type = std::tuple; - - conditions_type conditions; - }; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct get_all_optional_t { - using type = T; - using return_type = R; - - using conditions_type = std::tuple; - - conditions_type conditions; - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template - struct update_all_t { - using set_type = S; - using conditions_type = std::tuple; - - static_assert(is_set::value, "update_all_t must have set or dynamic set as the first argument"); - - set_type set; - conditions_type conditions; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_update_all_v = polyfill::is_specialization_of::value; - - template - using is_update_all = polyfill::bool_constant>; - - template - struct remove_all_t { - using type = T; - using conditions_type = std::tuple; - - conditions_type conditions; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_remove_all_v = polyfill::is_specialization_of::value; - - template - using is_remove_all = polyfill::bool_constant>; - - template - struct get_t { - using type = T; - using ids_type = std::tuple; - - ids_type ids; - }; - - template - struct get_pointer_t { - using type = T; - using ids_type = std::tuple; - - ids_type ids; - }; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct get_optional_t { - using type = T; - using ids_type = std::tuple; - - ids_type ids; - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template - struct update_t { - using type = T; - - type object; - }; - - template - struct remove_t { - using type = T; - using ids_type = std::tuple; - - ids_type ids; - }; - - template - struct insert_t { - using type = T; - - type object; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_insert_v = polyfill::is_specialization_of::value; - - template - struct is_insert : polyfill::bool_constant> {}; - - template - struct insert_explicit { - using type = T; - using columns_type = columns_t; - - type obj; - columns_type columns; - }; - - template - struct replace_t { - using type = T; - - type object; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_replace_v = polyfill::is_specialization_of::value; - - template - struct is_replace : polyfill::bool_constant> {}; - - template - struct insert_range_t { - using iterator_type = It; - using transformer_type = Projection; - using object_type = O; - - std::pair range; - transformer_type transformer; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_insert_range_v = - polyfill::is_specialization_of::value; - - template - struct is_insert_range : polyfill::bool_constant> {}; - - template - struct replace_range_t { - using iterator_type = It; - using transformer_type = Projection; - using object_type = O; - - std::pair range; - transformer_type transformer; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_replace_range_v = - polyfill::is_specialization_of::value; - - template - struct is_replace_range : polyfill::bool_constant> {}; - - template - struct insert_raw_t { - using args_tuple = std::tuple; - - args_tuple args; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_insert_raw_v = polyfill::is_specialization_of::value; - - template - struct is_insert_raw : polyfill::bool_constant> {}; - - template - struct replace_raw_t { - using args_tuple = std::tuple; - - args_tuple args; - }; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_replace_raw_v = polyfill::is_specialization_of::value; - - template - struct is_replace_raw : polyfill::bool_constant> {}; - - struct default_values_t {}; - - template - using is_default_values = std::is_same; - - enum class conflict_action { - abort, - fail, - ignore, - replace, - rollback, - }; - - struct insert_constraint { - conflict_action action = conflict_action::abort; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - insert_constraint(conflict_action action) : action{action} {} -#endif - }; - - template - using is_insert_constraint = std::is_same; - } - - inline internal::insert_constraint or_rollback() { - return {internal::conflict_action::rollback}; - } - - inline internal::insert_constraint or_replace() { - return {internal::conflict_action::replace}; - } - - inline internal::insert_constraint or_ignore() { - return {internal::conflict_action::ignore}; - } - - inline internal::insert_constraint or_fail() { - return {internal::conflict_action::fail}; - } - - inline internal::insert_constraint or_abort() { - return {internal::conflict_action::abort}; - } - - /** - * Use this function to add `DEFAULT VALUES` modifier to raw `INSERT`. - * - * @example - * ``` - * storage.insert(into(), default_values()); - * ``` - */ - inline internal::default_values_t default_values() { - return {}; - } - - /** - * Raw insert statement creation routine. Use this if `insert` with object does not fit you. This insert is designed to be able - * to call any type of `INSERT` query with no limitations. - * @example - * ```sql - * INSERT INTO users (id, name) VALUES(5, 'Little Mix') - * ``` - * will be - * ```c++ - * auto statement = storage.prepare(insert(into, columns(&User::id, &User::name), values(std::make_tuple(5, "Little Mix")))); - * storage.execute(statement)); - * ``` - * One more example: - * ```sql - * INSERT INTO singers (name) VALUES ('Sofia Reyes')('Kungs') - * ``` - * will be - * ```c++ - * auto statement = storage.prepare(insert(into(), columns(&Singer::name), values(std::make_tuple("Sofia Reyes"), std::make_tuple("Kungs")))); - * storage.execute(statement)); - * ``` - * One can use `default_values` to add `DEFAULT VALUES` modifier: - * ```sql - * INSERT INTO users DEFAULT VALUES - * ``` - * will be - * ```c++ - * auto statement = storage.prepare(insert(into(), default_values())); - * storage.execute(statement)); - * ``` - * Also one can use `INSERT OR ABORT`/`INSERT OR FAIL`/`INSERT OR IGNORE`/`INSERT OR REPLACE`/`INSERT ROLLBACK`: - * ```c++ - * auto statement = storage.prepare(insert(or_ignore(), into(), columns(&Singer::name), values(std::make_tuple("Sofia Reyes"), std::make_tuple("Kungs")))); - * auto statement2 = storage.prepare(insert(or_rollback(), into(), default_values())); - * auto statement3 = storage.prepare(insert(or_abort(), into, columns(&User::id, &User::name), values(std::make_tuple(5, "Little Mix")))); - * ``` - */ - template - internal::insert_raw_t insert(Args... args) { - using args_tuple = std::tuple; - using internal::count_tuple; - using internal::is_columns; - using internal::is_insert_constraint; - using internal::is_into; - using internal::is_select; - using internal::is_upsert_clause; - using internal::is_values; - - constexpr int orArgsCount = count_tuple::value; - static_assert(orArgsCount < 2, "Raw insert must have only one OR... argument"); - - constexpr int intoArgsCount = count_tuple::value; - static_assert(intoArgsCount != 0, "Raw insert must have into argument"); - static_assert(intoArgsCount < 2, "Raw insert must have only one into argument"); - - constexpr int columnsArgsCount = count_tuple::value; - static_assert(columnsArgsCount < 2, "Raw insert must have only one columns(...) argument"); - - constexpr int valuesArgsCount = count_tuple::value; - static_assert(valuesArgsCount < 2, "Raw insert must have only one values(...) argument"); - - constexpr int defaultValuesCount = count_tuple::value; - static_assert(defaultValuesCount < 2, "Raw insert must have only one default_values() argument"); - - constexpr int selectsArgsCount = count_tuple::value; - static_assert(selectsArgsCount < 2, "Raw insert must have only one select(...) argument"); - - constexpr int upsertClausesCount = count_tuple::value; - static_assert(upsertClausesCount <= 2, "Raw insert can contain 2 instances of upsert clause maximum"); - - constexpr int argsCount = int(std::tuple_size::value); - static_assert(argsCount == intoArgsCount + columnsArgsCount + valuesArgsCount + defaultValuesCount + - selectsArgsCount + orArgsCount + upsertClausesCount, - "Raw insert has invalid arguments"); - - return {{std::forward(args)...}}; - } - - /** - * Raw replace statement creation routine. Use this if `replace` with object does not fit you. This replace is designed to be able - * to call any type of `REPLACE` query with no limitations. Actually this is the same query as raw insert except `OR...` option existance. - * @example - * ```sql - * REPLACE INTO users (id, name) VALUES(5, 'Little Mix') - * ``` - * will be - * ```c++ - * auto statement = storage.prepare(replace(into, columns(&User::id, &User::name), values(std::make_tuple(5, "Little Mix")))); - * storage.execute(statement)); - * ``` - * One more example: - * ```sql - * REPLACE INTO singers (name) VALUES ('Sofia Reyes')('Kungs') - * ``` - * will be - * ```c++ - * auto statement = storage.prepare(replace(into(), columns(&Singer::name), values(std::make_tuple("Sofia Reyes"), std::make_tuple("Kungs")))); - * storage.execute(statement)); - * ``` - * One can use `default_values` to add `DEFAULT VALUES` modifier: - * ```sql - * REPLACE INTO users DEFAULT VALUES - * ``` - * will be - * ```c++ - * auto statement = storage.prepare(replace(into(), default_values())); - * storage.execute(statement)); - * ``` - */ - template - internal::replace_raw_t replace(Args... args) { - using args_tuple = std::tuple; - using internal::count_tuple; - using internal::is_columns; - using internal::is_into; - using internal::is_values; - - constexpr int intoArgsCount = count_tuple::value; - static_assert(intoArgsCount != 0, "Raw replace must have into argument"); - static_assert(intoArgsCount < 2, "Raw replace must have only one into argument"); - - constexpr int columnsArgsCount = count_tuple::value; - static_assert(columnsArgsCount < 2, "Raw replace must have only one columns(...) argument"); - - constexpr int valuesArgsCount = count_tuple::value; - static_assert(valuesArgsCount < 2, "Raw replace must have only one values(...) argument"); - - constexpr int defaultValuesCount = count_tuple::value; - static_assert(defaultValuesCount < 2, "Raw replace must have only one default_values() argument"); - - constexpr int selectsArgsCount = count_tuple::value; - static_assert(selectsArgsCount < 2, "Raw replace must have only one select(...) argument"); - - constexpr int argsCount = int(std::tuple_size::value); - static_assert(argsCount == - intoArgsCount + columnsArgsCount + valuesArgsCount + defaultValuesCount + selectsArgsCount, - "Raw replace has invalid arguments"); - - return {{std::forward(args)...}}; - } - - /** - * Create a replace range statement. - * The objects in the range are transformed using the specified projection, which defaults to identity projection. - * - * @example - * ``` - * std::vector users; - * users.push_back(User{1, "Leony"}); - * auto statement = storage.prepare(replace_range(users.begin(), users.end())); - * storage.execute(statement); - * ``` - * @example - * ``` - * std::vector> userPointers; - * userPointers.push_back(std::make_unique(1, "Eneli")); - * auto statement = storage.prepare(replace_range(userPointers.begin(), userPointers.end(), &std::unique_ptr::operator*)); - * storage.execute(statement); - * ``` - */ - template - auto replace_range(It from, It to, Projection project = {}) { - using O = std::decay_t(), *std::declval()))>; - return internal::replace_range_t{{std::move(from), std::move(to)}, std::move(project)}; - } - - /* - * Create a replace range statement. - * Overload of `replace_range(It, It, Projection)` with explicit object type template parameter. - */ - template - internal::replace_range_t replace_range(It from, It to, Projection project = {}) { - return {{std::move(from), std::move(to)}, std::move(project)}; - } - - /** - * Create an insert range statement. - * The objects in the range are transformed using the specified projection, which defaults to identity projection. - * - * @example - * ``` - * std::vector users; - * users.push_back(User{1, "Leony"}); - * auto statement = storage.prepare(insert_range(users.begin(), users.end())); - * storage.execute(statement); - * ``` - * @example - * ``` - * std::vector> userPointers; - * userPointers.push_back(std::make_unique(1, "Eneli")); - * auto statement = storage.prepare(insert_range(userPointers.begin(), userPointers.end(), &std::unique_ptr::operator*)); - * storage.execute(statement); - * ``` - */ - template - auto insert_range(It from, It to, Projection project = {}) { - using O = std::decay_t(), *std::declval()))>; - return internal::insert_range_t{{std::move(from), std::move(to)}, std::move(project)}; - } - - /* - * Create an insert range statement. - * Overload of `insert_range(It, It, Projection)` with explicit object type template parameter. - */ - template - internal::insert_range_t insert_range(It from, It to, Projection project = {}) { - return {{std::move(from), std::move(to)}, std::move(project)}; - } - - /** - * Create a replace statement. - * T is an object type mapped to a storage. - * Usage: storage.replace(myUserInstance); - * Parameter obj is accepted by value. If you want to accept it by ref - * please use std::ref function: storage.replace(std::ref(myUserInstance)); - */ - template - internal::replace_t replace(T obj) { - return {std::move(obj)}; - } - - /** - * Create an insert statement. - * T is an object type mapped to a storage. - * Usage: storage.insert(myUserInstance); - * Parameter obj is accepted by value. If you want to accept it by ref - * please use std::ref function: storage.insert(std::ref(myUserInstance)); - */ - template - internal::insert_t insert(T obj) { - return {std::move(obj)}; - } - - /** - * Create an explicit insert statement. - * T is an object type mapped to a storage. - * Cols is columns types aparameter pack. Must contain member pointers - * Usage: storage.insert(myUserInstance, columns(&User::id, &User::name)); - * Parameter obj is accepted by value. If you want to accept it by ref - * please use std::ref function: storage.insert(std::ref(myUserInstance), columns(&User::id, &User::name)); - */ - template - internal::insert_explicit insert(T obj, internal::columns_t cols) { - return {std::move(obj), std::move(cols)}; - } - - /** - * Create a remove statement - * T is an object type mapped to a storage. - * Usage: remove(5); - */ - template - internal::remove_t remove(Ids... ids) { - return {{std::forward(ids)...}}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a remove statement - * `table` is an explicitly specified table reference of a mapped object to be extracted. - * Usage: remove(5); - */ - template - auto remove(Ids... ids) { - return remove>(std::forward(ids)...); - } -#endif - - /** - * Create an update statement. - * T is an object type mapped to a storage. - * Usage: storage.update(myUserInstance); - * Parameter obj is accepted by value. If you want to accept it by ref - * please use std::ref function: storage.update(std::ref(myUserInstance)); - */ - template - internal::update_t update(T obj) { - return {std::move(obj)}; - } - - /** - * Create a get statement. - * T is an object type mapped to a storage. - * Usage: get(5); - */ - template - internal::get_t get(Ids... ids) { - return {{std::forward(ids)...}}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a get statement. - * `table` is an explicitly specified table reference of a mapped object to be extracted. - * Usage: get(5); - */ - template - auto get(Ids... ids) { - return get>(std::forward(ids)...); - } -#endif - - /** - * Create a get pointer statement. - * T is an object type mapped to a storage. - * Usage: get_pointer(5); - */ - template - internal::get_pointer_t get_pointer(Ids... ids) { - return {{std::forward(ids)...}}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a get pointer statement. - * `table` is an explicitly specified table reference of a mapped object to be extracted. - * Usage: get_pointer(5); - */ - template - auto get_pointer(Ids... ids) { - return get_pointer>(std::forward(ids)...); - } -#endif - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - /** - * Create a get optional statement. - * T is an object type mapped to a storage. - * Usage: get_optional(5); - */ - template - internal::get_optional_t get_optional(Ids... ids) { - return {{std::forward(ids)...}}; - } -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a get optional statement. - * `table` is an explicitly specified table reference of a mapped object to be extracted. - * Usage: get_optional(5); - */ - template - auto get_optional(Ids... ids) { - return get_optional>(std::forward(ids)...); - } -#endif - - /** - * Create a remove all statement. - * T is an object type mapped to a storage. - * Usage: storage.remove_all(...); - */ - template - internal::remove_all_t remove_all(Args... args) { - using args_tuple = std::tuple; - internal::validate_conditions(); - return {{std::forward(args)...}}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a remove all statement. - * `table` is an explicitly specified table reference of a mapped object to be extracted. - * Usage: storage.remove_all(...); - */ - template - auto remove_all(Args... args) { - return remove_all>(std::forward(args)...); - } -#endif - - /** - * Create a get all statement. - * T is an explicitly specified object mapped to a storage or a table alias. - * R is a container type. std::vector is default - * Usage: storage.prepare(get_all(...)); - */ - template>, class... Args> - internal::get_all_t get_all(Args... conditions) { - using conditions_tuple = std::tuple; - internal::validate_conditions(); - return {{std::forward(conditions)...}}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a get all statement. - * `mapped` is an explicitly specified table reference or table alias to be extracted. - * `R` is the container return type, which must have a `R::push_back(T&&)` method, and defaults to `std::vector` - * Usage: storage.get_all(...); - */ - template>, - class... Args> - auto get_all(Args&&... conditions) { - return get_all, R>(std::forward(conditions)...); - } -#endif - - /** - * Create an update all statement. - * Usage: storage.update_all(set(...), ...); - */ - template - internal::update_all_t update_all(S set, Wargs... wh) { - static_assert(internal::is_set::value, "first argument in update_all can be either set or dynamic_set"); - using args_tuple = std::tuple; - internal::validate_conditions(); - return {std::move(set), {std::forward(wh)...}}; - } - - /** - * Create a get all pointer statement. - * T is an object type mapped to a storage. - * R is a container return type. std::vector> is default - * Usage: storage.prepare(get_all_pointer(...)); - */ - template>, class... Args> - internal::get_all_pointer_t get_all_pointer(Args... conditions) { - using conditions_tuple = std::tuple; - internal::validate_conditions(); - return {{std::forward(conditions)...}}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a get all pointer statement. - * `table` is an explicitly specified table reference of a mapped object to be extracted. - * R is a container return type. std::vector> is default - * Usage: storage.prepare(get_all_pointer(...)); - */ - template>, - class... Args> - auto get_all_pointer(Args... conditions) { - return get_all_pointer, R>(std::forward(conditions)...); - } -#endif - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - /** - * Create a get all optional statement. - * T is an object type mapped to a storage. - * R is a container return type. std::vector> is default - * Usage: storage.get_all_optional(...); - */ - template>, class... Args> - internal::get_all_optional_t get_all_optional(Args... conditions) { - using conditions_tuple = std::tuple; - internal::validate_conditions(); - return {{std::forward(conditions)...}}; - } -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create a get all optional statement. - * `table` is an explicitly specified table reference of a mapped object to be extracted. - * R is a container return type. std::vector> is default - * Usage: storage.get_all_optional(...); - */ - template>, - class... Args> - auto get_all_optional(Args&&... conditions) { - return get_all_optional, R>(std::forward(conditions)...); - } -#endif -} - -// #include "values.h" - -// #include "function.h" - -// #include "ast/excluded.h" - -#include // std::move - -namespace sqlite_orm { - namespace internal { - - template - struct excluded_t { - using expression_type = T; - - expression_type expression; - }; - } - - template - internal::excluded_t excluded(T expression) { - return {std::move(expression)}; - } -} - -// #include "ast/upsert_clause.h" - -// #include "ast/where.h" - -// #include "ast/into.h" - -// #include "ast/group_by.h" - -// #include "ast/exists.h" - -#include // std::move - -// #include "../tags.h" - -namespace sqlite_orm { - namespace internal { - - template - struct exists_t : condition_t, negatable_t { - using expression_type = T; - using self = exists_t; - - expression_type expression; - - exists_t(expression_type expression_) : expression(std::move(expression_)) {} - }; - } - - /** - * EXISTS(condition). - * Example: storage.select(columns(&Agent::code, &Agent::name, &Agent::workingArea, &Agent::comission), - where(exists(select(asterisk(), - where(is_equal(&Customer::grade, 3) and - is_equal(&Agent::code, &Customer::agentCode))))), - order_by(&Agent::comission)); - */ - template - internal::exists_t exists(T expression) { - return {std::move(expression)}; - } -} - -// #include "ast/set.h" - -// #include "ast/match.h" - -#include // std::move - -namespace sqlite_orm { - namespace internal { - - template - struct match_t { - using mapped_type = T; - using argument_type = X; - - argument_type argument; - - match_t(argument_type argument) : argument(std::move(argument)) {} - }; - } - - template - internal::match_t match(X argument) { - return {std::move(argument)}; - } -} - -namespace sqlite_orm { - - namespace internal { - - /** - * ast_iterator accepts any expression and a callable object - * which will be called for any node of provided expression. - * E.g. if we pass `where(is_equal(5, max(&User::id, 10))` then - * callable object will be called with 5, &User::id and 10. - * ast_iterator is used in finding literals to be bound to - * a statement, and to collect table names. - * - * Note that not all leaves of the expression tree are always visited: - * Column expressions can be more complex, but are passed as a whole to the callable. - * Examples are `column_pointer<>` and `alias_column_t<>`. - * - * To use `ast_iterator` call `iterate_ast(object, callable);` - * - * `T` is an ast element, e.g. where_t - */ - template - struct ast_iterator { - using node_type = T; - - /** - * L is a callable type. Mostly is a templated lambda - */ - template - void operator()(const T& t, L& lambda) const { - lambda(t); - } - }; - - /** - * Simplified API - */ - template - void iterate_ast(const T& t, L&& lambda) { - ast_iterator iterator; - iterator(t, lambda); - } - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct ast_iterator, void> { - using node_type = as_optional_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.expression, lambda); - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template - struct ast_iterator, void> { - using node_type = std::reference_wrapper; - - template - void operator()(const node_type& expression, L& lambda) const { - iterate_ast(expression.get(), lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = match_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.argument, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = group_by_t; - - template - void operator()(const node_type& expression, L& lambda) const { - iterate_ast(expression.args, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = highlight_t; - - template - void operator()(const node_type& expression, L& lambda) const { - lambda(expression); - iterate_ast(expression.argument0, lambda); - iterate_ast(expression.argument1, lambda); - iterate_ast(expression.argument2, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = excluded_t; - - template - void operator()(const node_type& expression, L& lambda) const { - iterate_ast(expression.expression, lambda); - } - }; - - template - struct ast_iterator> { - using node_type = T; - - template - void operator()(const node_type& expression, L& lambda) const { - iterate_ast(expression.actions, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = where_t; - - template - void operator()(const node_type& expression, L& lambda) const { - iterate_ast(expression.expression, lambda); - } - }; - - template - struct ast_iterator< - T, - std::enable_if_t, is_binary_operator>::value>> { - using node_type = T; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.lhs, lambda); - iterate_ast(node.rhs, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = is_equal_with_table_t; - - template - void operator()(const node_type& node, C& lambda) const { - iterate_ast(node.rhs, lambda); - } - }; - - template - struct ast_iterator, is_struct>::value>> { - using node_type = C; - - template - void operator()(const node_type& cols, L& lambda) const { - iterate_ast(cols.columns, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = dynamic_in_t; - - template - void operator()(const node_type& in, C& lambda) const { - iterate_ast(in.left, lambda); - iterate_ast(in.argument, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = in_t; - - template - void operator()(const node_type& in, C& lambda) const { - iterate_ast(in.left, lambda); - iterate_ast(in.argument, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = std::vector; - - template - void operator()(const node_type& vec, L& lambda) const { - for (auto& i: vec) { - iterate_ast(i, lambda); - } - } - }; - - template<> - struct ast_iterator, void> { - using node_type = std::vector; - - template - void operator()(const node_type& vec, L& lambda) const { - lambda(vec); - } - }; - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - template - struct ast_iterator> { - using node_type = CTE; - - template - void operator()(const node_type& c, L& lambda) const { - iterate_ast(c.subselect, lambda); - } - }; - - template - struct ast_iterator> { - using node_type = With; - - template - void operator()(const node_type& c, L& lambda) const { - iterate_ast(c.cte, lambda); - iterate_ast(c.expression, lambda); - } - }; -#endif - - template - struct ast_iterator> { - using node_type = T; - - template - void operator()(const node_type& c, L& lambda) const { - iterate_ast(c.compound, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = into_t; - - template - void operator()(const node_type& /*node*/, L& /*lambda*/) const { - //.. - } - }; - - template - struct ast_iterator, void> { - using node_type = insert_raw_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.args, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = replace_raw_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.args, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = select_t; - - template - void operator()(const node_type& sel, L& lambda) const { - iterate_ast(sel.col, lambda); - iterate_ast(sel.conditions, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = get_all_t; - - template - void operator()(const node_type& get, L& lambda) const { - iterate_ast(get.conditions, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = get_all_pointer_t; - - template - void operator()(const node_type& get, L& lambda) const { - iterate_ast(get.conditions, lambda); - } - }; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct ast_iterator, void> { - using node_type = get_all_optional_t; - - template - void operator()(const node_type& get, L& lambda) const { - iterate_ast(get.conditions, lambda); - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template - struct ast_iterator, void> { - using node_type = update_all_t; - - template - void operator()(const node_type& u, L& lambda) const { - iterate_ast(u.set, lambda); - iterate_ast(u.conditions, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = remove_all_t; - - template - void operator()(const node_type& r, L& lambda) const { - iterate_ast(r.conditions, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = set_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.assigns, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = dynamic_set_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.entries, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = std::tuple; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_tuple(node, [&lambda](auto& v) { - iterate_ast(v, lambda); - }); - } - }; - - template - struct ast_iterator, void> { - using node_type = group_by_with_having; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.args, lambda); - iterate_ast(node.expression, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = cast_t; - - template - void operator()(const node_type& c, L& lambda) const { - iterate_ast(c.expression, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = exists_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.expression, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = like_t; - - template - void operator()(const node_type& lk, L& lambda) const { - iterate_ast(lk.arg, lambda); - iterate_ast(lk.pattern, lambda); - lk.arg3.apply([&lambda](auto& value) { - iterate_ast(value, lambda); - }); - } - }; - - template - struct ast_iterator, void> { - using node_type = glob_t; - - template - void operator()(const node_type& lk, L& lambda) const { - iterate_ast(lk.arg, lambda); - iterate_ast(lk.pattern, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = between_t; - - template - void operator()(const node_type& b, L& lambda) const { - iterate_ast(b.expr, lambda); - iterate_ast(b.b1, lambda); - iterate_ast(b.b2, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = named_collate; - - template - void operator()(const node_type& col, L& lambda) const { - iterate_ast(col.expr, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = negated_condition_t; - - template - void operator()(const node_type& neg, L& lambda) const { - iterate_ast(neg.c, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = is_null_t; - - template - void operator()(const node_type& i, L& lambda) const { - iterate_ast(i.t, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = is_not_null_t; - - template - void operator()(const node_type& i, L& lambda) const { - iterate_ast(i.t, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = function_call; - - template - void operator()(const node_type& f, L& lambda) const { - iterate_ast(f.callArgs, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = built_in_function_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.args, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = built_in_aggregate_function_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.args, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = filtered_aggregate_function; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.function, lambda); - iterate_ast(node.where, lambda); - } - }; - - template - struct ast_iterator> { - using node_type = Join; - - template - void operator()(const node_type& join, L& lambda) const { - iterate_ast(join.constraint, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = on_t; - - template - void operator()(const node_type& on, L& lambda) const { - iterate_ast(on.arg, lambda); - } - }; - - // note: not strictly necessary as there's no binding support for USING; - // we provide it nevertheless, in line with on_t. - template - struct ast_iterator::value>> { - using node_type = T; - - template - void operator()(const node_type& o, L& lambda) const { - iterate_ast(o.column, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = simple_case_t; - - template - void operator()(const node_type& c, L& lambda) const { - c.case_expression.apply([&lambda](auto& c_) { - iterate_ast(c_, lambda); - }); - iterate_tuple(c.args, [&lambda](auto& pair) { - iterate_ast(pair.first, lambda); - iterate_ast(pair.second, lambda); - }); - c.else_expression.apply([&lambda](auto& el) { - iterate_ast(el, lambda); - }); - } - }; - - template - struct ast_iterator, void> { - using node_type = as_t; - - template - void operator()(const node_type& a, L& lambda) const { - iterate_ast(a.expression, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = limit_t; - - template - void operator()(const node_type& a, L& lambda) const { - iterate_ast(a.lim, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = limit_t; - - template - void operator()(const node_type& a, L& lambda) const { - iterate_ast(a.lim, lambda); - a.off.apply([&lambda](auto& value) { - iterate_ast(value, lambda); - }); - } - }; - - template - struct ast_iterator, void> { - using node_type = limit_t; - - template - void operator()(const node_type& a, L& lambda) const { - a.off.apply([&lambda](auto& value) { - iterate_ast(value, lambda); - }); - iterate_ast(a.lim, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = distinct_t; - - template - void operator()(const node_type& a, L& lambda) const { - iterate_ast(a.expression, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = all_t; - - template - void operator()(const node_type& a, L& lambda) const { - iterate_ast(a.expression, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = bitwise_not_t; - - template - void operator()(const node_type& a, L& lambda) const { - iterate_ast(a.argument, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = values_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.tuple, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = dynamic_values_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.vector, lambda); - } - }; - - /** - * Column alias or literal: skipped - */ - template - struct ast_iterator, - polyfill::is_specialization_of, - is_column_alias>::value>> { - using node_type = T; - - template - void operator()(const node_type& /*node*/, L& /*lambda*/) const {} - }; - - template - struct ast_iterator, void> { - using node_type = order_by_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.expression, lambda); - } - }; - - template - struct ast_iterator, void> { - using node_type = collate_t; - - template - void operator()(const node_type& node, L& lambda) const { - iterate_ast(node.expr, lambda); - } - }; - - } -} - -// #include "prepared_statement.h" - -// #include "connection_holder.h" - -// #include "util.h" - -namespace sqlite_orm { - - namespace internal { - - /** - * A C++ view-like class which is returned - * by `storage_t::iterate()` function. This class contains STL functions: - * - size_t size() - * - bool empty() - * - iterator end() - * - iterator begin() - * All these functions are not right const cause all of them may open SQLite connections. - * - * `mapped_view` is also a 'borrowed range', - * meaning that iterators obtained from it are not tied to the lifetime of the view instance. - */ - template - struct mapped_view { - using mapped_type = T; - using storage_type = S; - using db_objects_type = typename S::db_objects_type; - - storage_type& storage; - connection_ref connection; - get_all_t expression; - - mapped_view(storage_type& storage, connection_ref conn, Args&&... args) : - storage(storage), connection(std::move(conn)), expression{{std::forward(args)...}} {} - - size_t size() const { - return this->storage.template count(); - } - - bool empty() const { - return !this->size(); - } - - mapped_iterator begin() { - using context_t = serializer_context; - auto& dbObjects = obtain_db_objects(this->storage); - context_t context{dbObjects}; - context.skip_table_name = false; - context.replace_bindable_with_question = true; - - statement_finalizer stmt{prepare_stmt(this->connection.get(), serialize(this->expression, context))}; - iterate_ast(this->expression.conditions, conditional_binder{stmt.get()}); - return {dbObjects, std::move(stmt)}; - } - - mapped_iterator end() { - return {}; - } - }; - } -} - -#ifdef SQLITE_ORM_CPP20_RANGES_SUPPORTED -template -inline constexpr bool std::ranges::enable_borrowed_range> = true; -#endif - -// #include "result_set_view.h" - -#include -#include // std::move, std::remove_cvref -#include // std::reference_wrapper -#if defined(SQLITE_ORM_SENTINEL_BASED_FOR_SUPPORTED) && defined(SQLITE_ORM_DEFAULT_COMPARISONS_SUPPORTED) && \ - defined(SQLITE_ORM_CPP20_RANGES_SUPPORTED) -#include // std::ranges::view_interface -#endif - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "row_extractor.h" - -// #include "result_set_iterator.h" - -#include -#include // std::move -#include // std::input_iterator_tag, std::default_sentinel_t -#include // std::reference_wrapper - -// #include "statement_finalizer.h" - -// #include "row_extractor.h" - -// #include "column_result_proxy.h" - -// #include "util.h" - -#if defined(SQLITE_ORM_SENTINEL_BASED_FOR_SUPPORTED) && defined(SQLITE_ORM_DEFAULT_COMPARISONS_SUPPORTED) -namespace sqlite_orm::internal { - - template - class result_set_iterator; - -#ifdef SQLITE_ORM_STL_HAS_DEFAULT_SENTINEL - using result_set_sentinel_t = std::default_sentinel_t; -#else - // sentinel - template<> - class result_set_iterator {}; - - using result_set_sentinel_t = result_set_iterator; -#endif - - /* - * Input iterator over a result set for a select statement. - */ - template - class result_set_iterator { - public: - using db_objects_type = DBOs; - -#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED - using iterator_concept = std::input_iterator_tag; -#else - using iterator_category = std::input_iterator_tag; -#endif - using difference_type = ptrdiff_t; - using value_type = column_result_proxy_t; - - public: - result_set_iterator(const db_objects_type& dbObjects, statement_finalizer stmt) : - db_objects{dbObjects}, stmt{std::move(stmt)} { - this->step(); - } - result_set_iterator(result_set_iterator&&) = default; - result_set_iterator& operator=(result_set_iterator&&) = default; - result_set_iterator(const result_set_iterator&) = delete; - result_set_iterator& operator=(const result_set_iterator&) = delete; - - /** @pre `*this != std::default_sentinel` */ - value_type operator*() const { - return this->extract(); - } - - result_set_iterator& operator++() { - this->step(); - return *this; - } - - void operator++(int) { - ++*this; - } - - friend bool operator==(const result_set_iterator& it, const result_set_sentinel_t&) noexcept { - return sqlite3_data_count(it.stmt.get()) == 0; - } - - private: - void step() { - perform_step(this->stmt.get(), [](sqlite3_stmt*) {}); - } - - value_type extract() const { - const auto rowExtractor = make_row_extractor(this->db_objects.get()); - return rowExtractor.extract(this->stmt.get(), 0); - } - - private: - std::reference_wrapper db_objects; - statement_finalizer stmt; - }; -} -#endif - -// #include "ast_iterator.h" - -// #include "connection_holder.h" - -// #include "util.h" - -// #include "type_traits.h" - -// #include "storage_lookup.h" - -#if defined(SQLITE_ORM_SENTINEL_BASED_FOR_SUPPORTED) && defined(SQLITE_ORM_DEFAULT_COMPARISONS_SUPPORTED) -namespace sqlite_orm::internal { - /* - * A C++ view over a result set of a select statement, returned by `storage_t::iterate()`. - * - * `result_set_view` is also a 'borrowed range', - * meaning that iterators obtained from it are not tied to the lifetime of the view instance. - */ - template - struct result_set_view -#ifdef SQLITE_ORM_CPP20_RANGES_SUPPORTED - : std::ranges::view_interface> -#endif - { - using db_objects_type = DBOs; - using expression_type = Select; - - result_set_view(const db_objects_type& dbObjects, connection_ref conn, Select expression) : - db_objects{dbObjects}, connection{std::move(conn)}, expression{std::move(expression)} {} - - result_set_view(result_set_view&&) = default; - result_set_view& operator=(result_set_view&&) = default; - result_set_view(const result_set_view&) = default; - result_set_view& operator=(const result_set_view&) = default; - - auto begin() { - const auto& exprDBOs = db_objects_for_expression(this->db_objects.get(), this->expression); - using ExprDBOs = std::remove_cvref_t; - // note: Select can be `select_t` or `with_t` - using select_type = polyfill::detected_or_t; - using column_result_type = column_result_of_t; - using context_t = serializer_context; - context_t context{exprDBOs}; - context.skip_table_name = false; - context.replace_bindable_with_question = true; - - statement_finalizer stmt{prepare_stmt(this->connection.get(), serialize(this->expression, context))}; - iterate_ast(this->expression, conditional_binder{stmt.get()}); - - // note: it is enough to only use the 'expression DBOs' at compile-time to determine the column results; - // because we cannot select objects/structs from a CTE, passing the permanently defined DBOs are enough. - using iterator_type = result_set_iterator; - return iterator_type{this->db_objects, std::move(stmt)}; - } - - result_set_sentinel_t end() { - return {}; - } - - private: - std::reference_wrapper db_objects; - connection_ref connection; - expression_type expression; - }; -} - -#ifdef SQLITE_ORM_CPP20_RANGES_SUPPORTED -template -inline constexpr bool std::ranges::enable_borrowed_range> = true; -#endif -#endif - -// #include "ast_iterator.h" - -// #include "storage_base.h" - -#include -#include // atoi -#include // std::allocator -#include // std::function, std::bind, std::bind_front -#include // std::string -#include // std::stringstream -#include // std::flush -#include // std::move -#include // std::system_error -#include // std::vector -#include // std::list -#include // std::make_unique, std::unique_ptr -#include // std::map -#include // std::is_same -#include // std::find_if, std::ranges::find - -// #include "functional/cxx_tuple_polyfill.h" - -#include // std::apply; std::tuple_size -#if __cpp_lib_apply < 201603L -#include // std::forward, std::index_sequence, std::make_index_sequence -#endif - -// #include "../functional/cxx_functional_polyfill.h" -// std::invoke - -namespace sqlite_orm { - namespace internal { - namespace polyfill { -#if __cpp_lib_apply >= 201603L - using std::apply; -#else - template - decltype(auto) apply(Callable&& callable, Tpl&& tpl, std::index_sequence) { - return polyfill::invoke(std::forward(callable), std::get(std::forward(tpl))...); - } - - template - decltype(auto) apply(Callable&& callable, Tpl&& tpl) { - constexpr size_t size = std::tuple_size>::value; - return apply(std::forward(callable), - std::forward(tpl), - std::make_index_sequence{}); - } -#endif - } - } - - namespace polyfill = internal::polyfill; -} -// std::apply -// #include "tuple_helper/tuple_iteration.h" - -// #include "pragma.h" - -#include -#include // atoi -#include // std::string -#include // std::function -#include // std::shared_ptr -#include // std::vector -#include -#include // std::flush - -// #include "error_code.h" - -// #include "row_extractor.h" - -// #include "journal_mode.h" - -// #include "locking_mode.h" - -// #include "connection_holder.h" - -// #include "util.h" - -// #include "serializing_util.h" - -#include // std::index_sequence, std::remove_cvref -#include -#include -#include -#include -#include // std::exchange, std::tuple_size, std::make_index_sequence - -// #include "functional/cxx_type_traits_polyfill.h" -// std::remove_cvref, polyfill::is_detected -// #include "functional/cxx_functional_polyfill.h" - -// #include "tuple_helper/tuple_iteration.h" - -// #include "type_traits.h" - -// #include "error_code.h" - -// #include "serializer_context.h" - -// #include "serialize_result_type.h" - -// #include "util.h" - -// #include "schema/column.h" - -namespace sqlite_orm { - namespace internal { - template - struct order_by_t; - - template - auto serialize(const T& t, const Ctx& context); - - template - std::string serialize_order_by(const T&, const Ctx&); - - inline void stream_sql_escaped(std::ostream& os, serialize_arg_type str, char char2Escape) { - for (size_t offset = 0, next; true; offset = next + 1) { - next = str.find(char2Escape, offset); - - if (next == str.npos) SQLITE_ORM_CPP_LIKELY { - os.write(str.data() + offset, str.size() - offset); - break; - } - - os.write(str.data() + offset, next - offset + 1); - os.write(&char2Escape, 1); - } - } - - inline void stream_identifier(std::ostream& ss, - serialize_arg_type qualifier, - serialize_arg_type identifier, - serialize_arg_type alias) { - constexpr char quoteChar = '"'; - constexpr char qualified[] = {quoteChar, '.', '\0'}; - constexpr char aliased[] = {' ', quoteChar, '\0'}; - - // note: In practice, escaping double quotes in identifiers is arguably overkill, - // but since the SQLite grammar allows it, it's better to be safe than sorry. - - if (!qualifier.empty()) { - ss << quoteChar; - stream_sql_escaped(ss, qualifier, quoteChar); - ss << qualified; - } - { - ss << quoteChar; - stream_sql_escaped(ss, identifier, quoteChar); - ss << quoteChar; - } - if (!alias.empty()) { - ss << aliased; - stream_sql_escaped(ss, alias, quoteChar); - ss << quoteChar; - } - } - - inline void stream_identifier(std::ostream& ss, const std::string& identifier, const std::string& alias) { - return stream_identifier(ss, "", identifier, alias); - } - - inline void stream_identifier(std::ostream& ss, const std::string& identifier) { - return stream_identifier(ss, "", identifier, ""); - } - - template - void stream_identifier(std::ostream& ss, const Tpl& tpl, std::index_sequence) { - static_assert(sizeof...(Is) > 0 && sizeof...(Is) <= 3, ""); - return stream_identifier(ss, std::get(tpl)...); - } - - template>::value, bool> = true> - void stream_identifier(std::ostream& ss, const Tpl& tpl) { - return stream_identifier(ss, tpl, std::make_index_sequence::value>{}); - } - - enum class stream_as { - conditions_tuple, - actions_tuple, - expressions_tuple, - dynamic_expressions, - compound_expressions, - serialized, - identifier, - identifiers, - values_placeholders, - table_columns, - non_generated_columns, - field_values_excluding, - mapped_columns_expressions, - column_constraints, - constraints_tuple, - }; - - template - struct streaming { - template - auto operator()(const Ts&... ts) const { - return std::forward_as_tuple(*this, ts...); - } - - template - constexpr std::index_sequence<1u + Idx...> offset_index(std::index_sequence) const { - return {}; - } - }; - constexpr streaming streaming_conditions_tuple{}; - constexpr streaming streaming_actions_tuple{}; - constexpr streaming streaming_expressions_tuple{}; - constexpr streaming streaming_dynamic_expressions{}; - constexpr streaming streaming_compound_expressions{}; - constexpr streaming streaming_serialized{}; - constexpr streaming streaming_identifier{}; - constexpr streaming streaming_identifiers{}; - constexpr streaming streaming_values_placeholders{}; - constexpr streaming streaming_table_column_names{}; - constexpr streaming streaming_non_generated_column_names{}; - constexpr streaming streaming_field_values_excluding{}; - constexpr streaming streaming_mapped_columns_expressions{}; - constexpr streaming streaming_constraints_tuple{}; - constexpr streaming streaming_column_constraints{}; - - // serialize and stream a tuple of condition expressions; - // space + space-separated - template - std::ostream& operator<<(std::ostream& ss, - std::tuple&, T, Ctx> tpl) { - const auto& conditions = std::get<1>(tpl); - auto& context = std::get<2>(tpl); - - iterate_tuple(conditions, [&ss, &context](auto& c) { - ss << " " << serialize(c, context); - }); - return ss; - } - - // serialize and stream a tuple of action expressions; - // space-separated - template - std::ostream& operator<<(std::ostream& ss, std::tuple&, T, Ctx> tpl) { - const auto& actions = std::get<1>(tpl); - auto& context = std::get<2>(tpl); - - iterate_tuple(actions, [&ss, &context, first = true](auto& action) mutable { - static constexpr std::array sep = {" ", ""}; - ss << sep[std::exchange(first, false)] << serialize(action, context); - }); - return ss; - } - - // serialize and stream a tuple of expressions; - // comma-separated - template - std::ostream& operator<<(std::ostream& ss, - std::tuple&, T, Ctx> tpl) { - const auto& args = std::get<1>(tpl); - auto& context = std::get<2>(tpl); - - iterate_tuple(args, [&ss, &context, first = true](auto& arg) mutable { - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)] << serialize(arg, context); - }); - return ss; - } - - // serialize and stream expressions of a compound statement; - // separated by compound operator - template - std::ostream& - operator<<(std::ostream& ss, - std::tuple&, T, const std::string&, Ctx> tpl) { - const auto& args = std::get<1>(tpl); - const std::string& opString = std::get<2>(tpl); - auto& context = std::get<3>(tpl); - - iterate_tuple(args, [&ss, &opString, &context, first = true](auto& arg) mutable { - if (!std::exchange(first, false)) { - ss << ' ' << opString << ' '; - } - ss << serialize(arg, context); - }); - return ss; - } - - // serialize and stream multi_order_by arguments; - // comma-separated - template - std::ostream& operator<<( - std::ostream& ss, - std::tuple&, const std::tuple...>&, Ctx> tpl) { - const auto& args = std::get<1>(tpl); - auto& context = std::get<2>(tpl); - - iterate_tuple(args, [&ss, &context, first = true](auto& arg) mutable { - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)] << serialize_order_by(arg, context); - }); - return ss; - } - - // serialize and stream a vector or any other STL container of expressions; - // comma-separated - template - std::ostream& operator<<(std::ostream& ss, - std::tuple&, C, Ctx> tpl) { - const auto& args = std::get<1>(tpl); - auto& context = std::get<2>(tpl); - - static constexpr std::array sep = {", ", ""}; - bool first = true; - for (auto& argument: args) { - ss << sep[std::exchange(first, false)] << serialize(argument, context); - } - return ss; - } - - // stream a vector of already serialized strings; - // comma-separated - template - std::ostream& operator<<(std::ostream& ss, std::tuple&, C> tpl) { - const auto& strings = std::get<1>(tpl); - - static constexpr std::array sep = {", ", ""}; - for (size_t i = 0, first = true; i < strings.size(); ++i) { - ss << sep[std::exchange(first, false)] << strings[i]; - } - return ss; - } - - // stream an identifier described by a variadic string pack, which is one of: - // 1. identifier - // 2. identifier, alias - // 3. qualifier, identifier, alias - template - std::ostream& operator<<(std::ostream& ss, - std::tuple&, Strings...> tpl) { - stream_identifier(ss, tpl, streaming_identifier.offset_index(std::index_sequence_for{})); - return ss; - } - - // stream a container of identifiers described by a string or a tuple, which is one of: - // 1. identifier - // 1. tuple(identifier) - // 2. tuple(identifier, alias), pair(identifier, alias) - // 3. tuple(qualifier, identifier, alias) - // - // comma-separated - template - std::ostream& operator<<(std::ostream& ss, std::tuple&, C> tpl) { - const auto& identifiers = std::get<1>(tpl); - - static constexpr std::array sep = {", ", ""}; - bool first = true; - for (auto& identifier: identifiers) { - ss << sep[std::exchange(first, false)]; - stream_identifier(ss, identifier); - } - return ss; - } - - // stream placeholders as part of a values clause - template - std::ostream& operator<<(std::ostream& ss, - std::tuple&, Ts...> tpl) { - const size_t& columnsCount = std::get<1>(tpl); - const ptrdiff_t& valuesCount = std::get<2>(tpl); - - if (!valuesCount || !columnsCount) { - return ss; - } - - std::string result; - result.reserve((1 + (columnsCount * 1) + (columnsCount * 2 - 2) + 1) * valuesCount + (valuesCount * 2 - 2)); - - static constexpr std::array sep = {", ", ""}; - for (ptrdiff_t i = 0, first = true; i < valuesCount; ++i) { - result += sep[std::exchange(first, false)]; - result += "("; - for (size_t i = 0, first = true; i < columnsCount; ++i) { - result += sep[std::exchange(first, false)]; - result += "?"; - } - result += ")"; - } - ss << result; - return ss; - } - - // stream a table's column identifiers, possibly qualified; - // comma-separated - template - std::ostream& - operator<<(std::ostream& ss, - std::tuple&, Table, const std::string&> tpl) { - const auto& table = std::get<1>(tpl); - const std::string& qualifier = std::get<2>(tpl); - - table.for_each_column([&ss, &qualifier, first = true](const column_identifier& column) mutable { - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)]; - stream_identifier(ss, qualifier, column.name, std::string{}); - }); - return ss; - } - - // stream a table's non-generated column identifiers, unqualified; - // comma-separated - template - std::ostream& operator<<(std::ostream& ss, - std::tuple&, Table> tpl) { - const auto& table = std::get<1>(tpl); - - table.template for_each_column_excluding( - [&ss, first = true](const column_identifier& column) mutable { - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)]; - stream_identifier(ss, column.name); - }); - return ss; - } - - // stream a table's non-generated column identifiers, unqualified; - // comma-separated - template - std::ostream& - operator<<(std::ostream& ss, - std::tuple&, PredFnCls, L, Ctx, Obj> tpl) { - using check_if_excluded = polyfill::remove_cvref_t>; - auto& excluded = std::get<2>(tpl); - auto& context = std::get<3>(tpl); - auto& object = std::get<4>(tpl); - using object_type = polyfill::remove_cvref_t; - auto& table = pick_table(context.db_objects); - - table.template for_each_column_excluding(call_as_template_base( - [&ss, &excluded, &context, &object, first = true](auto& column) mutable { - if (excluded(column)) { - return; - } - - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)] - << serialize(polyfill::invoke(column.member_pointer, object), context); - })); - return ss; - } - - // stream a tuple of mapped columns (which are member pointers or column pointers); - // comma-separated - template - std::ostream& operator<<(std::ostream& ss, - std::tuple&, T, Ctx> tpl) { - const auto& columns = std::get<1>(tpl); - auto& context = std::get<2>(tpl); - - iterate_tuple(columns, [&ss, &context, first = true](auto& colRef) mutable { - const std::string* columnName = find_column_name(context.db_objects, colRef); - if (!columnName) { - throw std::system_error{orm_error_code::column_not_found}; - } - - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)]; - stream_identifier(ss, *columnName); - }); - return ss; - } - - // serialize and stream a tuple of conditions or hints; - // space + space-separated - template - std::ostream& operator<<(std::ostream& ss, - std::tuple&, T, Ctx> tpl) { - const auto& constraints = get<1>(tpl); - auto& context = get<2>(tpl); - - iterate_tuple(constraints, [&ss, &context](auto& constraint) mutable { - ss << ' ' << serialize(constraint, context); - }); - return ss; - } - - // serialize and stream a tuple of column constraints; - // space + space-separated - template - std::ostream& operator<<(std::ostream& ss, - std::tuple&, - const column_constraints&, - const bool&, - Ctx> tpl) { - const auto& column = std::get<1>(tpl); - const bool& isNotNull = std::get<2>(tpl); - auto& context = std::get<3>(tpl); - - using constraints_tuple = decltype(column.constraints); - iterate_tuple(column.constraints, [&ss, &context](auto& constraint) { - ss << ' ' << serialize(constraint, context); - }); - // add implicit null constraint - if (!context.fts5_columns) { - constexpr bool hasExplicitNullableConstraint = - mpl::invoke_t, check_if_has_type>, - constraints_tuple>::value; - if SQLITE_ORM_CONSTEXPR_IF (!hasExplicitNullableConstraint) { - if (isNotNull) { - ss << " NOT NULL"; - } else { - ss << " NULL"; - } - } - } - - return ss; - } - } -} - -namespace sqlite_orm { - - namespace internal { - struct storage_base; - - template - int getPragmaCallback(void* data, int argc, char** argv, char** x) { - return extract_single_value(data, argc, argv, x); - } - - template<> - inline int getPragmaCallback>(void* data, int argc, char** argv, char**) { - auto& res = *(std::vector*)data; - res.reserve(argc); - const auto rowExtractor = column_text_extractor(); - for (int i = 0; i < argc; ++i) { - auto rowString = rowExtractor.extract(argv[i]); - res.push_back(std::move(rowString)); - } - return 0; - } - - struct pragma_t { - using get_connection_t = std::function; - - pragma_t(get_connection_t get_connection_) : get_connection(std::move(get_connection_)) {} - - std::vector module_list() { - return this->get_pragma>("module_list"); - } - - bool recursive_triggers() { - return bool(this->get_pragma("recursive_triggers")); - } - - void recursive_triggers(bool value) { - this->set_pragma("recursive_triggers", int(value)); - } - - void busy_timeout(int value) { - this->set_pragma("busy_timeout", value); - } - - int busy_timeout() { - return this->get_pragma("busy_timeout"); - } - - sqlite_orm::locking_mode locking_mode() { - return this->get_pragma("locking_mode"); - } - - void locking_mode(sqlite_orm::locking_mode value) { - this->set_pragma("locking_mode", value); - } - - sqlite_orm::journal_mode journal_mode() { - return this->get_pragma("journal_mode"); - } - - void journal_mode(sqlite_orm::journal_mode value) { - this->journal_mode_ = -1; - this->set_pragma("journal_mode", value); - this->journal_mode_ = static_castjournal_mode_)>(value); - } - - /** - * https://www.sqlite.org/pragma.html#pragma_application_id - */ - int application_id() { - return this->get_pragma("application_id"); - } - - /** - * https://www.sqlite.org/pragma.html#pragma_application_id - */ - void application_id(int value) { - this->set_pragma("application_id", value); - } - - int synchronous() { - return this->get_pragma("synchronous"); - } - - void synchronous(int value) { - this->synchronous_ = -1; - this->set_pragma("synchronous", value); - this->synchronous_ = value; - } - - int user_version() { - return this->get_pragma("user_version"); - } - - void user_version(int value) { - this->set_pragma("user_version", value); - } - - int auto_vacuum() { - return this->get_pragma("auto_vacuum"); - } - - void auto_vacuum(int value) { - this->set_pragma("auto_vacuum", value); - } - - int max_page_count() { - return this->get_pragma("max_page_count"); - } - - void max_page_count(int value) { - this->set_pragma("max_page_count", value); - } - - std::vector integrity_check() { - return this->get_pragma>("integrity_check"); - } - - template - std::vector integrity_check(T table_name) { - std::ostringstream ss; - ss << "integrity_check(" << table_name << ")" << std::flush; - return this->get_pragma>(ss.str()); - } - - std::vector integrity_check(int n) { - std::ostringstream ss; - ss << "integrity_check(" << n << ")" << std::flush; - return this->get_pragma>(ss.str()); - } - - std::vector quick_check() { - return this->get_pragma>("quick_check"); - } - - // will include generated columns in response as opposed to table_info - std::vector table_xinfo(const std::string& tableName) const { - auto connection = this->get_connection(); - - std::vector result; - std::ostringstream ss; - ss << "PRAGMA " - "table_xinfo(" - << streaming_identifier(tableName) << ")" << std::flush; - perform_exec( - connection.get(), - ss.str(), - [](void* data, int argc, char** argv, char**) -> int { - auto& res = *(std::vector*)data; - if (argc) { - auto index = 0; - auto cid = atoi(argv[index++]); - std::string name = argv[index++]; - std::string type = argv[index++]; - bool notnull = !!atoi(argv[index++]); - std::string dflt_value = argv[index] ? argv[index] : ""; - ++index; - auto pk = atoi(argv[index++]); - auto hidden = atoi(argv[index++]); - res.emplace_back(cid, - std::move(name), - std::move(type), - notnull, - std::move(dflt_value), - pk, - hidden); - } - return 0; - }, - &result); - return result; - } - - std::vector table_info(const std::string& tableName) const { - auto connection = this->get_connection(); - - std::ostringstream ss; - ss << "PRAGMA " - "table_info(" - << streaming_identifier(tableName) << ")" << std::flush; - std::vector result; - perform_exec( - connection.get(), - ss.str(), - [](void* data, int argc, char** argv, char**) -> int { - auto& res = *(std::vector*)data; - if (argc) { - auto index = 0; - auto cid = atoi(argv[index++]); - std::string name = argv[index++]; - std::string type = argv[index++]; - bool notnull = !!atoi(argv[index++]); - std::string dflt_value = argv[index] ? argv[index] : ""; - ++index; - auto pk = atoi(argv[index++]); - res.emplace_back(cid, std::move(name), std::move(type), notnull, std::move(dflt_value), pk); - } - return 0; - }, - &result); - return result; - } - - private: - friend struct storage_base; - - int synchronous_ = -1; - signed char journal_mode_ = -1; // if != -1 stores static_cast(journal_mode) - get_connection_t get_connection; - - template - T get_pragma(const std::string& name) { - auto connection = this->get_connection(); - T result; - perform_exec(connection.get(), "PRAGMA " + name, getPragmaCallback, &result); - return result; - } - - /** - * Yevgeniy Zakharov: I wanted to refactor this function with statements and value bindings - * but it turns out that bindings in pragma statements are not supported. - */ - template - void set_pragma(const std::string& name, const T& value, sqlite3* db = nullptr) { - std::stringstream ss; - ss << "PRAGMA " << name << " = " << value; - this->set_pragma_impl(ss.str(), db); - } - - void set_pragma(const std::string& name, sqlite_orm::journal_mode value, sqlite3* db = nullptr) { - std::stringstream ss; - ss << "PRAGMA " << name << " = " << journal_mode_to_string(value); - this->set_pragma_impl(ss.str(), db); - } - - void set_pragma(const std::string& name, sqlite_orm::locking_mode value, sqlite3* db = nullptr) { - std::stringstream ss; - ss << "PRAGMA " << name << " = " << locking_mode_to_string(value); - this->set_pragma_impl(ss.str(), db); - } - - void set_pragma_impl(const std::string& query, sqlite3* db = nullptr) { - auto con = this->get_connection(); - if (db == nullptr) { - db = con.get(); - } - perform_void_exec(db, query); - } - }; - } -} - -// #include "limit_accessor.h" - -#include -#include // std::map -#include // std::function -#include // std::shared_ptr - -// #include "connection_holder.h" - -namespace sqlite_orm { - - namespace internal { - - struct limit_accessor { - using get_connection_t = std::function; - - limit_accessor(get_connection_t get_connection_) : get_connection(std::move(get_connection_)) {} - - int length() { - return this->get(SQLITE_LIMIT_LENGTH); - } - - void length(int newValue) { - this->set(SQLITE_LIMIT_LENGTH, newValue); - } - - int sql_length() { - return this->get(SQLITE_LIMIT_SQL_LENGTH); - } - - void sql_length(int newValue) { - this->set(SQLITE_LIMIT_SQL_LENGTH, newValue); - } - - int column() { - return this->get(SQLITE_LIMIT_COLUMN); - } - - void column(int newValue) { - this->set(SQLITE_LIMIT_COLUMN, newValue); - } - - int expr_depth() { - return this->get(SQLITE_LIMIT_EXPR_DEPTH); - } - - void expr_depth(int newValue) { - this->set(SQLITE_LIMIT_EXPR_DEPTH, newValue); - } - - int compound_select() { - return this->get(SQLITE_LIMIT_COMPOUND_SELECT); - } - - void compound_select(int newValue) { - this->set(SQLITE_LIMIT_COMPOUND_SELECT, newValue); - } - - int vdbe_op() { - return this->get(SQLITE_LIMIT_VDBE_OP); - } - - void vdbe_op(int newValue) { - this->set(SQLITE_LIMIT_VDBE_OP, newValue); - } - - int function_arg() { - return this->get(SQLITE_LIMIT_FUNCTION_ARG); - } - - void function_arg(int newValue) { - this->set(SQLITE_LIMIT_FUNCTION_ARG, newValue); - } - - int attached() { - return this->get(SQLITE_LIMIT_ATTACHED); - } - - void attached(int newValue) { - this->set(SQLITE_LIMIT_ATTACHED, newValue); - } - - int like_pattern_length() { - return this->get(SQLITE_LIMIT_LIKE_PATTERN_LENGTH); - } - - void like_pattern_length(int newValue) { - this->set(SQLITE_LIMIT_LIKE_PATTERN_LENGTH, newValue); - } - - int variable_number() { - return this->get(SQLITE_LIMIT_VARIABLE_NUMBER); - } - - void variable_number(int newValue) { - this->set(SQLITE_LIMIT_VARIABLE_NUMBER, newValue); - } - - int trigger_depth() { - return this->get(SQLITE_LIMIT_TRIGGER_DEPTH); - } - - void trigger_depth(int newValue) { - this->set(SQLITE_LIMIT_TRIGGER_DEPTH, newValue); - } - -#if SQLITE_VERSION_NUMBER >= 3008007 - int worker_threads() { - return this->get(SQLITE_LIMIT_WORKER_THREADS); - } - - void worker_threads(int newValue) { - this->set(SQLITE_LIMIT_WORKER_THREADS, newValue); - } -#endif - - protected: - get_connection_t get_connection; - - friend struct storage_base; - - /** - * Stores limit set between connections. - */ - std::map limits; - - int get(int id) { - auto connection = this->get_connection(); - return sqlite3_limit(connection.get(), id, -1); - } - - void set(int id, int newValue) { - this->limits[id] = newValue; - auto connection = this->get_connection(); - sqlite3_limit(connection.get(), id, newValue); - } - }; - } -} - -// #include "transaction_guard.h" - -#include // std::function -#include // std::move - -// #include "connection_holder.h" - -namespace sqlite_orm { - - namespace internal { - - /** - * Class used as a guard for a transaction. Calls `ROLLBACK` in destructor. - * Has explicit `commit()` and `rollback()` functions. After explicit function is fired - * guard won't do anything in d-tor. Also you can set `commit_on_destroy` to true to - * make it call `COMMIT` on destroy. - * - * Note: The guard's destructor is explicitly marked as potentially throwing, - * so exceptions that occur during commit or rollback are propagated to the caller. - */ - struct transaction_guard_t { - /** - * This is a public lever to tell a guard what it must do in its destructor - * if `gotta_fire` is true - */ - bool commit_on_destroy = false; - - transaction_guard_t(connection_ref connection_, - std::function commit_func_, - std::function rollback_func_) : - connection(std::move(connection_)), commit_func(std::move(commit_func_)), - rollback_func(std::move(rollback_func_)) {} - - transaction_guard_t(transaction_guard_t&& other) : - commit_on_destroy(other.commit_on_destroy), connection(std::move(other.connection)), - commit_func(std::move(other.commit_func)), rollback_func(std::move(other.rollback_func)), - gotta_fire(other.gotta_fire) { - other.gotta_fire = false; - } - - ~transaction_guard_t() noexcept(false) { - if (this->gotta_fire) { - if (this->commit_on_destroy) { - this->commit_func(); - } else { - this->rollback_func(); - } - } - } - - transaction_guard_t& operator=(transaction_guard_t&&) = delete; - - /** - * Call `COMMIT` explicitly. After this call - * guard will not call `COMMIT` or `ROLLBACK` - * in its destructor. - */ - void commit() { - this->gotta_fire = false; - this->commit_func(); - } - - /** - * Call `ROLLBACK` explicitly. After this call - * guard will not call `COMMIT` or `ROLLBACK` - * in its destructor. - */ - void rollback() { - this->gotta_fire = false; - this->rollback_func(); - } - - protected: - connection_ref connection; - std::function commit_func; - std::function rollback_func; - bool gotta_fire = true; - }; - } -} - -// #include "row_extractor.h" - -// #include "connection_holder.h" - -// #include "backup.h" - -#include -#include // std::system_error -#include // std::string -#include -#include // std::move, std::exchange - -// #include "error_code.h" - -// #include "connection_holder.h" - -namespace sqlite_orm { - - namespace internal { - - /** - * A backup class. Don't construct it as is, call storage.make_backup_from or storage.make_backup_to instead. - * An instance of this class represents a wrapper around sqlite3_backup pointer. Use this class - * to have maximum control on a backup operation. In case you need a single backup in one line you - * can skip creating a backup_t instance and just call storage.backup_from or storage.backup_to function. - */ - struct backup_t { - backup_t(connection_ref to_, - const std::string& zDestName, - connection_ref from_, - const std::string& zSourceName, - std::unique_ptr holder_) : - handle(sqlite3_backup_init(to_.get(), zDestName.c_str(), from_.get(), zSourceName.c_str())), - holder(std::move(holder_)), to(to_), from(from_) { - if (!this->handle) { - throw std::system_error{orm_error_code::failed_to_init_a_backup}; - } - } - - backup_t(backup_t&& other) : - handle(std::exchange(other.handle, nullptr)), holder(std::move(other.holder)), to(other.to), - from(other.from) {} - - ~backup_t() { - if (this->handle) { - (void)sqlite3_backup_finish(this->handle); - } - } - - /** - * Calls sqlite3_backup_step with pages argument - */ - int step(int pages) { - return sqlite3_backup_step(this->handle, pages); - } - - /** - * Returns sqlite3_backup_remaining result - */ - int remaining() const { - return sqlite3_backup_remaining(this->handle); - } - - /** - * Returns sqlite3_backup_pagecount result - */ - int pagecount() const { - return sqlite3_backup_pagecount(this->handle); - } - - protected: - sqlite3_backup* handle = nullptr; - std::unique_ptr holder; - connection_ref to; - connection_ref from; - }; - } -} - -// #include "function.h" - -// #include "values_to_tuple.h" - -#include -#include // std::enable_if, std::is_same, std::index_sequence, std::make_index_sequence -#include // std::tuple, std::tuple_size, std::tuple_element - -// #include "functional/cxx_functional_polyfill.h" - -// #include "type_traits.h" - -// #include "row_extractor.h" - -// #include "arg_values.h" - -#include - -// #include "row_extractor.h" - -namespace sqlite_orm { - - /** @short Wrapper around a dynamically typed value object. - */ - struct arg_value { - - arg_value() : arg_value(nullptr) {} - - arg_value(sqlite3_value* value_) : value(value_) {} - - template - T get() const { - const auto rowExtractor = internal::boxed_value_extractor(); - return rowExtractor.extract(this->value); - } - - bool is_null() const { - auto type = sqlite3_value_type(this->value); - return type == SQLITE_NULL; - } - - bool is_text() const { - auto type = sqlite3_value_type(this->value); - return type == SQLITE_TEXT; - } - - bool is_integer() const { - auto type = sqlite3_value_type(this->value); - return type == SQLITE_INTEGER; - } - - bool is_float() const { - auto type = sqlite3_value_type(this->value); - return type == SQLITE_FLOAT; - } - - bool is_blob() const { - auto type = sqlite3_value_type(this->value); - return type == SQLITE_BLOB; - } - - bool empty() const { - return this->value == nullptr; - } - - private: - sqlite3_value* value = nullptr; - }; - - struct arg_values { - - struct iterator { - - iterator(const arg_values& container_, int index_) : - container(container_), index(index_), - currentValue(index_ < int(container_.size()) ? container_[index_] : arg_value()) {} - - iterator& operator++() { - ++this->index; - if (this->index < int(this->container.size())) { - this->currentValue = this->container[this->index]; - } else { - this->currentValue = {}; - } - return *this; - } - - iterator operator++(int) { - auto res = *this; - ++this->index; - if (this->index < int(this->container.size())) { - this->currentValue = this->container[this->index]; - } else { - this->currentValue = {}; - } - return res; - } - - arg_value operator*() const { - if (this->index < int(this->container.size()) && this->index >= 0) { - return this->currentValue; - } else { - throw std::system_error{orm_error_code::index_is_out_of_bounds}; - } - } - - arg_value* operator->() const { - return &this->currentValue; - } - - bool operator==(const iterator& other) const { - return &other.container == &this->container && other.index == this->index; - } - - bool operator!=(const iterator& other) const { - return !(*this == other); - } - - private: - const arg_values& container; - int index = 0; - mutable arg_value currentValue; - }; - - arg_values() : arg_values(0, nullptr) {} - - arg_values(int argsCount_, sqlite3_value** values_) : argsCount(argsCount_), values(values_) {} - - size_t size() const { - return this->argsCount; - } - - bool empty() const { - return 0 == this->argsCount; - } - - arg_value operator[](int index) const { - if (index < this->argsCount && index >= 0) { - sqlite3_value* value = this->values[index]; - return {value}; - } else { - throw std::system_error{orm_error_code::index_is_out_of_bounds}; - } - } - - arg_value at(int index) const { - return this->operator[](index); - } - - iterator begin() const { - return {*this, 0}; - } - - iterator end() const { - return {*this, this->argsCount}; - } - - private: - int argsCount = 0; - sqlite3_value** values = nullptr; - }; -} - -namespace sqlite_orm { - - namespace internal { - - template - struct tuple_from_values { - template> = true> - R operator()(sqlite3_value** values, int /*argsCount*/) const { - return this->create_from(values, std::make_index_sequence::value>{}); - } - - template> = true> - R operator()(sqlite3_value** values, int argsCount) const { - return {arg_values(argsCount, values)}; - } - - private: - template - Tpl create_from(sqlite3_value** values, std::index_sequence) const { - return {this->extract>(values[Idx])...}; - } - - template - T extract(sqlite3_value* value) const { - const auto rowExtractor = boxed_value_extractor(); - return rowExtractor.extract(value); - } - }; - } -} - -// #include "arg_values.h" - -// #include "util.h" - -// #include "xdestroy_handling.h" - -// #include "udf_proxy.h" - -#include -#include // assert macro -#include // std::true_type, std::false_type -#include // std::bad_alloc -#include // std::allocator, std::allocator_traits, std::unique_ptr -#include // std::string -#include // std::function -#include // std::move, std::pair - -// #include "error_code.h" - -namespace sqlite_orm { - namespace internal { - /* - * Returns properly allocated memory space for the specified application-defined function object - * paired with an accompanying deallocation function. - */ - template - std::pair preallocate_udf_memory() { - std::allocator allocator; - using traits = std::allocator_traits; - - SQLITE_ORM_CONSTEXPR_LAMBDA_CPP17 auto deallocate = [](void* location) noexcept { - std::allocator allocator; - using traits = std::allocator_traits; - traits::deallocate(allocator, (UDF*)location, 1); - }; - - return {traits::allocate(allocator, 1), deallocate}; - } - - /* - * Returns a pair of functions to allocate/deallocate properly aligned memory space for the specified application-defined function object. - */ - template - std::pair obtain_udf_allocator() { - SQLITE_ORM_CONSTEXPR_LAMBDA_CPP17 auto allocate = []() { - std::allocator allocator; - using traits = std::allocator_traits; - return (void*)traits::allocate(allocator, 1); - }; - - SQLITE_ORM_CONSTEXPR_LAMBDA_CPP17 auto deallocate = [](void* location) noexcept { - std::allocator allocator; - using traits = std::allocator_traits; - traits::deallocate(allocator, (UDF*)location, 1); - }; - - return {allocate, deallocate}; - } - - /* - * A deleter that only destroys the application-defined function object. - */ - struct udf_destruct_only_deleter { - template - void operator()(UDF* f) const noexcept { - std::allocator allocator; - using traits = std::allocator_traits; - traits::destroy(allocator, f); - } - }; - - /* - * Stores type-erased information in relation to an application-defined scalar or aggregate function object: - * - name and argument count - * - function dispatch (step, final) - * - either preallocated memory with a possibly a priori constructed function object [scalar], - * - or memory allocation/deallocation functions [aggregate] - */ - struct udf_proxy { - using sqlite_func_t = void (*)(sqlite3_context* context, int argsCount, sqlite3_value** values); - using final_call_fn_t = void (*)(void* udfHandle, sqlite3_context* context); - using memory_alloc = std::pair; - using memory_space = std::pair; - - std::string name; - int argumentsCount; - std::function constructAt; - xdestroy_fn_t destroy; - sqlite_func_t func; - final_call_fn_t finalAggregateCall; - - // allocator/deallocator function pair for aggregate UDF - const memory_alloc udfAllocator; - // pointer to preallocated memory space for scalar UDF, already constructed by caller if stateless - const memory_space udfMemorySpace; - - udf_proxy(std::string name, - int argumentsCount, - std::function constructAt, - xdestroy_fn_t destroy, - sqlite_func_t func, - memory_space udfMemorySpace) : - name{std::move(name)}, argumentsCount{argumentsCount}, constructAt{std::move(constructAt)}, - destroy{destroy}, func{func}, finalAggregateCall{nullptr}, udfAllocator{}, - udfMemorySpace{udfMemorySpace} {} - - udf_proxy(std::string name, - int argumentsCount, - std::function constructAt, - xdestroy_fn_t destroy, - sqlite_func_t func, - final_call_fn_t finalAggregateCall, - memory_alloc udfAllocator) : - name{std::move(name)}, argumentsCount{argumentsCount}, constructAt{std::move(constructAt)}, - destroy{destroy}, func{func}, finalAggregateCall{finalAggregateCall}, udfAllocator{udfAllocator}, - udfMemorySpace{} {} - - ~udf_proxy() { - // destruct - if (/*bool aprioriConstructed = */ !constructAt && destroy) { - destroy(udfMemorySpace.first); - } - // deallocate - if (udfMemorySpace.second) { - udfMemorySpace.second(udfMemorySpace.first); - } - } - - udf_proxy(const udf_proxy&) = delete; - udf_proxy& operator=(const udf_proxy&) = delete; - - // convenience accessors for better legibility; - // [`friend` is intentional - it ensures that these are core accessors (only found via ADL), yet still be an out-of-class interface] - - friend void* preallocated_udf_handle(udf_proxy* proxy) { - return proxy->udfMemorySpace.first; - } - - friend void* allocate_udf(udf_proxy* proxy) { - return proxy->udfAllocator.first(); - } - - friend void deallocate_udf(udf_proxy* proxy, void* udfHandle) { - proxy->udfAllocator.second(udfHandle); - } - }; - - // safety net of doing a triple check at runtime - inline void assert_args_count(const udf_proxy* proxy, int argsCount) { - assert((proxy->argumentsCount == -1) || (proxy->argumentsCount == argsCount || - /*check fin call*/ argsCount == -1)); - (void)proxy; - (void)argsCount; - } - - // safety net of doing a triple check at runtime - inline void proxy_assert_args_count(sqlite3_context* context, int argsCount) { - udf_proxy* proxy; - assert((proxy = static_cast(sqlite3_user_data(context))) != nullptr); - assert_args_count(proxy, argsCount); - (void)context; - } - - // note: may throw `std::bad_alloc` in case memory space for the aggregate function object cannot be allocated - inline void* ensure_aggregate_udf(sqlite3_context* context, udf_proxy* proxy, int argsCount) { - // reserve memory for storing a void pointer (which is the `udfHandle`, i.e. address of the aggregate function object) - void* ctxMemory = sqlite3_aggregate_context(context, sizeof(void*)); - if (!ctxMemory) SQLITE_ORM_CPP_UNLIKELY { - throw std::bad_alloc(); - } - void*& udfHandle = *static_cast(ctxMemory); - - if (udfHandle) SQLITE_ORM_CPP_LIKELY { - return udfHandle; - } else { - assert_args_count(proxy, argsCount); - udfHandle = allocate_udf(proxy); - // Note on the use of the `udfHandle` pointer after the object construction: - // since we only ever cast between void* and UDF* pointer types and - // only use the memory space for one type during the entire lifetime of a proxy, - // we can use `udfHandle` interconvertibly without laundering its provenance. - proxy->constructAt(udfHandle); - return udfHandle; - } - } - - inline void delete_aggregate_udf(udf_proxy* proxy, void* udfHandle) { - proxy->destroy(udfHandle); - deallocate_udf(proxy, udfHandle); - } - - // Return C pointer to preallocated and a priori constructed UDF - template - inline UDF* - proxy_get_scalar_udf(std::true_type /*is_stateless*/, sqlite3_context* context, int argsCount) noexcept { - proxy_assert_args_count(context, argsCount); - udf_proxy* proxy = static_cast(sqlite3_user_data(context)); - return static_cast(preallocated_udf_handle(proxy)); - } - - // Return unique pointer to newly constructed UDF at preallocated memory space - template - inline auto proxy_get_scalar_udf(std::false_type /*is_stateless*/, sqlite3_context* context, int argsCount) { - proxy_assert_args_count(context, argsCount); - udf_proxy* proxy = static_cast(sqlite3_user_data(context)); - // Note on the use of the `udfHandle` pointer after the object construction: - // since we only ever cast between void* and UDF* pointer types and - // only use the memory space for one type during the entire lifetime of a proxy, - // we can use `udfHandle` interconvertibly without laundering its provenance. - proxy->constructAt(preallocated_udf_handle(proxy)); - return std::unique_ptr{static_cast(preallocated_udf_handle(proxy)), - proxy->destroy}; - } - - // note: may throw `std::bad_alloc` in case memory space for the aggregate function object cannot be allocated - template - inline UDF* proxy_get_aggregate_step_udf(sqlite3_context* context, int argsCount) { - udf_proxy* proxy = static_cast(sqlite3_user_data(context)); - void* udfHandle = ensure_aggregate_udf(context, proxy, argsCount); - return static_cast(udfHandle); - } - - inline void aggregate_function_final_callback(sqlite3_context* context) { - udf_proxy* proxy = static_cast(sqlite3_user_data(context)); - void* udfHandle; - try { - // note: it is possible that the 'step' function was never called - udfHandle = ensure_aggregate_udf(context, proxy, -1); - } catch (const std::bad_alloc&) { - sqlite3_result_error_nomem(context); - return; - } - proxy->finalAggregateCall(udfHandle, context); - delete_aggregate_udf(proxy, udfHandle); - } - } -} - -// #include "serializing_util.h" - -// #include "table_info.h" - -namespace sqlite_orm { - - namespace internal { - - struct storage_base { - using collating_function = std::function; - - std::function on_open; - pragma_t pragma; - limit_accessor limit; - - transaction_guard_t transaction_guard() { - this->begin_transaction(); - return {this->get_connection(), - std::bind(&storage_base::commit, this), - std::bind(&storage_base::rollback, this)}; - } - - transaction_guard_t deferred_transaction_guard() { - this->begin_deferred_transaction(); - return {this->get_connection(), - std::bind(&storage_base::commit, this), - std::bind(&storage_base::rollback, this)}; - } - - transaction_guard_t immediate_transaction_guard() { - this->begin_immediate_transaction(); - return {this->get_connection(), - std::bind(&storage_base::commit, this), - std::bind(&storage_base::rollback, this)}; - } - - transaction_guard_t exclusive_transaction_guard() { - this->begin_exclusive_transaction(); - return {this->get_connection(), - std::bind(&storage_base::commit, this), - std::bind(&storage_base::rollback, this)}; - } - - /** - * Drops index with given name. - * Calls `DROP INDEX indexName`. - * More info: https://www.sqlite.org/lang_dropindex.html - */ - void drop_index(const std::string& indexName) { - this->drop_index_internal(indexName, false); - } - - /** - * Drops trigger with given name if trigger exists. - * Calls `DROP INDEX IF EXISTS indexName`. - * More info: https://www.sqlite.org/lang_dropindex.html - */ - void drop_index_if_exists(const std::string& indexName) { - this->drop_index_internal(indexName, true); - } - - /** - * Drops trigger with given name. - * Calls `DROP TRIGGER triggerName`. - * More info: https://www.sqlite.org/lang_droptrigger.html - */ - void drop_trigger(const std::string& triggerName) { - this->drop_trigger_internal(triggerName, false); - } - - /** - * Drops trigger with given name if trigger exists. - * Calls `DROP TRIGGER IF EXISTS triggerName`. - * More info: https://www.sqlite.org/lang_droptrigger.html - */ - void drop_trigger_if_exists(const std::string& triggerName) { - this->drop_trigger_internal(triggerName, true); - } - - /** - * `VACUUM` query. - * More info: https://www.sqlite.org/lang_vacuum.html - */ - void vacuum() { - perform_void_exec(this->get_connection().get(), "VACUUM"); - } - - /** - * Drops table with given name. - * Calls `DROP TABLE tableName`. - * More info: https://www.sqlite.org/lang_droptable.html - */ - void drop_table(const std::string& tableName) { - this->drop_table_internal(this->get_connection().get(), tableName, false); - } - - /** - * Drops table with given name if table exists. - * Calls `DROP TABLE IF EXISTS tableName`. - * More info: https://www.sqlite.org/lang_droptable.html - */ - void drop_table_if_exists(const std::string& tableName) { - this->drop_table_internal(this->get_connection().get(), tableName, true); - } - - /** - * Rename table named `from` to `to`. - */ - void rename_table(const std::string& from, const std::string& to) { - this->rename_table(this->get_connection().get(), from, to); - } - - protected: - void rename_table(sqlite3* db, const std::string& oldName, const std::string& newName) const { - std::stringstream ss; - ss << "ALTER TABLE " << streaming_identifier(oldName) << " RENAME TO " << streaming_identifier(newName) - << std::flush; - perform_void_exec(db, ss.str()); - } - - /** - * Checks whether table exists in db. Doesn't check storage itself - works only with actual database. - * Note: table can be not mapped to a storage - * @return true if table with a given name exists in db, false otherwise. - */ - bool table_exists(const std::string& tableName) { - auto con = this->get_connection(); - return this->table_exists(con.get(), tableName); - } - - bool table_exists(sqlite3* db, const std::string& tableName) const { - bool result = false; - std::stringstream ss; - ss << "SELECT COUNT(*) FROM sqlite_master WHERE type = " << quote_string_literal("table") - << " AND name = " << quote_string_literal(tableName) << std::flush; - perform_exec( - db, - ss.str(), - [](void* data, int argc, char** argv, char** /*azColName*/) -> int { - auto& res = *(bool*)data; - if (argc) { - res = !!atoi(argv[0]); - } - return 0; - }, - &result); - return result; - } - - void add_generated_cols(std::vector& columnsToAdd, - const std::vector& storageTableInfo) { - // iterate through storage columns - for (const table_xinfo& storageColumnInfo: storageTableInfo) { - if (storageColumnInfo.hidden) { - columnsToAdd.push_back(&storageColumnInfo); - } - } - } - - public: - /** - * sqlite3_changes function. - */ - int changes() { - auto con = this->get_connection(); - return sqlite3_changes(con.get()); - } - - /** - * sqlite3_total_changes function. - */ - int total_changes() { - auto con = this->get_connection(); - return sqlite3_total_changes(con.get()); - } - - int64 last_insert_rowid() { - auto con = this->get_connection(); - return sqlite3_last_insert_rowid(con.get()); - } - - int busy_timeout(int ms) { - auto con = this->get_connection(); - return sqlite3_busy_timeout(con.get(), ms); - } - - /** - * Returns libsqlite3 version, not sqlite_orm - */ - std::string libversion() { - return sqlite3_libversion(); - } - - bool transaction(const std::function& f) { - auto guard = this->transaction_guard(); - return guard.commit_on_destroy = f(); - } - - std::string current_time() { - auto con = this->get_connection(); - return this->current_time(con.get()); - } - - std::string current_date() { - auto con = this->get_connection(); - return this->current_date(con.get()); - } - - std::string current_timestamp() { - auto con = this->get_connection(); - return this->current_timestamp(con.get()); - } - -#if SQLITE_VERSION_NUMBER >= 3007010 - /** - * \fn db_release_memory - * \brief Releases freeable memory of database. It is function can/should be called periodically by - * application, if application has less memory usage constraint. \note sqlite3_db_release_memory added - * in 3.7.10 https://sqlite.org/changes.html - */ - int db_release_memory() { - auto con = this->get_connection(); - return sqlite3_db_release_memory(con.get()); - } -#endif - - /** - * Returns existing permanent table names in database. Doesn't check storage itself - works only with - * actual database. - * @return Returns list of tables in database. - */ - std::vector table_names() { - auto con = this->get_connection(); - std::vector tableNames; - using data_t = std::vector; - perform_exec( - con.get(), - "SELECT name FROM sqlite_master WHERE type='table'", - [](void* data, int argc, char** argv, char** /*columnName*/) -> int { - auto& tableNames_ = *(data_t*)data; - for (int i = 0; i < argc; ++i) { - if (argv[i]) { - tableNames_.emplace_back(argv[i]); - } - } - return 0; - }, - &tableNames); - tableNames.shrink_to_fit(); - return tableNames; - } - - /** - * Call it once during storage lifetime to make it keeping its connection opened till dtor call. - * By default if storage is not in-memory it calls `sqlite3_open` only when the connection is really - * needed and closes when it is not needed. This function breaks this rule. In memory storage always - * keeps connection opened so calling this for in-memory storage changes nothing. - * Note about multithreading: in multithreading context avoiding using this function for not in-memory - * storage may lead to data races. If you have data races in such a configuration try to call `open_forever` - * before accessing your storage - it may fix data races. - */ - void open_forever() { - this->isOpenedForever = true; - this->connection->retain(); - if (1 == this->connection->retain_count()) { - this->on_open_internal(this->connection->get()); - } - } - - /** - * Create an application-defined scalar SQL function. - * Can be called at any time no matter whether the database connection is opened or not. - * - * Note: `create_scalar_function()` merely creates a closure to generate an instance of the scalar function object, - * together with a copy of the passed initialization arguments. - * If `F` is a stateless function object, an instance of the function object is created once, otherwise - * an instance of the function object is repeatedly recreated for each result row, - * ensuring that the calculations always start with freshly initialized values. - * - * T - function class. T must have operator() overload and static name function like this: - * ``` - * struct SqrtFunction { - * - * double operator()(double arg) const { - * return std::sqrt(arg); - * } - * - * static const char *name() { - * return "SQRT"; - * } - * }; - * ``` - */ - template - void create_scalar_function(Args&&... constructorArgs) { - static_assert(is_scalar_udf_v, "F must be a scalar function"); - - this->create_scalar_function_impl( - udf_holder{}, -#ifdef SQLITE_ORM_PACK_EXPANSION_IN_INIT_CAPTURE_SUPPORTED - /* constructAt */ [... constructorArgs = std::move(constructorArgs)](void* location) { -#else - /* constructAt */ - [constructorArgs...](void* location) { -#endif - std::allocator allocator; - using traits = std::allocator_traits; - traits::construct(allocator, (F*)location, constructorArgs...); - }); - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create an application-defined scalar function. - * Can be called at any time no matter whether the database connection is opened or not. - * - * Note: `create_scalar_function()` merely creates a closure to generate an instance of the scalar function object, - * together with a copy of the passed initialization arguments. - * If `F` is a stateless function object, an instance of the function object is created once, otherwise - * an instance of the function object is repeatedly recreated for each result row, - * ensuring that the calculations always start with freshly initialized values. - */ - template - void create_scalar_function(Args&&... constructorArgs) { - return this->create_scalar_function>(std::forward(constructorArgs)...); - } - - /** - * Create an application-defined scalar function. - * Can be called at any time no matter whether the database connection is opened or not. - * - * If `quotedF` contains a freestanding function, stateless lambda or stateless function object, - * `quoted_scalar_function::callable()` uses the original function object, assuming it is free of side effects; - * otherwise, it repeatedly uses a copy of the contained function object, assuming possible side effects. - */ - template - void create_scalar_function() { - using Sig = auto_udf_type_t; - using args_tuple = typename callable_arguments::args_tuple; - using return_type = typename callable_arguments::return_type; - constexpr auto argsCount = std::is_same>::value - ? -1 - : int(std::tuple_size::value); - this->scalarFunctions.emplace_back( - std::string{quotedF.name()}, - argsCount, - /* constructAt = */ - nullptr, - /* destroy = */ - nullptr, - /* call = */ - [](sqlite3_context* context, int argsCount, sqlite3_value** values) { - proxy_assert_args_count(context, argsCount); - args_tuple argsTuple = tuple_from_values{}(values, argsCount); - auto result = polyfill::apply(quotedF.callable(), std::move(argsTuple)); - statement_binder().result(context, result); - }, - /* finalCall = */ - nullptr, - std::pair{nullptr, null_xdestroy_f}); - - if (this->connection->retain_count() > 0) { - sqlite3* db = this->connection->get(); - try_to_create_scalar_function(db, this->scalarFunctions.back()); - } - } -#endif - - /** - * Create an application-defined aggregate SQL function. - * Can be called at any time no matter whether the database connection is opened or not. - * - * Note: `create_aggregate_function()` merely creates a closure to generate an instance of the aggregate function object, - * together with a copy of the passed initialization arguments. - * An instance of the function object is repeatedly recreated for each result row, - * ensuring that the calculations always start with freshly initialized values. - * - * T - function class. T must have step member function, fin member function and static name function like this: - * ``` - * struct MeanFunction { - * double total = 0; - * int count = 0; - * - * void step(double value) { - * total += value; - * ++count; - * } - * - * int fin() const { - * return total / count; - * } - * - * static std::string name() { - * return "MEAN"; - * } - * }; - * ``` - */ - template - void create_aggregate_function(Args&&... constructorArgs) { - static_assert(is_aggregate_udf_v, "F must be an aggregate function"); - - this->create_aggregate_function_impl( - udf_holder{}, /* constructAt = */ -#ifdef SQLITE_ORM_PACK_EXPANSION_IN_INIT_CAPTURE_SUPPORTED - /* constructAt */ [... constructorArgs = std::move(constructorArgs)](void* location) { -#else - /* constructAt */ - [constructorArgs...](void* location) { -#endif - std::allocator allocator; - using traits = std::allocator_traits; - traits::construct(allocator, (F*)location, constructorArgs...); - }); - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Create an application-defined aggregate function. - * Can be called at any time no matter whether the database connection is opened or not. - * - * Note: `create_aggregate_function()` merely creates a closure to generate an instance of the aggregate function object, - * together with a copy of the passed initialization arguments. - * An instance of the function object is repeatedly recreated for each result row, - * ensuring that the calculations always start with freshly initialized values. - */ - template - void create_aggregate_function(Args&&... constructorArgs) { - return this->create_aggregate_function>(std::forward(constructorArgs)...); - } -#endif - - /** - * Delete a scalar function you created before. - * Can be called at any time no matter whether the database connection is open or not. - */ - template - void delete_scalar_function() { - static_assert(is_scalar_udf_v, "F must be a scalar function"); - udf_holder udfName; - this->delete_function_impl(udfName(), this->scalarFunctions); - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - /** - * Delete a scalar function you created before. - * Can be called at any time no matter whether the database connection is open or not. - */ - template - void delete_scalar_function() { - this->delete_function_impl(f.name(), this->scalarFunctions); - } - - /** - * Delete a quoted scalar function you created before. - * Can be called at any time no matter whether the database connection is open or not. - */ - template - void delete_scalar_function() { - this->delete_function_impl(quotedF.name(), this->scalarFunctions); - } -#endif - - /** - * Delete aggregate function you created before. - * Can be called at any time no matter whether the database connection is open or not. - */ - template - void delete_aggregate_function() { - static_assert(is_aggregate_udf_v, "F must be an aggregate function"); - udf_holder udfName; - this->delete_function_impl(udfName(), this->aggregateFunctions); - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - void delete_aggregate_function() { - this->delete_function_impl(f.name(), this->aggregateFunctions); - } -#endif - - template - void create_collation() { - collating_function func = [](int leftLength, const void* lhs, int rightLength, const void* rhs) { - C collatingObject; - return collatingObject(leftLength, lhs, rightLength, rhs); - }; - std::stringstream ss; - ss << C::name() << std::flush; - this->create_collation(ss.str(), std::move(func)); - } - - void create_collation(const std::string& name, collating_function f) { - const auto functionExists = bool(f); - collating_function* function = nullptr; - if (functionExists) { - function = &(collatingFunctions[name] = std::move(f)); - } - - // create collations if db is open - if (this->connection->retain_count() > 0) { - sqlite3* db = this->connection->get(); - int rc = sqlite3_create_collation(db, - name.c_str(), - SQLITE_UTF8, - function, - functionExists ? collate_callback : nullptr); - if (rc != SQLITE_OK) { - throw_translated_sqlite_error(db); - } - } - - if (!functionExists) { - collatingFunctions.erase(name); - } - } - - template - void delete_collation() { - std::stringstream ss; - ss << C::name() << std::flush; - this->create_collation(ss.str(), {}); - } - - void begin_transaction() { - this->begin_transaction_internal("BEGIN TRANSACTION"); - } - - void begin_deferred_transaction() { - this->begin_transaction_internal("BEGIN DEFERRED TRANSACTION"); - } - - void begin_immediate_transaction() { - this->begin_transaction_internal("BEGIN IMMEDIATE TRANSACTION"); - } - - void begin_exclusive_transaction() { - this->begin_transaction_internal("BEGIN EXCLUSIVE TRANSACTION"); - } - - void commit() { - sqlite3* db = this->connection->get(); - perform_void_exec(db, "COMMIT"); - this->connection->release(); - if (this->connection->retain_count() < 0) { - throw std::system_error{orm_error_code::no_active_transaction}; - } - } - - void rollback() { - sqlite3* db = this->connection->get(); - perform_void_exec(db, "ROLLBACK"); - this->connection->release(); - if (this->connection->retain_count() < 0) { - throw std::system_error{orm_error_code::no_active_transaction}; - } - } - - void backup_to(const std::string& filename) { - auto backup = this->make_backup_to(filename); - backup.step(-1); - } - - void backup_to(storage_base& other) { - auto backup = this->make_backup_to(other); - backup.step(-1); - } - - void backup_from(const std::string& filename) { - auto backup = this->make_backup_from(filename); - backup.step(-1); - } - - void backup_from(storage_base& other) { - auto backup = this->make_backup_from(other); - backup.step(-1); - } - - backup_t make_backup_to(const std::string& filename) { - auto holder = std::make_unique(filename); - connection_ref conRef{*holder}; - return {conRef, "main", this->get_connection(), "main", std::move(holder)}; - } - - backup_t make_backup_to(storage_base& other) { - return {other.get_connection(), "main", this->get_connection(), "main", {}}; - } - - backup_t make_backup_from(const std::string& filename) { - auto holder = std::make_unique(filename); - connection_ref conRef{*holder}; - return {this->get_connection(), "main", conRef, "main", std::move(holder)}; - } - - backup_t make_backup_from(storage_base& other) { - return {this->get_connection(), "main", other.get_connection(), "main", {}}; - } - - const std::string& filename() const { - return this->connection->filename; - } - - /** - * Checks whether connection to database is opened right now. - * Returns always `true` for in memory databases. - */ - bool is_opened() const { - return this->connection->retain_count() > 0; - } - - /* - * returning false when there is a transaction in place - * otherwise true; function is not const because it has to call get_connection() - */ - bool get_autocommit() { - auto con = this->get_connection(); - return sqlite3_get_autocommit(con.get()); - } - - int busy_handler(std::function handler) { - _busy_handler = std::move(handler); - if (this->is_opened()) { - if (_busy_handler) { - return sqlite3_busy_handler(this->connection->get(), busy_handler_callback, this); - } else { - return sqlite3_busy_handler(this->connection->get(), nullptr, nullptr); - } - } else { - return SQLITE_OK; - } - } - - protected: - storage_base(std::string filename, int foreignKeysCount) : - pragma(std::bind(&storage_base::get_connection, this)), - limit(std::bind(&storage_base::get_connection, this)), - inMemory(filename.empty() || filename == ":memory:"), - connection(std::make_unique(std::move(filename))), - cachedForeignKeysCount(foreignKeysCount) { - if (this->inMemory) { - this->connection->retain(); - this->on_open_internal(this->connection->get()); - } - } - - storage_base(const storage_base& other) : - on_open(other.on_open), pragma(std::bind(&storage_base::get_connection, this)), - limit(std::bind(&storage_base::get_connection, this)), inMemory(other.inMemory), - connection(std::make_unique(other.connection->filename)), - cachedForeignKeysCount(other.cachedForeignKeysCount) { - if (this->inMemory) { - this->connection->retain(); - this->on_open_internal(this->connection->get()); - } - } - - ~storage_base() { - if (this->isOpenedForever) { - this->connection->release(); - } - if (this->inMemory) { - this->connection->release(); - } - } - - void begin_transaction_internal(const std::string& query) { - this->connection->retain(); - if (1 == this->connection->retain_count()) { - this->on_open_internal(this->connection->get()); - } - sqlite3* db = this->connection->get(); - perform_void_exec(db, query); - } - - connection_ref get_connection() { - connection_ref res{*this->connection}; - if (1 == this->connection->retain_count()) { - this->on_open_internal(this->connection->get()); - } - return res; - } - -#if SQLITE_VERSION_NUMBER >= 3006019 - void foreign_keys(sqlite3* db, bool value) { - std::stringstream ss; - ss << "PRAGMA foreign_keys = " << value << std::flush; - perform_void_exec(db, ss.str()); - } - - bool foreign_keys(sqlite3* db) { - bool result = false; - perform_exec(db, "PRAGMA foreign_keys", extract_single_value, &result); - return result; - } - -#endif - void on_open_internal(sqlite3* db) { - -#if SQLITE_VERSION_NUMBER >= 3006019 - if (this->cachedForeignKeysCount) { - this->foreign_keys(db, true); - } -#endif - if (this->pragma.synchronous_ != -1) { - this->pragma.synchronous(this->pragma.synchronous_); - } - - if (this->pragma.journal_mode_ != -1) { - this->pragma.set_pragma("journal_mode", static_cast(this->pragma.journal_mode_), db); - } - - for (auto& p: this->collatingFunctions) { - int rc = sqlite3_create_collation(db, p.first.c_str(), SQLITE_UTF8, &p.second, collate_callback); - if (rc != SQLITE_OK) { - throw_translated_sqlite_error(db); - } - } - - for (auto& p: this->limit.limits) { - sqlite3_limit(db, p.first, p.second); - } - - if (_busy_handler) { - sqlite3_busy_handler(this->connection->get(), busy_handler_callback, this); - } - - for (auto& udfProxy: this->scalarFunctions) { - try_to_create_scalar_function(db, udfProxy); - } - - for (auto& udfProxy: this->aggregateFunctions) { - try_to_create_aggregate_function(db, udfProxy); - } - - if (this->on_open) { - this->on_open(db); - } - } - - template - void create_scalar_function_impl(udf_holder udfName, std::function constructAt) { - using args_tuple = typename callable_arguments::args_tuple; - using return_type = typename callable_arguments::return_type; - constexpr auto argsCount = std::is_same>::value - ? -1 - : int(std::tuple_size::value); - using is_stateless = std::is_empty; - auto udfMemorySpace = preallocate_udf_memory(); - if SQLITE_ORM_CONSTEXPR_IF (is_stateless::value) { - constructAt(udfMemorySpace.first); - } - this->scalarFunctions.emplace_back( - udfName(), - argsCount, - is_stateless::value ? nullptr : std::move(constructAt), - /* destroy = */ - obtain_xdestroy_for(udf_destruct_only_deleter{}), - /* call = */ - [](sqlite3_context* context, int argsCount, sqlite3_value** values) { - auto udfPointer = proxy_get_scalar_udf(is_stateless{}, context, argsCount); - args_tuple argsTuple = tuple_from_values{}(values, argsCount); - auto result = polyfill::apply(*udfPointer, std::move(argsTuple)); - statement_binder().result(context, result); - }, - udfMemorySpace); - - if (this->connection->retain_count() > 0) { - sqlite3* db = this->connection->get(); - try_to_create_scalar_function(db, this->scalarFunctions.back()); - } - } - - template - void create_aggregate_function_impl(udf_holder udfName, - std::function constructAt) { - using args_tuple = typename callable_arguments::args_tuple; - using return_type = typename callable_arguments::return_type; - constexpr auto argsCount = std::is_same>::value - ? -1 - : int(std::tuple_size::value); - this->aggregateFunctions.emplace_back( - udfName(), - argsCount, - std::move(constructAt), - /* destroy = */ - obtain_xdestroy_for(udf_destruct_only_deleter{}), - /* step = */ - [](sqlite3_context* context, int argsCount, sqlite3_value** values) { - F* udfPointer; - try { - udfPointer = proxy_get_aggregate_step_udf(context, argsCount); - } catch (const std::bad_alloc&) { - sqlite3_result_error_nomem(context); - return; - } - args_tuple argsTuple = tuple_from_values{}(values, argsCount); -#if __cpp_lib_bind_front >= 201907L - std::apply(std::bind_front(&F::step, udfPointer), std::move(argsTuple)); -#else - polyfill::apply( - [udfPointer](auto&&... args) { - udfPointer->step(std::forward(args)...); - }, - std::move(argsTuple)); -#endif - }, - /* finalCall = */ - [](void* udfHandle, sqlite3_context* context) { - F& udf = *static_cast(udfHandle); - auto result = udf.fin(); - statement_binder().result(context, result); - }, - obtain_udf_allocator()); - - if (this->connection->retain_count() > 0) { - sqlite3* db = this->connection->get(); - try_to_create_aggregate_function(db, this->aggregateFunctions.back()); - } - } - - void delete_function_impl(const std::string& name, std::list& functions) const { -#if __cpp_lib_ranges >= 201911L - auto it = std::ranges::find(functions, name, &udf_proxy::name); -#else - auto it = std::find_if(functions.begin(), functions.end(), [&name](auto& udfProxy) { - return udfProxy.name == name; - }); -#endif - if (it != functions.end()) { - if (this->connection->retain_count() > 0) { - sqlite3* db = this->connection->get(); - int rc = sqlite3_create_function_v2(db, - name.c_str(), - it->argumentsCount, - SQLITE_UTF8, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr); - if (rc != SQLITE_OK) { - throw_translated_sqlite_error(db); - } - } - it = functions.erase(it); - } else { - throw std::system_error{orm_error_code::function_not_found}; - } - } - - static void try_to_create_scalar_function(sqlite3* db, udf_proxy& udfProxy) { - int rc = sqlite3_create_function_v2(db, - udfProxy.name.c_str(), - udfProxy.argumentsCount, - SQLITE_UTF8, - &udfProxy, - udfProxy.func, - nullptr, - nullptr, - nullptr); - if (rc != SQLITE_OK) { - throw_translated_sqlite_error(db); - } - } - - static void try_to_create_aggregate_function(sqlite3* db, udf_proxy& udfProxy) { - int rc = sqlite3_create_function(db, - udfProxy.name.c_str(), - udfProxy.argumentsCount, - SQLITE_UTF8, - &udfProxy, - nullptr, - udfProxy.func, - aggregate_function_final_callback); - if (rc != SQLITE_OK) { - throw_translated_sqlite_error(rc); - } - } - - std::string current_time(sqlite3* db) { - std::string result; - perform_exec(db, "SELECT CURRENT_TIME", extract_single_value, &result); - return result; - } - - std::string current_date(sqlite3* db) { - std::string result; - perform_exec(db, "SELECT CURRENT_DATE", extract_single_value, &result); - return result; - } - - std::string current_timestamp(sqlite3* db) { - std::string result; - perform_exec(db, "SELECT CURRENT_TIMESTAMP", extract_single_value, &result); - return result; - } - - void drop_table_internal(sqlite3* db, const std::string& tableName, bool ifExists) { - std::stringstream ss; - ss << "DROP TABLE"; - if (ifExists) { - ss << " IF EXISTS"; - } - ss << ' ' << streaming_identifier(tableName) << std::flush; - perform_void_exec(db, ss.str()); - } - - void drop_index_internal(const std::string& indexName, bool ifExists) { - std::stringstream ss; - ss << "DROP INDEX"; - if (ifExists) { - ss << " IF EXISTS"; - } - ss << ' ' << quote_identifier(indexName) << std::flush; - perform_void_exec(this->get_connection().get(), ss.str()); - } - - void drop_trigger_internal(const std::string& triggerName, bool ifExists) { - std::stringstream ss; - ss << "DROP TRIGGER"; - if (ifExists) { - ss << " IF EXISTS"; - } - ss << ' ' << quote_identifier(triggerName) << std::flush; - perform_void_exec(this->get_connection().get(), ss.str()); - } - - static int - collate_callback(void* argument, int leftLength, const void* lhs, int rightLength, const void* rhs) { - auto& function = *(collating_function*)argument; - return function(leftLength, lhs, rightLength, rhs); - } - - static int busy_handler_callback(void* selfPointer, int triesCount) { - auto& storage = *static_cast(selfPointer); - if (storage._busy_handler) { - return storage._busy_handler(triesCount); - } else { - return 0; - } - } - - bool calculate_remove_add_columns(std::vector& columnsToAdd, - std::vector& storageTableInfo, - std::vector& dbTableInfo) const { - bool notEqual = false; - - // iterate through storage columns - for (size_t storageColumnInfoIndex = 0; storageColumnInfoIndex < storageTableInfo.size(); - ++storageColumnInfoIndex) { - - // get storage's column info - table_xinfo& storageColumnInfo = storageTableInfo[storageColumnInfoIndex]; - const std::string& columnName = storageColumnInfo.name; - - // search for a column in db with the same name -#if __cpp_lib_ranges >= 201911L - auto dbColumnInfoIt = std::ranges::find(dbTableInfo, columnName, &table_xinfo::name); -#else - auto dbColumnInfoIt = std::find_if(dbTableInfo.begin(), dbTableInfo.end(), [&columnName](auto& ti) { - return ti.name == columnName; - }); -#endif - if (dbColumnInfoIt != dbTableInfo.end()) { - auto& dbColumnInfo = *dbColumnInfoIt; - auto columnsAreEqual = - dbColumnInfo.name == storageColumnInfo.name && - dbColumnInfo.notnull == storageColumnInfo.notnull && - (!dbColumnInfo.dflt_value.empty()) == (!storageColumnInfo.dflt_value.empty()) && - dbColumnInfo.pk == storageColumnInfo.pk && - (dbColumnInfo.hidden == 0) == (storageColumnInfo.hidden == 0); - if (!columnsAreEqual) { - notEqual = true; - break; - } - dbTableInfo.erase(dbColumnInfoIt); - storageTableInfo.erase(storageTableInfo.begin() + - static_cast(storageColumnInfoIndex)); - --storageColumnInfoIndex; - } else { - columnsToAdd.push_back(&storageColumnInfo); - } - } - return notEqual; - } - - const bool inMemory; - bool isOpenedForever = false; - std::unique_ptr connection; - std::map collatingFunctions; - const int cachedForeignKeysCount; - std::function _busy_handler; - std::list scalarFunctions; - std::list aggregateFunctions; - }; - } -} - -// #include "prepared_statement.h" - -// #include "expression_object_type.h" - -#include // std::decay, std::remove_reference -#include // std::reference_wrapper - -// #include "type_traits.h" - -// #include "prepared_statement.h" - -namespace sqlite_orm { - - namespace internal { - - template - struct expression_object_type; - - template - using expression_object_type_t = typename expression_object_type::type; - - template - using statement_object_type_t = expression_object_type_t>>; - - template - struct expression_object_type, void> : value_unref_type {}; - - template - struct expression_object_type, void> : value_unref_type {}; - - template - struct expression_object_type> { - using type = object_type_t; - }; - - template - struct expression_object_type, void> : value_unref_type {}; - - template - struct expression_object_type, void> : value_unref_type {}; - - template - struct expression_object_type> { - using type = object_type_t; - }; - - template - struct expression_object_type, void> : value_unref_type {}; - - template - struct get_ref_t { - - template - auto& operator()(O& t) const { - return t; - } - }; - - template - struct get_ref_t> { - - template - auto& operator()(O& t) const { - return t.get(); - } - }; - - template - auto& get_ref(T& t) { - using arg_type = std::decay_t; - get_ref_t g; - return g(t); - } - - template - struct get_object_t; - - template - struct get_object_t : get_object_t {}; - - template - auto& get_object(T& t) { - using expression_type = std::decay_t; - get_object_t obj; - return obj(t); - } - - template - struct get_object_t> { - using expression_type = replace_t; - - template - auto& operator()(O& e) const { - return get_ref(e.object); - } - }; - - template - struct get_object_t> { - using expression_type = insert_t; - - template - auto& operator()(O& e) const { - return get_ref(e.object); - } - }; - - template - struct get_object_t> { - using expression_type = update_t; - - template - auto& operator()(O& e) const { - return get_ref(e.object); - } - }; - } -} - -// #include "statement_serializer.h" - -#include // std::enable_if, std::remove_pointer, std::remove_reference, std::remove_cvref, std::disjunction -#include // std::stringstream -#include // std::string -#include // std::vector -#ifndef SQLITE_ORM_OMITS_CODECVT -#include // std::wstring_convert -#include // std::codecvt_utf8_utf16 -#endif -#include -#include -#include // std::list -// #include "functional/cxx_string_view.h" - -// #include "functional/cxx_optional.h" - -// #include "functional/cxx_type_traits_polyfill.h" -// std::remove_cvref, std::disjunction -// #include "functional/cxx_functional_polyfill.h" -// std::identity, std::invoke -// #include "functional/mpl.h" - -// #include "tuple_helper/tuple_filter.h" - -// #include "ast/upsert_clause.h" - -// #include "ast/excluded.h" - -// #include "ast/group_by.h" - -// #include "ast/into.h" - -// #include "ast/match.h" - -// #include "ast/rank.h" - -namespace sqlite_orm { - namespace internal { - struct rank_t {}; - } - - inline internal::rank_t rank() { - return {}; - } -} - -// #include "ast/special_keywords.h" - -// #include "core_functions.h" - -// #include "constraints.h" - -// #include "conditions.h" - -// #include "indexed_column.h" - -// #include "function.h" - -// #include "prepared_statement.h" - -// #include "rowid.h" - -// #include "pointer_value.h" - -// #include "type_printer.h" - -// #include "field_printer.h" - -// #include "literal.h" - -// #include "expression.h" - -// #include "table_name_collector.h" - -// #include "column_names_getter.h" - -#include // std::is_base_of -#include // std::string -#include // std::vector -#include // std::reference_wrapper -#include -#include // std::move - -// #include "tuple_helper/tuple_traits.h" - -// #include "tuple_helper/tuple_iteration.h" - -// #include "error_code.h" - -// #include "mapped_type_proxy.h" - -// #include "alias_traits.h" - -// #include "select_constraints.h" - -// #include "storage_lookup.h" -// pick_table -// #include "serializer_context.h" - -// #include "util.h" - -namespace sqlite_orm { - - namespace internal { - - template - auto serialize(const T& t, const Ctx& context); - - template - std::vector& collect_table_column_names(std::vector& collectedExpressions, - bool definedOrder, - const Ctx& context) { - if (definedOrder) { - auto& table = pick_table>(context.db_objects); - collectedExpressions.reserve(collectedExpressions.size() + table.template count_of()); - table.for_each_column([qualified = !context.skip_table_name, - &tableName = table.name, - &collectedExpressions](const column_identifier& column) { - if (is_alias::value) { - collectedExpressions.push_back(quote_identifier(alias_extractor::extract()) + "." + - quote_identifier(column.name)); - } else if (qualified) { - collectedExpressions.push_back(quote_identifier(tableName) + "." + - quote_identifier(column.name)); - } else { - collectedExpressions.push_back(quote_identifier(column.name)); - } - }); - } else { - collectedExpressions.reserve(collectedExpressions.size() + 1); - if (is_alias::value) { - collectedExpressions.push_back(quote_identifier(alias_extractor::extract()) + ".*"); - } else if (!context.skip_table_name) { - const basic_table& table = pick_table>(context.db_objects); - collectedExpressions.push_back(quote_identifier(table.name) + ".*"); - } else { - collectedExpressions.emplace_back("*"); - } - } - - return collectedExpressions; - } - - /** @short Column expression collector. - */ - struct column_names_getter { - /** - * The default implementation simply serializes the passed argument. - */ - template - std::vector& operator()(const E& t, const Ctx& context) { - auto columnExpression = serialize(t, context); - if (columnExpression.empty()) { - throw std::system_error{orm_error_code::column_not_found}; - } - this->collectedExpressions.reserve(this->collectedExpressions.size() + 1); - this->collectedExpressions.push_back(std::move(columnExpression)); - return this->collectedExpressions; - } - - template - std::vector& operator()(const std::reference_wrapper& expression, const Ctx& context) { - return (*this)(expression.get(), context); - } - - template - std::vector& operator()(const asterisk_t& expression, const Ctx& context) { - return collect_table_column_names(this->collectedExpressions, expression.defined_order, context); - } - - template - std::vector& operator()(const object_t& expression, const Ctx& context) { - return collect_table_column_names(this->collectedExpressions, expression.defined_order, context); - } - - template - std::vector& operator()(const columns_t& cols, const Ctx& context) { - this->collectedExpressions.reserve(this->collectedExpressions.size() + cols.count); - iterate_tuple(cols.columns, [this, &context](auto& colExpr) { - (*this)(colExpr, context); - }); - // note: `capacity() > size()` can occur in case `asterisk_t<>` does spell out the columns in defined order - if (tuple_has_template::columns_type, asterisk_t>::value && - this->collectedExpressions.capacity() > this->collectedExpressions.size()) { - this->collectedExpressions.shrink_to_fit(); - } - return this->collectedExpressions; - } - - template - std::vector& operator()(const struct_t& cols, const Ctx& context) { - this->collectedExpressions.reserve(this->collectedExpressions.size() + cols.count); - iterate_tuple(cols.columns, [this, &context](auto& colExpr) { - (*this)(colExpr, context); - }); - // note: `capacity() > size()` can occur in case `asterisk_t<>` does spell out the columns in defined order - if (tuple_has_template::columns_type, asterisk_t>::value && - this->collectedExpressions.capacity() > this->collectedExpressions.size()) { - this->collectedExpressions.shrink_to_fit(); - } - return this->collectedExpressions; - } - - std::vector collectedExpressions; - }; - - template - std::vector get_column_names(const T& expression, const Ctx& context) { - column_names_getter serializer; - return serializer(access_column_expression(expression), context); - } - } -} - -// #include "cte_column_names_collector.h" - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -#include -#include -#include // std::reference_wrapper -#include -#endif - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "type_traits.h" - -// #include "member_traits/member_traits.h" - -// #include "error_code.h" - -// #include "alias.h" - -// #include "select_constraints.h" - -// #include "serializer_context.h" - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -namespace sqlite_orm { - namespace internal { - // collecting column names utilizes the statement serializer - template - auto serialize(const T& t, const Ctx& context); - - inline void unquote_identifier(std::string& identifier) { - if (!identifier.empty()) { - constexpr char quoteChar = '"'; - constexpr char sqlEscaped[] = {quoteChar, quoteChar}; - identifier.erase(identifier.end() - 1); - identifier.erase(identifier.begin()); - for (size_t pos = 0; (pos = identifier.find(sqlEscaped, pos, 2)) != identifier.npos; ++pos) { - identifier.erase(pos, 1); - } - } - } - - inline void unquote_or_erase(std::string& name) { - constexpr char quoteChar = '"'; - if (name.front() == quoteChar) { - unquote_identifier(name); - } else { - // unaliased expression - see 3. below - name.clear(); - } - } - - template - struct cte_column_names_collector { - using expression_type = T; - - // Compound statements are never passed in by db_objects_for_expression() - static_assert(!is_compound_operator_v); - - template - std::vector operator()(const expression_type& t, const Ctx& context) const { - auto newContext = context; - newContext.skip_table_name = true; - std::string columnName = serialize(t, newContext); - if (columnName.empty()) { - throw std::system_error{orm_error_code::column_not_found}; - } - unquote_or_erase(columnName); - return {std::move(columnName)}; - } - }; - - template - std::vector get_cte_column_names(const T& t, const Ctx& context) { - cte_column_names_collector collector; - return collector(access_column_expression(t), context); - } - - template - struct cte_column_names_collector> { - using expression_type = As; - - template - std::vector operator()(const expression_type& /*expression*/, const Ctx& /*context*/) const { - return {alias_extractor>::extract()}; - } - }; - - template - struct cte_column_names_collector> { - using expression_type = Wrapper; - - template - std::vector operator()(const expression_type& expression, const Ctx& context) const { - return get_cte_column_names(expression.get(), context); - } - }; - - template - struct cte_column_names_collector> { - using expression_type = Asterisk; - using T = typename Asterisk::type; - - template - std::vector operator()(const expression_type&, const Ctx& context) const { - auto& table = pick_table(context.db_objects); - - std::vector columnNames; - columnNames.reserve(size_t(table.template count_of())); - - table.for_each_column([&columnNames](const column_identifier& column) { - columnNames.push_back(column.name); - }); - return columnNames; - } - }; - - // No CTE for object expressions. - template - struct cte_column_names_collector> { - static_assert(polyfill::always_false_v, "Selecting an object in a subselect is not allowed."); - }; - - // No CTE for object expressions. - template - struct cte_column_names_collector> { - static_assert(polyfill::always_false_v, "Repacking columns in a subselect is not allowed."); - }; - - template - struct cte_column_names_collector> { - using expression_type = Columns; - - template - std::vector operator()(const expression_type& cols, const Ctx& context) const { - std::vector columnNames; - columnNames.reserve(size_t(cols.count)); - auto newContext = context; - newContext.skip_table_name = true; - iterate_tuple(cols.columns, [&columnNames, &newContext](auto& m) { - using value_type = polyfill::remove_cvref_t; - - if constexpr (polyfill::is_specialization_of_v) { - columnNames.push_back(alias_extractor>::extract()); - } else { - std::string columnName = serialize(m, newContext); - if (!columnName.empty()) { - columnNames.push_back(std::move(columnName)); - } else { - throw std::system_error{orm_error_code::column_not_found}; - } - unquote_or_erase(columnNames.back()); - } - }); - return columnNames; - } - }; - - template = true> - std::vector - collect_cte_column_names(const E& sel, const ExplicitColRefs& explicitColRefs, const Ctx& context) { - // 1. determine column names from subselect - std::vector columnNames = get_cte_column_names(sel.col, context); - - // 2. override column names from cte expression - if (size_t n = std::tuple_size_v) { - if (n != columnNames.size()) { - throw std::system_error{orm_error_code::column_not_found}; - } - - size_t idx = 0; - iterate_tuple(explicitColRefs, [&idx, &columnNames, &context](auto& colRef) { - using ColRef = polyfill::remove_cvref_t; - - if constexpr (polyfill::is_specialization_of_v) { - columnNames[idx] = alias_extractor>::extract(); - } else if constexpr (std::is_member_pointer::value) { - using O = table_type_of_t; - if (auto* columnName = find_column_name(context.db_objects, colRef)) { - columnNames[idx] = *columnName; - } else { - // relaxed: allow any member pointer as column reference - columnNames[idx] = typeid(ColRef).name(); - } - } else if constexpr (polyfill::is_specialization_of_v) { - columnNames[idx] = colRef.name; - } else if constexpr (std::is_same_v) { - if (!colRef.empty()) { - columnNames[idx] = colRef; - } - } else if constexpr (std::is_same_v>) { - if (columnNames[idx].empty()) { - columnNames[idx] = std::to_string(idx + 1); - } - } else { - static_assert(polyfill::always_false_v, "Invalid explicit column reference specified"); - } - ++idx; - }); - } - - // 3. fill in blanks with numerical column identifiers - { - for (size_t i = 0, n = columnNames.size(); i < n; ++i) { - if (columnNames[i].empty()) { - columnNames[i] = std::to_string(i + 1); - } - } - } - - return columnNames; - } - } -} -#endif - -// #include "order_by_serializer.h" - -#include // std::string -#include // std::stringstream - -namespace sqlite_orm { - - namespace internal { - - template - struct order_by_serializer; - - template - std::string serialize_order_by(const T& t, const Ctx& context) { - order_by_serializer serializer; - return serializer(t, context); - } - - template - struct order_by_serializer, void> { - using statement_type = order_by_t; - - template - std::string operator()(const statement_type& orderBy, const Ctx& context) const { - std::stringstream ss; - auto newContext = context; - newContext.skip_table_name = false; - - ss << serialize(orderBy.expression, newContext); - if (!orderBy._collate_argument.empty()) { - ss << " COLLATE " << orderBy._collate_argument; - } - switch (orderBy.asc_desc) { - case 1: - ss << " ASC"; - break; - case -1: - ss << " DESC"; - break; - } - return ss.str(); - } - }; - - template - struct order_by_serializer, void> { - using statement_type = dynamic_order_by_t; - - template - std::string operator()(const statement_type& orderBy, const Ctx&) const { - std::stringstream ss; - ss << static_cast(orderBy) << " "; - int index = 0; - for (const dynamic_order_by_entry_t& entry: orderBy) { - if (index > 0) { - ss << ", "; - } - - ss << entry.name; - if (!entry._collate_argument.empty()) { - ss << " COLLATE " << entry._collate_argument; - } - switch (entry.asc_desc) { - case 1: - ss << " ASC"; - break; - case -1: - ss << " DESC"; - break; - } - ++index; - }; - return ss.str(); - } - }; - - } -} - -// #include "serializing_util.h" - -// #include "serialize_result_type.h" - -// #include "statement_binder.h" - -// #include "values.h" - -// #include "table_type_of.h" - -// #include "util.h" - -// #include "error_code.h" - -// #include "schema/triggers.h" - -#include -#include -#include -#include - -// #include "../optional_container.h" - -// NOTE Idea : Maybe also implement a custom trigger system to call a c++ callback when a trigger triggers ? -// (Could be implemented with a normal trigger that insert or update an internal table and then retreive -// the event in the C++ code, to call the C++ user callback, with update hooks: https://www.sqlite.org/c3ref/update_hook.html) -// It could be an interesting feature to bring to sqlite_orm that other libraries don't have ? - -namespace sqlite_orm { - namespace internal { - enum class trigger_timing { trigger_before, trigger_after, trigger_instead_of }; - enum class trigger_type { trigger_delete, trigger_insert, trigger_update }; - - /** - * This class is an intermediate SQLite trigger, to be used with - * `make_trigger` to create a full trigger. - * T is the base of the trigger (contains its type, timing and associated table) - * S is the list of trigger statements - */ - template - struct partial_trigger_t { - using statements_type = std::tuple; - - /** - * Base of the trigger (contains its type, timing and associated table) - */ - T base; - /** - * Statements of the triggers (to be executed when the trigger fires) - */ - statements_type statements; - - partial_trigger_t(T trigger_base, S... statements) : - base{std::move(trigger_base)}, statements{std::make_tuple(std::forward(statements)...)} {} - - partial_trigger_t& end() { - return *this; - } - }; - - struct base_trigger { - /** - * Name of the trigger - */ - std::string name; - }; - - /** - * This class represent a SQLite trigger - * T is the base of the trigger (contains its type, timing and associated table) - * S is the list of trigger statments - */ - template - struct trigger_t : base_trigger { - using object_type = void; - using elements_type = typename partial_trigger_t::statements_type; - - /** - * Base of the trigger (contains its type, timing and associated table) - */ - T base; - - /** - * Statements of the triggers (to be executed when the trigger fires) - */ - elements_type elements; - -#ifndef SQLITE_ORM_AGGREGATE_BASES_SUPPORTED - trigger_t(std::string name, T trigger_base, elements_type statements) : - base_trigger{std::move(name)}, base(std::move(trigger_base)), elements(std::move(statements)) {} -#endif - }; - - /** - * Base of a trigger. Contains the trigger type/timming and the table type - * T is the table type - * W is `when` expression type - * Type is the trigger base type (type+timing) - */ - template - struct trigger_base_t { - using table_type = T; - using when_type = W; - using trigger_type_base = Type; - - /** - * Contains the trigger type and timing - */ - trigger_type_base type_base; - /** - * Value used to determine if we execute the trigger on each row or on each statement - * (SQLite doesn't support the FOR EACH STATEMENT syntax yet: https://sqlite.org/lang_createtrigger.html#description - * so this value is more of a placeholder for a later update) - */ - bool do_for_each_row = false; - /** - * When expression (if any) - * If a WHEN expression is specified, the trigger will only execute - * if the expression evaluates to true when the trigger is fired - */ - optional_container container_when; - - trigger_base_t(trigger_type_base type_base_) : type_base(std::move(type_base_)) {} - - trigger_base_t& for_each_row() { - this->do_for_each_row = true; - return *this; - } - - template - trigger_base_t when(WW expression) { - trigger_base_t res(this->type_base); - res.container_when.field = std::move(expression); - return res; - } - - template - partial_trigger_t, S...> begin(S... statements) { - return {*this, std::forward(statements)...}; - } - }; - - /** - * Contains the trigger type and timing - */ - struct trigger_type_base_t { - /** - * Value indicating if the trigger is run BEFORE, AFTER or INSTEAD OF - * the statement that fired it. - */ - trigger_timing timing; - /** - * The type of the statement that would cause the trigger to fire. - * Can be DELETE, INSERT, or UPDATE. - */ - trigger_type type; - - trigger_type_base_t(trigger_timing timing, trigger_type type) : timing(timing), type(type) {} - - template - trigger_base_t on() { - return {*this}; - } - }; - - /** - * Special case for UPDATE OF (columns) - * Contains the trigger type and timing - */ - template - struct trigger_update_type_t : trigger_type_base_t { - using columns_type = std::tuple; - - /** - * Contains the columns the trigger is watching. Will only - * trigger if one of theses columns is updated. - */ - columns_type columns; - - trigger_update_type_t(trigger_timing timing, trigger_type type, Cs... columns) : - trigger_type_base_t(timing, type), columns(std::make_tuple(std::forward(columns)...)) {} - - template - trigger_base_t> on() { - return {*this}; - } - }; - - struct trigger_timing_t { - trigger_timing timing; - - trigger_type_base_t delete_() { - return {timing, trigger_type::trigger_delete}; - } - - trigger_type_base_t insert() { - return {timing, trigger_type::trigger_insert}; - } - - trigger_type_base_t update() { - return {timing, trigger_type::trigger_update}; - } - - template - trigger_update_type_t update_of(Cs... columns) { - return {timing, trigger_type::trigger_update, std::forward(columns)...}; - } - }; - - struct raise_t { - enum class type_t { - ignore, - rollback, - abort, - fail, - }; - - type_t type = type_t::ignore; - std::string message; - -#ifndef SQLITE_ORM_AGGREGATE_NSDMI_SUPPORTED - raise_t(type_t type, std::string message) : type{type}, message{std::move(message)} {} -#endif - }; - - template - struct new_t { - using expression_type = T; - - expression_type expression; - }; - - template - struct old_t { - using expression_type = T; - - expression_type expression; - }; - } // NAMESPACE internal - - /** - * NEW.expression function used within TRIGGER expressions - */ - template - internal::new_t new_(T expression) { - return {std::move(expression)}; - } - - /** - * OLD.expression function used within TRIGGER expressions - */ - template - internal::old_t old(T expression) { - return {std::move(expression)}; - } - - /** - * RAISE(IGNORE) expression used within TRIGGER expressions - */ - inline internal::raise_t raise_ignore() { - return {internal::raise_t::type_t::ignore, {}}; - } - - /** - * RAISE(ROLLBACK, %message%) expression used within TRIGGER expressions - */ - inline internal::raise_t raise_rollback(std::string message) { - return {internal::raise_t::type_t::rollback, std::move(message)}; - } - - /** - * RAISE(ABORT, %message%) expression used within TRIGGER expressions - */ - inline internal::raise_t raise_abort(std::string message) { - return {internal::raise_t::type_t::abort, std::move(message)}; - } - - /** - * RAISE(FAIL, %message%) expression used within TRIGGER expressions - */ - inline internal::raise_t raise_fail(std::string message) { - return {internal::raise_t::type_t::fail, std::move(message)}; - } - - template - internal::trigger_t make_trigger(std::string name, const internal::partial_trigger_t& part) { - SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES( - return {std::move(name), std::move(part.base), std::move(part.statements)}); - } - - inline internal::trigger_timing_t before() { - return {internal::trigger_timing::trigger_before}; - } - - inline internal::trigger_timing_t after() { - return {internal::trigger_timing::trigger_after}; - } - - inline internal::trigger_timing_t instead_of() { - return {internal::trigger_timing::trigger_instead_of}; - } -} - -// #include "schema/column.h" - -// #include "schema/index.h" - -// #include "schema/table.h" - -namespace sqlite_orm { - - namespace internal { - - template - struct statement_serializer; - - template - auto serialize(const T& t, const Ctx& context) { - statement_serializer serializer; - return serializer(t, context); - } - - /** - * Serializer for bindable types. - */ - template - struct statement_serializer> { - using statement_type = T; - - template - std::string operator()(const T& statement, const Ctx& context) const { - if (context.replace_bindable_with_question) { - return "?"; - } else { - return this->do_serialize(statement); - } - } - - private: - template::value && !std::is_base_of::value -#ifndef SQLITE_ORM_OMITS_CODECVT - && !std::is_base_of::value -#endif - , - bool> = true> - std::string do_serialize(const X& c) const { - static_assert(std::is_same::value, ""); - - // implementation detail: utilizing field_printer - return field_printer{}(c); - } - - std::string do_serialize(const std::string& c) const { - // implementation detail: utilizing field_printer - return quote_string_literal(field_printer{}(c)); - } - - std::string do_serialize(const char* c) const { - return quote_string_literal(c); - } -#ifndef SQLITE_ORM_OMITS_CODECVT - std::string do_serialize(const std::wstring& c) const { - // implementation detail: utilizing field_printer - return quote_string_literal(field_printer{}(c)); - } - - std::string do_serialize(const wchar_t* c) const { - std::wstring_convert> converter; - return quote_string_literal(converter.to_bytes(c)); - } -#endif -#ifdef SQLITE_ORM_STRING_VIEW_SUPPORTED - std::string do_serialize(const std::string_view& c) const { - return quote_string_literal(std::string(c)); - } -#ifndef SQLITE_ORM_OMITS_CODECVT - std::string do_serialize(const std::wstring_view& c) const { - std::wstring_convert> converter; - return quote_string_literal(converter.to_bytes(c.data(), c.data() + c.size())); - } -#endif -#endif - /** - * Specialization for binary data (std::vector). - */ - std::string do_serialize(const std::vector& t) const { - return quote_blob_literal(field_printer>{}(t)); - } - -#if SQLITE_VERSION_NUMBER >= 3020000 - template - std::string do_serialize(const pointer_binding&) const { - // always serialize null (security reasons) - return field_printer{}(nullptr); - } -#endif - }; - - template - struct statement_serializer, void> { - using statement_type = table_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) { - return this->serialize(statement, context, statement.name); - } - - template - auto serialize(const statement_type& statement, const Ctx& context, const std::string& tableName) { - std::stringstream ss; - ss << "CREATE TABLE " << streaming_identifier(tableName) << " (" - << streaming_expressions_tuple(statement.elements, context) << ")"; - if (statement_type::is_without_rowid_v) { - ss << " WITHOUT ROWID"; - } - return ss.str(); - } - }; - - template<> - struct statement_serializer { - using statement_type = current_time_t; - - template - std::string operator()(const statement_type& /*statement*/, const Ctx& /*context*/) { - return "CURRENT_TIME"; - } - }; - - template<> - struct statement_serializer { - using statement_type = current_date_t; - - template - std::string operator()(const statement_type& /*statement*/, const Ctx& /*context*/) { - return "CURRENT_DATE"; - } - }; - - template<> - struct statement_serializer { - using statement_type = current_timestamp_t; - - template - std::string operator()(const statement_type& /*statement*/, const Ctx& /*context*/) { - return "CURRENT_TIMESTAMP"; - } - }; - - template - struct statement_serializer, void> { - using statement_type = highlight_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) { - std::stringstream ss; - auto& tableName = lookup_table_name(context.db_objects); - ss << "HIGHLIGHT (" << streaming_identifier(tableName); - ss << ", " << serialize(statement.argument0, context); - ss << ", " << serialize(statement.argument1, context); - ss << ", " << serialize(statement.argument2, context) << ")"; - return ss.str(); - } - }; - - /** - * Serializer for literal values. - */ - template - struct statement_serializer> { - using statement_type = T; - - template - std::string operator()(const statement_type& literal, const Ctx& context) const { - static_assert(is_bindable_v>, "A literal value must be also bindable"); - - Ctx literalCtx = context; - literalCtx.replace_bindable_with_question = false; - statement_serializer> serializer{}; - return serializer(literal.value, literalCtx); - } - }; - - template - struct statement_serializer, void> { - using statement_type = filtered_aggregate_function; - - template - std::string operator()(const statement_type& statement, const Ctx& context) { - std::stringstream ss; - ss << serialize(statement.function, context); - ss << " FILTER (WHERE " << serialize(statement.where, context) << ")"; - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = excluded_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "excluded."; - if (auto* columnName = find_column_name(context.db_objects, statement.expression)) { - ss << streaming_identifier(*columnName); - } else { - throw std::system_error{orm_error_code::column_not_found}; - } - return ss.str(); - } - }; -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct statement_serializer, void> { - using statement_type = as_optional_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - return serialize(statement.expression, context); - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct statement_serializer, void> { - using statement_type = std::reference_wrapper; - - template - std::string operator()(const statement_type& s, const Ctx& context) const { - return serialize(s.get(), context); - } - }; - - template - struct statement_serializer, void> { - using statement_type = alias_holder; - - template - std::string operator()(const statement_type&, const Ctx&) { - std::stringstream ss; - ss << streaming_identifier(T::get()); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = match_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - auto& table = pick_table(context.db_objects); - std::stringstream ss; - ss << streaming_identifier(table.name) << " MATCH " << serialize(statement.argument, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = column_alias; - - template - std::string operator()(const statement_type&, const Ctx&) { - std::stringstream ss; - ss << streaming_identifier(statement_type::get()); - return ss.str(); - } - }; - - template - struct statement_serializer> { - using statement_type = T; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "ON CONFLICT"; - iterate_tuple(statement.target_args, [&ss, &context](auto& value) { - using value_type = polyfill::remove_cvref_t; - auto needParenthesis = std::is_member_pointer::value; - ss << ' '; - if (needParenthesis) { - ss << '('; - } - ss << serialize(value, context); - if (needParenthesis) { - ss << ')'; - } - }); - ss << ' ' << "DO"; - if (std::tuple_size::value == 0) { - ss << " NOTHING"; - } else { - auto updateContext = context; - updateContext.use_parentheses = false; - ss << " UPDATE " << streaming_actions_tuple(statement.actions, updateContext); - } - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = built_in_function_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << statement.serialize() << "(" << streaming_expressions_tuple(statement.args, context) << ")"; - return ss.str(); - } - }; - - template - struct statement_serializer, void> - : statement_serializer, void> {}; - - template - struct statement_serializer, void> { - using statement_type = function_call; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - stream_identifier(ss, "", statement.name(), ""); - ss << "(" << streaming_expressions_tuple(statement.callArgs, context) << ")"; - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = as_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - ss << serialize(c.expression, context) + " AS " << streaming_identifier(alias_extractor::extract()); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = alias_column_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - if (!context.skip_table_name) { - ss << streaming_identifier(alias_extractor::extract()) << "."; - } - auto newContext = context; - newContext.skip_table_name = true; - ss << serialize(c.column, newContext); - return ss.str(); - } - }; - - template - struct statement_serializer< - E, - std::enable_if_t, is_column_pointer>::value>> { - using statement_type = E; - - template - std::string operator()(const statement_type& e, const Ctx& context) const { - std::stringstream ss; - if (auto* columnName = find_column_name(context.db_objects, e)) { - ss << streaming_identifier( - !context.skip_table_name ? lookup_table_name>(context.db_objects) : "", - *columnName, - ""); - } else { - throw std::system_error{orm_error_code::column_not_found}; - } - return ss.str(); - } - }; - - template<> - struct statement_serializer { - using statement_type = rank_t; - - template - serialize_result_type operator()(const statement_type& /*statement*/, const Ctx&) const { - return "rank"; - } - }; - - template<> - struct statement_serializer { - using statement_type = rowid_t; - - template - std::string operator()(const statement_type& statement, const Ctx&) const { - return static_cast(statement); - } - }; - - template<> - struct statement_serializer { - using statement_type = oid_t; - - template - std::string operator()(const statement_type& statement, const Ctx&) const { - return static_cast(statement); - } - }; - - template<> - struct statement_serializer<_rowid_t, void> { - using statement_type = _rowid_t; - - template - std::string operator()(const statement_type& statement, const Ctx&) const { - return static_cast(statement); - } - }; - - template - struct statement_serializer, void> { - using statement_type = table_rowid_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - if (!context.skip_table_name) { - ss << streaming_identifier(lookup_table_name(context.db_objects)) << "."; - } - ss << static_cast(statement); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = table_oid_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - if (!context.skip_table_name) { - ss << streaming_identifier(lookup_table_name(context.db_objects)) << "."; - } - ss << static_cast(statement); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = table__rowid_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - if (!context.skip_table_name) { - ss << streaming_identifier(lookup_table_name(context.db_objects)) << "."; - } - ss << static_cast(statement); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = is_equal_with_table_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - const auto tableName = lookup_table_name(context.db_objects); - ss << streaming_identifier(tableName); - ss << " = "; - ss << serialize(statement.rhs, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = count_asterisk_t; - - template - std::string operator()(const statement_type&, const Ctx& context) const { - return serialize(count_asterisk_without_type{}, context); - } - }; - - template<> - struct statement_serializer { - using statement_type = count_asterisk_without_type; - - template - std::string operator()(const statement_type& c, const Ctx&) const { - std::stringstream ss; - auto functionName = c.serialize(); - ss << functionName << "(*)"; - return ss.str(); - } - }; - - // note (internal): this is a serializer for the deduplicator in an aggregate function; - // the result set deduplicators in a simple-select are treated by the select serializer. - template - struct statement_serializer, void> { - using statement_type = distinct_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - // DISTINCT introduces no parentheses - auto subCtx = context; - subCtx.use_parentheses = false; - - std::stringstream ss; - auto expr = serialize(c.expression, subCtx); - ss << static_cast(c) << " " << expr; - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = cast_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - ss << static_cast(c) << " ("; - ss << serialize(c.expression, context) << " AS " << type_printer().print() << ")"; - return ss.str(); - } - }; - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -#if SQLITE_VERSION_NUMBER >= 3035003 -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template<> - struct statement_serializer { - using statement_type = materialized_t; - - template - std::string_view operator()(const statement_type& /*statement*/, const Ctx& /*context*/) const { - return "MATERIALIZED"; - } - }; - - template<> - struct statement_serializer { - using statement_type = not_materialized_t; - - template - std::string_view operator()(const statement_type& /*statement*/, const Ctx& /*context*/) const { - return "NOT MATERIALIZED"; - } - }; -#endif -#endif - - template - struct statement_serializer> { - using statement_type = CTE; - - template - std::string operator()(const statement_type& cte, const Ctx& context) const { - // A CTE always starts a new 'highest level' context - Ctx cteContext = context; - cteContext.use_parentheses = false; - - std::stringstream ss; - ss << streaming_identifier(alias_extractor>::extract()); - { - std::vector columnNames = - collect_cte_column_names(get_cte_driving_subselect(cte.subselect), - cte.explicitColumns, - context); - ss << '(' << streaming_identifiers(columnNames) << ')'; - } - ss << " AS" << streaming_constraints_tuple(cte.hints, context) << " (" - << serialize(cte.subselect, cteContext) << ')'; - return ss.str(); - } - }; - - template - struct statement_serializer> { - using statement_type = With; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - Ctx tupleContext = context; - tupleContext.use_parentheses = false; - - std::stringstream ss; - ss << "WITH"; - if (c.recursiveIndicated) { - ss << " RECURSIVE"; - } - ss << " " << serialize(c.cte, tupleContext); - ss << " " << serialize(c.expression, context); - return ss.str(); - } - }; -#endif - - template - struct statement_serializer> { - using statement_type = T; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - ss << streaming_compound_expressions(c.compound, static_cast(c), context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = simple_case_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - ss << "CASE "; - c.case_expression.apply([&ss, context](auto& c_) { - ss << serialize(c_, context) << " "; - }); - iterate_tuple(c.args, [&ss, context](auto& pair) { - ss << "WHEN " << serialize(pair.first, context) << " "; - ss << "THEN " << serialize(pair.second, context) << " "; - }); - c.else_expression.apply([&ss, context](auto& el) { - ss << "ELSE " << serialize(el, context) << " "; - }); - ss << "END"; - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = is_null_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - ss << serialize(c.t, context) << " " << static_cast(c); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = is_not_null_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - ss << serialize(c.t, context) << " " << static_cast(c); - return ss.str(); - } - }; - - template - struct statement_serializer< - T, - std::enable_if_t, - polyfill::is_specialization_of>::value>> { - using statement_type = T; - - template - std::string operator()(const statement_type& expression, const Ctx& context) const { - // subqueries should always use parentheses in binary expressions - auto subCtx = context; - subCtx.use_parentheses = true; - // parentheses for sub-trees to ensure the order of precedence - constexpr bool parenthesize = is_binary_condition::value || - is_binary_operator::value; - - std::stringstream ss; - ss << expression.serialize(); - if SQLITE_ORM_CONSTEXPR_IF (parenthesize) { - ss << "("; - } - ss << serialize(get_from_expression(expression.argument), subCtx); - if SQLITE_ORM_CONSTEXPR_IF (parenthesize) { - ss << ")"; - } - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = negated_condition_t; - - template - std::string operator()(const statement_type& expression, const Ctx& context) const { - // subqueries should always use parentheses in binary expressions - auto subCtx = context; - subCtx.use_parentheses = true; - // parentheses for sub-trees to ensure the order of precedence - constexpr bool parenthesize = is_binary_condition::value || - is_binary_operator::value; - - std::stringstream ss; - ss << static_cast(expression) << " "; - if SQLITE_ORM_CONSTEXPR_IF (parenthesize) { - ss << "("; - } - ss << serialize(get_from_expression(expression.c), subCtx); - if SQLITE_ORM_CONSTEXPR_IF (parenthesize) { - ss << ")"; - } - return ss.str(); - } - }; - - template - struct statement_serializer< - T, - std::enable_if_t, is_binary_operator>::value>> { - using statement_type = T; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - // subqueries should always use parentheses in binary expressions - auto subCtx = context; - subCtx.use_parentheses = true; - // parentheses for sub-trees to ensure the order of precedence - constexpr bool parenthesizeLeft = is_binary_condition>::value || - is_binary_operator>::value; - constexpr bool parenthesizeRight = is_binary_condition>::value || - is_binary_operator>::value; - - std::stringstream ss; - if SQLITE_ORM_CONSTEXPR_IF (parenthesizeLeft) { - ss << "("; - } - ss << serialize(statement.lhs, subCtx); - if SQLITE_ORM_CONSTEXPR_IF (parenthesizeLeft) { - ss << ")"; - } - ss << " " << statement.serialize() << " "; - if SQLITE_ORM_CONSTEXPR_IF (parenthesizeRight) { - ss << "("; - } - ss << serialize(statement.rhs, subCtx); - if SQLITE_ORM_CONSTEXPR_IF (parenthesizeRight) { - ss << ")"; - } - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = named_collate; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - auto newContext = context; - newContext.use_parentheses = false; - auto res = serialize(c.expr, newContext); - return res + " " + static_cast(c); - } - }; - - template - struct statement_serializer, void> { - using statement_type = collate_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - auto newContext = context; - newContext.use_parentheses = false; - auto res = serialize(c.expr, newContext); - return res + " " + static_cast(c); - } - }; - - template - struct statement_serializer< - dynamic_in_t, - std::enable_if_t, - polyfill::is_specialization_of>::value>> { - using statement_type = dynamic_in_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - auto leftString = serialize(statement.left, context); - ss << leftString << " "; - if (!statement.negative) { - ss << "IN"; - } else { - ss << "NOT IN"; - } - ss << " "; - if (is_compound_operator::value) { - ss << '('; - } - auto newContext = context; - newContext.use_parentheses = true; - ss << serialize(statement.argument, newContext); - if (is_compound_operator::value) { - ss << ')'; - } - return ss.str(); - } - }; - - template - struct statement_serializer< - dynamic_in_t, - std::enable_if_t, - polyfill::is_specialization_of>::value>> { - using statement_type = dynamic_in_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - auto leftString = serialize(statement.left, context); - ss << leftString << " "; - if (!statement.negative) { - ss << "IN"; - } else { - ss << "NOT IN"; - } - ss << " (" << streaming_dynamic_expressions(statement.argument, context) << ")"; - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = in_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - auto leftString = serialize(statement.left, context); - ss << leftString << " "; - if (!statement.negative) { - ss << "IN"; - } else { - ss << "NOT IN"; - } - ss << " "; - using args_type = std::tuple; - constexpr bool theOnlySelect = - std::tuple_size::value == 1 && is_select>::value; - if (!theOnlySelect) { - ss << "("; - } - ss << streaming_expressions_tuple(statement.argument, context); - if (!theOnlySelect) { - ss << ")"; - } - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = like_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - ss << serialize(c.arg, context) << " "; - ss << static_cast(c) << " "; - ss << serialize(c.pattern, context); - c.arg3.apply([&ss, &context](auto& value) { - ss << " ESCAPE " << serialize(value, context); - }); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = glob_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - ss << serialize(c.arg, context) << " "; - ss << static_cast(c) << " "; - ss << serialize(c.pattern, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = between_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - auto expr = serialize(c.expr, context); - ss << expr << " " << static_cast(c) << " "; - ss << serialize(c.b1, context); - ss << " AND "; - ss << serialize(c.b2, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = exists_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - auto newContext = context; - newContext.use_parentheses = true; - ss << "EXISTS " << serialize(statement.expression, newContext); - return ss.str(); - } - }; - - template<> - struct statement_serializer { - using statement_type = conflict_clause_t; - - template - serialize_result_type operator()(const statement_type& statement, const Ctx&) const { - switch (statement) { - case conflict_clause_t::rollback: - return "ROLLBACK"; - case conflict_clause_t::abort: - return "ABORT"; - case conflict_clause_t::fail: - return "FAIL"; - case conflict_clause_t::ignore: - return "IGNORE"; - case conflict_clause_t::replace: - return "REPLACE"; - } - return {}; - } - }; - - template - struct statement_serializer, void> { - using statement_type = primary_key_with_autoincrement; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - return serialize(statement.as_base(), context) + " AUTOINCREMENT"; - } - }; - - template<> - struct statement_serializer { - using statement_type = null_t; - - template - serialize_result_type operator()(const statement_type& /*statement*/, const Ctx& /*context*/) const { - return "NULL"; - } - }; - - template<> - struct statement_serializer { - using statement_type = not_null_t; - - template - serialize_result_type operator()(const statement_type& /*statement*/, const Ctx& /*context*/) const { - return "NOT NULL"; - } - }; - - template - struct statement_serializer, void> { - using statement_type = primary_key_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "PRIMARY KEY"; - switch (statement.options.asc_option) { - case statement_type::order_by::ascending: - ss << " ASC"; - break; - case statement_type::order_by::descending: - ss << " DESC"; - break; - default: - break; - } - if (statement.options.conflict_clause_is_on) { - ss << " ON CONFLICT " << serialize(statement.options.conflict_clause, context); - } - using columns_tuple = typename statement_type::columns_tuple; - const size_t columnsCount = std::tuple_size::value; - if (columnsCount) { - ss << "(" << streaming_mapped_columns_expressions(statement.columns, context) << ")"; - } - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = unique_t; - - template - std::string operator()(const statement_type& c, const Ctx& context) const { - std::stringstream ss; - ss << static_cast(c); - using columns_tuple = typename statement_type::columns_tuple; - const size_t columnsCount = std::tuple_size::value; - if (columnsCount) { - ss << "(" << streaming_mapped_columns_expressions(c.columns, context) << ")"; - } - return ss.str(); - } - }; - -#if SQLITE_VERSION_NUMBER >= 3009000 - template<> - struct statement_serializer { - using statement_type = unindexed_t; - - template - serialize_result_type operator()(const statement_type& /*statement*/, const Ctx& /*context*/) const { - return "UNINDEXED"; - } - }; - - template - struct statement_serializer, void> { - using statement_type = prefix_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "prefix=" << serialize(statement.value, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = tokenize_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "tokenize = " << serialize(statement.value, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = content_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "content=" << serialize(statement.value, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = table_content_t; - - template - std::string operator()(const statement_type& /*statement*/, const Ctx& context) const { - using mapped_type = typename statement_type::mapped_type; - - auto& table = pick_table(context.db_objects); - - std::stringstream ss; - ss << "content=" << streaming_identifier(table.name); - return ss.str(); - } - }; -#endif - - template<> - struct statement_serializer { - using statement_type = collate_constraint_t; - - template - std::string operator()(const statement_type& statement, const Ctx&) const { - return static_cast(statement); - } - }; - - template - struct statement_serializer, void> { - using statement_type = default_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - return static_cast(statement) + " (" + serialize(statement.value, context) + ")"; - } - }; - -#if SQLITE_VERSION_NUMBER >= 3006019 - template - struct statement_serializer, std::tuple>, void> { - using statement_type = foreign_key_t, std::tuple>; - - template - std::string operator()(const statement_type& fk, const Ctx& context) const { - std::stringstream ss; - ss << "FOREIGN KEY(" << streaming_mapped_columns_expressions(fk.columns, context) << ") REFERENCES "; - { - using references_type_t = typename statement_type::references_type; - using first_reference_t = std::tuple_element_t<0, references_type_t>; - using first_reference_mapped_type = table_type_of_t; - auto refTableName = lookup_table_name(context.db_objects); - ss << streaming_identifier(refTableName); - } - ss << "(" << streaming_mapped_columns_expressions(fk.references, context) << ")"; - if (fk.on_update) { - ss << ' ' << static_cast(fk.on_update) << " " << fk.on_update._action; - } - if (fk.on_delete) { - ss << ' ' << static_cast(fk.on_delete) << " " << fk.on_delete._action; - } - return ss.str(); - } - }; -#endif - - template - struct statement_serializer, void> { - using statement_type = check_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "CHECK (" << serialize(statement.expression, context) << ")"; - return ss.str(); - } - }; -#if SQLITE_VERSION_NUMBER >= 3031000 - template - struct statement_serializer, void> { - using statement_type = generated_always_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - if (statement.full) { - ss << "GENERATED ALWAYS "; - } - ss << "AS ("; - ss << serialize(statement.expression, context) << ")"; - switch (statement.storage) { - case basic_generated_always::storage_type::not_specified: - //.. - break; - case basic_generated_always::storage_type::virtual_: - ss << " VIRTUAL"; - break; - case basic_generated_always::storage_type::stored: - ss << " STORED"; - break; - } - return ss.str(); - } - }; -#endif - template - struct statement_serializer, void> { - using statement_type = column_t; - - template - std::string operator()(const statement_type& column, const Ctx& context) const { - std::stringstream ss; - ss << streaming_identifier(column.name); - if (!context.fts5_columns) { - ss << " " << type_printer>>().print(); - } - ss << streaming_column_constraints( - call_as_template_base(polyfill::identity{})(column), - column.is_not_null(), - context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = remove_all_t; - - template - std::string operator()(const statement_type& rem, const Ctx& context) const { - auto& table = pick_table(context.db_objects); - - std::stringstream ss; - ss << "DELETE FROM " << streaming_identifier(table.name) - << streaming_conditions_tuple(rem.conditions, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = replace_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - using object_type = expression_object_type_t; - auto& table = pick_table(context.db_objects); - std::stringstream ss; - ss << "REPLACE INTO " << streaming_identifier(table.name) << " (" - << streaming_non_generated_column_names(table) << ")" - << " VALUES (" - << streaming_field_values_excluding(check_if{}, - empty_callable, // don't exclude - context, - get_ref(statement.object)) - << ")"; - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = insert_explicit; - - template - std::string operator()(const statement_type& ins, const Ctx& context) const { - constexpr size_t colsCount = std::tuple_size>::value; - static_assert(colsCount > 0, "Use insert or replace with 1 argument instead"); - using object_type = expression_object_type_t; - auto& table = pick_table(context.db_objects); - std::stringstream ss; - ss << "INSERT INTO " << streaming_identifier(table.name) << " "; - ss << "(" << streaming_mapped_columns_expressions(ins.columns.columns, context) << ") " - << "VALUES ("; - iterate_tuple(ins.columns.columns, - [&ss, &context, &object = get_ref(ins.obj), first = true](auto& memberPointer) mutable { - using member_pointer_type = std::remove_reference_t; - static_assert(!is_setter_v, - "Unable to use setter within insert explicit"); - - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)] - << serialize(polyfill::invoke(memberPointer, object), context); - }); - ss << ")"; - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = update_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - using object_type = expression_object_type_t; - auto& table = pick_table(context.db_objects); - - std::stringstream ss; - ss << "UPDATE " << streaming_identifier(table.name) << " SET "; - table.template for_each_column_excluding>( - [&table, &ss, &context, &object = get_ref(statement.object), first = true](auto& column) mutable { - if (exists_in_composite_primary_key(table, column)) { - return; - } - - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)] << streaming_identifier(column.name) << " = " - << serialize(polyfill::invoke(column.member_pointer, object), context); - }); - ss << " WHERE "; - table.for_each_column( - [&table, &context, &ss, &object = get_ref(statement.object), first = true](auto& column) mutable { - if (!column.template is() && !exists_in_composite_primary_key(table, column)) { - return; - } - - static constexpr std::array sep = {" AND ", ""}; - ss << sep[std::exchange(first, false)] << streaming_identifier(column.name) << " = " - << serialize(polyfill::invoke(column.member_pointer, object), context); - }); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = dynamic_set_t; - - template - std::string operator()(const statement_type& statement, const Ctx&) const { - std::stringstream ss; - ss << "SET "; - int index = 0; - for (const dynamic_set_entry& entry: statement) { - if (index > 0) { - ss << ", "; - } - ss << entry.serialized_value; - ++index; - } - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = set_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "SET "; - auto leftContext = context; - leftContext.skip_table_name = true; - iterate_tuple(statement.assigns, [&ss, &context, &leftContext, first = true](auto& value) mutable { - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)] << serialize(value.lhs, leftContext) << ' ' - << value.serialize() << ' ' << serialize(value.rhs, context); - }); - return ss.str(); - } - }; - - template - std::set> collect_table_names(const set_t& set, const Ctx& ctx) { - auto collector = make_table_name_collector(ctx.db_objects); - // note: we are only interested in the table name on the left-hand side of the assignment operator expression - iterate_tuple(set.assigns, [&collector](const auto& assignmentOperator) { - iterate_ast(assignmentOperator.lhs, collector); - }); - return std::move(collector.table_names); - } - - template - const std::set>& collect_table_names(const dynamic_set_t& set, - const Ctx&) { - return set.collector.table_names; - } - - template = true> - std::set> collect_table_names(const T& sel, const Ctx& ctx) { - auto collector = make_table_name_collector(ctx.db_objects); - iterate_ast(sel, collector); - return std::move(collector.table_names); - } - - template - struct statement_serializer, void> { - using statement_type = update_all_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - const auto& tableNames = collect_table_names(statement.set, context); - if (tableNames.empty()) { - throw std::system_error{orm_error_code::no_tables_specified}; - } - const std::string& tableName = tableNames.begin()->first; - - std::stringstream ss; - ss << "UPDATE " << streaming_identifier(tableName) << ' ' << serialize(statement.set, context) - << streaming_conditions_tuple(statement.conditions, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = insert_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - using object_type = expression_object_type_t; - auto& table = pick_table(context.db_objects); - using is_without_rowid = typename std::remove_reference_t::is_without_rowid; - - std::vector> columnNames; - table.template for_each_column_excluding< - mpl::conjunction>, - mpl::disjunction_fn>>( - [&table, &columnNames](auto& column) { - if (exists_in_composite_primary_key(table, column)) { - return; - } - - columnNames.push_back(cref(column.name)); - }); - const size_t columnNamesCount = columnNames.size(); - - std::stringstream ss; - ss << "INSERT INTO " << streaming_identifier(table.name) << " "; - if (columnNamesCount) { - ss << "(" << streaming_identifiers(columnNames) << ")"; - } else { - ss << "DEFAULT"; - } - ss << " VALUES"; - if (columnNamesCount) { - ss << " (" - << streaming_field_values_excluding( - mpl::conjunction>, - mpl::disjunction_fn>{}, - [&table](auto& column) { - return exists_in_composite_primary_key(table, column); - }, - context, - get_ref(statement.object)) - << ")"; - } - - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = into_t; - - template - std::string operator()(const statement_type&, const Ctx& context) const { - auto& table = pick_table(context.db_objects); - - std::stringstream ss; - ss << "INTO " << streaming_identifier(table.name); - return ss.str(); - } - }; - - template - struct statement_serializer, is_struct>::value>> { - using statement_type = C; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - // subqueries should always use parentheses in column names - auto subCtx = context; - subCtx.use_parentheses = true; - - std::stringstream ss; - if (context.use_parentheses) { - ss << '('; - } - ss << streaming_serialized(get_column_names(statement, subCtx)); - if (context.use_parentheses) { - ss << ')'; - } - return ss.str(); - } - }; - - template - struct statement_serializer< - T, - std::enable_if_t, is_replace_raw>::value>> { - using statement_type = T; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - if (is_insert_raw::value) { - ss << "INSERT"; - } else { - ss << "REPLACE"; - } - iterate_tuple(statement.args, [&context, &ss](auto& value) { - using value_type = polyfill::remove_cvref_t; - ss << ' '; - if (is_columns::value) { - auto newContext = context; - newContext.skip_table_name = true; - newContext.use_parentheses = true; - ss << serialize(value, newContext); - } else if (is_values::value || is_select::value) { - auto newContext = context; - newContext.use_parentheses = false; - ss << serialize(value, newContext); - } else { - ss << serialize(value, context); - } - }); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = remove_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - auto& table = pick_table(context.db_objects); - std::stringstream ss; - ss << "DELETE FROM " << streaming_identifier(table.name) << " " - << "WHERE "; - std::vector idsStrings; - idsStrings.reserve(std::tuple_size::value); - iterate_tuple(statement.ids, [&idsStrings, &context](auto& idValue) { - idsStrings.push_back(serialize(idValue, context)); - }); - table.for_each_primary_key_column([&table, &ss, &idsStrings, index = 0](auto& memberPointer) mutable { - auto* columnName = table.find_column_name(memberPointer); - if (!columnName) { - throw std::system_error{orm_error_code::column_not_found}; - } - - static constexpr std::array sep = {" AND ", ""}; - ss << sep[index == 0] << streaming_identifier(*columnName) << " = " << idsStrings[index]; - ++index; - }); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = replace_range_t; - - template - std::string operator()(const statement_type& rep, const Ctx& context) const { - using object_type = expression_object_type_t; - auto& table = pick_table(context.db_objects); - - std::stringstream ss; - ss << "REPLACE INTO " << streaming_identifier(table.name) << " (" - << streaming_non_generated_column_names(table) << ")"; - const auto valuesCount = std::distance(rep.range.first, rep.range.second); - const auto columnsCount = table.template count_of_columns_excluding(); - ss << " VALUES " << streaming_values_placeholders(columnsCount, valuesCount); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = insert_range_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - using object_type = expression_object_type_t; - auto& table = pick_table(context.db_objects); - using is_without_rowid = typename std::remove_reference_t::is_without_rowid; - - std::vector> columnNames; - table.template for_each_column_excluding< - mpl::conjunction>, - mpl::disjunction_fn>>( - [&table, &columnNames](auto& column) { - if (exists_in_composite_primary_key(table, column)) { - return; - } - - columnNames.push_back(cref(column.name)); - }); - const size_t valuesCount = std::distance(statement.range.first, statement.range.second); - const size_t columnNamesCount = columnNames.size(); - - std::stringstream ss; - ss << "INSERT INTO " << streaming_identifier(table.name) << " "; - if (columnNamesCount) { - ss << "(" << streaming_identifiers(columnNames) << ")"; - } else { - ss << "DEFAULT"; - } - ss << " VALUES "; - if (columnNamesCount) { - ss << streaming_values_placeholders(columnNamesCount, valuesCount); - } else if (valuesCount != 1) { - throw std::system_error{orm_error_code::cannot_use_default_value}; - } - return ss.str(); - } - }; - - template - std::string serialize_get_all_impl(const T& getAll, const Ctx& context) { - using table_type = type_t; - using mapped_type = mapped_type_proxy_t; - - auto& table = pick_table(context.db_objects); - - std::stringstream ss; - ss << "SELECT " << streaming_table_column_names(table, alias_extractor::as_qualifier(table)) - << " FROM " << streaming_identifier(table.name, alias_extractor::as_alias()) - << streaming_conditions_tuple(getAll.conditions, context); - return ss.str(); - } - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct statement_serializer, void> { - using statement_type = get_all_optional_t; - - template - std::string operator()(const statement_type& get, const Ctx& context) const { - return serialize_get_all_impl(get, context); - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template - struct statement_serializer, void> { - using statement_type = get_all_pointer_t; - - template - std::string operator()(const statement_type& get, const Ctx& context) const { - return serialize_get_all_impl(get, context); - } - }; - - template - struct statement_serializer, void> { - using statement_type = get_all_t; - - template - std::string operator()(const statement_type& get, const Ctx& context) const { - return serialize_get_all_impl(get, context); - } - }; - - template - std::string serialize_get_impl(const T&, const Ctx& context) { - using primary_type = type_t; - auto& table = pick_table(context.db_objects); - std::stringstream ss; - ss << "SELECT " << streaming_table_column_names(table, std::string{}) << " FROM " - << streaming_identifier(table.name) << " WHERE "; - - auto primaryKeyColumnNames = table.primary_key_column_names(); - if (primaryKeyColumnNames.empty()) { - throw std::system_error{orm_error_code::table_has_no_primary_key_column}; - } - - for (size_t i = 0; i < primaryKeyColumnNames.size(); ++i) { - if (i > 0) { - ss << " AND "; - } - ss << streaming_identifier(primaryKeyColumnNames[i]) << " = ?"; - } - return ss.str(); - } - - template - struct statement_serializer, void> { - using statement_type = get_t; - - template - std::string operator()(const statement_type& get, const Ctx& context) const { - return serialize_get_impl(get, context); - } - }; - - template - struct statement_serializer, void> { - using statement_type = get_pointer_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - return serialize_get_impl(statement, context); - } - }; - - template<> - struct statement_serializer { - using statement_type = conflict_action; - - template - serialize_result_type operator()(const statement_type& statement, const Ctx&) const { - switch (statement) { - case conflict_action::replace: - return "REPLACE"; - case conflict_action::abort: - return "ABORT"; - case conflict_action::fail: - return "FAIL"; - case conflict_action::ignore: - return "IGNORE"; - case conflict_action::rollback: - return "ROLLBACK"; - } - return {}; - } - }; - - template<> - struct statement_serializer { - using statement_type = insert_constraint; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - - ss << "OR " << serialize(statement.action, context); - return ss.str(); - } - }; - -#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED - template - struct statement_serializer, void> { - using statement_type = get_optional_t; - - template - std::string operator()(const statement_type& get, const Ctx& context) const { - return serialize_get_impl(get, context); - } - }; -#endif // SQLITE_ORM_OPTIONAL_SUPPORTED - - template - struct statement_serializer, void> { - using statement_type = select_t; - using return_type = typename statement_type::return_type; - - template - std::string operator()(const statement_type& sel, Ctx context) const { - context.skip_table_name = false; - // subqueries should always use parentheses in column names - auto subCtx = context; - subCtx.use_parentheses = true; - - std::stringstream ss; - if (!is_compound_operator::value) { - if (!sel.highest_level && context.use_parentheses) { - ss << "("; - } - ss << "SELECT "; - call_if_constexpr>( - // note: make use of implicit to-string conversion - [&ss](std::string keyword) { - ss << keyword << ' '; - }, - sel.col); - } - - ss << streaming_serialized(get_column_names(sel.col, subCtx)); - using conditions_tuple = typename statement_type::conditions_type; - constexpr bool hasExplicitFrom = tuple_has::value; - if (!hasExplicitFrom) { - auto tableNames = collect_table_names(sel, context); - using joins_index_sequence = filter_tuple_sequence_t; - // deduplicate table names of constrained join statements - iterate_tuple(sel.conditions, joins_index_sequence{}, [&tableNames, &context](auto& join) { - using original_join_type = typename std::remove_reference_t::type; - using cross_join_type = mapped_type_proxy_t; - std::pair tableNameWithAlias{ - lookup_table_name(context.db_objects), - alias_extractor::as_alias()}; - tableNames.erase(tableNameWithAlias); - }); - if (!tableNames.empty() && !is_compound_operator::value) { - ss << " FROM " << streaming_identifiers(tableNames); - } - } - ss << streaming_conditions_tuple(sel.conditions, context); - if (!is_compound_operator::value) { - if (!sel.highest_level && context.use_parentheses) { - ss << ")"; - } - } - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = indexed_column_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << serialize(statement.column_or_expression, context); - if (!statement._collation_name.empty()) { - ss << " COLLATE " << statement._collation_name; - } - if (statement._order) { - switch (statement._order) { - case 1: - ss << " ASC"; - break; - case -1: - ss << " DESC"; - break; - } - } - return ss.str(); - } - }; - -#if SQLITE_VERSION_NUMBER >= 3009000 - template - struct statement_serializer, void> { - using statement_type = using_fts5_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "USING FTS5("; - auto subContext = context; - subContext.fts5_columns = true; - ss << streaming_expressions_tuple(statement.columns, subContext) << ")"; - return ss.str(); - } - }; -#endif - - template - struct statement_serializer, void> { - using statement_type = virtual_table_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "CREATE VIRTUAL TABLE IF NOT EXISTS "; - ss << streaming_identifier(statement.name) << ' '; - ss << serialize(statement.module_details, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = index_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "CREATE "; - if (statement.unique) { - ss << "UNIQUE "; - } - using indexed_type = typename statement_type::table_mapped_type; - ss << "INDEX IF NOT EXISTS " << streaming_identifier(statement.name) << " ON " - << streaming_identifier(lookup_table_name(context.db_objects)); - std::vector columnNames; - std::string whereString; - iterate_tuple(statement.elements, [&columnNames, &context, &whereString](auto& value) { - using value_type = polyfill::remove_cvref_t; - if (!is_where::value) { - auto newContext = context; - newContext.use_parentheses = false; - auto whereString = serialize(value, newContext); - columnNames.push_back(std::move(whereString)); - } else { - auto columnName = serialize(value, context); - whereString = std::move(columnName); - } - }); - ss << " (" << streaming_serialized(columnNames) << ")"; - if (!whereString.empty()) { - ss << ' ' << whereString; - } - return ss.str(); - } - }; - - template - struct statement_serializer> { - using statement_type = From; - - template - std::string operator()(const statement_type&, const Ctx& context) const { - std::stringstream ss; - ss << "FROM "; - iterate_tuple([&context, &ss, first = true](auto* dummyItem) mutable { - using table_type = std::remove_pointer_t; - - static constexpr std::array sep = {", ", ""}; - ss << sep[std::exchange(first, false)] - << streaming_identifier(lookup_table_name>(context.db_objects), - alias_extractor::as_alias()); - }); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = old_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "OLD."; - auto newContext = context; - newContext.skip_table_name = true; - ss << serialize(statement.expression, newContext); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = new_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "NEW."; - auto newContext = context; - newContext.skip_table_name = true; - ss << serialize(statement.expression, newContext); - return ss.str(); - } - }; - - template<> - struct statement_serializer { - using statement_type = raise_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - switch (statement.type) { - case raise_t::type_t::ignore: - return "RAISE(IGNORE)"; - - case raise_t::type_t::rollback: - return "RAISE(ROLLBACK, " + serialize(statement.message, context) + ")"; - - case raise_t::type_t::abort: - return "RAISE(ABORT, " + serialize(statement.message, context) + ")"; - - case raise_t::type_t::fail: - return "RAISE(FAIL, " + serialize(statement.message, context) + ")"; - } - return {}; - } - }; - - template<> - struct statement_serializer { - using statement_type = trigger_timing; - - template - serialize_result_type operator()(const statement_type& statement, const Ctx&) const { - switch (statement) { - case trigger_timing::trigger_before: - return "BEFORE"; - case trigger_timing::trigger_after: - return "AFTER"; - case trigger_timing::trigger_instead_of: - return "INSTEAD OF"; - } - return {}; - } - }; - - template<> - struct statement_serializer { - using statement_type = trigger_type; - - template - serialize_result_type operator()(const statement_type& statement, const Ctx&) const { - switch (statement) { - case trigger_type::trigger_delete: - return "DELETE"; - case trigger_type::trigger_insert: - return "INSERT"; - case trigger_type::trigger_update: - return "UPDATE"; - } - return {}; - } - }; - - template<> - struct statement_serializer { - using statement_type = trigger_type_base_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - - ss << serialize(statement.timing, context) << " " << serialize(statement.type, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = trigger_update_type_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - - ss << serialize(statement.timing, context) << " UPDATE OF " - << streaming_mapped_columns_expressions(statement.columns, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = trigger_base_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - - ss << serialize(statement.type_base, context); - ss << " ON " << streaming_identifier(lookup_table_name(context.db_objects)); - if (statement.do_for_each_row) { - ss << " FOR EACH ROW"; - } - statement.container_when.apply([&ss, &context](auto& value) { - ss << " WHEN " << serialize(value, context); - }); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = trigger_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << "CREATE "; - - ss << "TRIGGER IF NOT EXISTS " << streaming_identifier(statement.name) << " " - << serialize(statement.base, context); - ss << " BEGIN "; - iterate_tuple(statement.elements, [&ss, &context](auto& element) { - using element_type = polyfill::remove_cvref_t; - if (is_select::value) { - auto newContext = context; - newContext.use_parentheses = false; - ss << serialize(element, newContext); - } else { - ss << serialize(element, context); - } - ss << ";"; - }); - ss << " END"; - - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = where_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - ss << statement.serialize() << " "; - auto whereString = serialize(statement.expression, context); - ss << '(' << whereString << ')'; - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = order_by_t; - - template - std::string operator()(const statement_type& orderBy, const Ctx& context) const { - std::stringstream ss; - ss << static_cast(orderBy) << " "; - ss << serialize_order_by(orderBy, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = dynamic_order_by_t; - - template - std::string operator()(const statement_type& orderBy, const Ctx& context) const { - return serialize_order_by(orderBy, context); - } - }; - - template - struct statement_serializer, void> { - using statement_type = multi_order_by_t; - - template - std::string operator()(const statement_type& orderBy, const Ctx& context) const { - std::stringstream ss; - ss << static_cast(orderBy) << " " << streaming_expressions_tuple(orderBy.args, context); - return ss.str(); - } - }; - - template - struct statement_serializer< - Join, - std::enable_if_t, - polyfill::is_specialization_of>::value>> { - using statement_type = Join; - - template - std::string operator()(const statement_type& join, const Ctx& context) const { - std::stringstream ss; - ss << static_cast(join) << " " - << streaming_identifier(lookup_table_name>(context.db_objects)); - return ss.str(); - } - }; - - template - struct statement_serializer> { - using statement_type = Join; - - template - std::string operator()(const statement_type& join, const Ctx& context) const { - std::stringstream ss; - ss << static_cast(join) << " " - << streaming_identifier(lookup_table_name>>(context.db_objects), - alias_extractor>::as_alias()) - << " " << serialize(join.constraint, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = on_t; - - template - std::string operator()(const statement_type& on, const Ctx& context) const { - std::stringstream ss; - auto newContext = context; - newContext.skip_table_name = false; - ss << static_cast(on) << " " << serialize(on.arg, newContext) << " "; - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = group_by_with_having; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - auto newContext = context; - newContext.skip_table_name = false; - ss << "GROUP BY " << streaming_expressions_tuple(statement.args, newContext) << " HAVING " - << serialize(statement.expression, context); - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = group_by_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - auto newContext = context; - newContext.skip_table_name = false; - ss << "GROUP BY " << streaming_expressions_tuple(statement.args, newContext); - return ss.str(); - } - }; - - /** - * HO - has offset - * OI - offset is implicit - */ - template - struct statement_serializer, void> { - using statement_type = limit_t; - - template - std::string operator()(const statement_type& limt, const Ctx& context) const { - auto newContext = context; - newContext.skip_table_name = false; - std::stringstream ss; - ss << static_cast(limt) << " "; - if (HO) { - if (OI) { - limt.off.apply([&newContext, &ss](auto& value) { - ss << serialize(value, newContext); - }); - ss << ", "; - ss << serialize(limt.lim, newContext); - } else { - ss << serialize(limt.lim, newContext) << " OFFSET "; - limt.off.apply([&newContext, &ss](auto& value) { - ss << serialize(value, newContext); - }); - } - } else { - ss << serialize(limt.lim, newContext); - } - return ss.str(); - } - }; - - template<> - struct statement_serializer { - using statement_type = default_values_t; - - template - serialize_result_type operator()(const statement_type&, const Ctx&) const { - return "DEFAULT VALUES"; - } - }; - - template - struct statement_serializer, void> { - using statement_type = using_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - auto newContext = context; - newContext.skip_table_name = true; - return static_cast(statement) + " (" + serialize(statement.column, newContext) + ")"; - } - }; - - template - struct statement_serializer, void> { - using statement_type = std::tuple; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - if (context.use_parentheses) { - ss << '('; - } - ss << streaming_expressions_tuple(statement, context); - if (context.use_parentheses) { - ss << ')'; - } - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = values_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - if (context.use_parentheses) { - ss << '('; - } - ss << "VALUES "; - { - Ctx tupleContext = context; - tupleContext.use_parentheses = true; - ss << streaming_expressions_tuple(statement.tuple, tupleContext); - } - if (context.use_parentheses) { - ss << ')'; - } - return ss.str(); - } - }; - - template - struct statement_serializer, void> { - using statement_type = dynamic_values_t; - - template - std::string operator()(const statement_type& statement, const Ctx& context) const { - std::stringstream ss; - if (context.use_parentheses) { - ss << '('; - } - ss << "VALUES " << streaming_dynamic_expressions(statement.vector, context); - if (context.use_parentheses) { - ss << ')'; - } - return ss.str(); - } - }; - } -} - -// #include "serializer_context.h" - -// #include "schema/triggers.h" - -// #include "object_from_column_builder.h" - -// #include "row_extractor.h" - -// #include "schema/table.h" - -// #include "schema/column.h" - -// #include "schema/index.h" - -// #include "cte_storage.h" - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) -#include -#include -#include -#include -#endif - -// #include "tuple_helper/tuple_fy.h" - -// #include "table_type_of.h" - -// #include "column_result.h" - -// #include "select_constraints.h" - -// #include "schema/table.h" - -// #include "alias.h" - -// #include "cte_types.h" - -// #include "cte_column_names_collector.h" - -// #include "column_expression.h" - -#include // std::enable_if, std::is_same, std::decay, std::is_arithmetic -#include // std::tuple -#include // std::reference_wrapper - -// #include "functional/cxx_type_traits_polyfill.h" - -// #include "tuple_helper/tuple_transformer.h" - -// #include "type_traits.h" - -// #include "select_constraints.h" - -// #include "alias.h" - -// #include "storage_traits.h" - -namespace sqlite_orm { - - namespace internal { - - template - struct column_expression_type; - - /** - * Obains the expressions that form the columns of a subselect statement. - */ - template - using column_expression_of_t = typename column_expression_type::type; - - /** - * Identity. - */ - template - struct column_expression_type { - using type = E; - }; - - /** - * Resolve column alias. - * as_t -> as_t - */ - template - struct column_expression_type> { - using type = as_t, column_expression_of_t>>; - }; - - /** - * Resolve reference wrapper. - * reference_wrapper -> T& - */ - template - struct column_expression_type, void> - : std::add_lvalue_reference> {}; - - // No CTE for object expression. - template - struct column_expression_type, void> { - static_assert(polyfill::always_false_v, "Selecting an object in a subselect is not allowed."); - }; - - /** - * Resolve all columns of a mapped object or CTE. - * asterisk_t -> tuple - */ - template - struct column_expression_type, - std::enable_if_t>, - is_cte_moniker>::value>> - : storage_traits::storage_mapped_column_expressions {}; - - template - struct add_column_alias { - template - using apply_t = alias_column_t; - }; - /** - * Resolve all columns of an aliased object. - * asterisk_t -> tuple...> - */ - template - struct column_expression_type, match_if> - : tuple_transformer>::type, - add_column_alias::template apply_t> {}; - - /** - * Resolve multiple columns. - * columns_t -> tuple - */ - template - struct column_expression_type, void> { - using type = std::tuple>...>; - }; - - /** - * Resolve multiple columns. - * struct_t -> tuple - */ - template - struct column_expression_type, void> { - using type = std::tuple>...>; - }; - - /** - * Resolve column(s) of subselect. - * select_t -> ColExpr, tuple - */ - template - struct column_expression_type> : column_expression_type {}; - } -} - -// #include "storage_lookup.h" - -namespace sqlite_orm { - namespace internal { - -#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE) - // F = field_type - template - struct create_cte_mapper { - using type = subselect_mapper; - }; - - // std::tuple - template - struct create_cte_mapper> { - using type = subselect_mapper; - }; - - template - using create_cte_mapper_t = - typename create_cte_mapper:: - type; - - // aliased column expressions, explicit or implicitly numbered - template = true> - static auto make_cte_column(std::string name, const ColRef& /*finalColRef*/) { - using object_type = aliased_field, F>; - - return sqlite_orm::make_column<>(std::move(name), &object_type::field); - } - - // F O::* - template = true> - static auto make_cte_column(std::string name, const ColRef& finalColRef) { - using object_type = table_type_of_t; - using column_type = column_t; - - return column_type{std::move(name), finalColRef, empty_setter{}}; - } - - /** - * Concatenate newly created tables with given DBOs, forming a new set of DBOs. - */ - template - auto db_objects_cat(const DBOs& dbObjects, std::index_sequence, CTETables&&... cteTables) { - return std::tuple{std::forward(cteTables)..., get(dbObjects)...}; - } - - /** - * Concatenate newly created tables with given DBOs, forming a new set of DBOs. - */ - template - auto db_objects_cat(const DBOs& dbObjects, CTETables&&... cteTables) { - return db_objects_cat(dbObjects, - std::make_index_sequence>{}, - std::forward(cteTables)...); - } - - /** - * This function returns the expression contained in a subselect that is relevant for - * creating the definition of a CTE table. - * Because CTEs can recursively refer to themselves in a compound statement, parsing - * the whole compound statement would lead to compiler errors if a column_pointer<> - * can't be resolved. Therefore, at the time of building a CTE table, we are only - * interested in the column results of the left-most select expression. - */ - template - decltype(auto) get_cte_driving_subselect(const Select& subSelect); - - /** - * Return given select expression. - */ - template - decltype(auto) get_cte_driving_subselect(const Select& subSelect) { - return subSelect; - } - - /** - * Return left-most select expression of compound statement. - */ - template, bool> = true> - decltype(auto) get_cte_driving_subselect(const select_t& subSelect) { - return std::get<0>(subSelect.col.compound); - } - - /** - * Return a tuple of member pointers of all columns - */ - template - auto get_table_columns_fields(const C& coldef, std::index_sequence) { - return std::make_tuple(get(coldef).member_pointer...); - } - - // any expression -> numeric column alias - template>, bool> = true> - auto extract_colref_expressions(const DBOs& /*dbObjects*/, const E& /*col*/, std::index_sequence = {}) - -> std::tuple())>> { - return {}; - } - - // expression_t<> - template - auto - extract_colref_expressions(const DBOs& dbObjects, const expression_t& col, std::index_sequence s = {}) { - return extract_colref_expressions(dbObjects, col.value, s); - } - - // F O::* (field/getter) -> field/getter - template - auto extract_colref_expressions(const DBOs& /*dbObjects*/, F O::* col, std::index_sequence = {}) { - return std::make_tuple(col); - } - - // as_t<> (aliased expression) -> alias_holder - template - std::tuple> extract_colref_expressions(const DBOs& /*dbObjects*/, - const as_t& /*col*/, - std::index_sequence = {}) { - return {}; - } - - // alias_holder<> (colref) -> alias_holder - template - std::tuple> extract_colref_expressions(const DBOs& /*dbObjects*/, - const alias_holder& /*col*/, - std::index_sequence = {}) { - return {}; - } - - // column_pointer<> - template - auto extract_colref_expressions(const DBOs& dbObjects, - const column_pointer& col, - std::index_sequence s = {}) { - return extract_colref_expressions(dbObjects, col.field, s); - } - - // column expression tuple - template - auto extract_colref_expressions(const DBOs& dbObjects, - const std::tuple& cols, - std::index_sequence) { - return std::tuple_cat(extract_colref_expressions(dbObjects, get(cols), std::index_sequence{})...); - } - - // columns_t<> - template - auto extract_colref_expressions(const DBOs& dbObjects, const columns_t& cols) { - return extract_colref_expressions(dbObjects, cols.columns, std::index_sequence_for{}); - } - - // asterisk_t<> -> fields - template - auto extract_colref_expressions(const DBOs& dbObjects, const asterisk_t& /*col*/) { - using table_type = storage_pick_table_t; - using elements_t = typename table_type::elements_type; - using column_idxs = filter_tuple_sequence_t; - - auto& table = pick_table(dbObjects); - return get_table_columns_fields(table.elements, column_idxs{}); - } - - template - void extract_colref_expressions(const DBOs& /*dbObjects*/, const select_t& /*subSelect*/) = delete; - - template, bool> = true> - void extract_colref_expressions(const DBOs& /*dbObjects*/, const Compound& /*subSelect*/) = delete; - - /* - * Depending on ExplicitColRef's type returns either the explicit column reference - * or the expression's column reference otherwise. - */ - template - auto determine_cte_colref(const DBOs& /*dbObjects*/, - const SubselectColRef& subselectColRef, - const ExplicitColRef& explicitColRef) { - if constexpr (polyfill::is_specialization_of_v) { - return explicitColRef; - } else if constexpr (std::is_member_pointer::value) { - return explicitColRef; - } else if constexpr (std::is_base_of_v) { - return explicitColRef.member_pointer; - } else if constexpr (std::is_same_v) { - return subselectColRef; - } else if constexpr (std::is_same_v>) { - return subselectColRef; - } else { - static_assert(polyfill::always_false_v, "Invalid explicit column reference specified"); - } - } - - template - auto determine_cte_colrefs([[maybe_unused]] const DBOs& dbObjects, - const SubselectColRefs& subselectColRefs, - [[maybe_unused]] const ExplicitColRefs& explicitColRefs, - std::index_sequence) { - if constexpr (std::tuple_size_v != 0) { - static_assert( - (!is_builtin_numeric_column_alias_v< - alias_holder_type_or_none_t>> && - ...), - "Numeric column aliases are reserved for referencing columns locally within a single CTE."); - - return std::tuple{ - determine_cte_colref(dbObjects, get(subselectColRefs), get(explicitColRefs))...}; - } else { - return subselectColRefs; - } - } - - template - auto make_cte_table_using_column_indices(const DBOs& /*dbObjects*/, - std::string tableName, - std::vector columnNames, - const ColRefs& finalColRefs, - std::index_sequence) { - return make_table( - std::move(tableName), - make_cte_column>(std::move(columnNames.at(CIs)), - get(finalColRefs))...); - } - - template - auto make_cte_table(const DBOs& dbObjects, const CTE& cte) { - using cte_type = CTE; - - auto subSelect = get_cte_driving_subselect(cte.subselect); - - using subselect_type = decltype(subSelect); - using column_results = column_result_of_t; - using index_sequence = std::make_index_sequence>>; - static_assert(cte_type::explicit_colref_count == 0 || - cte_type::explicit_colref_count == index_sequence::size(), - "Number of explicit columns of common table expression doesn't match the number of columns " - "in the subselect."); - - std::string tableName = alias_extractor>::extract(); - auto subselectColRefs = extract_colref_expressions(dbObjects, subSelect.col); - const auto& finalColRefs = - determine_cte_colrefs(dbObjects, subselectColRefs, cte.explicitColumns, index_sequence{}); - - serializer_context context{dbObjects}; - std::vector columnNames = collect_cte_column_names(subSelect, cte.explicitColumns, context); - - using mapper_type = create_cte_mapper_t, - typename cte_type::explicit_colrefs_tuple, - column_expression_of_t, - decltype(subselectColRefs), - polyfill::remove_cvref_t, - column_results>; - return make_cte_table_using_column_indices(dbObjects, - std::move(tableName), - std::move(columnNames), - finalColRefs, - index_sequence{}); - } - - template - decltype(auto) make_recursive_cte_db_objects(const DBOs& dbObjects, - const common_table_expressions& cte, - std::index_sequence) { - auto tbl = make_cte_table(dbObjects, get(cte)); - - if constexpr (sizeof...(In) > 0) { - return make_recursive_cte_db_objects( - // Because CTEs can depend on their predecessor we recursively pass in a new set of DBOs - db_objects_cat(dbObjects, std::move(tbl)), - cte, - std::index_sequence{}); - } else { - return db_objects_cat(dbObjects, std::move(tbl)); - } - } - - /** - * Return new DBOs for CTE expressions. - */ - template = true> - decltype(auto) db_objects_for_expression(DBOs& dbObjects, const with_t& e) { - return make_recursive_cte_db_objects(dbObjects, e.cte, std::index_sequence_for{}); - } -#endif - } -} - -// #include "util.h" - -// #include "serializing_util.h" - -namespace sqlite_orm { - - namespace internal { - /* - * Implementation note: the technique of indirect expression testing is because - * of older compilers having problems with the detection of dependent templates [SQLITE_ORM_BROKEN_ALIAS_TEMPLATE_DEPENDENT_EXPR_SFINAE]. - * It must also be a type that differs from those for `is_printable_v`, `is_bindable_v`. - */ - template - struct indirectly_test_preparable; - - template - SQLITE_ORM_INLINE_VAR constexpr bool is_preparable_v = false; - template - SQLITE_ORM_INLINE_VAR constexpr bool is_preparable_v< - S, - E, - polyfill::void_t().prepare(std::declval()))>>> = - true; - - /** - * Storage class itself. Create an instanse to use it as an interfacto to sqlite db by calling `make_storage` - * function. - */ - template - struct storage_t : storage_base { - using self = storage_t; - using db_objects_type = db_objects_tuple; - - /** - * @param filename database filename. - * @param dbObjects db_objects_tuple - */ - storage_t(std::string filename, db_objects_type dbObjects) : - storage_base{std::move(filename), foreign_keys_count(dbObjects)}, db_objects{std::move(dbObjects)} {} - - storage_t(const storage_t&) = default; - - private: - db_objects_type db_objects; - - /** - * Obtain a storage_t's const db_objects_tuple. - * - * @note Historically, `serializer_context_builder` was declared friend, along with - * a few other library stock objects, in order to limit access to the db_objects_tuple. - * However, one could gain access to a storage_t's db_objects_tuple through - * `serializer_context_builder`, hence leading the whole friend declaration mambo-jumbo - * ad absurdum. - * Providing a free function is way better and cleaner. - * - * Hence, friend was replaced by `obtain_db_objects()` and `pick_const_impl()`. - */ - friend const db_objects_type& obtain_db_objects(const self& storage) noexcept { - return storage.db_objects; - } - - template - void create_table(sqlite3* db, const std::string& tableName, const Table& table) { - using context_t = serializer_context; - - context_t context{this->db_objects}; - statement_serializer serializer; - std::string sql = serializer.serialize(table, context, tableName); - perform_void_exec(db, std::move(sql)); - } - - /** - * Copies sourceTableName to another table with name: destinationTableName - * Performs INSERT INTO %destinationTableName% () SELECT %table.column_names% FROM %sourceTableName% - */ - template - void copy_table(sqlite3* db, - const std::string& sourceTableName, - const std::string& destinationTableName, - const Table& table, - const std::vector& columnsToIgnore) const; - -#if SQLITE_VERSION_NUMBER >= 3035000 // DROP COLUMN feature exists (v3.35.0) - void drop_column(sqlite3* db, const std::string& tableName, const std::string& columnName) { - std::stringstream ss; - ss << "ALTER TABLE " << streaming_identifier(tableName) << " DROP COLUMN " - << streaming_identifier(columnName) << std::flush; - perform_void_exec(db, ss.str()); - } -#endif - - template - void drop_create_with_loss(sqlite3* db, const Table& table) { - // eliminated all transaction handling - this->drop_table_internal(db, table.name, false); - this->create_table(db, table.name, table); - } - - template - void backup_table(sqlite3* db, const Table& table, const std::vector& columnsToIgnore) { - - // here we copy source table to another with a name with '_backup' suffix, but in case table with such - // a name already exists we append suffix 1, then 2, etc until we find a free name.. - auto backupTableName = table.name + "_backup"; - if (this->table_exists(db, backupTableName)) { - int suffix = 1; - do { - std::stringstream ss; - ss << suffix << std::flush; - auto anotherBackupTableName = backupTableName + ss.str(); - if (!this->table_exists(db, anotherBackupTableName)) { - backupTableName = std::move(anotherBackupTableName); - break; - } - ++suffix; - } while (true); - } - this->create_table(db, backupTableName, table); - - this->copy_table(db, table.name, backupTableName, table, columnsToIgnore); - - this->drop_table_internal(db, table.name, false); - - this->rename_table(db, backupTableName, table.name); - } - - template - void assert_mapped_type() const { - static_assert(tuple_has_type::value, - "type is not mapped to storage"); - } - - template - void assert_updatable_type() const { -#if defined(SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED) - using Table = storage_pick_table_t; - using elements_type = elements_type_t; - using col_index_sequence = filter_tuple_sequence_t; - using pk_index_sequence = filter_tuple_sequence_t; - using pkcol_index_sequence = col_index_sequence_with; - constexpr size_t dedicatedPrimaryKeyColumnsCount = - nested_tuple_size_for_t::value; - - constexpr size_t primaryKeyColumnsCount = - dedicatedPrimaryKeyColumnsCount + pkcol_index_sequence::size(); - constexpr ptrdiff_t nonPrimaryKeysColumnsCount = col_index_sequence::size() - primaryKeyColumnsCount; - static_assert(primaryKeyColumnsCount > 0, "A table without primary keys cannot be updated"); - static_assert( - nonPrimaryKeysColumnsCount > 0, - "A table with only primary keys cannot be updated. You need at least 1 non-primary key column"); -#endif - } - - template, - std::enable_if_t = true> - void assert_insertable_type() const {} - - template, - std::enable_if_t = true> - void assert_insertable_type() const { - using elements_type = elements_type_t
; - using pkcol_index_sequence = col_index_sequence_with; - static_assert( - count_filtered_tuple::value <= 1, - "Attempting to execute 'insert' request into an noninsertable table was detected. " - "Insertable table cannot contain > 1 primary keys. Please use 'replace' instead of " - "'insert', or you can use 'insert' with explicit column listing."); - static_assert(count_filtered_tuple::template fn, - pkcol_index_sequence>::value == 0, - "Attempting to execute 'insert' request into an noninsertable table was detected. " - "Insertable table cannot contain non-standard primary keys. Please use 'replace' instead " - "of 'insert', or you can use 'insert' with explicit column listing."); - } - - template - auto& get_table() const { - return pick_table(this->db_objects); - } - - template - auto& get_table() { - return pick_table(this->db_objects); - } - - public: - template, class... Args> - mapped_view iterate(Args&&... args) { - this->assert_mapped_type(); - - auto con = this->get_connection(); - return {*this, std::move(con), std::forward(args)...}; - } - -#ifdef SQLITE_ORM_WITH_CPP20_ALIASES - template - auto iterate(Args&&... args) { - return this->iterate(std::forward(args)...); - } -#endif - -#if defined(SQLITE_ORM_SENTINEL_BASED_FOR_SUPPORTED) && defined(SQLITE_ORM_DEFAULT_COMPARISONS_SUPPORTED) - template -#ifdef SQLITE_ORM_CONCEPTS_SUPPORTED - requires (is_select_v
"; -} - diff --git a/src/htmx/HtmxTable.h b/src/htmx/HtmxTable.h deleted file mode 100644 index 9a57e8d..0000000 --- a/src/htmx/HtmxTable.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// Created by lukas on 5/11/25. -// - -#ifndef HTMXTABLE_H -#define HTMXTABLE_H - -#include "HtmxObject.h" -#include "HtmxTableRow.h" -#include "format" - -class HtmxTable : public HtmxObject { - -public: - template - requires std::convertible_to, std::string_view> - HtmxTable(const R& strings) { - // define the table header - html = ""; - for (const auto& s : strings) { - html += format("", s); - } - html += ""; - } - - /** - * Add a htmx row to the table - * - * @param row - * @return htmx representation of the row - */ - void add_row(const HtmxTableRow& row); - - /** - * Complete the table - */ - void complete(); - -}; -#endif //HTMXTABLE_H diff --git a/src/htmx/HtmxTableRow.cpp b/src/htmx/HtmxTableRow.cpp deleted file mode 100644 index 5b479f2..0000000 --- a/src/htmx/HtmxTableRow.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Created by lukas on 5/11/25. -// -#include -#include "HtmxTableRow.h" - -using namespace std; - -void HtmxTableRow::add_button(string_view endpoint, string_view name, string_view text) { - html += format("", endpoint, name, text); -} - -static string_view get_button_class(bool is_active) { - return is_active ? "active-button" : "inactive-button"; -} - -void HtmxTableRow::add_status_box(std::string_view name, bool is_active) { - html += format("", get_button_class(is_active), name); -} - -void HtmxTableRow::add(string_view text) { - html += format("", text); -} - -void HtmxTableRow::complete() { - html += ""; -} \ No newline at end of file diff --git a/src/htmx/HtmxTableRow.h b/src/htmx/HtmxTableRow.h deleted file mode 100644 index a95c2f3..0000000 --- a/src/htmx/HtmxTableRow.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by lukas on 5/11/25. -// - -#ifndef HTMXTABLEROW_H -#define HTMXTABLEROW_H - -#include -#include "HtmxObject.h" - -class HtmxTableRow : public HtmxObject { - -public: - void add_status_box(std::string_view name, bool is_active); - - void add_button(std::string_view endpoint, std::string_view name, std::string_view text); - - void add(std::string_view text); - - /** - * Complete the row - */ - void complete(); -}; - - - -#endif //HTMXTABLEROW_H diff --git a/src/htmx_helper.cpp b/src/htmx_helper.cpp deleted file mode 100644 index 0dc3144..0000000 --- a/src/htmx_helper.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// Created by lukas on 5/11/25. -// -#include -#include "systemd.h" -#include "htmx_helper.h" -#include "json_settings.h" -#include "utils.hpp" - -using namespace std; - -HtmxTableRow create_service_table_row(string_view service_name, string_view service_id) { - HtmxTableRow row; - - const bool isRunning = systemd::is_service_active(service_id); - const bool isEnabled = systemd::is_service_active(service_id); - - const auto running = isRunning ? "Running" : "Stopped"; - const auto enabled = isEnabled ? "Enabled" : "Disabled"; - - row.add(service_name); - row.add_status_box(running, isRunning); - row.add_status_box(enabled, isEnabled); - - // create buttons - row.add_button("/toggle-service", service_name, isRunning ? "Stop" : "Start"); - row.add_button("/restart-service", service_name, "Restart"); - row.complete(); - - return row; -} - -HtmxTableRow create_error_table_row(string_view error) { - HtmxTableRow row; - row.add("Error"); - row.add(error); - return row; -} - -HtmxTable create_service_table() { - constexpr array cols = { - "Service", "Status", "State" - }; - - HtmxTable table(cols); - - auto settings = AppSettings::loadAppSettings(); - - if(settings.has_value()){ - AppSettings& data = settings.value(); - for (auto& service : data.services) { - table.add_row(create_service_table_row(service.name, service.service)); - } - } - else { - table.add_row(create_error_table_row(settings.error())); - } - - return table; -} \ No newline at end of file diff --git a/src/htmx_helper.h b/src/htmx_helper.h deleted file mode 100644 index 7e7807b..0000000 --- a/src/htmx_helper.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Created by lukas on 5/11/25. -// - -#ifndef HTMX_HELPER_H -#define HTMX_HELPER_H - -#include -#include "htmx/HtmxTable.h" - -HtmxTableRow create_service_table_row(std::string_view service_name, std::string_view service_id); -HtmxTableRow create_error_table_row(std::string_view error); -HtmxTable create_service_table(); - -#endif //HTMX_HELPER_H diff --git a/src/json.hpp b/src/json.hpp deleted file mode 100644 index 31590ff..0000000 --- a/src/json.hpp +++ /dev/null @@ -1,25580 +0,0 @@ -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - -/****************************************************************************\ - * Note on documentation: The source files contain links to the online * - * documentation of the public API at https://json.nlohmann.me. This URL * - * contains the most recent documentation and should also be applicable to * - * previous versions; documentation for deprecated functions is not * - * removed, but marked deprecated. See "Generate documentation" section in * - * file docs/README.md. * -\****************************************************************************/ - -#ifndef INCLUDE_NLOHMANN_JSON_HPP_ -#define INCLUDE_NLOHMANN_JSON_HPP_ - -#include // all_of, find, for_each -#include // nullptr_t, ptrdiff_t, size_t -#include // hash, less -#include // initializer_list -#ifndef JSON_NO_IO - #include // istream, ostream -#endif // JSON_NO_IO -#include // random_access_iterator_tag -#include // unique_ptr -#include // string, stoi, to_string -#include // declval, forward, move, pair, swap -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// This file contains all macro definitions affecting or depending on the ABI - -#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK - #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) - #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0 - #warning "Already included a different version of the library!" - #endif - #endif -#endif - -#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum) - -#ifndef JSON_DIAGNOSTICS - #define JSON_DIAGNOSTICS 0 -#endif - -#ifndef JSON_DIAGNOSTIC_POSITIONS - #define JSON_DIAGNOSTIC_POSITIONS 0 -#endif - -#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 -#endif - -#if JSON_DIAGNOSTICS - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag -#else - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS -#endif - -#if JSON_DIAGNOSTIC_POSITIONS - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp -#else - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS -#endif - -#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp -#else - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION - #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 -#endif - -// Construct the namespace ABI tags component -#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c -#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \ - NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) - -#define NLOHMANN_JSON_ABI_TAGS \ - NLOHMANN_JSON_ABI_TAGS_CONCAT( \ - NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ - NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \ - NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS) - -// Construct the namespace version component -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ - _v ## major ## _ ## minor ## _ ## patch -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) - -#if NLOHMANN_JSON_NAMESPACE_NO_VERSION -#define NLOHMANN_JSON_NAMESPACE_VERSION -#else -#define NLOHMANN_JSON_NAMESPACE_VERSION \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ - NLOHMANN_JSON_VERSION_MINOR, \ - NLOHMANN_JSON_VERSION_PATCH) -#endif - -// Combine namespace components -#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b -#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ - NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) - -#ifndef NLOHMANN_JSON_NAMESPACE -#define NLOHMANN_JSON_NAMESPACE \ - nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN -#define NLOHMANN_JSON_NAMESPACE_BEGIN \ - namespace nlohmann \ - { \ - inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) \ - { -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_END -#define NLOHMANN_JSON_NAMESPACE_END \ - } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ - } // namespace nlohmann -#endif - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // transform -#include // array -#include // forward_list -#include // inserter, front_inserter, end -#include // map -#include // string -#include // tuple, make_tuple -#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible -#include // unordered_map -#include // pair, declval -#include // valarray - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // nullptr_t -#include // exception -#if JSON_DIAGNOSTICS - #include // accumulate -#endif -#include // runtime_error -#include // to_string -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // uint8_t -#include // string - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // declval, pair -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -// https://en.cppreference.com/w/cpp/experimental/is_detected -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; -}; - -template class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; - -template class Op, class... Args> -using is_detected = typename detector::value_t; - -template class Op, class... Args> -struct is_detected_lazy : is_detected { }; - -template class Op, class... Args> -using detected_t = typename detector::type; - -template class Op, class... Args> -using detected_or = detector; - -template class Op, class... Args> -using detected_or_t = typename detected_or::type; - -template class Op, class... Args> -using is_detected_exact = std::is_same>; - -template class Op, class... Args> -using is_detected_convertible = - std::is_convertible, To>; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - - -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-FileCopyrightText: 2016 - 2021 Evan Nemerson -// SPDX-License-Identifier: MIT - -/* Hedley - https://nemequ.github.io/hedley - * Created by Evan Nemerson - */ - -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) -#if defined(JSON_HEDLEY_VERSION) - #undef JSON_HEDLEY_VERSION -#endif -#define JSON_HEDLEY_VERSION 15 - -#if defined(JSON_HEDLEY_STRINGIFY_EX) - #undef JSON_HEDLEY_STRINGIFY_EX -#endif -#define JSON_HEDLEY_STRINGIFY_EX(x) #x - -#if defined(JSON_HEDLEY_STRINGIFY) - #undef JSON_HEDLEY_STRINGIFY -#endif -#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) - -#if defined(JSON_HEDLEY_CONCAT_EX) - #undef JSON_HEDLEY_CONCAT_EX -#endif -#define JSON_HEDLEY_CONCAT_EX(a,b) a##b - -#if defined(JSON_HEDLEY_CONCAT) - #undef JSON_HEDLEY_CONCAT -#endif -#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) - -#if defined(JSON_HEDLEY_CONCAT3_EX) - #undef JSON_HEDLEY_CONCAT3_EX -#endif -#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c - -#if defined(JSON_HEDLEY_CONCAT3) - #undef JSON_HEDLEY_CONCAT3 -#endif -#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) - -#if defined(JSON_HEDLEY_VERSION_ENCODE) - #undef JSON_HEDLEY_VERSION_ENCODE -#endif -#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) - #undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) - #undef JSON_HEDLEY_VERSION_DECODE_MINOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) - #undef JSON_HEDLEY_VERSION_DECODE_REVISION -#endif -#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) - -#if defined(JSON_HEDLEY_GNUC_VERSION) - #undef JSON_HEDLEY_GNUC_VERSION -#endif -#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#elif defined(__GNUC__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) -#endif - -#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) - #undef JSON_HEDLEY_GNUC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GNUC_VERSION) - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION) - #undef JSON_HEDLEY_MSVC_VERSION -#endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) - #undef JSON_HEDLEY_MSVC_VERSION_CHECK -#endif -#if !defined(JSON_HEDLEY_MSVC_VERSION) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) -#else - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION) - #undef JSON_HEDLEY_INTEL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_VERSION) - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #undef JSON_HEDLEY_INTEL_CL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) - #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION) - #undef JSON_HEDLEY_PGI_VERSION -#endif -#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) - #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) - #undef JSON_HEDLEY_PGI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PGI_VERSION) - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #undef JSON_HEDLEY_SUNPRO_VERSION -#endif -#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) -#elif defined(__SUNPRO_C) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) -#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) -#elif defined(__SUNPRO_CC) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) - #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#endif -#if defined(__EMSCRIPTEN__) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION) - #undef JSON_HEDLEY_ARM_VERSION -#endif -#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) -#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) - #undef JSON_HEDLEY_ARM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_ARM_VERSION) - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION) - #undef JSON_HEDLEY_IBM_VERSION -#endif -#if defined(__ibmxl__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) -#elif defined(__xlC__) && defined(__xlC_ver__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) -#elif defined(__xlC__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) - #undef JSON_HEDLEY_IBM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IBM_VERSION) - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_VERSION) - #undef JSON_HEDLEY_TI_VERSION -#endif -#if \ - defined(__TI_COMPILER_VERSION__) && \ - ( \ - defined(__TMS470__) || defined(__TI_ARM__) || \ - defined(__MSP430__) || \ - defined(__TMS320C2000__) \ - ) -#if (__TI_COMPILER_VERSION__ >= 16000000) - #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif -#endif - -#if defined(JSON_HEDLEY_TI_VERSION_CHECK) - #undef JSON_HEDLEY_TI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_VERSION) - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #undef JSON_HEDLEY_TI_CL2000_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) - #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #undef JSON_HEDLEY_TI_CL430_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) - #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #undef JSON_HEDLEY_TI_ARMCL_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) - #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) - #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #undef JSON_HEDLEY_TI_CL6X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) - #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #undef JSON_HEDLEY_TI_CL7X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) - #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #undef JSON_HEDLEY_TI_CLPRU_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) - #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION) - #undef JSON_HEDLEY_CRAY_VERSION -#endif -#if defined(_CRAYC) - #if defined(_RELEASE_PATCHLEVEL) - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) - #else - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) - #undef JSON_HEDLEY_CRAY_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_CRAY_VERSION) - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION) - #undef JSON_HEDLEY_IAR_VERSION -#endif -#if defined(__IAR_SYSTEMS_ICC__) - #if __VER__ > 1000 - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) - #else - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) - #undef JSON_HEDLEY_IAR_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IAR_VERSION) - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION) - #undef JSON_HEDLEY_TINYC_VERSION -#endif -#if defined(__TINYC__) - #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) - #undef JSON_HEDLEY_TINYC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION) - #undef JSON_HEDLEY_DMC_VERSION -#endif -#if defined(__DMC__) - #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) - #undef JSON_HEDLEY_DMC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_DMC_VERSION) - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #undef JSON_HEDLEY_COMPCERT_VERSION -#endif -#if defined(__COMPCERT_VERSION__) - #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) - #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION) - #undef JSON_HEDLEY_PELLES_VERSION -#endif -#if defined(__POCC__) - #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) - #undef JSON_HEDLEY_PELLES_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PELLES_VERSION) - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #undef JSON_HEDLEY_MCST_LCC_VERSION -#endif -#if defined(__LCC__) && defined(__LCC_MINOR__) - #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) - #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION) - #undef JSON_HEDLEY_GCC_VERSION -#endif -#if \ - defined(JSON_HEDLEY_GNUC_VERSION) && \ - !defined(__clang__) && \ - !defined(JSON_HEDLEY_INTEL_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_ARM_VERSION) && \ - !defined(JSON_HEDLEY_CRAY_VERSION) && \ - !defined(JSON_HEDLEY_TI_VERSION) && \ - !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ - !defined(__COMPCERT__) && \ - !defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_ATTRIBUTE -#endif -#if \ - defined(__has_attribute) && \ - ( \ - (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ - ) -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) -#else -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#endif -#if \ - defined(__has_cpp_attribute) && \ - defined(__cplusplus) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#endif -#if !defined(__cplusplus) || !defined(__has_cpp_attribute) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#elif \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ - (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_BUILTIN) - #undef JSON_HEDLEY_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) -#else - #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) - #undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) - #undef JSON_HEDLEY_GCC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_FEATURE) - #undef JSON_HEDLEY_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) -#else - #define JSON_HEDLEY_HAS_FEATURE(feature) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) - #undef JSON_HEDLEY_GNUC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) - #undef JSON_HEDLEY_GCC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_EXTENSION) - #undef JSON_HEDLEY_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) -#else - #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) - #undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) - #undef JSON_HEDLEY_GCC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_WARNING) - #undef JSON_HEDLEY_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) -#else - #define JSON_HEDLEY_HAS_WARNING(warning) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) - #undef JSON_HEDLEY_GNUC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_WARNING) - #undef JSON_HEDLEY_GCC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(__clang__) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) - #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_PRAGMA(value) __pragma(value) -#else - #define JSON_HEDLEY_PRAGMA(value) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) - #undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#endif -#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) - #undef JSON_HEDLEY_DIAGNOSTIC_POP -#endif -#if defined(__clang__) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) - #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) -#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_PUSH - #define JSON_HEDLEY_DIAGNOSTIC_POP -#endif - -/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") -# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") -# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# endif -#endif -#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x -#endif - -#if defined(JSON_HEDLEY_CONST_CAST) - #undef JSON_HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) -#elif \ - JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_REINTERPRET_CAST) - #undef JSON_HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) -#else - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_STATIC_CAST) - #undef JSON_HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) -#else - #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_CPP_CAST) - #undef JSON_HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ - ((T) (expr)) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("diag_suppress=Pe137") \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) -# endif -#else -# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif - -#if defined(JSON_HEDLEY_DEPRECATED) - #undef JSON_HEDLEY_DEPRECATED -#endif -#if defined(JSON_HEDLEY_DEPRECATED_FOR) - #undef JSON_HEDLEY_DEPRECATED_FOR -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) -#elif \ - (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) -#elif defined(__cplusplus) && (__cplusplus >= 201402L) - #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") -#else - #define JSON_HEDLEY_DEPRECATED(since) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) -#endif - -#if defined(JSON_HEDLEY_UNAVAILABLE) - #undef JSON_HEDLEY_UNAVAILABLE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) -#else - #define JSON_HEDLEY_UNAVAILABLE(available_since) -#endif - -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT -#endif -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) -#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#elif defined(_Check_return_) /* SAL */ - #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ -#else - #define JSON_HEDLEY_WARN_UNUSED_RESULT - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) -#endif - -#if defined(JSON_HEDLEY_SENTINEL) - #undef JSON_HEDLEY_SENTINEL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) -#else - #define JSON_HEDLEY_SENTINEL(position) -#endif - -#if defined(JSON_HEDLEY_NO_RETURN) - #undef JSON_HEDLEY_NO_RETURN -#endif -#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NO_RETURN __noreturn -#elif \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L - #define JSON_HEDLEY_NO_RETURN _Noreturn -#elif defined(__cplusplus) && (__cplusplus >= 201103L) - #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#else - #define JSON_HEDLEY_NO_RETURN -#endif - -#if defined(JSON_HEDLEY_NO_ESCAPE) - #undef JSON_HEDLEY_NO_ESCAPE -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) - #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) -#else - #define JSON_HEDLEY_NO_ESCAPE -#endif - -#if defined(JSON_HEDLEY_UNREACHABLE) - #undef JSON_HEDLEY_UNREACHABLE -#endif -#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) - #undef JSON_HEDLEY_UNREACHABLE_RETURN -#endif -#if defined(JSON_HEDLEY_ASSUME) - #undef JSON_HEDLEY_ASSUME -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_ASSUME(expr) __assume(expr) -#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) - #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #if defined(__cplusplus) - #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) - #else - #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) - #endif -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif defined(JSON_HEDLEY_ASSUME) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif -#if !defined(JSON_HEDLEY_ASSUME) - #if defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) - #else - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) - #endif -#endif -#if defined(JSON_HEDLEY_UNREACHABLE) - #if \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) - #else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() - #endif -#else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) -#endif -#if !defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif - -JSON_HEDLEY_DIAGNOSTIC_PUSH -#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") - #pragma clang diagnostic ignored "-Wpedantic" -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) - #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif -#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) - #if defined(__clang__) - #pragma clang diagnostic ignored "-Wvariadic-macros" - #elif defined(JSON_HEDLEY_GCC_VERSION) - #pragma GCC diagnostic ignored "-Wvariadic-macros" - #endif -#endif -#if defined(JSON_HEDLEY_NON_NULL) - #undef JSON_HEDLEY_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else - #define JSON_HEDLEY_NON_NULL(...) -#endif -JSON_HEDLEY_DIAGNOSTIC_POP - -#if defined(JSON_HEDLEY_PRINTF_FORMAT) - #undef JSON_HEDLEY_PRINTF_FORMAT -#endif -#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) -#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) -#else - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) -#endif - -#if defined(JSON_HEDLEY_CONSTEXPR) - #undef JSON_HEDLEY_CONSTEXPR -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) - #endif -#endif -#if !defined(JSON_HEDLEY_CONSTEXPR) - #define JSON_HEDLEY_CONSTEXPR -#endif - -#if defined(JSON_HEDLEY_PREDICT) - #undef JSON_HEDLEY_PREDICT -#endif -#if defined(JSON_HEDLEY_LIKELY) - #undef JSON_HEDLEY_LIKELY -#endif -#if defined(JSON_HEDLEY_UNLIKELY) - #undef JSON_HEDLEY_UNLIKELY -#endif -#if defined(JSON_HEDLEY_UNPREDICTABLE) - #undef JSON_HEDLEY_UNPREDICTABLE -#endif -#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) - #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) -#elif \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ - })) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ - })) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) -# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) -#endif -#if !defined(JSON_HEDLEY_UNPREDICTABLE) - #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) -#endif - -#if defined(JSON_HEDLEY_MALLOC) - #undef JSON_HEDLEY_MALLOC -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_MALLOC __declspec(restrict) -#else - #define JSON_HEDLEY_MALLOC -#endif - -#if defined(JSON_HEDLEY_PURE) - #undef JSON_HEDLEY_PURE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PURE __attribute__((__pure__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ - ) -# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") -#else -# define JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_CONST) - #undef JSON_HEDLEY_CONST -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_CONST __attribute__((__const__)) -#elif \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_CONST _Pragma("no_side_effect") -#else - #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_RESTRICT) - #undef JSON_HEDLEY_RESTRICT -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT restrict -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RESTRICT __restrict -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT _Restrict -#else - #define JSON_HEDLEY_RESTRICT -#endif - -#if defined(JSON_HEDLEY_INLINE) - #undef JSON_HEDLEY_INLINE -#endif -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 199711L)) - #define JSON_HEDLEY_INLINE inline -#elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) - #define JSON_HEDLEY_INLINE __inline__ -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_INLINE __inline -#else - #define JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_ALWAYS_INLINE) - #undef JSON_HEDLEY_ALWAYS_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_ALWAYS_INLINE __forceinline -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ - ) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") -#else -# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_NEVER_INLINE) - #undef JSON_HEDLEY_NEVER_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#else - #define JSON_HEDLEY_NEVER_INLINE -#endif - -#if defined(JSON_HEDLEY_PRIVATE) - #undef JSON_HEDLEY_PRIVATE -#endif -#if defined(JSON_HEDLEY_PUBLIC) - #undef JSON_HEDLEY_PUBLIC -#endif -#if defined(JSON_HEDLEY_IMPORT) - #undef JSON_HEDLEY_IMPORT -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC __declspec(dllexport) -# define JSON_HEDLEY_IMPORT __declspec(dllimport) -#else -# if \ - JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - ( \ - defined(__TI_EABI__) && \ - ( \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ - ) \ - ) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) -# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) -# else -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC -# endif -# define JSON_HEDLEY_IMPORT extern -#endif - -#if defined(JSON_HEDLEY_NO_THROW) - #undef JSON_HEDLEY_NO_THROW -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NO_THROW __declspec(nothrow) -#else - #define JSON_HEDLEY_NO_THROW -#endif - -#if defined(JSON_HEDLEY_FALL_THROUGH) - #undef JSON_HEDLEY_FALL_THROUGH -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) -#elif defined(__fallthrough) /* SAL */ - #define JSON_HEDLEY_FALL_THROUGH __fallthrough -#else - #define JSON_HEDLEY_FALL_THROUGH -#endif - -#if defined(JSON_HEDLEY_RETURNS_NON_NULL) - #undef JSON_HEDLEY_RETURNS_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) -#elif defined(_Ret_notnull_) /* SAL */ - #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ -#else - #define JSON_HEDLEY_RETURNS_NON_NULL -#endif - -#if defined(JSON_HEDLEY_ARRAY_PARAM) - #undef JSON_HEDLEY_ARRAY_PARAM -#endif -#if \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__STDC_NO_VLA__) && \ - !defined(__cplusplus) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_ARRAY_PARAM(name) (name) -#else - #define JSON_HEDLEY_ARRAY_PARAM(name) -#endif - -#if defined(JSON_HEDLEY_IS_CONSTANT) - #undef JSON_HEDLEY_IS_CONSTANT -#endif -#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) - #undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#endif -/* JSON_HEDLEY_IS_CONSTEXPR_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #undef JSON_HEDLEY_IS_CONSTEXPR_ -#endif -#if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) -#endif -#if !defined(__cplusplus) -# if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) -#endif -# elif \ - ( \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ - !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION)) || \ - (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) -#endif -# elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - defined(JSON_HEDLEY_INTEL_VERSION) || \ - defined(JSON_HEDLEY_TINYC_VERSION) || \ - defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ - defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ - defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ - defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ - defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ - defined(__clang__) -# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ - sizeof(void) != \ - sizeof(*( \ - 1 ? \ - ((void*) ((expr) * 0L) ) : \ -((struct { char v[sizeof(void) * 2]; } *) 1) \ - ) \ - ) \ - ) -# endif -#endif -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) -#else - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) (0) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) -#endif - -#if defined(JSON_HEDLEY_BEGIN_C_DECLS) - #undef JSON_HEDLEY_BEGIN_C_DECLS -#endif -#if defined(JSON_HEDLEY_END_C_DECLS) - #undef JSON_HEDLEY_END_C_DECLS -#endif -#if defined(JSON_HEDLEY_C_DECL) - #undef JSON_HEDLEY_C_DECL -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { - #define JSON_HEDLEY_END_C_DECLS } - #define JSON_HEDLEY_C_DECL extern "C" -#else - #define JSON_HEDLEY_BEGIN_C_DECLS - #define JSON_HEDLEY_END_C_DECLS - #define JSON_HEDLEY_C_DECL -#endif - -#if defined(JSON_HEDLEY_STATIC_ASSERT) - #undef JSON_HEDLEY_STATIC_ASSERT -#endif -#if \ - !defined(__cplusplus) && ( \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - defined(_Static_assert) \ - ) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) -#elif \ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) -#else -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) -#endif - -#if defined(JSON_HEDLEY_NULL) - #undef JSON_HEDLEY_NULL -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) - #elif defined(NULL) - #define JSON_HEDLEY_NULL NULL - #else - #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) - #endif -#elif defined(NULL) - #define JSON_HEDLEY_NULL NULL -#else - #define JSON_HEDLEY_NULL ((void*) 0) -#endif - -#if defined(JSON_HEDLEY_MESSAGE) - #undef JSON_HEDLEY_MESSAGE -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_MESSAGE(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(message msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) -#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_WARNING) - #undef JSON_HEDLEY_WARNING -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_WARNING(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(clang warning msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_REQUIRE) - #undef JSON_HEDLEY_REQUIRE -#endif -#if defined(JSON_HEDLEY_REQUIRE_MSG) - #undef JSON_HEDLEY_REQUIRE_MSG -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) -# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") -# define JSON_HEDLEY_REQUIRE(expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), #expr, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), msg, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) -# endif -#else -# define JSON_HEDLEY_REQUIRE(expr) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) -#endif - -#if defined(JSON_HEDLEY_FLAGS) - #undef JSON_HEDLEY_FLAGS -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) - #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) -#else - #define JSON_HEDLEY_FLAGS -#endif - -#if defined(JSON_HEDLEY_FLAGS_CAST) - #undef JSON_HEDLEY_FLAGS_CAST -#endif -#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) -# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("warning(disable:188)") \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) -#endif - -#if defined(JSON_HEDLEY_EMPTY_BASES) - #undef JSON_HEDLEY_EMPTY_BASES -#endif -#if \ - (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) -#else - #define JSON_HEDLEY_EMPTY_BASES -#endif - -/* Remaining macros are deprecated. */ - -#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#endif -#if defined(__clang__) - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) -#else - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) - #undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#endif -#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) - -#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) - #undef JSON_HEDLEY_CLANG_HAS_FEATURE -#endif -#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) - -#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) - #undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#endif -#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) - -#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) - #undef JSON_HEDLEY_CLANG_HAS_WARNING -#endif -#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) - -#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ - - -// This file contains all internal macro definitions (except those affecting ABI) -// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them - -// #include - - -// exclude unsupported compilers -#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) - #if defined(__clang__) - #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 - #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) - #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 - #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #endif -#endif - -// C++ language standard detection -// if the user manually specified the used C++ version, this is skipped -#if !defined(JSON_HAS_CPP_23) && !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) - #if (defined(__cplusplus) && __cplusplus > 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202002L) - #define JSON_HAS_CPP_23 - #define JSON_HAS_CPP_20 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus > 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L) - #define JSON_HAS_CPP_20 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus > 201402L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus > 201103L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 - #endif - // the cpp 11 flag is always specified because it is the minimal required version - #define JSON_HAS_CPP_11 -#endif - -#ifdef __has_include - #if __has_include() - #include - #endif -#endif - -#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) - #ifdef JSON_HAS_CPP_17 - #if defined(__cpp_lib_filesystem) - #define JSON_HAS_FILESYSTEM 1 - #elif defined(__cpp_lib_experimental_filesystem) - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #elif !defined(__has_include) - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #elif __has_include() - #define JSON_HAS_FILESYSTEM 1 - #elif __has_include() - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #endif - - // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ - #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support - #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support - #if defined(__clang_major__) && __clang_major__ < 7 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support - #if defined(_MSC_VER) && _MSC_VER < 1914 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before iOS 13 - #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before macOS Catalina - #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - #endif -#endif - -#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_FILESYSTEM - #define JSON_HAS_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_THREE_WAY_COMPARISON - #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ - && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L - #define JSON_HAS_THREE_WAY_COMPARISON 1 - #else - #define JSON_HAS_THREE_WAY_COMPARISON 0 - #endif -#endif - -#ifndef JSON_HAS_RANGES - // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has a syntax error - #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 - #define JSON_HAS_RANGES 0 - #elif defined(__cpp_lib_ranges) - #define JSON_HAS_RANGES 1 - #else - #define JSON_HAS_RANGES 0 - #endif -#endif - -#ifndef JSON_HAS_STATIC_RTTI - #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0 - #define JSON_HAS_STATIC_RTTI 1 - #else - #define JSON_HAS_STATIC_RTTI 0 - #endif -#endif - -#ifdef JSON_HAS_CPP_17 - #define JSON_INLINE_VARIABLE inline -#else - #define JSON_INLINE_VARIABLE -#endif - -#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) - #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] -#else - #define JSON_NO_UNIQUE_ADDRESS -#endif - -// disable documentation warnings on clang -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdocumentation" - #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -#endif - -// allow disabling exceptions -#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) - #define JSON_THROW(exception) throw exception - #define JSON_TRY try - #define JSON_CATCH(exception) catch(exception) - #define JSON_INTERNAL_CATCH(exception) catch(exception) -#else - #include - #define JSON_THROW(exception) std::abort() - #define JSON_TRY if(true) - #define JSON_CATCH(exception) if(false) - #define JSON_INTERNAL_CATCH(exception) if(false) -#endif - -// override exception macros -#if defined(JSON_THROW_USER) - #undef JSON_THROW - #define JSON_THROW JSON_THROW_USER -#endif -#if defined(JSON_TRY_USER) - #undef JSON_TRY - #define JSON_TRY JSON_TRY_USER -#endif -#if defined(JSON_CATCH_USER) - #undef JSON_CATCH - #define JSON_CATCH JSON_CATCH_USER - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_CATCH_USER -#endif -#if defined(JSON_INTERNAL_CATCH_USER) - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER -#endif - -// allow overriding assert -#if !defined(JSON_ASSERT) - #include // assert - #define JSON_ASSERT(x) assert(x) -#endif - -// allow accessing some private functions (needed by the test suite) -#if defined(JSON_TESTS_PRIVATE) - #define JSON_PRIVATE_UNLESS_TESTED public -#else - #define JSON_PRIVATE_UNLESS_TESTED private -#endif - -/*! -@brief macro to briefly define a mapping between an enum and JSON -@def NLOHMANN_JSON_SERIALIZE_ENUM -@since version 3.4.0 -*/ -#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template \ - inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ - { \ - /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.first == e; \ - }); \ - j = ((it != std::end(m)) ? it : std::begin(m))->second; \ - } \ - template \ - inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ - { \ - /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [&j](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.second == j; \ - }); \ - e = ((it != std::end(m)) ? it : std::begin(m))->first; \ - } - -// Ugly macros to avoid uglier copy-paste when specializing basic_json. They -// may be removed in the future once the class is split. - -#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ - template class ObjectType, \ - template class ArrayType, \ - class StringType, class BooleanType, class NumberIntegerType, \ - class NumberUnsignedType, class NumberFloatType, \ - template class AllocatorType, \ - template class JSONSerializer, \ - class BinaryType, \ - class CustomBaseClass> - -#define NLOHMANN_BASIC_JSON_TPL \ - basic_json - -// Macros to simplify conversion from/to types - -#define NLOHMANN_JSON_EXPAND( x ) x -#define NLOHMANN_JSON_GET_MACRO(_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, _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, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME -#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ - NLOHMANN_JSON_PASTE64, \ - NLOHMANN_JSON_PASTE63, \ - NLOHMANN_JSON_PASTE62, \ - NLOHMANN_JSON_PASTE61, \ - NLOHMANN_JSON_PASTE60, \ - NLOHMANN_JSON_PASTE59, \ - NLOHMANN_JSON_PASTE58, \ - NLOHMANN_JSON_PASTE57, \ - NLOHMANN_JSON_PASTE56, \ - NLOHMANN_JSON_PASTE55, \ - NLOHMANN_JSON_PASTE54, \ - NLOHMANN_JSON_PASTE53, \ - NLOHMANN_JSON_PASTE52, \ - NLOHMANN_JSON_PASTE51, \ - NLOHMANN_JSON_PASTE50, \ - NLOHMANN_JSON_PASTE49, \ - NLOHMANN_JSON_PASTE48, \ - NLOHMANN_JSON_PASTE47, \ - NLOHMANN_JSON_PASTE46, \ - NLOHMANN_JSON_PASTE45, \ - NLOHMANN_JSON_PASTE44, \ - NLOHMANN_JSON_PASTE43, \ - NLOHMANN_JSON_PASTE42, \ - NLOHMANN_JSON_PASTE41, \ - NLOHMANN_JSON_PASTE40, \ - NLOHMANN_JSON_PASTE39, \ - NLOHMANN_JSON_PASTE38, \ - NLOHMANN_JSON_PASTE37, \ - NLOHMANN_JSON_PASTE36, \ - NLOHMANN_JSON_PASTE35, \ - NLOHMANN_JSON_PASTE34, \ - NLOHMANN_JSON_PASTE33, \ - NLOHMANN_JSON_PASTE32, \ - NLOHMANN_JSON_PASTE31, \ - NLOHMANN_JSON_PASTE30, \ - NLOHMANN_JSON_PASTE29, \ - NLOHMANN_JSON_PASTE28, \ - NLOHMANN_JSON_PASTE27, \ - NLOHMANN_JSON_PASTE26, \ - NLOHMANN_JSON_PASTE25, \ - NLOHMANN_JSON_PASTE24, \ - NLOHMANN_JSON_PASTE23, \ - NLOHMANN_JSON_PASTE22, \ - NLOHMANN_JSON_PASTE21, \ - NLOHMANN_JSON_PASTE20, \ - NLOHMANN_JSON_PASTE19, \ - NLOHMANN_JSON_PASTE18, \ - NLOHMANN_JSON_PASTE17, \ - NLOHMANN_JSON_PASTE16, \ - NLOHMANN_JSON_PASTE15, \ - NLOHMANN_JSON_PASTE14, \ - NLOHMANN_JSON_PASTE13, \ - NLOHMANN_JSON_PASTE12, \ - NLOHMANN_JSON_PASTE11, \ - NLOHMANN_JSON_PASTE10, \ - NLOHMANN_JSON_PASTE9, \ - NLOHMANN_JSON_PASTE8, \ - NLOHMANN_JSON_PASTE7, \ - NLOHMANN_JSON_PASTE6, \ - NLOHMANN_JSON_PASTE5, \ - NLOHMANN_JSON_PASTE4, \ - NLOHMANN_JSON_PASTE3, \ - NLOHMANN_JSON_PASTE2, \ - NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) -#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) -#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) -#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) -#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) -#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) -#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) -#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) -#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) -#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) -#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) -#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) -#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) -#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) -#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) -#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) -#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) -#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) -#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) -#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) -#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) -#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) -#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) -#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) -#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) -#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) -#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) -#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) -#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) -#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) -#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) -#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) -#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) -#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) -#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) -#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) -#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) -#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) -#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) -#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) -#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) -#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) -#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) -#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) -#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) -#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) -#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) -#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) -#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) -#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) -#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) -#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) -#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) -#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) -#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) -#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) -#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) - -#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; -#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); -#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1) : nlohmann_json_default_obj.v1; - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE -@since version 3.9.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - template::value, int> = 0> \ - friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - template::value, int> = 0> \ - friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT -@since version 3.11.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - template::value, int> = 0> \ - friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - template::value, int> = 0> \ - friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE -@since version 3.11.3 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ - template::value, int> = 0> \ - friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE -@since version 3.9.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - template::value, int> = 0> \ - void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - template::value, int> = 0> \ - void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT -@since version 3.11.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - template::value, int> = 0> \ - void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - template::value, int> = 0> \ - void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE -@since version 3.11.3 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ - template::value, int> = 0> \ - void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE -@since version 3.12.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ -*/ -#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ - template::value, int> = 0> \ - friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - template::value, int> = 0> \ - friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT -@since version 3.12.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ -*/ -#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ - template::value, int> = 0> \ - friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - template::value, int> = 0> \ - friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE -@since version 3.12.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ -*/ -#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ - template::value, int> = 0> \ - friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE -@since version 3.12.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ -*/ -#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ - template::value, int> = 0> \ - void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - template::value, int> = 0> \ - void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT -@since version 3.12.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ -*/ -#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ - template::value, int> = 0> \ - void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - template::value, int> = 0> \ - void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE -@since version 3.12.0 -@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ -*/ -#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ - template::value, int> = 0> \ - void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } - -// inspired from https://stackoverflow.com/a/26745591 -// allows calling any std function as if (e.g., with begin): -// using std::begin; begin(x); -// -// it allows using the detected idiom to retrieve the return type -// of such an expression -#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ - namespace detail { \ - using std::std_name; \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - } \ - \ - namespace detail2 { \ - struct std_name##_tag \ - { \ - }; \ - \ - template \ - std_name##_tag std_name(T&&...); \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - \ - template \ - struct would_call_std_##std_name \ - { \ - static constexpr auto const value = ::nlohmann::detail:: \ - is_detected_exact::value; \ - }; \ - } /* namespace detail2 */ \ - \ - template \ - struct would_call_std_##std_name : detail2::would_call_std_##std_name \ - { \ - } - -#ifndef JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_USE_IMPLICIT_CONVERSIONS 1 -#endif - -#if JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_EXPLICIT -#else - #define JSON_EXPLICIT explicit -#endif - -#ifndef JSON_DISABLE_ENUM_SERIALIZATION - #define JSON_DISABLE_ENUM_SERIALIZATION 0 -#endif - -#ifndef JSON_USE_GLOBAL_UDLS - #define JSON_USE_GLOBAL_UDLS 1 -#endif - -#if JSON_HAS_THREE_WAY_COMPARISON - #include // partial_ordering -#endif - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/////////////////////////// -// JSON type enumeration // -/////////////////////////// - -/*! -@brief the JSON type enumeration - -This enumeration collects the different JSON types. It is internally used to -distinguish the stored values, and the functions @ref basic_json::is_null(), -@ref basic_json::is_object(), @ref basic_json::is_array(), -@ref basic_json::is_string(), @ref basic_json::is_boolean(), -@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), -@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), -@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and -@ref basic_json::is_structured() rely on it. - -@note There are three enumeration entries (number_integer, number_unsigned, and -number_float), because the library distinguishes these three types for numbers: -@ref basic_json::number_unsigned_t is used for unsigned integers, -@ref basic_json::number_integer_t is used for signed integers, and -@ref basic_json::number_float_t is used for floating-point numbers or to -approximate integers which do not fit in the limits of their respective type. - -@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON -value with the default value for a given type - -@since version 1.0.0 -*/ -enum class value_t : std::uint8_t -{ - null, ///< null value - object, ///< object (unordered set of name/value pairs) - array, ///< array (ordered collection of values) - string, ///< string value - boolean, ///< boolean value - number_integer, ///< number value (signed integer) - number_unsigned, ///< number value (unsigned integer) - number_float, ///< number value (floating-point) - binary, ///< binary array (ordered collection of bytes) - discarded ///< discarded by the parser callback function -}; - -/*! -@brief comparison operator for JSON types - -Returns an ordering that is similar to Python: -- order: null < boolean < number < object < array < string < binary -- furthermore, each type is not smaller than itself -- discarded values are not comparable -- binary is represented as a b"" string in python and directly comparable to a - string; however, making a binary array directly comparable with a string would - be surprising behavior in a JSON file. - -@since version 1.0.0 -*/ -#if JSON_HAS_THREE_WAY_COMPARISON - inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* -#else - inline bool operator<(const value_t lhs, const value_t rhs) noexcept -#endif -{ - static constexpr std::array order = {{ - 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, - 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, - 6 /* binary */ - } - }; - - const auto l_index = static_cast(lhs); - const auto r_index = static_cast(rhs); -#if JSON_HAS_THREE_WAY_COMPARISON - if (l_index < order.size() && r_index < order.size()) - { - return order[l_index] <=> order[r_index]; // *NOPAD* - } - return std::partial_ordering::unordered; -#else - return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; -#endif -} - -// GCC selects the built-in operator< over an operator rewritten from -// a user-defined spaceship operator -// Clang, MSVC, and ICC select the rewritten candidate -// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) -#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) -inline bool operator<(const value_t lhs, const value_t rhs) noexcept -{ - return std::is_lt(lhs <=> rhs); // *NOPAD* -} -#endif - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/*! -@brief replace all occurrences of a substring by another string - -@param[in,out] s the string to manipulate; changed so that all - occurrences of @a f are replaced with @a t -@param[in] f the substring to replace with @a t -@param[in] t the string to replace @a f - -@pre The search string @a f must not be empty. **This precondition is -enforced with an assertion.** - -@since version 2.0.0 -*/ -template -inline void replace_substring(StringType& s, const StringType& f, - const StringType& t) -{ - JSON_ASSERT(!f.empty()); - for (auto pos = s.find(f); // find the first occurrence of f - pos != StringType::npos; // make sure f was found - s.replace(pos, f.size(), t), // replace with t, and - pos = s.find(f, pos + t.size())) // find the next occurrence of f - {} -} - -/*! - * @brief string escaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to escape - * @return escaped string - * - * Note the order of escaping "~" to "~0" and "/" to "~1" is important. - */ -template -inline StringType escape(StringType s) -{ - replace_substring(s, StringType{"~"}, StringType{"~0"}); - replace_substring(s, StringType{"/"}, StringType{"~1"}); - return s; -} - -/*! - * @brief string unescaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to unescape - * @return unescaped string - * - * Note the order of escaping "~1" to "/" and "~0" to "~" is important. - */ -template -inline void unescape(StringType& s) -{ - replace_substring(s, StringType{"~1"}, StringType{"/"}); - replace_substring(s, StringType{"~0"}, StringType{"~"}); -} - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // size_t - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/// struct to capture the start position of the current token -struct position_t -{ - /// the total number of characters read - std::size_t chars_read_total = 0; - /// the number of characters read in the current line - std::size_t chars_read_current_line = 0; - /// the number of lines read - std::size_t lines_read = 0; - - /// conversion to size_t to preserve SAX interface - constexpr operator size_t() const - { - return chars_read_total; - } -}; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-FileCopyrightText: 2018 The Abseil Authors -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type -#include // index_sequence, make_index_sequence, index_sequence_for - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template -using uncvref_t = typename std::remove_cv::type>::type; - -#ifdef JSON_HAS_CPP_14 - -// the following utilities are natively available in C++14 -using std::enable_if_t; -using std::index_sequence; -using std::make_index_sequence; -using std::index_sequence_for; - -#else - -// alias templates to reduce boilerplate -template -using enable_if_t = typename std::enable_if::type; - -// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h -// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. - -//// START OF CODE FROM GOOGLE ABSEIL - -// integer_sequence -// -// Class template representing a compile-time integer sequence. An instantiation -// of `integer_sequence` has a sequence of integers encoded in its -// type through its template arguments (which is a common need when -// working with C++11 variadic templates). `absl::integer_sequence` is designed -// to be a drop-in replacement for C++14's `std::integer_sequence`. -// -// Example: -// -// template< class T, T... Ints > -// void user_function(integer_sequence); -// -// int main() -// { -// // user_function's `T` will be deduced to `int` and `Ints...` -// // will be deduced to `0, 1, 2, 3, 4`. -// user_function(make_integer_sequence()); -// } -template -struct integer_sequence -{ - using value_type = T; - static constexpr std::size_t size() noexcept - { - return sizeof...(Ints); - } -}; - -// index_sequence -// -// A helper template for an `integer_sequence` of `size_t`, -// `absl::index_sequence` is designed to be a drop-in replacement for C++14's -// `std::index_sequence`. -template -using index_sequence = integer_sequence; - -namespace utility_internal -{ - -template -struct Extend; - -// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. -template -struct Extend, SeqSize, 0> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; -}; - -template -struct Extend, SeqSize, 1> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; -}; - -// Recursion helper for 'make_integer_sequence'. -// 'Gen::type' is an alias for 'integer_sequence'. -template -struct Gen -{ - using type = - typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; -}; - -template -struct Gen -{ - using type = integer_sequence; -}; - -} // namespace utility_internal - -// Compile-time sequences of integers - -// make_integer_sequence -// -// This template alias is equivalent to -// `integer_sequence`, and is designed to be a drop-in -// replacement for C++14's `std::make_integer_sequence`. -template -using make_integer_sequence = typename utility_internal::Gen::type; - -// make_index_sequence -// -// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, -// and is designed to be a drop-in replacement for C++14's -// `std::make_index_sequence`. -template -using make_index_sequence = make_integer_sequence; - -// index_sequence_for -// -// Converts a typename pack into an index sequence of the same length, and -// is designed to be a drop-in replacement for C++14's -// `std::index_sequence_for()` -template -using index_sequence_for = make_index_sequence; - -//// END OF CODE FROM GOOGLE ABSEIL - -#endif - -// dispatch utility (taken from ranges-v3) -template struct priority_tag : priority_tag < N - 1 > {}; -template<> struct priority_tag<0> {}; - -// taken from ranges-v3 -template -struct static_const -{ - static JSON_INLINE_VARIABLE constexpr T value{}; -}; - -#ifndef JSON_HAS_CPP_17 - template - constexpr T static_const::value; -#endif - -template -constexpr std::array make_array(Args&& ... args) -{ - return std::array {{static_cast(std::forward(args))...}}; -} - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // numeric_limits -#include // char_traits -#include // tuple -#include // false_type, is_constructible, is_integral, is_same, true_type -#include // declval -#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L - #include // byte -#endif -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // random_access_iterator_tag - -// #include - -// #include - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template -struct iterator_types {}; - -template -struct iterator_types < - It, - void_t> -{ - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; -}; - -// This is required as some compilers implement std::iterator_traits in a way that -// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. -template -struct iterator_traits -{ -}; - -template -struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> - : iterator_types -{ -}; - -template -struct iterator_traits::value>> -{ - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; -}; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); - -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); - -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.12.0 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann -// SPDX-License-Identifier: MIT - -#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ - #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - #include // int64_t, uint64_t - #include // map - #include // allocator - #include // string - #include // vector - - // #include - - - /*! - @brief namespace for Niels Lohmann - @see https://github.com/nlohmann - @since version 1.0.0 - */ - NLOHMANN_JSON_NAMESPACE_BEGIN - - /*! - @brief default JSONSerializer template argument - - This serializer ignores the template arguments and uses ADL - ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) - for serialization. - */ - template - struct adl_serializer; - - /// a class to store JSON values - /// @sa https://json.nlohmann.me/api/basic_json/ - template class ObjectType = - std::map, - template class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template class AllocatorType = std::allocator, - template class JSONSerializer = - adl_serializer, - class BinaryType = std::vector, // cppcheck-suppress syntaxError - class CustomBaseClass = void> - class basic_json; - - /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document - /// @sa https://json.nlohmann.me/api/json_pointer/ - template - class json_pointer; - - /*! - @brief default specialization - @sa https://json.nlohmann.me/api/json/ - */ - using json = basic_json<>; - - /// @brief a minimal map-like container that preserves insertion order - /// @sa https://json.nlohmann.me/api/ordered_map/ - template - struct ordered_map; - - /// @brief specialization that maintains the insertion order of object keys - /// @sa https://json.nlohmann.me/api/ordered_json/ - using ordered_json = basic_json; - - NLOHMANN_JSON_NAMESPACE_END - -#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - -NLOHMANN_JSON_NAMESPACE_BEGIN -/*! -@brief detail namespace with internal helper functions - -This namespace collects functions that should not be exposed, -implementations of some @ref basic_json methods, and meta-programming helpers. - -@since version 2.1.0 -*/ -namespace detail -{ - -///////////// -// helpers // -///////////// - -// Note to maintainers: -// -// Every trait in this file expects a non-CV-qualified type. -// The only exceptions are in the 'aliases for detected' section -// (i.e., those of the form: decltype(T::member_function(std::declval()))) -// -// In this case, T has to be properly CV-qualified to constraint the function arguments -// (e.g., to_json(BasicJsonType&, const T&)) - -template struct is_basic_json : std::false_type {}; - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -struct is_basic_json : std::true_type {}; - -// used by exceptions create() member functions -// true_type for the pointer to possibly cv-qualified basic_json or std::nullptr_t -// false_type otherwise -template -struct is_basic_json_context : - std::integral_constant < bool, - is_basic_json::type>::type>::value - || std::is_same::value > -{}; - -////////////////////// -// json_ref helpers // -////////////////////// - -template -class json_ref; - -template -struct is_json_ref : std::false_type {}; - -template -struct is_json_ref> : std::true_type {}; - -////////////////////////// -// aliases for detected // -////////////////////////// - -template -using mapped_type_t = typename T::mapped_type; - -template -using key_type_t = typename T::key_type; - -template -using value_type_t = typename T::value_type; - -template -using difference_type_t = typename T::difference_type; - -template -using pointer_t = typename T::pointer; - -template -using reference_t = typename T::reference; - -template -using iterator_category_t = typename T::iterator_category; - -template -using to_json_function = decltype(T::to_json(std::declval()...)); - -template -using from_json_function = decltype(T::from_json(std::declval()...)); - -template -using get_template_function = decltype(std::declval().template get()); - -// trait checking if JSONSerializer::from_json(json const&, udt&) exists -template -struct has_from_json : std::false_type {}; - -// trait checking if j.get is valid -// use this trait instead of std::is_constructible or std::is_convertible, -// both rely on, or make use of implicit conversions, and thus fail when T -// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) -template -struct is_getable -{ - static constexpr bool value = is_detected::value; -}; - -template -struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if JSONSerializer::from_json(json const&) exists -// this overload is used for non-default-constructible user-defined-types -template -struct has_non_default_from_json : std::false_type {}; - -template -struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if BasicJsonType::json_serializer::to_json exists -// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. -template -struct has_to_json : std::false_type {}; - -template -struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -template -using detect_key_compare = typename T::key_compare; - -template -struct has_key_compare : std::integral_constant::value> {}; - -// obtains the actual object key comparator -template -struct actual_object_comparator -{ - using object_t = typename BasicJsonType::object_t; - using object_comparator_t = typename BasicJsonType::default_object_comparator_t; - using type = typename std::conditional < has_key_compare::value, - typename object_t::key_compare, object_comparator_t>::type; -}; - -template -using actual_object_comparator_t = typename actual_object_comparator::type; - -///////////////// -// char_traits // -///////////////// - -// Primary template of char_traits calls std char_traits -template -struct char_traits : std::char_traits -{}; - -// Explicitly define char traits for unsigned char since it is not standard -template<> -struct char_traits : std::char_traits -{ - using char_type = unsigned char; - using int_type = uint64_t; - - // Redefine to_int_type function - static int_type to_int_type(char_type c) noexcept - { - return static_cast(c); - } - - static char_type to_char_type(int_type i) noexcept - { - return static_cast(i); - } - - static constexpr int_type eof() noexcept - { - return static_cast(std::char_traits::eof()); - } -}; - -// Explicitly define char traits for signed char since it is not standard -template<> -struct char_traits : std::char_traits -{ - using char_type = signed char; - using int_type = uint64_t; - - // Redefine to_int_type function - static int_type to_int_type(char_type c) noexcept - { - return static_cast(c); - } - - static char_type to_char_type(int_type i) noexcept - { - return static_cast(i); - } - - static constexpr int_type eof() noexcept - { - return static_cast(std::char_traits::eof()); - } -}; - -#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L -template<> -struct char_traits : std::char_traits -{ - using char_type = std::byte; - using int_type = uint64_t; - - static int_type to_int_type(char_type c) noexcept - { - return static_cast(std::to_integer(c)); - } - - static char_type to_char_type(int_type i) noexcept - { - return std::byte(static_cast(i)); - } - - static constexpr int_type eof() noexcept - { - return static_cast(std::char_traits::eof()); - } -}; -#endif - -/////////////////// -// is_ functions // -/////////////////// - -// https://en.cppreference.com/w/cpp/types/conjunction -template struct conjunction : std::true_type { }; -template struct conjunction : B { }; -template -struct conjunction -: std::conditional(B::value), conjunction, B>::type {}; - -// https://en.cppreference.com/w/cpp/types/negation -template struct negation : std::integral_constant < bool, !B::value > { }; - -// Reimplementation of is_constructible and is_default_constructible, due to them being broken for -// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). -// This causes compile errors in e.g., Clang 3.5 or GCC 4.9. -template -struct is_default_constructible : std::is_default_constructible {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - -template -struct is_constructible : std::is_constructible {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_iterator_traits : std::false_type {}; - -template -struct is_iterator_traits> -{ - private: - using traits = iterator_traits; - - public: - static constexpr auto value = - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value; -}; - -template -struct is_range -{ - private: - using t_ref = typename std::add_lvalue_reference::type; - - using iterator = detected_t; - using sentinel = detected_t; - - // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator - // and https://en.cppreference.com/w/cpp/iterator/sentinel_for - // but reimplementing these would be too much work, as a lot of other concepts are used underneath - static constexpr auto is_iterator_begin = - is_iterator_traits>::value; - - public: - static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; -}; - -template -using iterator_t = enable_if_t::value, result_of_begin())>>; - -template -using range_value_t = value_type_t>>; - -// The following implementation of is_complete_type is taken from -// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ -// and is written by Xiang Fan who agreed to use it in this library. - -template -struct is_complete_type : std::false_type {}; - -template -struct is_complete_type : std::true_type {}; - -template -struct is_compatible_object_type_impl : std::false_type {}; - -template -struct is_compatible_object_type_impl < - BasicJsonType, CompatibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - // macOS's is_constructible does not play well with nonesuch... - static constexpr bool value = - is_constructible::value && - is_constructible::value; -}; - -template -struct is_compatible_object_type - : is_compatible_object_type_impl {}; - -template -struct is_constructible_object_type_impl : std::false_type {}; - -template -struct is_constructible_object_type_impl < - BasicJsonType, ConstructibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - static constexpr bool value = - (is_default_constructible::value && - (std::is_move_assignable::value || - std::is_copy_assignable::value) && - (is_constructible::value && - std::is_same < - typename object_t::mapped_type, - typename ConstructibleObjectType::mapped_type >::value)) || - (has_from_json::value || - has_non_default_from_json < - BasicJsonType, - typename ConstructibleObjectType::mapped_type >::value); -}; - -template -struct is_constructible_object_type - : is_constructible_object_type_impl {}; - -template -struct is_compatible_string_type -{ - static constexpr auto value = - is_constructible::value; -}; - -template -struct is_constructible_string_type -{ - // launder type through decltype() to fix compilation failure on ICPC -#ifdef __INTEL_COMPILER - using laundered_type = decltype(std::declval()); -#else - using laundered_type = ConstructibleStringType; -#endif - - static constexpr auto value = - conjunction < - is_constructible, - is_detected_exact>::value; -}; - -template -struct is_compatible_array_type_impl : std::false_type {}; - -template -struct is_compatible_array_type_impl < - BasicJsonType, CompatibleArrayType, - enable_if_t < - is_detected::value&& - is_iterator_traits>>::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 - !std::is_same>::value >> -{ - static constexpr bool value = - is_constructible>::value; -}; - -template -struct is_compatible_array_type - : is_compatible_array_type_impl {}; - -template -struct is_constructible_array_type_impl : std::false_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t::value >> - : std::true_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t < !std::is_same::value&& - !is_compatible_string_type::value&& - is_default_constructible::value&& -(std::is_move_assignable::value || - std::is_copy_assignable::value)&& -is_detected::value&& -is_iterator_traits>>::value&& -is_detected::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 -!std::is_same>::value&& -is_complete_type < -detected_t>::value >> -{ - using value_type = range_value_t; - - static constexpr bool value = - std::is_same::value || - has_from_json::value || - has_non_default_from_json < - BasicJsonType, - value_type >::value; -}; - -template -struct is_constructible_array_type - : is_constructible_array_type_impl {}; - -template -struct is_compatible_integer_type_impl : std::false_type {}; - -template -struct is_compatible_integer_type_impl < - RealIntegerType, CompatibleNumberIntegerType, - enable_if_t < std::is_integral::value&& - std::is_integral::value&& - !std::is_same::value >> -{ - // is there an assert somewhere on overflows? - using RealLimits = std::numeric_limits; - using CompatibleLimits = std::numeric_limits; - - static constexpr auto value = - is_constructible::value && - CompatibleLimits::is_integer && - RealLimits::is_signed == CompatibleLimits::is_signed; -}; - -template -struct is_compatible_integer_type - : is_compatible_integer_type_impl {}; - -template -struct is_compatible_type_impl: std::false_type {}; - -template -struct is_compatible_type_impl < - BasicJsonType, CompatibleType, - enable_if_t::value >> -{ - static constexpr bool value = - has_to_json::value; -}; - -template -struct is_compatible_type - : is_compatible_type_impl {}; - -template -struct is_constructible_tuple : std::false_type {}; - -template -struct is_constructible_tuple> : conjunction...> {}; - -template -struct is_json_iterator_of : std::false_type {}; - -template -struct is_json_iterator_of : std::true_type {}; - -template -struct is_json_iterator_of : std::true_type -{}; - -// checks if a given type T is a template specialization of Primary -template
{}
\ - \ - {} \ - \ - {}{}