├── .gitattributes ├── .gitignore ├── Content └── Blueprints │ ├── ImportMap │ ├── Mapbox_BP.uasset │ └── old │ │ ├── ImportLines.uasset │ │ └── TestMapImport.uasset │ └── TrackGenerator │ ├── Blueprints │ ├── BP_Road_Generator.uasset │ ├── BP_TrackGenerator.uasset │ └── BP_TrackGenerator_2.uasset │ ├── Data │ ├── E_GaurdRailLengths.uasset │ ├── E_TrackMeshType.uasset │ └── RoadData.uasset │ ├── Maps │ └── ShowCase.umap │ ├── Materials │ ├── M_Concrete_Panels.uasset │ ├── M_Metal_Burnished_Steel.uasset │ ├── Road.uasset │ └── Road_Inst.uasset │ ├── Props │ ├── L_GuardRail.uasset │ ├── R_GuardRail.uasset │ └── RoadMesh.uasset │ └── Textures │ ├── RoadTexture_BaseColor_Alpha.uasset │ ├── RoadTexture_Normal_Alpha.uasset │ ├── T_Concrete_Panels_D.uasset │ ├── T_Concrete_Panels_N.uasset │ ├── T_MacroVariation.uasset │ ├── T_Metal_Aluminum_D.uasset │ ├── T_Metal_Gold_N.uasset │ └── T_Perlin_Noise_M.uasset ├── Docs └── BBSizeInKM.png ├── LICENSE ├── README.md ├── Resources ├── main.py ├── set_editor_property.py └── terrainmagic.py ├── Source ├── UnrealMapboxBridge │ ├── Private │ │ ├── EditorLandscapeLibrary.cpp │ │ ├── GeoJsonStruct.cpp │ │ ├── GeoJsonStructGeneratorComponent.cpp │ │ └── UnrealMapboxBridge.cpp │ ├── Public │ │ ├── EditorLandscapeLibrary.h │ │ ├── GeoJsonStruct.h │ │ ├── GeoJsonStructGeneratorComponent.h │ │ └── UnrealMapboxBridge.h │ └── UnrealMapboxBridge.Build.cs └── nlohmann │ ├── adl_serializer.hpp │ ├── byte_container_with_subtype.hpp │ ├── detail │ ├── conversions │ │ ├── from_json.hpp │ │ ├── to_chars.hpp │ │ └── to_json.hpp │ ├── exceptions.hpp │ ├── hash.hpp │ ├── input │ │ ├── binary_reader.hpp │ │ ├── input_adapters.hpp │ │ ├── json_sax.hpp │ │ ├── lexer.hpp │ │ ├── parser.hpp │ │ └── position_t.hpp │ ├── iterators │ │ ├── internal_iterator.hpp │ │ ├── iter_impl.hpp │ │ ├── iteration_proxy.hpp │ │ ├── iterator_traits.hpp │ │ ├── json_reverse_iterator.hpp │ │ └── primitive_iterator.hpp │ ├── json_pointer.hpp │ ├── json_ref.hpp │ ├── macro_scope.hpp │ ├── macro_unscope.hpp │ ├── meta │ │ ├── call_std │ │ │ ├── begin.hpp │ │ │ └── end.hpp │ │ ├── cpp_future.hpp │ │ ├── detected.hpp │ │ ├── identity_tag.hpp │ │ ├── is_sax.hpp │ │ ├── type_traits.hpp │ │ └── void_t.hpp │ ├── output │ │ ├── binary_writer.hpp │ │ ├── output_adapters.hpp │ │ └── serializer.hpp │ ├── string_escape.hpp │ └── value_t.hpp │ ├── json.hpp │ ├── json_fwd.hpp │ ├── ordered_map.hpp │ └── thirdparty │ └── hedley │ ├── hedley.hpp │ └── hedley_undef.hpp └── UnrealMapboxBridge.uplugin /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | # UE file types 4 | *.uasset filter=lfs diff=lfs merge=lfs -text 5 | *.umap filter=lfs diff=lfs merge=lfs -text 6 | *.udk filter=lfs diff=lfs merge=lfs -text 7 | *.upk filter=lfs diff=lfs merge=lfs -text 8 | # Anything in `/RawContent` dir. [You create this directory in your projects root folder] 9 | /RawContent/**/* filter=lfs diff=lfs merge=lfs -text 10 | 11 | ## 3D models 12 | *.3dm filter=lfs diff=lfs merge=lfs -text 13 | *.3ds filter=lfs diff=lfs merge=lfs -text 14 | *.blend filter=lfs diff=lfs merge=lfs -text 15 | *.bin.fbx filter=lfs diff=lfs merge=lfs -text 16 | *.c4d filter=lfs diff=lfs merge=lfs -text 17 | *.collada filter=lfs diff=lfs merge=lfs -text 18 | *.cubemap filter=lfs diff=lfs merge=lfs -text 19 | *.dae filter=lfs diff=lfs merge=lfs -text 20 | *.duf filter=lfs diff=lfs merge=lfs -text 21 | *.dxf filter=lfs diff=lfs merge=lfs -text 22 | *.fbx filter=lfs diff=lfs merge=lfs -text 23 | 24 | *.jas filter=lfs diff=lfs merge=lfs -text 25 | *.lws filter=lfs diff=lfs merge=lfs -text 26 | *.lxo filter=lfs diff=lfs merge=lfs -text 27 | *.ma filter=lfs diff=lfs merge=lfs -text 28 | *.max filter=lfs diff=lfs merge=lfs -text 29 | *.mb filter=lfs diff=lfs merge=lfs -text 30 | *.obj filter=lfs diff=lfs merge=lfs -text 31 | *.ply filter=lfs diff=lfs merge=lfs -text 32 | *.skp filter=lfs diff=lfs merge=lfs -text 33 | *.stl filter=lfs diff=lfs merge=lfs -text 34 | *.xcf filter=lfs diff=lfs merge=lfs -text 35 | *.ztl filter=lfs diff=lfs merge=lfs -text 36 | 37 | ## Audio 38 | *.aif filter=lfs diff=lfs merge=lfs -text 39 | *.aiff filter=lfs diff=lfs merge=lfs -text 40 | *.it filter=lfs diff=lfs merge=lfs -text 41 | *.mod filter=lfs diff=lfs merge=lfs -text 42 | *.mp3 filter=lfs diff=lfs merge=lfs -text 43 | *.ogg filter=lfs diff=lfs merge=lfs -text 44 | *.s3m filter=lfs diff=lfs merge=lfs -text 45 | *.wav filter=lfs diff=lfs merge=lfs -text 46 | *.xm filter=lfs diff=lfs merge=lfs -text 47 | 48 | # Video 49 | *.asf filter=lfs diff=lfs merge=lfs -text 50 | *.avi filter=lfs diff=lfs merge=lfs -text 51 | *.flv filter=lfs diff=lfs merge=lfs -text 52 | *.mov filter=lfs diff=lfs merge=lfs -text 53 | *.mp4 filter=lfs diff=lfs merge=lfs -text 54 | *.mpeg filter=lfs diff=lfs merge=lfs -text 55 | *.mpg filter=lfs diff=lfs merge=lfs -text 56 | *.ogv filter=lfs diff=lfs merge=lfs -text 57 | *.wmv filter=lfs diff=lfs merge=lfs -text 58 | 59 | ## Images 60 | *.bmp filter=lfs diff=lfs merge=lfs -text 61 | *.exr filter=lfs diff=lfs merge=lfs -text 62 | *.gif filter=lfs diff=lfs merge=lfs -text 63 | *.hdr filter=lfs diff=lfs merge=lfs -text 64 | *.iff filter=lfs diff=lfs merge=lfs -text 65 | *.jpeg filter=lfs diff=lfs merge=lfs -text 66 | *.jpg filter=lfs diff=lfs merge=lfs -text 67 | *.pict filter=lfs diff=lfs merge=lfs -text 68 | *.png filter=lfs diff=lfs merge=lfs -text 69 | *.psd filter=lfs diff=lfs merge=lfs -text 70 | *.tga filter=lfs diff=lfs merge=lfs -text 71 | *.tif filter=lfs diff=lfs merge=lfs -text 72 | *.tiff filter=lfs diff=lfs merge=lfs -text 73 | 74 | # Compressed Archive 75 | *.7z filter=lfs diff=lfs merge=lfs -text 76 | *.bz2 filter=lfs diff=lfs merge=lfs -text 77 | *.gz filter=lfs diff=lfs merge=lfs -text 78 | *.rar filter=lfs diff=lfs merge=lfs -text 79 | *.tar filter=lfs diff=lfs merge=lfs -text 80 | *.zip filter=lfs diff=lfs merge=lfs -text 81 | 82 | # Compiled Dynamic Library 83 | *.dll filter=lfs diff=lfs merge=lfs -text 84 | *.pdb filter=lfs diff=lfs merge=lfs -text 85 | *.so filter=lfs diff=lfs merge=lfs -text 86 | 87 | ## Fonts 88 | *.otf filter=lfs diff=lfs merge=lfs -text 89 | *.ttf filter=lfs diff=lfs merge=lfs -text 90 | 91 | # Executable/Installer 92 | *.apk filter=lfs diff=lfs merge=lfs -text 93 | *.exe filter=lfs diff=lfs merge=lfs -text 94 | *.asar 95 | 96 | # Documents 97 | *.pdf filter=lfs diff=lfs merge=lfs -text -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio 2015 user specific files 2 | .vs/ 3 | .idea 4 | 5 | # Compiled Object files 6 | *.slo 7 | *.lo 8 | *.o 9 | *.obj 10 | 11 | # Precompiled Headers 12 | *.gch 13 | *.pch 14 | 15 | # Compiled Dynamic libraries 16 | *.so 17 | *.dylib 18 | # *.dll 19 | 20 | # Fortran module files 21 | *.mod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | # *.exe 31 | # *.out 32 | # *.app 33 | # *.ipa 34 | 35 | # These project files can be generated by the engine 36 | *.xcodeproj 37 | *.xcworkspace 38 | *.sln 39 | *.suo 40 | *.opensdf 41 | *.sdf 42 | *.VC.db 43 | *.VC.opendb 44 | 45 | # Precompiled Assets 46 | SourceArt/**/*.png 47 | SourceArt/**/*.tga 48 | 49 | # Binary Files 50 | Plugins/Developer/* 51 | 52 | # Builds 53 | Build/* 54 | 55 | # Whitelist PakBlacklist-.txt files 56 | !Build/*/ 57 | Build/*/** 58 | !Build/*/PakBlacklist*.txt 59 | 60 | # Don't ignore icon files in Build 61 | !Build/**/*.ico 62 | 63 | # Built data for maps 64 | *_BuiltData.uasset 65 | 66 | # Configuration files generated by the Editor 67 | Saved/* 68 | 69 | # Compiled source files for the engine to use 70 | Intermediate/* 71 | Plugins/*/Intermediate/* 72 | # Plugins/* 73 | 74 | # Cache files for the editor to use 75 | DerivedDataCache/* 76 | 77 | # Content/Geometry/* 78 | # Content/Mannequin/* 79 | # Content/ThirdPerson/* 80 | # Content/ThirdPersonBP/* 81 | # Content/Megascans/* 82 | # Content/MSPresets/* 83 | # Content/KiteDemo/* 84 | # Content/StarterContent/* 85 | 86 | # Exclude MarketPlace Content For Integration Testing 87 | /Binaries/ 88 | -------------------------------------------------------------------------------- /Content/Blueprints/ImportMap/Mapbox_BP.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f6564d0fd4ee099775d358dfae540c51be8f70d56059fe90b53875a45b9413c4 3 | size 850854 4 | -------------------------------------------------------------------------------- /Content/Blueprints/ImportMap/old/ImportLines.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5c2769663880b228042b397148b812db8e558a6b4d15f52995d25552fe6697b8 3 | size 157530 4 | -------------------------------------------------------------------------------- /Content/Blueprints/ImportMap/old/TestMapImport.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fee0a3e62183d9536833356bfb3e069d99598021fcd1b13bfe4bc0883196336e 3 | size 44430 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Blueprints/BP_Road_Generator.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4932f5c7f2912c6fd86176acbd9db105f17be2d9146f9834e6c97d83eb487e69 3 | size 845941 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Blueprints/BP_TrackGenerator.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6d0dd0cba7e0b48cf9348dbf42af3557004161c9c699c04956ae2d5ffd39aa07 3 | size 416747 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Blueprints/BP_TrackGenerator_2.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6fae7c33d2f8fcaef442319babfed2bc7b02ab0b1b599b8059f3dc1a8c2a10e1 3 | size 2826 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Data/E_GaurdRailLengths.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9a713baf89f2c2881cb03c75ebeaac35f422e5857f8b1a035a5247f98e09f6ee 3 | size 2769 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Data/E_TrackMeshType.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e125d885aa85ea82fc995c1c21d6234adecc7b2f5b7b32cb8930b2f2552d9eb0 3 | size 2345 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Data/RoadData.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8b42df9c74651f98fa6565a071c064245e1dbb488c05377ed99738ea8174ca6d 3 | size 17302 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Maps/ShowCase.umap: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b8a1b408a14189b144a6d2f1a7ca9844cdee8294eb9b782d3a726dd51bb88f55 3 | size 54939 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Materials/M_Concrete_Panels.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:406a0436bfefd3812a3e360780547df1bf3c4c9503f4541d87b1bbb791d73733 3 | size 121703 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Materials/M_Metal_Burnished_Steel.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:437ace9015854667dd9e8978d6306741ee2785316e576dfa75bf9ecf6311a7bd 3 | size 117569 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Materials/Road.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9a0aec89d46075d7a21621c7eddd37edce96250c7e9f3587d264d070a9f844c1 3 | size 154312 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Materials/Road_Inst.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:59c68f08590c8a9927ebdcdff127d9c0e017d56a446e69f10fd62d05bf2c2a51 3 | size 153239 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Props/L_GuardRail.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fa1715b7a9abd80547d5aa2817b151852641403e5754e1712b9131e1042b2ee6 3 | size 42353 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Props/R_GuardRail.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:147f759cff92e372222f4bb7f67f761076747ca0f624168c02fd5e23a0cc1534 3 | size 43579 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Props/RoadMesh.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:626974c3d3d6c37229a30d15588444b9a3c8efb445c5cbb2b6ded7ae9fd1cf80 3 | size 35991 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Textures/RoadTexture_BaseColor_Alpha.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:519ef372db65832cc3b2a9db4c7c26126dec2c645752ca6c6e29bda331f5b673 3 | size 11422270 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Textures/RoadTexture_Normal_Alpha.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:970971073e5f741726d76290fd73bf4538d05df630ddd5747a9a7da826352e40 3 | size 10627338 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Textures/T_Concrete_Panels_D.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e84a0b0c41355e19c4a605cb75cca4d84276d101baf178000cd165a38acd7f12 3 | size 8511220 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Textures/T_Concrete_Panels_N.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0806511b90a6276d0fdc76b19316b631a869f03d6fc02ac5950cf6bd984237b7 3 | size 6557318 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Textures/T_MacroVariation.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:71227ecea9ed0d53e8cd930ff8f542eb928505892726761402e055eacf51e4d9 3 | size 10880771 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Textures/T_Metal_Aluminum_D.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:27e6496a67826cbcaebf932ec6989545119e890466d38fea69f828639537a66e 3 | size 9735495 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Textures/T_Metal_Gold_N.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1b2455ad9ed5638e94fbde31022bd6ddf302623e81da802bcf18e357005d30a3 3 | size 2813718 4 | -------------------------------------------------------------------------------- /Content/Blueprints/TrackGenerator/Textures/T_Perlin_Noise_M.uasset: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:11c4feeffd0682549cd87c7f457a1ca6b685cf9b726c4b9964f660cca2d15759 3 | size 7918220 4 | -------------------------------------------------------------------------------- /Docs/BBSizeInKM.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:28cf0a4a761d972b4d81c8847d6106c7ff7b3e71c21dd12dabae0d42e63881f6 3 | size 1543559 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Daniel Elebash 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unreal Map Bridge Plugin 2 | 3 | This project allows you to create an Unreal landscape from a real world location on a map. 4 | This project is not affiliated with Mapbox or Maptiler it is just something I wanted to do. Cheers! 5 | 6 | 7 | 8 | ![image](https://user-images.githubusercontent.com/2220160/177798094-7e1b613d-7f27-402d-b966-5a07288cf6b8.png) 9 | 10 | 11 | ## Tutorial Playlist 12 | 13 | https://www.youtube.com/playlist?list=PLFCVXzupw1r_7ExUSGDxHGHU-gPRxOGeZ 14 | 15 | ## Web App Live New Map App 08/22/2023 16 | 17 | https://map.justgeektechs.com/ 18 | 19 | ## Support: 20 | https://discord.gg/2WkHWNDf8q 21 | 22 | ## My other projects: 23 | 24 | Unreal Map Bridge - Import real world locations into UE as Landscapes 25 | https://github.com/delebash/UnrealMapboxBridgePlugin 26 | 27 | Unreal Vault Organizer - Organize your Unreal Vault with Tags and get update notifications 28 | https://github.com/delebash/unreal_vault_organizer 29 | 30 | Texture From Mesh Creator - Creates a texture from a screen shot of a Mesh. Main puporse for this was so I could easily capture the show print of my characters so I could stamp that texture into the landscape for footprint effects. 31 | https://github.com/delebash/TextureFromMeshCreator 32 | 33 | Global Environmental System (GES) -- This system integrates Ultra Dynamic Sky Weather (potentially any Weather System) with Megascan Foliage, Trees, Props, UE Water, Ambient Wind System, and various other Systems. 34 | https://github.com/delebash/UE_GlobalEnvironmentalSystem 35 | 36 | 37 | ## [Intro and Install Video](https://www.youtube.com/watch?v=wwEDuVmCayU) 38 | 39 | 40 | 41 | 10/19/2022 New Featuere 42 | 43 | Size in KM of selected tile at selected zoom level 44 | 45 | ![](Docs/BBSizeInKM.png) 46 | 47 | 10/14/2022 New Features -- Alpha (WIP) 48 | 49 | Track Generator 50 | 51 | Georeference Lng/Lat points on landscape 52 | 53 | Import Geojson features. 54 | 55 | 56 | 57 | 10/08/2022 Updated for 5.1 Preview 58 | 59 | Updated for UE 5.0 Release 60 | 61 | ### New Feature: 09/09/2022 62 | 63 | Added ability to create landmass brush stamps from selected location. 64 | This feature requires a paid plugin from the market place. 65 | https://www.unrealengine.com/marketplace/en-US/product/landscape-stamping-tool-100-custom-brushes?sessionInvalidated=true 66 | 67 | This new feature automates the creation of the landscape brush for the above plugin. 68 | 69 | Video demo 70 | 71 | 72 | **To Install and Setup:** 73 | 74 | 1) Download this repo or the release file 75 | 2) Unzip 76 | 3) Rename the plugin the one with all the files, by removing the -master so the folder is just called UnrealMapboxBridgePlugin 77 | 4) Copy that folder to your Plugins directory in your Unreal Project. If you do not have a Plugins directory just create one. 78 | 5) Open your project. It should ask you to build the plugin, click ok. 79 | 6) In your content viewer you will need to show Plugin Content 80 | 7) Go to the UnrealMapboxBridge Content/Blueprints folder and drag the Mapbox_BP blueprint onto your empty scene. Set up lights per normal. 81 | 82 | 8) On the Mapbox_BP properties screen click the Select Map button to open up a Web Application. This is the application that allows you to choose a real world location. The first time you open the app you will need to enter a Mapbox Api on the settings page and choose a download directory for the map files. A free Mapbox account works great! 83 | 84 | 9) Once you have selected your download folder you need to manually copy the folder path and set that to the Height Map Directory on the Mapbox_BP settings. Ie. copy path 85 | E:\\MyDowloadDirectory and paste that into the Height Map Directory field in Unreal. You only need to do this once unless you delete the Blueprint from your scene or change download directory. 86 | 87 | 10) You can navigate around the map by holding your left mouse button and dragging around. Zoom in and out via mouse wheel. 88 | 89 | 10) Once you find a location you want left click on it. A blue square will be shown to indicate you have made a selection. 90 | 91 | 11) Click the Download button and wait for the loading screen to complete the download. 92 | 93 | 12) Click on the Send to Unreal Button and wait for the loading screen to complete. 94 | 95 | At this point if you switch back to your Unreal project you will see your newly imported landscape. You can import multiple different landscapes in one project. The location of the imported landscapes will be on top of each other so you will need to move them to see each landscape. 96 | 97 | The map application is simply a web application bundled to an exe for use in Unreal. For source see https://github.com/delebash/unreal_mapbox_bridge 98 | 99 | Adjust the Z-scale of the landscape in the landscape properties as needed to look correctly, Usually you will need to adjust it down in number. The Map Application has a Z-scale displayed but this is not always accurate. 100 | 101 | The Create Features Button is a work in progress on importing landscape features. Currently not working correctly. 102 | 103 | 104 | Features Implemented: 105 | 106 | 1) Select real world location from Map and import it as a landscape into Unreal 107 | 2) WIP -- Import landscape features such as rivers, roads, lakes. 108 | 109 | For project status please check the Roadmap 110 | 111 | 112 | Credits to: 113 | 114 | Zak Parrish for Track Generator https://www.youtube.com/watch?v=wR0fH6O9jD8 115 | 116 | [L1z4rD89](https://forums.unrealengine.com/u/L1z4rD89) for Georeference and Track Generator integration 117 | -------------------------------------------------------------------------------- /Resources/main.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | import sys 3 | 4 | alpha_brush_path = sys.argv[1] 5 | alpha_brush_name = sys.argv[2] 6 | heightmap_directory = sys.argv[3] 7 | alpha_brush_template_path = sys.argv[4] 8 | alpha_textures = sys.argv[5] 9 | heightmap_property = sys.argv[6] 10 | stamp_tool = sys.argv[7] 11 | alpha_textures_path = alpha_brush_path + alpha_textures 12 | 13 | # Import known images as a list of Texture2D objects 14 | alpha_texture_png = heightmap_directory + "\\" + alpha_brush_name + ".png" 15 | 16 | data = unreal.AutomatedAssetImportData() 17 | data.set_editor_property('destination_path', alpha_textures_path) 18 | data.set_editor_property('filenames', [alpha_texture_png]) 19 | lst_texture2D = unreal.AssetToolsHelpers.get_asset_tools().import_assets_automated(data) 20 | 21 | if stamp_tool == 'Unreal Stamp Brush Plugin': 22 | # Duplicate stamp brush 23 | unreal.EditorAssetLibrary.duplicate_asset(alpha_brush_template_path, alpha_brush_path + alpha_brush_name) 24 | 25 | # Load texture 26 | blueprint_generated = unreal.EditorAssetLibrary.load_blueprint_class(alpha_brush_path + alpha_brush_name) 27 | texture = unreal.EditorAssetLibrary.load_asset(alpha_textures_path + alpha_brush_name) 28 | 29 | # from that, get the class default object ( the actual template for the blueprint ) 30 | blueprint_class_default = unreal.get_default_object(blueprint_generated) 31 | 32 | # set or get properties 33 | blueprint_class_default.set_editor_property(heightmap_property, texture) 34 | unreal.EditorAssetLibrary.save_asset(alpha_brush_path + alpha_brush_name) 35 | -------------------------------------------------------------------------------- /Resources/set_editor_property.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | import sys 3 | 4 | asset_path = sys.argv[1] 5 | asset_property = sys.argv[2] 6 | asset_value = sys.argv[3] 7 | is_texture = sys.argv[4] 8 | in_scene = sys.argv[5] 9 | asset_class = sys.argv[6] 10 | method = sys.argv[7] 11 | 12 | world = unreal.EditorLevelLibrary.get_editor_world 13 | 14 | if is_texture == "1": 15 | # Load texture 16 | value = unreal.EditorAssetLibrary.load_asset(asset_value) 17 | else: 18 | value = asset_value 19 | 20 | if in_scene == "0": 21 | # print(in_scene) 22 | # Asset to be loaded from Editor Content 23 | # from that, get the class default object ( the actual template for the blueprint ) 24 | blueprint_generated = unreal.EditorAssetLibrary.load_blueprint_class(asset_path) 25 | my_act = unreal.get_default_object(blueprint_generated) 26 | 27 | 28 | if in_scene == "1": 29 | lst_actors = unreal.EditorLevelLibrary.get_all_level_actors() 30 | for act in lst_actors: 31 | act_label = act.get_actor_label() 32 | if asset_class in act_label: 33 | my_act = act 34 | 35 | 36 | if asset_property != "/": 37 | my_act.set_editor_property(asset_property,value) 38 | 39 | if method == "import_tile": 40 | my_act.import_tile(my_act) 41 | 42 | if method == "match_landscape_size": 43 | my_act.match_landscape_size(my_act) 44 | 45 | 46 | 47 | # print('tets') 48 | # if(len(method) == 0): 49 | # print(method) 50 | 51 | 52 | 53 | # Asset to be loaded from Scene 54 | # print(asset_path) 55 | # asset = unreal.find_object(None, asset_path) 56 | # print (type(asset)) 57 | # blueprint_class_default = unreal.get_default_object(asset) 58 | # print (type(blueprint_class_default)) 59 | # print(dir(blueprint_class_default)) 60 | # blueprint_class_default.set_editor_property('height_map',value) 61 | 62 | # m = unreal.find_object("EarthLandscapeClip") 63 | # m = unreal.load_object(Blueprint, asset_path) 64 | # act = unreal.load_class(Class, ' + asset_class + ') 65 | # print(act) 66 | 67 | 68 | 69 | 70 | # # set or get properties 71 | # blueprint_class_default.set_editor_property(asset_property, value) 72 | # unreal.EditorAssetLibrary.save_asset(asset_path) 73 | -------------------------------------------------------------------------------- /Resources/terrainmagic.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | import sys 3 | 4 | heightmap_directory = sys.argv[1] 5 | heightmap_file_name = sys.argv[2] 6 | heightmap_textures_path = sys.argv[3] 7 | 8 | # # Import known images as a list of Texture2D objects 9 | heightmap_texture_png = heightmap_directory + "\\" + heightmap_file_name 10 | data = unreal.AutomatedAssetImportData() 11 | data.set_editor_property('destination_path', heightmap_textures_path) 12 | data.set_editor_property('filenames', [heightmap_texture_png]) 13 | lst_texture2D = unreal.AssetToolsHelpers.get_asset_tools().import_assets_automated(data) 14 | -------------------------------------------------------------------------------- /Source/UnrealMapboxBridge/Private/EditorLandscapeLibrary.cpp: -------------------------------------------------------------------------------- 1 | #include "EditorLandscapeLibrary.h" 2 | #include "LandscapeFileFormatInterface.h" 3 | #include "LandscapeEditorModule.h" 4 | #include 5 | #include "Misc/Paths.h" 6 | #include "Editor.h" 7 | #include "Editor/EditorEngine.h" 8 | #include "LandscapeSubsystem.h" 9 | #include "Editor/LandscapeEditor/Private/LandscapeEdMode.h" 10 | 11 | 12 | void UEditorLandscapeLibrary::ImportHeightmap(FString FilePath, FString LandscapeName, 13 | FString FileName, const int Width, 14 | const int Height, const int WorldPartitionGridSize) 15 | { 16 | FilePath += + "\\" + FileName; 17 | 18 | int NewLandscape_QuadsPerSection; 19 | int NewLandscape_SectionsPerComponent; 20 | FIntPoint NewLandscape_ComponentCount; 21 | 22 | 23 | FLandscapeImportHelper::ChooseBestComponentSizeForImport(Width, Height, NewLandscape_QuadsPerSection, NewLandscape_SectionsPerComponent, NewLandscape_ComponentCount); 24 | 25 | const int32 ComponentCountX = NewLandscape_ComponentCount.X; 26 | const int32 ComponentCountY = NewLandscape_ComponentCount.Y; 27 | const int32 QuadsPerComponent = NewLandscape_SectionsPerComponent * NewLandscape_QuadsPerSection; 28 | const int32 SizeX = ComponentCountX * QuadsPerComponent + 1; 29 | const int32 SizeY = ComponentCountY * QuadsPerComponent + 1; 30 | 31 | 32 | ALandscape* Landscape = GEditor->GetEditorWorldContext().World()->SpawnActor(); 33 | Landscape->bCanHaveLayersContent = true; 34 | 35 | const auto ActualPath = FilePath.IsEmpty() ? Landscape->ReimportHeightmapFilePath : FilePath; 36 | if (ActualPath.IsEmpty()) 37 | return; 38 | 39 | //Read png file to height array 40 | TArray RawData; 41 | ReadHeightmapFile(RawData, *ActualPath, Width, Height); 42 | 43 | // Setup heightmap for landscape 44 | TMap> HeightmapDataPerLayers; 45 | TMap> MaterialLayerDataPerLayer; 46 | 47 | // Generate LandscapeActor from heightmap 48 | HeightmapDataPerLayers.Add(FGuid(), RawData); 49 | MaterialLayerDataPerLayer.Add(FGuid(), TArray()); 50 | 51 | Landscape->Import(FGuid::NewGuid(), 0, 0, SizeX - 1, SizeY - 1, 52 | NewLandscape_SectionsPerComponent, NewLandscape_QuadsPerSection, HeightmapDataPerLayers, 53 | *ActualPath, MaterialLayerDataPerLayer, ELandscapeImportAlphamapType::Layered); 54 | 55 | ULandscapeInfo* LandscapeInfo = Landscape->GetLandscapeInfo(); 56 | 57 | Landscape->SetActorLocation(FVector(0, 0, 100)); 58 | Landscape->SetActorScale3D(FVector(100, 100, 100)); 59 | Landscape->SetActorLabel(LandscapeName); 60 | LandscapeInfo->UpdateLayerInfoMap(Landscape); 61 | UE_LOG(LogStreaming, Warning, TEXT("%d"), WorldPartitionGridSize); 62 | if (WorldPartitionGridSize > 0) 63 | { 64 | //Setup World partition streaming proxies 65 | GEditor->GetEditorWorldContext().World()->GetSubsystem()->ChangeGridSize(LandscapeInfo, WorldPartitionGridSize); 66 | } 67 | 68 | } 69 | 70 | 71 | bool UEditorLandscapeLibrary::ReadHeightmapFile(TArray& Result, const FString& Filename, int32 ExpectedWidth, 72 | int32 ExpectedHeight) 73 | { 74 | bool bResult = true; 75 | 76 | const ILandscapeEditorModule& LandscapeEditorModule = FModuleManager::GetModuleChecked( 77 | "LandscapeEditor"); 78 | const ILandscapeHeightmapFileFormat* HeightmapFormat = LandscapeEditorModule.GetHeightmapFormatByExtension( 79 | *FPaths::GetExtension(Filename, true)); 80 | 81 | FLandscapeHeightmapImportData ImportData = HeightmapFormat->Import(*Filename, { 82 | (uint32)ExpectedWidth, (uint32)ExpectedHeight 83 | }); 84 | if (ImportData.ResultCode != ELandscapeImportResult::Error) 85 | { 86 | Result = MoveTemp(ImportData.Data); 87 | } 88 | else 89 | { 90 | UE_LOG(LogStreaming, Warning, TEXT("%s"), *ImportData.ErrorMessage.ToString()); 91 | Result.Empty(); 92 | bResult = false; 93 | } 94 | 95 | return bResult; 96 | } 97 | -------------------------------------------------------------------------------- /Source/UnrealMapboxBridge/Private/GeoJsonStruct.cpp: -------------------------------------------------------------------------------- 1 | #include "GeoJsonStruct.h" 2 | 3 | FGeoJsonStruct FGeoJsonStruct::BuildGeoJsonStruct( 4 | FString GeometryType, 5 | FString Type 6 | // TArray GeometryCoordinates 7 | ) 8 | { 9 | FGeoJsonStruct FGeoJsonStruct; 10 | FGeoJsonStruct.GeometryType = GeometryType; 11 | FGeoJsonStruct.Type = Type; 12 | // FGeoJsonStruct.GeometryCoordinates = GeometryCoordinates; 13 | return FGeoJsonStruct; 14 | } 15 | -------------------------------------------------------------------------------- /Source/UnrealMapboxBridge/Private/GeoJsonStructGeneratorComponent.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "GeoJsonStructGeneratorComponent.h" 5 | 6 | #include "JsonUtilities.h" 7 | 8 | #include "Developer/DesktopPlatform/Public/IDesktopPlatform.h" 9 | #include "Developer/DesktopPlatform/Public/DesktopPlatformModule.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | using json = nlohmann::json; 17 | 18 | // // Sets default values for this component's properties 19 | UGeoJsonStructGeneratorComponent::UGeoJsonStructGeneratorComponent() 20 | { 21 | } 22 | 23 | 24 | // void tokenize(string &str, char delim, vector &out) 25 | // { 26 | // size_t start; 27 | // size_t end = 0; 28 | // 29 | // while ((start = str.find_first_not_of(delim, end)) != string::npos) 30 | // { 31 | // end = str.find(delim, start); 32 | // out.push_back(str.substr(start, end - start)); 33 | // } 34 | // } 35 | 36 | void UGeoJsonStructGeneratorComponent::OpenMyFileDialog(const FString& DialogTitle, const FString& DefaultPath, 37 | const FString& FileTypes, TArray& OutFileNames) 38 | { 39 | if (GEngine) 40 | 41 | { 42 | //void* ParentWindowHandle = GEngine->GameViewport->GetWindow()->GetNativeWindow()->GetOSWindowHandle(); 43 | IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get(); 44 | if (DesktopPlatform) 45 | { 46 | //Opening the file picker! 47 | uint32 SelectionFlag = 0; 48 | //A value of 0 represents single file selection while a value of 1 represents multiple file selection 49 | DesktopPlatform->OpenFileDialog(NULL, DialogTitle, DefaultPath, FString(""), FileTypes, SelectionFlag, 50 | OutFileNames); 51 | } 52 | } 53 | } 54 | 55 | 56 | FString UGeoJsonStructGeneratorComponent::ParseJsonToString(FString FilePath, FString FileName) 57 | { 58 | 59 | FilePath += + "\\" + FileName; 60 | FString JsonString; //Json converted to FString 61 | FFileHelper::LoadFileToString(JsonString, *FilePath); 62 | return JsonString; 63 | //std::string MyStdString(TCHAR_TO_UTF8(*JsonString)); 64 | } 65 | // 66 | // void UGeoJsonStructGeneratorComponent::ConvertLongLatToXY(FJsonValueArray arry) 67 | // { 68 | // auto test = arry; 69 | // 70 | // return test; 71 | // } 72 | 73 | 74 | // void from_json(const nlohmann::json& object, Inner& i) 75 | // { 76 | // // j.at("Name").get_to(i.Name); 77 | // // j.at("Value").get_to(i.Value); 78 | // 79 | // if (object.contains("type")) 80 | // { 81 | // object.at("type").get_to(i.Value); 82 | // } 83 | // object.at("geometry")["type"].get_to(i.Value); 84 | // } 85 | 86 | 87 | void UGeoJsonStructGeneratorComponent::ParseJson(const FString& File, TArray& GeoJsonStructs) 88 | { 89 | // json j; 90 | // ifstream ifs(*File); 91 | // if (!ifs.is_open()) 92 | // { 93 | // //return false;; 94 | // } 95 | // ifs >> j; 96 | // ifs.close(); 97 | 98 | 99 | // // iterate the array 100 | // for (json::iterator it = j.begin(); it != j.end(); ++it) { 101 | // std::cout << *it << '\n'; 102 | // } 103 | // 104 | // // range-based for 105 | // for (auto& element : j) { 106 | // std::cout << element << '\n'; 107 | // } 108 | 109 | 110 | // for (auto& elm : j.items()) 111 | // { 112 | // nlohmann::json object = elm.value(); 113 | // 114 | // string type; 115 | // int32 id; 116 | // string sourceLayer; 117 | // string source; 118 | // 119 | // string Geotype = object.at("geometry")["type"]; 120 | // 121 | // nlohmann::json GeoArrycoordinates = object.at("geometry")["coordinates"]; 122 | // 123 | // if (object.contains("type")) 124 | // { 125 | // type = object.at("type"); 126 | // } 127 | // nlohmann::json Objproperties = object.at("properties"); 128 | // 129 | // if (object.contains("id")) 130 | // { 131 | // id = object.at("id"); 132 | // } 133 | // 134 | // nlohmann::json Objlayer = object.at("layer"); 135 | // 136 | // if (object.contains("sourceLayer")) 137 | // { 138 | // sourceLayer = object.at("sourceLayer"); 139 | // } 140 | // 141 | // if (object.contains("source")) 142 | // { 143 | // source = object.at("source"); 144 | // } 145 | // 146 | // nlohmann::json Objstate = object.at("state"); 147 | // 148 | // 149 | // if (Geotype == "LineString") 150 | // { 151 | // // JsonCoordinatesArray = Coordinates[1]->AsArray(); 152 | // } 153 | // 154 | // 155 | // 156 | // 157 | // 158 | // 159 | // 160 | // 161 | // // FString Geotype(SGeotype. c_str()); 162 | // // FString type(Stype.c_str()); 163 | // // 164 | // // FGeoJsonStruct GeoJsonStruct = FGeoJsonStruct::BuildGeoJsonStruct( 165 | // // Geotype, type 166 | // // ); 167 | // // 168 | // // GeoJsonStructs.Push(GeoJsonStruct); 169 | // // from_json(); 170 | // // FString Geotype(SGeotype.c_str()); 171 | // // FString type(Stype.c_str()); 172 | // // 173 | // // 174 | // // FGeoJsonStruct GeoJsonStruct = FGeoJsonStruct::BuildGeoJsonStruct( 175 | // // Geotype, type 176 | // // ); 177 | // // 178 | // // GeoJsonStructs.Push(GeoJsonStruct); 179 | // //std::cout << id << std::endl; 180 | // // GLog->Log("multiline done"); 181 | // } 182 | } 183 | 184 | 185 | // 186 | // void UGeoJsonStructGeneratorComponent::GenerateStructsFromJson(const FString& File, 187 | // TArray& GeoJsonStructs) 188 | // { 189 | // FString JsonString; //Json converted to FString 190 | // FFileHelper::LoadFileToString(JsonString, *File);; 191 | // 192 | // // char* path = TCHAR_TO_ANSI(*File); 193 | // // 194 | // // string s=path; 195 | // // char d='-'; 196 | // // vector a; 197 | // // tokenize(s,d,a); 198 | // // string & zoom = a.at(1); 199 | // // string & resolution = a.at(4); 200 | // // GLog->Log(zoom.c_str()); 201 | // // GLog->Log(resolution.c_str()); 202 | // 203 | // 204 | // TSharedRef> JsonReader = TJsonReaderFactory<>::Create(*JsonString); 205 | // TArray> RawJsonValueArray; 206 | // bool success = FJsonSerializer::Deserialize(JsonReader, RawJsonValueArray); 207 | // 208 | // 209 | // if (success) 210 | // { 211 | // for (int32 Index = 0; Index < RawJsonValueArray.Num(); Index++) 212 | // { 213 | // TSharedPtr* JsonObject = new TSharedPtr(RawJsonValueArray[Index]->AsObject()); 214 | // FJsonObject* GeoJsonObject = JsonObject->Get(); 215 | // FString GeometryType; 216 | // FString Type; 217 | // TArray> JsonCoordinatesArray; 218 | // // FVector GeometryLongLat; 219 | // 220 | // // TSharedPtr GeoJsonValue = RawJsonValueArray[Index]; 221 | // // TSharedPtr GeoJsonObject = GeoJsonValue->AsObject(); 222 | // 223 | // if (GeoJsonObject->HasField("geometry")) 224 | // { 225 | // TSharedPtr geometry = GeoJsonObject->GetObjectField("geometry"); 226 | // 227 | // if (GeoJsonObject->HasField("type")) 228 | // { 229 | // Type = GeoJsonObject->GetStringField("type"); 230 | // } 231 | // if (geometry->HasField("type")) 232 | // { 233 | // GeometryType = geometry->GetStringField("type"); 234 | // } 235 | // 236 | // 237 | // TArray> Coordinates = geometry->GetArrayField("coordinates"); 238 | // if (GeometryType == "MultiLineString") 239 | // { 240 | // JsonCoordinatesArray = Coordinates[0]->AsArray(); 241 | // } 242 | // if (GeometryType == "LineString") 243 | // { 244 | // JsonCoordinatesArray = Coordinates; 245 | // } 246 | // 247 | // if (GeometryType == "LineString") 248 | // { 249 | // JsonCoordinatesArray = Coordinates[1]->AsArray(); 250 | // } 251 | // double Long; 252 | // double Lat; 253 | // TArray GeometryCoordinates; 254 | // 255 | // for (int32 i = 0; i < JsonCoordinatesArray.Num(); i++) 256 | // { 257 | // TArray> JsonLongLat = JsonCoordinatesArray[i]->AsArray(); 258 | // Long = JsonLongLat[0]->AsNumber(); 259 | // Lat = JsonLongLat[1]->AsNumber(); 260 | // 261 | // FVector LonLatCoordinates; 262 | // 263 | // LonLatCoordinates.X = Long; 264 | // LonLatCoordinates.Y = Lat; 265 | // 266 | // GeometryCoordinates.Push(LonLatCoordinates); 267 | // 268 | // FGeoJsonStruct GeoJsonStruct = FGeoJsonStruct::BuildGeoJsonStruct( 269 | // GeometryType, Type, GeometryCoordinates 270 | // ); 271 | // 272 | // GeoJsonStructs.Push(GeoJsonStruct); 273 | // 274 | // 275 | // // 276 | // // if (GeoJsonObject->HasField("properties")) 277 | // // { 278 | // // TSharedPtr properties = GeoJsonObject->GetObjectField("properties");; 279 | // // } 280 | // // if (GeoJsonObject->HasField("layer")) 281 | // // { 282 | // // TSharedPtr layer = GeoJsonObject->GetObjectField("layer"); 283 | // // } 284 | // // if (GeoJsonObject->HasField("source")) 285 | // // { 286 | // // FString source = GeoJsonObject->GetStringField("source"); 287 | // // } 288 | // // if (GeoJsonObject->HasField("id")) 289 | // // { 290 | // // FString source = GeoJsonObject->GetStringField("id"); 291 | // // } 292 | // // if (GeoJsonObject->HasField("state")) 293 | // // { 294 | // // TSharedPtr state = GeoJsonObject->GetObjectField("state"); 295 | // // } 296 | // } 297 | // } 298 | // } 299 | // } 300 | // } 301 | -------------------------------------------------------------------------------- /Source/UnrealMapboxBridge/Private/UnrealMapboxBridge.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "UnrealMapboxBridge.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FUnrealMapboxBridgeModule" 6 | 7 | void FUnrealMapboxBridgeModule::StartupModule() 8 | { 9 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 10 | } 11 | 12 | void FUnrealMapboxBridgeModule::ShutdownModule() 13 | { 14 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 15 | // we call this function before unloading the module. 16 | } 17 | 18 | #undef LOCTEXT_NAMESPACE 19 | 20 | IMPLEMENT_MODULE(FUnrealMapboxBridgeModule, UnrealMapboxBridge) -------------------------------------------------------------------------------- /Source/UnrealMapboxBridge/Public/EditorLandscapeLibrary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreUObject.h" 4 | #include "Kismet/BlueprintFunctionLibrary.h" 5 | #include "EditorLandscapeLibrary.generated.h" 6 | 7 | 8 | class ALandscape; 9 | class ALandscapeProxy; 10 | 11 | UCLASS(Blueprintable) 12 | class UNREALMAPBOXBRIDGE_API UEditorLandscapeLibrary 13 | : public UBlueprintFunctionLibrary 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | 19 | UFUNCTION(BlueprintCallable, Category = "Dan Editor Scripting | Landscape") 20 | static void ImportHeightmap(FString FilePath, FString LandscapeName, 21 | FString FileName, const int Width, const int Height,const int WorldPartitionGridSize); 22 | 23 | private: 24 | static bool ReadHeightmapFile(TArray& Result, const FString& Filename, int32 ExpectedWidth, 25 | int32 ExpectedHeight); 26 | }; 27 | -------------------------------------------------------------------------------- /Source/UnrealMapboxBridge/Public/GeoJsonStruct.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GeoJsonStruct.generated.h" 4 | 5 | USTRUCT(BlueprintType) 6 | struct FGeoJsonStruct 7 | { 8 | GENERATED_USTRUCT_BODY() 9 | 10 | public: 11 | UPROPERTY(EditAnyWhere, BluePrintReadWrite, Category = "GeoJson") 12 | FString GeometryType; 13 | 14 | UPROPERTY(EditAnyWhere, BluePrintReadWrite, Category = "GeoJson") 15 | FString Type; 16 | 17 | // UPROPERTY(EditAnyWhere, BluePrintReadWrite, Category = "GeoJson") 18 | // TArray GeometryCoordinates; 19 | 20 | public: 21 | static FGeoJsonStruct BuildGeoJsonStruct( 22 | FString GeometryType, 23 | FString Type 24 | // TArray GeometryCoordinates 25 | ); 26 | }; 27 | 28 | // 29 | // UPROPERTY() 30 | // FJsonObject properties; 31 | // 32 | // UPROPERTY() 33 | // FJsonObject layer; 34 | // 35 | // UPROPERTY() 36 | // FString source; 37 | // 38 | // UPROPERTY() 39 | // FJsonObject state; 40 | -------------------------------------------------------------------------------- /Source/UnrealMapboxBridge/Public/GeoJsonStructGeneratorComponent.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "EditorUtilityWidget.h" 7 | #include "GeoJsonStruct.h" 8 | #include "GeoJsonStructGeneratorComponent.generated.h" 9 | 10 | 11 | UCLASS(Blueprintable) 12 | class UNREALMAPBOXBRIDGE_API UGeoJsonStructGeneratorComponent : public UEditorUtilityWidget 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | UGeoJsonStructGeneratorComponent(); 18 | 19 | UFUNCTION(BlueprintCallable, Category = "UnrealMapbox") 20 | void OpenMyFileDialog(const FString& DialogTitle, const FString& DefaultPath, const FString& FileTypes, 21 | TArray& OutFileNames); 22 | 23 | 24 | UFUNCTION(BlueprintCallable, Category = "UnrealMapbox") 25 | static FString ParseJsonToString(FString FilePath, FString FileName); 26 | // UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="UnrealMapbox") 27 | // FString health; 28 | // UFUNCTION(BlueprintCallable, Category = "UnrealMapbox") 29 | // void ConvertLongLatToXY(FJsonValueArray arry); 30 | 31 | 32 | void ParseJson(const FString& File, TArray& GeoJsonStructs); 33 | 34 | 35 | // void GenerateStructsFromJson(const FString& File, TArray &GeoJsonStructs); 36 | 37 | 38 | private: 39 | // FString JsonFullPath(FString Path); 40 | 41 | //FVector ParseAsVector(TSharedPtr json, FString KeyName); 42 | 43 | //FRotator ParseAsRotator(TSharedPtr json, FString KeyName); 44 | }; 45 | -------------------------------------------------------------------------------- /Source/UnrealMapboxBridge/Public/UnrealMapboxBridge.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Modules/ModuleManager.h" 7 | 8 | class FUnrealMapboxBridgeModule : public IModuleInterface 9 | { 10 | public: 11 | 12 | /** IModuleInterface implementation */ 13 | virtual void StartupModule() override; 14 | virtual void ShutdownModule() override; 15 | }; 16 | -------------------------------------------------------------------------------- /Source/UnrealMapboxBridge/UnrealMapboxBridge.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class UnrealMapboxBridge : ModuleRules 6 | { 7 | public UnrealMapboxBridge(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | // ... add public include paths required here ... 14 | } 15 | ); 16 | 17 | 18 | PrivateIncludePaths.AddRange( 19 | new string[] { 20 | // ... add other private include paths required here ... 21 | } 22 | ); 23 | 24 | 25 | PublicDependencyModuleNames.AddRange( 26 | new string[] 27 | { 28 | "Core", "Landscape", 29 | "LandscapeEditor", 30 | "EditorScriptingUtilities", 31 | "RemoteControl" 32 | // ... add other public dependencies that you statically link with here ... 33 | } 34 | ); 35 | 36 | 37 | PrivateDependencyModuleNames.AddRange( 38 | new string[] 39 | { 40 | "CoreUObject", 41 | "Engine", 42 | "Slate", 43 | "SlateCore", 44 | "Blutility", 45 | "UMG", 46 | "Json", 47 | "JsonUtilities", 48 | "Foliage", 49 | "LandscapeEditorUtilities", 50 | "CoreUObject", 51 | "Landscape", 52 | "Foliage", 53 | "UnrealEd", 54 | "RHI", 55 | "RenderCore", 56 | "Projects" 57 | // ... add private dependencies that you statically link with here ... 58 | } 59 | ); 60 | 61 | 62 | DynamicallyLoadedModuleNames.AddRange( 63 | new string[] 64 | { 65 | // ... add any modules that your module loads dynamically here ... 66 | } 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Source/nlohmann/adl_serializer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace nlohmann 12 | { 13 | 14 | /// @sa https://json.nlohmann.me/api/adl_serializer/ 15 | template 16 | struct adl_serializer 17 | { 18 | /// @brief convert a JSON value to any value type 19 | /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ 20 | template 21 | static auto from_json(BasicJsonType && j, TargetType& val) noexcept( 22 | noexcept(::nlohmann::from_json(std::forward(j), val))) 23 | -> decltype(::nlohmann::from_json(std::forward(j), val), void()) 24 | { 25 | ::nlohmann::from_json(std::forward(j), val); 26 | } 27 | 28 | /// @brief convert a JSON value to any value type 29 | /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ 30 | template 31 | static auto from_json(BasicJsonType && j) noexcept( 32 | noexcept(::nlohmann::from_json(std::forward(j), detail::identity_tag {}))) 33 | -> decltype(::nlohmann::from_json(std::forward(j), detail::identity_tag {})) 34 | { 35 | return ::nlohmann::from_json(std::forward(j), detail::identity_tag {}); 36 | } 37 | 38 | /// @brief convert any value type to a JSON value 39 | /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/ 40 | template 41 | static auto to_json(BasicJsonType& j, TargetType && val) noexcept( 42 | noexcept(::nlohmann::to_json(j, std::forward(val)))) 43 | -> decltype(::nlohmann::to_json(j, std::forward(val)), void()) 44 | { 45 | ::nlohmann::to_json(j, std::forward(val)); 46 | } 47 | }; 48 | } // namespace nlohmann 49 | -------------------------------------------------------------------------------- /Source/nlohmann/byte_container_with_subtype.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // uint8_t, uint64_t 4 | #include // tie 5 | #include // move 6 | 7 | namespace nlohmann 8 | { 9 | 10 | /// @brief an internal type for a backed binary type 11 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/ 12 | template 13 | class byte_container_with_subtype : public BinaryType 14 | { 15 | public: 16 | using container_type = BinaryType; 17 | using subtype_type = std::uint64_t; 18 | 19 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 20 | byte_container_with_subtype() noexcept(noexcept(container_type())) 21 | : container_type() 22 | {} 23 | 24 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 25 | byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) 26 | : container_type(b) 27 | {} 28 | 29 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 30 | byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) 31 | : container_type(std::move(b)) 32 | {} 33 | 34 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 35 | byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b))) 36 | : container_type(b) 37 | , m_subtype(subtype_) 38 | , m_has_subtype(true) 39 | {} 40 | 41 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 42 | byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b)))) 43 | : container_type(std::move(b)) 44 | , m_subtype(subtype_) 45 | , m_has_subtype(true) 46 | {} 47 | 48 | bool operator==(const byte_container_with_subtype& rhs) const 49 | { 50 | return std::tie(static_cast(*this), m_subtype, m_has_subtype) == 51 | std::tie(static_cast(rhs), rhs.m_subtype, rhs.m_has_subtype); 52 | } 53 | 54 | bool operator!=(const byte_container_with_subtype& rhs) const 55 | { 56 | return !(rhs == *this); 57 | } 58 | 59 | /// @brief sets the binary subtype 60 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/ 61 | void set_subtype(subtype_type subtype_) noexcept 62 | { 63 | m_subtype = subtype_; 64 | m_has_subtype = true; 65 | } 66 | 67 | /// @brief return the binary subtype 68 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/ 69 | constexpr subtype_type subtype() const noexcept 70 | { 71 | return m_has_subtype ? m_subtype : static_cast(-1); 72 | } 73 | 74 | /// @brief return whether the value has a subtype 75 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/ 76 | constexpr bool has_subtype() const noexcept 77 | { 78 | return m_has_subtype; 79 | } 80 | 81 | /// @brief clears the binary subtype 82 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/ 83 | void clear_subtype() noexcept 84 | { 85 | m_subtype = 0; 86 | m_has_subtype = false; 87 | } 88 | 89 | private: 90 | subtype_type m_subtype = 0; 91 | bool m_has_subtype = false; 92 | }; 93 | 94 | } // namespace nlohmann 95 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/conversions/from_json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // transform 4 | #include // array 5 | #include // forward_list 6 | #include // inserter, front_inserter, end 7 | #include // map 8 | #include // string 9 | #include // tuple, make_tuple 10 | #include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible 11 | #include // unordered_map 12 | #include // pair, declval 13 | #include // valarray 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #if JSON_HAS_EXPERIMENTAL_FILESYSTEM 23 | #include 24 | namespace nlohmann::detail 25 | { 26 | namespace std_fs = std::experimental::filesystem; 27 | } // namespace nlohmann::detail 28 | #elif JSON_HAS_FILESYSTEM 29 | #include 30 | namespace nlohmann::detail 31 | { 32 | namespace std_fs = std::filesystem; 33 | } // namespace nlohmann::detail 34 | #endif 35 | 36 | namespace nlohmann 37 | { 38 | namespace detail 39 | { 40 | template 41 | void from_json(const BasicJsonType& j, typename std::nullptr_t& n) 42 | { 43 | if (JSON_HEDLEY_UNLIKELY(!j.is_null())) 44 | { 45 | JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j)); 46 | } 47 | n = nullptr; 48 | } 49 | 50 | // overloads for basic_json template parameters 51 | template < typename BasicJsonType, typename ArithmeticType, 52 | enable_if_t < std::is_arithmetic::value&& 53 | !std::is_same::value, 54 | int > = 0 > 55 | void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) 56 | { 57 | switch (static_cast(j)) 58 | { 59 | case value_t::number_unsigned: 60 | { 61 | val = static_cast(*j.template get_ptr()); 62 | break; 63 | } 64 | case value_t::number_integer: 65 | { 66 | val = static_cast(*j.template get_ptr()); 67 | break; 68 | } 69 | case value_t::number_float: 70 | { 71 | val = static_cast(*j.template get_ptr()); 72 | break; 73 | } 74 | 75 | case value_t::null: 76 | case value_t::object: 77 | case value_t::array: 78 | case value_t::string: 79 | case value_t::boolean: 80 | case value_t::binary: 81 | case value_t::discarded: 82 | default: 83 | JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j)); 84 | } 85 | } 86 | 87 | template 88 | void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) 89 | { 90 | if (JSON_HEDLEY_UNLIKELY(!j.is_boolean())) 91 | { 92 | JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j)); 93 | } 94 | b = *j.template get_ptr(); 95 | } 96 | 97 | template 98 | void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) 99 | { 100 | if (JSON_HEDLEY_UNLIKELY(!j.is_string())) 101 | { 102 | JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); 103 | } 104 | s = *j.template get_ptr(); 105 | } 106 | 107 | template < 108 | typename BasicJsonType, typename ConstructibleStringType, 109 | enable_if_t < 110 | is_constructible_string_type::value&& 111 | !std::is_same::value, 113 | int > = 0 > 114 | void from_json(const BasicJsonType& j, ConstructibleStringType& s) 115 | { 116 | if (JSON_HEDLEY_UNLIKELY(!j.is_string())) 117 | { 118 | JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); 119 | } 120 | 121 | s = *j.template get_ptr(); 122 | } 123 | 124 | template 125 | void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) 126 | { 127 | get_arithmetic_value(j, val); 128 | } 129 | 130 | template 131 | void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) 132 | { 133 | get_arithmetic_value(j, val); 134 | } 135 | 136 | template 137 | void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) 138 | { 139 | get_arithmetic_value(j, val); 140 | } 141 | 142 | template::value, int> = 0> 144 | void from_json(const BasicJsonType& j, EnumType& e) 145 | { 146 | typename std::underlying_type::type val; 147 | get_arithmetic_value(j, val); 148 | e = static_cast(val); 149 | } 150 | 151 | // forward_list doesn't have an insert method 152 | template::value, int> = 0> 154 | void from_json(const BasicJsonType& j, std::forward_list& l) 155 | { 156 | if (JSON_HEDLEY_UNLIKELY(!j.is_array())) 157 | { 158 | JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); 159 | } 160 | l.clear(); 161 | std::transform(j.rbegin(), j.rend(), 162 | std::front_inserter(l), [](const BasicJsonType & i) 163 | { 164 | return i.template get(); 165 | }); 166 | } 167 | 168 | // valarray doesn't have an insert method 169 | template::value, int> = 0> 171 | void from_json(const BasicJsonType& j, std::valarray& l) 172 | { 173 | if (JSON_HEDLEY_UNLIKELY(!j.is_array())) 174 | { 175 | JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); 176 | } 177 | l.resize(j.size()); 178 | std::transform(j.begin(), j.end(), std::begin(l), 179 | [](const BasicJsonType & elem) 180 | { 181 | return elem.template get(); 182 | }); 183 | } 184 | 185 | template 186 | auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 187 | -> decltype(j.template get(), void()) 188 | { 189 | for (std::size_t i = 0; i < N; ++i) 190 | { 191 | arr[i] = j.at(i).template get(); 192 | } 193 | } 194 | 195 | template 196 | void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) 197 | { 198 | arr = *j.template get_ptr(); 199 | } 200 | 201 | template 202 | auto from_json_array_impl(const BasicJsonType& j, std::array& arr, 203 | priority_tag<2> /*unused*/) 204 | -> decltype(j.template get(), void()) 205 | { 206 | for (std::size_t i = 0; i < N; ++i) 207 | { 208 | arr[i] = j.at(i).template get(); 209 | } 210 | } 211 | 212 | template::value, 215 | int> = 0> 216 | auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/) 217 | -> decltype( 218 | arr.reserve(std::declval()), 219 | j.template get(), 220 | void()) 221 | { 222 | using std::end; 223 | 224 | ConstructibleArrayType ret; 225 | ret.reserve(j.size()); 226 | std::transform(j.begin(), j.end(), 227 | std::inserter(ret, end(ret)), [](const BasicJsonType & i) 228 | { 229 | // get() returns *this, this won't call a from_json 230 | // method when value_type is BasicJsonType 231 | return i.template get(); 232 | }); 233 | arr = std::move(ret); 234 | } 235 | 236 | template::value, 239 | int> = 0> 240 | void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, 241 | priority_tag<0> /*unused*/) 242 | { 243 | using std::end; 244 | 245 | ConstructibleArrayType ret; 246 | std::transform( 247 | j.begin(), j.end(), std::inserter(ret, end(ret)), 248 | [](const BasicJsonType & i) 249 | { 250 | // get() returns *this, this won't call a from_json 251 | // method when value_type is BasicJsonType 252 | return i.template get(); 253 | }); 254 | arr = std::move(ret); 255 | } 256 | 257 | template < typename BasicJsonType, typename ConstructibleArrayType, 258 | enable_if_t < 259 | is_constructible_array_type::value&& 260 | !is_constructible_object_type::value&& 261 | !is_constructible_string_type::value&& 262 | !std::is_same::value&& 263 | !is_basic_json::value, 264 | int > = 0 > 265 | auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) 266 | -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), 267 | j.template get(), 268 | void()) 269 | { 270 | if (JSON_HEDLEY_UNLIKELY(!j.is_array())) 271 | { 272 | JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); 273 | } 274 | 275 | from_json_array_impl(j, arr, priority_tag<3> {}); 276 | } 277 | 278 | template < typename BasicJsonType, typename T, std::size_t... Idx > 279 | std::array from_json_inplace_array_impl(BasicJsonType&& j, 280 | identity_tag> /*unused*/, index_sequence /*unused*/) 281 | { 282 | return { { std::forward(j).at(Idx).template get()... } }; 283 | } 284 | 285 | template < typename BasicJsonType, typename T, std::size_t N > 286 | auto from_json(BasicJsonType&& j, identity_tag> tag) 287 | -> decltype(from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {})) 288 | { 289 | if (JSON_HEDLEY_UNLIKELY(!j.is_array())) 290 | { 291 | JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); 292 | } 293 | 294 | return from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {}); 295 | } 296 | 297 | template 298 | void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) 299 | { 300 | if (JSON_HEDLEY_UNLIKELY(!j.is_binary())) 301 | { 302 | JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j)); 303 | } 304 | 305 | bin = *j.template get_ptr(); 306 | } 307 | 308 | template::value, int> = 0> 310 | void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) 311 | { 312 | if (JSON_HEDLEY_UNLIKELY(!j.is_object())) 313 | { 314 | JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j)); 315 | } 316 | 317 | ConstructibleObjectType ret; 318 | const auto* inner_object = j.template get_ptr(); 319 | using value_type = typename ConstructibleObjectType::value_type; 320 | std::transform( 321 | inner_object->begin(), inner_object->end(), 322 | std::inserter(ret, ret.begin()), 323 | [](typename BasicJsonType::object_t::value_type const & p) 324 | { 325 | return value_type(p.first, p.second.template get()); 326 | }); 327 | obj = std::move(ret); 328 | } 329 | 330 | // overload for arithmetic types, not chosen for basic_json template arguments 331 | // (BooleanType, etc..); note: Is it really necessary to provide explicit 332 | // overloads for boolean_t etc. in case of a custom BooleanType which is not 333 | // an arithmetic type? 334 | template < typename BasicJsonType, typename ArithmeticType, 335 | enable_if_t < 336 | std::is_arithmetic::value&& 337 | !std::is_same::value&& 338 | !std::is_same::value&& 339 | !std::is_same::value&& 340 | !std::is_same::value, 341 | int > = 0 > 342 | void from_json(const BasicJsonType& j, ArithmeticType& val) 343 | { 344 | switch (static_cast(j)) 345 | { 346 | case value_t::number_unsigned: 347 | { 348 | val = static_cast(*j.template get_ptr()); 349 | break; 350 | } 351 | case value_t::number_integer: 352 | { 353 | val = static_cast(*j.template get_ptr()); 354 | break; 355 | } 356 | case value_t::number_float: 357 | { 358 | val = static_cast(*j.template get_ptr()); 359 | break; 360 | } 361 | case value_t::boolean: 362 | { 363 | val = static_cast(*j.template get_ptr()); 364 | break; 365 | } 366 | 367 | case value_t::null: 368 | case value_t::object: 369 | case value_t::array: 370 | case value_t::string: 371 | case value_t::binary: 372 | case value_t::discarded: 373 | default: 374 | JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j)); 375 | } 376 | } 377 | 378 | template 379 | std::tuple from_json_tuple_impl_base(BasicJsonType&& j, index_sequence /*unused*/) 380 | { 381 | return std::make_tuple(std::forward(j).at(Idx).template get()...); 382 | } 383 | 384 | template < typename BasicJsonType, class A1, class A2 > 385 | std::pair from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<0> /*unused*/) 386 | { 387 | return {std::forward(j).at(0).template get(), 388 | std::forward(j).at(1).template get()}; 389 | } 390 | 391 | template 392 | void from_json_tuple_impl(BasicJsonType&& j, std::pair& p, priority_tag<1> /*unused*/) 393 | { 394 | p = from_json_tuple_impl(std::forward(j), identity_tag> {}, priority_tag<0> {}); 395 | } 396 | 397 | template 398 | std::tuple from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<2> /*unused*/) 399 | { 400 | return from_json_tuple_impl_base(std::forward(j), index_sequence_for {}); 401 | } 402 | 403 | template 404 | void from_json_tuple_impl(BasicJsonType&& j, std::tuple& t, priority_tag<3> /*unused*/) 405 | { 406 | t = from_json_tuple_impl_base(std::forward(j), index_sequence_for {}); 407 | } 408 | 409 | template 410 | auto from_json(BasicJsonType&& j, TupleRelated&& t) 411 | -> decltype(from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {})) 412 | { 413 | if (JSON_HEDLEY_UNLIKELY(!j.is_array())) 414 | { 415 | JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); 416 | } 417 | 418 | return from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {}); 419 | } 420 | 421 | template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, 422 | typename = enable_if_t < !std::is_constructible < 423 | typename BasicJsonType::string_t, Key >::value >> 424 | void from_json(const BasicJsonType& j, std::map& m) 425 | { 426 | if (JSON_HEDLEY_UNLIKELY(!j.is_array())) 427 | { 428 | JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); 429 | } 430 | m.clear(); 431 | for (const auto& p : j) 432 | { 433 | if (JSON_HEDLEY_UNLIKELY(!p.is_array())) 434 | { 435 | JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j)); 436 | } 437 | m.emplace(p.at(0).template get(), p.at(1).template get()); 438 | } 439 | } 440 | 441 | template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, 442 | typename = enable_if_t < !std::is_constructible < 443 | typename BasicJsonType::string_t, Key >::value >> 444 | void from_json(const BasicJsonType& j, std::unordered_map& m) 445 | { 446 | if (JSON_HEDLEY_UNLIKELY(!j.is_array())) 447 | { 448 | JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); 449 | } 450 | m.clear(); 451 | for (const auto& p : j) 452 | { 453 | if (JSON_HEDLEY_UNLIKELY(!p.is_array())) 454 | { 455 | JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j)); 456 | } 457 | m.emplace(p.at(0).template get(), p.at(1).template get()); 458 | } 459 | } 460 | 461 | #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM 462 | template 463 | void from_json(const BasicJsonType& j, std_fs::path& p) 464 | { 465 | if (JSON_HEDLEY_UNLIKELY(!j.is_string())) 466 | { 467 | JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); 468 | } 469 | p = *j.template get_ptr(); 470 | } 471 | #endif 472 | 473 | struct from_json_fn 474 | { 475 | template 476 | auto operator()(const BasicJsonType& j, T&& val) const 477 | noexcept(noexcept(from_json(j, std::forward(val)))) 478 | -> decltype(from_json(j, std::forward(val))) 479 | { 480 | return from_json(j, std::forward(val)); 481 | } 482 | }; 483 | } // namespace detail 484 | 485 | /// namespace to hold default `from_json` function 486 | /// to see why this is required: 487 | /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html 488 | namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) 489 | { 490 | constexpr const auto& from_json = detail::static_const::value; // NOLINT(misc-definitions-in-headers) 491 | } // namespace 492 | } // namespace nlohmann 493 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/conversions/to_json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // copy 4 | #include // begin, end 5 | #include // string 6 | #include // tuple, get 7 | #include // is_same, is_constructible, is_floating_point, is_enum, underlying_type 8 | #include // move, forward, declval, pair 9 | #include // valarray 10 | #include // vector 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #if JSON_HAS_EXPERIMENTAL_FILESYSTEM 19 | #include 20 | namespace nlohmann::detail 21 | { 22 | namespace std_fs = std::experimental::filesystem; 23 | } // namespace nlohmann::detail 24 | #elif JSON_HAS_FILESYSTEM 25 | #include 26 | namespace nlohmann::detail 27 | { 28 | namespace std_fs = std::filesystem; 29 | } // namespace nlohmann::detail 30 | #endif 31 | 32 | namespace nlohmann 33 | { 34 | namespace detail 35 | { 36 | ////////////////// 37 | // constructors // 38 | ////////////////// 39 | 40 | /* 41 | * Note all external_constructor<>::construct functions need to call 42 | * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an 43 | * allocated value (e.g., a string). See bug issue 44 | * https://github.com/nlohmann/json/issues/2865 for more information. 45 | */ 46 | 47 | template struct external_constructor; 48 | 49 | template<> 50 | struct external_constructor 51 | { 52 | template 53 | static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept 54 | { 55 | j.m_value.destroy(j.m_type); 56 | j.m_type = value_t::boolean; 57 | j.m_value = b; 58 | j.assert_invariant(); 59 | } 60 | }; 61 | 62 | template<> 63 | struct external_constructor 64 | { 65 | template 66 | static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) 67 | { 68 | j.m_value.destroy(j.m_type); 69 | j.m_type = value_t::string; 70 | j.m_value = s; 71 | j.assert_invariant(); 72 | } 73 | 74 | template 75 | static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) 76 | { 77 | j.m_value.destroy(j.m_type); 78 | j.m_type = value_t::string; 79 | j.m_value = std::move(s); 80 | j.assert_invariant(); 81 | } 82 | 83 | template < typename BasicJsonType, typename CompatibleStringType, 84 | enable_if_t < !std::is_same::value, 85 | int > = 0 > 86 | static void construct(BasicJsonType& j, const CompatibleStringType& str) 87 | { 88 | j.m_value.destroy(j.m_type); 89 | j.m_type = value_t::string; 90 | j.m_value.string = j.template create(str); 91 | j.assert_invariant(); 92 | } 93 | }; 94 | 95 | template<> 96 | struct external_constructor 97 | { 98 | template 99 | static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) 100 | { 101 | j.m_value.destroy(j.m_type); 102 | j.m_type = value_t::binary; 103 | j.m_value = typename BasicJsonType::binary_t(b); 104 | j.assert_invariant(); 105 | } 106 | 107 | template 108 | static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) 109 | { 110 | j.m_value.destroy(j.m_type); 111 | j.m_type = value_t::binary; 112 | j.m_value = typename BasicJsonType::binary_t(std::move(b)); 113 | j.assert_invariant(); 114 | } 115 | }; 116 | 117 | template<> 118 | struct external_constructor 119 | { 120 | template 121 | static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept 122 | { 123 | j.m_value.destroy(j.m_type); 124 | j.m_type = value_t::number_float; 125 | j.m_value = val; 126 | j.assert_invariant(); 127 | } 128 | }; 129 | 130 | template<> 131 | struct external_constructor 132 | { 133 | template 134 | static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept 135 | { 136 | j.m_value.destroy(j.m_type); 137 | j.m_type = value_t::number_unsigned; 138 | j.m_value = val; 139 | j.assert_invariant(); 140 | } 141 | }; 142 | 143 | template<> 144 | struct external_constructor 145 | { 146 | template 147 | static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept 148 | { 149 | j.m_value.destroy(j.m_type); 150 | j.m_type = value_t::number_integer; 151 | j.m_value = val; 152 | j.assert_invariant(); 153 | } 154 | }; 155 | 156 | template<> 157 | struct external_constructor 158 | { 159 | template 160 | static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) 161 | { 162 | j.m_value.destroy(j.m_type); 163 | j.m_type = value_t::array; 164 | j.m_value = arr; 165 | j.set_parents(); 166 | j.assert_invariant(); 167 | } 168 | 169 | template 170 | static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) 171 | { 172 | j.m_value.destroy(j.m_type); 173 | j.m_type = value_t::array; 174 | j.m_value = std::move(arr); 175 | j.set_parents(); 176 | j.assert_invariant(); 177 | } 178 | 179 | template < typename BasicJsonType, typename CompatibleArrayType, 180 | enable_if_t < !std::is_same::value, 181 | int > = 0 > 182 | static void construct(BasicJsonType& j, const CompatibleArrayType& arr) 183 | { 184 | using std::begin; 185 | using std::end; 186 | 187 | j.m_value.destroy(j.m_type); 188 | j.m_type = value_t::array; 189 | j.m_value.array = j.template create(begin(arr), end(arr)); 190 | j.set_parents(); 191 | j.assert_invariant(); 192 | } 193 | 194 | template 195 | static void construct(BasicJsonType& j, const std::vector& arr) 196 | { 197 | j.m_value.destroy(j.m_type); 198 | j.m_type = value_t::array; 199 | j.m_value = value_t::array; 200 | j.m_value.array->reserve(arr.size()); 201 | for (const bool x : arr) 202 | { 203 | j.m_value.array->push_back(x); 204 | j.set_parent(j.m_value.array->back()); 205 | } 206 | j.assert_invariant(); 207 | } 208 | 209 | template::value, int> = 0> 211 | static void construct(BasicJsonType& j, const std::valarray& arr) 212 | { 213 | j.m_value.destroy(j.m_type); 214 | j.m_type = value_t::array; 215 | j.m_value = value_t::array; 216 | j.m_value.array->resize(arr.size()); 217 | if (arr.size() > 0) 218 | { 219 | std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); 220 | } 221 | j.set_parents(); 222 | j.assert_invariant(); 223 | } 224 | }; 225 | 226 | template<> 227 | struct external_constructor 228 | { 229 | template 230 | static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) 231 | { 232 | j.m_value.destroy(j.m_type); 233 | j.m_type = value_t::object; 234 | j.m_value = obj; 235 | j.set_parents(); 236 | j.assert_invariant(); 237 | } 238 | 239 | template 240 | static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) 241 | { 242 | j.m_value.destroy(j.m_type); 243 | j.m_type = value_t::object; 244 | j.m_value = std::move(obj); 245 | j.set_parents(); 246 | j.assert_invariant(); 247 | } 248 | 249 | template < typename BasicJsonType, typename CompatibleObjectType, 250 | enable_if_t < !std::is_same::value, int > = 0 > 251 | static void construct(BasicJsonType& j, const CompatibleObjectType& obj) 252 | { 253 | using std::begin; 254 | using std::end; 255 | 256 | j.m_value.destroy(j.m_type); 257 | j.m_type = value_t::object; 258 | j.m_value.object = j.template create(begin(obj), end(obj)); 259 | j.set_parents(); 260 | j.assert_invariant(); 261 | } 262 | }; 263 | 264 | ///////////// 265 | // to_json // 266 | ///////////// 267 | 268 | template::value, int> = 0> 270 | void to_json(BasicJsonType& j, T b) noexcept 271 | { 272 | external_constructor::construct(j, b); 273 | } 274 | 275 | template::value, int> = 0> 277 | void to_json(BasicJsonType& j, const CompatibleString& s) 278 | { 279 | external_constructor::construct(j, s); 280 | } 281 | 282 | template 283 | void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s) 284 | { 285 | external_constructor::construct(j, std::move(s)); 286 | } 287 | 288 | template::value, int> = 0> 290 | void to_json(BasicJsonType& j, FloatType val) noexcept 291 | { 292 | external_constructor::construct(j, static_cast(val)); 293 | } 294 | 295 | template::value, int> = 0> 297 | void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept 298 | { 299 | external_constructor::construct(j, static_cast(val)); 300 | } 301 | 302 | template::value, int> = 0> 304 | void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept 305 | { 306 | external_constructor::construct(j, static_cast(val)); 307 | } 308 | 309 | template::value, int> = 0> 311 | void to_json(BasicJsonType& j, EnumType e) noexcept 312 | { 313 | using underlying_type = typename std::underlying_type::type; 314 | external_constructor::construct(j, static_cast(e)); 315 | } 316 | 317 | template 318 | void to_json(BasicJsonType& j, const std::vector& e) 319 | { 320 | external_constructor::construct(j, e); 321 | } 322 | 323 | template < typename BasicJsonType, typename CompatibleArrayType, 324 | enable_if_t < is_compatible_array_type::value&& 326 | !is_compatible_object_type::value&& 327 | !is_compatible_string_type::value&& 328 | !std::is_same::value&& 329 | !is_basic_json::value, 330 | int > = 0 > 331 | void to_json(BasicJsonType& j, const CompatibleArrayType& arr) 332 | { 333 | external_constructor::construct(j, arr); 334 | } 335 | 336 | template 337 | void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) 338 | { 339 | external_constructor::construct(j, bin); 340 | } 341 | 342 | template::value, int> = 0> 344 | void to_json(BasicJsonType& j, const std::valarray& arr) 345 | { 346 | external_constructor::construct(j, std::move(arr)); 347 | } 348 | 349 | template 350 | void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) 351 | { 352 | external_constructor::construct(j, std::move(arr)); 353 | } 354 | 355 | template < typename BasicJsonType, typename CompatibleObjectType, 356 | enable_if_t < is_compatible_object_type::value&& !is_basic_json::value, int > = 0 > 357 | void to_json(BasicJsonType& j, const CompatibleObjectType& obj) 358 | { 359 | external_constructor::construct(j, obj); 360 | } 361 | 362 | template 363 | void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) 364 | { 365 | external_constructor::construct(j, std::move(obj)); 366 | } 367 | 368 | template < 369 | typename BasicJsonType, typename T, std::size_t N, 370 | enable_if_t < !std::is_constructible::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 372 | int > = 0 > 373 | void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 374 | { 375 | external_constructor::construct(j, arr); 376 | } 377 | 378 | template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible::value&& std::is_constructible::value, int > = 0 > 379 | void to_json(BasicJsonType& j, const std::pair& p) 380 | { 381 | j = { p.first, p.second }; 382 | } 383 | 384 | // for https://github.com/nlohmann/json/pull/1134 385 | template>::value, int> = 0> 387 | void to_json(BasicJsonType& j, const T& b) 388 | { 389 | j = { {b.key(), b.value()} }; 390 | } 391 | 392 | template 393 | void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence /*unused*/) 394 | { 395 | j = { std::get(t)... }; 396 | } 397 | 398 | template::value, int > = 0> 399 | void to_json(BasicJsonType& j, const T& t) 400 | { 401 | to_json_tuple_impl(j, t, make_index_sequence::value> {}); 402 | } 403 | 404 | #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM 405 | template 406 | void to_json(BasicJsonType& j, const std_fs::path& p) 407 | { 408 | j = p.string(); 409 | } 410 | #endif 411 | 412 | struct to_json_fn 413 | { 414 | template 415 | auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward(val)))) 416 | -> decltype(to_json(j, std::forward(val)), void()) 417 | { 418 | return to_json(j, std::forward(val)); 419 | } 420 | }; 421 | } // namespace detail 422 | 423 | /// namespace to hold default `to_json` function 424 | /// to see why this is required: 425 | /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html 426 | namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) 427 | { 428 | constexpr const auto& to_json = detail::static_const::value; // NOLINT(misc-definitions-in-headers) 429 | } // namespace 430 | } // namespace nlohmann 431 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/exceptions.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // exception 4 | #include // runtime_error 5 | #include // to_string 6 | #include // vector 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace nlohmann 14 | { 15 | namespace detail 16 | { 17 | //////////////// 18 | // exceptions // 19 | //////////////// 20 | 21 | /// @brief general exception of the @ref basic_json class 22 | /// @sa https://json.nlohmann.me/api/basic_json/exception/ 23 | class exception : public std::exception 24 | { 25 | public: 26 | /// returns the explanatory string 27 | const char* what() const noexcept override 28 | { 29 | return m.what(); 30 | } 31 | 32 | /// the id of the exception 33 | const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) 34 | 35 | protected: 36 | JSON_HEDLEY_NON_NULL(3) 37 | exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing) 38 | 39 | static std::string name(const std::string& ename, int id_) 40 | { 41 | return "[json.exception." + ename + "." + std::to_string(id_) + "] "; 42 | } 43 | 44 | template 45 | static std::string diagnostics(const BasicJsonType& leaf_element) 46 | { 47 | #if JSON_DIAGNOSTICS 48 | std::vector tokens; 49 | for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent) 50 | { 51 | switch (current->m_parent->type()) 52 | { 53 | case value_t::array: 54 | { 55 | for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i) 56 | { 57 | if (¤t->m_parent->m_value.array->operator[](i) == current) 58 | { 59 | tokens.emplace_back(std::to_string(i)); 60 | break; 61 | } 62 | } 63 | break; 64 | } 65 | 66 | case value_t::object: 67 | { 68 | for (const auto& element : *current->m_parent->m_value.object) 69 | { 70 | if (&element.second == current) 71 | { 72 | tokens.emplace_back(element.first.c_str()); 73 | break; 74 | } 75 | } 76 | break; 77 | } 78 | 79 | case value_t::null: // LCOV_EXCL_LINE 80 | case value_t::string: // LCOV_EXCL_LINE 81 | case value_t::boolean: // LCOV_EXCL_LINE 82 | case value_t::number_integer: // LCOV_EXCL_LINE 83 | case value_t::number_unsigned: // LCOV_EXCL_LINE 84 | case value_t::number_float: // LCOV_EXCL_LINE 85 | case value_t::binary: // LCOV_EXCL_LINE 86 | case value_t::discarded: // LCOV_EXCL_LINE 87 | default: // LCOV_EXCL_LINE 88 | break; // LCOV_EXCL_LINE 89 | } 90 | } 91 | 92 | if (tokens.empty()) 93 | { 94 | return ""; 95 | } 96 | 97 | return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, 98 | [](const std::string & a, const std::string & b) 99 | { 100 | return a + "/" + detail::escape(b); 101 | }) + ") "; 102 | #else 103 | static_cast(leaf_element); 104 | return ""; 105 | #endif 106 | } 107 | 108 | private: 109 | /// an exception object as storage for error messages 110 | std::runtime_error m; 111 | }; 112 | 113 | /// @brief exception indicating a parse error 114 | /// @sa https://json.nlohmann.me/api/basic_json/parse_error/ 115 | class parse_error : public exception 116 | { 117 | public: 118 | /*! 119 | @brief create a parse error exception 120 | @param[in] id_ the id of the exception 121 | @param[in] pos the position where the error occurred (or with 122 | chars_read_total=0 if the position cannot be 123 | determined) 124 | @param[in] what_arg the explanatory string 125 | @return parse_error object 126 | */ 127 | template 128 | static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context) 129 | { 130 | std::string w = exception::name("parse_error", id_) + "parse error" + 131 | position_string(pos) + ": " + exception::diagnostics(context) + what_arg; 132 | return {id_, pos.chars_read_total, w.c_str()}; 133 | } 134 | 135 | template 136 | static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context) 137 | { 138 | std::string w = exception::name("parse_error", id_) + "parse error" + 139 | (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") + 140 | ": " + exception::diagnostics(context) + what_arg; 141 | return {id_, byte_, w.c_str()}; 142 | } 143 | 144 | /*! 145 | @brief byte index of the parse error 146 | 147 | The byte index of the last read character in the input file. 148 | 149 | @note For an input with n bytes, 1 is the index of the first character and 150 | n+1 is the index of the terminating null byte or the end of file. 151 | This also holds true when reading a byte vector (CBOR or MessagePack). 152 | */ 153 | const std::size_t byte; 154 | 155 | private: 156 | parse_error(int id_, std::size_t byte_, const char* what_arg) 157 | : exception(id_, what_arg), byte(byte_) {} 158 | 159 | static std::string position_string(const position_t& pos) 160 | { 161 | return " at line " + std::to_string(pos.lines_read + 1) + 162 | ", column " + std::to_string(pos.chars_read_current_line); 163 | } 164 | }; 165 | 166 | /// @brief exception indicating errors with iterators 167 | /// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/ 168 | class invalid_iterator : public exception 169 | { 170 | public: 171 | template 172 | static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context) 173 | { 174 | std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg; 175 | return {id_, w.c_str()}; 176 | } 177 | 178 | private: 179 | JSON_HEDLEY_NON_NULL(3) 180 | invalid_iterator(int id_, const char* what_arg) 181 | : exception(id_, what_arg) {} 182 | }; 183 | 184 | /// @brief exception indicating executing a member function with a wrong type 185 | /// @sa https://json.nlohmann.me/api/basic_json/type_error/ 186 | class type_error : public exception 187 | { 188 | public: 189 | template 190 | static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context) 191 | { 192 | std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg; 193 | return {id_, w.c_str()}; 194 | } 195 | 196 | private: 197 | JSON_HEDLEY_NON_NULL(3) 198 | type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} 199 | }; 200 | 201 | /// @brief exception indicating access out of the defined range 202 | /// @sa https://json.nlohmann.me/api/basic_json/out_of_range/ 203 | class out_of_range : public exception 204 | { 205 | public: 206 | template 207 | static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context) 208 | { 209 | std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg; 210 | return {id_, w.c_str()}; 211 | } 212 | 213 | private: 214 | JSON_HEDLEY_NON_NULL(3) 215 | out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} 216 | }; 217 | 218 | /// @brief exception indicating other library errors 219 | /// @sa https://json.nlohmann.me/api/basic_json/other_error/ 220 | class other_error : public exception 221 | { 222 | public: 223 | template 224 | static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context) 225 | { 226 | std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg; 227 | return {id_, w.c_str()}; 228 | } 229 | 230 | private: 231 | JSON_HEDLEY_NON_NULL(3) 232 | other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} 233 | }; 234 | 235 | } // namespace detail 236 | } // namespace nlohmann 237 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/hash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // uint8_t 4 | #include // size_t 5 | #include // hash 6 | 7 | #include 8 | #include 9 | 10 | namespace nlohmann 11 | { 12 | namespace detail 13 | { 14 | 15 | // boost::hash_combine 16 | inline std::size_t combine(std::size_t seed, std::size_t h) noexcept 17 | { 18 | seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); 19 | return seed; 20 | } 21 | 22 | /*! 23 | @brief hash a JSON value 24 | 25 | The hash function tries to rely on std::hash where possible. Furthermore, the 26 | type of the JSON value is taken into account to have different hash values for 27 | null, 0, 0U, and false, etc. 28 | 29 | @tparam BasicJsonType basic_json specialization 30 | @param j JSON value to hash 31 | @return hash value of j 32 | */ 33 | template 34 | std::size_t hash(const BasicJsonType& j) 35 | { 36 | using string_t = typename BasicJsonType::string_t; 37 | using number_integer_t = typename BasicJsonType::number_integer_t; 38 | using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 39 | using number_float_t = typename BasicJsonType::number_float_t; 40 | 41 | const auto type = static_cast(j.type()); 42 | switch (j.type()) 43 | { 44 | case BasicJsonType::value_t::null: 45 | case BasicJsonType::value_t::discarded: 46 | { 47 | return combine(type, 0); 48 | } 49 | 50 | case BasicJsonType::value_t::object: 51 | { 52 | auto seed = combine(type, j.size()); 53 | for (const auto& element : j.items()) 54 | { 55 | const auto h = std::hash {}(element.key()); 56 | seed = combine(seed, h); 57 | seed = combine(seed, hash(element.value())); 58 | } 59 | return seed; 60 | } 61 | 62 | case BasicJsonType::value_t::array: 63 | { 64 | auto seed = combine(type, j.size()); 65 | for (const auto& element : j) 66 | { 67 | seed = combine(seed, hash(element)); 68 | } 69 | return seed; 70 | } 71 | 72 | case BasicJsonType::value_t::string: 73 | { 74 | const auto h = std::hash {}(j.template get_ref()); 75 | return combine(type, h); 76 | } 77 | 78 | case BasicJsonType::value_t::boolean: 79 | { 80 | const auto h = std::hash {}(j.template get()); 81 | return combine(type, h); 82 | } 83 | 84 | case BasicJsonType::value_t::number_integer: 85 | { 86 | const auto h = std::hash {}(j.template get()); 87 | return combine(type, h); 88 | } 89 | 90 | case BasicJsonType::value_t::number_unsigned: 91 | { 92 | const auto h = std::hash {}(j.template get()); 93 | return combine(type, h); 94 | } 95 | 96 | case BasicJsonType::value_t::number_float: 97 | { 98 | const auto h = std::hash {}(j.template get()); 99 | return combine(type, h); 100 | } 101 | 102 | case BasicJsonType::value_t::binary: 103 | { 104 | auto seed = combine(type, j.get_binary().size()); 105 | const auto h = std::hash {}(j.get_binary().has_subtype()); 106 | seed = combine(seed, h); 107 | seed = combine(seed, static_cast(j.get_binary().subtype())); 108 | for (const auto byte : j.get_binary()) 109 | { 110 | seed = combine(seed, std::hash {}(byte)); 111 | } 112 | return seed; 113 | } 114 | 115 | default: // LCOV_EXCL_LINE 116 | JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE 117 | return 0; // LCOV_EXCL_LINE 118 | } 119 | } 120 | 121 | } // namespace detail 122 | } // namespace nlohmann 123 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/input/input_adapters.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // array 4 | #include // size_t 5 | #include // strlen 6 | #include // begin, end, iterator_traits, random_access_iterator_tag, distance, next 7 | #include // shared_ptr, make_shared, addressof 8 | #include // accumulate 9 | #include // string, char_traits 10 | #include // enable_if, is_base_of, is_pointer, is_integral, remove_pointer 11 | #include // pair, declval 12 | 13 | #ifndef JSON_NO_IO 14 | #include // FILE * 15 | #include // istream 16 | #endif // JSON_NO_IO 17 | 18 | #include 19 | #include 20 | 21 | namespace nlohmann 22 | { 23 | namespace detail 24 | { 25 | /// the supported input formats 26 | enum class input_format_t { json, cbor, msgpack, ubjson, bson }; 27 | 28 | //////////////////// 29 | // input adapters // 30 | //////////////////// 31 | 32 | #ifndef JSON_NO_IO 33 | /*! 34 | Input adapter for stdio file access. This adapter read only 1 byte and do not use any 35 | buffer. This adapter is a very low level adapter. 36 | */ 37 | class file_input_adapter 38 | { 39 | public: 40 | using char_type = char; 41 | 42 | JSON_HEDLEY_NON_NULL(2) 43 | explicit file_input_adapter(std::FILE* f) noexcept 44 | : m_file(f) 45 | {} 46 | 47 | // make class move-only 48 | file_input_adapter(const file_input_adapter&) = delete; 49 | file_input_adapter(file_input_adapter&&) noexcept = default; 50 | file_input_adapter& operator=(const file_input_adapter&) = delete; 51 | file_input_adapter& operator=(file_input_adapter&&) = delete; 52 | ~file_input_adapter() = default; 53 | 54 | std::char_traits::int_type get_character() noexcept 55 | { 56 | return std::fgetc(m_file); 57 | } 58 | 59 | private: 60 | /// the file pointer to read from 61 | std::FILE* m_file; 62 | }; 63 | 64 | 65 | /*! 66 | Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at 67 | beginning of input. Does not support changing the underlying std::streambuf 68 | in mid-input. Maintains underlying std::istream and std::streambuf to support 69 | subsequent use of standard std::istream operations to process any input 70 | characters following those used in parsing the JSON input. Clears the 71 | std::istream flags; any input errors (e.g., EOF) will be detected by the first 72 | subsequent call for input from the std::istream. 73 | */ 74 | class input_stream_adapter 75 | { 76 | public: 77 | using char_type = char; 78 | 79 | ~input_stream_adapter() 80 | { 81 | // clear stream flags; we use underlying streambuf I/O, do not 82 | // maintain ifstream flags, except eof 83 | if (is != nullptr) 84 | { 85 | is->clear(is->rdstate() & std::ios::eofbit); 86 | } 87 | } 88 | 89 | explicit input_stream_adapter(std::istream& i) 90 | : is(&i), sb(i.rdbuf()) 91 | {} 92 | 93 | // delete because of pointer members 94 | input_stream_adapter(const input_stream_adapter&) = delete; 95 | input_stream_adapter& operator=(input_stream_adapter&) = delete; 96 | input_stream_adapter& operator=(input_stream_adapter&&) = delete; 97 | 98 | input_stream_adapter(input_stream_adapter&& rhs) noexcept 99 | : is(rhs.is), sb(rhs.sb) 100 | { 101 | rhs.is = nullptr; 102 | rhs.sb = nullptr; 103 | } 104 | 105 | // std::istream/std::streambuf use std::char_traits::to_int_type, to 106 | // ensure that std::char_traits::eof() and the character 0xFF do not 107 | // end up as the same value, e.g. 0xFFFFFFFF. 108 | std::char_traits::int_type get_character() 109 | { 110 | auto res = sb->sbumpc(); 111 | // set eof manually, as we don't use the istream interface. 112 | if (JSON_HEDLEY_UNLIKELY(res == std::char_traits::eof())) 113 | { 114 | is->clear(is->rdstate() | std::ios::eofbit); 115 | } 116 | return res; 117 | } 118 | 119 | private: 120 | /// the associated input stream 121 | std::istream* is = nullptr; 122 | std::streambuf* sb = nullptr; 123 | }; 124 | #endif // JSON_NO_IO 125 | 126 | // General-purpose iterator-based adapter. It might not be as fast as 127 | // theoretically possible for some containers, but it is extremely versatile. 128 | template 129 | class iterator_input_adapter 130 | { 131 | public: 132 | using char_type = typename std::iterator_traits::value_type; 133 | 134 | iterator_input_adapter(IteratorType first, IteratorType last) 135 | : current(std::move(first)), end(std::move(last)) 136 | {} 137 | 138 | typename std::char_traits::int_type get_character() 139 | { 140 | if (JSON_HEDLEY_LIKELY(current != end)) 141 | { 142 | auto result = std::char_traits::to_int_type(*current); 143 | std::advance(current, 1); 144 | return result; 145 | } 146 | 147 | return std::char_traits::eof(); 148 | } 149 | 150 | private: 151 | IteratorType current; 152 | IteratorType end; 153 | 154 | template 155 | friend struct wide_string_input_helper; 156 | 157 | bool empty() const 158 | { 159 | return current == end; 160 | } 161 | }; 162 | 163 | 164 | template 165 | struct wide_string_input_helper; 166 | 167 | template 168 | struct wide_string_input_helper 169 | { 170 | // UTF-32 171 | static void fill_buffer(BaseInputAdapter& input, 172 | std::array::int_type, 4>& utf8_bytes, 173 | size_t& utf8_bytes_index, 174 | size_t& utf8_bytes_filled) 175 | { 176 | utf8_bytes_index = 0; 177 | 178 | if (JSON_HEDLEY_UNLIKELY(input.empty())) 179 | { 180 | utf8_bytes[0] = std::char_traits::eof(); 181 | utf8_bytes_filled = 1; 182 | } 183 | else 184 | { 185 | // get the current character 186 | const auto wc = input.get_character(); 187 | 188 | // UTF-32 to UTF-8 encoding 189 | if (wc < 0x80) 190 | { 191 | utf8_bytes[0] = static_cast::int_type>(wc); 192 | utf8_bytes_filled = 1; 193 | } 194 | else if (wc <= 0x7FF) 195 | { 196 | utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u) & 0x1Fu)); 197 | utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); 198 | utf8_bytes_filled = 2; 199 | } 200 | else if (wc <= 0xFFFF) 201 | { 202 | utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u) & 0x0Fu)); 203 | utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); 204 | utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); 205 | utf8_bytes_filled = 3; 206 | } 207 | else if (wc <= 0x10FFFF) 208 | { 209 | utf8_bytes[0] = static_cast::int_type>(0xF0u | ((static_cast(wc) >> 18u) & 0x07u)); 210 | utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 12u) & 0x3Fu)); 211 | utf8_bytes[2] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); 212 | utf8_bytes[3] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); 213 | utf8_bytes_filled = 4; 214 | } 215 | else 216 | { 217 | // unknown character 218 | utf8_bytes[0] = static_cast::int_type>(wc); 219 | utf8_bytes_filled = 1; 220 | } 221 | } 222 | } 223 | }; 224 | 225 | template 226 | struct wide_string_input_helper 227 | { 228 | // UTF-16 229 | static void fill_buffer(BaseInputAdapter& input, 230 | std::array::int_type, 4>& utf8_bytes, 231 | size_t& utf8_bytes_index, 232 | size_t& utf8_bytes_filled) 233 | { 234 | utf8_bytes_index = 0; 235 | 236 | if (JSON_HEDLEY_UNLIKELY(input.empty())) 237 | { 238 | utf8_bytes[0] = std::char_traits::eof(); 239 | utf8_bytes_filled = 1; 240 | } 241 | else 242 | { 243 | // get the current character 244 | const auto wc = input.get_character(); 245 | 246 | // UTF-16 to UTF-8 encoding 247 | if (wc < 0x80) 248 | { 249 | utf8_bytes[0] = static_cast::int_type>(wc); 250 | utf8_bytes_filled = 1; 251 | } 252 | else if (wc <= 0x7FF) 253 | { 254 | utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u))); 255 | utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); 256 | utf8_bytes_filled = 2; 257 | } 258 | else if (0xD800 > wc || wc >= 0xE000) 259 | { 260 | utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u))); 261 | utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); 262 | utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); 263 | utf8_bytes_filled = 3; 264 | } 265 | else 266 | { 267 | if (JSON_HEDLEY_UNLIKELY(!input.empty())) 268 | { 269 | const auto wc2 = static_cast(input.get_character()); 270 | const auto charcode = 0x10000u + (((static_cast(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); 271 | utf8_bytes[0] = static_cast::int_type>(0xF0u | (charcode >> 18u)); 272 | utf8_bytes[1] = static_cast::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu)); 273 | utf8_bytes[2] = static_cast::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu)); 274 | utf8_bytes[3] = static_cast::int_type>(0x80u | (charcode & 0x3Fu)); 275 | utf8_bytes_filled = 4; 276 | } 277 | else 278 | { 279 | utf8_bytes[0] = static_cast::int_type>(wc); 280 | utf8_bytes_filled = 1; 281 | } 282 | } 283 | } 284 | } 285 | }; 286 | 287 | // Wraps another input apdater to convert wide character types into individual bytes. 288 | template 289 | class wide_string_input_adapter 290 | { 291 | public: 292 | using char_type = char; 293 | 294 | wide_string_input_adapter(BaseInputAdapter base) 295 | : base_adapter(base) {} 296 | 297 | typename std::char_traits::int_type get_character() noexcept 298 | { 299 | // check if buffer needs to be filled 300 | if (utf8_bytes_index == utf8_bytes_filled) 301 | { 302 | fill_buffer(); 303 | 304 | JSON_ASSERT(utf8_bytes_filled > 0); 305 | JSON_ASSERT(utf8_bytes_index == 0); 306 | } 307 | 308 | // use buffer 309 | JSON_ASSERT(utf8_bytes_filled > 0); 310 | JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled); 311 | return utf8_bytes[utf8_bytes_index++]; 312 | } 313 | 314 | private: 315 | BaseInputAdapter base_adapter; 316 | 317 | template 318 | void fill_buffer() 319 | { 320 | wide_string_input_helper::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled); 321 | } 322 | 323 | /// a buffer for UTF-8 bytes 324 | std::array::int_type, 4> utf8_bytes = {{0, 0, 0, 0}}; 325 | 326 | /// index to the utf8_codes array for the next valid byte 327 | std::size_t utf8_bytes_index = 0; 328 | /// number of valid bytes in the utf8_codes array 329 | std::size_t utf8_bytes_filled = 0; 330 | }; 331 | 332 | 333 | template 334 | struct iterator_input_adapter_factory 335 | { 336 | using iterator_type = IteratorType; 337 | using char_type = typename std::iterator_traits::value_type; 338 | using adapter_type = iterator_input_adapter; 339 | 340 | static adapter_type create(IteratorType first, IteratorType last) 341 | { 342 | return adapter_type(std::move(first), std::move(last)); 343 | } 344 | }; 345 | 346 | template 347 | struct is_iterator_of_multibyte 348 | { 349 | using value_type = typename std::iterator_traits::value_type; 350 | enum 351 | { 352 | value = sizeof(value_type) > 1 353 | }; 354 | }; 355 | 356 | template 357 | struct iterator_input_adapter_factory::value>> 358 | { 359 | using iterator_type = IteratorType; 360 | using char_type = typename std::iterator_traits::value_type; 361 | using base_adapter_type = iterator_input_adapter; 362 | using adapter_type = wide_string_input_adapter; 363 | 364 | static adapter_type create(IteratorType first, IteratorType last) 365 | { 366 | return adapter_type(base_adapter_type(std::move(first), std::move(last))); 367 | } 368 | }; 369 | 370 | // General purpose iterator-based input 371 | template 372 | typename iterator_input_adapter_factory::adapter_type input_adapter(IteratorType first, IteratorType last) 373 | { 374 | using factory_type = iterator_input_adapter_factory; 375 | return factory_type::create(first, last); 376 | } 377 | 378 | // Convenience shorthand from container to iterator 379 | // Enables ADL on begin(container) and end(container) 380 | // Encloses the using declarations in namespace for not to leak them to outside scope 381 | 382 | namespace container_input_adapter_factory_impl 383 | { 384 | 385 | using std::begin; 386 | using std::end; 387 | 388 | template 389 | struct container_input_adapter_factory {}; 390 | 391 | template 392 | struct container_input_adapter_factory< ContainerType, 393 | void_t()), end(std::declval()))>> 394 | { 395 | using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); 396 | 397 | static adapter_type create(const ContainerType& container) 398 | { 399 | return input_adapter(begin(container), end(container)); 400 | } 401 | }; 402 | 403 | } // namespace container_input_adapter_factory_impl 404 | 405 | template 406 | typename container_input_adapter_factory_impl::container_input_adapter_factory::adapter_type input_adapter(const ContainerType& container) 407 | { 408 | return container_input_adapter_factory_impl::container_input_adapter_factory::create(container); 409 | } 410 | 411 | #ifndef JSON_NO_IO 412 | // Special cases with fast paths 413 | inline file_input_adapter input_adapter(std::FILE* file) 414 | { 415 | return file_input_adapter(file); 416 | } 417 | 418 | inline input_stream_adapter input_adapter(std::istream& stream) 419 | { 420 | return input_stream_adapter(stream); 421 | } 422 | 423 | inline input_stream_adapter input_adapter(std::istream&& stream) 424 | { 425 | return input_stream_adapter(stream); 426 | } 427 | #endif // JSON_NO_IO 428 | 429 | using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval(), std::declval())); 430 | 431 | // Null-delimited strings, and the like. 432 | template < typename CharT, 433 | typename std::enable_if < 434 | std::is_pointer::value&& 435 | !std::is_array::value&& 436 | std::is_integral::type>::value&& 437 | sizeof(typename std::remove_pointer::type) == 1, 438 | int >::type = 0 > 439 | contiguous_bytes_input_adapter input_adapter(CharT b) 440 | { 441 | auto length = std::strlen(reinterpret_cast(b)); 442 | const auto* ptr = reinterpret_cast(b); 443 | return input_adapter(ptr, ptr + length); 444 | } 445 | 446 | template 447 | auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 448 | { 449 | return input_adapter(array, array + N); 450 | } 451 | 452 | // This class only handles inputs of input_buffer_adapter type. 453 | // It's required so that expressions like {ptr, len} can be implicitly cast 454 | // to the correct adapter. 455 | class span_input_adapter 456 | { 457 | public: 458 | template < typename CharT, 459 | typename std::enable_if < 460 | std::is_pointer::value&& 461 | std::is_integral::type>::value&& 462 | sizeof(typename std::remove_pointer::type) == 1, 463 | int >::type = 0 > 464 | span_input_adapter(CharT b, std::size_t l) 465 | : ia(reinterpret_cast(b), reinterpret_cast(b) + l) {} 466 | 467 | template::iterator_category, std::random_access_iterator_tag>::value, 470 | int>::type = 0> 471 | span_input_adapter(IteratorType first, IteratorType last) 472 | : ia(input_adapter(first, last)) {} 473 | 474 | contiguous_bytes_input_adapter&& get() 475 | { 476 | return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg) 477 | } 478 | 479 | private: 480 | contiguous_bytes_input_adapter ia; 481 | }; 482 | } // namespace detail 483 | } // namespace nlohmann 484 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/input/parser.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // isfinite 4 | #include // uint8_t 5 | #include // function 6 | #include // string 7 | #include // move 8 | #include // vector 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace nlohmann 19 | { 20 | namespace detail 21 | { 22 | //////////// 23 | // parser // 24 | //////////// 25 | 26 | enum class parse_event_t : std::uint8_t 27 | { 28 | /// the parser read `{` and started to process a JSON object 29 | object_start, 30 | /// the parser read `}` and finished processing a JSON object 31 | object_end, 32 | /// the parser read `[` and started to process a JSON array 33 | array_start, 34 | /// the parser read `]` and finished processing a JSON array 35 | array_end, 36 | /// the parser read a key of a value in an object 37 | key, 38 | /// the parser finished reading a JSON value 39 | value 40 | }; 41 | 42 | template 43 | using parser_callback_t = 44 | std::function; 45 | 46 | /*! 47 | @brief syntax analysis 48 | 49 | This class implements a recursive descent parser. 50 | */ 51 | template 52 | class parser 53 | { 54 | using number_integer_t = typename BasicJsonType::number_integer_t; 55 | using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 56 | using number_float_t = typename BasicJsonType::number_float_t; 57 | using string_t = typename BasicJsonType::string_t; 58 | using lexer_t = lexer; 59 | using token_type = typename lexer_t::token_type; 60 | 61 | public: 62 | /// a parser reading from an input adapter 63 | explicit parser(InputAdapterType&& adapter, 64 | const parser_callback_t cb = nullptr, 65 | const bool allow_exceptions_ = true, 66 | const bool skip_comments = false) 67 | : callback(cb) 68 | , m_lexer(std::move(adapter), skip_comments) 69 | , allow_exceptions(allow_exceptions_) 70 | { 71 | // read first token 72 | get_token(); 73 | } 74 | 75 | /*! 76 | @brief public parser interface 77 | 78 | @param[in] strict whether to expect the last token to be EOF 79 | @param[in,out] result parsed JSON value 80 | 81 | @throw parse_error.101 in case of an unexpected token 82 | @throw parse_error.102 if to_unicode fails or surrogate error 83 | @throw parse_error.103 if to_unicode fails 84 | */ 85 | void parse(const bool strict, BasicJsonType& result) 86 | { 87 | if (callback) 88 | { 89 | json_sax_dom_callback_parser sdp(result, callback, allow_exceptions); 90 | sax_parse_internal(&sdp); 91 | 92 | // in strict mode, input must be completely read 93 | if (strict && (get_token() != token_type::end_of_input)) 94 | { 95 | sdp.parse_error(m_lexer.get_position(), 96 | m_lexer.get_token_string(), 97 | parse_error::create(101, m_lexer.get_position(), 98 | exception_message(token_type::end_of_input, "value"), BasicJsonType())); 99 | } 100 | 101 | // in case of an error, return discarded value 102 | if (sdp.is_errored()) 103 | { 104 | result = value_t::discarded; 105 | return; 106 | } 107 | 108 | // set top-level value to null if it was discarded by the callback 109 | // function 110 | if (result.is_discarded()) 111 | { 112 | result = nullptr; 113 | } 114 | } 115 | else 116 | { 117 | json_sax_dom_parser sdp(result, allow_exceptions); 118 | sax_parse_internal(&sdp); 119 | 120 | // in strict mode, input must be completely read 121 | if (strict && (get_token() != token_type::end_of_input)) 122 | { 123 | sdp.parse_error(m_lexer.get_position(), 124 | m_lexer.get_token_string(), 125 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType())); 126 | } 127 | 128 | // in case of an error, return discarded value 129 | if (sdp.is_errored()) 130 | { 131 | result = value_t::discarded; 132 | return; 133 | } 134 | } 135 | 136 | result.assert_invariant(); 137 | } 138 | 139 | /*! 140 | @brief public accept interface 141 | 142 | @param[in] strict whether to expect the last token to be EOF 143 | @return whether the input is a proper JSON text 144 | */ 145 | bool accept(const bool strict = true) 146 | { 147 | json_sax_acceptor sax_acceptor; 148 | return sax_parse(&sax_acceptor, strict); 149 | } 150 | 151 | template 152 | JSON_HEDLEY_NON_NULL(2) 153 | bool sax_parse(SAX* sax, const bool strict = true) 154 | { 155 | (void)detail::is_sax_static_asserts {}; 156 | const bool result = sax_parse_internal(sax); 157 | 158 | // strict mode: next byte must be EOF 159 | if (result && strict && (get_token() != token_type::end_of_input)) 160 | { 161 | return sax->parse_error(m_lexer.get_position(), 162 | m_lexer.get_token_string(), 163 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType())); 164 | } 165 | 166 | return result; 167 | } 168 | 169 | private: 170 | template 171 | JSON_HEDLEY_NON_NULL(2) 172 | bool sax_parse_internal(SAX* sax) 173 | { 174 | // stack to remember the hierarchy of structured values we are parsing 175 | // true = array; false = object 176 | std::vector states; 177 | // value to avoid a goto (see comment where set to true) 178 | bool skip_to_state_evaluation = false; 179 | 180 | while (true) 181 | { 182 | if (!skip_to_state_evaluation) 183 | { 184 | // invariant: get_token() was called before each iteration 185 | switch (last_token) 186 | { 187 | case token_type::begin_object: 188 | { 189 | if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) 190 | { 191 | return false; 192 | } 193 | 194 | // closing } -> we are done 195 | if (get_token() == token_type::end_object) 196 | { 197 | if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) 198 | { 199 | return false; 200 | } 201 | break; 202 | } 203 | 204 | // parse key 205 | if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) 206 | { 207 | return sax->parse_error(m_lexer.get_position(), 208 | m_lexer.get_token_string(), 209 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType())); 210 | } 211 | if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) 212 | { 213 | return false; 214 | } 215 | 216 | // parse separator (:) 217 | if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) 218 | { 219 | return sax->parse_error(m_lexer.get_position(), 220 | m_lexer.get_token_string(), 221 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType())); 222 | } 223 | 224 | // remember we are now inside an object 225 | states.push_back(false); 226 | 227 | // parse values 228 | get_token(); 229 | continue; 230 | } 231 | 232 | case token_type::begin_array: 233 | { 234 | if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) 235 | { 236 | return false; 237 | } 238 | 239 | // closing ] -> we are done 240 | if (get_token() == token_type::end_array) 241 | { 242 | if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) 243 | { 244 | return false; 245 | } 246 | break; 247 | } 248 | 249 | // remember we are now inside an array 250 | states.push_back(true); 251 | 252 | // parse values (no need to call get_token) 253 | continue; 254 | } 255 | 256 | case token_type::value_float: 257 | { 258 | const auto res = m_lexer.get_number_float(); 259 | 260 | if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) 261 | { 262 | return sax->parse_error(m_lexer.get_position(), 263 | m_lexer.get_token_string(), 264 | out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType())); 265 | } 266 | 267 | if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) 268 | { 269 | return false; 270 | } 271 | 272 | break; 273 | } 274 | 275 | case token_type::literal_false: 276 | { 277 | if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) 278 | { 279 | return false; 280 | } 281 | break; 282 | } 283 | 284 | case token_type::literal_null: 285 | { 286 | if (JSON_HEDLEY_UNLIKELY(!sax->null())) 287 | { 288 | return false; 289 | } 290 | break; 291 | } 292 | 293 | case token_type::literal_true: 294 | { 295 | if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) 296 | { 297 | return false; 298 | } 299 | break; 300 | } 301 | 302 | case token_type::value_integer: 303 | { 304 | if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) 305 | { 306 | return false; 307 | } 308 | break; 309 | } 310 | 311 | case token_type::value_string: 312 | { 313 | if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) 314 | { 315 | return false; 316 | } 317 | break; 318 | } 319 | 320 | case token_type::value_unsigned: 321 | { 322 | if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) 323 | { 324 | return false; 325 | } 326 | break; 327 | } 328 | 329 | case token_type::parse_error: 330 | { 331 | // using "uninitialized" to avoid "expected" message 332 | return sax->parse_error(m_lexer.get_position(), 333 | m_lexer.get_token_string(), 334 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType())); 335 | } 336 | 337 | case token_type::uninitialized: 338 | case token_type::end_array: 339 | case token_type::end_object: 340 | case token_type::name_separator: 341 | case token_type::value_separator: 342 | case token_type::end_of_input: 343 | case token_type::literal_or_value: 344 | default: // the last token was unexpected 345 | { 346 | return sax->parse_error(m_lexer.get_position(), 347 | m_lexer.get_token_string(), 348 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType())); 349 | } 350 | } 351 | } 352 | else 353 | { 354 | skip_to_state_evaluation = false; 355 | } 356 | 357 | // we reached this line after we successfully parsed a value 358 | if (states.empty()) 359 | { 360 | // empty stack: we reached the end of the hierarchy: done 361 | return true; 362 | } 363 | 364 | if (states.back()) // array 365 | { 366 | // comma -> next value 367 | if (get_token() == token_type::value_separator) 368 | { 369 | // parse a new value 370 | get_token(); 371 | continue; 372 | } 373 | 374 | // closing ] 375 | if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) 376 | { 377 | if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) 378 | { 379 | return false; 380 | } 381 | 382 | // We are done with this array. Before we can parse a 383 | // new value, we need to evaluate the new state first. 384 | // By setting skip_to_state_evaluation to false, we 385 | // are effectively jumping to the beginning of this if. 386 | JSON_ASSERT(!states.empty()); 387 | states.pop_back(); 388 | skip_to_state_evaluation = true; 389 | continue; 390 | } 391 | 392 | return sax->parse_error(m_lexer.get_position(), 393 | m_lexer.get_token_string(), 394 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType())); 395 | } 396 | 397 | // states.back() is false -> object 398 | 399 | // comma -> next value 400 | if (get_token() == token_type::value_separator) 401 | { 402 | // parse key 403 | if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) 404 | { 405 | return sax->parse_error(m_lexer.get_position(), 406 | m_lexer.get_token_string(), 407 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType())); 408 | } 409 | 410 | if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) 411 | { 412 | return false; 413 | } 414 | 415 | // parse separator (:) 416 | if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) 417 | { 418 | return sax->parse_error(m_lexer.get_position(), 419 | m_lexer.get_token_string(), 420 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType())); 421 | } 422 | 423 | // parse values 424 | get_token(); 425 | continue; 426 | } 427 | 428 | // closing } 429 | if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) 430 | { 431 | if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) 432 | { 433 | return false; 434 | } 435 | 436 | // We are done with this object. Before we can parse a 437 | // new value, we need to evaluate the new state first. 438 | // By setting skip_to_state_evaluation to false, we 439 | // are effectively jumping to the beginning of this if. 440 | JSON_ASSERT(!states.empty()); 441 | states.pop_back(); 442 | skip_to_state_evaluation = true; 443 | continue; 444 | } 445 | 446 | return sax->parse_error(m_lexer.get_position(), 447 | m_lexer.get_token_string(), 448 | parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType())); 449 | } 450 | } 451 | 452 | /// get next token from lexer 453 | token_type get_token() 454 | { 455 | return last_token = m_lexer.scan(); 456 | } 457 | 458 | std::string exception_message(const token_type expected, const std::string& context) 459 | { 460 | std::string error_msg = "syntax error "; 461 | 462 | if (!context.empty()) 463 | { 464 | error_msg += "while parsing " + context + " "; 465 | } 466 | 467 | error_msg += "- "; 468 | 469 | if (last_token == token_type::parse_error) 470 | { 471 | error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" + 472 | m_lexer.get_token_string() + "'"; 473 | } 474 | else 475 | { 476 | error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token)); 477 | } 478 | 479 | if (expected != token_type::uninitialized) 480 | { 481 | error_msg += "; expected " + std::string(lexer_t::token_type_name(expected)); 482 | } 483 | 484 | return error_msg; 485 | } 486 | 487 | private: 488 | /// callback function 489 | const parser_callback_t callback = nullptr; 490 | /// the type of the last read token 491 | token_type last_token = token_type::uninitialized; 492 | /// the lexer 493 | lexer_t m_lexer; 494 | /// whether to throw exceptions in case of errors 495 | const bool allow_exceptions = true; 496 | }; 497 | 498 | } // namespace detail 499 | } // namespace nlohmann 500 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/input/position_t.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // size_t 4 | 5 | namespace nlohmann 6 | { 7 | namespace detail 8 | { 9 | /// struct to capture the start position of the current token 10 | struct position_t 11 | { 12 | /// the total number of characters read 13 | std::size_t chars_read_total = 0; 14 | /// the number of characters read in the current line 15 | std::size_t chars_read_current_line = 0; 16 | /// the number of lines read 17 | std::size_t lines_read = 0; 18 | 19 | /// conversion to size_t to preserve SAX interface 20 | constexpr operator size_t() const 21 | { 22 | return chars_read_total; 23 | } 24 | }; 25 | 26 | } // namespace detail 27 | } // namespace nlohmann 28 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/iterators/internal_iterator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace nlohmann 6 | { 7 | namespace detail 8 | { 9 | /*! 10 | @brief an iterator value 11 | 12 | @note This structure could easily be a union, but MSVC currently does not allow 13 | unions members with complex constructors, see https://github.com/nlohmann/json/pull/105. 14 | */ 15 | template struct internal_iterator 16 | { 17 | /// iterator for JSON objects 18 | typename BasicJsonType::object_t::iterator object_iterator {}; 19 | /// iterator for JSON arrays 20 | typename BasicJsonType::array_t::iterator array_iterator {}; 21 | /// generic iterator for all other types 22 | primitive_iterator_t primitive_iterator {}; 23 | }; 24 | } // namespace detail 25 | } // namespace nlohmann 26 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/iterators/iteration_proxy.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // size_t 4 | #include // input_iterator_tag 5 | #include // string, to_string 6 | #include // tuple_size, get, tuple_element 7 | #include // move 8 | 9 | #include 10 | #include 11 | 12 | namespace nlohmann 13 | { 14 | namespace detail 15 | { 16 | template 17 | void int_to_string( string_type& target, std::size_t value ) 18 | { 19 | // For ADL 20 | using std::to_string; 21 | target = to_string(value); 22 | } 23 | template class iteration_proxy_value 24 | { 25 | public: 26 | using difference_type = std::ptrdiff_t; 27 | using value_type = iteration_proxy_value; 28 | using pointer = value_type * ; 29 | using reference = value_type & ; 30 | using iterator_category = std::input_iterator_tag; 31 | using string_type = typename std::remove_cv< typename std::remove_reference().key() ) >::type >::type; 32 | 33 | private: 34 | /// the iterator 35 | IteratorType anchor; 36 | /// an index for arrays (used to create key names) 37 | std::size_t array_index = 0; 38 | /// last stringified array index 39 | mutable std::size_t array_index_last = 0; 40 | /// a string representation of the array index 41 | mutable string_type array_index_str = "0"; 42 | /// an empty string (to return a reference for primitive values) 43 | const string_type empty_str{}; 44 | 45 | public: 46 | explicit iteration_proxy_value(IteratorType it) noexcept 47 | : anchor(std::move(it)) 48 | {} 49 | 50 | /// dereference operator (needed for range-based for) 51 | iteration_proxy_value& operator*() 52 | { 53 | return *this; 54 | } 55 | 56 | /// increment operator (needed for range-based for) 57 | iteration_proxy_value& operator++() 58 | { 59 | ++anchor; 60 | ++array_index; 61 | 62 | return *this; 63 | } 64 | 65 | /// equality operator (needed for InputIterator) 66 | bool operator==(const iteration_proxy_value& o) const 67 | { 68 | return anchor == o.anchor; 69 | } 70 | 71 | /// inequality operator (needed for range-based for) 72 | bool operator!=(const iteration_proxy_value& o) const 73 | { 74 | return anchor != o.anchor; 75 | } 76 | 77 | /// return key of the iterator 78 | const string_type& key() const 79 | { 80 | JSON_ASSERT(anchor.m_object != nullptr); 81 | 82 | switch (anchor.m_object->type()) 83 | { 84 | // use integer array index as key 85 | case value_t::array: 86 | { 87 | if (array_index != array_index_last) 88 | { 89 | int_to_string( array_index_str, array_index ); 90 | array_index_last = array_index; 91 | } 92 | return array_index_str; 93 | } 94 | 95 | // use key from the object 96 | case value_t::object: 97 | return anchor.key(); 98 | 99 | // use an empty key for all primitive types 100 | case value_t::null: 101 | case value_t::string: 102 | case value_t::boolean: 103 | case value_t::number_integer: 104 | case value_t::number_unsigned: 105 | case value_t::number_float: 106 | case value_t::binary: 107 | case value_t::discarded: 108 | default: 109 | return empty_str; 110 | } 111 | } 112 | 113 | /// return value of the iterator 114 | typename IteratorType::reference value() const 115 | { 116 | return anchor.value(); 117 | } 118 | }; 119 | 120 | /// proxy class for the items() function 121 | template class iteration_proxy 122 | { 123 | private: 124 | /// the container to iterate 125 | typename IteratorType::reference container; 126 | 127 | public: 128 | /// construct iteration proxy from a container 129 | explicit iteration_proxy(typename IteratorType::reference cont) noexcept 130 | : container(cont) {} 131 | 132 | /// return iterator begin (needed for range-based for) 133 | iteration_proxy_value begin() noexcept 134 | { 135 | return iteration_proxy_value(container.begin()); 136 | } 137 | 138 | /// return iterator end (needed for range-based for) 139 | iteration_proxy_value end() noexcept 140 | { 141 | return iteration_proxy_value(container.end()); 142 | } 143 | }; 144 | // Structured Bindings Support 145 | // For further reference see https://blog.tartanllama.xyz/structured-bindings/ 146 | // And see https://github.com/nlohmann/json/pull/1391 147 | template = 0> 148 | auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.key()) 149 | { 150 | return i.key(); 151 | } 152 | // Structured Bindings Support 153 | // For further reference see https://blog.tartanllama.xyz/structured-bindings/ 154 | // And see https://github.com/nlohmann/json/pull/1391 155 | template = 0> 156 | auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.value()) 157 | { 158 | return i.value(); 159 | } 160 | } // namespace detail 161 | } // namespace nlohmann 162 | 163 | // The Addition to the STD Namespace is required to add 164 | // Structured Bindings Support to the iteration_proxy_value class 165 | // For further reference see https://blog.tartanllama.xyz/structured-bindings/ 166 | // And see https://github.com/nlohmann/json/pull/1391 167 | namespace std 168 | { 169 | #if defined(__clang__) 170 | // Fix: https://github.com/nlohmann/json/issues/1401 171 | #pragma clang diagnostic push 172 | #pragma clang diagnostic ignored "-Wmismatched-tags" 173 | #endif 174 | template 175 | class tuple_size<::nlohmann::detail::iteration_proxy_value> 176 | : public std::integral_constant {}; 177 | 178 | template 179 | class tuple_element> 180 | { 181 | public: 182 | using type = decltype( 183 | get(std::declval < 184 | ::nlohmann::detail::iteration_proxy_value> ())); 185 | }; 186 | #if defined(__clang__) 187 | #pragma clang diagnostic pop 188 | #endif 189 | } // namespace std 190 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/iterators/iterator_traits.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // random_access_iterator_tag 4 | 5 | #include 6 | #include 7 | 8 | namespace nlohmann 9 | { 10 | namespace detail 11 | { 12 | template 13 | struct iterator_types {}; 14 | 15 | template 16 | struct iterator_types < 17 | It, 18 | void_t> 20 | { 21 | using difference_type = typename It::difference_type; 22 | using value_type = typename It::value_type; 23 | using pointer = typename It::pointer; 24 | using reference = typename It::reference; 25 | using iterator_category = typename It::iterator_category; 26 | }; 27 | 28 | // This is required as some compilers implement std::iterator_traits in a way that 29 | // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. 30 | template 31 | struct iterator_traits 32 | { 33 | }; 34 | 35 | template 36 | struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> 37 | : iterator_types 38 | { 39 | }; 40 | 41 | template 42 | struct iterator_traits::value>> 43 | { 44 | using iterator_category = std::random_access_iterator_tag; 45 | using value_type = T; 46 | using difference_type = ptrdiff_t; 47 | using pointer = T*; 48 | using reference = T&; 49 | }; 50 | } // namespace detail 51 | } // namespace nlohmann 52 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/iterators/json_reverse_iterator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // ptrdiff_t 4 | #include // reverse_iterator 5 | #include // declval 6 | 7 | namespace nlohmann 8 | { 9 | namespace detail 10 | { 11 | ////////////////////// 12 | // reverse_iterator // 13 | ////////////////////// 14 | 15 | /*! 16 | @brief a template for a reverse iterator class 17 | 18 | @tparam Base the base iterator type to reverse. Valid types are @ref 19 | iterator (to create @ref reverse_iterator) and @ref const_iterator (to 20 | create @ref const_reverse_iterator). 21 | 22 | @requirement The class satisfies the following concept requirements: 23 | - 24 | [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): 25 | The iterator that can be moved can be moved in both directions (i.e. 26 | incremented and decremented). 27 | - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator): 28 | It is possible to write to the pointed-to element (only if @a Base is 29 | @ref iterator). 30 | 31 | @since version 1.0.0 32 | */ 33 | template 34 | class json_reverse_iterator : public std::reverse_iterator 35 | { 36 | public: 37 | using difference_type = std::ptrdiff_t; 38 | /// shortcut to the reverse iterator adapter 39 | using base_iterator = std::reverse_iterator; 40 | /// the reference type for the pointed-to element 41 | using reference = typename Base::reference; 42 | 43 | /// create reverse iterator from iterator 44 | explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept 45 | : base_iterator(it) {} 46 | 47 | /// create reverse iterator from base class 48 | explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} 49 | 50 | /// post-increment (it++) 51 | json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type) 52 | { 53 | return static_cast(base_iterator::operator++(1)); 54 | } 55 | 56 | /// pre-increment (++it) 57 | json_reverse_iterator& operator++() 58 | { 59 | return static_cast(base_iterator::operator++()); 60 | } 61 | 62 | /// post-decrement (it--) 63 | json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type) 64 | { 65 | return static_cast(base_iterator::operator--(1)); 66 | } 67 | 68 | /// pre-decrement (--it) 69 | json_reverse_iterator& operator--() 70 | { 71 | return static_cast(base_iterator::operator--()); 72 | } 73 | 74 | /// add to iterator 75 | json_reverse_iterator& operator+=(difference_type i) 76 | { 77 | return static_cast(base_iterator::operator+=(i)); 78 | } 79 | 80 | /// add to iterator 81 | json_reverse_iterator operator+(difference_type i) const 82 | { 83 | return static_cast(base_iterator::operator+(i)); 84 | } 85 | 86 | /// subtract from iterator 87 | json_reverse_iterator operator-(difference_type i) const 88 | { 89 | return static_cast(base_iterator::operator-(i)); 90 | } 91 | 92 | /// return difference 93 | difference_type operator-(const json_reverse_iterator& other) const 94 | { 95 | return base_iterator(*this) - base_iterator(other); 96 | } 97 | 98 | /// access to successor 99 | reference operator[](difference_type n) const 100 | { 101 | return *(this->operator+(n)); 102 | } 103 | 104 | /// return the key of an object iterator 105 | auto key() const -> decltype(std::declval().key()) 106 | { 107 | auto it = --this->base(); 108 | return it.key(); 109 | } 110 | 111 | /// return the value of an iterator 112 | reference value() const 113 | { 114 | auto it = --this->base(); 115 | return it.operator * (); 116 | } 117 | }; 118 | } // namespace detail 119 | } // namespace nlohmann 120 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/iterators/primitive_iterator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // ptrdiff_t 4 | #include // numeric_limits 5 | 6 | #include 7 | 8 | namespace nlohmann 9 | { 10 | namespace detail 11 | { 12 | /* 13 | @brief an iterator for primitive JSON types 14 | 15 | This class models an iterator for primitive JSON types (boolean, number, 16 | string). It's only purpose is to allow the iterator/const_iterator classes 17 | to "iterate" over primitive values. Internally, the iterator is modeled by 18 | a `difference_type` variable. Value begin_value (`0`) models the begin, 19 | end_value (`1`) models past the end. 20 | */ 21 | class primitive_iterator_t 22 | { 23 | private: 24 | using difference_type = std::ptrdiff_t; 25 | static constexpr difference_type begin_value = 0; 26 | static constexpr difference_type end_value = begin_value + 1; 27 | 28 | JSON_PRIVATE_UNLESS_TESTED: 29 | /// iterator as signed integer type 30 | difference_type m_it = (std::numeric_limits::min)(); 31 | 32 | public: 33 | constexpr difference_type get_value() const noexcept 34 | { 35 | return m_it; 36 | } 37 | 38 | /// set iterator to a defined beginning 39 | void set_begin() noexcept 40 | { 41 | m_it = begin_value; 42 | } 43 | 44 | /// set iterator to a defined past the end 45 | void set_end() noexcept 46 | { 47 | m_it = end_value; 48 | } 49 | 50 | /// return whether the iterator can be dereferenced 51 | constexpr bool is_begin() const noexcept 52 | { 53 | return m_it == begin_value; 54 | } 55 | 56 | /// return whether the iterator is at end 57 | constexpr bool is_end() const noexcept 58 | { 59 | return m_it == end_value; 60 | } 61 | 62 | friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept 63 | { 64 | return lhs.m_it == rhs.m_it; 65 | } 66 | 67 | friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept 68 | { 69 | return lhs.m_it < rhs.m_it; 70 | } 71 | 72 | primitive_iterator_t operator+(difference_type n) noexcept 73 | { 74 | auto result = *this; 75 | result += n; 76 | return result; 77 | } 78 | 79 | friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept 80 | { 81 | return lhs.m_it - rhs.m_it; 82 | } 83 | 84 | primitive_iterator_t& operator++() noexcept 85 | { 86 | ++m_it; 87 | return *this; 88 | } 89 | 90 | primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type) 91 | { 92 | auto result = *this; 93 | ++m_it; 94 | return result; 95 | } 96 | 97 | primitive_iterator_t& operator--() noexcept 98 | { 99 | --m_it; 100 | return *this; 101 | } 102 | 103 | primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type) 104 | { 105 | auto result = *this; 106 | --m_it; 107 | return result; 108 | } 109 | 110 | primitive_iterator_t& operator+=(difference_type n) noexcept 111 | { 112 | m_it += n; 113 | return *this; 114 | } 115 | 116 | primitive_iterator_t& operator-=(difference_type n) noexcept 117 | { 118 | m_it -= n; 119 | return *this; 120 | } 121 | }; 122 | } // namespace detail 123 | } // namespace nlohmann 124 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/json_ref.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | namespace nlohmann 9 | { 10 | namespace detail 11 | { 12 | template 13 | class json_ref 14 | { 15 | public: 16 | using value_type = BasicJsonType; 17 | 18 | json_ref(value_type&& value) 19 | : owned_value(std::move(value)) 20 | {} 21 | 22 | json_ref(const value_type& value) 23 | : value_ref(&value) 24 | {} 25 | 26 | json_ref(std::initializer_list init) 27 | : owned_value(init) 28 | {} 29 | 30 | template < 31 | class... Args, 32 | enable_if_t::value, int> = 0 > 33 | json_ref(Args && ... args) 34 | : owned_value(std::forward(args)...) 35 | {} 36 | 37 | // class should be movable only 38 | json_ref(json_ref&&) noexcept = default; 39 | json_ref(const json_ref&) = delete; 40 | json_ref& operator=(const json_ref&) = delete; 41 | json_ref& operator=(json_ref&&) = delete; 42 | ~json_ref() = default; 43 | 44 | value_type moved_or_copied() const 45 | { 46 | if (value_ref == nullptr) 47 | { 48 | return std::move(owned_value); 49 | } 50 | return *value_ref; 51 | } 52 | 53 | value_type const& operator*() const 54 | { 55 | return value_ref ? *value_ref : owned_value; 56 | } 57 | 58 | value_type const* operator->() const 59 | { 60 | return &** this; 61 | } 62 | 63 | private: 64 | mutable value_type owned_value = nullptr; 65 | value_type const* value_ref = nullptr; 66 | }; 67 | } // namespace detail 68 | } // namespace nlohmann 69 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/macro_unscope.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // restore clang diagnostic settings 4 | #if defined(__clang__) 5 | #pragma clang diagnostic pop 6 | #endif 7 | 8 | // clean up 9 | #undef JSON_ASSERT 10 | #undef JSON_INTERNAL_CATCH 11 | #undef JSON_CATCH 12 | #undef JSON_THROW 13 | #undef JSON_TRY 14 | #undef JSON_PRIVATE_UNLESS_TESTED 15 | #undef JSON_HAS_CPP_11 16 | #undef JSON_HAS_CPP_14 17 | #undef JSON_HAS_CPP_17 18 | #undef JSON_HAS_CPP_20 19 | #undef JSON_HAS_FILESYSTEM 20 | #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM 21 | #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 22 | #undef NLOHMANN_BASIC_JSON_TPL 23 | #undef JSON_EXPLICIT 24 | #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL 25 | 26 | #include 27 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/meta/call_std/begin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace nlohmann 6 | { 7 | NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); 8 | } // namespace nlohmann 9 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/meta/call_std/end.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace nlohmann 6 | { 7 | NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); 8 | } // namespace nlohmann 9 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/meta/cpp_future.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // size_t 4 | #include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type 5 | #include // index_sequence, make_index_sequence, index_sequence_for 6 | 7 | #include 8 | 9 | namespace nlohmann 10 | { 11 | namespace detail 12 | { 13 | 14 | template 15 | using uncvref_t = typename std::remove_cv::type>::type; 16 | 17 | #ifdef JSON_HAS_CPP_14 18 | 19 | // the following utilities are natively available in C++14 20 | using std::enable_if_t; 21 | using std::index_sequence; 22 | using std::make_index_sequence; 23 | using std::index_sequence_for; 24 | 25 | #else 26 | 27 | // alias templates to reduce boilerplate 28 | template 29 | using enable_if_t = typename std::enable_if::type; 30 | 31 | // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h 32 | // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. 33 | 34 | //// START OF CODE FROM GOOGLE ABSEIL 35 | 36 | // integer_sequence 37 | // 38 | // Class template representing a compile-time integer sequence. An instantiation 39 | // of `integer_sequence` has a sequence of integers encoded in its 40 | // type through its template arguments (which is a common need when 41 | // working with C++11 variadic templates). `absl::integer_sequence` is designed 42 | // to be a drop-in replacement for C++14's `std::integer_sequence`. 43 | // 44 | // Example: 45 | // 46 | // template< class T, T... Ints > 47 | // void user_function(integer_sequence); 48 | // 49 | // int main() 50 | // { 51 | // // user_function's `T` will be deduced to `int` and `Ints...` 52 | // // will be deduced to `0, 1, 2, 3, 4`. 53 | // user_function(make_integer_sequence()); 54 | // } 55 | template 56 | struct integer_sequence 57 | { 58 | using value_type = T; 59 | static constexpr std::size_t size() noexcept 60 | { 61 | return sizeof...(Ints); 62 | } 63 | }; 64 | 65 | // index_sequence 66 | // 67 | // A helper template for an `integer_sequence` of `size_t`, 68 | // `absl::index_sequence` is designed to be a drop-in replacement for C++14's 69 | // `std::index_sequence`. 70 | template 71 | using index_sequence = integer_sequence; 72 | 73 | namespace utility_internal 74 | { 75 | 76 | template 77 | struct Extend; 78 | 79 | // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. 80 | template 81 | struct Extend, SeqSize, 0> 82 | { 83 | using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; 84 | }; 85 | 86 | template 87 | struct Extend, SeqSize, 1> 88 | { 89 | using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; 90 | }; 91 | 92 | // Recursion helper for 'make_integer_sequence'. 93 | // 'Gen::type' is an alias for 'integer_sequence'. 94 | template 95 | struct Gen 96 | { 97 | using type = 98 | typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; 99 | }; 100 | 101 | template 102 | struct Gen 103 | { 104 | using type = integer_sequence; 105 | }; 106 | 107 | } // namespace utility_internal 108 | 109 | // Compile-time sequences of integers 110 | 111 | // make_integer_sequence 112 | // 113 | // This template alias is equivalent to 114 | // `integer_sequence`, and is designed to be a drop-in 115 | // replacement for C++14's `std::make_integer_sequence`. 116 | template 117 | using make_integer_sequence = typename utility_internal::Gen::type; 118 | 119 | // make_index_sequence 120 | // 121 | // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, 122 | // and is designed to be a drop-in replacement for C++14's 123 | // `std::make_index_sequence`. 124 | template 125 | using make_index_sequence = make_integer_sequence; 126 | 127 | // index_sequence_for 128 | // 129 | // Converts a typename pack into an index sequence of the same length, and 130 | // is designed to be a drop-in replacement for C++14's 131 | // `std::index_sequence_for()` 132 | template 133 | using index_sequence_for = make_index_sequence; 134 | 135 | //// END OF CODE FROM GOOGLE ABSEIL 136 | 137 | #endif 138 | 139 | // dispatch utility (taken from ranges-v3) 140 | template struct priority_tag : priority_tag < N - 1 > {}; 141 | template<> struct priority_tag<0> {}; 142 | 143 | // taken from ranges-v3 144 | template 145 | struct static_const 146 | { 147 | static constexpr T value{}; 148 | }; 149 | 150 | template 151 | constexpr T static_const::value; // NOLINT(readability-redundant-declaration) 152 | 153 | } // namespace detail 154 | } // namespace nlohmann 155 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/meta/detected.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | // https://en.cppreference.com/w/cpp/experimental/is_detected 8 | namespace nlohmann 9 | { 10 | namespace detail 11 | { 12 | struct nonesuch 13 | { 14 | nonesuch() = delete; 15 | ~nonesuch() = delete; 16 | nonesuch(nonesuch const&) = delete; 17 | nonesuch(nonesuch const&&) = delete; 18 | void operator=(nonesuch const&) = delete; 19 | void operator=(nonesuch&&) = delete; 20 | }; 21 | 22 | template class Op, 25 | class... Args> 26 | struct detector 27 | { 28 | using value_t = std::false_type; 29 | using type = Default; 30 | }; 31 | 32 | template class Op, class... Args> 33 | struct detector>, Op, Args...> 34 | { 35 | using value_t = std::true_type; 36 | using type = Op; 37 | }; 38 | 39 | template class Op, class... Args> 40 | using is_detected = typename detector::value_t; 41 | 42 | template class Op, class... Args> 43 | struct is_detected_lazy : is_detected { }; 44 | 45 | template class Op, class... Args> 46 | using detected_t = typename detector::type; 47 | 48 | template class Op, class... Args> 49 | using detected_or = detector; 50 | 51 | template class Op, class... Args> 52 | using detected_or_t = typename detected_or::type; 53 | 54 | template class Op, class... Args> 55 | using is_detected_exact = std::is_same>; 56 | 57 | template class Op, class... Args> 58 | using is_detected_convertible = 59 | std::is_convertible, To>; 60 | } // namespace detail 61 | } // namespace nlohmann 62 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/meta/identity_tag.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace nlohmann 4 | { 5 | namespace detail 6 | { 7 | // dispatching helper struct 8 | template struct identity_tag {}; 9 | } // namespace detail 10 | } // namespace nlohmann 11 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/meta/is_sax.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // size_t 4 | #include // declval 5 | #include // string 6 | 7 | #include 8 | #include 9 | 10 | namespace nlohmann 11 | { 12 | namespace detail 13 | { 14 | template 15 | using null_function_t = decltype(std::declval().null()); 16 | 17 | template 18 | using boolean_function_t = 19 | decltype(std::declval().boolean(std::declval())); 20 | 21 | template 22 | using number_integer_function_t = 23 | decltype(std::declval().number_integer(std::declval())); 24 | 25 | template 26 | using number_unsigned_function_t = 27 | decltype(std::declval().number_unsigned(std::declval())); 28 | 29 | template 30 | using number_float_function_t = decltype(std::declval().number_float( 31 | std::declval(), std::declval())); 32 | 33 | template 34 | using string_function_t = 35 | decltype(std::declval().string(std::declval())); 36 | 37 | template 38 | using binary_function_t = 39 | decltype(std::declval().binary(std::declval())); 40 | 41 | template 42 | using start_object_function_t = 43 | decltype(std::declval().start_object(std::declval())); 44 | 45 | template 46 | using key_function_t = 47 | decltype(std::declval().key(std::declval())); 48 | 49 | template 50 | using end_object_function_t = decltype(std::declval().end_object()); 51 | 52 | template 53 | using start_array_function_t = 54 | decltype(std::declval().start_array(std::declval())); 55 | 56 | template 57 | using end_array_function_t = decltype(std::declval().end_array()); 58 | 59 | template 60 | using parse_error_function_t = decltype(std::declval().parse_error( 61 | std::declval(), std::declval(), 62 | std::declval())); 63 | 64 | template 65 | struct is_sax 66 | { 67 | private: 68 | static_assert(is_basic_json::value, 69 | "BasicJsonType must be of type basic_json<...>"); 70 | 71 | using number_integer_t = typename BasicJsonType::number_integer_t; 72 | using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 73 | using number_float_t = typename BasicJsonType::number_float_t; 74 | using string_t = typename BasicJsonType::string_t; 75 | using binary_t = typename BasicJsonType::binary_t; 76 | using exception_t = typename BasicJsonType::exception; 77 | 78 | public: 79 | static constexpr bool value = 80 | is_detected_exact::value && 81 | is_detected_exact::value && 82 | is_detected_exact::value && 83 | is_detected_exact::value && 84 | is_detected_exact::value && 85 | is_detected_exact::value && 86 | is_detected_exact::value && 87 | is_detected_exact::value && 88 | is_detected_exact::value && 89 | is_detected_exact::value && 90 | is_detected_exact::value && 91 | is_detected_exact::value && 92 | is_detected_exact::value; 93 | }; 94 | 95 | template 96 | struct is_sax_static_asserts 97 | { 98 | private: 99 | static_assert(is_basic_json::value, 100 | "BasicJsonType must be of type basic_json<...>"); 101 | 102 | using number_integer_t = typename BasicJsonType::number_integer_t; 103 | using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 104 | using number_float_t = typename BasicJsonType::number_float_t; 105 | using string_t = typename BasicJsonType::string_t; 106 | using binary_t = typename BasicJsonType::binary_t; 107 | using exception_t = typename BasicJsonType::exception; 108 | 109 | public: 110 | static_assert(is_detected_exact::value, 111 | "Missing/invalid function: bool null()"); 112 | static_assert(is_detected_exact::value, 113 | "Missing/invalid function: bool boolean(bool)"); 114 | static_assert(is_detected_exact::value, 115 | "Missing/invalid function: bool boolean(bool)"); 116 | static_assert( 117 | is_detected_exact::value, 119 | "Missing/invalid function: bool number_integer(number_integer_t)"); 120 | static_assert( 121 | is_detected_exact::value, 123 | "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); 124 | static_assert(is_detected_exact::value, 126 | "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); 127 | static_assert( 128 | is_detected_exact::value, 129 | "Missing/invalid function: bool string(string_t&)"); 130 | static_assert( 131 | is_detected_exact::value, 132 | "Missing/invalid function: bool binary(binary_t&)"); 133 | static_assert(is_detected_exact::value, 134 | "Missing/invalid function: bool start_object(std::size_t)"); 135 | static_assert(is_detected_exact::value, 136 | "Missing/invalid function: bool key(string_t&)"); 137 | static_assert(is_detected_exact::value, 138 | "Missing/invalid function: bool end_object()"); 139 | static_assert(is_detected_exact::value, 140 | "Missing/invalid function: bool start_array(std::size_t)"); 141 | static_assert(is_detected_exact::value, 142 | "Missing/invalid function: bool end_array()"); 143 | static_assert( 144 | is_detected_exact::value, 145 | "Missing/invalid function: bool parse_error(std::size_t, const " 146 | "std::string&, const exception&)"); 147 | }; 148 | } // namespace detail 149 | } // namespace nlohmann 150 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/meta/type_traits.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // numeric_limits 4 | #include // false_type, is_constructible, is_integral, is_same, true_type 5 | #include // declval 6 | #include // tuple 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace nlohmann 18 | { 19 | /*! 20 | @brief detail namespace with internal helper functions 21 | 22 | This namespace collects functions that should not be exposed, 23 | implementations of some @ref basic_json methods, and meta-programming helpers. 24 | 25 | @since version 2.1.0 26 | */ 27 | namespace detail 28 | { 29 | ///////////// 30 | // helpers // 31 | ///////////// 32 | 33 | // Note to maintainers: 34 | // 35 | // Every trait in this file expects a non CV-qualified type. 36 | // The only exceptions are in the 'aliases for detected' section 37 | // (i.e. those of the form: decltype(T::member_function(std::declval()))) 38 | // 39 | // In this case, T has to be properly CV-qualified to constraint the function arguments 40 | // (e.g. to_json(BasicJsonType&, const T&)) 41 | 42 | template struct is_basic_json : std::false_type {}; 43 | 44 | NLOHMANN_BASIC_JSON_TPL_DECLARATION 45 | struct is_basic_json : std::true_type {}; 46 | 47 | ////////////////////// 48 | // json_ref helpers // 49 | ////////////////////// 50 | 51 | template 52 | class json_ref; 53 | 54 | template 55 | struct is_json_ref : std::false_type {}; 56 | 57 | template 58 | struct is_json_ref> : std::true_type {}; 59 | 60 | ////////////////////////// 61 | // aliases for detected // 62 | ////////////////////////// 63 | 64 | template 65 | using mapped_type_t = typename T::mapped_type; 66 | 67 | template 68 | using key_type_t = typename T::key_type; 69 | 70 | template 71 | using value_type_t = typename T::value_type; 72 | 73 | template 74 | using difference_type_t = typename T::difference_type; 75 | 76 | template 77 | using pointer_t = typename T::pointer; 78 | 79 | template 80 | using reference_t = typename T::reference; 81 | 82 | template 83 | using iterator_category_t = typename T::iterator_category; 84 | 85 | template 86 | using to_json_function = decltype(T::to_json(std::declval()...)); 87 | 88 | template 89 | using from_json_function = decltype(T::from_json(std::declval()...)); 90 | 91 | template 92 | using get_template_function = decltype(std::declval().template get()); 93 | 94 | // trait checking if JSONSerializer::from_json(json const&, udt&) exists 95 | template 96 | struct has_from_json : std::false_type {}; 97 | 98 | // trait checking if j.get is valid 99 | // use this trait instead of std::is_constructible or std::is_convertible, 100 | // both rely on, or make use of implicit conversions, and thus fail when T 101 | // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) 102 | template 103 | struct is_getable 104 | { 105 | static constexpr bool value = is_detected::value; 106 | }; 107 | 108 | template 109 | struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> 110 | { 111 | using serializer = typename BasicJsonType::template json_serializer; 112 | 113 | static constexpr bool value = 114 | is_detected_exact::value; 116 | }; 117 | 118 | // This trait checks if JSONSerializer::from_json(json const&) exists 119 | // this overload is used for non-default-constructible user-defined-types 120 | template 121 | struct has_non_default_from_json : std::false_type {}; 122 | 123 | template 124 | struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> 125 | { 126 | using serializer = typename BasicJsonType::template json_serializer; 127 | 128 | static constexpr bool value = 129 | is_detected_exact::value; 131 | }; 132 | 133 | // This trait checks if BasicJsonType::json_serializer::to_json exists 134 | // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. 135 | template 136 | struct has_to_json : std::false_type {}; 137 | 138 | template 139 | struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> 140 | { 141 | using serializer = typename BasicJsonType::template json_serializer; 142 | 143 | static constexpr bool value = 144 | is_detected_exact::value; 146 | }; 147 | 148 | 149 | /////////////////// 150 | // is_ functions // 151 | /////////////////// 152 | 153 | // https://en.cppreference.com/w/cpp/types/conjunction 154 | template struct conjunction : std::true_type { }; 155 | template struct conjunction : B1 { }; 156 | template 157 | struct conjunction 158 | : std::conditional, B1>::type {}; 159 | 160 | // https://en.cppreference.com/w/cpp/types/negation 161 | template struct negation : std::integral_constant < bool, !B::value > { }; 162 | 163 | // Reimplementation of is_constructible and is_default_constructible, due to them being broken for 164 | // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). 165 | // This causes compile errors in e.g. clang 3.5 or gcc 4.9. 166 | template 167 | struct is_default_constructible : std::is_default_constructible {}; 168 | 169 | template 170 | struct is_default_constructible> 171 | : conjunction, is_default_constructible> {}; 172 | 173 | template 174 | struct is_default_constructible> 175 | : conjunction, is_default_constructible> {}; 176 | 177 | template 178 | struct is_default_constructible> 179 | : conjunction...> {}; 180 | 181 | template 182 | struct is_default_constructible> 183 | : conjunction...> {}; 184 | 185 | 186 | template 187 | struct is_constructible : std::is_constructible {}; 188 | 189 | template 190 | struct is_constructible> : is_default_constructible> {}; 191 | 192 | template 193 | struct is_constructible> : is_default_constructible> {}; 194 | 195 | template 196 | struct is_constructible> : is_default_constructible> {}; 197 | 198 | template 199 | struct is_constructible> : is_default_constructible> {}; 200 | 201 | 202 | template 203 | struct is_iterator_traits : std::false_type {}; 204 | 205 | template 206 | struct is_iterator_traits> 207 | { 208 | private: 209 | using traits = iterator_traits; 210 | 211 | public: 212 | static constexpr auto value = 213 | is_detected::value && 214 | is_detected::value && 215 | is_detected::value && 216 | is_detected::value && 217 | is_detected::value; 218 | }; 219 | 220 | template 221 | struct is_range 222 | { 223 | private: 224 | using t_ref = typename std::add_lvalue_reference::type; 225 | 226 | using iterator = detected_t; 227 | using sentinel = detected_t; 228 | 229 | // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator 230 | // and https://en.cppreference.com/w/cpp/iterator/sentinel_for 231 | // but reimplementing these would be too much work, as a lot of other concepts are used underneath 232 | static constexpr auto is_iterator_begin = 233 | is_iterator_traits>::value; 234 | 235 | public: 236 | static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; 237 | }; 238 | 239 | template 240 | using iterator_t = enable_if_t::value, result_of_begin())>>; 241 | 242 | template 243 | using range_value_t = value_type_t>>; 244 | 245 | // The following implementation of is_complete_type is taken from 246 | // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ 247 | // and is written by Xiang Fan who agreed to using it in this library. 248 | 249 | template 250 | struct is_complete_type : std::false_type {}; 251 | 252 | template 253 | struct is_complete_type : std::true_type {}; 254 | 255 | template 257 | struct is_compatible_object_type_impl : std::false_type {}; 258 | 259 | template 260 | struct is_compatible_object_type_impl < 261 | BasicJsonType, CompatibleObjectType, 262 | enable_if_t < is_detected::value&& 263 | is_detected::value >> 264 | { 265 | using object_t = typename BasicJsonType::object_t; 266 | 267 | // macOS's is_constructible does not play well with nonesuch... 268 | static constexpr bool value = 269 | is_constructible::value && 271 | is_constructible::value; 273 | }; 274 | 275 | template 276 | struct is_compatible_object_type 277 | : is_compatible_object_type_impl {}; 278 | 279 | template 281 | struct is_constructible_object_type_impl : std::false_type {}; 282 | 283 | template 284 | struct is_constructible_object_type_impl < 285 | BasicJsonType, ConstructibleObjectType, 286 | enable_if_t < is_detected::value&& 287 | is_detected::value >> 288 | { 289 | using object_t = typename BasicJsonType::object_t; 290 | 291 | static constexpr bool value = 292 | (is_default_constructible::value && 293 | (std::is_move_assignable::value || 294 | std::is_copy_assignable::value) && 295 | (is_constructible::value && 297 | std::is_same < 298 | typename object_t::mapped_type, 299 | typename ConstructibleObjectType::mapped_type >::value)) || 300 | (has_from_json::value || 302 | has_non_default_from_json < 303 | BasicJsonType, 304 | typename ConstructibleObjectType::mapped_type >::value); 305 | }; 306 | 307 | template 308 | struct is_constructible_object_type 309 | : is_constructible_object_type_impl {}; 311 | 312 | template 313 | struct is_compatible_string_type 314 | { 315 | static constexpr auto value = 316 | is_constructible::value; 317 | }; 318 | 319 | template 320 | struct is_constructible_string_type 321 | { 322 | static constexpr auto value = 323 | is_constructible::value; 325 | }; 326 | 327 | template 328 | struct is_compatible_array_type_impl : std::false_type {}; 329 | 330 | template 331 | struct is_compatible_array_type_impl < 332 | BasicJsonType, CompatibleArrayType, 333 | enable_if_t < 334 | is_detected::value&& 335 | is_iterator_traits>>::value&& 336 | // special case for types like std::filesystem::path whose iterator's value_type are themselves 337 | // c.f. https://github.com/nlohmann/json/pull/3073 338 | !std::is_same>::value >> 339 | { 340 | static constexpr bool value = 341 | is_constructible>::value; 343 | }; 344 | 345 | template 346 | struct is_compatible_array_type 347 | : is_compatible_array_type_impl {}; 348 | 349 | template 350 | struct is_constructible_array_type_impl : std::false_type {}; 351 | 352 | template 353 | struct is_constructible_array_type_impl < 354 | BasicJsonType, ConstructibleArrayType, 355 | enable_if_t::value >> 357 | : std::true_type {}; 358 | 359 | template 360 | struct is_constructible_array_type_impl < 361 | BasicJsonType, ConstructibleArrayType, 362 | enable_if_t < !std::is_same::value&& 364 | !is_compatible_string_type::value&& 365 | is_default_constructible::value&& 366 | (std::is_move_assignable::value || 367 | std::is_copy_assignable::value)&& 368 | is_detected::value&& 369 | is_iterator_traits>>::value&& 370 | is_detected::value&& 371 | // special case for types like std::filesystem::path whose iterator's value_type are themselves 372 | // c.f. https://github.com/nlohmann/json/pull/3073 373 | !std::is_same>::value&& 374 | is_complete_type < 375 | detected_t>::value >> 376 | { 377 | using value_type = range_value_t; 378 | 379 | static constexpr bool value = 380 | std::is_same::value || 382 | has_from_json::value || 384 | has_non_default_from_json < 385 | BasicJsonType, 386 | value_type >::value; 387 | }; 388 | 389 | template 390 | struct is_constructible_array_type 391 | : is_constructible_array_type_impl {}; 392 | 393 | template 395 | struct is_compatible_integer_type_impl : std::false_type {}; 396 | 397 | template 398 | struct is_compatible_integer_type_impl < 399 | RealIntegerType, CompatibleNumberIntegerType, 400 | enable_if_t < std::is_integral::value&& 401 | std::is_integral::value&& 402 | !std::is_same::value >> 403 | { 404 | // is there an assert somewhere on overflows? 405 | using RealLimits = std::numeric_limits; 406 | using CompatibleLimits = std::numeric_limits; 407 | 408 | static constexpr auto value = 409 | is_constructible::value && 411 | CompatibleLimits::is_integer && 412 | RealLimits::is_signed == CompatibleLimits::is_signed; 413 | }; 414 | 415 | template 416 | struct is_compatible_integer_type 417 | : is_compatible_integer_type_impl {}; 419 | 420 | template 421 | struct is_compatible_type_impl: std::false_type {}; 422 | 423 | template 424 | struct is_compatible_type_impl < 425 | BasicJsonType, CompatibleType, 426 | enable_if_t::value >> 427 | { 428 | static constexpr bool value = 429 | has_to_json::value; 430 | }; 431 | 432 | template 433 | struct is_compatible_type 434 | : is_compatible_type_impl {}; 435 | 436 | template 437 | struct is_constructible_tuple : std::false_type {}; 438 | 439 | template 440 | struct is_constructible_tuple> : conjunction...> {}; 441 | 442 | // a naive helper to check if a type is an ordered_map (exploits the fact that 443 | // ordered_map inherits capacity() from std::vector) 444 | template 445 | struct is_ordered_map 446 | { 447 | using one = char; 448 | 449 | struct two 450 | { 451 | char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 452 | }; 453 | 454 | template static one test( decltype(&C::capacity) ) ; 455 | template static two test(...); 456 | 457 | enum { value = sizeof(test(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) 458 | }; 459 | 460 | // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324) 461 | template < typename T, typename U, enable_if_t < !std::is_same::value, int > = 0 > 462 | T conditional_static_cast(U value) 463 | { 464 | return static_cast(value); 465 | } 466 | 467 | template::value, int> = 0> 468 | T conditional_static_cast(U value) 469 | { 470 | return value; 471 | } 472 | 473 | } // namespace detail 474 | } // namespace nlohmann 475 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/meta/void_t.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace nlohmann 4 | { 5 | namespace detail 6 | { 7 | template struct make_void 8 | { 9 | using type = void; 10 | }; 11 | template using void_t = typename make_void::type; 12 | } // namespace detail 13 | } // namespace nlohmann 14 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/output/output_adapters.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // copy 4 | #include // size_t 5 | #include // back_inserter 6 | #include // shared_ptr, make_shared 7 | #include // basic_string 8 | #include // vector 9 | 10 | #ifndef JSON_NO_IO 11 | #include // streamsize 12 | #include // basic_ostream 13 | #endif // JSON_NO_IO 14 | 15 | #include 16 | 17 | namespace nlohmann 18 | { 19 | namespace detail 20 | { 21 | /// abstract output adapter interface 22 | template struct output_adapter_protocol 23 | { 24 | virtual void write_character(CharType c) = 0; 25 | virtual void write_characters(const CharType* s, std::size_t length) = 0; 26 | virtual ~output_adapter_protocol() = default; 27 | 28 | output_adapter_protocol() = default; 29 | output_adapter_protocol(const output_adapter_protocol&) = default; 30 | output_adapter_protocol(output_adapter_protocol&&) noexcept = default; 31 | output_adapter_protocol& operator=(const output_adapter_protocol&) = default; 32 | output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default; 33 | }; 34 | 35 | /// a type to simplify interfaces 36 | template 37 | using output_adapter_t = std::shared_ptr>; 38 | 39 | /// output adapter for byte vectors 40 | template> 41 | class output_vector_adapter : public output_adapter_protocol 42 | { 43 | public: 44 | explicit output_vector_adapter(std::vector& vec) noexcept 45 | : v(vec) 46 | {} 47 | 48 | void write_character(CharType c) override 49 | { 50 | v.push_back(c); 51 | } 52 | 53 | JSON_HEDLEY_NON_NULL(2) 54 | void write_characters(const CharType* s, std::size_t length) override 55 | { 56 | std::copy(s, s + length, std::back_inserter(v)); 57 | } 58 | 59 | private: 60 | std::vector& v; 61 | }; 62 | 63 | #ifndef JSON_NO_IO 64 | /// output adapter for output streams 65 | template 66 | class output_stream_adapter : public output_adapter_protocol 67 | { 68 | public: 69 | explicit output_stream_adapter(std::basic_ostream& s) noexcept 70 | : stream(s) 71 | {} 72 | 73 | void write_character(CharType c) override 74 | { 75 | stream.put(c); 76 | } 77 | 78 | JSON_HEDLEY_NON_NULL(2) 79 | void write_characters(const CharType* s, std::size_t length) override 80 | { 81 | stream.write(s, static_cast(length)); 82 | } 83 | 84 | private: 85 | std::basic_ostream& stream; 86 | }; 87 | #endif // JSON_NO_IO 88 | 89 | /// output adapter for basic_string 90 | template> 91 | class output_string_adapter : public output_adapter_protocol 92 | { 93 | public: 94 | explicit output_string_adapter(StringType& s) noexcept 95 | : str(s) 96 | {} 97 | 98 | void write_character(CharType c) override 99 | { 100 | str.push_back(c); 101 | } 102 | 103 | JSON_HEDLEY_NON_NULL(2) 104 | void write_characters(const CharType* s, std::size_t length) override 105 | { 106 | str.append(s, length); 107 | } 108 | 109 | private: 110 | StringType& str; 111 | }; 112 | 113 | template> 114 | class output_adapter 115 | { 116 | public: 117 | template> 118 | output_adapter(std::vector& vec) 119 | : oa(std::make_shared>(vec)) {} 120 | 121 | #ifndef JSON_NO_IO 122 | output_adapter(std::basic_ostream& s) 123 | : oa(std::make_shared>(s)) {} 124 | #endif // JSON_NO_IO 125 | 126 | output_adapter(StringType& s) 127 | : oa(std::make_shared>(s)) {} 128 | 129 | operator output_adapter_t() 130 | { 131 | return oa; 132 | } 133 | 134 | private: 135 | output_adapter_t oa = nullptr; 136 | }; 137 | } // namespace detail 138 | } // namespace nlohmann 139 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/string_escape.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace nlohmann 7 | { 8 | namespace detail 9 | { 10 | 11 | /*! 12 | @brief replace all occurrences of a substring by another string 13 | 14 | @param[in,out] s the string to manipulate; changed so that all 15 | occurrences of @a f are replaced with @a t 16 | @param[in] f the substring to replace with @a t 17 | @param[in] t the string to replace @a f 18 | 19 | @pre The search string @a f must not be empty. **This precondition is 20 | enforced with an assertion.** 21 | 22 | @since version 2.0.0 23 | */ 24 | inline void replace_substring(std::string& s, const std::string& f, 25 | const std::string& t) 26 | { 27 | JSON_ASSERT(!f.empty()); 28 | for (auto pos = s.find(f); // find first occurrence of f 29 | pos != std::string::npos; // make sure f was found 30 | s.replace(pos, f.size(), t), // replace with t, and 31 | pos = s.find(f, pos + t.size())) // find next occurrence of f 32 | {} 33 | } 34 | 35 | /*! 36 | * @brief string escaping as described in RFC 6901 (Sect. 4) 37 | * @param[in] s string to escape 38 | * @return escaped string 39 | * 40 | * Note the order of escaping "~" to "~0" and "/" to "~1" is important. 41 | */ 42 | inline std::string escape(std::string s) 43 | { 44 | replace_substring(s, "~", "~0"); 45 | replace_substring(s, "/", "~1"); 46 | return s; 47 | } 48 | 49 | /*! 50 | * @brief string unescaping as described in RFC 6901 (Sect. 4) 51 | * @param[in] s string to unescape 52 | * @return unescaped string 53 | * 54 | * Note the order of escaping "~1" to "/" and "~0" to "~" is important. 55 | */ 56 | static void unescape(std::string& s) 57 | { 58 | replace_substring(s, "~1", "/"); 59 | replace_substring(s, "~0", "~"); 60 | } 61 | 62 | } // namespace detail 63 | } // namespace nlohmann 64 | -------------------------------------------------------------------------------- /Source/nlohmann/detail/value_t.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // array 4 | #include // size_t 5 | #include // uint8_t 6 | #include // string 7 | 8 | namespace nlohmann 9 | { 10 | namespace detail 11 | { 12 | /////////////////////////// 13 | // JSON type enumeration // 14 | /////////////////////////// 15 | 16 | /*! 17 | @brief the JSON type enumeration 18 | 19 | This enumeration collects the different JSON types. It is internally used to 20 | distinguish the stored values, and the functions @ref basic_json::is_null(), 21 | @ref basic_json::is_object(), @ref basic_json::is_array(), 22 | @ref basic_json::is_string(), @ref basic_json::is_boolean(), 23 | @ref basic_json::is_number() (with @ref basic_json::is_number_integer(), 24 | @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), 25 | @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and 26 | @ref basic_json::is_structured() rely on it. 27 | 28 | @note There are three enumeration entries (number_integer, number_unsigned, and 29 | number_float), because the library distinguishes these three types for numbers: 30 | @ref basic_json::number_unsigned_t is used for unsigned integers, 31 | @ref basic_json::number_integer_t is used for signed integers, and 32 | @ref basic_json::number_float_t is used for floating-point numbers or to 33 | approximate integers which do not fit in the limits of their respective type. 34 | 35 | @sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON 36 | value with the default value for a given type 37 | 38 | @since version 1.0.0 39 | */ 40 | enum class value_t : std::uint8_t 41 | { 42 | null, ///< null value 43 | object, ///< object (unordered set of name/value pairs) 44 | array, ///< array (ordered collection of values) 45 | string, ///< string value 46 | boolean, ///< boolean value 47 | number_integer, ///< number value (signed integer) 48 | number_unsigned, ///< number value (unsigned integer) 49 | number_float, ///< number value (floating-point) 50 | binary, ///< binary array (ordered collection of bytes) 51 | discarded ///< discarded by the parser callback function 52 | }; 53 | 54 | /*! 55 | @brief comparison operator for JSON types 56 | 57 | Returns an ordering that is similar to Python: 58 | - order: null < boolean < number < object < array < string < binary 59 | - furthermore, each type is not smaller than itself 60 | - discarded values are not comparable 61 | - binary is represented as a b"" string in python and directly comparable to a 62 | string; however, making a binary array directly comparable with a string would 63 | be surprising behavior in a JSON file. 64 | 65 | @since version 1.0.0 66 | */ 67 | inline bool operator<(const value_t lhs, const value_t rhs) noexcept 68 | { 69 | static constexpr std::array order = {{ 70 | 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, 71 | 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, 72 | 6 /* binary */ 73 | } 74 | }; 75 | 76 | const auto l_index = static_cast(lhs); 77 | const auto r_index = static_cast(rhs); 78 | return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; 79 | } 80 | } // namespace detail 81 | } // namespace nlohmann 82 | -------------------------------------------------------------------------------- /Source/nlohmann/json_fwd.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ 2 | #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ 3 | 4 | #include // int64_t, uint64_t 5 | #include // map 6 | #include // allocator 7 | #include // string 8 | #include // vector 9 | 10 | /*! 11 | @brief namespace for Niels Lohmann 12 | @see https://github.com/nlohmann 13 | @since version 1.0.0 14 | */ 15 | namespace nlohmann 16 | { 17 | /*! 18 | @brief default JSONSerializer template argument 19 | 20 | This serializer ignores the template arguments and uses ADL 21 | ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) 22 | for serialization. 23 | */ 24 | template 25 | struct adl_serializer; 26 | 27 | /// a class to store JSON values 28 | /// @sa https://json.nlohmann.me/api/basic_json/ 29 | template class ObjectType = 30 | std::map, 31 | template class ArrayType = std::vector, 32 | class StringType = std::string, class BooleanType = bool, 33 | class NumberIntegerType = std::int64_t, 34 | class NumberUnsignedType = std::uint64_t, 35 | class NumberFloatType = double, 36 | template class AllocatorType = std::allocator, 37 | template class JSONSerializer = 38 | adl_serializer, 39 | class BinaryType = std::vector> 40 | class basic_json; 41 | 42 | /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document 43 | /// @sa https://json.nlohmann.me/api/json_pointer/ 44 | template 45 | class json_pointer; 46 | 47 | /*! 48 | @brief default specialization 49 | @sa https://json.nlohmann.me/api/json/ 50 | */ 51 | using json = basic_json<>; 52 | 53 | /// @brief a minimal map-like container that preserves insertion order 54 | /// @sa https://json.nlohmann.me/api/ordered_map/ 55 | template 56 | struct ordered_map; 57 | 58 | /// @brief specialization that maintains the insertion order of object keys 59 | /// @sa https://json.nlohmann.me/api/ordered_json/ 60 | using ordered_json = basic_json; 61 | 62 | } // namespace nlohmann 63 | 64 | #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ 65 | -------------------------------------------------------------------------------- /Source/nlohmann/ordered_map.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // less 4 | #include // initializer_list 5 | #include // input_iterator_tag, iterator_traits 6 | #include // allocator 7 | #include // for out_of_range 8 | #include // enable_if, is_convertible 9 | #include // pair 10 | #include // vector 11 | 12 | #include 13 | 14 | namespace nlohmann 15 | { 16 | 17 | /// ordered_map: a minimal map-like container that preserves insertion order 18 | /// for use within nlohmann::basic_json 19 | template , 20 | class Allocator = std::allocator>> 21 | struct ordered_map : std::vector, Allocator> 22 | { 23 | using key_type = Key; 24 | using mapped_type = T; 25 | using Container = std::vector, Allocator>; 26 | using iterator = typename Container::iterator; 27 | using const_iterator = typename Container::const_iterator; 28 | using size_type = typename Container::size_type; 29 | using value_type = typename Container::value_type; 30 | 31 | // Explicit constructors instead of `using Container::Container` 32 | // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4) 33 | ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {} 34 | template 35 | ordered_map(It first, It last, const Allocator& alloc = Allocator()) 36 | : Container{first, last, alloc} {} 37 | ordered_map(std::initializer_list init, const Allocator& alloc = Allocator() ) 38 | : Container{init, alloc} {} 39 | 40 | std::pair emplace(const key_type& key, T&& t) 41 | { 42 | for (auto it = this->begin(); it != this->end(); ++it) 43 | { 44 | if (it->first == key) 45 | { 46 | return {it, false}; 47 | } 48 | } 49 | Container::emplace_back(key, t); 50 | return {--this->end(), true}; 51 | } 52 | 53 | T& operator[](const Key& key) 54 | { 55 | return emplace(key, T{}).first->second; 56 | } 57 | 58 | const T& operator[](const Key& key) const 59 | { 60 | return at(key); 61 | } 62 | 63 | T& at(const Key& key) 64 | { 65 | for (auto it = this->begin(); it != this->end(); ++it) 66 | { 67 | if (it->first == key) 68 | { 69 | return it->second; 70 | } 71 | } 72 | 73 | JSON_THROW(std::out_of_range("key not found")); 74 | } 75 | 76 | const T& at(const Key& key) const 77 | { 78 | for (auto it = this->begin(); it != this->end(); ++it) 79 | { 80 | if (it->first == key) 81 | { 82 | return it->second; 83 | } 84 | } 85 | 86 | JSON_THROW(std::out_of_range("key not found")); 87 | } 88 | 89 | size_type erase(const Key& key) 90 | { 91 | for (auto it = this->begin(); it != this->end(); ++it) 92 | { 93 | if (it->first == key) 94 | { 95 | // Since we cannot move const Keys, re-construct them in place 96 | for (auto next = it; ++next != this->end(); ++it) 97 | { 98 | it->~value_type(); // Destroy but keep allocation 99 | new (&*it) value_type{std::move(*next)}; 100 | } 101 | Container::pop_back(); 102 | return 1; 103 | } 104 | } 105 | return 0; 106 | } 107 | 108 | iterator erase(iterator pos) 109 | { 110 | return erase(pos, std::next(pos)); 111 | } 112 | 113 | iterator erase(iterator first, iterator last) 114 | { 115 | const auto elements_affected = std::distance(first, last); 116 | const auto offset = std::distance(Container::begin(), first); 117 | 118 | // This is the start situation. We need to delete elements_affected 119 | // elements (3 in this example: e, f, g), and need to return an 120 | // iterator past the last deleted element (h in this example). 121 | // Note that offset is the distance from the start of the vector 122 | // to first. We will need this later. 123 | 124 | // [ a, b, c, d, e, f, g, h, i, j ] 125 | // ^ ^ 126 | // first last 127 | 128 | // Since we cannot move const Keys, we re-construct them in place. 129 | // We start at first and re-construct (viz. copy) the elements from 130 | // the back of the vector. Example for first iteration: 131 | 132 | // ,--------. 133 | // v | destroy e and re-construct with h 134 | // [ a, b, c, d, e, f, g, h, i, j ] 135 | // ^ ^ 136 | // it it + elements_affected 137 | 138 | for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it) 139 | { 140 | it->~value_type(); // destroy but keep allocation 141 | new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it 142 | } 143 | 144 | // [ a, b, c, d, h, i, j, h, i, j ] 145 | // ^ ^ 146 | // first last 147 | 148 | // remove the unneeded elements at the end of the vector 149 | Container::resize(this->size() - static_cast(elements_affected)); 150 | 151 | // [ a, b, c, d, h, i, j ] 152 | // ^ ^ 153 | // first last 154 | 155 | // first is now pointing past the last deleted element, but we cannot 156 | // use this iterator, because it may have been invalidated by the 157 | // resize call. Instead, we can return begin() + offset. 158 | return Container::begin() + offset; 159 | } 160 | 161 | size_type count(const Key& key) const 162 | { 163 | for (auto it = this->begin(); it != this->end(); ++it) 164 | { 165 | if (it->first == key) 166 | { 167 | return 1; 168 | } 169 | } 170 | return 0; 171 | } 172 | 173 | iterator find(const Key& key) 174 | { 175 | for (auto it = this->begin(); it != this->end(); ++it) 176 | { 177 | if (it->first == key) 178 | { 179 | return it; 180 | } 181 | } 182 | return Container::end(); 183 | } 184 | 185 | const_iterator find(const Key& key) const 186 | { 187 | for (auto it = this->begin(); it != this->end(); ++it) 188 | { 189 | if (it->first == key) 190 | { 191 | return it; 192 | } 193 | } 194 | return Container::end(); 195 | } 196 | 197 | std::pair insert( value_type&& value ) 198 | { 199 | return emplace(value.first, std::move(value.second)); 200 | } 201 | 202 | std::pair insert( const value_type& value ) 203 | { 204 | for (auto it = this->begin(); it != this->end(); ++it) 205 | { 206 | if (it->first == value.first) 207 | { 208 | return {it, false}; 209 | } 210 | } 211 | Container::push_back(value); 212 | return {--this->end(), true}; 213 | } 214 | 215 | template 216 | using require_input_iter = typename std::enable_if::iterator_category, 217 | std::input_iterator_tag>::value>::type; 218 | 219 | template> 220 | void insert(InputIt first, InputIt last) 221 | { 222 | for (auto it = first; it != last; ++it) 223 | { 224 | insert(*it); 225 | } 226 | } 227 | }; 228 | 229 | } // namespace nlohmann 230 | -------------------------------------------------------------------------------- /Source/nlohmann/thirdparty/hedley/hedley_undef.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #undef JSON_HEDLEY_ALWAYS_INLINE 4 | #undef JSON_HEDLEY_ARM_VERSION 5 | #undef JSON_HEDLEY_ARM_VERSION_CHECK 6 | #undef JSON_HEDLEY_ARRAY_PARAM 7 | #undef JSON_HEDLEY_ASSUME 8 | #undef JSON_HEDLEY_BEGIN_C_DECLS 9 | #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE 10 | #undef JSON_HEDLEY_CLANG_HAS_BUILTIN 11 | #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE 12 | #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE 13 | #undef JSON_HEDLEY_CLANG_HAS_EXTENSION 14 | #undef JSON_HEDLEY_CLANG_HAS_FEATURE 15 | #undef JSON_HEDLEY_CLANG_HAS_WARNING 16 | #undef JSON_HEDLEY_COMPCERT_VERSION 17 | #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK 18 | #undef JSON_HEDLEY_CONCAT 19 | #undef JSON_HEDLEY_CONCAT3 20 | #undef JSON_HEDLEY_CONCAT3_EX 21 | #undef JSON_HEDLEY_CONCAT_EX 22 | #undef JSON_HEDLEY_CONST 23 | #undef JSON_HEDLEY_CONSTEXPR 24 | #undef JSON_HEDLEY_CONST_CAST 25 | #undef JSON_HEDLEY_CPP_CAST 26 | #undef JSON_HEDLEY_CRAY_VERSION 27 | #undef JSON_HEDLEY_CRAY_VERSION_CHECK 28 | #undef JSON_HEDLEY_C_DECL 29 | #undef JSON_HEDLEY_DEPRECATED 30 | #undef JSON_HEDLEY_DEPRECATED_FOR 31 | #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL 32 | #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ 33 | #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED 34 | #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES 35 | #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS 36 | #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION 37 | #undef JSON_HEDLEY_DIAGNOSTIC_POP 38 | #undef JSON_HEDLEY_DIAGNOSTIC_PUSH 39 | #undef JSON_HEDLEY_DMC_VERSION 40 | #undef JSON_HEDLEY_DMC_VERSION_CHECK 41 | #undef JSON_HEDLEY_EMPTY_BASES 42 | #undef JSON_HEDLEY_EMSCRIPTEN_VERSION 43 | #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK 44 | #undef JSON_HEDLEY_END_C_DECLS 45 | #undef JSON_HEDLEY_FLAGS 46 | #undef JSON_HEDLEY_FLAGS_CAST 47 | #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE 48 | #undef JSON_HEDLEY_GCC_HAS_BUILTIN 49 | #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE 50 | #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE 51 | #undef JSON_HEDLEY_GCC_HAS_EXTENSION 52 | #undef JSON_HEDLEY_GCC_HAS_FEATURE 53 | #undef JSON_HEDLEY_GCC_HAS_WARNING 54 | #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK 55 | #undef JSON_HEDLEY_GCC_VERSION 56 | #undef JSON_HEDLEY_GCC_VERSION_CHECK 57 | #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE 58 | #undef JSON_HEDLEY_GNUC_HAS_BUILTIN 59 | #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE 60 | #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE 61 | #undef JSON_HEDLEY_GNUC_HAS_EXTENSION 62 | #undef JSON_HEDLEY_GNUC_HAS_FEATURE 63 | #undef JSON_HEDLEY_GNUC_HAS_WARNING 64 | #undef JSON_HEDLEY_GNUC_VERSION 65 | #undef JSON_HEDLEY_GNUC_VERSION_CHECK 66 | #undef JSON_HEDLEY_HAS_ATTRIBUTE 67 | #undef JSON_HEDLEY_HAS_BUILTIN 68 | #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE 69 | #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS 70 | #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE 71 | #undef JSON_HEDLEY_HAS_EXTENSION 72 | #undef JSON_HEDLEY_HAS_FEATURE 73 | #undef JSON_HEDLEY_HAS_WARNING 74 | #undef JSON_HEDLEY_IAR_VERSION 75 | #undef JSON_HEDLEY_IAR_VERSION_CHECK 76 | #undef JSON_HEDLEY_IBM_VERSION 77 | #undef JSON_HEDLEY_IBM_VERSION_CHECK 78 | #undef JSON_HEDLEY_IMPORT 79 | #undef JSON_HEDLEY_INLINE 80 | #undef JSON_HEDLEY_INTEL_CL_VERSION 81 | #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK 82 | #undef JSON_HEDLEY_INTEL_VERSION 83 | #undef JSON_HEDLEY_INTEL_VERSION_CHECK 84 | #undef JSON_HEDLEY_IS_CONSTANT 85 | #undef JSON_HEDLEY_IS_CONSTEXPR_ 86 | #undef JSON_HEDLEY_LIKELY 87 | #undef JSON_HEDLEY_MALLOC 88 | #undef JSON_HEDLEY_MCST_LCC_VERSION 89 | #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK 90 | #undef JSON_HEDLEY_MESSAGE 91 | #undef JSON_HEDLEY_MSVC_VERSION 92 | #undef JSON_HEDLEY_MSVC_VERSION_CHECK 93 | #undef JSON_HEDLEY_NEVER_INLINE 94 | #undef JSON_HEDLEY_NON_NULL 95 | #undef JSON_HEDLEY_NO_ESCAPE 96 | #undef JSON_HEDLEY_NO_RETURN 97 | #undef JSON_HEDLEY_NO_THROW 98 | #undef JSON_HEDLEY_NULL 99 | #undef JSON_HEDLEY_PELLES_VERSION 100 | #undef JSON_HEDLEY_PELLES_VERSION_CHECK 101 | #undef JSON_HEDLEY_PGI_VERSION 102 | #undef JSON_HEDLEY_PGI_VERSION_CHECK 103 | #undef JSON_HEDLEY_PREDICT 104 | #undef JSON_HEDLEY_PRINTF_FORMAT 105 | #undef JSON_HEDLEY_PRIVATE 106 | #undef JSON_HEDLEY_PUBLIC 107 | #undef JSON_HEDLEY_PURE 108 | #undef JSON_HEDLEY_REINTERPRET_CAST 109 | #undef JSON_HEDLEY_REQUIRE 110 | #undef JSON_HEDLEY_REQUIRE_CONSTEXPR 111 | #undef JSON_HEDLEY_REQUIRE_MSG 112 | #undef JSON_HEDLEY_RESTRICT 113 | #undef JSON_HEDLEY_RETURNS_NON_NULL 114 | #undef JSON_HEDLEY_SENTINEL 115 | #undef JSON_HEDLEY_STATIC_ASSERT 116 | #undef JSON_HEDLEY_STATIC_CAST 117 | #undef JSON_HEDLEY_STRINGIFY 118 | #undef JSON_HEDLEY_STRINGIFY_EX 119 | #undef JSON_HEDLEY_SUNPRO_VERSION 120 | #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK 121 | #undef JSON_HEDLEY_TINYC_VERSION 122 | #undef JSON_HEDLEY_TINYC_VERSION_CHECK 123 | #undef JSON_HEDLEY_TI_ARMCL_VERSION 124 | #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK 125 | #undef JSON_HEDLEY_TI_CL2000_VERSION 126 | #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK 127 | #undef JSON_HEDLEY_TI_CL430_VERSION 128 | #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK 129 | #undef JSON_HEDLEY_TI_CL6X_VERSION 130 | #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK 131 | #undef JSON_HEDLEY_TI_CL7X_VERSION 132 | #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK 133 | #undef JSON_HEDLEY_TI_CLPRU_VERSION 134 | #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK 135 | #undef JSON_HEDLEY_TI_VERSION 136 | #undef JSON_HEDLEY_TI_VERSION_CHECK 137 | #undef JSON_HEDLEY_UNAVAILABLE 138 | #undef JSON_HEDLEY_UNLIKELY 139 | #undef JSON_HEDLEY_UNPREDICTABLE 140 | #undef JSON_HEDLEY_UNREACHABLE 141 | #undef JSON_HEDLEY_UNREACHABLE_RETURN 142 | #undef JSON_HEDLEY_VERSION 143 | #undef JSON_HEDLEY_VERSION_DECODE_MAJOR 144 | #undef JSON_HEDLEY_VERSION_DECODE_MINOR 145 | #undef JSON_HEDLEY_VERSION_DECODE_REVISION 146 | #undef JSON_HEDLEY_VERSION_ENCODE 147 | #undef JSON_HEDLEY_WARNING 148 | #undef JSON_HEDLEY_WARN_UNUSED_RESULT 149 | #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG 150 | #undef JSON_HEDLEY_FALL_THROUGH 151 | -------------------------------------------------------------------------------- /UnrealMapboxBridge.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "UnrealMapboxBridge", 6 | "Description": "Create roads, lakes, rivers from a Geojson file", 7 | "Category": "GIS", 8 | "CreatedBy": "Daniel Elebash", 9 | "CreatedByURL": "", 10 | "DocsURL": "", 11 | "MarketplaceURL": "", 12 | "SupportURL": "", 13 | "CanContainContent": true, 14 | "IsBetaVersion": false, 15 | "IsExperimentalVersion": false, 16 | "Installed": true, 17 | "Modules": [ 18 | { 19 | "Name": "UnrealMapboxBridge", 20 | "Type": "Editor", 21 | "LoadingPhase": "Default" 22 | } 23 | ], 24 | "Plugins": [ 25 | { 26 | "Name": "EditorScriptingUtilities", 27 | "Enabled": true 28 | }, 29 | { 30 | "Name": "RemoteControl", 31 | "Enabled": true 32 | } 33 | ] 34 | } --------------------------------------------------------------------------------