From d815bb5674904a4e7f87137bb31398218136ebf9 Mon Sep 17 00:00:00 2001 From: tobid7 Date: Thu, 9 Jan 2025 20:22:49 +0100 Subject: [PATCH] # Rewrite Stage 1 - Switch to CMake build system - delete everything for a new structure - Add SmartCtor class and saperate New func - New Faster and Open Lithium Command API - Rewritten Text Renderer to ghet rid of all that janky code - New TimeTrace System and use of NanoTime using GetTimeNano - Overall going to a more Object oriented way - Updated vec api to support vec2 input on vec3 ## Todo - Support vec2 and vec3 in vec4 as inputs - Continue UI7 - Fix SystemFont on 3ds freezing the system - Fix TTF Font UV Mapping ## Warning Creating Apps for the 3ds is not possible yet as the 3ds is Freezing and this is only stage 1 of ? Emulator works perfect --- .gitignore | 1 + .vscode/c_cpp_properties.json | 28 +- .vscode/launch.json | 21 + .vscode/settings.json | 4 +- CHANGELOG.md | 127 - CMakeLists.txt | 82 + Makefile | 152 - README.md | 91 +- docs/javascripts/mathjax.js | 18 - docs/overrides/partials/copyright.html | 18 - docs/stylesheets/doxide.css | 49 - doxide.yaml | 9 - include/pd.hpp | 61 +- include/pd/Error.hpp | 18 - include/pd/Hardware.hpp | 26 - include/pd/Hid.hpp | 42 - include/pd/Image.hpp | 33 - include/pd/Installer.hpp | 17 - include/pd/Lithium.hpp | 238 - include/pd/Message.hpp | 27 - include/pd/Net.hpp | 42 - include/pd/Overlays.hpp | 107 - include/pd/Ovl.hpp | 28 - include/pd/ResultDecoder.hpp | 54 - include/pd/Rubidium.hpp | 30 - include/pd/Sheet.hpp | 23 - include/pd/Sound.hpp | 35 - include/pd/Sprite.hpp | 63 - include/pd/Tasks.hpp | 13 - include/pd/Texture.hpp | 77 - include/pd/ThemeEditor.hpp | 28 - include/pd/Time.hpp | 13 - include/pd/Timer.hpp | 26 - include/pd/UI7.hpp | 134 - include/pd/base/Allocator.hpp | 40 - include/pd/base/Color.hpp | 204 - include/pd/base/FileSystem.hpp | 24 - include/pd/base/FunctionTrace.hpp | 137 - include/pd/base/Lang.hpp | 24 - include/pd/base/Memory.hpp | 26 - include/pd/base/stringtool.hpp | 98 - include/pd/common/app.hpp | 68 + include/pd/common/common.hpp | 71 + include/pd/common/error.hpp | 31 + include/pd/common/lang.hpp | 57 + include/pd/common/memory.hpp | 60 + include/pd/common/strings.hpp | 42 + include/pd/common/sys.hpp | 37 + include/pd/common/timer.hpp | 44 + include/pd/common/timetrace.hpp | 102 + include/pd/external/json.hpp | 15161 +++++++++---------- include/pd/external/stb_image.h | 12841 ++++++++-------- include/pd/external/stb_image_write.h | 2054 --- include/pd/external/stb_truetype.h | 7891 +++++----- include/pd/global_db.hpp | 78 - include/pd/graphics/li7_shader.hpp | 31 + include/pd/graphics/lithium.hpp | 433 + include/pd/graphics/screen.hpp | 74 + include/pd/graphics/texture.hpp | 123 + include/pd/internal_db.hpp | 64 - include/pd/li7_shader.hpp | 8 - include/pd/maths/NMat.hpp | 45 - include/pd/maths/NVec.hpp | 366 - include/pd/maths/bit_util.hpp | 34 + include/pd/maths/color.hpp | 102 + include/pd/maths/img_convert.hpp | 34 + include/pd/maths/vec.hpp | 404 + include/pd/nimg.hpp | 30 - include/pd/palladium.hpp | 183 - include/pd/parameter.hpp | 134 - include/pd/smart_ctor.hpp | 10 - include/pd/sound/sound.hpp | 46 + include/pd/thread.hpp | 122 - include/pd/tools/markdown.hpp | 103 + include/pd/tools/result_decoder.hpp | 37 + include/pd/ui7/drawlist.hpp | 53 + include/pd/ui7/flags.hpp | 35 + include/pd/ui7/theme.hpp | 52 + include/pd/ui7/ui7.hpp | 53 + mkdocs.yaml | 44 - source/Error.cpp | 59 - source/Hardware.cpp | 47 - source/Hid.cpp | 118 - source/Image.cpp | 44 - source/Installer.cpp | 149 - source/Lithium.cpp | 789 - source/Message.cpp | 94 - source/Net.cpp | 243 - source/Overlays.cpp | 616 - source/ResultDecoder.cpp | 460 - source/Rubidium.cpp | 124 - source/Sheet.cpp | 51 - source/Sound.cpp | 129 - source/Sprite.cpp | 53 - source/Tasks.cpp | 22 - source/Texture.cpp | 243 - source/ThemeEditor.cpp | 138 - source/Time.cpp | 30 - source/Timer.cpp | 31 - source/UI7.cpp | 1463 -- source/base/Color.cpp | 229 - source/base/FileSystem.cpp | 70 - source/base/FunctionTrace.cpp | 3 - source/base/Lang.cpp | 125 - source/base/Memory.cpp | 55 - source/common/app.cpp | 66 + source/common/common.cpp | 32 + source/common/error.cpp | 50 + source/common/lang.cpp | 61 + source/common/strings.cpp | 128 + source/common/sys.cpp | 48 + source/common/timetrace.cpp | 37 + source/{ => external}/stb.cpp | 8 +- source/{ => graphics}/li7_shader.cpp | 26 +- source/graphics/lithium.cpp | 662 + source/graphics/texture.cpp | 203 + source/internal_db.cpp | 276 - source/maths/bit_util.cpp | 38 + source/maths/color.cpp | 72 + source/maths/img_convert.cpp | 41 + source/nimg.cpp | 117 - source/palladium.cpp | 917 -- source/thread.cpp | 77 - source/tools/result_decoder.cpp | 311 + source/ui7/drawlist.cpp | 85 + test/main.cpp | 116 + test/romfs/ComicNeue.ttf | Bin 0 -> 53384 bytes test/romfs/icon.png | Bin 0 -> 844 bytes test/romfs/lang/de.json | 9 + build_shaders.py => tools/build_shaders.py | 41 +- clang-format.py => tools/clang-format.py | 50 +- 131 files changed, 21457 insertions(+), 30844 deletions(-) create mode 100644 .gitignore create mode 100644 .vscode/launch.json delete mode 100644 CHANGELOG.md create mode 100644 CMakeLists.txt delete mode 100644 Makefile delete mode 100644 docs/javascripts/mathjax.js delete mode 100644 docs/overrides/partials/copyright.html delete mode 100644 docs/stylesheets/doxide.css delete mode 100644 doxide.yaml delete mode 100644 include/pd/Error.hpp delete mode 100644 include/pd/Hardware.hpp delete mode 100644 include/pd/Hid.hpp delete mode 100644 include/pd/Image.hpp delete mode 100644 include/pd/Installer.hpp delete mode 100644 include/pd/Lithium.hpp delete mode 100644 include/pd/Message.hpp delete mode 100644 include/pd/Net.hpp delete mode 100644 include/pd/Overlays.hpp delete mode 100644 include/pd/Ovl.hpp delete mode 100644 include/pd/ResultDecoder.hpp delete mode 100644 include/pd/Rubidium.hpp delete mode 100644 include/pd/Sheet.hpp delete mode 100644 include/pd/Sound.hpp delete mode 100644 include/pd/Sprite.hpp delete mode 100644 include/pd/Tasks.hpp delete mode 100644 include/pd/Texture.hpp delete mode 100644 include/pd/ThemeEditor.hpp delete mode 100644 include/pd/Time.hpp delete mode 100644 include/pd/Timer.hpp delete mode 100644 include/pd/UI7.hpp delete mode 100644 include/pd/base/Allocator.hpp delete mode 100644 include/pd/base/Color.hpp delete mode 100644 include/pd/base/FileSystem.hpp delete mode 100644 include/pd/base/FunctionTrace.hpp delete mode 100644 include/pd/base/Lang.hpp delete mode 100644 include/pd/base/Memory.hpp delete mode 100644 include/pd/base/stringtool.hpp create mode 100644 include/pd/common/app.hpp create mode 100644 include/pd/common/common.hpp create mode 100644 include/pd/common/error.hpp create mode 100644 include/pd/common/lang.hpp create mode 100644 include/pd/common/memory.hpp create mode 100644 include/pd/common/strings.hpp create mode 100644 include/pd/common/sys.hpp create mode 100644 include/pd/common/timer.hpp create mode 100644 include/pd/common/timetrace.hpp delete mode 100644 include/pd/external/stb_image_write.h delete mode 100644 include/pd/global_db.hpp create mode 100644 include/pd/graphics/li7_shader.hpp create mode 100644 include/pd/graphics/lithium.hpp create mode 100644 include/pd/graphics/screen.hpp create mode 100644 include/pd/graphics/texture.hpp delete mode 100644 include/pd/internal_db.hpp delete mode 100644 include/pd/li7_shader.hpp delete mode 100644 include/pd/maths/NMat.hpp delete mode 100644 include/pd/maths/NVec.hpp create mode 100644 include/pd/maths/bit_util.hpp create mode 100644 include/pd/maths/color.hpp create mode 100644 include/pd/maths/img_convert.hpp create mode 100644 include/pd/maths/vec.hpp delete mode 100644 include/pd/nimg.hpp delete mode 100644 include/pd/palladium.hpp delete mode 100644 include/pd/parameter.hpp delete mode 100644 include/pd/smart_ctor.hpp create mode 100644 include/pd/sound/sound.hpp delete mode 100644 include/pd/thread.hpp create mode 100644 include/pd/tools/markdown.hpp create mode 100644 include/pd/tools/result_decoder.hpp create mode 100644 include/pd/ui7/drawlist.hpp create mode 100644 include/pd/ui7/flags.hpp create mode 100644 include/pd/ui7/theme.hpp create mode 100644 include/pd/ui7/ui7.hpp delete mode 100644 mkdocs.yaml delete mode 100644 source/Error.cpp delete mode 100644 source/Hardware.cpp delete mode 100644 source/Hid.cpp delete mode 100644 source/Image.cpp delete mode 100644 source/Installer.cpp delete mode 100644 source/Lithium.cpp delete mode 100644 source/Message.cpp delete mode 100644 source/Net.cpp delete mode 100644 source/Overlays.cpp delete mode 100644 source/ResultDecoder.cpp delete mode 100644 source/Rubidium.cpp delete mode 100644 source/Sheet.cpp delete mode 100644 source/Sound.cpp delete mode 100644 source/Sprite.cpp delete mode 100644 source/Tasks.cpp delete mode 100644 source/Texture.cpp delete mode 100644 source/ThemeEditor.cpp delete mode 100644 source/Time.cpp delete mode 100644 source/Timer.cpp delete mode 100644 source/UI7.cpp delete mode 100644 source/base/Color.cpp delete mode 100644 source/base/FileSystem.cpp delete mode 100644 source/base/FunctionTrace.cpp delete mode 100644 source/base/Lang.cpp delete mode 100644 source/base/Memory.cpp create mode 100644 source/common/app.cpp create mode 100644 source/common/common.cpp create mode 100644 source/common/error.cpp create mode 100644 source/common/lang.cpp create mode 100644 source/common/strings.cpp create mode 100644 source/common/sys.cpp create mode 100644 source/common/timetrace.cpp rename source/{ => external}/stb.cpp (62%) rename source/{ => graphics}/li7_shader.cpp (60%) create mode 100644 source/graphics/lithium.cpp create mode 100644 source/graphics/texture.cpp delete mode 100644 source/internal_db.cpp create mode 100644 source/maths/bit_util.cpp create mode 100644 source/maths/color.cpp create mode 100644 source/maths/img_convert.cpp delete mode 100644 source/nimg.cpp delete mode 100644 source/palladium.cpp delete mode 100644 source/thread.cpp create mode 100644 source/tools/result_decoder.cpp create mode 100644 source/ui7/drawlist.cpp create mode 100644 test/main.cpp create mode 100644 test/romfs/ComicNeue.ttf create mode 100644 test/romfs/icon.png create mode 100644 test/romfs/lang/de.json rename build_shaders.py => tools/build_shaders.py (56%) rename clang-format.py => tools/clang-format.py (76%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d163863 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 4e41604..8c6320a 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -7,12 +7,30 @@ "C:/devkitpro/libctru/include/**", "C:/devkitpro/devkitARM/include/**", "C:/devkitpro/devkitARM/arm-none-eabi/include/**", - "C:/devkitpro/portlibs/3ds/include/**", + "C:/devkitpro/portlibs/3ds/include/**" + ], + "defines": [ + "BUILD_CTR" + ], + "compilerPath": "C:/devkitPro/devkitARM/bin/arm-none-eabi-g++.exe", + "intelliSenseMode": "gcc-arm", + "cStandard": "c11", + "cppStandard": "c++20" + }, + { + "name": "3DS | Linux", + "includePath": [ + "${workspaceFolder}/**", "/opt/devkitpro/libctru/include/**", - "/opt/devkitpro/portlibs/**" - - ] + "/opt/devkitpro/portlibs/3ds/include/**" + ], + "defines": [ + "BUILD_CTR" + ], + "cStandard": "c17", + "cppStandard": "gnu++20", + "intelliSenseMode": "gcc-arm" } ], "version": 4 -} \ No newline at end of file +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5b3ebbd --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "name": "3DS GDB", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/test.elf", + "miDebuggerServerAddress": "localhost:4003", + "miDebuggerPath": "C:\\devkitPro\\devkitARM\\bin\\arm-none-eabi-gdb.exe", + "cwd": "${workspaceFolder}", + "externalConsole": true, + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 6152f6f..8790a01 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -113,6 +113,8 @@ "__threading_support": "cpp", "__tree": "cpp", "__verbose_abort": "cpp", - "complex": "cpp" + "complex": "cpp", + "any": "cpp", + "text_encoding": "cpp" } } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index fc3ff5b..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,127 +0,0 @@ -# Palladium Changelog -## 1.0.0 -- Rename Everyting to PD -- R7Vec -> NVec -- Switch from C2D to Lithium (LI7) -- For the Rest See RenderD7 Changelog below -- swr -> Rubidium -- LIFont (TTF Font Renderer) -- Implement shbin as c++ array -- Larger Mesaage Box -- Add Texture Loader -- Update Image/Error and other sytems to Lithium -- Remove Render2 -- Add Deltatime to every moving object -- Restructure Project -# RenderD7 Changelog -## 0.9.5 -- Remove Npi Intro and NVID Api -- Replace Toasts System with Message -- Added GetTime -- Move from Draw to Render2 Api -- Implement RD7Color and R7Vec2 -- Add new Features to Color::RGBA -- Cleanup Code -- Added RenderD7 Keyboard (Overlay) -- Added Ftrace Overlay -- Moved MetrikOVL into an Overlay -- Removed Old Font/Text Handlers -- Added UI7 (New UI Api) -- Remove Old UI Api -- Rewrite of RenderD7::Image -- Internal Debugger/Database (IDB) -- Removed BitmapPrinter -- Added nimg and swr(render2nimg | SoftwareRender) -- Removed Old Error/Message Handler -- GetTextSize (extra buffer) + New TextShorter -- Require specific FLAG for MemTrack -- Replace all lodepng usage by stb_image -- Move Asset Generator into single python script -- Remove INI reader -- Python based clangformat script -- Move some Init code into functions to not use twice -- Added Font class -- Add LinearAllocator (for std) -- Fix Crash in FilsSystem -- Implement basic Theme System -- Remove 0.9.4 Security -- Tasks now based on std functional/thread -- Add Network Support (Download Files, APi Requests) -- Remove RD7TF -- Add Cia Installer -- Move from Init bool values to flags -## 0.9.4 -- Implement new Security System To prevent from crashes -- Implement Functiontrace for better Timing Tests -- Implement MemAlloc Tracker (only size) -- Add some new Overlays (not functional yet) -- Complete Rewrite of Overlay System -- Fixed the FrameEnd Crash -- New System to get Hardware Info -- Removed RenderD7 Super Reselution (800px mode) -## 0.9.3 -- Completly Documented Everything -- Fix typo in Sprite::getHeight -- Remove Deprecated/Useless Stuff -## 0.9.2 -- Add Nvid Support(v0.0.1) -- Add Basic RenderD7 Splash -- Faster Graphics Init -- Fade Effects -- Fix Changelog Screen -## 0.9.1 -- Fix Critical bug in Spritesheet animations -- Fix RenderD7::Color::Hex (Major performance tweak) -## 0.9.0 -- Remove Stupid try of Console -- Add Services list -- Clean up Code -- Added Minimal Init for hax2.x -## 0.8.5 -- Fix Deltatime -## 0.8.4 -- A lot of Fixes -- New Features for BitmapPrinter -## 0.8.3 -- Added Overlaycount to Info -- Addet ResultDecoder for errors -## 0.8.2 -- Fix a lot of Stuff -- Use c++17 std::filesystem for RenderD7::Filesystem -## 0.8.1 -- Add abillity to Get Stdout as string to render it to the screen. -## 0.8.0 -- Implement BitmapPrinter -## 0.7.3 -- Implement Over Render Overlay Framework -## 0.7.2 -- Implement MT to csv file saving -- Add RGB2HEX -## 0.7.1 -- Add the New Overlay Handler. Its Just in code and does nothing yet -## 0.7.0 -- Made Big Progress In the MT Ovl but it still crashes On a 2nd C3D_FrameEnd \ -- Implement 800px but doesn't work that good -## 0.6.2 -- Fix Crash when exiting through Home Menu. -## 0.6.10 -- Rewrite Threadsystem -- Improve framerate -## 0.6.02 -- Fix Code in lang.hpp -- Add Draw Text Left Function (Right since 0.7.0) -- Add changelog -## 0.6.01 -- Add Threading system -## 0.6.0 -- Better Scene Management -## 0.5.0 -- Fixed some Bugs! -## 0.4.0 -- Trying to fix Filesystem and Bugs -## 0.3.0 -- Recreate D7-Core into RenderD7 -## 0.2.0 -- Trying to create Animations of Images instead of Sheets -## 0.1.0 -- Inital Release of D7-Core sprite animation plugin \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f167b50 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,82 @@ +cmake_minimum_required(VERSION 3.18) + +# Setup Toolchain if not specified +# Could propably avoided by using arm-none-eabi-cmake +if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) + if(DEFINED ENV{DEVKITPRO}) + set(CMAKE_TOOLCHAIN_FILE "$ENV{DEVKITPRO}/cmake/3DS.cmake" CACHE PATH "toolchain file") + else() + message(FATAL_ERROR "Please define DEVKITPRO to point to your SDK path!") + endif() +endif() + +# Set Project +project(palladium LANGUAGES C CXX VERSION 1.0.0) + +# Enable Compile Command Export +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Force C++ 20 +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) + +# Set Special C and CXX flags +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-psabi -O3") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions") + +set(SRC_FILES + # Core (common) + source/common/app.cpp + source/common/strings.cpp + source/common/timetrace.cpp + source/common/sys.cpp + source/common/lang.cpp + source/common/error.cpp + # Maths + source/maths/color.cpp + source/maths/bit_util.cpp + source/maths/img_convert.cpp + # Graphics + source/graphics/texture.cpp + source/graphics/li7_shader.cpp + source/graphics/lithium.cpp + # External + source/external/stb.cpp +) + +set(TARGET_NAME palladium) + +# Set Executable and its sources +add_library(${TARGET_NAME} STATIC ${SRC_FILES}) + +# Set dependencies, include dirs and definitions +target_include_directories(${TARGET_NAME} PUBLIC + include + ${DEVKITPRO}/portlibs/3ds/include +) +target_compile_definitions(${TARGET_NAME} PUBLIC + -D_GNU_SOURCE=1 + -DVERSION="${PROJECT_VERSION}" + -DBUILD_CTR=1 +) + +add_executable(test test/main.cpp) +target_include_directories(test PUBLIC include) +target_link_directories(test PUBLIC ${CMAKE_BINARY_DIR}) +target_link_libraries(test PUBLIC palladium citro3d ctru m) +# Generate 3DSX +ctr_generate_smdh( + ${CMAKE_BINARY_DIR}/test.smdh + NAME "${APP_NAME}" + DESCRIPTION "Palladium test app" + AUTHOR "tobid7" + ICON "test/romfs/icon.png" +) +ctr_create_3dsx( + test + OUTPUT "${CMAKE_BINARY_DIR}/test.3dsx" + SMDH "${CMAKE_BINARY_DIR}/test.smdh" + ROMFS "${CMAKE_SOURCE_DIR}/test/romfs" +) +install(TARGETS ${TARGET_NAME}) +install(DIRECTORY include DESTINATION ".") \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index b625922..0000000 --- a/Makefile +++ /dev/null @@ -1,152 +0,0 @@ -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- - -ifeq ($(strip $(DEVKITARM)),) -$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") -endif - -include $(DEVKITARM)/3ds_rules - -export PD_MAJOR := 1 -export PD_MINOR := 0 -export PD_PATCH := 0 - -VERSION := $(PD_MAJOR).$(PD_MINOR).$(PD_PATCH) - -#--------------------------------------------------------------------------------- -# TARGET is the name of the output -# BUILD is the directory where object files & intermediate files will be placed -# SOURCES is a list of directories containing source code -# DATA is a list of directories containing data files -# INCLUDES is a list of directories containing header files -#--------------------------------------------------------------------------------- -TARGET := palladium -SOURCES := source source/base -DATA := data -INCLUDES := include - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft - -CFLAGS := -g -Wall -Wno-psabi -Werror -mword-relocations \ - -ffunction-sections -fdata-sections \ - -fomit-frame-pointer -ffast-math \ - $(ARCH) $(BUILD_CFLAGS) - -CFLAGS += $(INCLUDE) -D__3DS__ -D_GNU_SOURCE=1 - -CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=c++20 - -ASFLAGS := -g $(ARCH) $(DEFINES) - -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := $(PORTLIBS) $(CTRULIB) - -#--------------------------------------------------------------------------------- -# no real need to edit anything past this point unless you need to add additional -# rules for different file extensions -#--------------------------------------------------------------------------------- -ifneq ($(BUILD),$(notdir $(CURDIR))) -#--------------------------------------------------------------------------------- - -export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) - -CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) -CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) -SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) - -#--------------------------------------------------------------------------------- -# use CXX for linking C++ projects, CC for standard C -#--------------------------------------------------------------------------------- -ifeq ($(strip $(CPPFILES)),) -#--------------------------------------------------------------------------------- - export LD := $(CC) -#--------------------------------------------------------------------------------- -else -#--------------------------------------------------------------------------------- - export LD := $(CXX) -#--------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------- - -export OFILES := $(addsuffix .o,$(BINFILES)) \ - $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) - -export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I. - -.PHONY: clean all doc - -#--------------------------------------------------------------------------------- -all: lib/libpalladium.a lib/libpalladiumd.a - -dist-bin: all - @tar --exclude=*~ -cjf palladium-$(VERSION).tar.bz2 include lib - -dist-src: - @tar --exclude=*~ -cjf palladium-src-$(VERSION).tar.bz2 include source Makefile - -dist: dist-src dist-bin - -install: dist-bin - mkdir -p $(DESTDIR)$(DEVKITPRO)/libctru - bzip2 -cd palladium-$(VERSION).tar.bz2 | tar -xf - -C $(DESTDIR)$(DEVKITPRO)/libctru - -lib: - @[ -d $@ ] || mkdir -p $@ - -release: - @[ -d $@ ] || mkdir -p $@ - -debug: - @[ -d $@ ] || mkdir -p $@ - -lib/libpalladium.a : lib release $(SOURCES) $(INCLUDES) - @$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \ - BUILD_CFLAGS="-DNDEBUG=1 -O3 -fomit-frame-pointer -fno-math-errno" \ - DEPSDIR=$(CURDIR)/release \ - --no-print-directory -C release \ - -f $(CURDIR)/Makefile - -lib/libpalladiumd.a : lib debug $(SOURCES) $(INCLUDES) - @$(MAKE) BUILD=debug OUTPUT=$(CURDIR)/$@ \ - BUILD_CFLAGS="-DDEBUG=1 -Og" \ - DEPSDIR=$(CURDIR)/debug \ - --no-print-directory -C debug \ - -f $(CURDIR)/Makefile - -#--------------------------------------------------------------------------------- -clean: - @echo clean ... - @rm -fr release debug lib - -#--------------------------------------------------------------------------------- -else - -DEPENDS := $(OFILES:.o=.d) - -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- -$(OUTPUT) : $(OFILES) - -#--------------------------------------------------------------------------------- -%.bin.o : %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/README.md b/README.md index bf15cc4..a5fa9fa 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,41 @@ # Palladium -Create README ? -# RenderD7 as Submodule (0.9.5+) -To use RenderD7 just use this command: `git submodule add https://github.com/NPI-D7/RenderD7` and add `-b v0.9.5` for example for a specific version. +## Build types -And in Your Project Makefile add this -``` -# Make Sure to Change this paths if your Submodule -# is located somewhere else -RENDERD7_SRC := RenderD7/source RenderD7/external -RENDERD7_INC := RenderD7/include -# Libraries used for RenderD7 -# if you already use -lm, -lctru etc place a # before -lm -RENDERD7_LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lz -lm -lcitro2dd -lcitro3d -lctru -``` -Now you need to add it to your sources and includes -``` -SOURCES := source $(RENDERD7_SRC) -INCLUDES := source $(RENDERD7_INC) +```bash +PD_EXTENDED_DEBUG=0 # Include things like ResultDecoder and Check for Memory usage +PD_DEBUG=0 # not yet +PD_NO_SAFE_CODE=0 # Remove All not important safetey checks ``` -Example from rd7tf -### Installation (0.8.0-0.9.4) (OUTDATED) -Download a Package From Releses Page -`https://github.com/NPI-D7/RenderD7/releases/download/v0.9.4/renderd7.tar.bz2 -o renderd7.tar.bz2` -Then Extract it to your Libraries Path -`bzip2 -cd renderd7.tar.bz2 | tar -xf - -C path_to_your_libs` -Finally put `-lrenderd7` to the First Place and add the path_to_your_libs -``` -LIBS := -lrenderd7 -lcurl -lstdc++ -lm -lcitro2d -lcitro3d -lctru -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := $(PORTLIBS) $(CTRULIB) ../path_to_your_libs -``` -Make sure that `-lrenderd7` is before `-lcitro2d`, `-lcitro3d`, `-lctru`. -Here an example tree -``` -Example-App -├── gfx -├── libs -│ ├── include -│ │ ├── rd7.hpp -│ │ └── renderd7 -│ └── lib -│ ├── librenderd7.a -│ └── librenderd7d.a -├── Makefile -├── romfs -│ └── gfx -└── src - └── main.cpp -``` -# Credits -- NPI-D7 - - Tobi-D7 Main Dev +## Building -Some Icons are From -https://icons8.de/ -See Subfolder Readmes +Install Dependencies: + +```bash +# This Command will install everything +(dkp-)pacman -S --noconfirm 3ds-dev 3ds-portlibs +``` + +Building: + +If you want to have the lib in a projects `libs` dir or so you can simply add `-DCMAKE_INSTALL_PREFIX=./res` to the cmake command and copy the dirs from res to you libs folder + +For Debug build the Cmake Script generates a `libpalladiumd.a` + +```bash +mkdir -p build +cd build +cmake .. -DCMAKE_BUILD_TYPE=Release # Make sure to build in Release Mode (exept you want to debug some issues) +make +make install +``` + +## Credits +| Icon | Username | Description | +|---|---|---| +| https://github.com/tobid7 | [tobid7](https://github.com/tobid7) | main dev of RenderD7, Palladium | +| https://github.com/devkitpro | [devkitpro](https://github.com/devkitpro) | devkitarm, picasso, libctru and citro3d | +| https://github.com/Universal-Team | [Universal-Team](https://github.com/Universal-Team) | Inspiration for Lang System, Cia Installer Code | +| https://github.com/nothings | [nothings](https://github.com/nothings) | stb_image(_write) and stb_truetype | +| https://github.com/nlohmann | [nlohmann](https://github.com/nlohmann) | for json.hpp | diff --git a/docs/javascripts/mathjax.js b/docs/javascripts/mathjax.js deleted file mode 100644 index d46d1fe..0000000 --- a/docs/javascripts/mathjax.js +++ /dev/null @@ -1,18 +0,0 @@ - - diff --git a/docs/overrides/partials/copyright.html b/docs/overrides/partials/copyright.html deleted file mode 100644 index d46d1fe..0000000 --- a/docs/overrides/partials/copyright.html +++ /dev/null @@ -1,18 +0,0 @@ - - diff --git a/docs/stylesheets/doxide.css b/docs/stylesheets/doxide.css deleted file mode 100644 index f11f299..0000000 --- a/docs/stylesheets/doxide.css +++ /dev/null @@ -1,49 +0,0 @@ -:root { - --md-admonition-icon--variable: url('data:image/svg+xml;charset=utf-8,'); - --md-admonition-icon--function: url('data:image/svg+xml;charset=utf-8,'); - --md-admonition-icon--concept: url('data:image/svg+xml;charset=utf-8,'); - --md-admonition-icon--macro: url('data:image/svg+xml;charset=utf-8,'); -} - -.md-typeset .admonition.variable, .md-typeset details.variable, -.md-typeset .admonition.function, .md-typeset details.function, -.md-typeset .admonition.concept, .md-typeset details.concept, -.md-typeset .admonition.macro, .md-typeset details.macro { - border-color: var(--md-default-fg-color--lighter); -} - -.md-typeset .variable > .admonition-title, .md-typeset .variable > summary, -.md-typeset .function > .admonition-title, .md-typeset .function > summary, -.md-typeset .concept > .admonition-title, .md-typeset .concept > summary, -.md-typeset .macro > .admonition-title, .md-typeset .macro > summary { - background-color: var(--md-default-bg-color); -} - -.md-typeset .variable > .admonition-title::before, -.md-typeset .variable > summary::before { - background-color: var(--md-default-fg-color--light); - -webkit-mask-image: var(--md-admonition-icon--variable); - mask-image: var(--md-admonition-icon--variable); -} - -.md-typeset .function > .admonition-title::before, -.md-typeset .function > summary::before { - background-color: var(--md-default-fg-color--light); - -webkit-mask-image: var(--md-admonition-icon--function); - mask-image: var(--md-admonition-icon--function); -} - -.md-typeset .concept > .admonition-title::before, -.md-typeset .concept > summary::before { - background-color: var(--md-default-fg-color--light); - -webkit-mask-image: var(--md-admonition-icon--concept); - mask-image: var(--md-admonition-icon--concept); -} - -.md-typeset .macro > .admonition-title::before, -.md-typeset .macro > summary::before { - background-color: var(--md-default-fg-color--light); - -webkit-mask-image: var(--md-admonition-icon--macro); - mask-image: var(--md-admonition-icon--macro); -} - diff --git a/doxide.yaml b/doxide.yaml deleted file mode 100644 index 6292407..0000000 --- a/doxide.yaml +++ /dev/null @@ -1,9 +0,0 @@ -title: Palladium -description: -files: - - "include/*.hpp" - - "include/pd/*.hpp" - - "include/pd/base/*.hpp" - - "include/*.h" - - "include/pd/*.h" - - "include/pd/base/*.h" \ No newline at end of file diff --git a/include/pd.hpp b/include/pd.hpp index 7da6178..62dcc29 100644 --- a/include/pd.hpp +++ b/include/pd.hpp @@ -1,27 +1,42 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +/* +MIT License -namespace Palladium { -using Lithium = LI; -using RB = Rubidium; -} // namespace Palladium +Copyright (c) 2024 tobid7 -namespace PD = Palladium; +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +// Common +#include +#include +#include +#include +#include +// Graphics +#include +#include +// Maths +#include +#include +#include +#include + +// namespace Palladium = PD; \ No newline at end of file diff --git a/include/pd/Error.hpp b/include/pd/Error.hpp deleted file mode 100644 index 02c3a68..0000000 --- a/include/pd/Error.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -namespace Palladium { -void Error(const std::string& msg); -inline void InlineError(const std::string& msg) { - std::string location = __FILE__ + std::string(":") + std::to_string(__LINE__); - Error("Error: \n" + location + "\n" + msg); -} -inline void InlineAssert(bool v, const std::string& msg = "") { - if (v == false) { - std::string location = - __FILE__ + std::string(":") + std::to_string(__LINE__); - Error("Assert Failed:\n" + location + "\n" + msg); - } -} -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Hardware.hpp b/include/pd/Hardware.hpp deleted file mode 100644 index a8d8a2b..0000000 --- a/include/pd/Hardware.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -namespace Palladium { -namespace Hardware { -/// @brief Initialisize required Services -void Initialisize(); -/// @brief Check if Headphones are Plugged in -/// @return true if headphones plugged in -bool IsHeadphones(); -/// @brief Check if the 3ds Is Charging -/// @return true if System gets Charged -bool IsCharging(); -/// @brief Check the Battery Percentage -/// @return Persentage as int -int GetBatteryPercentage(); -/// @brief Get current State of 3d Slider -/// @return current 3dslider poition -float Get3dSliderLevel(); -/// @brief Get Current state of Sound Slider -/// @return current SoundSlider state -float GetSoundSliderLevel(); -/// @brief Get Current Wifi Level -/// @return current wifi level -int GetWifiLevel(); -} // namespace Hardware -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Hid.hpp b/include/pd/Hid.hpp deleted file mode 100644 index 5194ddc..0000000 --- a/include/pd/Hid.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// WARNING -// THIS IS BETA STUFF -// ITS MAKE LIKE EXTERNAL BUT -// FOR Palladium ITS INTEGRATED - -#pragma once - -#include -#include - -namespace Palladium { -namespace Hid { -enum Actions { - Down = 0, - Held = 1, - Up = 2, - DownRepeat = 3, -}; -// Register Functions -// Register Current state values -void RegKeyDown(uint32_t &key_down); -void RegKeyHeld(uint32_t &key_held); -void RegKeyUp(uint32_t &key_up); -void RegKeyRepeat(uint32_t &repeat); -void RegTouchCoords(NVec2 &touch_pos); -// Not Corectly Implemented Yet -void RegAnalog1Movement(NVec2 &movement); -void RegAnalog2Movement(NVec2 &movement); -// Register Keys -void RegKeyEvent(const std::string &event, uint32_t key); -// KeyEvents -bool IsEvent(const std::string &event, Actions action); -NVec2 GetTouchPosition(); -NVec2 GetLastTouchPosition(); -NVec2 GetTouchDownPosition(); -void Update(); -// Lock/Unlock Input api for example for Keyboard -void Lock(); -void Unlock(); -void Clear(); -} // namespace Hid -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Image.hpp b/include/pd/Image.hpp deleted file mode 100644 index a9af01c..0000000 --- a/include/pd/Image.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include <3ds.h> - -#include -#include -#include -#include -#include - -namespace Palladium { -class Image { - public: - Image() = default; - Image(const std::string& path) { this->Load(path); } - ~Image() = default; - PD_SMART_CTOR(Image) - void Load(const std::string& path); - void From_NIMG(const nimg& image); - void Delete(); - - Texture::Ref Get(); - void Set(Texture::Ref i, NVec4 uvs = NVec4(-1, -1, -1, -1)); - NVec2 GetSize(); - NVec4 GetUV() { return (custom_uvs.x() != -1) ? custom_uvs : img->GetUV(); } - bool Loadet(); - - private: - bool ext = false; - Texture::Ref img; - NVec4 custom_uvs = NVec4(-1, -1, -1, -1); -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Installer.hpp b/include/pd/Installer.hpp deleted file mode 100644 index d888e29..0000000 --- a/include/pd/Installer.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include <3ds.h> // Result - -#include - -namespace Palladium { -struct InstallerInfo { - unsigned long long total; - unsigned long long current; - unsigned int mem_size = 0x80000; - bool active = false; -}; -Result InstallCia(const std::string& path, bool self); -void InstallSetBuffersSize(unsigned int bytes); -InstallerInfo InstallGetInfo(); -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Lithium.hpp b/include/pd/Lithium.hpp deleted file mode 100644 index eb9c97f..0000000 --- a/include/pd/Lithium.hpp +++ /dev/null @@ -1,238 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define MAKEFLAG(x) (1 << x) - -using PDTextFlags = unsigned int; - -enum PDTextFlags_ { - PDTextFlags_None = 0, //< Align is Left and Other things are disabled - PDTextFlags_AlignRight = MAKEFLAG(0), - PDTextFlags_AlignMid = MAKEFLAG(1), - PDTextFlags_Shaddow = MAKEFLAG(2), // TextBuf Killer lol (doubled Text) - PDTextFlags_Wrap = MAKEFLAG(3), - PDTextFlags_Short = MAKEFLAG(4), - PDTextFlags_Scroll = MAKEFLAG(5), -}; - -using PDLithiumFlags = unsigned int; - -enum PDLithiumFlags_ { - PDLithiumFlags_None = 0, - PDLithiumFlags_TMS = MAKEFLAG(0), // Text Map System - PDLithiumFlags_LRS = MAKEFLAG(1), // Layer Render System - PDLithiumFlags_FCS = MAKEFLAG(2), // Floor Coords System - PDLithiumFlags_Default = PDLithiumFlags_TMS, -}; - -namespace Palladium { -class LIFont { - public: - struct CPI { - CPI() - : codepoint(0), - uv(NVec4()), - tex(nullptr), - szs(NVec2()), - off(0.f), - invalid(false) {} - CPI(bool iv) - : codepoint(0), - uv(NVec4()), - tex(nullptr), - szs(NVec2()), - off(0.f), - invalid(iv) {} - unsigned int codepoint; - NVec4 uv; - Texture::Ref tex; - NVec2 szs; - float off; - bool invalid; - }; - LIFont() = default; - ~LIFont() = default; - PD_SMART_CTOR(LIFont) - - void LoadTFF(const std::string path, int px_size = 32); - void LoadBitmapFont(const std::string& path); - void LoadSystemFont(); - - int GetPixelHeight(); - CPI GetCodepoint(unsigned int c); - std::string GetName() { return name; }; - - bool IsSystemFont() { return sysfnt; } - - void Dump(); - - private: - bool sysfnt = false; - std::string name; - int pixel_height; - std::map cpmap; - std::vector tex; -}; - -class LI { - public: - struct Vtx { - Vtx() {} - Vtx(NVec2 xy, float u, float v, unsigned int clr) { - // Coords - pos[0] = xy[0]; - pos[1] = xy[1]; - pos[2] = 0.f; - // UV - uv[0] = u; - uv[1] = v; - col = clr; - } - NVec3 pos; - NVec2 uv; - unsigned int col; - }; - /// CMD TYPES /// - /// 0 = SKIP - /// 2 = TRIANGLE - /// 1 = RECT - /// 3 = Circle - ///////////////// - struct Cmd { - NVec4 top; - NVec4 bot; - NVec4 uv; - int layer = 0; - int cmd_type = 0; - bool fcs = false; // Floor Coords System - unsigned int clr = 0; - bool sfr = false; // SysFontRender - Texture::Ref tex = nullptr; - int index = 0; - }; - /// Text Box /// - /// System to Make GetTextDiemnsions - /// and Short/Wrap faster - struct TextBox { - NVec2 size; - float time_created; - // Optional - bool optinal = false; - std::string text; - }; - LI() = default; - ~LI() = default; - - static void Init(); - static void Exit(); - - // Settings - static void EnableFeature(PDLithiumFlags flag) { flags |= flag; } - static void DisableFeature(PDLithiumFlags flag) { flags &= ~flag; } - static PDLithiumFlags& GetFeatures() { return flags; } - - static void OnScreen(bool bottom); - static void Render(C3D_RenderTarget* top, C3D_RenderTarget* bot); - static NVec2 GetScreenSize() { return screen_size; } - static LIFont::Ref GetFont() { return font; } - static void SetFont(LIFont::Ref i) { - font_update = true; - font = i; - } - static void UseTexture(Texture::Ref tex = nullptr) { - active_texture = tex ? tex : single_color; - } - static bool IsBottomScreen() { return bottom_screen; } - static float GetTextScale() { return text_scale; } - static void SetTextScale(float scale) { - font_update = true; - text_scale = scale; - } - static void DefaultTextScale() { - font_update = true; - text_scale = default_text_size; - } - static void Layer(int v) { layer = v; } - static int Layer() { return layer; } - static void NewLayer() { layer++; } - static NVec2 GetTextDimensions(const std::string& text); - static std::string ShortText(const std::string& in, int maxlen, NVec2& dim); - static std::string WrapText(const std::string& in, int maxlen, NVec2& dim); - - // Drawing Functions - static void DrawRect(NVec2 pos, NVec2 size, unsigned int color, NVec4 uvs); - static void DrawLine(NVec2 a, NVec2 b, unsigned int clr, int t = 1); - static void DrawCircle(NVec2 pos, float r, unsigned int color, int segments); - static void DrawRect(NVec2 pos, NVec2 size, unsigned int color) { - UseTexture(); - DrawRect(pos, size, color, NVec4(0, 1, 1, 0)); - } - static void DrawTriangle(NVec2 a, NVec2 b, NVec2 c, unsigned int color); - static void DrawImage(NVec2 pos, Texture::Ref tex, NVec2 size, NVec4 uvs) { - UseTexture(tex); - DrawRect(pos, size, 0xffffffff, uvs); - } - static void DrawText(NVec2 pos, unsigned int color, const std::string& text, - PDTextFlags flags = 0, NVec2 ap = NVec2()); - - static int Vertices() { return num_vertices; } - static int Indices() { return num_indices; } - static int Drawcalls() { return num_drawcalls; } - static int DarwCommands() { return num_commands; } - static size_t GetMaxVerticesNum() { return vertex_buffer.size(); } - - private: - static void RotateCorner(NVec2& v, float s, float c); - static void MakeRect(NVec4& top, NVec4& bot, NVec2 pos, NVec2 szs, - float angle = 0.f); - static bool CompareCommands(const Cmd& a, const Cmd& b); - static void RenderFrame(bool bottom); - - /// CTX /// - static PDLithiumFlags flags; - // Font Stuff - // Default Font Size in (px) - static const float default_font_size; - static const float default_text_size; - static float text_scale; - - // Renderer Stuff - static NVec2 screen_size; - static bool bottom_screen; - static int layer; - static std::vector draw_lists[2]; - static Texture::Ref active_texture; - static Texture::Ref single_color; - static std::vector> vertex_buffer; - static std::vector> - idx_buffer; - static size_t vertex_index; - static size_t idx_index; - static LIFont::Ref font; - static bool font_update; - static bool sysfont_render; - static std::map text_sizes; - static int cmd_index; - - // Debug - static int num_vertices; - static int num_drawcalls; - static int num_commands; - static int num_indices; - - // Shader - static DVLB_s* li7_dvlb; - static shaderProgram_s li7_prog; - static C3D_AttrInfo li7_attr; - static int uLoc_proj; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Message.hpp b/include/pd/Message.hpp deleted file mode 100644 index 0770135..0000000 --- a/include/pd/Message.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -namespace Palladium { -struct Message { - Message(std::string t, std::string m) { - title = t; - message = m; - animtime = 0.f; - } - - std::string title; - std::string message; - float animtime; -}; - -void ProcessMessages(); -void PushMessage(const Message& msg); -inline void PushMessage(const std::string& head, const std::string& msg) { - PushMessage(Message(head, msg)); -} -// Config -void SetMessageIdleStartFrame(int frame); -void SetMessageTotalAnimationFrames(int total_frames); -void SetMessageFadeOutStartFrame(int frame); -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Net.hpp b/include/pd/Net.hpp deleted file mode 100644 index 4de0010..0000000 --- a/include/pd/Net.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -#include - -namespace Palladium { -namespace Net { -// Define List of Errors -enum Error_ { - Error_None, // Function Executed Successfully - Error_Memory, // Memory Allocation Error - Error_Write, // Unable to Write File - Error_StatusCode, // Error with Status Code - Error_Git, // Git Error - Error_CtrStatus, // 3ds Result Code - Error_Curl, // Curl Error - Error_Busy, // Another Download Taskl is already running - Error_Invalid, // Invalid Json struct - Error_NoWifi, // Console not connected to wifi -}; -// Set an typedefine for Error code -using Error = unsigned long long; -// Extract Error_ from Error code -inline Error_ ErrorCode(Error err) { - return static_cast(static_cast(err & 0xffffffff)); -} -// Extract Http Status code, Curl Error Code or Ctr Result Code -inline int StatusCode(Error err) { - Error_ c = ErrorCode(err); - if (c != Error_StatusCode && c != Error_CtrStatus && c != Error_Curl) - return 0; - return static_cast(err >> 32); -} -Error Download(const std::string& url, std::string& data); -Error Download2File(const std::string& url, const std::string& path); -Error GitDownloadRelease(const std::string& url, const std::string& asset_name, - const std::string& path, bool prerelease = false); -Error JsonApiRequest(const std::string& api_url, nlohmann::json& res); -unsigned long long GetProgressCurrent(); -unsigned long long GetProgressTotal(); -} // namespace Net -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Overlays.hpp b/include/pd/Overlays.hpp deleted file mode 100644 index 6fb6c7e..0000000 --- a/include/pd/Overlays.hpp +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -typedef int PDKeyboard; - -enum PDKeyboard_ { - PDKeyboard_Default, - PDKeyboard_Numpad, - PDKeyboard_Password, -}; - -enum PDKeyboardState { - PDKeyboardState_None = 0, - PDKeyboardState_Cancel = 1, - PDKeyboardState_Confirm = 2, -}; - -using PDKeyboardFlags = unsigned int; -enum PDKeyboardFlags_ { - PDKeyboardFlags_None = 0, - PDKeyboardFlags_BlendTop = 1 << 0, - PDKeyboardFlags_BlendBottom = 1 << 1, - PDKeyboardFlags_LockControls = 1 << 2, - PDKeyboardFlags_Default = PDKeyboardFlags_BlendTop | - PDKeyboardFlags_BlendBottom | - PDKeyboardFlags_LockControls, -}; - -namespace Palladium { -class Ovl_Ftrace : public Palladium::Ovl { - public: - /// @brief Constructor - Ovl_Ftrace(bool* is_enabled); - /// @brief Override for Draw - void Draw(void) const override; - /// @brief Override for Logic - void Logic() override; - - private: - bool* i_is_enabled; -}; - -class Ovl_Metrik : public Palladium::Ovl { - public: - /// @brief Constructor - Ovl_Metrik(bool* is_enabled, bool* screen, unsigned int* mt_color, - unsigned int* txt_color, float* txt_size); - /// @brief Override for Draw - void Draw(void) const override; - /// @brief Override for Logic - void Logic() override; - - private: - // Mutable internal values - mutable std::string mt_fps; - mutable std::string mt_cpu; - mutable std::string mt_gpu; - mutable std::string mt_cmd; - mutable std::string mt_lfr; - mutable std::string mt_vtx; - mutable std::string mt_idx; - mutable std::string mt_drc; - mutable std::string mt_dmc; - mutable std::string mt_mem; - - // Importand Adresses - bool* i_is_enabled; - bool* i_screen; - unsigned int* i_mt_color; - unsigned int* i_txt_color; - float* i_txt_size; - mutable Ftrace::TimeStats cpu_stats; - mutable Ftrace::TimeStats gpu_stats; - mutable Timer v_update; -}; - -class Ovl_Keyboard : public Palladium::Ovl { - public: - /// @brief Constructor - /// Keyboard Type not Supported for now - Ovl_Keyboard(std::string& ref, PDKeyboardState& state, - const std::string& hint = "", PDKeyboard type = 0, - PDKeyboardFlags flags = PDKeyboardFlags_Default); - /// @brief Deconstructor - ~Ovl_Keyboard(); - /// @brief Override for Draw - void Draw(void) const override; - /// @brief Override for Logic - void Logic() override; - - private: - mutable std::map shared_data; - // Pointer to useres String - std::string* typed_text = nullptr; - std::string str_bak; - PDKeyboardState* state; - PDKeyboard type; - int mode = 0; - int ft3 = 0; - PDKeyboardFlags flags; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Ovl.hpp b/include/pd/Ovl.hpp deleted file mode 100644 index 98812e5..0000000 --- a/include/pd/Ovl.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include -#include - -namespace Palladium { -/// @brief The Overlay Class (Used for Toasts for example) -class Ovl { - public: - /// @brief Deconstructor - virtual ~Ovl() {} - /// @brief Function Called to Draw this - virtual void Draw() const = 0; - /// @brief Logic of the Overlay - virtual void Logic() = 0; - /// @brief Should the overlay be killed - /// @return Killed or Not - inline bool IsKilled() { return this->iskilled; } - /// @brief Kill The Overlay - inline void Kill() { iskilled = true; } - - private: - /// @param iskilled For IsKilled(); - bool iskilled = false; -}; -/// @brief Add an Overlay to the Screen -/// @param scene Overlay to push to Screen -void AddOvl(std::unique_ptr scene); -} // namespace Palladium diff --git a/include/pd/ResultDecoder.hpp b/include/pd/ResultDecoder.hpp deleted file mode 100644 index 2f902f9..0000000 --- a/include/pd/ResultDecoder.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -#include <3ds.h> - -#include - -namespace Palladium { -/// @brief Decoder for 3ds Result Codes -class ResultDecoder { - public: - /// @brief Constructor - ResultDecoder() {} - /// @brief Deconstructor - ~ResultDecoder() {} - /// @brief Load a Result into Decoder - /// @param rescode Result Code - void Load(Result rescode); - /// @brief Load A Hex Converted Code into Decoder - /// @param rescode Result-Hex Code - void Load(std::string rescode); - /// @brief Get Hex Code - /// @return Hex-Code - std::string GetCode(); - /// @brief Get Level Name - /// @return Level Name - std::string GetLevel(); - /// @brief Get Level Value - /// @return Level Value - int GetLevelInt(); - /// @brief Get The Mosule Name - /// @return Module Name - std::string GetModule(); - /// @brief Get The Module Value - /// @return Module Value - int GetModuleInt(); - /// @brief Get The Description - /// @return Description - std::string GetDescription(); - /// @brief Get The Description Valur - /// @return Description Value - int GetDescriptionInt(); - /// @brief Get the Summary - /// @return Summary - std::string GetSummary(); - /// @brief Get the Summary Value - /// @return Summary Value - int GetSummaryInt(); - /// @brief Write a Result log file to sd - void WriteLog(void); - - private: - /// @param m_rescode Result code - Result m_rescode; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Rubidium.hpp b/include/pd/Rubidium.hpp deleted file mode 100644 index 68567ec..0000000 --- a/include/pd/Rubidium.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include - -namespace Palladium { -class Rubidium { - public: - Rubidium(int w, int h); - Rubidium(); - ~Rubidium(); - PD_SMART_CTOR(Rubidium) - nimg& GetNimg() { return image; } - void LoadFile(const std::string& path); - void LoadNimg(const std::string& path); - - // Rendering - void DrawPixel(int x, int y, unsigned int color); - void DrawRect(int x, int y, int w, int h, unsigned int color, int t = 1); - void DrawRectSolid(int x, int y, int w, int h, unsigned int color); - void DrawLine(int x1, int y1, int x2, int y2, unsigned int color, int t = 1); - void Flip(bool h, bool v); - void EnableAA(bool enable) { enable_aa = enable; } - - private: - // Leinwand (dont know english word for that) - nimg image; - bool enable_aa = true; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Sheet.hpp b/include/pd/Sheet.hpp deleted file mode 100644 index 49d11aa..0000000 --- a/include/pd/Sheet.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include - -#include -#include -#include - -namespace Palladium { -class Sheet { - public: - Sheet() = default; - ~Sheet() = default; - PD_SMART_CTOR(Sheet) - void LoadT3X(const std::string& path); - Texture::Ref Get(int idx); - Image::Ref GetImage(int idx); - - private: - std::vector sprites; - Tex3DS_Texture sheet; - C3D_Tex* sheet_tex = nullptr; -}; -} // namespace Palladium diff --git a/include/pd/Sound.hpp b/include/pd/Sound.hpp deleted file mode 100644 index 3c0a615..0000000 --- a/include/pd/Sound.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <3ds.h> - -#include -#include - -namespace Palladium { -/** Sound Class */ -class Sound { - public: - /// \brief Construct new Soundeffect - /// \param path Path to the .wav file - /// \param channel the channel 1-23 - /// \param toloop true:loop the sound, false: don't loop - Sound(const std::string &path, int channel = 1, bool toloop = false); - /// @brief Deconstructor - ~Sound(); - PD_SMART_CTOR(Sound) - /// @brief Play the sound - void Play(); - /// @brief Stop the sound - void Stop(); - - private: - /// \param dataSize Size of the filedata - u32 dataSize; - /// \param waveBuf For ndsp - ndspWaveBuf waveBuf; - /// \param data Memmory data of the sound - uint8_t *data = NULL; - /// \param chnl Channel of the sound - int chnl; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Sprite.hpp b/include/pd/Sprite.hpp deleted file mode 100644 index 1876ffd..0000000 --- a/include/pd/Sprite.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace Palladium { -/// @brief Sprite Class -class Sprite { - public: - /// \brief Construct Sprite - Sprite() = default; - /// \brief Deconstruct Sprite - ~Sprite() = default; - PD_SMART_CTOR(Sprite) - /// \brief Load a Sprite From SpriteSheet - /// \param img the Image to load from.(Palladium::Image) - void FromImage(Palladium::Image::Ref img); - /// @brief Draw the Sprite - /// @return success ? - bool Draw(); - /// @brief Set the Center Position - /// @param x X Pos - /// @param y Y Pos - void SetCenter(float x, float y); - /// @brief Set the Sprite's Position - /// @param x X Pos - /// @param y Y Pos - void SetPos(float x, float y); - /// @brief Set The Sprite's Scale - /// @param x Scale on X-Axis - /// @param y Scale on Y-Axis - void SetScale(float x, float y); - /// @brief Set the Sprite's Rotation - /// @param rotation ratation - void SetRotation(float rotation); - /// @brief Rotate the Sprite - /// @param speed Speed to Rotate - void Rotate(float speed); - /// @brief Get Tje Sprite's Width - /// @return Width - float GetWidth(); - /// @brief Get the Sprite's Height - /// @return Height - float GetHeight(); - /// @brief Get The Sprite's X Position - /// @return X Position - float GetPosX(); - /// @brief Get the Sprite's Y Position - /// @return Y Position - float GetPosY(); - NVec2 GetSize(); - NVec2 GetPos(); - void SetPos(NVec2 pos); - void SetScale(NVec2 scale); - void SetRotCenter(NVec2 percentage); - - private: - ///// @param sprite The Sprite - // C2D_Sprite sprite; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Tasks.hpp b/include/pd/Tasks.hpp deleted file mode 100644 index c967b7c..0000000 --- a/include/pd/Tasks.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include - -namespace Palladium { -namespace Tasks { -/// @brief Push A Task -/// @param fun Function of Your Task -/// @return index -int Create(std::function fun); -/// @brief Destroy all Tasks -void DestroyAll(); -} // namespace Tasks -} // namespace Palladium diff --git a/include/pd/Texture.hpp b/include/pd/Texture.hpp deleted file mode 100644 index 23d4bcf..0000000 --- a/include/pd/Texture.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -#include - -#include -#include -#include -#include - -namespace Palladium { -class Texture { - public: - // Define Types supported by the texture loader - // For example usefull to waste not as much space - // in linear mem - enum Type { - RGBA32, - RGB24, - A8, - }; - - enum Filter { - NEAREST, - LINEAR, - }; - Texture() { - // Set Default UV - this->uvs[0] = 0.0f; - this->uvs[1] = 1.0f; - this->uvs[2] = 1.0f; - this->uvs[3] = 0.0f; - }; - ~Texture() { Delete(); } - PD_SMART_CTOR(Texture) - - void Delete(); - - /// @brief Loads an Image [png, jpg, bmp] as texture - /// by default it sets up the texture as RGBA32 and - /// only supports RGB24 and RGBA32 images - /// @param path Path to file - void LoadFile(const std::string& path); - /// @brief Loads an Image [png, jpg, bmp] as texture - /// by default it sets up the texture as RGBA32 and - /// only supports RGB24 and RGBA32 images - /// @param data Data of file - void LoadFromMemory(const std::vector& data); - /// @brief Create Texture by pixel Data. This function supports - /// [RGBA32, RGB24, A8] - /// @param data Pixel Data - /// @param w Width of data - /// @param h Height of Data - /// @param type Type of Data (default is RGBA32) - void LoadPixels(const std::vector& data, int w, int h, - Type type = RGBA32, Filter filter = NEAREST); - - /// @brief This function sets up a texture Object based on the input - /// Data and a self setup C3D_Tex. You dont need to delete it as - /// This class does this automatically - void ExternalLoad(C3D_Tex* tex, NVec2 rszs, NVec4 uvs); - - C3D_Tex* Get() { return this->tex; } - NVec2 GetTexSize(); - NVec2 GetSize() { return img_size; } - // As the texture is a pow of 2 we need a uv - NVec4 GetUV() { return uvs; } - - void AutoDelete(bool enable) { ad = enable; } - - private: - void MakeTex(std::vector& buf, int w, int h, - Type type = RGBA32, Filter filter = NEAREST); - C3D_Tex* tex = nullptr; - NVec2 img_size; - NVec4 uvs; - bool ad = true; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/ThemeEditor.hpp b/include/pd/ThemeEditor.hpp deleted file mode 100644 index 10872dc..0000000 --- a/include/pd/ThemeEditor.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include - -namespace Palladium { -class ThemeEditor : public Palladium::Scene { - public: - ThemeEditor(); - ~ThemeEditor(); - - void Update() override; - - private: - Theme::Ref edit_theme; - // Placeholder to save active one to - Theme::Ref temp_theme; - - // temp vars for samples - bool cm; - std::string inpt; - int menu = 0; - - // Keyboard - PDKeyboardState kbd_state; - std::string kbd_text; - std::vector theme_list; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Time.hpp b/include/pd/Time.hpp deleted file mode 100644 index 21426b3..0000000 --- a/include/pd/Time.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include - -namespace Palladium { -/// @brief Format a String -/// @param fmt_str Format To -/// @param ... Additional Args -/// @return Formatted String -std::string FormatString(std::string fmt_str, ...); -/// @brief Get Current Time as String -/// @return Time-String -std::string GetTimeStr(void); -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Timer.hpp b/include/pd/Timer.hpp deleted file mode 100644 index e2e38d5..0000000 --- a/include/pd/Timer.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include <3ds.h> - -#include - -namespace Palladium { -class Timer { - public: - Timer(bool autostart = true); - ~Timer() {} - PD_SMART_CTOR(Timer) - void Reset(); - void Tick(); - void Pause(); - void Resume(); - float Get(); - float GetLive(); - bool Running(); - - private: - uint64_t last = 0; - uint64_t current = 0; - bool is_running = false; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/UI7.hpp b/include/pd/UI7.hpp deleted file mode 100644 index e5f6935..0000000 --- a/include/pd/UI7.hpp +++ /dev/null @@ -1,134 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#define UI7MAKEFLAG(x) (1 << x) - -using UI7MenuFlags = unsigned int; - -enum UI7MenuFlags_ { - UI7MenuFlags_None = 0, - UI7MenuFlags_NoTitlebar = UI7MAKEFLAG(0), - UI7MenuFlags_TitleMid = UI7MAKEFLAG(1), - UI7MenuFlags_HzScrolling = MAKEFLAG(2), - UI7MenuFlags_VtScrolling = MAKEFLAG(3), - UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling, -}; - -enum UI7Horizontal { - UI7Horizontal_Left = 0, - UI7Horizontal_Center = 1, - UI7Horizontal_Right = 2, -}; - -enum UI7Vertical { - UI7Vertical_Top = 0, - UI7Vertical_Center = 1, - UI7Vertical_Bot = 2, -}; - -class DrawCmd; -class UI7DrawList { - public: - UI7DrawList() = default; - ~UI7DrawList() = default; - - void AddRectangle(NVec2 pos, NVec2 szs, PDColor clr); - void AddRectangle(NVec2 pos, NVec2 szs, unsigned int clr); - void AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, PDColor clr); - void AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, unsigned int clr); - void AddText(NVec2 pos, const std::string &text, PDColor clr, - PDTextFlags flags = 0, NVec2 box = NVec2()); - void AddText(NVec2 pos, const std::string &text, unsigned int clr, - PDTextFlags flags = 0, NVec2 box = NVec2()); - void AddImage(NVec2 pos, Palladium::Image::Ref img); - void AddCall(std::shared_ptr cmd); - - void Process(bool auto_clear = true); - void Clear(); - int Layer() { return layer; } - void Layer(int v) { layer = v; } - int BaseLayer() { return bl; } - void BaseLayer(int v) { bl = v; } - - PD_SMART_CTOR(UI7DrawList) - - private: - int layer = 0; - int bl = 0; - void AddDebugCall(std::shared_ptr cmd); - std::vector> list; -}; - -namespace UI7 { -// Key functions -void Init(); -void Deinit(); -void Update(); -float GetTime(); -float GetDeltaTime(); -bool &IsDebugging(); -// Internal Function -// Should not be used -void Debug(); -bool &DebugMenu(); - -bool Button(const std::string &label, NVec2 size = NVec2(0, 0)); -void Checkbox(const std::string &label, bool &c); -void Label(const std::string &label, PDTextFlags flags = 0); -void Progressbar(float value); -/// @brief Draw Image in Menu -/// @param img Pointer f.e to Palladium::Image2 -void Image(Palladium::Image::Ref img); -void BrowserList(const std::vector &entrys, int &selection, - PDTextFlags txtflags = 0, NVec2 size = NVec2(0, 0), - int max_entrys = 13); -void InputText(const std::string &label, std::string &text, - const std::string &hint = ""); -bool BeginMenu(const std::string &title, NVec2 size = NVec2(0, 0), - UI7MenuFlags flags = 0); -void EndMenu(); -void Grid(const std::string &name, const NVec2 &size, const NVec2 &entry_size, - void (*display_func)(void *, NVec2), void **data_array, - size_t num_entrys); -void ColorSelector(const std::string &label, unsigned int &color); -bool BeginTree(const std::string &text); -void EndTree(); -void Prompt(const std::string &label, int &res, - // For Translations - const std::string &lcf = "Confirm", - const std::string &lcc = "Cancel"); -void ClosePromts(); -NVec2 GetCursorPos(); -void SetCursorPos(NVec2 cp); -void RestoreCursor(); -void SameLine(); -void Separator(); -// Internal API (For Creating Custom Objects) -bool InBox(NVec2 inpos, NVec2 boxpos, NVec2 boxsize); -void MoveCursor(NVec2 size); -bool HandleScrolling(NVec2 &pos, NVec2 size); -bool InMenu(); -namespace Menu { -// All of them return the Main BG DrawList if Menu is null -UI7DrawList::Ref GetBackgroundList(); -UI7DrawList::Ref GetList(); -UI7DrawList::Ref GetForegroundList(); -// Other Menu Specific Functions -float GetScrollingOffset(); -void SetScrollingOffset(float off); -bool IsScrolling(); -} // namespace Menu -namespace Next { -// Alignment in ScreenSpace -void Align(UI7Horizontal hz = UI7Horizontal_Left, - UI7Vertical vt = UI7Vertical_Top); -} // namespace Next -// DrawLists -UI7DrawList::Ref GetForegroundList(); -UI7DrawList::Ref GetBackgroundList(); -} // namespace UI7 diff --git a/include/pd/base/Allocator.hpp b/include/pd/base/Allocator.hpp deleted file mode 100644 index b44c8e9..0000000 --- a/include/pd/base/Allocator.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include <3ds.h> - -#include -#include - -// Write own LinearAllocator for learning - -namespace Palladium { -template -class LinearAllocator : public std::allocator { - public: - typedef size_t size_type; - typedef T* pointer; - typedef const T* const_pointer; - - template - struct rebind { - typedef LinearAllocator other; - }; - - pointer allocate(size_type n, const void* hint = nullptr) { - if (n > this->max_size()) { - Palladium::Error( - "Linear Allocator: \nBad Alloc -> size is larger than free space!"); - return nullptr; - } - return (pointer)linearAlloc(n * sizeof(T)); - } - - void deallocate(pointer p, size_type) { linearFree((void*)p); } - - size_type max_size() { return linearSpaceFree(); } - - LinearAllocator() throw() {} - LinearAllocator(const LinearAllocator& a) throw() : std::allocator(a) {} - ~LinearAllocator() throw() {} -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/base/Color.hpp b/include/pd/base/Color.hpp deleted file mode 100644 index 8e2097c..0000000 --- a/include/pd/base/Color.hpp +++ /dev/null @@ -1,204 +0,0 @@ -#pragma once -#include - -#include -#include -#include -#include -#include - -#define UNPACK_RGBA(col) \ - (unsigned char)(col >> 24), (col >> 16), (col >> 8), (col) -#define UNPACK_BGRA(col) \ - (unsigned char)(col >> 8), (col >> 16), (col >> 24), (col) - -inline unsigned int RGBA8(unsigned char r, unsigned char g, unsigned char b, - unsigned char a = 255) { - return (r | g << 8 | b << 16 | a << 24); -} - -typedef int PDColor; - -// MultiColor (Less FunctionNameLen) - -struct Color2 { - unsigned int color0; - unsigned int color1; -}; - -struct Color3 { - unsigned int color0; - unsigned int color1; - unsigned int color2; -}; - -struct Color4 { - unsigned int color0; - unsigned int color1; - unsigned int color2; - unsigned int color3; -}; - -enum PDColor_ { - PDColor_Text, ///< This Color Should always be used for Light Backgrounds - PDColor_TextDisabled, /// Text Disabled Color - PDColor_Text2, ///< And This want for Texts on Dark Backgrounds - PDColor_Background, ///< Your Bg Color - PDColor_Header, ///< Header Color (if the header is dark text2 is used) - PDColor_Selector, ///< Selector Color - PDColor_SelectorFade, ///< Selector FadingTo Color - PDColor_List0, ///< List Color1 - PDColor_List1, ///< List Color2 - PDColor_MessageBackground, ///< Message Background - PDColor_Button, ///< Button Color - PDColor_ButtonHovered, ///< Button Color if Hovered - PDColor_ButtonDisabled, ///< Button Color if disabled - PDColor_ButtonActive, ///< Button Colkor if Clicked - PDColor_Checkmark, ///< Checkbox Checkmark Color - PDColor_FrameBg, ///< Frame Background Color - PDColor_FrameBgHovered, ///< Frame Background Color if hovered - PDColor_Progressbar, ///< Progressbar Color - /// NON COLOR /// - PDColor_Len, ///< Used to define the lengh of this list -}; - -namespace Palladium { -class Theme { - public: - Theme() = default; - ~Theme() = default; - - void Load(const std::string &path); - void Default(); - void Save(const std::string &path); - - unsigned int Get(PDColor clr); - void Set(PDColor clr, unsigned int v); - void Swap(PDColor a, PDColor b); - bool Undo(); - void UndoAll(); - void TextBy(PDColor bg); - PDColor AutoText(PDColor bg); - void ClearHistory() { changes.clear(); } - - std::vector &GetTableRef() { return clr_tab; } - // For Smart Pointer - PD_SMART_CTOR(Theme); - - // Loader method - void CopyOther(Theme::Ref theme); - - private: - struct change { - change(PDColor a, unsigned int f, unsigned int t) - : clr(a), from(f), to(t) {} - change(PDColor a, PDColor b, unsigned int f, unsigned int t) - : clr(a), clr2(b), from(f), to(t) {} - PDColor clr; - PDColor clr2 = 0; // Used if Swap - unsigned int from; - unsigned int to; - }; - // Use a vector for faster access - std::vector clr_tab; - std::vector changes; -}; - -Theme::Ref ThemeActive(); -/// @brief Change Theme Adress -/// @param theme your adress -void ThemeSet(Theme::Ref theme); -namespace Color { -/// @brief RGBA Class -class RGBA { - public: - /// @brief Construct - /// @param r - /// @param g - /// @param b - /// @param a - RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255) - : m_r(r), m_g(g), m_b(b), m_a(a) {} - /// @brief Construct - /// @param r - /// @param g - /// @param b - /// @param a - RGBA(float r, float g, float b, float a = 1.f) - : m_r(r * 255.f), m_g(g * 255.f), m_b(b * 255.f), m_a(a * 255.f) {} - RGBA(unsigned int in) { -#define ISIMPLEUNPAK(x, y) (((x) >> y) & 0xFF) - m_r = ISIMPLEUNPAK(in, 0); - m_g = ISIMPLEUNPAK(in, 8); - m_b = ISIMPLEUNPAK(in, 16); - m_a = ISIMPLEUNPAK(in, 24); - } - RGBA(PDColor in) { - if (!Palladium::ThemeActive()) return; - unsigned int col = Palladium::ThemeActive()->Get(in); - m_r = ISIMPLEUNPAK(col, 0); - m_g = ISIMPLEUNPAK(col, 8); - m_b = ISIMPLEUNPAK(col, 16); - m_a = ISIMPLEUNPAK(col, 24); - } - RGBA &changeR(unsigned char r) { - m_r = r; - return *this; - } - RGBA &changeG(unsigned char g) { - m_g = g; - return *this; - } - RGBA &changeB(unsigned char b) { - m_b = b; - return *this; - } - RGBA &changeA(unsigned char a) { - m_a = a; - return *this; - } - - RGBA &fade_to(const RGBA &color, float p) { - m_a = - m_a + static_cast((color.m_a - m_a) * ((p + 1.0f) / 2)); - m_b = - m_b + static_cast((color.m_b - m_b) * ((p + 1.0f) / 2)); - m_g = - m_g + static_cast((color.m_g - m_g) * ((p + 1.0f) / 2)); - m_r = - m_r + static_cast((color.m_r - m_r) * ((p + 1.0f) / 2)); - return *this; - } - - /// @brief Get as Uint32 - /// @return color - unsigned int toRGBA() const { return RGBA8(m_r, m_g, m_b, m_a); } - - // Just calculate the "lightness" f.e. to use Text or Text2 - float luminance() const { - // For Reference https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness - return (0.3 * (m_r / 255.f) + 0.59 * (m_g / 255.f) + 0.11 * (m_b / 255.f)); - } - - bool is_light() { - // Gives us the light or dark to not - // always use the below "if" statement - return (luminance() >= 0.5); - } - - unsigned char m_r = 0, m_g = 0, m_b = 0, m_a = 0; -}; -std::string RGBA2Hex(unsigned int c32); -/// @brief Convert RGB to Hex -/// @param r -/// @param g -/// @param b -/// @return Hex-String -std::string RGB2Hex(int r, int g, int b); -/// @brief Hex to U32 -/// @param color -/// @param a -/// @return Color32 -unsigned int Hex(const std::string &color, unsigned char a = 255); -} // namespace Color -} // namespace Palladium diff --git a/include/pd/base/FileSystem.hpp b/include/pd/base/FileSystem.hpp deleted file mode 100644 index e4c0ed4..0000000 --- a/include/pd/base/FileSystem.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include -#include - -namespace Palladium { -namespace FileSystem { -/// @brief A Directory Entry -struct Entry { - /// @brief Patf of The Entry - std::string path; - /// @brief Name of The Entry - std::string name; - /// @brief Directory or File - bool dir = false; -}; -/// @brief Gets All Entrys of A Directory into a Vector -/// @param path The Path of the Directory -/// @return The Vector of found Entrys -std::vector GetDirContent(std::string path); -std::string GetParentPath(std::string path, std::string mount_point); -std::vector GetDirContentsExt( - std::string &path, const std::vector &extensions); -} // namespace FileSystem -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/base/FunctionTrace.hpp b/include/pd/base/FunctionTrace.hpp deleted file mode 100644 index 63d6cce..0000000 --- a/include/pd/base/FunctionTrace.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#pragma once -// Base includes -#include -#include -#include - -// 3ds does not support std::chrono -#include <3ds.h> - -/// @brief 3ds System Ticks per milli second -#define TICKS_PER_MSEC 268111.856 - -#define f2s(x_) #x_ -#define scomb(x1, x2) std::string(x1 + x2) - -namespace Palladium { -namespace Ftrace { -class TimeStats { - public: - TimeStats(int len) : len(len), values(len, 0) {} - - void Add(float v) { - values[idx] = v; - idx = next_index(idx); - num_values = std::min(num_values + 1, len); - } - - float GetAverage() { - float res = 0.f; - if (!num_values) { - return res; - } - for (int i = 0; i < num_values; ++i) { - res += values[index(i)]; - } - return res / num_values; - } - - float GetMax() { - float res = 0.f; - if (!num_values) { - return res; - } - for (int i = 0; i < num_values; i++) { - res = std::max(res, values[index(i)]); - } - return res; - } - - float GetMin() { - float res = 0.f; - if (!num_values) { - return res; - } - res = values[0]; - for (int i = 0; i < num_values; i++) { - res = std::min(res, values[index(i)]); - } - return res; - } - - const std::vector& GetData() { return values; } - const float& operator[](int i) { return values[index(i)]; } - const size_t GetLen() { return len; } - const size_t GetNumValues() { return num_values; } - - private: - // Indexing Functions for better overview - size_t next_index(size_t current) const { return (current + 1) % len; } - size_t index(size_t v) const { return (idx + len - num_values + v) % len; } - - // Data - int len = 0; - std::vector values; - int idx = 0; - int num_values = 0; -}; -/// @brief Result of FTrace -struct FTRes { - FTRes() : time_start(0), time_end(0), time_of(0.f), is_ovl(false), ts(60) {} - std::string group; ///< Group of the Trace - std::string func_name; ///< Function Name - - uint64_t time_start; ///< when started - uint64_t time_end; ///< when stopped - float time_of; ///< stop - start (how long) - bool is_ovl; ///< is displayed in overlay? - TimeStats ts; ///< Time Stats -}; - -/// @brief Map of Traces -extern std::map pd_traces; - -/// @brief Set a Start TracePoint -/// @param group Set a Group Name -/// @param func_name Set a Function Name -inline void Beg(const std::string& group, const std::string& func_name) { - std::string trace_id = scomb(group, func_name); - auto& trace = pd_traces[trace_id]; - trace.group = group; - trace.func_name = func_name; - trace.time_start = svcGetSystemTick(); -} -/// @brief Set an End TracePoint -/// @param group Set a Group Name -/// @param func_name Set a Function Name -inline void End(const std::string& group, const std::string& func_name) { - std::string trace_id = scomb(group, func_name); - auto& trace = pd_traces[trace_id]; - trace.time_end = svcGetSystemTick(); - trace.time_of = - static_cast(trace.time_end - trace.time_start) / TICKS_PER_MSEC; - trace.ts.Add(trace.time_of); -} -/// @brief Trace a function execution -/// @param group Set a Group Name -/// @param name Set a Function Name -inline void Func(const std::string& group, const std::string& name, - std::function fun) { - if (!fun) return; - Beg(group, name); - fun(); - End(group, name); -} - -/// @brief This Starts an Ftrace and -/// end ist when going out of scope -struct ScopedTrace { - ScopedTrace(std::string g, std::string n) : group(g), name(n) { - Ftrace::Beg(g, n); - } - ~ScopedTrace() { Ftrace::End(group, name); } - std::string group; - std::string name; -}; -} // namespace Ftrace -} // namespace Palladium diff --git a/include/pd/base/Lang.hpp b/include/pd/base/Lang.hpp deleted file mode 100644 index c78651d..0000000 --- a/include/pd/base/Lang.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -// clang-format off -#include -#include -// clang-format on - -namespace Palladium { -namespace Lang { -/// @brief Get 3ds System lang! [en] by default -/// @return Sytemlang as string -std::string GetSys(); -/// @brief Get The Translation String -/// @param key Key of Translation -/// @return The Translated String -std::string Get(const std::string &key); -/// @brief Load A Language json -/// @param lang The Language Key [en], [de], etc, or getSys() -void Load(const std::string &lang); -// New funcs -std::string GetName(); -std::string GetAuthor(); -std::string GetShortcut(); -} // namespace Lang -} // namespace Palladium diff --git a/include/pd/base/Memory.hpp b/include/pd/base/Memory.hpp deleted file mode 100644 index b2badba..0000000 --- a/include/pd/base/Memory.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include - -namespace Palladium { -namespace Memory { -/// @brief Metriks struct For the Internal Tracker -struct memory_metrics { - unsigned int t_TotalAllocated = 0; ///< Total Allocated Memory - unsigned int t_TotalFreed = 0; ///< Total Deleted Memory - /// @brief Gets the Currently Allocated Memory - unsigned int t_CurrentlyAllocated() { - return t_TotalAllocated - t_TotalFreed; - } -}; -/// @brief Get Total Allocated Memory -/// @return Total Allocated Memory -size_t GetTotalAllocated(); -/// @brief Get Total Deleted Memory -/// @return Total Deleted Memory -size_t GetTotalFreed(); -/// @brief Get Current Allocated Memory -/// @return Current Allocated Memory -size_t GetCurrent(); -} // namespace Memory -} // namespace Palladium diff --git a/include/pd/base/stringtool.hpp b/include/pd/base/stringtool.hpp deleted file mode 100644 index 3b29e85..0000000 --- a/include/pd/base/stringtool.hpp +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace Palladium { -/// @brief Check if A String ends with -/// @param name Input String -/// @param extensions Extensions to Check for -/// @return Ends with or not -inline bool NameIsEndingWith(const std::string &name, - const std::vector &extensions) { - if (name.substr(0, 2) == "._") return false; - - if (name.size() == 0) return false; - - if (extensions.size() == 0) return true; - - for (int i = 0; i < (int)extensions.size(); i++) { - const std::string ext = extensions.at(i); - if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) - return true; - } - - return false; -} -/// @brief Format Milliseconds to clean string (Stolen from one of my Mc -/// Plugins) -/// @param t_time Time in ms -/// @return String -inline std::string MsTimeFmt(float t_time, bool dems = false) { - std::string res; - - if (t_time < 0.000001f) { - res = std::format("{:.2f}ns", t_time * 1000000.f); - } else if (t_time < 0.001f) { - res = std::format("{:.2f}µs", t_time * 1000.f); - } else if (t_time < 1.0f) { - res = std::format("{:.2f}ms", t_time); - } else if (t_time < 60000.0f) { - int seconds = static_cast(t_time / 1000.0f); - float milliseconds = t_time - (seconds * 1000.0f); - if (seconds) { - res = std::format("{}s {:.2f}ms", seconds, milliseconds); - } - res = std::format("{:.2f}ms", milliseconds); - } else { - int minutes = static_cast(t_time / 60000.0f); - int seconds = static_cast((t_time - (minutes * 60000.0f)) / 1000.0f); - float milliseconds = t_time - (minutes * 60000.0f) - (seconds * 1000.0f); - - res = std::format("{}m {}s {:.2f}ms", minutes, seconds, milliseconds); - } - - return res; -} - -inline std::string FormatBytes(int bytes) { - char out[32]; - - if (bytes == 1) - snprintf(out, sizeof(out), "%d Byte", bytes); - - else if (bytes < 1024) - snprintf(out, sizeof(out), "%d Bytes", bytes); - - else if (bytes < 1024 * 1024) - snprintf(out, sizeof(out), "%.1f KB", (float)bytes / 1024); - - else if (bytes < 1024 * 1024 * 1024) - snprintf(out, sizeof(out), "%.1f MB", (float)bytes / 1024 / 1024); - - else - snprintf(out, sizeof(out), "%.1f GB", (float)bytes / 1024 / 1024 / 1024); - - return out; -} -} // namespace Palladium - -template -T GetFileName(T const &path, T const &delims = "/\\") { - return path.substr(path.find_last_of(delims) + 1); -} -template -T remove_ext(T const &filename) { - typename T::size_type const p(filename.find_last_of('.')); - return p > 0 && p != T::npos ? filename.substr(0, p) : filename; -} - -template -std::string Int_To_Hex(T i) { - std::stringstream stream; - stream << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex - << i; - return stream.str(); -} \ No newline at end of file diff --git a/include/pd/common/app.hpp b/include/pd/common/app.hpp new file mode 100644 index 0000000..ed92138 --- /dev/null +++ b/include/pd/common/app.hpp @@ -0,0 +1,68 @@ +#pragma once + +/* +MIT License +Copyright (c) 2024 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include +#include +#include + +namespace PD { +/// @brief Template Class for User Application +class App : public SmartCtor { + public: + App() = default; + ~App() = default; + + /// @brief Templete function where the user can Init his stuff + virtual void Init() {} + /// @brief Templeta funciton to deinit stuff + /// (most of that is done automatically) + virtual void Deinit() {} + /// @brief App Mainloop + /// @param delta Deltatime + /// @param time App RunTime + /// @return false to exit the app + virtual bool MainLoop(u64 delta, float time) { return false; } + + /// @brief Function to run the App + /// (int main() { + /// auto app = PD::New(); + /// app->Run(); + /// return 0; + /// }) + void Run(); + + LI::Renderer::Ref Renderer() { return renderer; } + + float GetFps() const { return fps; } + + private: + void PreInit(); + void PostDeinit(); + LI::Renderer::Ref renderer; + u64 last_time; + float app_time; + float fps; +}; +} // namespace PD \ No newline at end of file diff --git a/include/pd/common/common.hpp b/include/pd/common/common.hpp new file mode 100644 index 0000000..b7c1016 --- /dev/null +++ b/include/pd/common/common.hpp @@ -0,0 +1,71 @@ +#pragma once + +/* +MIT License +Copyright (c) 2024 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include +#include +#include +#include // Requires C++ 17 or later +#include // Requires C++ 20 or later +#include +#include +#include +#include +#include +#include +#include + +namespace PD { +// New Version of Smart CTOR +// Using as Template class +template +class SmartCtor { + public: + /// @brief Type Reference + using Ref = std::shared_ptr; + + /// @brief Creates a New Shared Pointer + /// @param ...args Arguments to forward + /// @return Shared Pointer (Reference) + template + static Ref New(Args&&... args) { + return std::make_shared(std::forward(args)...); + } +}; +/// @brief Wrapper for SmartCtor::New +/// @tparam T class type +/// @param ...args Arguments +/// @return SmartCtor::Ref type reference +/// @note Not sure if this is solving the problem or +/// if I schould switch back to the macro +template +SmartCtor::Ref New(Args&&... args) { + return SmartCtor::New(std::forward(args)...); +} +// Defines +using u64 = unsigned long long; +using u32 = unsigned int; +using u16 = unsigned short; +using u8 = unsigned char; +} // namespace PD \ No newline at end of file diff --git a/include/pd/common/error.hpp b/include/pd/common/error.hpp new file mode 100644 index 0000000..96892b0 --- /dev/null +++ b/include/pd/common/error.hpp @@ -0,0 +1,31 @@ +#pragma once + +/* +MIT License +Copyright (c) 2024 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include + +namespace PD { +void Error(const std::string& error); +void Assert(bool v, const std::string& msg); +} // namespace PD \ No newline at end of file diff --git a/include/pd/common/lang.hpp b/include/pd/common/lang.hpp new file mode 100644 index 0000000..d38b69f --- /dev/null +++ b/include/pd/common/lang.hpp @@ -0,0 +1,57 @@ +#pragma once + +/* +MIT License +Copyright (c) 2024 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include + +namespace PD { +/// @brief Lang System +///< Translations are saved into json files +///< Path should point to a directory the fils +///< for example the files ar named [en.json, de.json, fr.json] +class Lang : public SmartCtor { + public: + Lang() = default; + ~Lang() = default; + + void SetBasePath(const std::string &path) { langs_path = path; } + void Load(const std::string &lang_key) { + LoadFile(langs_path + "/" + lang_key + ".json"); + } + void LoadFile(const std::string &path); + const std::string &Get(const std::string &k); + const std::string &GetName() { return lang_name; } + const std::string &GetID() { return lang_id; } + const std::string &GetAuthor() { return lang_author; } + const std::string &GetPath() { return langs_path; } + + private: + const int ver = 0; + std::string langs_path = "romfs:/lang"; + std::string lang_name; + std::string lang_id; + std::string lang_author; + std::map ltable; +}; +} // namespace PD \ No newline at end of file diff --git a/include/pd/common/memory.hpp b/include/pd/common/memory.hpp new file mode 100644 index 0000000..96a09ad --- /dev/null +++ b/include/pd/common/memory.hpp @@ -0,0 +1,60 @@ +#pragma once + +/* +MIT License + +Copyright (c) 2024 tobid7 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include <3ds.h> + +#include +#include + +namespace PD { +template +class LinearAllocator : public std::allocator { + public: + using size_type = size_t; + using pointer = T*; + using const_pointer = const T*; + + template + struct rebind { + using other = LinearAllocator; + }; + + pointer allocate(size_type n, const void* hint = nullptr) { + if (n > this->max_size()) { + Error("Linear Alloc failed (no space left)"); + return nullptr; + } + return (pointer)linearAlloc(n * sizeof(T)); + } + void deallocate(pointer p, size_type) { linearFree((void*)p); } + size_type max_size() { return linearSpaceFree(); } + + LinearAllocator() noexcept {} + LinearAllocator(const LinearAllocator& a) noexcept + : std::allocator(a) {} + ~LinearAllocator() noexcept {} +}; +} // namespace PD \ No newline at end of file diff --git a/include/pd/common/strings.hpp b/include/pd/common/strings.hpp new file mode 100644 index 0000000..00e6a3d --- /dev/null +++ b/include/pd/common/strings.hpp @@ -0,0 +1,42 @@ +#pragma once + +/* +MIT License +Copyright (c) 2024 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include + +namespace PD { +namespace Strings { +bool StringEndsWith(const std::string& str, + const std::vector& exts); +std::wstring MakeWstring(const std::string& s); +const std::string FormatNanos(unsigned long long nanos); +const std::string FormatMillis(unsigned long long millis); +const std::string FormatBytes(unsigned long long bytes); +const std::string GetFileName(const std::string& path, + const std::string& saperators = "/\\"); +const std::string PathRemoveExtension(const std::string& path); +template +const std::string ToHex(const T& v); +} // namespace Strings +} // namespace PD \ No newline at end of file diff --git a/include/pd/common/sys.hpp b/include/pd/common/sys.hpp new file mode 100644 index 0000000..59c5956 --- /dev/null +++ b/include/pd/common/sys.hpp @@ -0,0 +1,37 @@ +#pragma once + +/* +MIT License +Copyright (c) 2024 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include +#include + +namespace PD { +namespace Sys { +using TraceMap = std::map; +u64 GetTime(); +u64 GetNanoTime(); +TT::Res::Ref& GetTraceRef(const std::string& id); +TraceMap& GetTraceMap(); +} // namespace Sys +} // namespace PD diff --git a/include/pd/common/timer.hpp b/include/pd/common/timer.hpp new file mode 100644 index 0000000..3a0d3be --- /dev/null +++ b/include/pd/common/timer.hpp @@ -0,0 +1,44 @@ +#pragma once + +/* +MIT License +Copyright (c) 2024 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include +#include + +namespace PD { +class Timer { + public: + Timer() {} + ~Timer() {} + void Start() {} + void Pause() {} + void Update() {} + void Reset() { start_ = Sys::GetTime(); } + u64 Get() {} + + private: + u64 start_; + u64 now_; +}; +} // namespace PD \ No newline at end of file diff --git a/include/pd/common/timetrace.hpp b/include/pd/common/timetrace.hpp new file mode 100644 index 0000000..a38993a --- /dev/null +++ b/include/pd/common/timetrace.hpp @@ -0,0 +1,102 @@ +#pragma once + +/* +MIT License +Copyright (c) 2024 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include + +namespace PD { +class TimeStats : public SmartCtor { + public: + TimeStats(int l) : len(l), val(l, 0) {} + ~TimeStats() = default; + + void Add(unsigned long long v) { + val[idx] = v; + idx = next(idx); + num_val = std::min(num_val + 1, len); + } + + unsigned long long GetAverage() { + if (!num_val) return 0.f; + unsigned long long res = 0; + for (int i = 0; i < num_val; i++) { + res += val[smart_idx(i)]; + } + return res / num_val; + } + + const std::vector &GetData() { return val; } + const unsigned long long &operator[](int i) { return val[smart_idx(i)]; } + const size_t GetLen() { return len; } + const size_t GetNumValues() { return num_val; } + + private: + size_t next(size_t c) const { return (c + 1) % len; } + size_t smart_idx(size_t v) const { return (idx + len - num_val + v) % len; } + + int len = 0; + std::vector val; + int idx = 0; + int num_val = 0; +}; +namespace TT { +class Res : public SmartCtor { + public: + Res() { protocol = TimeStats::New(60); } + ~Res() = default; + + void SetID(const std::string &v) { id = v; } + const std::string GetID() { return id; } + void SetStart(unsigned long long v) { start = v; } + unsigned long long GetStart() { return start; } + void SetEnd(unsigned long long v) { + end = v; + protocol->Add(GetLastDiff()); + } + unsigned long long GetEnd() { return end; } + + unsigned long long GetLastDiff() { return end - start; } + TimeStats::Ref GetProtocol() { return protocol; } + + private: + std::string id; + unsigned long long start; + unsigned long long end; + TimeStats::Ref protocol; +}; +void Beg(const std::string &id); +void End(const std::string &id); +class Scope { + public: + Scope(const std::string &id) { + this->id = id; + Beg(id); + } + ~Scope() { End(id); } + + private: + std::string id; +}; +} // namespace TT +} // namespace PD \ No newline at end of file diff --git a/include/pd/external/json.hpp b/include/pd/external/json.hpp index a07fc88..d7f137e 100644 --- a/include/pd/external/json.hpp +++ b/include/pd/external/json.hpp @@ -1,57 +1,160 @@ -/* - __ _____ _____ _____ - __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.9.1 -|_____|_____|_____|_|___| https://github.com/nlohmann/json +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-License-Identifier: MIT -Licensed under the MIT License . -SPDX-License-Identifier: MIT -Copyright (c) 2013-2019 Niels Lohmann . - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +/****************************************************************************\ + * 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_ -#define NLOHMANN_JSON_VERSION_MAJOR 3 -#define NLOHMANN_JSON_VERSION_MINOR 9 -#define NLOHMANN_JSON_VERSION_PATCH 1 - #include // all_of, find, for_each #include // nullptr_t, ptrdiff_t, size_t #include // hash, less #include // initializer_list -#include // istream, ostream +#ifndef JSON_NO_IO + #include // istream, ostream +#endif // JSON_NO_IO #include // random_access_iterator_tag #include // unique_ptr -#include // accumulate #include // string, stoi, to_string #include // declval, forward, move, pair, swap #include // vector // #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-License-Identifier: MIT + #include +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 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 != 11 || NLOHMANN_JSON_VERSION_PATCH != 3 + #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 11 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum) + +#ifndef JSON_DIAGNOSTICS + #define JSON_DIAGNOSTICS 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_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) json_abi ## a ## b +#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ + NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) + +#define NLOHMANN_JSON_ABI_TAGS \ + NLOHMANN_JSON_ABI_TAGS_CONCAT( \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ + NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) + +// 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.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-License-Identifier: MIT + #include // transform @@ -59,6 +162,9 @@ SOFTWARE. #include // forward_list #include // inserter, front_inserter, end #include // map +#ifdef JSON_HAS_CPP_17 + #include // optional +#endif #include // string #include // tuple, make_tuple #include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible @@ -66,64 +172,174 @@ SOFTWARE. #include // pair, declval #include // valarray + // #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 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 +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-License-Identifier: MIT + +#include // array #include // size_t - -namespace nlohmann -{ -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 -} // namespace nlohmann +#include // uint8_t +#include // string // #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-License-Identifier: MIT -#include // pair + +#include // declval, pair +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 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.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-FileCopyrightText: 2016 - 2021 Evan Nemerson +// SPDX-License-Identifier: MIT + /* Hedley - https://nemequ.github.io/hedley * Created by Evan Nemerson - * - * To the extent possible under law, the author(s) have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. - * - * For details, see . - * SPDX-License-Identifier: CC0-1.0 */ -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13) +#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) #if defined(JSON_HEDLEY_VERSION) #undef JSON_HEDLEY_VERSION #endif -#define JSON_HEDLEY_VERSION 13 +#define JSON_HEDLEY_VERSION 15 #if defined(JSON_HEDLEY_STRINGIFY_EX) #undef JSON_HEDLEY_STRINGIFY_EX @@ -196,18 +412,18 @@ struct position_t #if defined(JSON_HEDLEY_MSVC_VERSION) #undef JSON_HEDLEY_MSVC_VERSION #endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) +#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) +#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) +#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(_MSC_VER) +#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))) @@ -220,9 +436,9 @@ struct position_t #if defined(JSON_HEDLEY_INTEL_VERSION) #undef JSON_HEDLEY_INTEL_VERSION #endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) +#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) +#elif defined(__INTEL_COMPILER) && !defined(__ICL) #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) #endif @@ -235,6 +451,22 @@ struct position_t #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 @@ -474,7 +706,7 @@ struct position_t #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) + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) #endif #endif @@ -551,6 +783,22 @@ struct position_t #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 @@ -560,6 +808,7 @@ struct position_t !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) && \ @@ -567,7 +816,8 @@ struct position_t !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ - !defined(__COMPCERT__) + !defined(__COMPCERT__) && \ + !defined(JSON_HEDLEY_MCST_LCC_VERSION) #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION #endif @@ -583,17 +833,21 @@ struct position_t #if defined(JSON_HEDLEY_HAS_ATTRIBUTE) #undef JSON_HEDLEY_HAS_ATTRIBUTE #endif -#if defined(__has_attribute) - #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) +#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) +# 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) __has_attribute(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 @@ -602,7 +856,7 @@ struct position_t #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE #endif #if defined(__has_attribute) - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(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 @@ -787,6 +1041,72 @@ struct position_t #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_) @@ -795,12 +1115,22 @@ struct position_t #if defined(__cplusplus) # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ +# 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 \ @@ -865,7 +1195,7 @@ struct position_t # define JSON_HEDLEY_CPP_CAST(T, expr) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ _Pragma("diag_suppress=Pe137") \ - JSON_HEDLEY_DIAGNOSTIC_POP \ + JSON_HEDLEY_DIAGNOSTIC_POP # else # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) # endif @@ -873,70 +1203,6 @@ struct position_t # define JSON_HEDLEY_CPP_CAST(T, expr) (expr) #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) - #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 - #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED #endif @@ -944,12 +1210,18 @@ struct position_t #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__)) || \ @@ -982,6 +1254,8 @@ struct position_t #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) @@ -998,6 +1272,8 @@ struct position_t #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 @@ -1011,8 +1287,12 @@ struct position_t #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) @@ -1024,6 +1304,8 @@ struct position_t #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 @@ -1041,20 +1323,34 @@ struct position_t #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) +#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 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_EXTENSION(attribute_deprecated_with_message) || \ + (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) || \ @@ -1064,9 +1360,13 @@ struct position_t 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_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) || \ @@ -1081,12 +1381,15 @@ struct position_t (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_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_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) @@ -1103,7 +1406,8 @@ struct position_t #if \ JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,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) @@ -1115,13 +1419,7 @@ struct position_t #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG #endif -#if (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 \ +#if \ JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ @@ -1137,9 +1435,16 @@ struct position_t 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_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_ @@ -1155,7 +1460,8 @@ struct position_t 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_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) @@ -1166,7 +1472,9 @@ struct position_t #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) +#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 @@ -1188,11 +1496,14 @@ struct position_t (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_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) +#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;") @@ -1224,7 +1535,8 @@ struct position_t #endif #if \ JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,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) @@ -1242,7 +1554,9 @@ struct position_t 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_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) @@ -1320,7 +1634,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP (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_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)) @@ -1356,15 +1671,16 @@ JSON_HEDLEY_DIAGNOSTIC_POP #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) #endif #if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) + (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) || \ + (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)) || \ @@ -1378,7 +1694,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP 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_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) \ @@ -1424,11 +1741,14 @@ JSON_HEDLEY_DIAGNOSTIC_POP (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_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) +#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 @@ -1455,7 +1775,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP 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_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") @@ -1491,7 +1812,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP 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_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) @@ -1509,6 +1831,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP 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) || \ @@ -1518,7 +1841,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP 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__) + 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 @@ -1539,13 +1863,15 @@ JSON_HEDLEY_DIAGNOSTIC_POP #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_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 @@ -1571,9 +1897,13 @@ JSON_HEDLEY_DIAGNOSTIC_POP (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_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) +#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) && \ ( \ @@ -1611,9 +1941,13 @@ JSON_HEDLEY_DIAGNOSTIC_POP (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_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) +#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") @@ -1656,7 +1990,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP (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 @@ -1672,10 +2007,12 @@ JSON_HEDLEY_DIAGNOSTIC_POP #if \ JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,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 @@ -1687,7 +2024,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) + 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]]) @@ -1704,7 +2042,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) + 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_ @@ -1746,7 +2085,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP 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_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) @@ -1770,7 +2110,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ !defined(JSON_HEDLEY_PGI_VERSION) && \ !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \ + (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) || \ @@ -1840,7 +2180,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP #if \ !defined(__cplusplus) && ( \ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \ + (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) \ @@ -1848,7 +2188,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP # 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_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) @@ -1908,7 +2249,9 @@ JSON_HEDLEY_DIAGNOSTIC_POP 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) +#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) @@ -1944,8 +2287,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP #if defined(JSON_HEDLEY_FLAGS) #undef JSON_HEDLEY_FLAGS #endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) +#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) @@ -1965,7 +2310,9 @@ JSON_HEDLEY_DIAGNOSTIC_POP #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) +#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 @@ -2020,9 +2367,12 @@ JSON_HEDLEY_DIAGNOSTIC_POP #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ -// This file contains all internal macro definitions +// 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__) @@ -2037,30 +2387,136 @@ JSON_HEDLEY_DIAGNOSTIC_POP #endif // C++ language standard detection -#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) - #define JSON_HAS_CPP_20 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 +// if the user manually specified the used c++ version this is skipped +#if !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_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (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 -// disable float-equal warnings on GCC/clang -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wfloat-equal" +#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 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 GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" #endif -// allow to disable exceptions +// allow disabling exceptions #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) #define JSON_THROW(exception) throw exception #define JSON_TRY try @@ -2094,12 +2550,19 @@ JSON_HEDLEY_DIAGNOSTIC_POP #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER #endif -// allow to override assert +// allow overriding assert #if !defined(JSON_ASSERT) #include // assert #define JSON_ASSERT(x) assert(x) #endif +// allow to access 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 @@ -2109,7 +2572,9 @@ JSON_HEDLEY_DIAGNOSTIC_POP 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 \ @@ -2121,7 +2586,9 @@ JSON_HEDLEY_DIAGNOSTIC_POP 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 \ @@ -2141,12 +2608,13 @@ JSON_HEDLEY_DIAGNOSTIC_POP class NumberUnsignedType, class NumberFloatType, \ template class AllocatorType, \ template class JSONSerializer, \ - class BinaryType> + class BinaryType, \ + class CustomBaseClass> #define NLOHMANN_BASIC_JSON_TPL \ basic_json + AllocatorType, JSONSerializer, BinaryType, CustomBaseClass> // Macros to simplify conversion from/to types @@ -2283,6 +2751,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP #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.value(#v1, nlohmann_json_default_obj.v1); /*! @brief macro @@ -2293,6 +2762,13 @@ JSON_HEDLEY_DIAGNOSTIC_POP friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& 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__)) } + +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + friend void to_json(nlohmann::json& 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 @@ -2302,6 +2778,77 @@ JSON_HEDLEY_DIAGNOSTIC_POP inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& 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_DERIVED_TYPE_INTRUSIVE +@since version 3.11.x +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ + friend void to_json(nlohmann::json& 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__)) } \ + friend void from_json(const nlohmann::json& 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__)) } + +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + friend void to_json(nlohmann::json& 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__)) } \ + friend void from_json(const nlohmann::json& 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 +@since version 3.11.x +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ + inline void to_json(nlohmann::json& 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__)) } \ + inline void from_json(const nlohmann::json& 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__)) } + +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + inline void to_json(nlohmann::json& 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__)) } \ + inline void from_json(const nlohmann::json& 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__)) } + +// inspired from https://stackoverflow.com/a/26745591 +// allows to call 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 @@ -2312,406 +2859,383 @@ JSON_HEDLEY_DIAGNOSTIC_POP #define JSON_EXPLICIT explicit #endif +#ifndef JSON_DISABLE_ENUM_SERIALIZATION + #define JSON_DISABLE_ENUM_SERIALIZATION 0 +#endif -namespace nlohmann -{ +#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 { -//////////////// -// exceptions // -//////////////// + +/////////////////////////// +// JSON type enumeration // +/////////////////////////// /*! -@brief general exception of the @ref basic_json class +@brief the JSON type enumeration -This class is an extension of `std::exception` objects with a member @a id for -exception ids. It is used as the base class for all exceptions thrown by the -@ref basic_json class. This class can hence be used as "wildcard" to catch -exceptions. +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. -Subclasses: -- @ref parse_error for exceptions indicating a parse error -- @ref invalid_iterator for exceptions indicating errors with iterators -- @ref type_error for exceptions indicating executing a member function with - a wrong type -- @ref out_of_range for exceptions indicating access out of the defined range -- @ref other_error for exceptions indicating other library errors +@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. -@internal -@note To have nothrow-copy-constructible exceptions, we internally use - `std::runtime_error` which can cope with arbitrary-length error messages. - Intermediate strings are built with static functions and then passed to - the actual constructor. -@endinternal +@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON +value with the default value for a given type -@liveexample{The following code shows how arbitrary library exceptions can be -caught.,exception} - -@since version 3.0.0 +@since version 1.0.0 */ -class exception : public std::exception +enum class value_t : std::uint8_t { - public: - /// returns the explanatory string - JSON_HEDLEY_RETURNS_NON_NULL - const char* what() const noexcept override - { - return m.what(); - } - - /// the id of the exception - const int id; - - protected: - JSON_HEDLEY_NON_NULL(3) - exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} - - static std::string name(const std::string& ename, int id_) - { - return "[json.exception." + ename + "." + std::to_string(id_) + "] "; - } - - private: - /// an exception object as storage for error messages - std::runtime_error m; + 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 exception indicating a parse error +@brief comparison operator for JSON types -This exception is thrown by the library when a parse error occurs. Parse errors -can occur during the deserialization of JSON text, CBOR, MessagePack, as well -as when using JSON Patch. +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. -Member @a byte holds the byte index of the last read character in the input -file. - -Exceptions have ids 1xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position. -json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point. -json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid. -json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects. -json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors. -json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`. -json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character. -json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences. -json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number. -json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read. -json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read. -json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read. -json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet). -json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed. - -@note For an input with n bytes, 1 is the index of the first character and n+1 - is the index of the terminating null byte or the end of file. This also - holds true when reading a byte vector (CBOR or MessagePack). - -@liveexample{The following code shows how a `parse_error` exception can be -caught.,parse_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 +@since version 1.0.0 */ -class parse_error : public exception +#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 { - public: - /*! - @brief create a parse error exception - @param[in] id_ the id of the exception - @param[in] pos the position where the error occurred (or with - chars_read_total=0 if the position cannot be - determined) - @param[in] what_arg the explanatory string - @return parse_error object - */ - static parse_error create(int id_, const position_t& pos, const std::string& what_arg) + 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()) { - std::string w = exception::name("parse_error", id_) + "parse error" + - position_string(pos) + ": " + what_arg; - return parse_error(id_, pos.chars_read_total, w.c_str()); + 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 +} - static parse_error create(int id_, std::size_t byte_, const std::string& what_arg) - { - std::string w = exception::name("parse_error", id_) + "parse error" + - (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") + - ": " + what_arg; - return parse_error(id_, byte_, w.c_str()); - } - - /*! - @brief byte index of the parse error - - The byte index of the last read character in the input file. - - @note For an input with n bytes, 1 is the index of the first character and - n+1 is the index of the terminating null byte or the end of file. - This also holds true when reading a byte vector (CBOR or MessagePack). - */ - const std::size_t byte; - - private: - parse_error(int id_, std::size_t byte_, const char* what_arg) - : exception(id_, what_arg), byte(byte_) {} - - static std::string position_string(const position_t& pos) - { - return " at line " + std::to_string(pos.lines_read + 1) + - ", column " + std::to_string(pos.chars_read_current_line); - } -}; - -/*! -@brief exception indicating errors with iterators - -This exception is thrown if iterators passed to a library function do not match -the expected semantics. - -Exceptions have ids 2xx. - -name / id | example message | description ------------------------------------ | --------------- | ------------------------- -json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion. -json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from. -json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid. -json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid. -json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range. -json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key. -json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to. -json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container. -json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered. -json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin(). - -@liveexample{The following code shows how an `invalid_iterator` exception can be -caught.,invalid_iterator} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class invalid_iterator : public exception +// 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 { - public: - static invalid_iterator create(int id_, const std::string& what_arg) - { - std::string w = exception::name("invalid_iterator", id_) + what_arg; - return invalid_iterator(id_, w.c_str()); - } + return std::is_lt(lhs <=> rhs); // *NOPAD* +} +#endif - private: - JSON_HEDLEY_NON_NULL(3) - invalid_iterator(int id_, const char* what_arg) - : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating executing a member function with a wrong type - -This exception is thrown in case of a type error; that is, a library function is -executed on a JSON value whose type does not match the expected semantics. - -Exceptions have ids 3xx. - -name / id | example message | description ------------------------------ | --------------- | ------------------------- -json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. -json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. -json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &. -json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types. -json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types. -json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types. -json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types. -json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types. -json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types. -json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types. -json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types. -json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types. -json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined. -json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers. -json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive. -json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. | -json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) | - -@liveexample{The following code shows how a `type_error` exception can be -caught.,type_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class type_error : public exception -{ - public: - static type_error create(int id_, const std::string& what_arg) - { - std::string w = exception::name("type_error", id_) + what_arg; - return type_error(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating access out of the defined range - -This exception is thrown in case a library function is called on an input -parameter that exceeds the expected range, for instance in case of array -indices or nonexisting object keys. - -Exceptions have ids 4xx. - -name / id | example message | description -------------------------------- | --------------- | ------------------------- -json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1. -json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it. -json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object. -json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved. -json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. -json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF. -json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) | -json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. | -json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | - -@liveexample{The following code shows how an `out_of_range` exception can be -caught.,out_of_range} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class out_of_range : public exception -{ - public: - static out_of_range create(int id_, const std::string& what_arg) - { - std::string w = exception::name("out_of_range", id_) + what_arg; - return out_of_range(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating other library errors - -This exception is thrown in case of errors that cannot be classified with the -other exception types. - -Exceptions have ids 5xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed. - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range - -@liveexample{The following code shows how an `other_error` exception can be -caught.,other_error} - -@since version 3.0.0 -*/ -class other_error : public exception -{ - public: - static other_error create(int id_, const std::string& what_arg) - { - std::string w = exception::name("other_error", id_) + what_arg; - return other_error(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; } // namespace detail -} // namespace nlohmann +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 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 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 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 +static 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.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 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.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 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 -namespace nlohmann -{ +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { -// alias templates to reduce boilerplate -template -using enable_if_t = typename std::enable_if::type; template using uncvref_t = typename std::remove_cv::type>::type; -// implementation of C++14 index_sequence and affiliates -// source: https://stackoverflow.com/a/32223343 -template -struct index_sequence +#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 type = index_sequence; - using value_type = std::size_t; + using value_type = T; static constexpr std::size_t size() noexcept { return sizeof...(Ints); } }; -template -struct merge_and_renumber; +// 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; -template -struct merge_and_renumber, index_sequence> - : index_sequence < I1..., (sizeof...(I1) + I2)... > {}; +namespace utility_internal +{ -template -struct make_index_sequence - : merge_and_renumber < typename make_index_sequence < N / 2 >::type, - typename make_index_sequence < N - N / 2 >::type > {}; +template +struct Extend; -template<> struct make_index_sequence<0> : index_sequence<> {}; -template<> struct make_index_sequence<1> : index_sequence<0> {}; +// 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 +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> {}; @@ -2720,48 +3244,64 @@ template<> struct priority_tag<0> {}; template struct static_const { - static constexpr T value{}; + static JSON_INLINE_VARIABLE constexpr T value{}; }; -template -constexpr T static_const::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 -} // namespace nlohmann +NLOHMANN_JSON_NAMESPACE_END // #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-License-Identifier: MIT + #include // numeric_limits #include // false_type, is_constructible, is_integral, is_same, true_type #include // declval +#include // tuple +#include // char_traits // #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-License-Identifier: MIT + #include // random_access_iterator_tag +// #include + // #include - -namespace nlohmann -{ -namespace detail -{ -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; -} // namespace detail -} // namespace nlohmann - // #include -namespace nlohmann -{ +NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { + template struct iterator_types {}; @@ -2800,157 +3340,136 @@ struct iterator_traits::value>> using pointer = T*; using reference = T&; }; -} // namespace detail -} // namespace nlohmann + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END // #include +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 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.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 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 - -// #include - - -// https://en.cppreference.com/w/cpp/experimental/is_detected -namespace nlohmann -{ -namespace detail -{ -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> -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 -} // namespace nlohmann - // #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2024 Niels Lohmann +// SPDX-License-Identifier: MIT + #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ -#define 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 // int64_t, uint64_t + #include // map + #include // allocator + #include // string + #include // vector -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -namespace nlohmann -{ -/*! -@brief default JSONSerializer template argument + // #include -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; -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> -class basic_json; + /*! + @brief namespace for Niels Lohmann + @see https://github.com/nlohmann + @since version 1.0.0 + */ + NLOHMANN_JSON_NAMESPACE_BEGIN -/*! -@brief JSON Pointer + /*! + @brief default JSONSerializer template argument -A JSON pointer defines a string syntax for identifying a specific value -within a JSON document. It can be used with functions `at` and -`operator[]`. Furthermore, JSON pointers are the base for JSON patches. + 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; -@sa [RFC 6901](https://tools.ietf.org/html/rfc6901) + /// 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; -@since version 2.0.0 -*/ -template -class json_pointer; + /// @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 JSON class + /*! + @brief default specialization + @sa https://json.nlohmann.me/api/json/ + */ + using json = basic_json<>; -This type is the default specialization of the @ref basic_json class which -uses the standard template types. + /// @brief a minimal map-like container that preserves insertion order + /// @sa https://json.nlohmann.me/api/ordered_map/ + template + struct ordered_map; -@since version 1.0.0 -*/ -using json = basic_json<>; + /// @brief specialization that maintains the insertion order of object keys + /// @sa https://json.nlohmann.me/api/ordered_json/ + using ordered_json = basic_json; -template -struct ordered_map; - -/*! -@brief ordered JSON class - -This type preserves the insertion order of object keys. - -@since version 3.9.0 -*/ -using ordered_json = basic_json; - -} // namespace nlohmann + NLOHMANN_JSON_NAMESPACE_END #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ -namespace nlohmann -{ +NLOHMANN_JSON_NAMESPACE_BEGIN /*! @brief detail namespace with internal helper functions @@ -2961,6 +3480,7 @@ implementations of some @ref basic_json methods, and meta-programming helpers. */ namespace detail { + ///////////// // helpers // ///////////// @@ -2979,6 +3499,16 @@ 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 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 // ////////////////////// @@ -3017,9 +3547,6 @@ using reference_t = typename T::reference; template using iterator_category_t = typename T::iterator_category; -template -using iterator_t = typename T::iterator; - template using to_json_function = decltype(T::to_json(std::declval()...)); @@ -3044,8 +3571,7 @@ struct is_getable }; template -struct has_from_json < BasicJsonType, T, - enable_if_t < !is_basic_json::value >> +struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> { using serializer = typename BasicJsonType::template json_serializer; @@ -3084,11 +3610,133 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> T>::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(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(EOF); + } +}; /////////////////// // 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 {}; @@ -3107,7 +3755,34 @@ struct is_iterator_traits> is_detected::value; }; -// source: https://stackoverflow.com/a/37193089/4116453 +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 using it in this library. template struct is_complete_type : std::false_type {}; @@ -3125,14 +3800,13 @@ struct is_compatible_object_type_impl < 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 = - std::is_constructible::value && - std::is_constructible::value; }; @@ -3153,10 +3827,10 @@ struct is_constructible_object_type_impl < using object_t = typename BasicJsonType::object_t; static constexpr bool value = - (std::is_default_constructible::value && + (is_default_constructible::value && (std::is_move_assignable::value || std::is_copy_assignable::value) && - (std::is_constructible::value && std::is_same < typename object_t::mapped_type, @@ -3173,42 +3847,29 @@ struct is_constructible_object_type : is_constructible_object_type_impl {}; -template -struct is_compatible_string_type_impl : std::false_type {}; - template -struct is_compatible_string_type_impl < - BasicJsonType, CompatibleStringType, - enable_if_t::value >> -{ - static constexpr auto value = - std::is_constructible::value; -}; - -template struct is_compatible_string_type - : is_compatible_string_type_impl {}; - -template -struct is_constructible_string_type_impl : std::false_type {}; - -template -struct is_constructible_string_type_impl < - BasicJsonType, ConstructibleStringType, - enable_if_t::value >> { static constexpr auto value = - std::is_constructible::value; + is_constructible::value; }; template struct is_constructible_string_type - : is_constructible_string_type_impl {}; +{ + // 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 {}; @@ -3216,17 +3877,16 @@ struct is_compatible_array_type_impl : std::false_type {}; template struct is_compatible_array_type_impl < BasicJsonType, CompatibleArrayType, - enable_if_t < is_detected::value&& + enable_if_t < is_detected::value&& -// This is needed because json_reverse_iterator has a ::iterator type... -// Therefore it is detected as a CompatibleArrayType. -// The real fix would be to have an Iterable concept. - !is_iterator_traits < - iterator_traits>::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 = - std::is_constructible::value; + is_constructible>::value; }; template @@ -3248,28 +3908,29 @@ struct is_constructible_array_type_impl < BasicJsonType, ConstructibleArrayType, enable_if_t < !std::is_same::value&& - std::is_default_constructible::value&& + !is_compatible_string_type::value&& + is_default_constructible::value&& (std::is_move_assignable::value || std::is_copy_assignable::value)&& -is_detected::value&& is_detected::value&& -is_complete_type < -detected_t>::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 >> { - static constexpr bool value = - // This is needed because json_reverse_iterator has a ::iterator type, - // furthermore, std::back_insert_iterator (and other iterators) have a - // base class `iterator`... Therefore it is detected as a - // ConstructibleArrayType. The real fix would be to have an Iterable - // concept. - !is_iterator_traits>::value && + using value_type = range_value_t; - (std::is_same::value || - has_from_json::value || - has_non_default_from_json < - BasicJsonType, typename ConstructibleArrayType::value_type >::value); + static constexpr bool value = + std::is_same::value || + has_from_json::value || + has_non_default_from_json < + BasicJsonType, + value_type >::value; }; template @@ -3292,7 +3953,7 @@ struct is_compatible_integer_type_impl < using CompatibleLimits = std::numeric_limits; static constexpr auto value = - std::is_constructible::value && CompatibleLimits::is_integer && RealLimits::is_signed == CompatibleLimits::is_signed; @@ -3319,119 +3980,764 @@ template struct is_compatible_type : is_compatible_type_impl {}; -// https://en.cppreference.com/w/cpp/types/conjunction -template struct conjunction : std::true_type { }; -template struct conjunction : B1 { }; -template -struct conjunction -: std::conditional, B1>::type {}; - template struct is_constructible_tuple : std::false_type {}; template -struct is_constructible_tuple> : conjunction...> {}; +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