From 6694a00b0b69044e365067456c7cd8616984360e Mon Sep 17 00:00:00 2001 From: Jeff L <51171427+LebJe@users.noreply.github.com> Date: Fri, 8 Apr 2022 14:26:06 -0400 Subject: [PATCH] Update to Toml++ 3.0.0 (#1) - Update to toml++ v3 - Improve code in src/utilites.cpp - Add magic_enum as a dependency - Update CHANGELOG - move some headers to `src/include` - Fix tests --- .gitmodules | 1 + .pre-commit-config.yaml | 2 +- CHANGELOG.md | 12 + CMakeLists.txt | 4 +- README.md | 97 +- examples/example.lua | 7 +- spec/decoding_spec.lua | 8 +- spec/encoding_spec.lua | 6 +- spec/test-data/massive.toml | 2000 +- spec/test-data/test.toml | 66 +- spec/test-data/test2.toml | 20 +- src/decoding/decoding.cpp | 80 +- src/encoding/encoding.cpp | 4 +- src/include/magicEnum/magic_enum.hpp | 1430 ++ src/{ => include}/sol/config.hpp | 0 src/{ => include}/sol/sol.hpp | 0 src/{ => include}/toml.hpp | 17024 +++++++++------- src/toml.cpp | 83 +- src/utilities/utilities.cpp | 151 +- src/utilities/utilities.hpp | 35 +- ...-0.0.4-0.rockspec => toml-0.1.0-0.rockspec | 2 +- toml.d.tl | 53 +- tomlplusplus | 2 +- 23 files changed, 12879 insertions(+), 8208 deletions(-) create mode 100644 src/include/magicEnum/magic_enum.hpp rename src/{ => include}/sol/config.hpp (100%) rename src/{ => include}/sol/sol.hpp (100%) rename src/{ => include}/toml.hpp (53%) rename toml-0.0.4-0.rockspec => toml-0.1.0-0.rockspec (97%) diff --git a/.gitmodules b/.gitmodules index d494f4f..708939c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,7 @@ [submodule "tomlplusplus"] path = tomlplusplus url = https://github.com/marzer/tomlplusplus + fetchRecurseSubmodules = false [submodule "sol2"] path = sol2 url = https://github.com/ThePhD/sol2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 88aff08..eb56c7c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: rev: "62302476d0da01515660132d76902359bed0f782" hooks: - id: "clang-format" - exclude: "sol2/|src/toml.hpp|src/sol/" + exclude: "sol2/tomlplusplus/|src/include" - repo: "https://github.com/LebJe/PreCommitStyLua.git" rev: "c7f96e8ba459f1c6c27cb21cc6a9dc05e14745ca" hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md index a437019..1daffda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.1.0](https://github.com/LebJe/toml.lua/releases/tag/0.0.4) - 2022-04-08 + +### Added + +- Upgrade to [toml++ 3.0.1](https://github.com/marzer/tomlplusplus/releases/tag/v3.0.1) +- TOML documents can be converted to JSON or YAML. +- Formatting options can be passed to the `encode`, `tomlToJSON`, and `tomlToYAML` functions. + +### Removed + +- Removed `formattedReason` from decoding error messages. + ## [0.0.4](https://github.com/LebJe/toml.lua/releases/tag/0.0.4) - 2021-11-24 ### Added diff --git a/CMakeLists.txt b/CMakeLists.txt index 1304ede..3927940 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ project(toml.lua VERSION ${TOML_LUA_VERSION}) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) -# compile in release mode by default +# compile in release mode by default if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) endif() @@ -59,7 +59,7 @@ if(NOT LUA_INCLUDE_DIR OR (WIN32 AND NOT LUA_LIBRARIES)) find_package(Lua REQUIRED) endif() -include_directories(${LUA_INCLUDE_DIR} src) +include_directories(${LUA_INCLUDE_DIR} src src/include) set(SOURCES src/toml.cpp diff --git a/README.md b/README.md index d5f14bb..a86b9c7 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,15 @@ toml.lua is a [Lua](https://www.lua.org) wrapper around [toml++](https://github. - [Decoding](#decoding) - [Encoding](#encoding) - [Error Handling](#error-handling) - - [TOML To JSON](#toml-to-json) + - [TOML Conversion](#toml-conversion) + - [JSON](#json) + - [YAML](#yaml) + - [Output Formatting](#output-formatting) - [Dependencies](#dependencies) - [Licenses](#licenses) - [Contributing](#contributing) - + @@ -48,10 +51,10 @@ luarocks install toml ### Manual Compilation -1. Run `cmake -H. -Bbuild -G` to generate the required files. +1. Run `cmake -S . -B build -G ` to generate the required files. > If you have a non standard Lua install location, add the environment variable `LUA_DIR` and have it point to the directory containing the `include` and `lib` folders for your Lua installation. For example: -> `LUA_DIR=/usr/local/openresty/luajit cmake -H. -Bbuild -G` +> `LUA_DIR=/usr/local/openresty/luajit cmake -S . -B build -G ` 2. Run `cmake --build build --config Release` to build the project. 3. You will find the `toml.so` (or `toml.dll`) dynamic library in the `build` folder. @@ -190,16 +193,17 @@ else column = 9, line = 4 }, - formattedReason = "Error while parsing floating-point: expected decimal digit, saw '\\n' (at line 4, column 9)", reason = "Error while parsing floating-point: expected decimal digit, saw '\\n'" } --]] end ``` -### TOML To JSON +### TOML Conversion ```lua +local toml = require("toml") + local tomlStr = [[ a = 1275892 b = 'Hello, World!' @@ -212,38 +216,77 @@ g = 1979-05-27 h = 07:32:00 i = 1979-05-27T07:32:00-07:00 ]] +``` -local toml = require("toml") -local json = toml.tomlToJSON(tomlStr) +#### JSON +```lua +local json = toml.tomlToJSON(tomlStr) print(json) +``` ---[[ +#### YAML + +```lua +local yaml = toml.tomlToYAML(tomlStr) +print(yaml) +``` + +### Output Formatting + +`toml.encode`, `toml.tomlToJSON`, and `toml.tomlToYAML` all take an optional second parameter: a table containing keys that disable or enable different formatting options. +Passing an empty table removes all options, while not providing a table will use the default options. + +```lua { - "a" : 1275892, - "b" : "Hello, World!", - "c" : true, - "d" : 124.2548, - "e" : { - "f" : [ - 1, - 2, - 3, - "4", - 5.142 - ], - "g" : "1979-05-27", - "h" : "07:32:00", - "i" : "1979-05-27T07:32:00-07:00" - } + --- Dates and times will be emitted as quoted strings. + quoteDatesAndTimes = true, + + --- Infinities and NaNs will be emitted as quoted strings. + quoteInfinitesAndNaNs = false, + + --- Strings will be emitted as single-quoted literal strings where possible. + allowLiteralStrings = false, + + --- Strings containing newlines will be emitted as triple-quoted 'multi-line' strings where possible. + allowMultiLineStrings = false, + + --- Allow real tab characters in string literals (as opposed to the escaped form `\t`). + allowRealTabsInStrings = false, + + --- Allow non-ASCII characters in strings (as opposed to their escaped form, e.g. `\u00DA`). + allow_unicode_strings = true, + + --- Allow integers with #value_flags::format_as_binary to be emitted as binary. + allowBinaryIntegers = true, + + --- Allow integers with #value_flags::format_as_octal to be emitted as octal. + allowOctalIntegers = true, + + --- Allow integers with #value_flags::format_as_hexadecimal to be emitted as hexadecimal. + allowHexadecimalIntegers = true, + + --- Apply indentation to tables nested within other tables/arrays. + indentSubTables = true, + + --- Apply indentation to array elements when the array is forced to wrap over multiple lines. + indentArrayElements = true, + + --- Combination of `indentSubTables` and `indentArrayElements`. + indentation = true, + + --- Emit floating-point values with relaxed (human-friendly) precision. + relaxedFloatPrecision = false } ---]] ``` +> The comments for the options are from [the tomlplusplus documentation](https://marzer.github.io/tomlplusplus/namespacetoml.html#a2102aa80bc57783d96180f36e1f64f6a) + ## Dependencies - [toml++](https://github.com/marzer/tomlplusplus/) - [sol2](https://github.com/ThePhD/sol2) +- [magic_enum](https://github.com/Neargye/magic_enum) ## Licenses @@ -251,6 +294,8 @@ The [toml++](https://github.com/marzer/tomlplusplus/) license is available in th The [sol2](https://github.com/ThePhD/sol2) license is available in the `sol2` directory in the `LICENSE.txt` file. +The [magic_enum](https://github.com/Neargye/magic_enum) license is available in [its repository](https://github.com/Neargye/magic_enum/blob/master/LICENSE). + ## Contributing Before committing, please install [pre-commit](https://pre-commit.com), [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [StyLua](https://github.com/JohnnyMorganz/StyLua), and [Prettier](https://prettier.io), then install the pre-commit hook: diff --git a/examples/example.lua b/examples/example.lua index c29f7b2..9bd4437 100644 --- a/examples/example.lua +++ b/examples/example.lua @@ -42,7 +42,10 @@ end print("\n\nEncoding:\n") -print(toml.encode(data)) +print(toml.encode(data, { indentation = true })) print("\n\nTOML to JSON:\n") -print(toml.tomlToJSON(tomlStr)) +print(toml.tomlToJSON(tomlStr, { indentation = true })) + +print("\n\nTOML to YAML:\n") +print(toml.tomlToYAML(tomlStr, { indentation = true })) diff --git a/spec/decoding_spec.lua b/spec/decoding_spec.lua index e45ac44..79d8d91 100644 --- a/spec/decoding_spec.lua +++ b/spec/decoding_spec.lua @@ -45,7 +45,6 @@ describe("toml.decode()", function() line = 7, column = 1, }, - formattedReason = "Error while parsing table header: cannot redefine existing table 'fruit' as array-of-tables (at line 7, column 1)", reason = "Error while parsing table header: cannot redefine existing table 'fruit' as array-of-tables", } @@ -60,14 +59,13 @@ describe("toml.decode()", function() local expectedError2 = { begin = { line = 10, - column = 1, + column = 7, }, ["end"] = { line = 10, - column = 1, + column = 7, }, - formattedReason = "Error while parsing key-value pair: cannot redefine existing integer as dotted key-value pair (at line 10, column 1)", - reason = "Error while parsing key-value pair: cannot redefine existing integer as dotted key-value pair", + reason = "Error while parsing key-value pair: cannot redefine existing table as dotted key-value pair", } assert.has_error(function() diff --git a/spec/encoding_spec.lua b/spec/encoding_spec.lua index b695322..b7056ba 100644 --- a/spec/encoding_spec.lua +++ b/spec/encoding_spec.lua @@ -7,7 +7,7 @@ describe("toml.encode()", function() local expectedTOML = fh:read("*all") fh:close() - assert.are.same(toml.encode(data.tableForTestToml), expectedTOML) + assert.are.same(toml.encode(data.tableForTestToml, {}), expectedTOML) end) it("can encode another sample TOML document", function() @@ -15,11 +15,11 @@ describe("toml.encode()", function() local expectedTOML = fh:read("*all") fh:close() - assert.are.same(toml.encode(data.tableForTest2Toml), expectedTOML) + assert.are.same(toml.encode(data.tableForTest2Toml, {}), expectedTOML) end) it("can encode massive table", function() - local returnedTOML = toml.encode(data.tableForMassiveToml) + local returnedTOML = toml.encode(data.tableForMassiveToml, {}) local fh = io.open("spec/test-data/massive.toml") local expectedTOML = fh:read("*all") diff --git a/spec/test-data/massive.toml b/spec/test-data/massive.toml index 8da4952..ab0db44 100644 --- a/spec/test-data/massive.toml +++ b/spec/test-data/massive.toml @@ -1,1002 +1,1002 @@ [key] end = 1 -key1 = 'abcdefg' -key10 = 'abcdefg' -key100 = 'abcdefg' -key1000 = 'abcdefg' -key101 = 'abcdefg' -key102 = 'abcdefg' -key103 = 'abcdefg' -key104 = 'abcdefg' -key105 = 'abcdefg' -key106 = 'abcdefg' -key107 = 'abcdefg' -key108 = 'abcdefg' -key109 = 'abcdefg' -key11 = 'abcdefg' -key110 = 'abcdefg' -key111 = 'abcdefg' -key112 = 'abcdefg' -key113 = 'abcdefg' -key114 = 'abcdefg' -key115 = 'abcdefg' -key116 = 'abcdefg' -key117 = 'abcdefg' -key118 = 'abcdefg' -key119 = 'abcdefg' -key12 = 'abcdefg' -key120 = 'abcdefg' -key121 = 'abcdefg' -key122 = 'abcdefg' -key123 = 'abcdefg' -key124 = 'abcdefg' -key125 = 'abcdefg' -key126 = 'abcdefg' -key127 = 'abcdefg' -key128 = 'abcdefg' -key129 = 'abcdefg' -key13 = 'abcdefg' -key130 = 'abcdefg' -key131 = 'abcdefg' -key132 = 'abcdefg' -key133 = 'abcdefg' -key134 = 'abcdefg' -key135 = 'abcdefg' -key136 = 'abcdefg' -key137 = 'abcdefg' -key138 = 'abcdefg' -key139 = 'abcdefg' -key14 = 'abcdefg' -key140 = 'abcdefg' -key141 = 'abcdefg' -key142 = 'abcdefg' -key143 = 'abcdefg' -key144 = 'abcdefg' -key145 = 'abcdefg' -key146 = 'abcdefg' -key147 = 'abcdefg' -key148 = 'abcdefg' -key149 = 'abcdefg' -key15 = 'abcdefg' -key150 = 'abcdefg' -key151 = 'abcdefg' -key152 = 'abcdefg' -key153 = 'abcdefg' -key154 = 'abcdefg' -key155 = 'abcdefg' -key156 = 'abcdefg' -key157 = 'abcdefg' -key158 = 'abcdefg' -key159 = 'abcdefg' -key16 = 'abcdefg' -key160 = 'abcdefg' -key161 = 'abcdefg' -key162 = 'abcdefg' -key163 = 'abcdefg' -key164 = 'abcdefg' -key165 = 'abcdefg' -key166 = 'abcdefg' -key167 = 'abcdefg' -key168 = 'abcdefg' -key169 = 'abcdefg' -key17 = 'abcdefg' -key170 = 'abcdefg' -key171 = 'abcdefg' -key172 = 'abcdefg' -key173 = 'abcdefg' -key174 = 'abcdefg' -key175 = 'abcdefg' -key176 = 'abcdefg' -key177 = 'abcdefg' -key178 = 'abcdefg' -key179 = 'abcdefg' -key18 = 'abcdefg' -key180 = 'abcdefg' -key181 = 'abcdefg' -key182 = 'abcdefg' -key183 = 'abcdefg' -key184 = 'abcdefg' -key185 = 'abcdefg' -key186 = 'abcdefg' -key187 = 'abcdefg' -key188 = 'abcdefg' -key189 = 'abcdefg' -key19 = 'abcdefg' -key190 = 'abcdefg' -key191 = 'abcdefg' -key192 = 'abcdefg' -key193 = 'abcdefg' -key194 = 'abcdefg' -key195 = 'abcdefg' -key196 = 'abcdefg' -key197 = 'abcdefg' -key198 = 'abcdefg' -key199 = 'abcdefg' -key2 = 'abcdefg' -key20 = 'abcdefg' -key200 = 'abcdefg' -key201 = 'abcdefg' -key202 = 'abcdefg' -key203 = 'abcdefg' -key204 = 'abcdefg' -key205 = 'abcdefg' -key206 = 'abcdefg' -key207 = 'abcdefg' -key208 = 'abcdefg' -key209 = 'abcdefg' -key21 = 'abcdefg' -key210 = 'abcdefg' -key211 = 'abcdefg' -key212 = 'abcdefg' -key213 = 'abcdefg' -key214 = 'abcdefg' -key215 = 'abcdefg' -key216 = 'abcdefg' -key217 = 'abcdefg' -key218 = 'abcdefg' -key219 = 'abcdefg' -key22 = 'abcdefg' -key220 = 'abcdefg' -key221 = 'abcdefg' -key222 = 'abcdefg' -key223 = 'abcdefg' -key224 = 'abcdefg' -key225 = 'abcdefg' -key226 = 'abcdefg' -key227 = 'abcdefg' -key228 = 'abcdefg' -key229 = 'abcdefg' -key23 = 'abcdefg' -key230 = 'abcdefg' -key231 = 'abcdefg' -key232 = 'abcdefg' -key233 = 'abcdefg' -key234 = 'abcdefg' -key235 = 'abcdefg' -key236 = 'abcdefg' -key237 = 'abcdefg' -key238 = 'abcdefg' -key239 = 'abcdefg' -key24 = 'abcdefg' -key240 = 'abcdefg' -key241 = 'abcdefg' -key242 = 'abcdefg' -key243 = 'abcdefg' -key244 = 'abcdefg' -key245 = 'abcdefg' -key246 = 'abcdefg' -key247 = 'abcdefg' -key248 = 'abcdefg' -key249 = 'abcdefg' -key25 = 'abcdefg' -key250 = 'abcdefg' -key251 = 'abcdefg' -key252 = 'abcdefg' -key253 = 'abcdefg' -key254 = 'abcdefg' -key255 = 'abcdefg' -key256 = 'abcdefg' -key257 = 'abcdefg' -key258 = 'abcdefg' -key259 = 'abcdefg' -key26 = 'abcdefg' -key260 = 'abcdefg' -key261 = 'abcdefg' -key262 = 'abcdefg' -key263 = 'abcdefg' -key264 = 'abcdefg' -key265 = 'abcdefg' -key266 = 'abcdefg' -key267 = 'abcdefg' -key268 = 'abcdefg' -key269 = 'abcdefg' -key27 = 'abcdefg' -key270 = 'abcdefg' -key271 = 'abcdefg' -key272 = 'abcdefg' -key273 = 'abcdefg' -key274 = 'abcdefg' -key275 = 'abcdefg' -key276 = 'abcdefg' -key277 = 'abcdefg' -key278 = 'abcdefg' -key279 = 'abcdefg' -key28 = 'abcdefg' -key280 = 'abcdefg' -key281 = 'abcdefg' -key282 = 'abcdefg' -key283 = 'abcdefg' -key284 = 'abcdefg' -key285 = 'abcdefg' -key286 = 'abcdefg' -key287 = 'abcdefg' -key288 = 'abcdefg' -key289 = 'abcdefg' -key29 = 'abcdefg' -key290 = 'abcdefg' -key291 = 'abcdefg' -key292 = 'abcdefg' -key293 = 'abcdefg' -key294 = 'abcdefg' -key295 = 'abcdefg' -key296 = 'abcdefg' -key297 = 'abcdefg' -key298 = 'abcdefg' -key299 = 'abcdefg' -key3 = 'abcdefg' -key30 = 'abcdefg' -key300 = 'abcdefg' -key301 = 'abcdefg' -key302 = 'abcdefg' -key303 = 'abcdefg' -key304 = 'abcdefg' -key305 = 'abcdefg' -key306 = 'abcdefg' -key307 = 'abcdefg' -key308 = 'abcdefg' -key309 = 'abcdefg' -key31 = 'abcdefg' -key310 = 'abcdefg' -key311 = 'abcdefg' -key312 = 'abcdefg' -key313 = 'abcdefg' -key314 = 'abcdefg' -key315 = 'abcdefg' -key316 = 'abcdefg' -key317 = 'abcdefg' -key318 = 'abcdefg' -key319 = 'abcdefg' -key32 = 'abcdefg' -key320 = 'abcdefg' -key321 = 'abcdefg' -key322 = 'abcdefg' -key323 = 'abcdefg' -key324 = 'abcdefg' -key325 = 'abcdefg' -key326 = 'abcdefg' -key327 = 'abcdefg' -key328 = 'abcdefg' -key329 = 'abcdefg' -key33 = 'abcdefg' -key330 = 'abcdefg' -key331 = 'abcdefg' -key332 = 'abcdefg' -key333 = 'abcdefg' -key334 = 'abcdefg' -key335 = 'abcdefg' -key336 = 'abcdefg' -key337 = 'abcdefg' -key338 = 'abcdefg' -key339 = 'abcdefg' -key34 = 'abcdefg' -key340 = 'abcdefg' -key341 = 'abcdefg' -key342 = 'abcdefg' -key343 = 'abcdefg' -key344 = 'abcdefg' -key345 = 'abcdefg' -key346 = 'abcdefg' -key347 = 'abcdefg' -key348 = 'abcdefg' -key349 = 'abcdefg' -key35 = 'abcdefg' -key350 = 'abcdefg' -key351 = 'abcdefg' -key352 = 'abcdefg' -key353 = 'abcdefg' -key354 = 'abcdefg' -key355 = 'abcdefg' -key356 = 'abcdefg' -key357 = 'abcdefg' -key358 = 'abcdefg' -key359 = 'abcdefg' -key36 = 'abcdefg' -key360 = 'abcdefg' -key361 = 'abcdefg' -key362 = 'abcdefg' -key363 = 'abcdefg' -key364 = 'abcdefg' -key365 = 'abcdefg' -key366 = 'abcdefg' -key367 = 'abcdefg' -key368 = 'abcdefg' -key369 = 'abcdefg' -key37 = 'abcdefg' -key370 = 'abcdefg' -key371 = 'abcdefg' -key372 = 'abcdefg' -key373 = 'abcdefg' -key374 = 'abcdefg' -key375 = 'abcdefg' -key376 = 'abcdefg' -key377 = 'abcdefg' -key378 = 'abcdefg' -key379 = 'abcdefg' -key38 = 'abcdefg' -key380 = 'abcdefg' -key381 = 'abcdefg' -key382 = 'abcdefg' -key383 = 'abcdefg' -key384 = 'abcdefg' -key385 = 'abcdefg' -key386 = 'abcdefg' -key387 = 'abcdefg' -key388 = 'abcdefg' -key389 = 'abcdefg' -key39 = 'abcdefg' -key390 = 'abcdefg' -key391 = 'abcdefg' -key392 = 'abcdefg' -key393 = 'abcdefg' -key394 = 'abcdefg' -key395 = 'abcdefg' -key396 = 'abcdefg' -key397 = 'abcdefg' -key398 = 'abcdefg' -key399 = 'abcdefg' -key4 = 'abcdefg' -key40 = 'abcdefg' -key400 = 'abcdefg' -key401 = 'abcdefg' -key402 = 'abcdefg' -key403 = 'abcdefg' -key404 = 'abcdefg' -key405 = 'abcdefg' -key406 = 'abcdefg' -key407 = 'abcdefg' -key408 = 'abcdefg' -key409 = 'abcdefg' -key41 = 'abcdefg' -key410 = 'abcdefg' -key411 = 'abcdefg' -key412 = 'abcdefg' -key413 = 'abcdefg' -key414 = 'abcdefg' -key415 = 'abcdefg' -key416 = 'abcdefg' -key417 = 'abcdefg' -key418 = 'abcdefg' -key419 = 'abcdefg' -key42 = 'abcdefg' -key420 = 'abcdefg' -key421 = 'abcdefg' -key422 = 'abcdefg' -key423 = 'abcdefg' -key424 = 'abcdefg' -key425 = 'abcdefg' -key426 = 'abcdefg' -key427 = 'abcdefg' -key428 = 'abcdefg' -key429 = 'abcdefg' -key43 = 'abcdefg' -key430 = 'abcdefg' -key431 = 'abcdefg' -key432 = 'abcdefg' -key433 = 'abcdefg' -key434 = 'abcdefg' -key435 = 'abcdefg' -key436 = 'abcdefg' -key437 = 'abcdefg' -key438 = 'abcdefg' -key439 = 'abcdefg' -key44 = 'abcdefg' -key440 = 'abcdefg' -key441 = 'abcdefg' -key442 = 'abcdefg' -key443 = 'abcdefg' -key444 = 'abcdefg' -key445 = 'abcdefg' -key446 = 'abcdefg' -key447 = 'abcdefg' -key448 = 'abcdefg' -key449 = 'abcdefg' -key45 = 'abcdefg' -key450 = 'abcdefg' -key451 = 'abcdefg' -key452 = 'abcdefg' -key453 = 'abcdefg' -key454 = 'abcdefg' -key455 = 'abcdefg' -key456 = 'abcdefg' -key457 = 'abcdefg' -key458 = 'abcdefg' -key459 = 'abcdefg' -key46 = 'abcdefg' -key460 = 'abcdefg' -key461 = 'abcdefg' -key462 = 'abcdefg' -key463 = 'abcdefg' -key464 = 'abcdefg' -key465 = 'abcdefg' -key466 = 'abcdefg' -key467 = 'abcdefg' -key468 = 'abcdefg' -key469 = 'abcdefg' -key47 = 'abcdefg' -key470 = 'abcdefg' -key471 = 'abcdefg' -key472 = 'abcdefg' -key473 = 'abcdefg' -key474 = 'abcdefg' -key475 = 'abcdefg' -key476 = 'abcdefg' -key477 = 'abcdefg' -key478 = 'abcdefg' -key479 = 'abcdefg' -key48 = 'abcdefg' -key480 = 'abcdefg' -key481 = 'abcdefg' -key482 = 'abcdefg' -key483 = 'abcdefg' -key484 = 'abcdefg' -key485 = 'abcdefg' -key486 = 'abcdefg' -key487 = 'abcdefg' -key488 = 'abcdefg' -key489 = 'abcdefg' -key49 = 'abcdefg' -key490 = 'abcdefg' -key491 = 'abcdefg' -key492 = 'abcdefg' -key493 = 'abcdefg' -key494 = 'abcdefg' -key495 = 'abcdefg' -key496 = 'abcdefg' -key497 = 'abcdefg' -key498 = 'abcdefg' -key499 = 'abcdefg' -key5 = 'abcdefg' -key50 = 'abcdefg' -key500 = 'abcdefg' -key501 = 'abcdefg' -key502 = 'abcdefg' -key503 = 'abcdefg' -key504 = 'abcdefg' -key505 = 'abcdefg' -key506 = 'abcdefg' -key507 = 'abcdefg' -key508 = 'abcdefg' -key509 = 'abcdefg' -key51 = 'abcdefg' -key510 = 'abcdefg' -key511 = 'abcdefg' -key512 = 'abcdefg' -key513 = 'abcdefg' -key514 = 'abcdefg' -key515 = 'abcdefg' -key516 = 'abcdefg' -key517 = 'abcdefg' -key518 = 'abcdefg' -key519 = 'abcdefg' -key52 = 'abcdefg' -key520 = 'abcdefg' -key521 = 'abcdefg' -key522 = 'abcdefg' -key523 = 'abcdefg' -key524 = 'abcdefg' -key525 = 'abcdefg' -key526 = 'abcdefg' -key527 = 'abcdefg' -key528 = 'abcdefg' -key529 = 'abcdefg' -key53 = 'abcdefg' -key530 = 'abcdefg' -key531 = 'abcdefg' -key532 = 'abcdefg' -key533 = 'abcdefg' -key534 = 'abcdefg' -key535 = 'abcdefg' -key536 = 'abcdefg' -key537 = 'abcdefg' -key538 = 'abcdefg' -key539 = 'abcdefg' -key54 = 'abcdefg' -key540 = 'abcdefg' -key541 = 'abcdefg' -key542 = 'abcdefg' -key543 = 'abcdefg' -key544 = 'abcdefg' -key545 = 'abcdefg' -key546 = 'abcdefg' -key547 = 'abcdefg' -key548 = 'abcdefg' -key549 = 'abcdefg' -key55 = 'abcdefg' -key550 = 'abcdefg' -key551 = 'abcdefg' -key552 = 'abcdefg' -key553 = 'abcdefg' -key554 = 'abcdefg' -key555 = 'abcdefg' -key556 = 'abcdefg' -key557 = 'abcdefg' -key558 = 'abcdefg' -key559 = 'abcdefg' -key56 = 'abcdefg' -key560 = 'abcdefg' -key561 = 'abcdefg' -key562 = 'abcdefg' -key563 = 'abcdefg' -key564 = 'abcdefg' -key565 = 'abcdefg' -key566 = 'abcdefg' -key567 = 'abcdefg' -key568 = 'abcdefg' -key569 = 'abcdefg' -key57 = 'abcdefg' -key570 = 'abcdefg' -key571 = 'abcdefg' -key572 = 'abcdefg' -key573 = 'abcdefg' -key574 = 'abcdefg' -key575 = 'abcdefg' -key576 = 'abcdefg' -key577 = 'abcdefg' -key578 = 'abcdefg' -key579 = 'abcdefg' -key58 = 'abcdefg' -key580 = 'abcdefg' -key581 = 'abcdefg' -key582 = 'abcdefg' -key583 = 'abcdefg' -key584 = 'abcdefg' -key585 = 'abcdefg' -key586 = 'abcdefg' -key587 = 'abcdefg' -key588 = 'abcdefg' -key589 = 'abcdefg' -key59 = 'abcdefg' -key590 = 'abcdefg' -key591 = 'abcdefg' -key592 = 'abcdefg' -key593 = 'abcdefg' -key594 = 'abcdefg' -key595 = 'abcdefg' -key596 = 'abcdefg' -key597 = 'abcdefg' -key598 = 'abcdefg' -key599 = 'abcdefg' -key6 = 'abcdefg' -key60 = 'abcdefg' -key600 = 'abcdefg' -key601 = 'abcdefg' -key602 = 'abcdefg' -key603 = 'abcdefg' -key604 = 'abcdefg' -key605 = 'abcdefg' -key606 = 'abcdefg' -key607 = 'abcdefg' -key608 = 'abcdefg' -key609 = 'abcdefg' -key61 = 'abcdefg' -key610 = 'abcdefg' -key611 = 'abcdefg' -key612 = 'abcdefg' -key613 = 'abcdefg' -key614 = 'abcdefg' -key615 = 'abcdefg' -key616 = 'abcdefg' -key617 = 'abcdefg' -key618 = 'abcdefg' -key619 = 'abcdefg' -key62 = 'abcdefg' -key620 = 'abcdefg' -key621 = 'abcdefg' -key622 = 'abcdefg' -key623 = 'abcdefg' -key624 = 'abcdefg' -key625 = 'abcdefg' -key626 = 'abcdefg' -key627 = 'abcdefg' -key628 = 'abcdefg' -key629 = 'abcdefg' -key63 = 'abcdefg' -key630 = 'abcdefg' -key631 = 'abcdefg' -key632 = 'abcdefg' -key633 = 'abcdefg' -key634 = 'abcdefg' -key635 = 'abcdefg' -key636 = 'abcdefg' -key637 = 'abcdefg' -key638 = 'abcdefg' -key639 = 'abcdefg' -key64 = 'abcdefg' -key640 = 'abcdefg' -key641 = 'abcdefg' -key642 = 'abcdefg' -key643 = 'abcdefg' -key644 = 'abcdefg' -key645 = 'abcdefg' -key646 = 'abcdefg' -key647 = 'abcdefg' -key648 = 'abcdefg' -key649 = 'abcdefg' -key65 = 'abcdefg' -key650 = 'abcdefg' -key651 = 'abcdefg' -key652 = 'abcdefg' -key653 = 'abcdefg' -key654 = 'abcdefg' -key655 = 'abcdefg' -key656 = 'abcdefg' -key657 = 'abcdefg' -key658 = 'abcdefg' -key659 = 'abcdefg' -key66 = 'abcdefg' -key660 = 'abcdefg' -key661 = 'abcdefg' -key662 = 'abcdefg' -key663 = 'abcdefg' -key664 = 'abcdefg' -key665 = 'abcdefg' -key666 = 'abcdefg' -key667 = 'abcdefg' -key668 = 'abcdefg' -key669 = 'abcdefg' -key67 = 'abcdefg' -key670 = 'abcdefg' -key671 = 'abcdefg' -key672 = 'abcdefg' -key673 = 'abcdefg' -key674 = 'abcdefg' -key675 = 'abcdefg' -key676 = 'abcdefg' -key677 = 'abcdefg' -key678 = 'abcdefg' -key679 = 'abcdefg' -key68 = 'abcdefg' -key680 = 'abcdefg' -key681 = 'abcdefg' -key682 = 'abcdefg' -key683 = 'abcdefg' -key684 = 'abcdefg' -key685 = 'abcdefg' -key686 = 'abcdefg' -key687 = 'abcdefg' -key688 = 'abcdefg' -key689 = 'abcdefg' -key69 = 'abcdefg' -key690 = 'abcdefg' -key691 = 'abcdefg' -key692 = 'abcdefg' -key693 = 'abcdefg' -key694 = 'abcdefg' -key695 = 'abcdefg' -key696 = 'abcdefg' -key697 = 'abcdefg' -key698 = 'abcdefg' -key699 = 'abcdefg' -key7 = 'abcdefg' -key70 = 'abcdefg' -key700 = 'abcdefg' -key701 = 'abcdefg' -key702 = 'abcdefg' -key703 = 'abcdefg' -key704 = 'abcdefg' -key705 = 'abcdefg' -key706 = 'abcdefg' -key707 = 'abcdefg' -key708 = 'abcdefg' -key709 = 'abcdefg' -key71 = 'abcdefg' -key710 = 'abcdefg' -key711 = 'abcdefg' -key712 = 'abcdefg' -key713 = 'abcdefg' -key714 = 'abcdefg' -key715 = 'abcdefg' -key716 = 'abcdefg' -key717 = 'abcdefg' -key718 = 'abcdefg' -key719 = 'abcdefg' -key72 = 'abcdefg' -key720 = 'abcdefg' -key721 = 'abcdefg' -key722 = 'abcdefg' -key723 = 'abcdefg' -key724 = 'abcdefg' -key725 = 'abcdefg' -key726 = 'abcdefg' -key727 = 'abcdefg' -key728 = 'abcdefg' -key729 = 'abcdefg' -key73 = 'abcdefg' -key730 = 'abcdefg' -key731 = 'abcdefg' -key732 = 'abcdefg' -key733 = 'abcdefg' -key734 = 'abcdefg' -key735 = 'abcdefg' -key736 = 'abcdefg' -key737 = 'abcdefg' -key738 = 'abcdefg' -key739 = 'abcdefg' -key74 = 'abcdefg' -key740 = 'abcdefg' -key741 = 'abcdefg' -key742 = 'abcdefg' -key743 = 'abcdefg' -key744 = 'abcdefg' -key745 = 'abcdefg' -key746 = 'abcdefg' -key747 = 'abcdefg' -key748 = 'abcdefg' -key749 = 'abcdefg' -key75 = 'abcdefg' -key750 = 'abcdefg' -key751 = 'abcdefg' -key752 = 'abcdefg' -key753 = 'abcdefg' -key754 = 'abcdefg' -key755 = 'abcdefg' -key756 = 'abcdefg' -key757 = 'abcdefg' -key758 = 'abcdefg' -key759 = 'abcdefg' -key76 = 'abcdefg' -key760 = 'abcdefg' -key761 = 'abcdefg' -key762 = 'abcdefg' -key763 = 'abcdefg' -key764 = 'abcdefg' -key765 = 'abcdefg' -key766 = 'abcdefg' -key767 = 'abcdefg' -key768 = 'abcdefg' -key769 = 'abcdefg' -key77 = 'abcdefg' -key770 = 'abcdefg' -key771 = 'abcdefg' -key772 = 'abcdefg' -key773 = 'abcdefg' -key774 = 'abcdefg' -key775 = 'abcdefg' -key776 = 'abcdefg' -key777 = 'abcdefg' -key778 = 'abcdefg' -key779 = 'abcdefg' -key78 = 'abcdefg' -key780 = 'abcdefg' -key781 = 'abcdefg' -key782 = 'abcdefg' -key783 = 'abcdefg' -key784 = 'abcdefg' -key785 = 'abcdefg' -key786 = 'abcdefg' -key787 = 'abcdefg' -key788 = 'abcdefg' -key789 = 'abcdefg' -key79 = 'abcdefg' -key790 = 'abcdefg' -key791 = 'abcdefg' -key792 = 'abcdefg' -key793 = 'abcdefg' -key794 = 'abcdefg' -key795 = 'abcdefg' -key796 = 'abcdefg' -key797 = 'abcdefg' -key798 = 'abcdefg' -key799 = 'abcdefg' -key8 = 'abcdefg' -key80 = 'abcdefg' -key800 = 'abcdefg' -key801 = 'abcdefg' -key802 = 'abcdefg' -key803 = 'abcdefg' -key804 = 'abcdefg' -key805 = 'abcdefg' -key806 = 'abcdefg' -key807 = 'abcdefg' -key808 = 'abcdefg' -key809 = 'abcdefg' -key81 = 'abcdefg' -key810 = 'abcdefg' -key811 = 'abcdefg' -key812 = 'abcdefg' -key813 = 'abcdefg' -key814 = 'abcdefg' -key815 = 'abcdefg' -key816 = 'abcdefg' -key817 = 'abcdefg' -key818 = 'abcdefg' -key819 = 'abcdefg' -key82 = 'abcdefg' -key820 = 'abcdefg' -key821 = 'abcdefg' -key822 = 'abcdefg' -key823 = 'abcdefg' -key824 = 'abcdefg' -key825 = 'abcdefg' -key826 = 'abcdefg' -key827 = 'abcdefg' -key828 = 'abcdefg' -key829 = 'abcdefg' -key83 = 'abcdefg' -key830 = 'abcdefg' -key831 = 'abcdefg' -key832 = 'abcdefg' -key833 = 'abcdefg' -key834 = 'abcdefg' -key835 = 'abcdefg' -key836 = 'abcdefg' -key837 = 'abcdefg' -key838 = 'abcdefg' -key839 = 'abcdefg' -key84 = 'abcdefg' -key840 = 'abcdefg' -key841 = 'abcdefg' -key842 = 'abcdefg' -key843 = 'abcdefg' -key844 = 'abcdefg' -key845 = 'abcdefg' -key846 = 'abcdefg' -key847 = 'abcdefg' -key848 = 'abcdefg' -key849 = 'abcdefg' -key85 = 'abcdefg' -key850 = 'abcdefg' -key851 = 'abcdefg' -key852 = 'abcdefg' -key853 = 'abcdefg' -key854 = 'abcdefg' -key855 = 'abcdefg' -key856 = 'abcdefg' -key857 = 'abcdefg' -key858 = 'abcdefg' -key859 = 'abcdefg' -key86 = 'abcdefg' -key860 = 'abcdefg' -key861 = 'abcdefg' -key862 = 'abcdefg' -key863 = 'abcdefg' -key864 = 'abcdefg' -key865 = 'abcdefg' -key866 = 'abcdefg' -key867 = 'abcdefg' -key868 = 'abcdefg' -key869 = 'abcdefg' -key87 = 'abcdefg' -key870 = 'abcdefg' -key871 = 'abcdefg' -key872 = 'abcdefg' -key873 = 'abcdefg' -key874 = 'abcdefg' -key875 = 'abcdefg' -key876 = 'abcdefg' -key877 = 'abcdefg' -key878 = 'abcdefg' -key879 = 'abcdefg' -key88 = 'abcdefg' -key880 = 'abcdefg' -key881 = 'abcdefg' -key882 = 'abcdefg' -key883 = 'abcdefg' -key884 = 'abcdefg' -key885 = 'abcdefg' -key886 = 'abcdefg' -key887 = 'abcdefg' -key888 = 'abcdefg' -key889 = 'abcdefg' -key89 = 'abcdefg' -key890 = 'abcdefg' -key891 = 'abcdefg' -key892 = 'abcdefg' -key893 = 'abcdefg' -key894 = 'abcdefg' -key895 = 'abcdefg' -key896 = 'abcdefg' -key897 = 'abcdefg' -key898 = 'abcdefg' -key899 = 'abcdefg' -key9 = 'abcdefg' -key90 = 'abcdefg' -key900 = 'abcdefg' -key901 = 'abcdefg' -key902 = 'abcdefg' -key903 = 'abcdefg' -key904 = 'abcdefg' -key905 = 'abcdefg' -key906 = 'abcdefg' -key907 = 'abcdefg' -key908 = 'abcdefg' -key909 = 'abcdefg' -key91 = 'abcdefg' -key910 = 'abcdefg' -key911 = 'abcdefg' -key912 = 'abcdefg' -key913 = 'abcdefg' -key914 = 'abcdefg' -key915 = 'abcdefg' -key916 = 'abcdefg' -key917 = 'abcdefg' -key918 = 'abcdefg' -key919 = 'abcdefg' -key92 = 'abcdefg' -key920 = 'abcdefg' -key921 = 'abcdefg' -key922 = 'abcdefg' -key923 = 'abcdefg' -key924 = 'abcdefg' -key925 = 'abcdefg' -key926 = 'abcdefg' -key927 = 'abcdefg' -key928 = 'abcdefg' -key929 = 'abcdefg' -key93 = 'abcdefg' -key930 = 'abcdefg' -key931 = 'abcdefg' -key932 = 'abcdefg' -key933 = 'abcdefg' -key934 = 'abcdefg' -key935 = 'abcdefg' -key936 = 'abcdefg' -key937 = 'abcdefg' -key938 = 'abcdefg' -key939 = 'abcdefg' -key94 = 'abcdefg' -key940 = 'abcdefg' -key941 = 'abcdefg' -key942 = 'abcdefg' -key943 = 'abcdefg' -key944 = 'abcdefg' -key945 = 'abcdefg' -key946 = 'abcdefg' -key947 = 'abcdefg' -key948 = 'abcdefg' -key949 = 'abcdefg' -key95 = 'abcdefg' -key950 = 'abcdefg' -key951 = 'abcdefg' -key952 = 'abcdefg' -key953 = 'abcdefg' -key954 = 'abcdefg' -key955 = 'abcdefg' -key956 = 'abcdefg' -key957 = 'abcdefg' -key958 = 'abcdefg' -key959 = 'abcdefg' -key96 = 'abcdefg' -key960 = 'abcdefg' -key961 = 'abcdefg' -key962 = 'abcdefg' -key963 = 'abcdefg' -key964 = 'abcdefg' -key965 = 'abcdefg' -key966 = 'abcdefg' -key967 = 'abcdefg' -key968 = 'abcdefg' -key969 = 'abcdefg' -key97 = 'abcdefg' -key970 = 'abcdefg' -key971 = 'abcdefg' -key972 = 'abcdefg' -key973 = 'abcdefg' -key974 = 'abcdefg' -key975 = 'abcdefg' -key976 = 'abcdefg' -key977 = 'abcdefg' -key978 = 'abcdefg' -key979 = 'abcdefg' -key98 = 'abcdefg' -key980 = 'abcdefg' -key981 = 'abcdefg' -key982 = 'abcdefg' -key983 = 'abcdefg' -key984 = 'abcdefg' -key985 = 'abcdefg' -key986 = 'abcdefg' -key987 = 'abcdefg' -key988 = 'abcdefg' -key989 = 'abcdefg' -key99 = 'abcdefg' -key990 = 'abcdefg' -key991 = 'abcdefg' -key992 = 'abcdefg' -key993 = 'abcdefg' -key994 = 'abcdefg' -key995 = 'abcdefg' -key996 = 'abcdefg' -key997 = 'abcdefg' -key998 = 'abcdefg' -key999 = 'abcdefg' \ No newline at end of file +key1 = "abcdefg" +key10 = "abcdefg" +key100 = "abcdefg" +key1000 = "abcdefg" +key101 = "abcdefg" +key102 = "abcdefg" +key103 = "abcdefg" +key104 = "abcdefg" +key105 = "abcdefg" +key106 = "abcdefg" +key107 = "abcdefg" +key108 = "abcdefg" +key109 = "abcdefg" +key11 = "abcdefg" +key110 = "abcdefg" +key111 = "abcdefg" +key112 = "abcdefg" +key113 = "abcdefg" +key114 = "abcdefg" +key115 = "abcdefg" +key116 = "abcdefg" +key117 = "abcdefg" +key118 = "abcdefg" +key119 = "abcdefg" +key12 = "abcdefg" +key120 = "abcdefg" +key121 = "abcdefg" +key122 = "abcdefg" +key123 = "abcdefg" +key124 = "abcdefg" +key125 = "abcdefg" +key126 = "abcdefg" +key127 = "abcdefg" +key128 = "abcdefg" +key129 = "abcdefg" +key13 = "abcdefg" +key130 = "abcdefg" +key131 = "abcdefg" +key132 = "abcdefg" +key133 = "abcdefg" +key134 = "abcdefg" +key135 = "abcdefg" +key136 = "abcdefg" +key137 = "abcdefg" +key138 = "abcdefg" +key139 = "abcdefg" +key14 = "abcdefg" +key140 = "abcdefg" +key141 = "abcdefg" +key142 = "abcdefg" +key143 = "abcdefg" +key144 = "abcdefg" +key145 = "abcdefg" +key146 = "abcdefg" +key147 = "abcdefg" +key148 = "abcdefg" +key149 = "abcdefg" +key15 = "abcdefg" +key150 = "abcdefg" +key151 = "abcdefg" +key152 = "abcdefg" +key153 = "abcdefg" +key154 = "abcdefg" +key155 = "abcdefg" +key156 = "abcdefg" +key157 = "abcdefg" +key158 = "abcdefg" +key159 = "abcdefg" +key16 = "abcdefg" +key160 = "abcdefg" +key161 = "abcdefg" +key162 = "abcdefg" +key163 = "abcdefg" +key164 = "abcdefg" +key165 = "abcdefg" +key166 = "abcdefg" +key167 = "abcdefg" +key168 = "abcdefg" +key169 = "abcdefg" +key17 = "abcdefg" +key170 = "abcdefg" +key171 = "abcdefg" +key172 = "abcdefg" +key173 = "abcdefg" +key174 = "abcdefg" +key175 = "abcdefg" +key176 = "abcdefg" +key177 = "abcdefg" +key178 = "abcdefg" +key179 = "abcdefg" +key18 = "abcdefg" +key180 = "abcdefg" +key181 = "abcdefg" +key182 = "abcdefg" +key183 = "abcdefg" +key184 = "abcdefg" +key185 = "abcdefg" +key186 = "abcdefg" +key187 = "abcdefg" +key188 = "abcdefg" +key189 = "abcdefg" +key19 = "abcdefg" +key190 = "abcdefg" +key191 = "abcdefg" +key192 = "abcdefg" +key193 = "abcdefg" +key194 = "abcdefg" +key195 = "abcdefg" +key196 = "abcdefg" +key197 = "abcdefg" +key198 = "abcdefg" +key199 = "abcdefg" +key2 = "abcdefg" +key20 = "abcdefg" +key200 = "abcdefg" +key201 = "abcdefg" +key202 = "abcdefg" +key203 = "abcdefg" +key204 = "abcdefg" +key205 = "abcdefg" +key206 = "abcdefg" +key207 = "abcdefg" +key208 = "abcdefg" +key209 = "abcdefg" +key21 = "abcdefg" +key210 = "abcdefg" +key211 = "abcdefg" +key212 = "abcdefg" +key213 = "abcdefg" +key214 = "abcdefg" +key215 = "abcdefg" +key216 = "abcdefg" +key217 = "abcdefg" +key218 = "abcdefg" +key219 = "abcdefg" +key22 = "abcdefg" +key220 = "abcdefg" +key221 = "abcdefg" +key222 = "abcdefg" +key223 = "abcdefg" +key224 = "abcdefg" +key225 = "abcdefg" +key226 = "abcdefg" +key227 = "abcdefg" +key228 = "abcdefg" +key229 = "abcdefg" +key23 = "abcdefg" +key230 = "abcdefg" +key231 = "abcdefg" +key232 = "abcdefg" +key233 = "abcdefg" +key234 = "abcdefg" +key235 = "abcdefg" +key236 = "abcdefg" +key237 = "abcdefg" +key238 = "abcdefg" +key239 = "abcdefg" +key24 = "abcdefg" +key240 = "abcdefg" +key241 = "abcdefg" +key242 = "abcdefg" +key243 = "abcdefg" +key244 = "abcdefg" +key245 = "abcdefg" +key246 = "abcdefg" +key247 = "abcdefg" +key248 = "abcdefg" +key249 = "abcdefg" +key25 = "abcdefg" +key250 = "abcdefg" +key251 = "abcdefg" +key252 = "abcdefg" +key253 = "abcdefg" +key254 = "abcdefg" +key255 = "abcdefg" +key256 = "abcdefg" +key257 = "abcdefg" +key258 = "abcdefg" +key259 = "abcdefg" +key26 = "abcdefg" +key260 = "abcdefg" +key261 = "abcdefg" +key262 = "abcdefg" +key263 = "abcdefg" +key264 = "abcdefg" +key265 = "abcdefg" +key266 = "abcdefg" +key267 = "abcdefg" +key268 = "abcdefg" +key269 = "abcdefg" +key27 = "abcdefg" +key270 = "abcdefg" +key271 = "abcdefg" +key272 = "abcdefg" +key273 = "abcdefg" +key274 = "abcdefg" +key275 = "abcdefg" +key276 = "abcdefg" +key277 = "abcdefg" +key278 = "abcdefg" +key279 = "abcdefg" +key28 = "abcdefg" +key280 = "abcdefg" +key281 = "abcdefg" +key282 = "abcdefg" +key283 = "abcdefg" +key284 = "abcdefg" +key285 = "abcdefg" +key286 = "abcdefg" +key287 = "abcdefg" +key288 = "abcdefg" +key289 = "abcdefg" +key29 = "abcdefg" +key290 = "abcdefg" +key291 = "abcdefg" +key292 = "abcdefg" +key293 = "abcdefg" +key294 = "abcdefg" +key295 = "abcdefg" +key296 = "abcdefg" +key297 = "abcdefg" +key298 = "abcdefg" +key299 = "abcdefg" +key3 = "abcdefg" +key30 = "abcdefg" +key300 = "abcdefg" +key301 = "abcdefg" +key302 = "abcdefg" +key303 = "abcdefg" +key304 = "abcdefg" +key305 = "abcdefg" +key306 = "abcdefg" +key307 = "abcdefg" +key308 = "abcdefg" +key309 = "abcdefg" +key31 = "abcdefg" +key310 = "abcdefg" +key311 = "abcdefg" +key312 = "abcdefg" +key313 = "abcdefg" +key314 = "abcdefg" +key315 = "abcdefg" +key316 = "abcdefg" +key317 = "abcdefg" +key318 = "abcdefg" +key319 = "abcdefg" +key32 = "abcdefg" +key320 = "abcdefg" +key321 = "abcdefg" +key322 = "abcdefg" +key323 = "abcdefg" +key324 = "abcdefg" +key325 = "abcdefg" +key326 = "abcdefg" +key327 = "abcdefg" +key328 = "abcdefg" +key329 = "abcdefg" +key33 = "abcdefg" +key330 = "abcdefg" +key331 = "abcdefg" +key332 = "abcdefg" +key333 = "abcdefg" +key334 = "abcdefg" +key335 = "abcdefg" +key336 = "abcdefg" +key337 = "abcdefg" +key338 = "abcdefg" +key339 = "abcdefg" +key34 = "abcdefg" +key340 = "abcdefg" +key341 = "abcdefg" +key342 = "abcdefg" +key343 = "abcdefg" +key344 = "abcdefg" +key345 = "abcdefg" +key346 = "abcdefg" +key347 = "abcdefg" +key348 = "abcdefg" +key349 = "abcdefg" +key35 = "abcdefg" +key350 = "abcdefg" +key351 = "abcdefg" +key352 = "abcdefg" +key353 = "abcdefg" +key354 = "abcdefg" +key355 = "abcdefg" +key356 = "abcdefg" +key357 = "abcdefg" +key358 = "abcdefg" +key359 = "abcdefg" +key36 = "abcdefg" +key360 = "abcdefg" +key361 = "abcdefg" +key362 = "abcdefg" +key363 = "abcdefg" +key364 = "abcdefg" +key365 = "abcdefg" +key366 = "abcdefg" +key367 = "abcdefg" +key368 = "abcdefg" +key369 = "abcdefg" +key37 = "abcdefg" +key370 = "abcdefg" +key371 = "abcdefg" +key372 = "abcdefg" +key373 = "abcdefg" +key374 = "abcdefg" +key375 = "abcdefg" +key376 = "abcdefg" +key377 = "abcdefg" +key378 = "abcdefg" +key379 = "abcdefg" +key38 = "abcdefg" +key380 = "abcdefg" +key381 = "abcdefg" +key382 = "abcdefg" +key383 = "abcdefg" +key384 = "abcdefg" +key385 = "abcdefg" +key386 = "abcdefg" +key387 = "abcdefg" +key388 = "abcdefg" +key389 = "abcdefg" +key39 = "abcdefg" +key390 = "abcdefg" +key391 = "abcdefg" +key392 = "abcdefg" +key393 = "abcdefg" +key394 = "abcdefg" +key395 = "abcdefg" +key396 = "abcdefg" +key397 = "abcdefg" +key398 = "abcdefg" +key399 = "abcdefg" +key4 = "abcdefg" +key40 = "abcdefg" +key400 = "abcdefg" +key401 = "abcdefg" +key402 = "abcdefg" +key403 = "abcdefg" +key404 = "abcdefg" +key405 = "abcdefg" +key406 = "abcdefg" +key407 = "abcdefg" +key408 = "abcdefg" +key409 = "abcdefg" +key41 = "abcdefg" +key410 = "abcdefg" +key411 = "abcdefg" +key412 = "abcdefg" +key413 = "abcdefg" +key414 = "abcdefg" +key415 = "abcdefg" +key416 = "abcdefg" +key417 = "abcdefg" +key418 = "abcdefg" +key419 = "abcdefg" +key42 = "abcdefg" +key420 = "abcdefg" +key421 = "abcdefg" +key422 = "abcdefg" +key423 = "abcdefg" +key424 = "abcdefg" +key425 = "abcdefg" +key426 = "abcdefg" +key427 = "abcdefg" +key428 = "abcdefg" +key429 = "abcdefg" +key43 = "abcdefg" +key430 = "abcdefg" +key431 = "abcdefg" +key432 = "abcdefg" +key433 = "abcdefg" +key434 = "abcdefg" +key435 = "abcdefg" +key436 = "abcdefg" +key437 = "abcdefg" +key438 = "abcdefg" +key439 = "abcdefg" +key44 = "abcdefg" +key440 = "abcdefg" +key441 = "abcdefg" +key442 = "abcdefg" +key443 = "abcdefg" +key444 = "abcdefg" +key445 = "abcdefg" +key446 = "abcdefg" +key447 = "abcdefg" +key448 = "abcdefg" +key449 = "abcdefg" +key45 = "abcdefg" +key450 = "abcdefg" +key451 = "abcdefg" +key452 = "abcdefg" +key453 = "abcdefg" +key454 = "abcdefg" +key455 = "abcdefg" +key456 = "abcdefg" +key457 = "abcdefg" +key458 = "abcdefg" +key459 = "abcdefg" +key46 = "abcdefg" +key460 = "abcdefg" +key461 = "abcdefg" +key462 = "abcdefg" +key463 = "abcdefg" +key464 = "abcdefg" +key465 = "abcdefg" +key466 = "abcdefg" +key467 = "abcdefg" +key468 = "abcdefg" +key469 = "abcdefg" +key47 = "abcdefg" +key470 = "abcdefg" +key471 = "abcdefg" +key472 = "abcdefg" +key473 = "abcdefg" +key474 = "abcdefg" +key475 = "abcdefg" +key476 = "abcdefg" +key477 = "abcdefg" +key478 = "abcdefg" +key479 = "abcdefg" +key48 = "abcdefg" +key480 = "abcdefg" +key481 = "abcdefg" +key482 = "abcdefg" +key483 = "abcdefg" +key484 = "abcdefg" +key485 = "abcdefg" +key486 = "abcdefg" +key487 = "abcdefg" +key488 = "abcdefg" +key489 = "abcdefg" +key49 = "abcdefg" +key490 = "abcdefg" +key491 = "abcdefg" +key492 = "abcdefg" +key493 = "abcdefg" +key494 = "abcdefg" +key495 = "abcdefg" +key496 = "abcdefg" +key497 = "abcdefg" +key498 = "abcdefg" +key499 = "abcdefg" +key5 = "abcdefg" +key50 = "abcdefg" +key500 = "abcdefg" +key501 = "abcdefg" +key502 = "abcdefg" +key503 = "abcdefg" +key504 = "abcdefg" +key505 = "abcdefg" +key506 = "abcdefg" +key507 = "abcdefg" +key508 = "abcdefg" +key509 = "abcdefg" +key51 = "abcdefg" +key510 = "abcdefg" +key511 = "abcdefg" +key512 = "abcdefg" +key513 = "abcdefg" +key514 = "abcdefg" +key515 = "abcdefg" +key516 = "abcdefg" +key517 = "abcdefg" +key518 = "abcdefg" +key519 = "abcdefg" +key52 = "abcdefg" +key520 = "abcdefg" +key521 = "abcdefg" +key522 = "abcdefg" +key523 = "abcdefg" +key524 = "abcdefg" +key525 = "abcdefg" +key526 = "abcdefg" +key527 = "abcdefg" +key528 = "abcdefg" +key529 = "abcdefg" +key53 = "abcdefg" +key530 = "abcdefg" +key531 = "abcdefg" +key532 = "abcdefg" +key533 = "abcdefg" +key534 = "abcdefg" +key535 = "abcdefg" +key536 = "abcdefg" +key537 = "abcdefg" +key538 = "abcdefg" +key539 = "abcdefg" +key54 = "abcdefg" +key540 = "abcdefg" +key541 = "abcdefg" +key542 = "abcdefg" +key543 = "abcdefg" +key544 = "abcdefg" +key545 = "abcdefg" +key546 = "abcdefg" +key547 = "abcdefg" +key548 = "abcdefg" +key549 = "abcdefg" +key55 = "abcdefg" +key550 = "abcdefg" +key551 = "abcdefg" +key552 = "abcdefg" +key553 = "abcdefg" +key554 = "abcdefg" +key555 = "abcdefg" +key556 = "abcdefg" +key557 = "abcdefg" +key558 = "abcdefg" +key559 = "abcdefg" +key56 = "abcdefg" +key560 = "abcdefg" +key561 = "abcdefg" +key562 = "abcdefg" +key563 = "abcdefg" +key564 = "abcdefg" +key565 = "abcdefg" +key566 = "abcdefg" +key567 = "abcdefg" +key568 = "abcdefg" +key569 = "abcdefg" +key57 = "abcdefg" +key570 = "abcdefg" +key571 = "abcdefg" +key572 = "abcdefg" +key573 = "abcdefg" +key574 = "abcdefg" +key575 = "abcdefg" +key576 = "abcdefg" +key577 = "abcdefg" +key578 = "abcdefg" +key579 = "abcdefg" +key58 = "abcdefg" +key580 = "abcdefg" +key581 = "abcdefg" +key582 = "abcdefg" +key583 = "abcdefg" +key584 = "abcdefg" +key585 = "abcdefg" +key586 = "abcdefg" +key587 = "abcdefg" +key588 = "abcdefg" +key589 = "abcdefg" +key59 = "abcdefg" +key590 = "abcdefg" +key591 = "abcdefg" +key592 = "abcdefg" +key593 = "abcdefg" +key594 = "abcdefg" +key595 = "abcdefg" +key596 = "abcdefg" +key597 = "abcdefg" +key598 = "abcdefg" +key599 = "abcdefg" +key6 = "abcdefg" +key60 = "abcdefg" +key600 = "abcdefg" +key601 = "abcdefg" +key602 = "abcdefg" +key603 = "abcdefg" +key604 = "abcdefg" +key605 = "abcdefg" +key606 = "abcdefg" +key607 = "abcdefg" +key608 = "abcdefg" +key609 = "abcdefg" +key61 = "abcdefg" +key610 = "abcdefg" +key611 = "abcdefg" +key612 = "abcdefg" +key613 = "abcdefg" +key614 = "abcdefg" +key615 = "abcdefg" +key616 = "abcdefg" +key617 = "abcdefg" +key618 = "abcdefg" +key619 = "abcdefg" +key62 = "abcdefg" +key620 = "abcdefg" +key621 = "abcdefg" +key622 = "abcdefg" +key623 = "abcdefg" +key624 = "abcdefg" +key625 = "abcdefg" +key626 = "abcdefg" +key627 = "abcdefg" +key628 = "abcdefg" +key629 = "abcdefg" +key63 = "abcdefg" +key630 = "abcdefg" +key631 = "abcdefg" +key632 = "abcdefg" +key633 = "abcdefg" +key634 = "abcdefg" +key635 = "abcdefg" +key636 = "abcdefg" +key637 = "abcdefg" +key638 = "abcdefg" +key639 = "abcdefg" +key64 = "abcdefg" +key640 = "abcdefg" +key641 = "abcdefg" +key642 = "abcdefg" +key643 = "abcdefg" +key644 = "abcdefg" +key645 = "abcdefg" +key646 = "abcdefg" +key647 = "abcdefg" +key648 = "abcdefg" +key649 = "abcdefg" +key65 = "abcdefg" +key650 = "abcdefg" +key651 = "abcdefg" +key652 = "abcdefg" +key653 = "abcdefg" +key654 = "abcdefg" +key655 = "abcdefg" +key656 = "abcdefg" +key657 = "abcdefg" +key658 = "abcdefg" +key659 = "abcdefg" +key66 = "abcdefg" +key660 = "abcdefg" +key661 = "abcdefg" +key662 = "abcdefg" +key663 = "abcdefg" +key664 = "abcdefg" +key665 = "abcdefg" +key666 = "abcdefg" +key667 = "abcdefg" +key668 = "abcdefg" +key669 = "abcdefg" +key67 = "abcdefg" +key670 = "abcdefg" +key671 = "abcdefg" +key672 = "abcdefg" +key673 = "abcdefg" +key674 = "abcdefg" +key675 = "abcdefg" +key676 = "abcdefg" +key677 = "abcdefg" +key678 = "abcdefg" +key679 = "abcdefg" +key68 = "abcdefg" +key680 = "abcdefg" +key681 = "abcdefg" +key682 = "abcdefg" +key683 = "abcdefg" +key684 = "abcdefg" +key685 = "abcdefg" +key686 = "abcdefg" +key687 = "abcdefg" +key688 = "abcdefg" +key689 = "abcdefg" +key69 = "abcdefg" +key690 = "abcdefg" +key691 = "abcdefg" +key692 = "abcdefg" +key693 = "abcdefg" +key694 = "abcdefg" +key695 = "abcdefg" +key696 = "abcdefg" +key697 = "abcdefg" +key698 = "abcdefg" +key699 = "abcdefg" +key7 = "abcdefg" +key70 = "abcdefg" +key700 = "abcdefg" +key701 = "abcdefg" +key702 = "abcdefg" +key703 = "abcdefg" +key704 = "abcdefg" +key705 = "abcdefg" +key706 = "abcdefg" +key707 = "abcdefg" +key708 = "abcdefg" +key709 = "abcdefg" +key71 = "abcdefg" +key710 = "abcdefg" +key711 = "abcdefg" +key712 = "abcdefg" +key713 = "abcdefg" +key714 = "abcdefg" +key715 = "abcdefg" +key716 = "abcdefg" +key717 = "abcdefg" +key718 = "abcdefg" +key719 = "abcdefg" +key72 = "abcdefg" +key720 = "abcdefg" +key721 = "abcdefg" +key722 = "abcdefg" +key723 = "abcdefg" +key724 = "abcdefg" +key725 = "abcdefg" +key726 = "abcdefg" +key727 = "abcdefg" +key728 = "abcdefg" +key729 = "abcdefg" +key73 = "abcdefg" +key730 = "abcdefg" +key731 = "abcdefg" +key732 = "abcdefg" +key733 = "abcdefg" +key734 = "abcdefg" +key735 = "abcdefg" +key736 = "abcdefg" +key737 = "abcdefg" +key738 = "abcdefg" +key739 = "abcdefg" +key74 = "abcdefg" +key740 = "abcdefg" +key741 = "abcdefg" +key742 = "abcdefg" +key743 = "abcdefg" +key744 = "abcdefg" +key745 = "abcdefg" +key746 = "abcdefg" +key747 = "abcdefg" +key748 = "abcdefg" +key749 = "abcdefg" +key75 = "abcdefg" +key750 = "abcdefg" +key751 = "abcdefg" +key752 = "abcdefg" +key753 = "abcdefg" +key754 = "abcdefg" +key755 = "abcdefg" +key756 = "abcdefg" +key757 = "abcdefg" +key758 = "abcdefg" +key759 = "abcdefg" +key76 = "abcdefg" +key760 = "abcdefg" +key761 = "abcdefg" +key762 = "abcdefg" +key763 = "abcdefg" +key764 = "abcdefg" +key765 = "abcdefg" +key766 = "abcdefg" +key767 = "abcdefg" +key768 = "abcdefg" +key769 = "abcdefg" +key77 = "abcdefg" +key770 = "abcdefg" +key771 = "abcdefg" +key772 = "abcdefg" +key773 = "abcdefg" +key774 = "abcdefg" +key775 = "abcdefg" +key776 = "abcdefg" +key777 = "abcdefg" +key778 = "abcdefg" +key779 = "abcdefg" +key78 = "abcdefg" +key780 = "abcdefg" +key781 = "abcdefg" +key782 = "abcdefg" +key783 = "abcdefg" +key784 = "abcdefg" +key785 = "abcdefg" +key786 = "abcdefg" +key787 = "abcdefg" +key788 = "abcdefg" +key789 = "abcdefg" +key79 = "abcdefg" +key790 = "abcdefg" +key791 = "abcdefg" +key792 = "abcdefg" +key793 = "abcdefg" +key794 = "abcdefg" +key795 = "abcdefg" +key796 = "abcdefg" +key797 = "abcdefg" +key798 = "abcdefg" +key799 = "abcdefg" +key8 = "abcdefg" +key80 = "abcdefg" +key800 = "abcdefg" +key801 = "abcdefg" +key802 = "abcdefg" +key803 = "abcdefg" +key804 = "abcdefg" +key805 = "abcdefg" +key806 = "abcdefg" +key807 = "abcdefg" +key808 = "abcdefg" +key809 = "abcdefg" +key81 = "abcdefg" +key810 = "abcdefg" +key811 = "abcdefg" +key812 = "abcdefg" +key813 = "abcdefg" +key814 = "abcdefg" +key815 = "abcdefg" +key816 = "abcdefg" +key817 = "abcdefg" +key818 = "abcdefg" +key819 = "abcdefg" +key82 = "abcdefg" +key820 = "abcdefg" +key821 = "abcdefg" +key822 = "abcdefg" +key823 = "abcdefg" +key824 = "abcdefg" +key825 = "abcdefg" +key826 = "abcdefg" +key827 = "abcdefg" +key828 = "abcdefg" +key829 = "abcdefg" +key83 = "abcdefg" +key830 = "abcdefg" +key831 = "abcdefg" +key832 = "abcdefg" +key833 = "abcdefg" +key834 = "abcdefg" +key835 = "abcdefg" +key836 = "abcdefg" +key837 = "abcdefg" +key838 = "abcdefg" +key839 = "abcdefg" +key84 = "abcdefg" +key840 = "abcdefg" +key841 = "abcdefg" +key842 = "abcdefg" +key843 = "abcdefg" +key844 = "abcdefg" +key845 = "abcdefg" +key846 = "abcdefg" +key847 = "abcdefg" +key848 = "abcdefg" +key849 = "abcdefg" +key85 = "abcdefg" +key850 = "abcdefg" +key851 = "abcdefg" +key852 = "abcdefg" +key853 = "abcdefg" +key854 = "abcdefg" +key855 = "abcdefg" +key856 = "abcdefg" +key857 = "abcdefg" +key858 = "abcdefg" +key859 = "abcdefg" +key86 = "abcdefg" +key860 = "abcdefg" +key861 = "abcdefg" +key862 = "abcdefg" +key863 = "abcdefg" +key864 = "abcdefg" +key865 = "abcdefg" +key866 = "abcdefg" +key867 = "abcdefg" +key868 = "abcdefg" +key869 = "abcdefg" +key87 = "abcdefg" +key870 = "abcdefg" +key871 = "abcdefg" +key872 = "abcdefg" +key873 = "abcdefg" +key874 = "abcdefg" +key875 = "abcdefg" +key876 = "abcdefg" +key877 = "abcdefg" +key878 = "abcdefg" +key879 = "abcdefg" +key88 = "abcdefg" +key880 = "abcdefg" +key881 = "abcdefg" +key882 = "abcdefg" +key883 = "abcdefg" +key884 = "abcdefg" +key885 = "abcdefg" +key886 = "abcdefg" +key887 = "abcdefg" +key888 = "abcdefg" +key889 = "abcdefg" +key89 = "abcdefg" +key890 = "abcdefg" +key891 = "abcdefg" +key892 = "abcdefg" +key893 = "abcdefg" +key894 = "abcdefg" +key895 = "abcdefg" +key896 = "abcdefg" +key897 = "abcdefg" +key898 = "abcdefg" +key899 = "abcdefg" +key9 = "abcdefg" +key90 = "abcdefg" +key900 = "abcdefg" +key901 = "abcdefg" +key902 = "abcdefg" +key903 = "abcdefg" +key904 = "abcdefg" +key905 = "abcdefg" +key906 = "abcdefg" +key907 = "abcdefg" +key908 = "abcdefg" +key909 = "abcdefg" +key91 = "abcdefg" +key910 = "abcdefg" +key911 = "abcdefg" +key912 = "abcdefg" +key913 = "abcdefg" +key914 = "abcdefg" +key915 = "abcdefg" +key916 = "abcdefg" +key917 = "abcdefg" +key918 = "abcdefg" +key919 = "abcdefg" +key92 = "abcdefg" +key920 = "abcdefg" +key921 = "abcdefg" +key922 = "abcdefg" +key923 = "abcdefg" +key924 = "abcdefg" +key925 = "abcdefg" +key926 = "abcdefg" +key927 = "abcdefg" +key928 = "abcdefg" +key929 = "abcdefg" +key93 = "abcdefg" +key930 = "abcdefg" +key931 = "abcdefg" +key932 = "abcdefg" +key933 = "abcdefg" +key934 = "abcdefg" +key935 = "abcdefg" +key936 = "abcdefg" +key937 = "abcdefg" +key938 = "abcdefg" +key939 = "abcdefg" +key94 = "abcdefg" +key940 = "abcdefg" +key941 = "abcdefg" +key942 = "abcdefg" +key943 = "abcdefg" +key944 = "abcdefg" +key945 = "abcdefg" +key946 = "abcdefg" +key947 = "abcdefg" +key948 = "abcdefg" +key949 = "abcdefg" +key95 = "abcdefg" +key950 = "abcdefg" +key951 = "abcdefg" +key952 = "abcdefg" +key953 = "abcdefg" +key954 = "abcdefg" +key955 = "abcdefg" +key956 = "abcdefg" +key957 = "abcdefg" +key958 = "abcdefg" +key959 = "abcdefg" +key96 = "abcdefg" +key960 = "abcdefg" +key961 = "abcdefg" +key962 = "abcdefg" +key963 = "abcdefg" +key964 = "abcdefg" +key965 = "abcdefg" +key966 = "abcdefg" +key967 = "abcdefg" +key968 = "abcdefg" +key969 = "abcdefg" +key97 = "abcdefg" +key970 = "abcdefg" +key971 = "abcdefg" +key972 = "abcdefg" +key973 = "abcdefg" +key974 = "abcdefg" +key975 = "abcdefg" +key976 = "abcdefg" +key977 = "abcdefg" +key978 = "abcdefg" +key979 = "abcdefg" +key98 = "abcdefg" +key980 = "abcdefg" +key981 = "abcdefg" +key982 = "abcdefg" +key983 = "abcdefg" +key984 = "abcdefg" +key985 = "abcdefg" +key986 = "abcdefg" +key987 = "abcdefg" +key988 = "abcdefg" +key989 = "abcdefg" +key99 = "abcdefg" +key990 = "abcdefg" +key991 = "abcdefg" +key992 = "abcdefg" +key993 = "abcdefg" +key994 = "abcdefg" +key995 = "abcdefg" +key996 = "abcdefg" +key997 = "abcdefg" +key998 = "abcdefg" +key999 = "abcdefg" \ No newline at end of file diff --git a/spec/test-data/test.toml b/spec/test-data/test.toml index ebf8b10..ed9dc0a 100644 --- a/spec/test-data/test.toml +++ b/spec/test-data/test.toml @@ -1,54 +1,54 @@ -author = 'Mark Gillard' +author = "Mark Gillard" cpp = 17 -description = 'TOML for C++' -extra_files = [ 'images/banner_small.png', 'images/badge-awesome.svg', 'images/badge-TOML.svg', 'images/badge-C++20.svg' ] -favicon = 'images/favicon.ico' -github = 'marzer/tomlplusplus' -license = [ 'MIT', 'https://github.com/marzer/tomlplusplus/blob/master/LICENSE' ] -logo = 'images/logo.png' -name = 'toml++' -navbar = [ 'namespaces', 'annotated' ] +description = "TOML for C++" +extra_files = [ "images/banner_small.png", "images/badge-awesome.svg", "images/badge-TOML.svg", "images/badge-C++20.svg" ] +favicon = "images/favicon.ico" +github = "marzer/tomlplusplus" +license = [ "MIT", "https://github.com/marzer/tomlplusplus/blob/master/LICENSE" ] +logo = "images/logo.png" +name = "toml++" +navbar = [ "namespaces", "annotated" ] show_includes = 0 -theme = 'dark' +theme = "dark" [autolinks] -"(?:toml::)?default[_ ]formatters?" = 'classtoml_1_1default__formatter.html' -"(?:toml::)?json[_ ]formatters?" = 'classtoml_1_1json__formatter.html' -"(?:toml::)?node[_ ]views?" = 'classtoml_1_1node__view.html' -"(?:toml::)?parse[_ ]errors?" = 'classtoml_1_1parse__error.html' -"(?:toml::)?parse[_ ]results?" = 'classtoml_1_1parse__result.html' -"(?:toml::)?source[_ ]positions?" = 'structtoml_1_1source__position.html' -"(?:toml::)?source[_ ]regions?" = 'structtoml_1_1source__region.html' +"(?:toml::)?default[_ ]formatters?" = "classtoml_1_1default__formatter.html" +"(?:toml::)?json[_ ]formatters?" = "classtoml_1_1json__formatter.html" +"(?:toml::)?node[_ ]views?" = "classtoml_1_1node__view.html" +"(?:toml::)?parse[_ ]errors?" = "classtoml_1_1parse__error.html" +"(?:toml::)?parse[_ ]results?" = "classtoml_1_1parse__result.html" +"(?:toml::)?source[_ ]positions?" = "structtoml_1_1source__position.html" +"(?:toml::)?source[_ ]regions?" = "structtoml_1_1source__region.html" [badges] -"1. C++20" = [ 'badge-C++20.svg', 'https://en.cppreference.com/w/cpp/compiler_support' ] -"2. TOML v1.0.0" = [ 'badge-TOML.svg', 'https://toml.io/en/v1.0.0' ] +"1. C++20" = [ "badge-C++20.svg", "https://en.cppreference.com/w/cpp/compiler_support" ] +"2. TOML v1.0.0" = [ "badge-TOML.svg", "https://toml.io/en/v1.0.0" ] "3. CircleCI" = [ - 'https://img.shields.io/circleci/build/github/marzer/tomlplusplus?label=circle%20ci&logo=circleci&logoColor=white&style=flat-square', - 'https://circleci.com/gh/marzer/tomlplusplus' +"https://img.shields.io/circleci/build/github/marzer/tomlplusplus?label=circle%20ci&logo=circleci&logoColor=white&style=flat-square", +"https://circleci.com/gh/marzer/tomlplusplus" ] -"4. Mentioned in Awesome C++" = [ 'badge-awesome.svg', 'https://github.com/fffaraz/awesome-cpp' ] +"4. Mentioned in Awesome C++" = [ "badge-awesome.svg", "https://github.com/fffaraz/awesome-cpp" ] [code_blocks] -macros = [ 'TOML_[A-Z0-9_]+?', 'print_value' ] -string_literals = [ '_toml' ] +macros = [ "TOML_[A-Z0-9_]+?", "print_value" ] +string_literals = [ "_toml" ] [images] -paths = [ 'images' ] +paths = [ "images" ] [macros] -"TOML_ABI_NAMESPACE_BOOL(...)" = 'static_assert(true)' -"TOML_ABI_NAMESPACE_START(...)" = 'static_assert(true)' -"TOML_ASYMMETRICAL_EQUALITY_OPS(...)" = 'static_assert(true)' +"TOML_ABI_NAMESPACE_BOOL(...)" = "static_assert(true)" +"TOML_ABI_NAMESPACE_START(...)" = "static_assert(true)" +"TOML_ASYMMETRICAL_EQUALITY_OPS(...)" = "static_assert(true)" [meta_tags] -google-site-verification = 'gbtcNgKlNiPSMKkYMw4zWFVWGPH_oU93m9n_-nb4qK8' +google-site-verification = "gbtcNgKlNiPSMKkYMw4zWFVWGPH_oU93m9n_-nb4qK8" [sources] -paths = [ 'pages' ] -patterns = [ '*.h', '*.dox' ] -recursive_paths = [ '../include' ] -strip_paths = [ '../include' ] +paths = [ "pages" ] +patterns = [ "*.h", "*.dox" ] +recursive_paths = [ "../include" ] +strip_paths = [ "../include" ] [warnings] enabled = 1 diff --git a/spec/test-data/test2.toml b/spec/test-data/test2.toml index b62c2f0..10f5583 100644 --- a/spec/test-data/test2.toml +++ b/spec/test-data/test2.toml @@ -1,22 +1,22 @@ -title = 'TOML Example' +title = "TOML Example" [database] -data = [ [ 'delta', 'phi' ], [ 3.14 ] ] +data = [ [ "delta", "phi" ], [ 3.1400000000000001 ] ] enabled = 1 ports = [ 8000, 8001, 8002 ] - [database.temp_targets] - case = 72 - cpu = 79.5 +[database.temp_targets] +case = 72 +cpu = 79.5 [owner] dob = 1979-05-27T07:32:00-08:00 -name = 'Tom Preston-Werner' +name = "Tom Preston-Werner" [servers.alpha] -ip = '10.0.0.1' -role = 'frontend' +ip = "10.0.0.1" +role = "frontend" [servers.beta] -ip = '10.0.0.2' -role = 'backend' \ No newline at end of file +ip = "10.0.0.2" +role = "backend" \ No newline at end of file diff --git a/src/decoding/decoding.cpp b/src/decoding/decoding.cpp index 7b11cc4..af0ff3f 100644 --- a/src/decoding/decoding.cpp +++ b/src/decoding/decoding.cpp @@ -1,28 +1,24 @@ #include "decoding.hpp" -void insertNodeInTable(sol::table & luaTable, std::string * key, size_t * index, void * value) { +void insertNodeInTable( + sol::table & luaTable, std::variant keyOrIndex, void * value) { auto node = reinterpret_cast(value); switch (node->type()) { case toml::node_type::string: { auto v = std::string(*node->as_string()); - - if (index != NULL) { - luaTable[*index] = v.c_str(); - } else { - luaTable[*key] = v.c_str(); - } + try { + luaTable[std::get(keyOrIndex)] = v; + } catch (std::bad_variant_access) { luaTable[std::get(keyOrIndex)] = v; } break; } case toml::node_type::integer: { auto v = int64_t { *node->as_integer() }; - if (index != NULL) { - luaTable[*index] = v; - } else { - luaTable[*key] = v; - } + try { + luaTable[std::get(keyOrIndex)] = v; + } catch (std::bad_variant_access) { luaTable[std::get(keyOrIndex)] = v; } break; } @@ -30,11 +26,9 @@ void insertNodeInTable(sol::table & luaTable, std::string * key, size_t * index, case toml::node_type::floating_point: { auto v = double { *node->as_floating_point() }; - if (index != NULL) { - luaTable[*index] = v; - } else { - luaTable[*key] = v; - } + try { + luaTable[std::get(keyOrIndex)] = v; + } catch (std::bad_variant_access) { luaTable[std::get(keyOrIndex)] = v; } break; } @@ -42,11 +36,9 @@ void insertNodeInTable(sol::table & luaTable, std::string * key, size_t * index, case toml::node_type::boolean: { auto v = *node->as_boolean() ? 1 : 0; - if (index != NULL) { - luaTable[*index] = v; - } else { - luaTable[*key] = v; - } + try { + luaTable[std::get(keyOrIndex)] = v; + } catch (std::bad_variant_access) { luaTable[std::get(keyOrIndex)] = v; } break; } @@ -57,10 +49,10 @@ void insertNodeInTable(sol::table & luaTable, std::string * key, size_t * index, newLTable.push(); - if (index != NULL) { - luaTable[*index] = newLTable; - } else { - luaTable[*key] = newLTable; + try { + luaTable[std::get(keyOrIndex)] = newLTable; + } catch (std::bad_variant_access) { + luaTable[std::get(keyOrIndex)] = newLTable; } break; @@ -72,10 +64,10 @@ void insertNodeInTable(sol::table & luaTable, std::string * key, size_t * index, newLTable.push(); - if (index != NULL) { - luaTable[*index] = newLTable; - } else { - luaTable[*key] = newLTable; + try { + luaTable[std::get(keyOrIndex)] = newLTable; + } catch (std::bad_variant_access) { + luaTable[std::get(keyOrIndex)] = newLTable; } break; @@ -83,22 +75,18 @@ void insertNodeInTable(sol::table & luaTable, std::string * key, size_t * index, case toml::node_type::date: { auto v = TOMLDate(*(*node->as_date())); - if (index != NULL) { - luaTable[*index] = v; - } else { - luaTable[*key] = v; - } + try { + luaTable[std::get(keyOrIndex)] = v; + } catch (std::bad_variant_access) { luaTable[std::get(keyOrIndex)] = v; } break; } case toml::node_type::time: { auto v = TOMLTime(*(*node->as_time())); - if (index != NULL) { - luaTable[*index] = v; - } else { - luaTable[*key] = v; - } + try { + luaTable[std::get(keyOrIndex)] = v; + } catch (std::bad_variant_access) { luaTable[std::get(keyOrIndex)] = v; } break; } @@ -109,11 +97,9 @@ void insertNodeInTable(sol::table & luaTable, std::string * key, size_t * index, if (v.offset.has_value()) { dt.setTimeOffset(TOMLTimeOffset(v.offset.value())); } - if (index != NULL) { - luaTable[*index] = dt; - } else { - luaTable[*key] = dt; - } + try { + luaTable[std::get(keyOrIndex)] = dt; + } catch (std::bad_variant_access) { luaTable[std::get(keyOrIndex)] = dt; } break; } @@ -129,7 +115,7 @@ void tomlArrayToLuaArray(toml::array & tomlArray, sol::table & luaTable) { for (size_t i = 0; i < size; i++) { auto element = tomlArray.get(i); size_t index = i + 1; - insertNodeInTable(luaTable, NULL, &index, reinterpret_cast(element)); + insertNodeInTable(luaTable, index, reinterpret_cast(element)); }; } @@ -137,6 +123,6 @@ void tomlArrayToLuaArray(toml::array & tomlArray, sol::table & luaTable) { void tomlToLuaTable(toml::table & table, sol::table & lTable) { for (auto && [key, value] : table) { auto k = std::string(key); - insertNodeInTable(lTable, &k, NULL, reinterpret_cast(&value)); + insertNodeInTable(lTable, k, reinterpret_cast(&value)); } } diff --git a/src/encoding/encoding.cpp b/src/encoding/encoding.cpp index 09acddc..e3b34a7 100644 --- a/src/encoding/encoding.cpp +++ b/src/encoding/encoding.cpp @@ -1,6 +1,8 @@ #include "encoding.hpp" #include "sol/sol.hpp" #include "utilities/utilities.hpp" +#include +#include void * luaValueToTomlNode(sol::object & luaValue) { switch (luaValue.get_type()) { @@ -110,7 +112,7 @@ toml::table tomlTableFromLuaTable(sol::table luaTable) { auto k = keyToString(key); throw sol::error((k->empty() ? "The keys in a table" : std::string("The key ") + k.value() + - " should be a string, not a " + + " should be a string, not " + solLuaDataTypeToString(key.get_type())) .c_str()); } diff --git a/src/include/magicEnum/magic_enum.hpp b/src/include/magicEnum/magic_enum.hpp new file mode 100644 index 0000000..3a66d4b --- /dev/null +++ b/src/include/magicEnum/magic_enum.hpp @@ -0,0 +1,1430 @@ +// __ __ _ ______ _____ +// | \/ | (_) | ____| / ____|_ _ +// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ +// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| +// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| +// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| +// __/ | https://github.com/Neargye/magic_enum +// |___/ version 0.7.3 +// +// Licensed under the MIT License . +// SPDX-License-Identifier: MIT +// Copyright (c) 2019 - 2022 Daniil Goncharov . +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#ifndef NEARGYE_MAGIC_ENUM_HPP +#define NEARGYE_MAGIC_ENUM_HPP + +#define MAGIC_ENUM_VERSION_MAJOR 0 +#define MAGIC_ENUM_VERSION_MINOR 7 +#define MAGIC_ENUM_VERSION_PATCH 3 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(MAGIC_ENUM_CONFIG_FILE) +#include MAGIC_ENUM_CONFIG_FILE +#endif + +#if !defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL) +#include +#endif +#if !defined(MAGIC_ENUM_USING_ALIAS_STRING) +#include +#endif +#if !defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW) +#include +#endif + +#if defined(__clang__) +# pragma clang diagnostic push +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // May be used uninitialized 'return {};'. +#elif defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable : 26495) // Variable 'static_string::chars_' is uninitialized. +# pragma warning(disable : 28020) // Arithmetic overflow: Using operator '-' on a 4 byte value and then casting the result to a 8 byte value. +# pragma warning(disable : 26451) // The expression '0<=_Param_(1)&&_Param_(1)<=1-1' is not true at this call. +#endif + +// Checks magic_enum compiler compatibility. +#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1910 +# undef MAGIC_ENUM_SUPPORTED +# define MAGIC_ENUM_SUPPORTED 1 +#endif + +// Checks magic_enum compiler aliases compatibility. +#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1920 +# undef MAGIC_ENUM_SUPPORTED_ALIASES +# define MAGIC_ENUM_SUPPORTED_ALIASES 1 +#endif + +// Enum value must be greater or equals than MAGIC_ENUM_RANGE_MIN. By default MAGIC_ENUM_RANGE_MIN = -128. +// If need another min range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN. +#if !defined(MAGIC_ENUM_RANGE_MIN) +# define MAGIC_ENUM_RANGE_MIN -128 +#endif + +// Enum value must be less or equals than MAGIC_ENUM_RANGE_MAX. By default MAGIC_ENUM_RANGE_MAX = 128. +// If need another max range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MAX. +#if !defined(MAGIC_ENUM_RANGE_MAX) +# define MAGIC_ENUM_RANGE_MAX 128 +#endif + +namespace magic_enum { + +// If need another optional type, define the macro MAGIC_ENUM_USING_ALIAS_OPTIONAL. +#if defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL) +MAGIC_ENUM_USING_ALIAS_OPTIONAL +#else +using std::optional; +#endif + +// If need another string_view type, define the macro MAGIC_ENUM_USING_ALIAS_STRING_VIEW. +#if defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW) +MAGIC_ENUM_USING_ALIAS_STRING_VIEW +#else +using std::string_view; +#endif + +// If need another string type, define the macro MAGIC_ENUM_USING_ALIAS_STRING. +#if defined(MAGIC_ENUM_USING_ALIAS_STRING) +MAGIC_ENUM_USING_ALIAS_STRING +#else +using std::string; +#endif + +namespace customize { + +// Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]. By default MAGIC_ENUM_RANGE_MIN = -128, MAGIC_ENUM_RANGE_MAX = 128. +// If need another range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN and MAGIC_ENUM_RANGE_MAX. +// If need another range for specific enum type, add specialization enum_range for necessary enum type. +template +struct enum_range { + static_assert(std::is_enum_v, "magic_enum::customize::enum_range requires enum type."); + static constexpr int min = MAGIC_ENUM_RANGE_MIN; + static constexpr int max = MAGIC_ENUM_RANGE_MAX; + static_assert(max > min, "magic_enum::customize::enum_range requires max > min."); +}; + +static_assert(MAGIC_ENUM_RANGE_MAX > MAGIC_ENUM_RANGE_MIN, "MAGIC_ENUM_RANGE_MAX must be greater than MAGIC_ENUM_RANGE_MIN."); +static_assert((MAGIC_ENUM_RANGE_MAX - MAGIC_ENUM_RANGE_MIN) < (std::numeric_limits::max)(), "MAGIC_ENUM_RANGE must be less than UINT16_MAX."); + +namespace detail { +enum class default_customize_tag {}; +enum class invalid_customize_tag {}; +} // namespace magic_enum::customize::detail + +using customize_t = std::variant; + +// Default customize. +inline constexpr auto default_tag = detail::default_customize_tag{}; +// Invalid customize. +inline constexpr auto invalid_tag = detail::invalid_customize_tag{}; + +// If need custom names for enum, add specialization enum_name for necessary enum type. +template +constexpr customize_t enum_name(E) noexcept { + return default_tag; +} + +// If need custom type name for enum, add specialization enum_type_name for necessary enum type. +template +constexpr customize_t enum_type_name() noexcept { + return default_tag; +} + +} // namespace magic_enum::customize + +namespace detail { + +template >>> +using enum_constant = std::integral_constant, V>; + +template +inline constexpr bool always_false_v = false; + +template +struct supported +#if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED || defined(MAGIC_ENUM_NO_CHECK_SUPPORT) + : std::true_type {}; +#else + : std::false_type {}; +#endif + +template +struct has_is_flags : std::false_type {}; + +template +struct has_is_flags::is_flags)>> : std::bool_constant::is_flags)>>> {}; + +template +struct range_min : std::integral_constant {}; + +template +struct range_min::min)>> : std::integral_constant::min), customize::enum_range::min> {}; + +template +struct range_max : std::integral_constant {}; + +template +struct range_max::max)>> : std::integral_constant::max), customize::enum_range::max> {}; + +template +class static_string { + public: + constexpr explicit static_string(string_view str) noexcept : static_string{str, std::make_index_sequence{}} { + assert(str.size() == N); + } + + constexpr const char* data() const noexcept { return chars_; } + + constexpr std::size_t size() const noexcept { return N; } + + constexpr operator string_view() const noexcept { return {data(), size()}; } + + private: + template + constexpr static_string(string_view str, std::index_sequence) noexcept : chars_{str[I]..., '\0'} {} + + char chars_[N + 1]; +}; + +template <> +class static_string<0> { + public: + constexpr explicit static_string() = default; + + constexpr explicit static_string(string_view) noexcept {} + + constexpr const char* data() const noexcept { return nullptr; } + + constexpr std::size_t size() const noexcept { return 0; } + + constexpr operator string_view() const noexcept { return {}; } +}; + +constexpr string_view pretty_name(string_view name) noexcept { + for (std::size_t i = name.size(); i > 0; --i) { + if (!((name[i - 1] >= '0' && name[i - 1] <= '9') || + (name[i - 1] >= 'a' && name[i - 1] <= 'z') || + (name[i - 1] >= 'A' && name[i - 1] <= 'Z') || +#if defined(MAGIC_ENUM_ENABLE_NONASCII) + (name[i - 1] & 0x80) || +#endif + (name[i - 1] == '_'))) { + name.remove_prefix(i); + break; + } + } + + if (name.size() > 0 && ((name.front() >= 'a' && name.front() <= 'z') || + (name.front() >= 'A' && name.front() <= 'Z') || +#if defined(MAGIC_ENUM_ENABLE_NONASCII) + (name.front() & 0x80) || +#endif + (name.front() == '_'))) { + return name; + } + + return {}; // Invalid name. +} + +class case_insensitive { + static constexpr char to_lower(char c) noexcept { + return (c >= 'A' && c <= 'Z') ? static_cast(c + ('a' - 'A')) : c; + } + + public: + template + constexpr auto operator()([[maybe_unused]] L lhs, [[maybe_unused]] R rhs) const noexcept -> std::enable_if_t, char> && std::is_same_v, char>, bool> { +#if defined(MAGIC_ENUM_ENABLE_NONASCII) + static_assert(always_false_v, "magic_enum::case_insensitive not supported Non-ASCII feature."); + return false; +#else + return to_lower(lhs) == to_lower(rhs); +#endif + } +}; + +constexpr std::size_t find(string_view str, char c) noexcept { +#if defined(__clang__) && __clang_major__ < 9 && defined(__GLIBCXX__) || defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__) +// https://stackoverflow.com/questions/56484834/constexpr-stdstring-viewfind-last-of-doesnt-work-on-clang-8-with-libstdc +// https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html + constexpr bool workaround = true; +#else + constexpr bool workaround = false; +#endif + + if constexpr (workaround) { + for (std::size_t i = 0; i < str.size(); ++i) { + if (str[i] == c) { + return i; + } + } + + return string_view::npos; + } else { + return str.find_first_of(c); + } +} + +template +constexpr std::array, N> to_array(T (&a)[N], std::index_sequence) noexcept { + return {{a[I]...}}; +} + +template +constexpr bool is_default_predicate() noexcept { + return std::is_same_v, std::equal_to> || + std::is_same_v, std::equal_to<>>; +} + +template +constexpr bool is_nothrow_invocable() { + return is_default_predicate() || + std::is_nothrow_invocable_r_v; +} + +template +constexpr bool cmp_equal(string_view lhs, string_view rhs, [[maybe_unused]] BinaryPredicate&& p) noexcept(is_nothrow_invocable()) { +#if defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__) + // https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html + // https://developercommunity.visualstudio.com/content/problem/232218/c-constexpr-string-view.html + constexpr bool workaround = true; +#else + constexpr bool workaround = false; +#endif + + if constexpr (!is_default_predicate() || workaround) { + if (lhs.size() != rhs.size()) { + return false; + } + + const auto size = lhs.size(); + for (std::size_t i = 0; i < size; ++i) { + if (!p(lhs[i], rhs[i])) { + return false; + } + } + + return true; + } else { + return lhs == rhs; + } +} + +template +constexpr bool cmp_less(L lhs, R rhs) noexcept { + static_assert(std::is_integral_v && std::is_integral_v, "magic_enum::detail::cmp_less requires integral type."); + + if constexpr (std::is_signed_v == std::is_signed_v) { + // If same signedness (both signed or both unsigned). + return lhs < rhs; + } else if constexpr (std::is_same_v) { // bool special case + return static_cast(lhs) < rhs; + } else if constexpr (std::is_same_v) { // bool special case + return lhs < static_cast(rhs); + } else if constexpr (std::is_signed_v) { + // If 'right' is negative, then result is 'false', otherwise cast & compare. + return rhs > 0 && lhs < static_cast>(rhs); + } else { + // If 'left' is negative, then result is 'true', otherwise cast & compare. + return lhs < 0 || static_cast>(lhs) < rhs; + } +} + +template +constexpr I log2(I value) noexcept { + static_assert(std::is_integral_v, "magic_enum::detail::log2 requires integral type."); + + if constexpr (std::is_same_v) { // bool special case + return assert(false), value; + } else { + auto ret = I{0}; + for (; value > I{1}; value >>= I{1}, ++ret) {} + + return ret; + } +} + +template +inline constexpr bool is_enum_v = std::is_enum_v && std::is_same_v>; + +template +constexpr auto n() noexcept { + static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); + + [[maybe_unused]] constexpr auto custom = customize::enum_type_name(); + static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); + if constexpr (custom.index() == 0) { + constexpr auto name = std::get(custom); + static_assert(!name.empty(), "magic_enum::customize requires not empty string."); + return static_string{name}; + } else if constexpr (custom.index() == 1 && supported::value) { +#if defined(__clang__) || defined(__GNUC__) + constexpr auto name = pretty_name({__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 2}); +#elif defined(_MSC_VER) + constexpr auto name = pretty_name({__FUNCSIG__, sizeof(__FUNCSIG__) - 17}); +#else + constexpr auto name = string_view{}; +#endif + return static_string{name}; + } else { + return static_string<0>{}; // Unsupported compiler or Invalid customize. + } +} + +template +inline constexpr auto type_name_v = n(); + +template +constexpr auto n() noexcept { + static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); + + [[maybe_unused]] constexpr auto custom = customize::enum_name(V); + static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); + if constexpr (custom.index() == 0) { + constexpr auto name = std::get(custom); + static_assert(!name.empty(), "magic_enum::customize requires not empty string."); + return static_string{name}; + } else if constexpr (custom.index() == 1 && supported::value) { +#if defined(__clang__) || defined(__GNUC__) + constexpr auto name = pretty_name({__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 2}); +#elif defined(_MSC_VER) + constexpr auto name = pretty_name({__FUNCSIG__, sizeof(__FUNCSIG__) - 17}); +#else + constexpr auto name = string_view{}; +#endif + return static_string{name}; + } else { + return static_string<0>{}; // Unsupported compiler or Invalid customize. + } +} + +template +inline constexpr auto enum_name_v = n(); + +template +constexpr bool is_valid() noexcept { + static_assert(is_enum_v, "magic_enum::detail::is_valid requires enum type."); + + return n(V)>().size() != 0; +} + +template > +constexpr E value(std::size_t i) noexcept { + static_assert(is_enum_v, "magic_enum::detail::value requires enum type."); + + if constexpr (std::is_same_v) { // bool special case + static_assert(O == 0, "magic_enum::detail::value requires valid offset."); + + return static_cast(i); + } else if constexpr (IsFlags) { + return static_cast(U{1} << static_cast(static_cast(i) + O)); + } else { + return static_cast(static_cast(i) + O); + } +} + +template > +constexpr int reflected_min() noexcept { + static_assert(is_enum_v, "magic_enum::detail::reflected_min requires enum type."); + + if constexpr (IsFlags) { + return 0; + } else { + constexpr auto lhs = range_min::value; + constexpr auto rhs = (std::numeric_limits::min)(); + + if constexpr (cmp_less(rhs, lhs)) { + return lhs; + } else { + return rhs; + } + } +} + +template > +constexpr int reflected_max() noexcept { + static_assert(is_enum_v, "magic_enum::detail::reflected_max requires enum type."); + + if constexpr (IsFlags) { + return std::numeric_limits::digits - 1; + } else { + constexpr auto lhs = range_max::value; + constexpr auto rhs = (std::numeric_limits::max)(); + + if constexpr (cmp_less(lhs, rhs)) { + return lhs; + } else { + return rhs; + } + } +} + +template +inline constexpr auto reflected_min_v = reflected_min(); + +template +inline constexpr auto reflected_max_v = reflected_max(); + +template +constexpr std::size_t values_count(const bool (&valid)[N]) noexcept { + auto count = std::size_t{0}; + for (std::size_t i = 0; i < N; ++i) { + if (valid[i]) { + ++count; + } + } + + return count; +} + +template +constexpr auto values(std::index_sequence) noexcept { + static_assert(is_enum_v, "magic_enum::detail::values requires enum type."); + constexpr bool valid[sizeof...(I)] = {is_valid(I)>()...}; + constexpr std::size_t count = values_count(valid); + + if constexpr (count > 0) { + E values[count] = {}; + for (std::size_t i = 0, v = 0; v < count; ++i) { + if (valid[i]) { + values[v++] = value(i); + } + } + + return to_array(values, std::make_index_sequence{}); + } else { + return std::array{}; + } +} + +template > +constexpr auto values() noexcept { + static_assert(is_enum_v, "magic_enum::detail::values requires enum type."); + constexpr auto min = reflected_min_v; + constexpr auto max = reflected_max_v; + constexpr auto range_size = max - min + 1; + static_assert(range_size > 0, "magic_enum::enum_range requires valid size."); + static_assert(range_size < (std::numeric_limits::max)(), "magic_enum::enum_range requires valid size."); + + return values>(std::make_index_sequence{}); +} + +template > +constexpr bool is_flags_enum() noexcept { + static_assert(is_enum_v, "magic_enum::detail::is_flags_enum requires enum type."); + + if constexpr (has_is_flags::value) { + return customize::enum_range::is_flags; + } else if constexpr (std::is_same_v) { // bool special case + return false; + } else { +#if defined(MAGIC_ENUM_NO_CHECK_FLAGS) + return false; +#else + constexpr auto flags_values = values(); + constexpr auto default_values = values(); + if (flags_values.size() == 0 || default_values.size() > flags_values.size()) { + return false; + } + for (std::size_t i = 0; i < default_values.size(); ++i) { + const auto v = static_cast(default_values[i]); + if (v != 0 && (v & (v - 1)) != 0) { + return false; + } + } + return flags_values.size() > 0; +#endif + } +} + +template +inline constexpr bool is_flags_v = is_flags_enum(); + +template +inline constexpr std::array values_v = values>(); + +template > +using values_t = decltype((values_v)); + +template +inline constexpr auto count_v = values_v.size(); + +template > +inline constexpr auto min_v = (count_v > 0) ? static_cast(values_v.front()) : U{0}; + +template > +inline constexpr auto max_v = (count_v > 0) ? static_cast(values_v.back()) : U{0}; + +template +constexpr auto names(std::index_sequence) noexcept { + static_assert(is_enum_v, "magic_enum::detail::names requires enum type."); + + return std::array{{enum_name_v[I]>...}}; +} + +template +inline constexpr std::array names_v = names(std::make_index_sequence>{}); + +template > +using names_t = decltype((names_v)); + +template +constexpr auto entries(std::index_sequence) noexcept { + static_assert(is_enum_v, "magic_enum::detail::entries requires enum type."); + + return std::array, sizeof...(I)>{{{values_v[I], enum_name_v[I]>}...}}; +} + +template +inline constexpr std::array entries_v = entries(std::make_index_sequence>{}); + +template > +using entries_t = decltype((entries_v)); + +template > +constexpr bool is_sparse() noexcept { + static_assert(is_enum_v, "magic_enum::detail::is_sparse requires enum type."); + + if constexpr (count_v == 0) { + return false; + } else if constexpr (std::is_same_v) { // bool special case + return false; + } else { + constexpr auto max = is_flags_v ? log2(max_v) : max_v; + constexpr auto min = is_flags_v ? log2(min_v) : min_v; + constexpr auto range_size = max - min + 1; + + return range_size != count_v; + } +} + +template +inline constexpr bool is_sparse_v = is_sparse(); + +template > +constexpr U values_ors() noexcept { + static_assert(is_enum_v, "magic_enum::detail::values_ors requires enum type."); + + auto ors = U{0}; + for (std::size_t i = 0; i < count_v; ++i) { + ors |= static_cast(values_v[i]); + } + + return ors; +} + +template +struct enable_if_enum {}; + +template +struct enable_if_enum { + using type = R; + static_assert(supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); +}; + +template > +using enable_if_t = typename enable_if_enum> && std::is_invocable_r_v, R>::type; + +template >>> +using enum_concept = T; + +template > +struct is_scoped_enum : std::false_type {}; + +template +struct is_scoped_enum : std::bool_constant>> {}; + +template > +struct is_unscoped_enum : std::false_type {}; + +template +struct is_unscoped_enum : std::bool_constant>> {}; + +template >> +struct underlying_type {}; + +template +struct underlying_type : std::underlying_type> {}; + +template +struct constexpr_hash_t; + +template +struct constexpr_hash_t>> { + constexpr auto operator()(Value value) const noexcept { + using U = typename underlying_type::type; + if constexpr (std::is_same_v) { // bool special case + return static_cast(value); + } else { + return static_cast(value); + } + } + using secondary_hash = constexpr_hash_t; +}; + +template +struct constexpr_hash_t>> { + static constexpr std::uint32_t crc_table[256] { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, + 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, + 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, + 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, + 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, + 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, + 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, + 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, + 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, + 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, + 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, + 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, + 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, + 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, + 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, + 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, + 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, + 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, + 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, + 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, + 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, + 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, + 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, + 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, + 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, + 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL + }; + constexpr std::uint32_t operator()(string_view value) const noexcept { + auto crc = static_cast(0xffffffffL); + for (const auto c : value) { + crc = (crc >> 8) ^ crc_table[(crc ^ static_cast(c)) & 0xff]; + } + return crc ^ 0xffffffffL; + } + + struct secondary_hash { + constexpr std::uint32_t operator()(string_view value) const noexcept { + auto acc = static_cast(2166136261ULL); + for (const auto c : value) { + acc = ((acc ^ static_cast(c)) * static_cast(16777619ULL)) & std::numeric_limits::max(); + } + return static_cast(acc); + } + }; +}; + +template +constexpr static Hash hash_v{}; + +template +constexpr auto calculate_cases(std::size_t Page) noexcept { + constexpr std::array values = *GlobValues; + constexpr std::size_t size = values.size(); + + using switch_t = std::invoke_result_t; + static_assert(std::is_integral_v && !std::is_same_v); + const std::size_t values_to = (std::min)(static_cast(256), size - Page); + + std::array result{}; + auto fill = result.begin(); + for (auto first = values.begin() + Page, last = values.begin() + Page + values_to; first != last; ) { + *fill++ = hash_v(*first++); + } + + // dead cases, try to avoid case collisions + for (switch_t last_value = result[values_to - 1]; fill != result.end() && last_value != (std::numeric_limits::max)(); *fill++ = ++last_value) { + } + + auto it = result.begin(); + for (auto last_value = (std::numeric_limits::min)(); fill != result.end(); *fill++ = last_value) { + while (last_value == *it) { + ++last_value, ++it; + } + } + + return result; +} + +template +constexpr R invoke_r(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_r_v) { + if constexpr (std::is_void_v) { + std::forward(f)(std::forward(args)...); + } else { + return static_cast(std::forward(f)(std::forward(args)...)); + } +} + +enum class case_call_t { + index, value +}; + +template +constexpr auto default_result_type_lambda = []() noexcept(std::is_nothrow_default_constructible_v) { return T{}; }; + +template <> +constexpr auto default_result_type_lambda = []() noexcept {}; + +template +constexpr bool no_duplicate() noexcept { + using value_t = std::decay_t; + using hash_value_t = std::invoke_result_t; + std::arraysize()> hashes{}; + std::size_t size = 0; + for (auto elem : *Arr) { + hashes[size] = hash_v(elem); + for (auto i = size++; i > 0; --i) { + if (hashes[i] < hashes[i - 1]) { + auto tmp = hashes[i]; + hashes[i] = hashes[i - 1]; + hashes[i - 1] = tmp; + } else if (hashes[i] == hashes[i - 1]) { + return false; + } else { + break; + } + } + } + return true; +} + +#define MAGIC_ENUM_FOR_EACH_256(T) T(0)T(1)T(2)T(3)T(4)T(5)T(6)T(7)T(8)T(9)T(10)T(11)T(12)T(13)T(14)T(15)T(16)T(17)T(18)T(19)T(20)T(21)T(22)T(23)T(24)T(25)T(26)T(27)T(28)T(29)T(30)T(31) \ + T(32)T(33)T(34)T(35)T(36)T(37)T(38)T(39)T(40)T(41)T(42)T(43)T(44)T(45)T(46)T(47)T(48)T(49)T(50)T(51)T(52)T(53)T(54)T(55)T(56)T(57)T(58)T(59)T(60)T(61)T(62)T(63) \ + T(64)T(65)T(66)T(67)T(68)T(69)T(70)T(71)T(72)T(73)T(74)T(75)T(76)T(77)T(78)T(79)T(80)T(81)T(82)T(83)T(84)T(85)T(86)T(87)T(88)T(89)T(90)T(91)T(92)T(93)T(94)T(95) \ + T(96)T(97)T(98)T(99)T(100)T(101)T(102)T(103)T(104)T(105)T(106)T(107)T(108)T(109)T(110)T(111)T(112)T(113)T(114)T(115)T(116)T(117)T(118)T(119)T(120)T(121)T(122)T(123)T(124)T(125)T(126)T(127) \ + T(128)T(129)T(130)T(131)T(132)T(133)T(134)T(135)T(136)T(137)T(138)T(139)T(140)T(141)T(142)T(143)T(144)T(145)T(146)T(147)T(148)T(149)T(150)T(151)T(152)T(153)T(154)T(155)T(156)T(157)T(158)T(159) \ + T(160)T(161)T(162)T(163)T(164)T(165)T(166)T(167)T(168)T(169)T(170)T(171)T(172)T(173)T(174)T(175)T(176)T(177)T(178)T(179)T(180)T(181)T(182)T(183)T(184)T(185)T(186)T(187)T(188)T(189)T(190)T(191) \ + T(192)T(193)T(194)T(195)T(196)T(197)T(198)T(199)T(200)T(201)T(202)T(203)T(204)T(205)T(206)T(207)T(208)T(209)T(210)T(211)T(212)T(213)T(214)T(215)T(216)T(217)T(218)T(219)T(220)T(221)T(222)T(223) \ + T(224)T(225)T(226)T(227)T(228)T(229)T(230)T(231)T(232)T(233)T(234)T(235)T(236)T(237)T(238)T(239)T(240)T(241)T(242)T(243)T(244)T(245)T(246)T(247)T(248)T(249)T(250)T(251)T(252)T(253)T(254)T(255) + +#define MAGIC_ENUM_CASE(val) \ + case cases[val]: \ + if constexpr ((val) + Page < size) { \ + if (!pred(values[val + Page], searched)) { \ + break; \ + } \ + if constexpr (CallValue == case_call_t::index) { \ + if constexpr (std::is_invocable_r_v>) { \ + return detail::invoke_r(std::forward(lambda), std::integral_constant{}); \ + } else if constexpr (std::is_invocable_v>) { \ + assert(false && "magic_enum::detail::constexpr_switch wrong result type."); \ + } \ + } else if constexpr (CallValue == case_call_t::value) { \ + if constexpr (std::is_invocable_r_v>) { \ + return detail::invoke_r(std::forward(lambda), enum_constant{}); \ + } else if constexpr (std::is_invocable_r_v>) { \ + assert(false && "magic_enum::detail::constexpr_switch wrong result type."); \ + } \ + } \ + break; \ + } else [[fallthrough]]; + +template ::value_type>, + typename Lambda, typename ResultGetterType = decltype(default_result_type_lambda<>), + typename BinaryPredicate = std::equal_to<>> +constexpr std::invoke_result_t constexpr_switch( + Lambda&& lambda, + typename std::decay_t::value_type searched, + ResultGetterType&& def = default_result_type_lambda<>, + BinaryPredicate&& pred = {}) { + using result_t = std::invoke_result_t; + using hash_t = std::conditional_t(), Hash, typename Hash::secondary_hash>; + constexpr std::array values = *GlobValues; + constexpr std::size_t size = values.size(); + constexpr std::array cases = calculate_cases(Page); + + switch (hash_v(searched)) { + MAGIC_ENUM_FOR_EACH_256(MAGIC_ENUM_CASE) + default: + if constexpr (size > 256 + Page) { + return constexpr_switch(std::forward(lambda), searched, std::forward(def)); + } + break; + } + return def(); +} + +#undef MAGIC_ENUM_FOR_EACH_256 +#undef MAGIC_ENUM_CASE + +template +constexpr auto for_each(Lambda&& lambda, std::index_sequence) { + static_assert(is_enum_v, "magic_enum::detail::for_each requires enum type."); + constexpr bool has_void_return = (std::is_void_v[I]>>> || ...); + constexpr bool all_same_return = (std::is_same_v[0]>>, std::invoke_result_t[I]>>> && ...); + + if constexpr (has_void_return) { + (lambda(enum_constant[I]>{}), ...); + } else if constexpr (all_same_return) { + return std::array{lambda(enum_constant[I]>{})...}; + } else { + return std::tuple{lambda(enum_constant[I]>{})...}; + } +} + +template > +using for_each_t = decltype(for_each(std::declval(), std::make_index_sequence>{})); + +} // namespace magic_enum::detail + +// Checks is magic_enum supported compiler. +inline constexpr bool is_magic_enum_supported = detail::supported::value; + +template +using Enum = detail::enum_concept; + +// Checks whether T is an Unscoped enumeration type. +// Provides the member constant value which is equal to true, if T is an [Unscoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Unscoped_enumeration) type. Otherwise, value is equal to false. +template +struct is_unscoped_enum : detail::is_unscoped_enum {}; + +template +inline constexpr bool is_unscoped_enum_v = is_unscoped_enum::value; + +// Checks whether T is an Scoped enumeration type. +// Provides the member constant value which is equal to true, if T is an [Scoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Scoped_enumerations) type. Otherwise, value is equal to false. +template +struct is_scoped_enum : detail::is_scoped_enum {}; + +template +inline constexpr bool is_scoped_enum_v = is_scoped_enum::value; + +// If T is a complete enumeration type, provides a member typedef type that names the underlying type of T. +// Otherwise, if T is not an enumeration type, there is no member type. Otherwise (T is an incomplete enumeration type), the program is ill-formed. +template +struct underlying_type : detail::underlying_type {}; + +template +using underlying_type_t = typename underlying_type::type; + +template +using enum_constant = detail::enum_constant; + +// Returns type name of enum. +template +[[nodiscard]] constexpr auto enum_type_name() noexcept -> detail::enable_if_t { + constexpr string_view name = detail::type_name_v>; + static_assert(!name.empty(), "magic_enum::enum_type_name enum type does not have a name."); + + return name; +} + +// Returns number of enum values. +template +[[nodiscard]] constexpr auto enum_count() noexcept -> detail::enable_if_t { + return detail::count_v>; +} + +// Returns enum value at specified index. +// No bounds checking is performed: the behavior is undefined if index >= number of enum values. +template +[[nodiscard]] constexpr auto enum_value(std::size_t index) noexcept -> detail::enable_if_t> { + using D = std::decay_t; + + if constexpr (detail::is_sparse_v) { + return assert((index < detail::count_v)), detail::values_v[index]; + } else { + constexpr bool is_flag = detail::is_flags_v; + constexpr auto min = is_flag ? detail::log2(detail::min_v) : detail::min_v; + + return assert((index < detail::count_v)), detail::value(index); + } +} + +// Returns enum value at specified index. +template +[[nodiscard]] constexpr auto enum_value() noexcept -> detail::enable_if_t> { + using D = std::decay_t; + static_assert(I < detail::count_v, "magic_enum::enum_value out of range."); + + return enum_value(I); +} + +// Returns std::array with enum values, sorted by enum value. +template +[[nodiscard]] constexpr auto enum_values() noexcept -> detail::enable_if_t> { + return detail::values_v>; +} + +// Returns integer value from enum value. +template +[[nodiscard]] constexpr auto enum_integer(E value) noexcept -> detail::enable_if_t> { + return static_cast>(value); +} + + +// Returns underlying value from enum value. +template +[[nodiscard]] constexpr auto enum_underlying(E value) noexcept -> detail::enable_if_t> { + return static_cast>(value); +} + +// Obtains index in enum values from enum value. +// Returns optional with index. +template +[[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t> { + using D = std::decay_t; + using U = underlying_type_t; + + if constexpr (detail::count_v == 0) { + return {}; // Empty enum. + } else if constexpr (detail::is_sparse_v || detail::is_flags_v) { + return detail::constexpr_switch<&detail::values_v, detail::case_call_t::index>( + [](std::size_t i) { return optional{i}; }, + value, + detail::default_result_type_lambda>); + } else { + const auto v = static_cast(value); + if (v >= detail::min_v && v <= detail::max_v) { + return static_cast(v - detail::min_v); + } + return {}; // Invalid value or out of range. + } +} + +// Returns name from static storage enum variable. +// This version is much lighter on the compile times and is not restricted to the enum_range limitation. +template +[[nodiscard]] constexpr auto enum_name() noexcept -> detail::enable_if_t { + constexpr string_view name = detail::enum_name_v, V>; + static_assert(!name.empty(), "magic_enum::enum_name enum value does not have a name."); + + return name; +} + +// Returns name from enum value. +// If enum value does not have name or value out of range, returns empty string. +template +[[nodiscard]] constexpr auto enum_name(E value) noexcept -> detail::enable_if_t { + using D = std::decay_t; + + if (const auto i = enum_index(value)) { + return detail::names_v[*i]; + } + return {}; +} + +// Returns name from enum-flags value. +// If enum-flags value does not have name or value out of range, returns empty string. +template +[[nodiscard]] auto enum_flags_name(E value) -> detail::enable_if_t { + using D = std::decay_t; + using U = underlying_type_t; + + if constexpr (detail::is_flags_v) { + string name; + auto check_value = U{0}; + for (std::size_t i = 0; i < detail::count_v; ++i) { + if (const auto v = static_cast(enum_value(i)); (static_cast(value) & v) != 0) { + check_value |= v; + const auto n = detail::names_v[i]; + if (!name.empty()) { + name.append(1, '|'); + } + name.append(n.data(), n.size()); + } + } + + if (check_value != 0 && check_value == static_cast(value)) { + return name; + } + + return {}; // Invalid value or out of range. + } else { + return string{enum_name(value)}; + } +} + +// Returns std::array with names, sorted by enum value. +template +[[nodiscard]] constexpr auto enum_names() noexcept -> detail::enable_if_t> { + return detail::names_v>; +} + +// Returns std::array with pairs (value, name), sorted by enum value. +template +[[nodiscard]] constexpr auto enum_entries() noexcept -> detail::enable_if_t> { + return detail::entries_v>; +} + +// Obtains enum value from integer value. +// Returns optional with enum value. +template +[[nodiscard]] constexpr auto enum_cast(underlying_type_t value) noexcept -> detail::enable_if_t>> { + using D = std::decay_t; + using U = underlying_type_t; + + if constexpr (detail::count_v == 0) { + return {}; // Empty enum. + } else if constexpr (detail::is_sparse_v) { + if constexpr (detail::is_flags_v) { + constexpr auto count = detail::count_v; + auto check_value = U{0}; + for (std::size_t i = 0; i < count; ++i) { + if (const auto v = static_cast(enum_value(i)); (value & v) != 0) { + check_value |= v; + } + } + + if (check_value != 0 && check_value == value) { + return static_cast(value); + } + return {}; // Invalid value or out of range. + } else { + return detail::constexpr_switch<&detail::values_v, detail::case_call_t::value>( + [](D v) { return optional{v}; }, + static_cast(value), + detail::default_result_type_lambda>); + } + } else { + constexpr auto min = detail::min_v; + constexpr auto max = detail::is_flags_v ? detail::values_ors() : detail::max_v; + + if (value >= min && value <= max) { + return static_cast(value); + } + return {}; // Invalid value or out of range. + } +} + +// Allows you to write magic_enum::enum_cast("bar", magic_enum::case_insensitive); +inline constexpr auto case_insensitive = detail::case_insensitive{}; + +// Obtains enum value from name. +// Returns optional with enum value. +template > +[[nodiscard]] constexpr auto enum_cast(string_view value, [[maybe_unused]] BinaryPredicate&& p = {}) noexcept(detail::is_nothrow_invocable()) -> detail::enable_if_t>, BinaryPredicate> { + static_assert(std::is_invocable_r_v, "magic_enum::enum_cast requires bool(char, char) invocable predicate."); + using D = std::decay_t; + using U = underlying_type_t; + + if constexpr (detail::count_v == 0) { + return {}; // Empty enum. + } else if constexpr (detail::is_flags_v) { + auto result = U{0}; + while (!value.empty()) { + const auto d = detail::find(value, '|'); + const auto s = (d == string_view::npos) ? value : value.substr(0, d); + auto f = U{0}; + for (std::size_t i = 0; i < detail::count_v; ++i) { + if (detail::cmp_equal(s, detail::names_v[i], p)) { + f = static_cast(enum_value(i)); + result |= f; + break; + } + } + if (f == U{0}) { + return {}; // Invalid value or out of range. + } + value.remove_prefix((d == string_view::npos) ? value.size() : d + 1); + } + + if (result != U{0}) { + return static_cast(result); + } + return {}; // Invalid value or out of range. + } else if constexpr (detail::count_v > 0) { + if constexpr (detail::is_default_predicate()) { + return detail::constexpr_switch<&detail::names_v, detail::case_call_t::index>( + [](std::size_t i) { return optional{detail::values_v[i]}; }, + value, + detail::default_result_type_lambda>, + [&p](string_view lhs, string_view rhs) { return detail::cmp_equal(lhs, rhs, p); }); + } else { + for (std::size_t i = 0; i < detail::count_v; ++i) { + if (detail::cmp_equal(value, detail::names_v[i], p)) { + return enum_value(i); + } + } + return {}; // Invalid value or out of range. + } + } +} + +// Obtains index in enum values from static storage enum variable. +template +[[nodiscard]] constexpr auto enum_index() noexcept -> detail::enable_if_t { + constexpr auto index = enum_index>(V); + static_assert(index, "magic_enum::enum_index enum value does not have a index."); + + return *index; +} + +// Checks whether enum contains enumerator with such enum value. +template +[[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_t { + using D = std::decay_t; + using U = underlying_type_t; + + return static_cast(enum_cast(static_cast(value))); +} + +// Checks whether enum contains enumerator with such integer value. +template +[[nodiscard]] constexpr auto enum_contains(underlying_type_t value) noexcept -> detail::enable_if_t { + using D = std::decay_t; + + return static_cast(enum_cast(value)); +} + +// Checks whether enum contains enumerator with such name. +template > +[[nodiscard]] constexpr auto enum_contains(string_view value, BinaryPredicate&& p = {}) noexcept(detail::is_nothrow_invocable()) -> detail::enable_if_t { + static_assert(std::is_invocable_r_v, "magic_enum::enum_contains requires bool(char, char) invocable predicate."); + using D = std::decay_t; + + return static_cast(enum_cast(value, std::forward(p))); +} + +template +constexpr auto enum_switch(Lambda&& lambda, E value) -> detail::enable_if_t { + using D = std::decay_t; + + return detail::constexpr_switch<&detail::values_v, detail::case_call_t::value>( + std::forward(lambda), + value, + detail::default_result_type_lambda); +} + +template +constexpr auto enum_switch(Lambda&& lambda, E value, Result&& result) -> detail::enable_if_t { + using D = std::decay_t; + + return detail::constexpr_switch<&detail::values_v, detail::case_call_t::value>( + std::forward(lambda), + value, + [&result] { return std::forward(result); }); +} + +template , typename Lambda> +constexpr auto enum_switch(Lambda&& lambda, string_view name, BinaryPredicate&& p = {}) -> detail::enable_if_t { + static_assert(std::is_invocable_r_v, "magic_enum::enum_switch requires bool(char, char) invocable predicate."); + using D = std::decay_t; + + if (const auto v = enum_cast(name, std::forward(p))) { + return enum_switch(std::forward(lambda), *v); + } + return detail::default_result_type_lambda(); +} + +template , typename Lambda> +constexpr auto enum_switch(Lambda&& lambda, string_view name, Result&& result, BinaryPredicate&& p = {}) -> detail::enable_if_t { + static_assert(std::is_invocable_r_v, "magic_enum::enum_switch requires bool(char, char) invocable predicate."); + using D = std::decay_t; + + if (const auto v = enum_cast(name, std::forward(p))) { + return enum_switch(std::forward(lambda), *v, std::forward(result)); + } + return std::forward(result); +} + +template +constexpr auto enum_switch(Lambda&& lambda, underlying_type_t value) -> detail::enable_if_t { + using D = std::decay_t; + + if (const auto v = enum_cast(value)) { + return enum_switch(std::forward(lambda), *v); + } + return detail::default_result_type_lambda(); +} + +template +constexpr auto enum_switch(Lambda&& lambda, underlying_type_t value, Result&& result) -> detail::enable_if_t { + using D = std::decay_t; + + if (const auto v = enum_cast(value)) { + return enum_switch(std::forward(lambda), *v, std::forward(result)); + } + return std::forward(result); +} + +template +constexpr auto enum_for_each(Lambda&& lambda) -> detail::enable_if_t> { + using D = std::decay_t; + + return detail::for_each(std::forward(lambda), std::make_index_sequence>{}); +} + +namespace detail { + +template +constexpr optional fuse_one_enum(optional hash, E value) noexcept { + if (hash) { + if (const auto index = enum_index(value)) { + return (*hash << log2(enum_count() + 1)) | *index; + } + } + return {}; +} + +template +constexpr optional fuse_enum(E value) noexcept { + return fuse_one_enum(0, value); +} + +template +constexpr optional fuse_enum(E head, Es... tail) noexcept { + return fuse_one_enum(fuse_enum(tail...), head); +} + +template +constexpr auto typesafe_fuse_enum(Es... values) noexcept { + enum class enum_fuse_t : std::uintmax_t; + const auto fuse = fuse_enum(values...); + if (fuse) { + return optional{static_cast(*fuse)}; + } + return optional{}; +} + +} // namespace magic_enum::detail + +// Returns a bijective mix of several enum values. This can be used to emulate 2D switch/case statements. +template +[[nodiscard]] constexpr auto enum_fuse(Es... values) noexcept { + static_assert((std::is_enum_v> && ...), "magic_enum::enum_fuse requires enum type."); + static_assert(sizeof...(Es) >= 2, "magic_enum::enum_fuse requires at least 2 values."); + static_assert((detail::log2(enum_count() + 1) + ...) <= (sizeof(std::uintmax_t) * 8), "magic_enum::enum_fuse does not work for large enums"); +#if defined(MAGIC_ENUM_NO_TYPESAFE_ENUM_FUSE) + const auto fuse = detail::fuse_enum...>(values...); +#else + const auto fuse = detail::typesafe_fuse_enum...>(values...); +#endif + return assert(fuse), fuse; +} + +namespace ostream_operators { + +template = 0> +std::basic_ostream& operator<<(std::basic_ostream& os, E value) { + using D = std::decay_t; + using U = underlying_type_t; + + if constexpr (detail::supported::value) { + if (const auto name = enum_flags_name(value); !name.empty()) { + for (const auto c : name) { + os.put(c); + } + return os; + } + } + return (os << static_cast(value)); +} + +template = 0> +std::basic_ostream& operator<<(std::basic_ostream& os, optional value) { + return value ? (os << *value) : os; +} + +} // namespace magic_enum::ostream_operators + +namespace istream_operators { + +template = 0> +std::basic_istream& operator>>(std::basic_istream& is, E& value) { + using D = std::decay_t; + + std::basic_string s; + is >> s; + if (const auto v = enum_cast(s)) { + value = *v; + } else { + is.setstate(std::ios::failbit); + } + return is; +} + +} // namespace magic_enum::istream_operators + +namespace iostream_operators { + +using namespace ostream_operators; +using namespace istream_operators; + +} // namespace magic_enum::iostream_operators + +namespace bitwise_operators { + +template = 0> +constexpr E operator~(E rhs) noexcept { + return static_cast(~static_cast>(rhs)); +} + +template = 0> +constexpr E operator|(E lhs, E rhs) noexcept { + return static_cast(static_cast>(lhs) | static_cast>(rhs)); +} + +template = 0> +constexpr E operator&(E lhs, E rhs) noexcept { + return static_cast(static_cast>(lhs) & static_cast>(rhs)); +} + +template = 0> +constexpr E operator^(E lhs, E rhs) noexcept { + return static_cast(static_cast>(lhs) ^ static_cast>(rhs)); +} + +template = 0> +constexpr E& operator|=(E& lhs, E rhs) noexcept { + return lhs = (lhs | rhs); +} + +template = 0> +constexpr E& operator&=(E& lhs, E rhs) noexcept { + return lhs = (lhs & rhs); +} + +template = 0> +constexpr E& operator^=(E& lhs, E rhs) noexcept { + return lhs = (lhs ^ rhs); +} + +} // namespace magic_enum::bitwise_operators + +} // namespace magic_enum + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#elif defined(_MSC_VER) +# pragma warning(pop) +#endif + +#endif // NEARGYE_MAGIC_ENUM_HPP diff --git a/src/sol/config.hpp b/src/include/sol/config.hpp similarity index 100% rename from src/sol/config.hpp rename to src/include/sol/config.hpp diff --git a/src/sol/sol.hpp b/src/include/sol/sol.hpp similarity index 100% rename from src/sol/sol.hpp rename to src/include/sol/sol.hpp diff --git a/src/toml.hpp b/src/include/toml.hpp similarity index 53% rename from src/toml.hpp rename to src/include/toml.hpp index e51ce50..d23ece1 100644 --- a/src/toml.hpp +++ b/src/include/toml.hpp @@ -1,6 +1,6 @@ //---------------------------------------------------------------------------------------------------------------------- // -// toml++ v2.6.0 +// toml++ v3.0.1 // https://github.com/marzer/tomlplusplus // SPDX-License-Identifier: MIT // @@ -41,8 +41,10 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //---------------------------------------------------------------------------------------------------------------------- -#ifndef INCLUDE_TOMLPLUSPLUS_H -#define INCLUDE_TOMLPLUSPLUS_H +#ifndef TOMLPLUSPLUS_H +#define TOMLPLUSPLUS_H + +#define INCLUDE_TOMLPLUSPLUS_H // old guard name used pre-v3 //******** impl/preprocessor.h *************************************************************************************** @@ -100,25 +102,27 @@ _Pragma("clang diagnostic ignored \"-Wswitch\"") \ static_assert(true) - #define TOML_DISABLE_INIT_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") \ - static_assert(true) - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \ _Pragma("clang diagnostic ignored \"-Wdouble-promotion\"") \ - _Pragma("clang diagnostic ignored \"-Wchar-subscripts\"") \ _Pragma("clang diagnostic ignored \"-Wshift-sign-overflow\"") \ static_assert(true) - #define TOML_DISABLE_SHADOW_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wshadow\"") \ - _Pragma("clang diagnostic ignored \"-Wshadow-field\"") \ - static_assert(true) + #if TOML_CLANG >= 10 + #define TOML_DISABLE_SPAM_WARNINGS_CLANG_10 \ + _Pragma("clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"") \ + static_assert(true) + #else + #define TOML_DISABLE_SPAM_WARNINGS_CLANG_10 static_assert(true) + #endif #define TOML_DISABLE_SPAM_WARNINGS \ + TOML_DISABLE_SPAM_WARNINGS_CLANG_10; \ _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \ _Pragma("clang diagnostic ignored \"-Wweak-template-vtables\"") \ + _Pragma("clang diagnostic ignored \"-Wdouble-promotion\"") \ + _Pragma("clang diagnostic ignored \"-Wchar-subscripts\"") \ + _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") \ _Pragma("clang diagnostic ignored \"-Wpadded\"") \ static_assert(true) @@ -133,7 +137,7 @@ #define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS - #define TOML_ASSUME(cond) __builtin_assume(cond) + #define TOML_ASSUME(expr) __builtin_assume(expr) #define TOML_UNREACHABLE __builtin_unreachable() #define TOML_ATTR(...) __attribute__((__VA_ARGS__)) #if defined(_MSC_VER) // msvc compat mode @@ -162,6 +166,17 @@ #if !defined(TOML_TRIVIAL_ABI) && __has_attribute(trivial_abi) #define TOML_TRIVIAL_ABI __attribute__((__trivial_abi__)) #endif + #if !defined(TOML_FLAGS_ENUM) && __has_attribute(flag_enum) + #define TOML_FLAGS_ENUM __attribute__((__flag_enum__)) + #endif + #if __has_attribute(enum_extensibility) + #ifndef TOML_OPEN_ENUM + #define TOML_OPEN_ENUM __attribute__((enum_extensibility(open))) + #endif + #ifndef TOML_CLOSED_ENUM + #define TOML_CLOSED_ENUM __attribute__((enum_extensibility(closed))) + #endif + #endif #endif #define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) ) #define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) ) @@ -192,8 +207,8 @@ #endif #define TOML_DISABLE_SWITCH_WARNINGS \ - __pragma(warning(disable: 4061)) \ - __pragma(warning(disable: 4062)) \ + __pragma(warning(disable: 4061)) /* enumerator 'identifier' is not explicitly handled by a case label */ \ + __pragma(warning(disable: 4062)) /* enumerator 'identifier' is not handled */ \ __pragma(warning(disable: 4063)) \ __pragma(warning(disable: 26819)) \ static_assert(true) @@ -252,7 +267,7 @@ #define TOML_ALWAYS_INLINE __forceinline #endif #define TOML_NEVER_INLINE __declspec(noinline) - #define TOML_ASSUME(cond) __assume(cond) + #define TOML_ASSUME(expr) __assume(expr) #define TOML_UNREACHABLE __assume(0) #define TOML_ABSTRACT_BASE __declspec(novtable) #define TOML_EMPTY_BASES __declspec(empty_bases) @@ -300,23 +315,17 @@ #define TOML_DISABLE_SWITCH_WARNINGS \ _Pragma("GCC diagnostic ignored \"-Wswitch\"") \ _Pragma("GCC diagnostic ignored \"-Wswitch-enum\"") \ - _Pragma("GCC diagnostic ignored \"-Wswitch-default\"") \ - static_assert(true) - - #define TOML_DISABLE_INIT_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \ - _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \ - _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma("GCC diagnostic ignored \"-Wswitch-default\"") \ static_assert(true) #define TOML_DISABLE_ARITHMETIC_WARNINGS \ _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") \ _Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \ - _Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \ static_assert(true) - #define TOML_DISABLE_SHADOW_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wshadow\"") \ + #define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \ + _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \ + _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"") \ static_assert(true) #define TOML_DISABLE_SPAM_WARNINGS \ @@ -325,8 +334,10 @@ _Pragma("GCC diagnostic ignored \"-Wcomment\"") \ _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") \ _Pragma("GCC diagnostic ignored \"-Wuseless-cast\"") \ - _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \ - _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"") \ + _Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \ + _Pragma("GCC diagnostic ignored \"-Wsubobject-linkage\"") \ + _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \ + _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \ static_assert(true) #define TOML_POP_WARNINGS \ @@ -339,10 +350,9 @@ _Pragma("GCC diagnostic ignored \"-Wextra\"") \ _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \ TOML_DISABLE_SWITCH_WARNINGS; \ - TOML_DISABLE_INIT_WARNINGS; \ TOML_DISABLE_ARITHMETIC_WARNINGS; \ - TOML_DISABLE_SHADOW_WARNINGS; \ TOML_DISABLE_SPAM_WARNINGS; \ + TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \ static_assert(true) #define TOML_ENABLE_WARNINGS \ @@ -359,24 +369,42 @@ #endif +#ifndef TOML_CPP_VERSION + #define TOML_CPP_VERSION __cplusplus +#endif +#if TOML_CPP_VERSION < 201103L + #error toml++ requires C++17 or higher. For a TOML library supporting pre-C++11 see https://github.com/ToruNiina/Boost.toml +#elif TOML_CPP_VERSION < 201703L + #error toml++ requires C++17 or higher. For a TOML library supporting C++11 see https://github.com/ToruNiina/toml11 +#endif + #ifdef TOML_CONFIG_HEADER #include TOML_CONFIG_HEADER #endif +// header-only mode +#if !defined(TOML_HEADER_ONLY) && defined(TOML_ALL_INLINE) // was TOML_ALL_INLINE pre-2.0 + #define TOML_HEADER_ONLY TOML_ALL_INLINE +#endif +#if !defined(TOML_HEADER_ONLY) || (defined(TOML_HEADER_ONLY) && TOML_HEADER_ONLY) || TOML_INTELLISENSE + #undef TOML_HEADER_ONLY + #define TOML_HEADER_ONLY 1 +#endif #ifdef DOXYGEN + #undef TOML_HEADER_ONLY #define TOML_HEADER_ONLY 0 - #define TOML_WINDOWS_COMPAT 1 #endif -#if defined(TOML_ALL_INLINE) && !defined(TOML_HEADER_ONLY) - #define TOML_HEADER_ONLY TOML_ALL_INLINE +// extern templates (for !TOML_HEADER_ONLY) +#ifndef TOML_EXTERN_TEMPLATES + #define TOML_EXTERN_TEMPLATES 1 #endif - -#if !defined(TOML_HEADER_ONLY) || (defined(TOML_HEADER_ONLY) && TOML_HEADER_ONLY) || TOML_INTELLISENSE - #undef TOML_HEADER_ONLY - #define TOML_HEADER_ONLY 1 +#if (defined(DOXYGEN) || TOML_HEADER_ONLY) + #undef TOML_EXTERN_TEMPLATES + #define TOML_EXTERN_TEMPLATES 0 #endif +// internal implementation switch #if defined(TOML_IMPLEMENTATION) || TOML_HEADER_ONLY #undef TOML_IMPLEMENTATION #define TOML_IMPLEMENTATION 1 @@ -384,79 +412,76 @@ #define TOML_IMPLEMENTATION 0 #endif +// dllexport etc #ifndef TOML_API #define TOML_API #endif -#ifndef TOML_UNRELEASED_FEATURES - #if TOML_INTELLISENSE - #define TOML_UNRELEASED_FEATURES 1 - #else - #define TOML_UNRELEASED_FEATURES 0 - #endif +// experimental language features +#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && defined(TOML_UNRELEASED_FEATURES) // was TOML_UNRELEASED_FEATURES pre-3.0 + #define TOML_ENABLE_UNRELEASED_FEATURES TOML_UNRELEASED_FEATURES #endif - -#ifndef TOML_LARGE_FILES - #define TOML_LARGE_FILES 0 +#if (defined(TOML_ENABLE_UNRELEASED_FEATURES) && TOML_ENABLE_UNRELEASED_FEATURES) || TOML_INTELLISENSE + #undef TOML_ENABLE_UNRELEASED_FEATURES + #define TOML_ENABLE_UNRELEASED_FEATURES 1 +#endif +#ifndef TOML_ENABLE_UNRELEASED_FEATURES + #define TOML_ENABLE_UNRELEASED_FEATURES 0 #endif -#ifndef TOML_UNDEF_MACROS - #define TOML_UNDEF_MACROS 1 +// parser +#if !defined(TOML_ENABLE_PARSER) && defined(TOML_PARSER) // was TOML_PARSER pre-3.0 + #define TOML_ENABLE_PARSER TOML_PARSER +#endif +#if !defined(TOML_ENABLE_PARSER) || (defined(TOML_ENABLE_PARSER) && TOML_ENABLE_PARSER) || TOML_INTELLISENSE + #undef TOML_ENABLE_PARSER + #define TOML_ENABLE_PARSER 1 #endif -#ifndef TOML_PARSER - #define TOML_PARSER 1 +// formatters +#if !defined(TOML_ENABLE_FORMATTERS) \ + || (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) \ + || TOML_INTELLISENSE + #undef TOML_ENABLE_FORMATTERS + #define TOML_ENABLE_FORMATTERS 1 #endif -#ifndef TOML_MAX_NESTED_VALUES - #define TOML_MAX_NESTED_VALUES 256 - // this refers to the depth of nested values, e.g. inline tables and arrays. - // 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job... +// SIMD +#if !defined(TOML_ENABLE_SIMD) \ + || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) \ + || TOML_INTELLISENSE + #undef TOML_ENABLE_SIMD + #define TOML_ENABLE_SIMD 1 #endif -#ifndef TOML_WINDOWS_COMPAT - #define TOML_WINDOWS_COMPAT 1 +// windows compat +#if !defined(TOML_ENABLE_WINDOWS_COMPAT) && defined(TOML_WINDOWS_COMPAT) // was TOML_WINDOWS_COMPAT pre-3.0 + #define TOML_ENABLE_WINDOWS_COMPAT TOML_WINDOWS_COMPAT +#endif +#if !defined(TOML_ENABLE_WINDOWS_COMPAT) \ + || (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) \ + || TOML_INTELLISENSE + #undef TOML_ENABLE_WINDOWS_COMPAT + #define TOML_ENABLE_WINDOWS_COMPAT 1 #endif #ifndef _WIN32 - #undef TOML_WINDOWS_COMPAT - #define TOML_WINDOWS_COMPAT 0 + #undef TOML_ENABLE_WINDOWS_COMPAT + #define TOML_ENABLE_WINDOWS_COMPAT 0 #endif #ifndef TOML_INCLUDE_WINDOWS_H #define TOML_INCLUDE_WINDOWS_H 0 #endif +// custom optional #ifdef TOML_OPTIONAL_TYPE #define TOML_HAS_CUSTOM_OPTIONAL_TYPE 1 #else #define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0 #endif -#ifdef TOML_CHAR_8_STRINGS - #if TOML_CHAR_8_STRINGS - #error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly. - #endif -#endif - -#ifndef TOML_CPP_VERSION - #define TOML_CPP_VERSION __cplusplus -#endif -#if TOML_CPP_VERSION < 201103L - #error toml++ requires C++17 or higher. For a TOML library supporting pre-C++11 see https://github.com/ToruNiina/Boost.toml -#elif TOML_CPP_VERSION < 201703L - #error toml++ requires C++17 or higher. For a TOML library supporting C++11 see https://github.com/ToruNiina/toml11 -#elif TOML_CPP_VERSION >= 202600L - #define TOML_CPP 26 -#elif TOML_CPP_VERSION >= 202300L - #define TOML_CPP 23 -#elif TOML_CPP_VERSION >= 202002L - #define TOML_CPP 20 -#elif TOML_CPP_VERSION >= 201703L - #define TOML_CPP 17 -#endif -#undef TOML_CPP_VERSION - +// exceptions (compiler support) #ifndef TOML_COMPILER_EXCEPTIONS #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) #define TOML_COMPILER_EXCEPTIONS 1 @@ -464,6 +489,8 @@ #define TOML_COMPILER_EXCEPTIONS 0 #endif #endif + +// exceptions (library use) #if TOML_COMPILER_EXCEPTIONS #if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS) #undef TOML_EXCEPTIONS @@ -477,18 +504,34 @@ #define TOML_EXCEPTIONS 0 #endif -#if defined(DOXYGEN) || TOML_EXCEPTIONS - #define TOML_MAY_THROW -#else - #define TOML_MAY_THROW noexcept +#ifndef TOML_UNDEF_MACROS + #define TOML_UNDEF_MACROS 1 +#endif + +#ifndef TOML_MAX_NESTED_VALUES + #define TOML_MAX_NESTED_VALUES 256 + // this refers to the depth of nested values, e.g. inline tables and arrays. + // 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job... +#endif + +#ifdef TOML_CHAR_8_STRINGS + #if TOML_CHAR_8_STRINGS + #error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly. + #endif +#endif + +#ifdef TOML_LARGE_FILES + #if !TOML_LARGE_FILES + #error Support for !TOML_LARGE_FILES (i.e. 'small files') was removed in toml++ 3.0.0. + #endif #endif -#if TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL) +#if !defined(TOML_FLOAT_CHARCONV) && (TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL)) // not supported by any version of GCC or Clang as of 26/11/2020 // not supported by any version of ICC on Linux as of 11/01/2021 #define TOML_FLOAT_CHARCONV 0 #endif -#if defined(__EMSCRIPTEN__) || defined(__APPLE__) +#if !defined(TOML_INT_CHARCONV) && (defined(__EMSCRIPTEN__) || defined(__APPLE__)) // causes link errors on emscripten // causes Mac OS SDK version errors on some versions of Apple Clang #define TOML_INT_CHARCONV 0 @@ -515,8 +558,8 @@ #ifndef TOML_DISABLE_SWITCH_WARNINGS #define TOML_DISABLE_SWITCH_WARNINGS static_assert(true) #endif -#ifndef TOML_DISABLE_INIT_WARNINGS - #define TOML_DISABLE_INIT_WARNINGS static_assert(true) +#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS + #define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true) #endif #ifndef TOML_DISABLE_SPAM_WARNINGS #define TOML_DISABLE_SPAM_WARNINGS static_assert(true) @@ -524,9 +567,6 @@ #ifndef TOML_DISABLE_ARITHMETIC_WARNINGS #define TOML_DISABLE_ARITHMETIC_WARNINGS static_assert(true) #endif -#ifndef TOML_DISABLE_SHADOW_WARNINGS - #define TOML_DISABLE_SHADOW_WARNINGS static_assert(true) -#endif #ifndef TOML_POP_WARNINGS #define TOML_POP_WARNINGS static_assert(true) #endif @@ -557,18 +597,31 @@ #endif #ifndef TOML_ASSUME - #define TOML_ASSUME(cond) (void)0 + #define TOML_ASSUME(expr) static_assert(true) #endif #ifndef TOML_UNREACHABLE - #define TOML_UNREACHABLE TOML_ASSERT(false) + #define TOML_UNREACHABLE TOML_ASSUME(false) #endif -#if defined(__cpp_consteval) && __cpp_consteval >= 201811 && !defined(_MSC_VER) - // https://developercommunity.visualstudio.com/t/Erroneous-C7595-error-with-consteval-in/1404234 - #define TOML_CONSTEVAL consteval -#else - #define TOML_CONSTEVAL constexpr +#ifndef TOML_FLAGS_ENUM + #define TOML_FLAGS_ENUM +#endif + +#ifndef TOML_OPEN_ENUM + #define TOML_OPEN_ENUM +#endif + +#ifndef TOML_CLOSED_ENUM + #define TOML_CLOSED_ENUM +#endif + +#ifndef TOML_OPEN_FLAGS_ENUM + #define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM +#endif + +#ifndef TOML_CLOSED_FLAGS_ENUM + #define TOML_CLOSED_FLAGS_ENUM TOML_CLOSED_ENUM TOML_FLAGS_ENUM #endif #ifdef __has_cpp_attribute @@ -577,19 +630,35 @@ #define TOML_HAS_ATTR(...) 0 #endif -#if !defined(TOML_LIKELY) && TOML_HAS_ATTR(likely) >= 201803 - #define TOML_LIKELY(...) (__VA_ARGS__) [[likely]] +#if TOML_HAS_ATTR(likely) >= 201803 + #ifndef TOML_LIKELY + #define TOML_LIKELY(...) (__VA_ARGS__) [[likely]] + #endif + #ifndef TOML_LIKELY_CASE + #define TOML_LIKELY_CASE [[likely]] + #endif #endif #ifndef TOML_LIKELY #define TOML_LIKELY(...) (__VA_ARGS__) #endif +#ifndef TOML_LIKELY_CASE + #define TOML_LIKELY_CASE +#endif -#if !defined(TOML_UNLIKELY) && TOML_HAS_ATTR(unlikely) >= 201803 - #define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]] +#if TOML_HAS_ATTR(unlikely) >= 201803 + #ifndef TOML_UNLIKELY + #define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]] + #endif + #ifndef TOML_UNLIKELY_CASE + #define TOML_UNLIKELY_CASE [[unlikely]] + #endif #endif #ifndef TOML_UNLIKELY #define TOML_UNLIKELY(...) (__VA_ARGS__) #endif +#ifndef TOML_UNLIKELY_CASE + #define TOML_UNLIKELY_CASE +#endif #if TOML_HAS_ATTR(nodiscard) #define TOML_NODISCARD [[nodiscard]] @@ -631,9 +700,7 @@ #endif #define TOML_MAKE_FLAGS_(name, op) \ - TOML_NODISCARD \ - TOML_ALWAYS_INLINE \ - TOML_ATTR(const) \ + TOML_CONST_INLINE_GETTER \ constexpr name operator op(name lhs, name rhs) noexcept \ { \ using under = std::underlying_type_t; \ @@ -649,17 +716,13 @@ TOML_MAKE_FLAGS_(name, &); \ TOML_MAKE_FLAGS_(name, |); \ TOML_MAKE_FLAGS_(name, ^); \ - TOML_NODISCARD \ - TOML_ALWAYS_INLINE \ - TOML_ATTR(const) \ + TOML_CONST_INLINE_GETTER \ constexpr name operator~(name val) noexcept \ { \ using under = std::underlying_type_t; \ return static_cast(~static_cast(val)); \ } \ - TOML_NODISCARD \ - TOML_ALWAYS_INLINE \ - TOML_ATTR(const) \ + TOML_CONST_INLINE_GETTER \ constexpr bool operator!(name val) noexcept \ { \ using under = std::underlying_type_t; \ @@ -675,6 +738,37 @@ #define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__ #endif +#if TOML_IMPLEMENTATION + #define TOML_EXTERN +#else + #define TOML_EXTERN extern +#endif +#if TOML_CLANG + #define TOML_EXTERN_NOEXCEPT(...) +#else + #define TOML_EXTERN_NOEXCEPT(...) noexcept(__VA_ARGS__) +#endif + +#ifdef NDEBUG + #define TOML_PURE_GETTER TOML_NODISCARD TOML_ATTR(pure) + #define TOML_CONST_GETTER TOML_NODISCARD TOML_ATTR(const) + #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_ATTR(pure) + #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_ATTR(const) +#else + #define TOML_PURE_GETTER TOML_NODISCARD + #define TOML_CONST_GETTER TOML_NODISCARD + #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE + #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE +#endif + +#define TOML_UNUSED(...) static_cast(__VA_ARGS__) + +#define TOML_DELETE_DEFAULTS(T) \ + T(const T&) = delete; \ + T(T&&) = delete; \ + T& operator=(const T&) = delete; \ + T& operator=(T&&) = delete + // SFINAE #if defined(__cpp_concepts) && __cpp_concepts >= 201907 #define TOML_REQUIRES(...) requires(__VA_ARGS__) @@ -683,10 +777,7 @@ #endif #define TOML_ENABLE_IF(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0 #define TOML_CONSTRAINED_TEMPLATE(condition, ...) template <__VA_ARGS__ TOML_ENABLE_IF(condition)> TOML_REQUIRES(condition) - -#ifndef TOML_CONSTRAINED_TEMPLATE - #define TOML_CONSTRAINED_TEMPLATE(condition, ...) template <__VA_ARGS__> -#endif +#define TOML_HIDDEN_CONSTRAINT(condition, ...) TOML_CONSTRAINED_TEMPLATE(condition, __VA_ARGS__) #ifdef __FLT16_MANT_DIG__ #if __FLT_RADIX__ == 2 \ @@ -717,9 +808,9 @@ #define TOML_UINT128 __uint128_t #endif -#define TOML_LIB_MAJOR 2 -#define TOML_LIB_MINOR 6 -#define TOML_LIB_PATCH 0 +#define TOML_LIB_MAJOR 3 +#define TOML_LIB_MINOR 0 +#define TOML_LIB_PATCH 1 #define TOML_LANG_MAJOR 1 #define TOML_LANG_MINOR 0 @@ -727,24 +818,24 @@ #define TOML_LIB_SINGLE_HEADER 1 -#define TOML_MAKE_VERSION(maj, min, rev) \ - ((maj) * 1000 + (min) * 25 + (rev)) +#define TOML_MAKE_VERSION(major, minor, patch) \ + ((major) * 10000 + (minor) * 100 + (patch)) -#if TOML_UNRELEASED_FEATURES - #define TOML_LANG_EFFECTIVE_VERSION \ +#if TOML_ENABLE_UNRELEASED_FEATURES + #define TOML_LANG_EFFECTIVE_VERSION \ TOML_MAKE_VERSION(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH+1) #else - #define TOML_LANG_EFFECTIVE_VERSION \ + #define TOML_LANG_EFFECTIVE_VERSION \ TOML_MAKE_VERSION(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH) #endif -#define TOML_LANG_HIGHER_THAN(maj, min, rev) \ - (TOML_LANG_EFFECTIVE_VERSION > TOML_MAKE_VERSION(maj, min, rev)) +#define TOML_LANG_HIGHER_THAN(major, minor, patch) \ + (TOML_LANG_EFFECTIVE_VERSION > TOML_MAKE_VERSION(major, minor, patch)) -#define TOML_LANG_AT_LEAST(maj, min, rev) \ - (TOML_LANG_EFFECTIVE_VERSION >= TOML_MAKE_VERSION(maj, min, rev)) +#define TOML_LANG_AT_LEAST(major, minor, patch) \ + (TOML_LANG_EFFECTIVE_VERSION >= TOML_MAKE_VERSION(major, minor, patch)) -#define TOML_LANG_UNRELEASED \ +#define TOML_LANG_UNRELEASED \ TOML_LANG_HIGHER_THAN(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH) #ifndef TOML_ABI_NAMESPACES @@ -772,33 +863,38 @@ #define TOML_IMPL_NAMESPACE_START TOML_NAMESPACE_START { namespace impl #define TOML_IMPL_NAMESPACE_END } TOML_NAMESPACE_END #if TOML_HEADER_ONLY - #define TOML_ANON_NAMESPACE_START TOML_IMPL_NAMESPACE_START + #define TOML_ANON_NAMESPACE_START static_assert(TOML_IMPLEMENTATION); TOML_IMPL_NAMESPACE_START #define TOML_ANON_NAMESPACE_END TOML_IMPL_NAMESPACE_END #define TOML_ANON_NAMESPACE TOML_NAMESPACE::impl - #define TOML_USING_ANON_NAMESPACE using namespace TOML_ANON_NAMESPACE #define TOML_EXTERNAL_LINKAGE inline #define TOML_INTERNAL_LINKAGE inline #else - #define TOML_ANON_NAMESPACE_START namespace + #define TOML_ANON_NAMESPACE_START static_assert(TOML_IMPLEMENTATION); \ + using namespace toml; \ + namespace #define TOML_ANON_NAMESPACE_END static_assert(true) #define TOML_ANON_NAMESPACE - #define TOML_USING_ANON_NAMESPACE static_cast(0) #define TOML_EXTERNAL_LINKAGE #define TOML_INTERNAL_LINKAGE static #endif -TOML_DISABLE_WARNINGS; +#ifdef NDEBUG + #undef TOML_ASSERT + #define TOML_ASSERT(expr) static_assert(true) +#endif #ifndef TOML_ASSERT - #if defined(NDEBUG) || !defined(_DEBUG) - #define TOML_ASSERT(expr) static_cast(0) - #else - #ifndef assert - #include - #endif - #define TOML_ASSERT(expr) assert(expr) + #ifndef assert + TOML_DISABLE_WARNINGS; + #include + TOML_ENABLE_WARNINGS; #endif + #define TOML_ASSERT(expr) assert(expr) +#endif +#ifdef NDEBUG + #define TOML_ASSERT_ASSUME(expr) TOML_ASSUME(expr) +#else + #define TOML_ASSERT_ASSUME(expr) TOML_ASSERT(expr) #endif -TOML_ENABLE_WARNINGS; #if TOML_SIMPLE_STATIC_ASSERT_MESSAGES @@ -853,64 +949,135 @@ TOML_ENABLE_WARNINGS; TOML_PUSH_WARNINGS; TOML_DISABLE_SPAM_WARNINGS; +TOML_DISABLE_SWITCH_WARNINGS; +TOML_DISABLE_SUGGEST_ATTR_WARNINGS; -//******** impl/common.h ********************************************************************************************* - -TOML_DISABLE_WARNINGS; -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if !TOML_HAS_CUSTOM_OPTIONAL_TYPE - #include -#endif -#if TOML_EXCEPTIONS - #include -#endif -#if TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV - #include +// misc warning false-positives +#if TOML_MSVC +#pragma warning(disable : 5031) // #pragma warning(pop): likely mismatch +#elif TOML_CLANG +#pragma clang diagnostic ignored "-Wheader-hygiene" +#if TOML_CLANG >= 12 +#pragma clang diagnostic ignored "-Wc++20-extensions" #endif -#if !TOML_INT_CHARCONV || !TOML_FLOAT_CHARCONV - #include +#if TOML_CLANG == 13 +#pragma clang diagnostic ignored "-Wreserved-identifier" #endif -#if !TOML_INT_CHARCONV - #include #endif + +//******** impl/std_new.h ******************************************************************************************** + +TOML_DISABLE_WARNINGS; +#include TOML_ENABLE_WARNINGS; -#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 - #define TOML_LAUNDER(x) std::launder(x) +#if TOML_CLANG >= 8 || TOML_GCC >= 7 || TOML_ICC >= 1910 || TOML_MSVC >= 1914 +#define TOML_LAUNDER(x) __builtin_launder(x) +#elif defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 +#define TOML_LAUNDER(x) std::launder(x) #else - #define TOML_LAUNDER(x) x +#define TOML_LAUNDER(x) x #endif +//******** impl/std_string.h ***************************************************************************************** + +TOML_DISABLE_WARNINGS; +#include +#include +TOML_ENABLE_WARNINGS; + #if defined(DOXYGEN) \ || (defined(__cpp_char8_t) && __cpp_char8_t >= 201811 && defined(__cpp_lib_char8_t) \ && __cpp_lib_char8_t >= 201907) - #define TOML_HAS_CHAR8 1 +#define TOML_HAS_CHAR8 1 +#else +#define TOML_HAS_CHAR8 0 +#endif + +namespace toml // non-abi namespace; this is not an error +{ + using namespace std::string_literals; + using namespace std::string_view_literals; +} + +#if TOML_ENABLE_WINDOWS_COMPAT + +TOML_IMPL_NAMESPACE_START +{ + TOML_NODISCARD + TOML_API + std::string narrow(std::wstring_view); + + TOML_NODISCARD + TOML_API + std::wstring widen(std::string_view); + +#if TOML_HAS_CHAR8 + + TOML_NODISCARD + TOML_API + std::wstring widen(std::u8string_view); + +#endif +} +TOML_IMPL_NAMESPACE_END; + +#endif // TOML_ENABLE_WINDOWS_COMPAT + +//******** impl/std_optional.h *************************************************************************************** + +TOML_DISABLE_WARNINGS; +#if !TOML_HAS_CUSTOM_OPTIONAL_TYPE +#include +#endif +TOML_ENABLE_WARNINGS; + +TOML_NAMESPACE_START +{ +#if TOML_HAS_CUSTOM_OPTIONAL_TYPE + + template + using optional = TOML_OPTIONAL_TYPE; + #else - #define TOML_HAS_CHAR8 0 + + template + using optional = std::optional; + +#endif +} +TOML_NAMESPACE_END; + +//******** impl/forward_declarations.h ******************************************************************************* + +TOML_DISABLE_WARNINGS; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +TOML_ENABLE_WARNINGS; +TOML_PUSH_WARNINGS; +#ifdef _MSC_VER +#pragma push_macro("min") +#pragma push_macro("max") +#undef min +#undef max #endif #ifndef TOML_DISABLE_ENVIRONMENT_CHECKS - #define TOML_ENV_MESSAGE \ - "If you're seeing this error it's because you're building toml++ for an environment that doesn't conform to " \ - "one of the 'ground truths' assumed by the library. Essentially this just means that I don't have the " \ - "resources to test on more platforms, but I wish I did! You can try disabling the checks by defining " \ - "TOML_DISABLE_ENVIRONMENT_CHECKS, but your mileage may vary. Please consider filing an issue at " \ - "https://github.com/marzer/tomlplusplus/issues to help me improve support for your target environment. " \ - "Thanks!" +#define TOML_ENV_MESSAGE \ + "If you're seeing this error it's because you're building toml++ for an environment that doesn't conform to " \ + "one of the 'ground truths' assumed by the library. Essentially this just means that I don't have the " \ + "resources to test on more platforms, but I wish I did! You can try disabling the checks by defining " \ + "TOML_DISABLE_ENVIRONMENT_CHECKS, but your mileage may vary. Please consider filing an issue at " \ + "https://github.com/marzer/tomlplusplus/issues to help me improve support for your target environment. " \ + "Thanks!" static_assert(CHAR_BIT == 8, TOML_ENV_MESSAGE); static_assert(FLT_RADIX == 2, TOML_ENV_MESSAGE); @@ -920,15 +1087,13 @@ static_assert(std::numeric_limits::is_iec559, TOML_ENV_MESSAGE); static_assert(std::numeric_limits::digits == 53, TOML_ENV_MESSAGE); static_assert(std::numeric_limits::digits10 == 15, TOML_ENV_MESSAGE); - #undef TOML_ENV_MESSAGE +#undef TOML_ENV_MESSAGE #endif // !TOML_DISABLE_ENVIRONMENT_CHECKS // undocumented forward declarations are hidden from doxygen because they fuck it up =/ namespace toml // non-abi namespace; this is not an error { - using namespace std::string_literals; - using namespace std::string_view_literals; using ::std::size_t; using ::std::intptr_t; using ::std::uintptr_t; @@ -944,14 +1109,9 @@ namespace toml // non-abi namespace; this is not an error using ::std::uint64_t; using ::std::uint_least32_t; using ::std::uint_least64_t; - - // legacy typedefs - using string_char = char; - using string = std::string; - using string_view = std::string_view; } -TOML_NAMESPACE_START // abi namespace +TOML_NAMESPACE_START { struct date; struct time; @@ -961,121 +1121,106 @@ TOML_NAMESPACE_START // abi namespace struct date_time; TOML_ABI_NAMESPACE_END; - class node; - class array; - class table; + struct source_position; + struct source_region; + class node; template class node_view; + + class key; + class array; + class table; template class value; - template - class default_formatter; - template + + class toml_formatter; class json_formatter; + class yaml_formatter; - TOML_NODISCARD - TOML_API - bool operator==(const array& lhs, const array& rhs) noexcept; + TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex); +#if TOML_EXCEPTIONS + using parse_result = table; +#else + class parse_result; +#endif + TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS +} +TOML_NAMESPACE_END; - TOML_NODISCARD - TOML_API - bool operator!=(const array& lhs, const array& rhs) noexcept; - - TOML_NODISCARD - TOML_API - bool operator==(const table& lhs, const table& rhs) noexcept; - - TOML_NODISCARD - TOML_API - bool operator!=(const table& lhs, const table& rhs) noexcept; - - template - std::basic_ostream& operator<<(std::basic_ostream&, const array&); - - template - std::basic_ostream& operator<<(std::basic_ostream&, const value&); - - template - std::basic_ostream& operator<<(std::basic_ostream&, const table&); +TOML_IMPL_NAMESPACE_START +{ + using node_ptr = std::unique_ptr; - template - std::basic_ostream& operator<<(std::basic_ostream&, default_formatter&); + TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, impl_ex, impl_noex); + class parser; + TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS - template - std::basic_ostream& operator<<(std::basic_ostream&, default_formatter&&); + // clang-format off - template - std::basic_ostream& operator<<(std::basic_ostream&, json_formatter&); + inline constexpr std::string_view control_char_escapes[] = + { + "\\u0000"sv, + "\\u0001"sv, + "\\u0002"sv, + "\\u0003"sv, + "\\u0004"sv, + "\\u0005"sv, + "\\u0006"sv, + "\\u0007"sv, + "\\b"sv, + "\\t"sv, + "\\n"sv, + "\\u000B"sv, + "\\f"sv, + "\\r"sv, + "\\u000E"sv, + "\\u000F"sv, + "\\u0010"sv, + "\\u0011"sv, + "\\u0012"sv, + "\\u0013"sv, + "\\u0014"sv, + "\\u0015"sv, + "\\u0016"sv, + "\\u0017"sv, + "\\u0018"sv, + "\\u0019"sv, + "\\u001A"sv, + "\\u001B"sv, + "\\u001C"sv, + "\\u001D"sv, + "\\u001E"sv, + "\\u001F"sv, + }; - template - std::basic_ostream& operator<<(std::basic_ostream&, json_formatter&&); + inline constexpr std::string_view node_type_friendly_names[] = + { + "none"sv, + "table"sv, + "array"sv, + "string"sv, + "integer"sv, + "floating-point"sv, + "boolean"sv, + "date"sv, + "time"sv, + "date-time"sv + }; - template - inline std::basic_ostream& operator<<(std::basic_ostream&, const node_view&); + // clang-format on +} +TOML_IMPL_NAMESPACE_END; - TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex); +#if TOML_ABI_NAMESPACES #if TOML_EXCEPTIONS - using parse_result = table; +#define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::impl_ex::parser #else - class parse_result; +#define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::impl_noex::parser #endif - TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS - - namespace impl - { - template - using string_map = std::map>; // heterogeneous lookup - - template - using remove_cvref_t = std::remove_cv_t>; - - template - inline constexpr bool is_one_of = (false || ... || std::is_same_v); - - template - inline constexpr bool is_cvref = std::is_reference_v || std::is_const_v || std::is_volatile_v; - - template - inline constexpr bool is_wide_string = - is_one_of, const wchar_t*, wchar_t*, std::wstring_view, std::wstring>; - - template - inline constexpr bool dependent_false = false; - -#if TOML_WINDOWS_COMPAT - - TOML_NODISCARD - TOML_API - std::string narrow(std::wstring_view) noexcept; - - TOML_NODISCARD - TOML_API - std::wstring widen(std::string_view) noexcept; - - #if TOML_HAS_CHAR8 - TOML_NODISCARD - TOML_API - std::wstring widen(std::u8string_view) noexcept; - #endif -#endif // TOML_WINDOWS_COMPAT - - TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex); - class parser; - TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS - -#if TOML_ABI_NAMESPACES - #if TOML_EXCEPTIONS - #define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::ex::parser - #else - #define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::noex::parser - #endif #else - #define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::parser +#define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::parser #endif - } -} -TOML_NAMESPACE_END; namespace toml { @@ -1087,16 +1232,7 @@ TOML_NAMESPACE_START // abi namespace { } -#if TOML_HAS_CUSTOM_OPTIONAL_TYPE - template - using optional = TOML_OPTIONAL_TYPE; -#else - - template - using optional = std::optional; -#endif - - enum class node_type : uint8_t + enum class TOML_CLOSED_ENUM node_type : uint8_t { none, table, @@ -1110,20 +1246,162 @@ TOML_NAMESPACE_START // abi namespace date_time }; - using source_path_ptr = std::shared_ptr; + template + inline std::basic_ostream& operator<<(std::basic_ostream& lhs, node_type rhs) + { + using underlying_t = std::underlying_type_t; + const auto str = impl::node_type_friendly_names[static_cast(rhs)]; + if constexpr (std::is_same_v) + return lhs << str; + else + { + if constexpr (sizeof(Char) == 1) + return lhs << std::basic_string_view{ reinterpret_cast(str.data()), str.length() }; + else + return lhs << str.data(); + } + } + + enum class TOML_OPEN_FLAGS_ENUM value_flags : uint16_t // being an "OPEN" flags enum is not an error + { + none, + format_as_binary = 1, + format_as_octal = 2, + format_as_hexadecimal = 3, + }; + TOML_MAKE_FLAGS(value_flags); + + inline constexpr value_flags preserve_source_value_flags = + POXY_IMPLEMENTATION_DETAIL(value_flags{ static_cast>(-1) }); + + enum class TOML_CLOSED_FLAGS_ENUM format_flags : uint64_t + { + none, + quote_dates_and_times = (1ull << 0), + quote_infinities_and_nans = (1ull << 1), + allow_literal_strings = (1ull << 2), + allow_multi_line_strings = (1ull << 3), + allow_real_tabs_in_strings = (1ull << 4), + allow_unicode_strings = (1ull << 5), + allow_binary_integers = (1ull << 6), + allow_octal_integers = (1ull << 7), + allow_hexadecimal_integers = (1ull << 8), + indent_sub_tables = (1ull << 9), + indent_array_elements = (1ull << 10), + indentation = indent_sub_tables | indent_array_elements, + relaxed_float_precision = (1ull << 11), + }; + TOML_MAKE_FLAGS(format_flags); template struct TOML_TRIVIAL_ABI inserter { - T&& value; + static_assert(std::is_reference_v); + + T value; }; template - inserter(T &&) -> inserter; + inserter(T &&) -> inserter; + template + inserter(T&) -> inserter; + + using default_formatter = toml_formatter; } TOML_NAMESPACE_END; TOML_IMPL_NAMESPACE_START { + template + using remove_cvref = std::remove_cv_t>; + + template + using common_signed_type = std::common_type_t...>; + + template + inline constexpr bool is_one_of = (false || ... || std::is_same_v); + + template + inline constexpr bool all_integral = (std::is_integral_v && ...); + + template + inline constexpr bool is_cvref = std::is_reference_v || std::is_const_v || std::is_volatile_v; + + template + inline constexpr bool is_wide_string = + is_one_of, const wchar_t*, wchar_t*, std::wstring_view, std::wstring>; + + template + inline constexpr bool value_retrieval_is_nothrow = !std::is_same_v, std::string> +#if TOML_HAS_CHAR8 + && !std::is_same_v, std::u8string> +#endif + + && !is_wide_string; + + template + struct copy_ref_; + template + using copy_ref = typename copy_ref_::type; + + template + struct copy_ref_ + { + using type = Dest; + }; + + template + struct copy_ref_ + { + using type = std::add_lvalue_reference_t; + }; + + template + struct copy_ref_ + { + using type = std::add_rvalue_reference_t; + }; + + template + struct copy_cv_; + template + using copy_cv = typename copy_cv_::type; + + template + struct copy_cv_ + { + using type = Dest; + }; + + template + struct copy_cv_ + { + using type = std::add_const_t; + }; + + template + struct copy_cv_ + { + using type = std::add_volatile_t; + }; + + template + struct copy_cv_ + { + using type = std::add_cv_t; + }; + + template + using copy_cvref = + copy_ref, std::remove_reference_t>, Dest>, Src>; + + template + inline constexpr bool dependent_false = false; + + template + inline constexpr bool first_is_same = false; + template + inline constexpr bool first_is_same = true; + // general value traits // (as they relate to their equivalent native TOML type) template @@ -1136,23 +1414,24 @@ TOML_IMPL_NAMESPACE_START static constexpr bool can_partially_represent_native = false; static constexpr auto type = node_type::none; }; + template - struct value_traits : value_traits + struct value_traits : value_traits {}; template - struct value_traits : value_traits + struct value_traits : value_traits {}; template - struct value_traits : value_traits + struct value_traits : value_traits {}; template - struct value_traits : value_traits + struct value_traits : value_traits {}; template - struct value_traits : value_traits + struct value_traits : value_traits {}; - // integer value traits + // integer value_traits specializations - standard types template struct integer_value_limits { @@ -1221,6 +1500,13 @@ TOML_IMPL_NAMESPACE_START template <> struct value_traits : integer_value_traits {}; + static_assert(value_traits::is_native); + static_assert(value_traits::is_signed); + static_assert(value_traits::is_losslessly_convertible_to_native); + static_assert(value_traits::can_represent_native); + static_assert(value_traits::can_partially_represent_native); + + // integer value_traits specializations - non-standard types #ifdef TOML_INT128 template <> struct integer_value_limits @@ -1248,13 +1534,8 @@ TOML_IMPL_NAMESPACE_START struct value_traits : signed_integer_value_traits {}; #endif - static_assert(value_traits::is_native); - static_assert(value_traits::is_signed); - static_assert(value_traits::is_losslessly_convertible_to_native); - static_assert(value_traits::can_represent_native); - static_assert(value_traits::can_partially_represent_native); - // float value traits + // floating-point value_traits specializations - standard types template struct float_value_limits { @@ -1265,18 +1546,23 @@ TOML_IMPL_NAMESPACE_START template struct float_value_traits : float_value_limits { - using native_type = double; - static constexpr bool is_native = std::is_same_v; - static constexpr bool is_signed = true; + using native_type = double; + static constexpr bool is_native = std::is_same_v; + static constexpr bool is_signed = true; + static constexpr bool is_losslessly_convertible_to_native = float_value_limits::is_iec559 && float_value_limits::digits <= 53 && float_value_limits::digits10 <= 15; + static constexpr bool can_represent_native = float_value_limits::is_iec559 && float_value_limits::digits >= 53 // DBL_MANT_DIG && float_value_limits::digits10 >= 15; // DBL_DIG - static constexpr bool can_partially_represent_native // 32-bit float values - = float_value_limits::is_iec559 && float_value_limits::digits >= 24 + + static constexpr bool can_partially_represent_native // 32-bit float values + = float_value_limits::is_iec559 // + && float_value_limits::digits >= 24 // && float_value_limits::digits10 >= 6; + static constexpr auto type = node_type::floating_point; }; template <> @@ -1295,6 +1581,12 @@ TOML_IMPL_NAMESPACE_START static constexpr int digits = mant_dig; static constexpr int digits10 = dig; }; + static_assert(value_traits::is_native); + static_assert(value_traits::is_losslessly_convertible_to_native); + static_assert(value_traits::can_represent_native); + static_assert(value_traits::can_partially_represent_native); + + // floating-point value_traits specializations - non-standard types #ifdef TOML_FP16 template <> struct float_value_limits : extended_float_value_limits<__FLT16_MANT_DIG__, __FLT16_DIG__> @@ -1324,12 +1616,8 @@ TOML_IMPL_NAMESPACE_START struct value_traits : float_value_traits {}; #endif - static_assert(value_traits::is_native); - static_assert(value_traits::is_losslessly_convertible_to_native); - static_assert(value_traits::can_represent_native); - static_assert(value_traits::can_partially_represent_native); - // string value traits + // string value_traits specializations - char-based strings template struct string_value_traits { @@ -1359,6 +1647,8 @@ TOML_IMPL_NAMESPACE_START template struct value_traits : string_value_traits {}; + + // string value_traits specializations - char8_t-based strings #if TOML_HAS_CHAR8 template <> struct value_traits : string_value_traits @@ -1379,7 +1669,9 @@ TOML_IMPL_NAMESPACE_START struct value_traits : string_value_traits {}; #endif -#if TOML_WINDOWS_COMPAT + + // string value_traits specializations - wchar_t-based strings on Windows +#if TOML_ENABLE_WINDOWS_COMPAT template struct wstring_value_traits { @@ -1410,7 +1702,7 @@ TOML_IMPL_NAMESPACE_START {}; #endif - // other native value traits + // other 'native' value_traits specializations template struct native_value_traits { @@ -1448,12 +1740,27 @@ TOML_IMPL_NAMESPACE_START template inline constexpr bool is_natively_one_of = is_one_of, U...>; - // native <=> node conversions + // native value types => nodes template struct node_wrapper { using type = T; }; + template + struct node_wrapper + { + using type = std::add_const_t::type>; + }; + template + struct node_wrapper + { + using type = std::add_volatile_t::type>; + }; + template + struct node_wrapper + { + using type = std::add_const_t::type>>; + }; template <> struct node_wrapper { @@ -1490,8 +1797,9 @@ TOML_IMPL_NAMESPACE_START using type = value; }; template - using wrap_node = typename node_wrapper::type; + using wrap_node = typename node_wrapper>::type; + // nodes => native value types template struct node_unwrapper { @@ -1503,7 +1811,22 @@ TOML_IMPL_NAMESPACE_START using type = T; }; template - using unwrap_node = typename node_unwrapper::type; + struct node_unwrapper> + { + using type = std::add_const_t; + }; + template + struct node_unwrapper> + { + using type = std::add_volatile_t; + }; + template + struct node_unwrapper> + { + using type = std::add_volatile_t>; + }; + template + using unwrap_node = typename node_unwrapper>::type; template struct node_type_getter @@ -1526,44 +1849,58 @@ TOML_IMPL_NAMESPACE_START static constexpr auto value = node_type::none; }; template - inline constexpr node_type node_type_of = node_type_getter>>::value; + inline constexpr node_type node_type_of = node_type_getter>>::value; } TOML_IMPL_NAMESPACE_END; TOML_NAMESPACE_START { template - inline constexpr bool is_table = std::is_same_v, table>; + inline constexpr bool is_table = std::is_same_v, table>; template - inline constexpr bool is_array = std::is_same_v, array>; + inline constexpr bool is_array = std::is_same_v, array>; template inline constexpr bool is_container = is_table || is_array; template - inline constexpr bool is_string = std::is_same_v>, value>; + inline constexpr bool is_string = std::is_same_v< // + impl::remove_cvref>>, // + value>; template - inline constexpr bool is_integer = std::is_same_v>, value>; + inline constexpr bool is_integer = std::is_same_v< // + impl::remove_cvref>>, // + value>; template - inline constexpr bool is_floating_point = std::is_same_v>, value>; + inline constexpr bool is_floating_point = std::is_same_v< // + impl::remove_cvref>>, // + value>; template inline constexpr bool is_number = is_integer || is_floating_point; template - inline constexpr bool is_boolean = std::is_same_v>, value>; + inline constexpr bool is_boolean = std::is_same_v< // + impl::remove_cvref>>, // + value>; template - inline constexpr bool is_date = std::is_same_v>, value>; + inline constexpr bool is_date = std::is_same_v< // + impl::remove_cvref>>, // + value>; template - inline constexpr bool is_time = std::is_same_v>, value