Windows compat
This commit is contained in:
parent
18c840b945
commit
ebada328e8
|
@ -1,5 +1,5 @@
|
|||
.vscode
|
||||
build
|
||||
build*
|
||||
docs
|
||||
external
|
||||
resource/*/.*
|
|
@ -8,6 +8,7 @@ option(USE_FMA "Use fma" 1)
|
|||
option(LOG_DEBUG "Show debug logs" 0)
|
||||
option(LOG_TRACE "Show trace logs" 0)
|
||||
option(NATIVE "Build with -march=native" 0)
|
||||
option(GL_OLD "Use OpenGL 4.2 not 4.6" 0)
|
||||
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
|
@ -23,10 +24,15 @@ if(NOT CMAKE_BUILD_TYPE)
|
|||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(/std:c++latest)
|
||||
add_compile_definitions(WIN32_LEAN_AND_MEAN=)
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
|
||||
endif()
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
add_compile_definitions(FIXED_WINDOW=${FIXED_WINDOW} LOG_DEBUG=${LOG_DEBUG} LOG_TRACE=${LOG_TRACE} HN_USE_FILESYSTEM=1)
|
||||
add_compile_definitions(FIXED_WINDOW=${FIXED_WINDOW} LOG_DEBUG=${LOG_DEBUG} LOG_TRACE=${LOG_TRACE} GL_OLD=${GL_OLD} HN_USE_FILESYSTEM=1)
|
||||
if(PROFILING)
|
||||
add_compile_definitions(TRACY_ENABLE=1)
|
||||
endif(PROFILING)
|
||||
|
@ -38,23 +44,39 @@ if(SIMD_LEVEL EQUAL "avx2")
|
|||
elseif(SIMD_LEVEL EQUAL "avx512f")
|
||||
add_compile_definitions(FN_COMPILE_AVX512=1)
|
||||
endif()
|
||||
if(WIN32)
|
||||
add_definitions(/arch:AVX2)
|
||||
else()
|
||||
add_definitions(-m${SIMD_LEVEL})
|
||||
endif()
|
||||
if(USE_FMA)
|
||||
if(WIN32)
|
||||
add_definitions(/GL /fp:fast)
|
||||
else()
|
||||
add_definitions(-mfma)
|
||||
endif()
|
||||
endif(USE_FMA)
|
||||
|
||||
file(GLOB_RECURSE CORE_SOURCES "src/core/*.cpp" "deps/tracy/TracyClient.cpp")
|
||||
set(CORE_HEADERS "deps/toml++" "deps/robin_hood" "deps/libguarded" "deps/tracy")
|
||||
set(CORE_LIBS pthread dl glm::glm_static picoquic-core zstd::zstd_static)
|
||||
set(CORE_LIBS glm::glm_static zstd::zstd_static) # picoquic
|
||||
|
||||
file(GLOB_RECURSE CLIENT_SOURCES "src/client/*.cpp" "deps/imgui/*.cpp" "deps/meshoptimizer/*.cpp" "deps/gl3w/gl3w.c" "deps/volk/volk.c")
|
||||
set(CLIENT_HEADERS "deps/imgui" "deps/meshoptimizer" "deps/gl3w" "deps/volk")
|
||||
set(CLIENT_HEADERS "deps/imgui" "deps/meshoptimizer" "deps/gl3w" "deps/volk") # vulkan
|
||||
set(CLIENT_LIBS glfw)
|
||||
|
||||
file(GLOB_RECURSE SERVER_SOURCES "src/server/*.cpp" "deps/FastNoiseSIMD/*.cpp")
|
||||
set(SERVER_HEADERS "deps/FastNoiseSIMD")
|
||||
set(SERVER_LINKED)
|
||||
|
||||
if(WIN32)
|
||||
set(CLIENT_HEADERS ${CLIENT_HEADERS} $ENV{VULKAN_SDK}\\include)
|
||||
find_package(OpenSSL)
|
||||
set(CORE_LIBS ${CORE_LIBS} ${CMAKE_BINARY_DIR}/libs/*.lib ${OPENSSL_LIBRARIES} ws2_32)
|
||||
else()
|
||||
set(CORE_LIBS ${CORE_LIBS} picoquic-core pthread dl)
|
||||
endif()
|
||||
|
||||
# All in one exec
|
||||
add_executable(univerxel "src/main.cpp" ${CORE_SOURCES} ${CLIENT_SOURCES} ${SERVER_SOURCES})
|
||||
target_compile_features(univerxel PUBLIC cxx_std_17)
|
||||
|
|
10
README.md
10
README.md
|
@ -14,6 +14,7 @@ Work in progress galaxy down to atom (mostly centimeter) online voxel game
|
|||
- [Optionally](#optionally)
|
||||
- [Installation](#installation)
|
||||
- [Additionally](#additionally)
|
||||
- [Windows](#windows)
|
||||
- [RoadMap](#roadmap)
|
||||
- [License](#license)
|
||||
- [Contact](#contact)
|
||||
|
@ -102,6 +103,7 @@ PROFILING | Tracy profiling | `0`
|
|||
LOG_DEBUG | Debug logs | `0`
|
||||
LOG_TRACE | Trace logs | `0`
|
||||
NATIVE | Optimize for native CPU | `0`
|
||||
GL_OLD | Use OpenGL 4.2 not 4.6 | `0`
|
||||
|
||||
1. Build Make
|
||||
```sh
|
||||
|
@ -132,6 +134,14 @@ cd resource/textures-src
|
|||
./merge.py <args> # Combine grey images to RGB
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
1. Setup Visual Studio 2017+ with C++
|
||||
2. Clone picotls and picoquic in a separate directory
|
||||
3. Set `%OPENSSL64DIR%` and check `WindowsPort.md` and `Readme.md` note from respective library
|
||||
4. Compile then with MsBuild
|
||||
5. Copy picoquic.lib, picotls-openssl.lib and picotls-fusion.lib to build/libs
|
||||
6. Build univerxel with cmake `-A x64` and MsBuild
|
||||
|
||||
<!-- ROADMAP -->
|
||||
## RoadMap
|
||||
|
|
4
TODO.md
4
TODO.md
|
@ -46,6 +46,9 @@
|
|||
- [~] CI build
|
||||
- [ ] CMake package
|
||||
- [x] GitLab CI
|
||||
- Platfoms
|
||||
- [x] Linux
|
||||
- [~] Windows
|
||||
- [ ] Universe
|
||||
- [ ] Galaxy
|
||||
- [ ] Rotation
|
||||
|
@ -107,5 +110,6 @@
|
|||
- [ ] Deferred
|
||||
- [ ] Cascaded shadow maps
|
||||
- [ ] Ray Tracing
|
||||
- [ ] Avoid transparent back-face
|
||||
- [ ] Translucency
|
||||
- Back face Depth based
|
||||
|
|
|
@ -4,11 +4,29 @@ cmake_policy(SET CMP0048 NEW)
|
|||
project(picoquic VERSION 0.0.1 LANGUAGES C CXX)
|
||||
find_package (Threads REQUIRED)
|
||||
|
||||
set(PICOQUIC_CORE_HEADERS
|
||||
picoquic.h
|
||||
picosocks.h
|
||||
picoquic_utils.h
|
||||
picoquic_packet_loop.h
|
||||
picoquic_unified_log.h
|
||||
picoquic_logger.h
|
||||
picoquic_binlog.h
|
||||
)
|
||||
|
||||
find_package(OpenSSL)
|
||||
|
||||
include_directories(picoquic "picotls/include" ${OPENSSL_INCLUDE_DIR})
|
||||
|
||||
if(WIN32)
|
||||
MESSAGE(WARNING "Please build picoquic and picotls with Visual Studio")
|
||||
MESSAGE(WARNING "Then put picoquic.lib, picotls-core.lib picotls-openssl.lib and picotls-fusion.lib in build/libs")
|
||||
else()
|
||||
add_subdirectory("picotls")
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
set(CMAKE_C_FLAGS "-std=c99 -Wall -Werror -O2 -g ${CC_WARNING_FLAGS} ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "-std=c99 -O2 -g ${CC_WARNING_FLAGS} ${CMAKE_C_FLAGS}")
|
||||
|
||||
if(DISABLE_DEBUG_PRINTF)
|
||||
set(CMAKE_C_FLAGS "-DDISABLE_DEBUG_PRINTF ${CMAKE_C_FLAGS}")
|
||||
|
@ -43,18 +61,6 @@ set(PICOQUIC_LIBRARY_FILES
|
|||
util.c
|
||||
)
|
||||
|
||||
set(PICOQUIC_CORE_HEADERS
|
||||
picoquic.h
|
||||
picosocks.h
|
||||
picoquic_utils.h
|
||||
picoquic_packet_loop.h
|
||||
picoquic_unified_log.h
|
||||
picoquic_logger.h
|
||||
picoquic_binlog.h
|
||||
)
|
||||
|
||||
find_package(OpenSSL)
|
||||
|
||||
include_directories(picoquic "picotls/include" ${OPENSSL_INCLUDE_DIR})
|
||||
add_library(picoquic-core ${PICOQUIC_CORE_HEADERS} ${PICOQUIC_LIBRARY_FILES})
|
||||
target_link_libraries(picoquic-core picotls-core picotls-openssl picotls-fusion ${OPENSSL_LIBRARIES})
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
|
||||
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.
|
|
@ -1,19 +1,20 @@
|
|||
#define TOML_HEADER_ONLY 0
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//# {{
|
||||
#ifndef INCLUDE_TOMLPLUSPLUS_H
|
||||
#define INCLUDE_TOMLPLUSPLUS_H
|
||||
//# }}
|
||||
|
||||
//# Note: most of these would be included transitively but
|
||||
//# they're listed explicitly here because this file
|
||||
//# is used as the source for generate_single_header.py.
|
||||
|
||||
#include "toml_preprocessor.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SPAM_WARNINGS
|
||||
|
||||
#include "toml_common.h"
|
||||
#include "toml_date_time.h"
|
||||
#include "toml_print_to_stream.h"
|
||||
|
@ -22,7 +23,6 @@
|
|||
#include "toml_array.h"
|
||||
#include "toml_table.h"
|
||||
#include "toml_node_view.h"
|
||||
#include "toml_utf8_generated.h"
|
||||
#include "toml_utf8.h"
|
||||
#include "toml_formatter.h"
|
||||
#include "toml_default_formatter.h"
|
||||
|
@ -40,68 +40,109 @@
|
|||
#include "toml_default_formatter.hpp"
|
||||
#include "toml_json_formatter.hpp"
|
||||
#if TOML_PARSER
|
||||
#include "toml_utf8_streams.hpp"
|
||||
#include "toml_parser.hpp"
|
||||
#endif // TOML_PARSER
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !TOML_HEADER_ONLY
|
||||
#include "toml_instantiations.hpp"
|
||||
#endif // !TOML_ALL_INLINE
|
||||
#endif // !TOML_HEADER_ONLY
|
||||
|
||||
#endif // TOML_IMPLEMENTATION
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SPAM_WARNINGS
|
||||
|
||||
// macro hygiene
|
||||
#if TOML_UNDEF_MACROS
|
||||
#undef TOML_INT_CHARCONV
|
||||
#undef TOML_FLOAT_CHARCONV
|
||||
#undef TOML_ABI_NAMESPACES
|
||||
#undef TOML_ABI_NAMESPACE_BOOL
|
||||
#undef TOML_ABI_NAMESPACE_END
|
||||
#undef TOML_ABI_NAMESPACE_START
|
||||
#undef TOML_ALWAYS_INLINE
|
||||
#undef TOML_ANON_NAMESPACE
|
||||
#undef TOML_ANON_NAMESPACE_END
|
||||
#undef TOML_ANON_NAMESPACE_START
|
||||
#undef TOML_ARM
|
||||
#undef TOML_ASSERT
|
||||
#undef TOML_ASSUME
|
||||
#undef TOML_ASYMMETRICAL_EQUALITY_OPS
|
||||
#undef TOML_ATTR
|
||||
#undef TOML_PUSH_WARNINGS
|
||||
#undef TOML_DISABLE_SWITCH_WARNINGS
|
||||
#undef TOML_CLANG
|
||||
#undef TOML_COMPILER_EXCEPTIONS
|
||||
#undef TOML_CONCAT
|
||||
#undef TOML_CONCAT_1
|
||||
#undef TOML_CONSTEVAL
|
||||
#undef TOML_CPP
|
||||
#undef TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
#undef TOML_DISABLE_INIT_WARNINGS
|
||||
#undef TOML_DISABLE_VTABLE_WARNINGS
|
||||
#undef TOML_DISABLE_PADDING_WARNINGS
|
||||
#undef TOML_DISABLE_FLOAT_WARNINGS
|
||||
#undef TOML_DISABLE_SPAM_WARNINGS
|
||||
#undef TOML_DISABLE_SHADOW_WARNINGS
|
||||
#undef TOML_DISABLE_SUGGEST_WARNINGS
|
||||
#undef TOML_DISABLE_ALL_WARNINGS
|
||||
#undef TOML_POP_WARNINGS
|
||||
#undef TOML_ALWAYS_INLINE
|
||||
#undef TOML_NEVER_INLINE
|
||||
#undef TOML_ASSUME
|
||||
#undef TOML_UNREACHABLE
|
||||
#undef TOML_INTERFACE
|
||||
#undef TOML_DISABLE_SWITCH_WARNINGS
|
||||
#undef TOML_DISABLE_WARNINGS
|
||||
#undef TOML_ENABLE_WARNINGS
|
||||
#undef TOML_EMPTY_BASES
|
||||
#undef TOML_CPP_VERSION
|
||||
#undef TOML_CPP
|
||||
#undef TOML_MAY_THROW
|
||||
#undef TOML_NO_DEFAULT_CASE
|
||||
#undef TOML_CONSTEVAL
|
||||
#undef TOML_LIKELY
|
||||
#undef TOML_UNLIKELY
|
||||
#undef TOML_NODISCARD_CTOR
|
||||
#undef TOML_MAKE_VERSION
|
||||
#undef TOML_EVAL_BOOL_0
|
||||
#undef TOML_EVAL_BOOL_1
|
||||
#undef TOML_EXTERNAL_LINKAGE
|
||||
#undef TOML_FLOAT128
|
||||
#undef TOML_FLOAT16
|
||||
#undef TOML_FLOAT_CHARCONV
|
||||
#undef TOML_FP16
|
||||
#undef TOML_GCC
|
||||
#undef TOML_HAS_ATTR
|
||||
#undef TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
#undef TOML_HAS_INCLUDE
|
||||
#undef TOML_ICC
|
||||
#undef TOML_ICC_CL
|
||||
#undef TOML_IMPLEMENTATION
|
||||
#undef TOML_IMPL_NAMESPACE_END
|
||||
#undef TOML_IMPL_NAMESPACE_START
|
||||
#undef TOML_INT128
|
||||
#undef TOML_INTELLISENSE
|
||||
#undef TOML_INTERFACE
|
||||
#undef TOML_INTERNAL_LINKAGE
|
||||
#undef TOML_INT_CHARCONV
|
||||
#undef TOML_LANG_AT_LEAST
|
||||
#undef TOML_LANG_EFFECTIVE_VERSION
|
||||
#undef TOML_LANG_HIGHER_THAN
|
||||
#undef TOML_LANG_AT_LEAST
|
||||
#undef TOML_LANG_UNRELEASED
|
||||
#undef TOML_STRING_PREFIX_1
|
||||
#undef TOML_STRING_PREFIX
|
||||
#undef TOML_UNDEF_MACROS
|
||||
#undef TOML_RELOPS_REORDERING
|
||||
#undef TOML_ASYMMETRICAL_EQUALITY_OPS
|
||||
#undef TOML_ALL_INLINE
|
||||
#undef TOML_IMPLEMENTATION
|
||||
#undef TOML_EXTERNAL_LINKAGE
|
||||
#undef TOML_INTERNAL_LINKAGE
|
||||
#undef TOML_INTERNAL_NAMESPACE
|
||||
#undef TOML_COMPILER_EXCEPTIONS
|
||||
#undef TOML_TRIVIAL_ABI
|
||||
#undef TOML_ABI_NAMESPACES
|
||||
#undef TOML_ABI_NAMESPACE_START
|
||||
#undef TOML_ABI_NAMESPACE_END
|
||||
#undef TOML_PARSER_TYPENAME
|
||||
#undef TOML_LAUNDER
|
||||
#undef TOML_LIFETIME_HOOKS
|
||||
#undef TOML_LIKELY
|
||||
#undef TOML_MAKE_BITOPS
|
||||
#undef TOML_MAKE_VERSION
|
||||
#undef TOML_MAY_THROW
|
||||
#undef TOML_MSVC
|
||||
#undef TOML_NAMESPACE
|
||||
#undef TOML_NAMESPACE_END
|
||||
#undef TOML_NAMESPACE_START
|
||||
#undef TOML_NEVER_INLINE
|
||||
#undef TOML_NODISCARD_CTOR
|
||||
#undef TOML_NO_DEFAULT_CASE
|
||||
#undef TOML_PARSER_TYPENAME
|
||||
#undef TOML_POP_WARNINGS
|
||||
#undef TOML_PUSH_WARNINGS
|
||||
#undef TOML_SA_LIST_BEG
|
||||
#undef TOML_SA_LIST_END
|
||||
#undef TOML_SA_LIST_NEW
|
||||
#undef TOML_SA_LIST_NXT
|
||||
#undef TOML_SA_LIST_SEP
|
||||
#undef TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
#undef TOML_SA_NEWLINE
|
||||
#undef TOML_SA_NODE_TYPE_LIST
|
||||
#undef TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
#undef TOML_SA_VALUE_EXACT_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_MESSAGE_CONST_CHAR8
|
||||
#undef TOML_SA_VALUE_MESSAGE_U8STRING_VIEW
|
||||
#undef TOML_SA_VALUE_MESSAGE_WSTRING
|
||||
#undef TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
#undef TOML_TRIVIAL_ABI
|
||||
#undef TOML_UINT128
|
||||
#undef TOML_UNLIKELY
|
||||
#undef TOML_UNREACHABLE
|
||||
#undef TOML_USING_ANON_NAMESPACE
|
||||
#endif
|
||||
|
||||
//# {{
|
||||
#endif // INCLUDE_TOMLPLUSPLUS_H
|
||||
//# }}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,41 +13,104 @@
|
|||
|
||||
#include "toml_array.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SUGGEST_WARNINGS
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
|
||||
namespace toml
|
||||
{
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::preinsertion_resize(size_t idx, size_t count) noexcept
|
||||
void array::lh_ctor() noexcept
|
||||
{
|
||||
const auto new_size = values.size() + count;
|
||||
const auto inserting_at_end = idx == values.size();
|
||||
values.resize(new_size);
|
||||
if (!inserting_at_end)
|
||||
{
|
||||
for (size_t r = new_size, e = idx + count, l = e; r-- > e; l--)
|
||||
values[r] = std::move(values[l]);
|
||||
}
|
||||
TOML_ARRAY_CREATED;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::array() noexcept = default;
|
||||
void array::lh_dtor() noexcept
|
||||
{
|
||||
TOML_ARRAY_DESTROYED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::array() noexcept
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_ctor();
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::array(const array& other) noexcept
|
||||
: node{ other }
|
||||
{
|
||||
elements.reserve(other.elements.size());
|
||||
for (const auto& elem : other)
|
||||
elements.emplace_back(impl::make_node(elem));
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_ctor();
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::array(array&& other) noexcept
|
||||
: node{ std::move(other) },
|
||||
values{ std::move(other.values) }
|
||||
{}
|
||||
elements{ std::move(other.elements) }
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_ctor();
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array& array::operator= (const array& rhs) noexcept
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
node::operator=(rhs);
|
||||
elements.clear();
|
||||
elements.reserve(rhs.elements.size());
|
||||
for (const auto& elem : rhs)
|
||||
elements.emplace_back(impl::make_node(elem));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array& array::operator= (array&& rhs) noexcept
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
node::operator=(std::move(rhs));
|
||||
values = std::move(rhs.values);
|
||||
elements = std::move(rhs.elements);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::~array() noexcept
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_dtor();
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::preinsertion_resize(size_t idx, size_t count) noexcept
|
||||
{
|
||||
TOML_ASSERT(idx <= elements.size());
|
||||
TOML_ASSERT(count >= 1_sz);
|
||||
const auto old_size = elements.size();
|
||||
const auto new_size = old_size + count;
|
||||
const auto inserting_at_end = idx == old_size;
|
||||
elements.resize(new_size);
|
||||
if (!inserting_at_end)
|
||||
{
|
||||
for(size_t left = old_size, right = new_size - 1_sz; left --> idx; right--)
|
||||
elements[right] = std::move(elements[left]);
|
||||
}
|
||||
}
|
||||
|
||||
#define TOML_MEMBER_ATTR(attr) TOML_EXTERNAL_LINKAGE TOML_ATTR(attr)
|
||||
|
||||
TOML_MEMBER_ATTR(const) node_type array::type() const noexcept { return node_type::array; }
|
||||
|
@ -57,69 +120,122 @@ namespace toml
|
|||
TOML_MEMBER_ATTR(const) const array* array::as_array() const noexcept { return this; }
|
||||
TOML_MEMBER_ATTR(const) array* array::as_array() noexcept { return this; }
|
||||
|
||||
TOML_MEMBER_ATTR(pure) const node& array::operator[] (size_t index) const noexcept { return *values[index]; }
|
||||
TOML_MEMBER_ATTR(pure) node& array::operator[] (size_t index) noexcept { return *values[index]; }
|
||||
TOML_MEMBER_ATTR(pure) const node& array::operator[] (size_t index) const noexcept { return *elements[index]; }
|
||||
TOML_MEMBER_ATTR(pure) node& array::operator[] (size_t index) noexcept { return *elements[index]; }
|
||||
|
||||
TOML_MEMBER_ATTR(pure) const node& array::front() const noexcept { return *values.front(); }
|
||||
TOML_MEMBER_ATTR(pure) const node& array::back() const noexcept { return *values.back(); }
|
||||
TOML_MEMBER_ATTR(pure) node& array::front() noexcept { return *values.front(); }
|
||||
TOML_MEMBER_ATTR(pure) node& array::back() noexcept { return *values.back(); }
|
||||
TOML_MEMBER_ATTR(pure) const node& array::front() const noexcept { return *elements.front(); }
|
||||
TOML_MEMBER_ATTR(pure) const node& array::back() const noexcept { return *elements.back(); }
|
||||
TOML_MEMBER_ATTR(pure) node& array::front() noexcept { return *elements.front(); }
|
||||
TOML_MEMBER_ATTR(pure) node& array::back() noexcept { return *elements.back(); }
|
||||
|
||||
TOML_MEMBER_ATTR(pure) array::const_iterator array::begin() const noexcept { return { values.begin() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::const_iterator array::end() const noexcept { return { values.end() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::const_iterator array::cbegin() const noexcept { return { values.cbegin() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::const_iterator array::cend() const noexcept { return { values.cend() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::iterator array::begin() noexcept { return { values.begin() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::iterator array::end() noexcept { return { values.end() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::const_iterator array::begin() const noexcept { return { elements.begin() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::const_iterator array::end() const noexcept { return { elements.end() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::const_iterator array::cbegin() const noexcept { return { elements.cbegin() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::const_iterator array::cend() const noexcept { return { elements.cend() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::iterator array::begin() noexcept { return { elements.begin() }; }
|
||||
TOML_MEMBER_ATTR(pure) array::iterator array::end() noexcept { return { elements.end() }; }
|
||||
|
||||
TOML_MEMBER_ATTR(pure) size_t array::size() const noexcept { return values.size(); }
|
||||
TOML_MEMBER_ATTR(pure) size_t array::capacity() const noexcept { return values.capacity(); }
|
||||
TOML_MEMBER_ATTR(pure) bool array::empty() const noexcept { return values.empty(); }
|
||||
TOML_MEMBER_ATTR(const) size_t array::max_size() const noexcept { return values.max_size(); }
|
||||
TOML_MEMBER_ATTR(pure) size_t array::size() const noexcept { return elements.size(); }
|
||||
TOML_MEMBER_ATTR(pure) size_t array::capacity() const noexcept { return elements.capacity(); }
|
||||
TOML_MEMBER_ATTR(pure) bool array::empty() const noexcept { return elements.empty(); }
|
||||
TOML_MEMBER_ATTR(const) size_t array::max_size() const noexcept { return elements.max_size(); }
|
||||
|
||||
TOML_EXTERNAL_LINKAGE void array::reserve(size_t new_capacity) { values.reserve(new_capacity); }
|
||||
TOML_EXTERNAL_LINKAGE void array::clear() noexcept { values.clear(); }
|
||||
TOML_EXTERNAL_LINKAGE void array::shrink_to_fit() { values.shrink_to_fit(); }
|
||||
TOML_EXTERNAL_LINKAGE void array::reserve(size_t new_capacity) { elements.reserve(new_capacity); }
|
||||
TOML_EXTERNAL_LINKAGE void array::clear() noexcept { elements.clear(); }
|
||||
TOML_EXTERNAL_LINKAGE void array::shrink_to_fit() { elements.shrink_to_fit(); }
|
||||
|
||||
#undef TOML_MEMBER_ATTR
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
if (elements.empty())
|
||||
return false;
|
||||
|
||||
if (ntype == node_type::none)
|
||||
ntype = elements[0]->type();
|
||||
|
||||
for (const auto& val : elements)
|
||||
if (val->type() != ntype)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool array_is_homogeneous(T& elements, node_type ntype, U& first_nonmatch) noexcept
|
||||
{
|
||||
if (elements.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = elements[0]->type();
|
||||
for (const auto& val : elements)
|
||||
{
|
||||
if (val->type() != ntype)
|
||||
{
|
||||
first_nonmatch = val.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype, toml::node*& first_nonmatch) noexcept
|
||||
{
|
||||
return impl::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::truncate(size_t new_size)
|
||||
{
|
||||
if (new_size < values.size())
|
||||
values.resize(new_size);
|
||||
if (new_size < elements.size())
|
||||
elements.resize(new_size);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::iterator array::erase(const_iterator pos) noexcept
|
||||
{
|
||||
return { values.erase(pos.raw_) };
|
||||
return { elements.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::iterator array::erase(const_iterator first, const_iterator last) noexcept
|
||||
{
|
||||
return { values.erase(first.raw_, last.raw_) };
|
||||
return { elements.erase(first.raw_, last.raw_) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::pop_back() noexcept
|
||||
{
|
||||
values.pop_back();
|
||||
elements.pop_back();
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
TOML_ATTR(pure)
|
||||
node* array::get(size_t index) noexcept
|
||||
{
|
||||
return index < values.size() ? values[index].get() : nullptr;
|
||||
return index < elements.size() ? elements[index].get() : nullptr;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
TOML_ATTR(pure)
|
||||
const node* array::get(size_t index) const noexcept
|
||||
{
|
||||
return index < values.size() ? values[index].get() : nullptr;
|
||||
return index < elements.size() ? elements[index].get() : nullptr;
|
||||
}
|
||||
|
||||
TOML_API
|
||||
|
@ -128,17 +244,17 @@ namespace toml
|
|||
{
|
||||
if (&lhs == &rhs)
|
||||
return true;
|
||||
if (lhs.values.size() != rhs.values.size())
|
||||
if (lhs.elements.size() != rhs.elements.size())
|
||||
return false;
|
||||
for (size_t i = 0, e = lhs.values.size(); i < e; i++)
|
||||
for (size_t i = 0, e = lhs.elements.size(); i < e; i++)
|
||||
{
|
||||
const auto lhs_type = lhs.values[i]->type();
|
||||
const node& rhs_ = *rhs.values[i];
|
||||
const auto lhs_type = lhs.elements[i]->type();
|
||||
const node& rhs_ = *rhs.elements[i];
|
||||
const auto rhs_type = rhs_.type();
|
||||
if (lhs_type != rhs_type)
|
||||
return false;
|
||||
|
||||
const bool equal = lhs.values[i]->visit([&](const auto& lhs_) noexcept
|
||||
const bool equal = lhs.elements[i]->visit([&](const auto& lhs_) noexcept
|
||||
{
|
||||
return lhs_ == *reinterpret_cast<std::remove_reference_t<decltype(lhs_)>*>(&rhs_);
|
||||
});
|
||||
|
@ -159,9 +275,9 @@ namespace toml
|
|||
size_t array::total_leaf_count() const noexcept
|
||||
{
|
||||
size_t leaves{};
|
||||
for (size_t i = 0, e = values.size(); i < e; i++)
|
||||
for (size_t i = 0, e = elements.size(); i < e; i++)
|
||||
{
|
||||
auto arr = values[i]->as_array();
|
||||
auto arr = elements[i]->as_array();
|
||||
leaves += arr ? arr->total_leaf_count() : 1_sz;
|
||||
}
|
||||
return leaves;
|
||||
|
@ -172,29 +288,29 @@ namespace toml
|
|||
{
|
||||
for (size_t i = 0, e = child.size(); i < e; i++)
|
||||
{
|
||||
auto type = child.values[i]->type();
|
||||
auto type = child.elements[i]->type();
|
||||
if (type == node_type::array)
|
||||
{
|
||||
array& arr = *reinterpret_cast<array*>(child.values[i].get());
|
||||
array& arr = *reinterpret_cast<array*>(child.elements[i].get());
|
||||
if (!arr.empty())
|
||||
flatten_child(std::move(arr), dest_index);
|
||||
}
|
||||
else
|
||||
values[dest_index++] = std::move(child.values[i]);
|
||||
elements[dest_index++] = std::move(child.elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array& array::flatten() &
|
||||
{
|
||||
if (values.empty())
|
||||
if (elements.empty())
|
||||
return *this;
|
||||
|
||||
bool requires_flattening = false;
|
||||
size_t size_after_flattening = values.size();
|
||||
for (size_t i = values.size(); i --> 0_sz;)
|
||||
size_t size_after_flattening = elements.size();
|
||||
for (size_t i = elements.size(); i --> 0_sz;)
|
||||
{
|
||||
auto arr = values[i]->as_array();
|
||||
auto arr = elements[i]->as_array();
|
||||
if (!arr)
|
||||
continue;
|
||||
size_after_flattening--; //discount the array itself
|
||||
|
@ -205,25 +321,25 @@ namespace toml
|
|||
size_after_flattening += leaf_count;
|
||||
}
|
||||
else
|
||||
values.erase(values.cbegin() + static_cast<ptrdiff_t>(i));
|
||||
elements.erase(elements.cbegin() + static_cast<ptrdiff_t>(i));
|
||||
}
|
||||
|
||||
if (!requires_flattening)
|
||||
return *this;
|
||||
|
||||
values.reserve(size_after_flattening);
|
||||
elements.reserve(size_after_flattening);
|
||||
|
||||
size_t i = 0;
|
||||
while (i < values.size())
|
||||
while (i < elements.size())
|
||||
{
|
||||
auto arr = values[i]->as_array();
|
||||
auto arr = elements[i]->as_array();
|
||||
if (!arr)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<node> arr_storage = std::move(values[i]);
|
||||
std::unique_ptr<node> arr_storage = std::move(elements[i]);
|
||||
const auto leaf_count = arr->total_leaf_count();
|
||||
if (leaf_count > 1_sz)
|
||||
preinsertion_resize(i + 1_sz, leaf_count - 1_sz);
|
||||
|
@ -232,6 +348,11 @@ namespace toml
|
|||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SUGGEST_WARNINGS
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_array_of_tables() const noexcept
|
||||
{
|
||||
return is_homogeneous(node_type::table);
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,10 +6,7 @@
|
|||
#pragma once
|
||||
#include "toml_common.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief A local date.
|
||||
struct TOML_TRIVIAL_ABI date
|
||||
|
@ -82,21 +79,20 @@ namespace toml
|
|||
|
||||
/// \brief Prints a date out to a stream as `YYYY-MM-DD` (per RFC 3339).
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::date{ 1987, 3, 16 } << std::endl;
|
||||
/// std::cout << toml::date{ 1987, 3, 16 } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 1987-03-16
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const date& rhs)
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const date& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const date&);
|
||||
#endif
|
||||
|
||||
|
@ -131,7 +127,8 @@ namespace toml
|
|||
|
||||
private:
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
static constexpr uint64_t pack(time t) noexcept
|
||||
{
|
||||
return static_cast<uint64_t>(t.hour) << 48
|
||||
|
@ -173,8 +170,8 @@ namespace toml
|
|||
|
||||
/// \brief Prints a time out to a stream as `HH:MM:SS.FFFFFF` (per RFC 3339).
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::time{ 10, 20, 34 } << std::endl;
|
||||
/// std::cout << toml::time{ 10, 20, 34, 500000000 } << std::endl;
|
||||
/// std::cout << toml::time{ 10, 20, 34 } << "\n";
|
||||
/// std::cout << toml::time{ 10, 20, 34, 500000000 } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
|
@ -182,14 +179,13 @@ namespace toml
|
|||
/// 10:20:34.5
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const time& rhs)
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const time& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const time&);
|
||||
#endif
|
||||
|
||||
|
@ -208,10 +204,10 @@ namespace toml
|
|||
/// \brief Constructs a timezone offset from separate hour and minute totals.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::time_offset{ 2, 30 } << std::endl;
|
||||
/// std::cout << toml::time_offset{ -2, 30 } << std::endl;
|
||||
/// std::cout << toml::time_offset{ -2, -30 } << std::endl;
|
||||
/// std::cout << toml::time_offset{ 0, 0 } << std::endl;
|
||||
/// std::cout << toml::time_offset{ 2, 30 } << "\n";
|
||||
/// std::cout << toml::time_offset{ -2, 30 } << "\n";
|
||||
/// std::cout << toml::time_offset{ -2, -30 } << "\n";
|
||||
/// std::cout << toml::time_offset{ 0, 0 } << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -274,11 +270,11 @@ namespace toml
|
|||
|
||||
/// \brief Prints a time_offset out to a stream as `+-HH:MM or Z` (per RFC 3339).
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::time_offset{ 2, 30 } << std::endl;
|
||||
/// std::cout << toml::time_offset{ 2, -30 } << std::endl;
|
||||
/// std::cout << toml::time_offset{} << std::endl;
|
||||
/// std::cout << toml::time_offset{ -2, 30 } << std::endl;
|
||||
/// std::cout << toml::time_offset{ -2, -30 } << std::endl;
|
||||
/// std::cout << toml::time_offset{ 2, 30 } << "\n";
|
||||
/// std::cout << toml::time_offset{ 2, -30 } << "\n";
|
||||
/// std::cout << toml::time_offset{} << "\n";
|
||||
/// std::cout << toml::time_offset{ -2, 30 } << "\n";
|
||||
/// std::cout << toml::time_offset{ -2, -30 } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
|
@ -289,22 +285,17 @@ namespace toml
|
|||
/// -02:30
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const time_offset& rhs)
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const time_offset& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const time_offset&);
|
||||
#endif
|
||||
|
||||
#ifdef TOML_OPTIONAL_TYPE
|
||||
TOML_ABI_NAMESPACE_START(custopt)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(stdopt)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt)
|
||||
|
||||
/// \brief A date-time.
|
||||
struct date_time
|
||||
|
@ -315,8 +306,8 @@ namespace toml
|
|||
toml::time time;
|
||||
/// \brief The timezone offset component.
|
||||
///
|
||||
/// \remarks The date_time is said to be 'local' if the time_offset is empty.
|
||||
optional<toml::time_offset> time_offset;
|
||||
/// \remarks The date_time is said to be 'local' if the offset is empty.
|
||||
optional<toml::time_offset> offset;
|
||||
|
||||
/// \brief Default-constructs a zero date-time.
|
||||
TOML_NODISCARD_CTOR
|
||||
|
@ -339,19 +330,19 @@ namespace toml
|
|||
///
|
||||
/// \param d The date component.
|
||||
/// \param t The time component.
|
||||
/// \param offset The timezone offset.
|
||||
/// \param off The timezone offset.
|
||||
TOML_NODISCARD_CTOR
|
||||
constexpr date_time(toml::date d, toml::time t, toml::time_offset offset) noexcept
|
||||
constexpr date_time(toml::date d, toml::time t, toml::time_offset off) noexcept
|
||||
: date{ d },
|
||||
time{ t },
|
||||
time_offset{ offset }
|
||||
offset{ off }
|
||||
{}
|
||||
|
||||
/// \brief Returns true if this date_time does not contain timezone offset information.
|
||||
[[nodiscard]]
|
||||
constexpr bool is_local() const noexcept
|
||||
{
|
||||
return !time_offset.has_value();
|
||||
return !offset.has_value();
|
||||
}
|
||||
|
||||
/// \brief Equality operator.
|
||||
|
@ -360,7 +351,7 @@ namespace toml
|
|||
{
|
||||
return lhs.date == rhs.date
|
||||
&& lhs.time == rhs.time
|
||||
&& lhs.time_offset == rhs.time_offset;
|
||||
&& lhs.offset == rhs.offset;
|
||||
}
|
||||
|
||||
/// \brief Inequality operator.
|
||||
|
@ -378,7 +369,7 @@ namespace toml
|
|||
return lhs.date < rhs.date;
|
||||
if (lhs.time != rhs.time)
|
||||
return lhs.time < rhs.time;
|
||||
return lhs.time_offset < rhs.time_offset;
|
||||
return lhs.offset < rhs.offset;
|
||||
}
|
||||
|
||||
/// \brief Less-than-or-equal-to operator.
|
||||
|
@ -389,7 +380,7 @@ namespace toml
|
|||
return lhs.date < rhs.date;
|
||||
if (lhs.time != rhs.time)
|
||||
return lhs.time < rhs.time;
|
||||
return lhs.time_offset <= rhs.time_offset;
|
||||
return lhs.offset <= rhs.offset;
|
||||
}
|
||||
|
||||
/// \brief Greater-than operator.
|
||||
|
@ -407,13 +398,13 @@ namespace toml
|
|||
}
|
||||
};
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_OPTIONAL_TYPE
|
||||
TOML_ABI_NAMESPACE_END // TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
|
||||
/// \brief Prints a date_time out to a stream in RFC 3339 format.
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 } } << std::endl;
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, { -2, -30 } } << std::endl;
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, {} } << std::endl;
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 } } << "\n";
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, { -2, -30 } } << "\n";
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, {} } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
|
@ -422,16 +413,14 @@ namespace toml
|
|||
/// 1987-03-16T10:20:34Z
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const date_time& rhs)
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const date_time& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const date_time&);
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_PADDING_WARNINGS
|
||||
TOML_NAMESPACE_END
|
||||
|
|
|
@ -11,27 +11,17 @@
|
|||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
|
||||
namespace toml::impl
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
[[nodiscard]] TOML_API
|
||||
toml::string default_formatter_make_key_segment(const toml::string& str) noexcept;
|
||||
|
||||
[[nodiscard]] TOML_API
|
||||
size_t default_formatter_inline_columns(const node& node) noexcept;
|
||||
|
||||
[[nodiscard]] TOML_API
|
||||
bool default_formatter_forces_multiline(const node& node, size_t starting_column_bias = 0) noexcept;
|
||||
[[nodiscard]] TOML_API std::string default_formatter_make_key_segment(const std::string&) noexcept;
|
||||
[[nodiscard]] TOML_API size_t default_formatter_inline_columns(const node&) noexcept;
|
||||
[[nodiscard]] TOML_API bool default_formatter_forces_multiline(const node&, size_t = 0) noexcept;
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
template <typename T, typename U>
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>&, default_formatter<U>&);
|
||||
template <typename T, typename U>
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>&, default_formatter<U>&&);
|
||||
|
||||
/// \brief A wrapper for printing TOML objects out to a stream as formatted TOML.
|
||||
///
|
||||
/// \remarks You generally don't need to create an instance of this class explicitly; the stream
|
||||
|
@ -46,8 +36,8 @@ namespace toml
|
|||
/// }};
|
||||
///
|
||||
/// // these two lines are equivalent:
|
||||
/// std::cout << toml::default_formatter{ tbl } << std::endl;
|
||||
/// std::cout << tbl << std::endl;
|
||||
/// std::cout << toml::default_formatter{ tbl } << "\n";
|
||||
/// std::cout << tbl << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -66,9 +56,9 @@ namespace toml
|
|||
{
|
||||
private:
|
||||
using base = impl::formatter<Char>;
|
||||
std::vector<toml::string> key_path;
|
||||
std::vector<std::string> key_path;
|
||||
|
||||
void print_key_segment(const toml::string& str)
|
||||
void print_key_segment(const std::string& str)
|
||||
{
|
||||
if (str.empty())
|
||||
impl::print_to_stream("''"sv, base::stream());
|
||||
|
@ -88,7 +78,11 @@ namespace toml
|
|||
}
|
||||
|
||||
if (requiresQuotes)
|
||||
base::print_quoted_string(str);
|
||||
{
|
||||
impl::print_to_stream('"', base::stream());
|
||||
impl::print_to_stream_with_escapes(str, base::stream());
|
||||
impl::print_to_stream('"', base::stream());
|
||||
}
|
||||
else
|
||||
impl::print_to_stream(str, base::stream());
|
||||
}
|
||||
|
@ -243,19 +237,21 @@ namespace toml
|
|||
if (child_value_count == 0_sz && (child_table_count > 0_sz || child_table_array_count > 0_sz))
|
||||
skip_self = true;
|
||||
|
||||
if (!skip_self)
|
||||
base::increase_indent();
|
||||
key_path.push_back(impl::default_formatter_make_key_segment(k));
|
||||
|
||||
if (!skip_self)
|
||||
{
|
||||
if (!base::naked_newline())
|
||||
{
|
||||
base::print_newline();
|
||||
base::print_newline(true);
|
||||
}
|
||||
base::increase_indent();
|
||||
base::print_indent();
|
||||
impl::print_to_stream("["sv, base::stream());
|
||||
print_key_path();
|
||||
impl::print_to_stream("]"sv, base::stream());
|
||||
base::print_newline(true);
|
||||
base::print_newline();
|
||||
}
|
||||
|
||||
print(child_tbl);
|
||||
|
@ -305,6 +301,7 @@ namespace toml
|
|||
{
|
||||
base::decrease_indent(); // so root kvps and tables have the same indent
|
||||
print(tbl);
|
||||
base::print_newline();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -320,12 +317,18 @@ namespace toml
|
|||
|
||||
public:
|
||||
|
||||
/// \brief The default flags for a default_formatter.
|
||||
static constexpr format_flags default_flags
|
||||
= format_flags::allow_literal_strings
|
||||
| format_flags::allow_multi_line_strings
|
||||
| format_flags::allow_value_format_flags;
|
||||
|
||||
/// \brief Constructs a default formatter and binds it to a TOML object.
|
||||
///
|
||||
/// \param source The source TOML object.
|
||||
/// \param flags Format option flags.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit default_formatter(const toml::node& source, format_flags flags = {}) noexcept
|
||||
explicit default_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
|
||||
: base{ source, flags }
|
||||
{}
|
||||
|
||||
|
@ -335,7 +338,7 @@ namespace toml
|
|||
friend std::basic_ostream<T>& operator << (std::basic_ostream<T>&, default_formatter<U>&&);
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template class TOML_API default_formatter<char>;
|
||||
#endif
|
||||
|
||||
|
@ -345,8 +348,7 @@ namespace toml
|
|||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML.
|
||||
template <typename T, typename U>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>& rhs)
|
||||
inline std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
rhs.key_path.clear();
|
||||
|
@ -357,32 +359,48 @@ namespace toml
|
|||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML (rvalue overload).
|
||||
template <typename T, typename U>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>&& rhs)
|
||||
inline std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>&& rhs)
|
||||
{
|
||||
return lhs << rhs; //as lvalue
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const table& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
#ifndef DOXYGEN
|
||||
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const array& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !TOML_HEADER_ONLY
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, default_formatter<char>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, default_formatter<char>&&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const table&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const array&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<std::string>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<int64_t>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<double>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<bool>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::time>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date_time>&);
|
||||
#endif
|
||||
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const table& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS, TOML_DISABLE_PADDING_WARNINGS
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const array& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const value<T>& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
#endif // !DOXYGEN
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
||||
|
|
|
@ -12,24 +12,24 @@
|
|||
//# }}
|
||||
|
||||
#include "toml_default_formatter.h"
|
||||
TOML_DISABLE_WARNINGS
|
||||
#include <cmath>
|
||||
TOML_ENABLE_WARNINGS
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
TOML_DISABLE_FLOAT_WARNINGS
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
||||
namespace toml::impl
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
inline constexpr size_t default_formatter_line_wrap = 120_sz;
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
string default_formatter_make_key_segment(const string& str) noexcept
|
||||
std::string default_formatter_make_key_segment(const std::string& str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return TOML_STRING_PREFIX("''"s);
|
||||
return "''"s;
|
||||
else
|
||||
{
|
||||
bool requiresQuotes = false;
|
||||
|
@ -47,24 +47,24 @@ namespace toml::impl
|
|||
|
||||
if (requiresQuotes)
|
||||
{
|
||||
string s;
|
||||
std::string s;
|
||||
s.reserve(str.length() + 2_sz);
|
||||
s += TOML_STRING_PREFIX('"');
|
||||
s += '"';
|
||||
for (auto c : str)
|
||||
{
|
||||
if TOML_UNLIKELY(c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F'))
|
||||
if TOML_UNLIKELY(c >= '\x00' && c <= '\x1F')
|
||||
{
|
||||
const auto& sv = low_character_escape_table[c];
|
||||
s.append(reinterpret_cast<const string_char*>(sv.data()), sv.length());
|
||||
s.append(reinterpret_cast<const char*>(sv.data()), sv.length());
|
||||
}
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('\x7F'))
|
||||
s.append(TOML_STRING_PREFIX("\\u007F"sv));
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('"'))
|
||||
s.append(TOML_STRING_PREFIX("\\\""sv));
|
||||
else if TOML_UNLIKELY(c == '\x7F')
|
||||
s.append("\\u007F"sv);
|
||||
else if TOML_UNLIKELY(c == '"')
|
||||
s.append("\\\""sv);
|
||||
else
|
||||
s += c;
|
||||
}
|
||||
s += TOML_STRING_PREFIX('"');
|
||||
s += '"';
|
||||
return s;
|
||||
}
|
||||
else
|
||||
|
@ -72,8 +72,6 @@ namespace toml::impl
|
|||
}
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
size_t default_formatter_inline_columns(const node& node) noexcept
|
||||
|
@ -112,7 +110,7 @@ namespace toml::impl
|
|||
|
||||
case node_type::string:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const value<string>*>(&node);
|
||||
auto& n = *reinterpret_cast<const value<std::string>*>(&node);
|
||||
return n.get().length() + 2_sz; // + ""
|
||||
}
|
||||
|
||||
|
@ -165,12 +163,12 @@ namespace toml::impl
|
|||
return (default_formatter_inline_columns(node) + starting_column_bias) > default_formatter_line_wrap;
|
||||
}
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void default_formatter<Char>::print_inline(const toml::table& tbl)
|
||||
inline void default_formatter<Char>::print_inline(const toml::table& tbl)
|
||||
{
|
||||
if (tbl.empty())
|
||||
impl::print_to_stream("{}"sv, base::stream());
|
||||
|
@ -204,5 +202,69 @@ namespace toml
|
|||
base::clear_naked_newline();
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS, TOML_DISABLE_FLOAT_WARNINGS
|
||||
// implementations of windows wide string nonsense
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_DISABLE_WARNINGS
|
||||
#include <windows.h> // fuckkkk :(
|
||||
TOML_ENABLE_WARNINGS
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::string narrow(std::wstring_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
std::string s;
|
||||
const auto len = WideCharToMultiByte(
|
||||
65001, 0, str.data(), static_cast<int>(str.length()), nullptr, 0, nullptr, nullptr
|
||||
);
|
||||
if (len)
|
||||
{
|
||||
s.resize(static_cast<size_t>(len));
|
||||
WideCharToMultiByte(65001, 0, str.data(), static_cast<int>(str.length()), s.data(), len, nullptr, nullptr);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::wstring widen(std::string_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
std::wstring s;
|
||||
const auto len = MultiByteToWideChar(65001, 0, str.data(), static_cast<int>(str.length()), nullptr, 0);
|
||||
if (len)
|
||||
{
|
||||
s.resize(static_cast<size_t>(len));
|
||||
MultiByteToWideChar(65001, 0, str.data(), static_cast<int>(str.length()), s.data(), len);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::wstring widen(std::u8string_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
return widen(std::string_view{ reinterpret_cast<const char*>(str.data()), str.length() });
|
||||
}
|
||||
|
||||
#endif // __cpp_lib_char8_t
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS, TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
|
|
@ -8,35 +8,8 @@
|
|||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
|
||||
namespace toml
|
||||
{
|
||||
/// \brief Format flags for modifying how TOML data is printed to streams.
|
||||
enum class format_flags : uint8_t
|
||||
{
|
||||
none,
|
||||
quote_dates_and_times = 1
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr format_flags operator & (format_flags lhs, format_flags rhs) noexcept
|
||||
{
|
||||
return static_cast<format_flags>(impl::unbox_enum(lhs) & impl::unbox_enum(rhs));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr format_flags operator | (format_flags lhs, format_flags rhs) noexcept
|
||||
{
|
||||
return static_cast<format_flags>( impl::unbox_enum(lhs) | impl::unbox_enum(rhs) );
|
||||
}
|
||||
}
|
||||
|
||||
namespace toml::impl
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
template <typename Char = char>
|
||||
class TOML_API formatter
|
||||
|
@ -45,24 +18,55 @@ namespace toml::impl
|
|||
const toml::node* source_;
|
||||
std::basic_ostream<Char>* stream_ = nullptr;
|
||||
format_flags flags_;
|
||||
int8_t indent_;
|
||||
int indent_;
|
||||
bool naked_newline_;
|
||||
|
||||
protected:
|
||||
|
||||
[[nodiscard]] const toml::node& source() const noexcept { return *source_; }
|
||||
[[nodiscard]] format_flags flags() const noexcept { return flags_; }
|
||||
[[nodiscard]] std::basic_ostream<Char>& stream() const noexcept { return *stream_; }
|
||||
|
||||
static constexpr size_t indent_columns = 4;
|
||||
static constexpr toml::string_view indent_string = TOML_STRING_PREFIX(" "sv);
|
||||
[[nodiscard]] int8_t indent() const noexcept { return indent_; }
|
||||
void indent(int8_t level) noexcept { indent_ = level; }
|
||||
static constexpr std::string_view indent_string = " "sv;
|
||||
[[nodiscard]] int indent() const noexcept { return indent_; }
|
||||
void indent(int level) noexcept { indent_ = level; }
|
||||
void increase_indent() noexcept { indent_++; }
|
||||
void decrease_indent() noexcept { indent_--; }
|
||||
|
||||
TOML_ALWAYS_INLINE
|
||||
void clear_naked_newline() noexcept { naked_newline_ = false; }
|
||||
[[nodiscard]]
|
||||
bool quote_dates_and_times() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::quote_dates_and_times) != format_flags::none;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool literal_strings_allowed() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::allow_literal_strings) != format_flags::none;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool multi_line_strings_allowed() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::allow_multi_line_strings) != format_flags::none;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool value_format_flags_allowed() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::allow_value_format_flags) != format_flags::none;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool naked_newline() const noexcept
|
||||
{
|
||||
return naked_newline_;
|
||||
}
|
||||
|
||||
void clear_naked_newline() noexcept
|
||||
{
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
void attach(std::basic_ostream<Char>& stream) noexcept
|
||||
{
|
||||
|
@ -87,53 +91,115 @@ namespace toml::impl
|
|||
|
||||
void print_indent()
|
||||
{
|
||||
for (int8_t i = 0; i < indent_; i++)
|
||||
for (int i = 0; i < indent_; i++)
|
||||
{
|
||||
print_to_stream(indent_string, *stream_);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void print_quoted_string(toml::string_view str)
|
||||
void print_quoted_string(std::string_view str, bool allow_multi_line = true)
|
||||
{
|
||||
auto literals = literal_strings_allowed();
|
||||
if (str.empty())
|
||||
print_to_stream("\"\""sv, *stream_);
|
||||
{
|
||||
print_to_stream(literals ? "''"sv : "\"\""sv, *stream_);
|
||||
clear_naked_newline();
|
||||
return;
|
||||
}
|
||||
|
||||
auto multi_line = allow_multi_line && multi_line_strings_allowed();
|
||||
if (multi_line || literals)
|
||||
{
|
||||
utf8_decoder decoder;
|
||||
bool has_line_breaks = false;
|
||||
bool has_control_chars = false;
|
||||
bool has_single_quotes = false;
|
||||
for (size_t i = 0; i < str.length() && !(has_line_breaks && has_control_chars && has_single_quotes); i++)
|
||||
{
|
||||
decoder(static_cast<uint8_t>(str[i]));
|
||||
if (decoder.error())
|
||||
{
|
||||
has_line_breaks = false;
|
||||
has_control_chars = true; //force ""
|
||||
has_single_quotes = true;
|
||||
break;
|
||||
}
|
||||
else if (decoder.has_code_point())
|
||||
{
|
||||
if (is_line_break(decoder.codepoint))
|
||||
has_line_breaks = true;
|
||||
else if (is_nontab_control_character(decoder.codepoint))
|
||||
has_control_chars = true;
|
||||
else if (decoder.codepoint == U'\'')
|
||||
has_single_quotes = true;
|
||||
}
|
||||
}
|
||||
multi_line = multi_line && has_line_breaks;
|
||||
literals = literals && !has_control_chars && !(!multi_line && has_single_quotes);
|
||||
}
|
||||
|
||||
if (literals)
|
||||
{
|
||||
const auto quot = multi_line ? "'''"sv : "'"sv;
|
||||
print_to_stream(quot, *stream_);
|
||||
print_to_stream(str, *stream_);
|
||||
print_to_stream(quot, *stream_);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_to_stream('"', *stream_);
|
||||
const auto quot = multi_line ? R"(""")"sv : R"(")"sv;
|
||||
print_to_stream(quot, *stream_);
|
||||
print_to_stream_with_escapes(str, *stream_);
|
||||
print_to_stream('"', *stream_);
|
||||
print_to_stream(quot, *stream_);
|
||||
}
|
||||
naked_newline_ = false;
|
||||
clear_naked_newline();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void print(const value<T>& val)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, string>)
|
||||
if constexpr (std::is_same_v<T, std::string>)
|
||||
{
|
||||
print_quoted_string(val.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
static constexpr auto is_dt =
|
||||
std::is_same_v<T, date>
|
||||
|| std::is_same_v<T, time>
|
||||
|| std::is_same_v<T, date_time>;
|
||||
|
||||
if constexpr (is_dt)
|
||||
if constexpr (is_one_of<T, date, time, date_time>)
|
||||
{
|
||||
if ((flags_ & format_flags::quote_dates_and_times) != format_flags::none)
|
||||
print_to_stream('"', *stream_);
|
||||
}
|
||||
|
||||
*stream_ << val;
|
||||
|
||||
if constexpr (is_dt)
|
||||
if (quote_dates_and_times())
|
||||
{
|
||||
if ((flags_ & format_flags::quote_dates_and_times) != format_flags::none)
|
||||
print_to_stream('"', *stream_);
|
||||
const auto quot = literal_strings_allowed() ? '\'' : '"';
|
||||
print_to_stream(quot, *stream_);
|
||||
print_to_stream(*val, *stream_);
|
||||
print_to_stream(quot, *stream_);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
}
|
||||
else if constexpr (is_one_of<T, int64_t/*, double*/>)
|
||||
{
|
||||
if (value_format_flags_allowed() && *val >= 0)
|
||||
{
|
||||
const auto fmt = val.flags() & value_flags::format_as_hexadecimal;
|
||||
if (fmt != value_flags::none)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case value_flags::format_as_binary: print_to_stream("0b"sv, *stream_); break;
|
||||
case value_flags::format_as_octal: print_to_stream("0o"sv, *stream_); break;
|
||||
case value_flags::format_as_hexadecimal: print_to_stream("0x"sv, *stream_); break;
|
||||
}
|
||||
print_to_stream(*val, *stream_, fmt);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
@ -144,7 +210,7 @@ namespace toml::impl
|
|||
TOML_ASSUME(type > node_type::array);
|
||||
switch (type)
|
||||
{
|
||||
case node_type::string: print(*reinterpret_cast<const value<string>*>(&val_node)); break;
|
||||
case node_type::string: print(*reinterpret_cast<const value<std::string>*>(&val_node)); break;
|
||||
case node_type::integer: print(*reinterpret_cast<const value<int64_t>*>(&val_node)); break;
|
||||
case node_type::floating_point: print(*reinterpret_cast<const value<double>*>(&val_node)); break;
|
||||
case node_type::boolean: print(*reinterpret_cast<const value<bool>*>(&val_node)); break;
|
||||
|
@ -161,9 +227,11 @@ namespace toml::impl
|
|||
{}
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template class TOML_API formatter<char>;
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS, TOML_DISABLE_PADDING_WARNINGS
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
|
|
@ -9,25 +9,40 @@
|
|||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
#if TOML_ALL_INLINE
|
||||
#error This header cannot not be included when TOML_ALL_INLINE is enabled.
|
||||
#if TOML_HEADER_ONLY && !TOML_INTELLISENSE
|
||||
#error This header cannot not be included when TOML_HEADER_ONLY is enabled.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
TOML_DISABLE_WARNINGS
|
||||
#include <ostream>
|
||||
#include <istream>
|
||||
#include <fstream>
|
||||
TOML_POP_WARNINGS
|
||||
TOML_ENABLE_WARNINGS
|
||||
|
||||
#include "toml_node_view.h"
|
||||
#include "toml_default_formatter.h"
|
||||
#include "toml_json_formatter.h"
|
||||
#if TOML_PARSER
|
||||
#include "toml_parser.h"
|
||||
#endif
|
||||
|
||||
namespace toml
|
||||
// internal implementation namespace
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
// formatters
|
||||
template class TOML_API formatter<char>;
|
||||
|
||||
// print to stream machinery
|
||||
template TOML_API void print_floating_point_to_stream(double, std::ostream&, bool);
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
// public namespace
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
// value<>
|
||||
template class TOML_API value<string>;
|
||||
template class TOML_API value<std::string>;
|
||||
template class TOML_API value<int64_t>;
|
||||
template class TOML_API value<double>;
|
||||
template class TOML_API value<bool>;
|
||||
|
@ -40,10 +55,6 @@ namespace toml
|
|||
template class TOML_API node_view<const node>;
|
||||
|
||||
// formatters
|
||||
namespace impl
|
||||
{
|
||||
template class TOML_API formatter<char>;
|
||||
}
|
||||
template class TOML_API default_formatter<char>;
|
||||
template class TOML_API json_formatter<char>;
|
||||
|
||||
|
@ -54,7 +65,7 @@ namespace toml
|
|||
template TOML_API std::ostream& operator << (std::ostream&, const time&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const time_offset&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const date_time&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<toml::string>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<std::string>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<int64_t>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<double>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const value<bool>&);
|
||||
|
@ -71,32 +82,74 @@ namespace toml
|
|||
template TOML_API std::ostream& operator << (std::ostream&, const node_view<const node>&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, node_type);
|
||||
|
||||
// print_to_stream() machinery
|
||||
namespace impl
|
||||
{
|
||||
template TOML_API void print_floating_point_to_stream(float, std::ostream&, bool);
|
||||
template TOML_API void print_floating_point_to_stream(double, std::ostream&, bool);
|
||||
}
|
||||
// node::value, node_view:::value etc
|
||||
#define TOML_INSTANTIATE(name, T) \
|
||||
template TOML_API optional<T> node::name<T>() const noexcept; \
|
||||
template TOML_API optional<T> node_view<node>::name<T>() const noexcept; \
|
||||
template TOML_API optional<T> node_view<const node>::name<T>() const noexcept
|
||||
TOML_INSTANTIATE(value_exact, std::string_view);
|
||||
TOML_INSTANTIATE(value_exact, std::string);
|
||||
TOML_INSTANTIATE(value_exact, const char*);
|
||||
TOML_INSTANTIATE(value_exact, int64_t);
|
||||
TOML_INSTANTIATE(value_exact, double);
|
||||
TOML_INSTANTIATE(value_exact, date);
|
||||
TOML_INSTANTIATE(value_exact, time);
|
||||
TOML_INSTANTIATE(value_exact, date_time);
|
||||
TOML_INSTANTIATE(value_exact, bool);
|
||||
TOML_INSTANTIATE(value, std::string_view);
|
||||
TOML_INSTANTIATE(value, std::string);
|
||||
TOML_INSTANTIATE(value, const char*);
|
||||
TOML_INSTANTIATE(value, signed char);
|
||||
TOML_INSTANTIATE(value, signed short);
|
||||
TOML_INSTANTIATE(value, signed int);
|
||||
TOML_INSTANTIATE(value, signed long);
|
||||
TOML_INSTANTIATE(value, signed long long);
|
||||
TOML_INSTANTIATE(value, unsigned char);
|
||||
TOML_INSTANTIATE(value, unsigned short);
|
||||
TOML_INSTANTIATE(value, unsigned int);
|
||||
TOML_INSTANTIATE(value, unsigned long);
|
||||
TOML_INSTANTIATE(value, unsigned long long);
|
||||
TOML_INSTANTIATE(value, double);
|
||||
TOML_INSTANTIATE(value, float);
|
||||
TOML_INSTANTIATE(value, date);
|
||||
TOML_INSTANTIATE(value, time);
|
||||
TOML_INSTANTIATE(value, date_time);
|
||||
TOML_INSTANTIATE(value, bool);
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_INSTANTIATE(value_exact, std::u8string_view);
|
||||
TOML_INSTANTIATE(value_exact, std::u8string);
|
||||
TOML_INSTANTIATE(value_exact, const char8_t*);
|
||||
TOML_INSTANTIATE(value, std::u8string_view);
|
||||
TOML_INSTANTIATE(value, std::u8string);
|
||||
TOML_INSTANTIATE(value, const char8_t*);
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_INSTANTIATE(value_exact, std::wstring);
|
||||
TOML_INSTANTIATE(value, std::wstring);
|
||||
#endif
|
||||
#undef TOML_INSTANTIATE
|
||||
|
||||
// parser machinery
|
||||
// parser instantiations
|
||||
#if TOML_PARSER
|
||||
|
||||
// parse error ostream
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
|
||||
// parse() and parse_file()
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(parse_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(parse_noex)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex)
|
||||
|
||||
template TOML_API parse_result parse(std::istream&, std::string_view) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse(std::istream&, std::string&&) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse_file(std::string_view) TOML_MAY_THROW;
|
||||
#ifdef __cpp_lib_char8_t
|
||||
template TOML_API parse_result parse_file(std::u8string_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
template TOML_API parse_result parse_file(std::wstring_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
|
||||
#endif // TOML_PARSER
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
|
|
@ -8,15 +8,9 @@
|
|||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
template <typename T, typename U>
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>&, json_formatter<U>&);
|
||||
template <typename T, typename U>
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>&, json_formatter<U>&&);
|
||||
|
||||
/// \brief A wrapper for printing TOML objects out to a stream as formatted JSON.
|
||||
///
|
||||
/// \detail \cpp
|
||||
|
@ -28,7 +22,7 @@ namespace toml
|
|||
/// [fruit.apple.texture]
|
||||
/// smooth = true
|
||||
/// )"sv);
|
||||
/// std::cout << toml::json_formatter{ some_toml } << std::endl;
|
||||
/// std::cout << toml::json_formatter{ some_toml } << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -96,21 +90,32 @@ namespace toml
|
|||
{
|
||||
switch (auto source_type = base::source().type())
|
||||
{
|
||||
case node_type::table: print(*reinterpret_cast<const table*>(&base::source())); break;
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&base::source())); break;
|
||||
default: base::print_value(base::source(), source_type);
|
||||
case node_type::table:
|
||||
print(*reinterpret_cast<const table*>(&base::source()));
|
||||
base::print_newline();
|
||||
break;
|
||||
|
||||
case node_type::array:
|
||||
print(*reinterpret_cast<const array*>(&base::source()));
|
||||
break;
|
||||
|
||||
default:
|
||||
base::print_value(base::source(), source_type);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief The default flags for a json_formatter.
|
||||
static constexpr format_flags default_flags = format_flags::quote_dates_and_times;
|
||||
|
||||
/// \brief Constructs a JSON formatter and binds it to a TOML object.
|
||||
///
|
||||
/// \param source The source TOML object.
|
||||
/// \param flags Format option flags.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit json_formatter(const toml::node& source, format_flags flags = {}) noexcept
|
||||
: base{ source, flags | format_flags::quote_dates_and_times }
|
||||
explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
|
||||
: base{ source, flags }
|
||||
{}
|
||||
|
||||
template <typename T, typename U>
|
||||
|
@ -119,7 +124,7 @@ namespace toml
|
|||
friend std::basic_ostream<T>& operator << (std::basic_ostream<T>&, json_formatter<U>&&);
|
||||
};
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template class TOML_API json_formatter<char>;
|
||||
#endif
|
||||
|
||||
|
@ -129,8 +134,7 @@ namespace toml
|
|||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON.
|
||||
template <typename T, typename U>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>& rhs)
|
||||
inline std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
rhs.print();
|
||||
|
@ -140,16 +144,16 @@ namespace toml
|
|||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON (rvalue overload).
|
||||
template <typename T, typename U>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>&& rhs)
|
||||
inline std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>&& rhs)
|
||||
{
|
||||
return lhs << rhs; //as lvalue
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, json_formatter<char>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, json_formatter<char>&&);
|
||||
#endif
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS, TOML_DISABLE_PADDING_WARNINGS
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
|
|
@ -16,11 +16,10 @@
|
|||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void json_formatter<Char>::print(const toml::table& tbl)
|
||||
inline void json_formatter<Char>::print(const toml::table& tbl)
|
||||
{
|
||||
if (tbl.empty())
|
||||
impl::print_to_stream("{}"sv, base::stream());
|
||||
|
@ -37,7 +36,7 @@ namespace toml
|
|||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
|
||||
base::print_quoted_string(k);
|
||||
base::print_quoted_string(k, false);
|
||||
impl::print_to_stream(" : "sv, base::stream());
|
||||
|
||||
const auto type = v.type();
|
||||
|
@ -59,5 +58,6 @@ namespace toml
|
|||
base::clear_naked_newline();
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
|
|
@ -6,10 +6,56 @@
|
|||
#pragma once
|
||||
#include "toml_common.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_VTABLE_WARNINGS
|
||||
#if defined(DOXYGEN) || TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
|
||||
namespace toml
|
||||
#define TOML_SA_NEWLINE " "
|
||||
#define TOML_SA_LIST_SEP ", "
|
||||
#define TOML_SA_LIST_BEG " ("
|
||||
#define TOML_SA_LIST_END ")"
|
||||
#define TOML_SA_LIST_NEW " "
|
||||
#define TOML_SA_LIST_NXT ", "
|
||||
|
||||
#else
|
||||
|
||||
#define TOML_SA_NEWLINE "\n| "
|
||||
#define TOML_SA_LIST_SEP TOML_SA_NEWLINE " - "
|
||||
#define TOML_SA_LIST_BEG TOML_SA_LIST_SEP
|
||||
#define TOML_SA_LIST_END
|
||||
#define TOML_SA_LIST_NEW TOML_SA_NEWLINE TOML_SA_NEWLINE
|
||||
#define TOML_SA_LIST_NXT TOML_SA_LIST_NEW
|
||||
|
||||
#endif
|
||||
|
||||
#define TOML_SA_NATIVE_VALUE_TYPE_LIST \
|
||||
TOML_SA_LIST_BEG "std::string" \
|
||||
TOML_SA_LIST_SEP "int64_t" \
|
||||
TOML_SA_LIST_SEP "double" \
|
||||
TOML_SA_LIST_SEP "bool" \
|
||||
TOML_SA_LIST_SEP "toml::date" \
|
||||
TOML_SA_LIST_SEP "toml::time" \
|
||||
TOML_SA_LIST_SEP "toml::date_time" \
|
||||
TOML_SA_LIST_END
|
||||
|
||||
#define TOML_SA_NODE_TYPE_LIST \
|
||||
TOML_SA_LIST_BEG "toml::table" \
|
||||
TOML_SA_LIST_SEP "toml::array" \
|
||||
TOML_SA_LIST_SEP "toml::value<std::string>" \
|
||||
TOML_SA_LIST_SEP "toml::value<int64_t>" \
|
||||
TOML_SA_LIST_SEP "toml::value<double>" \
|
||||
TOML_SA_LIST_SEP "toml::value<bool>" \
|
||||
TOML_SA_LIST_SEP "toml::value<toml::date>" \
|
||||
TOML_SA_LIST_SEP "toml::value<toml::time>" \
|
||||
TOML_SA_LIST_SEP "toml::value<toml::date_time>" \
|
||||
TOML_SA_LIST_END
|
||||
|
||||
#define TOML_SA_UNWRAPPED_NODE_TYPE_LIST \
|
||||
TOML_SA_LIST_NEW "A native TOML value type" \
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST \
|
||||
\
|
||||
TOML_SA_LIST_NXT "A TOML node type" \
|
||||
TOML_SA_NODE_TYPE_LIST
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief A TOML node.
|
||||
///
|
||||
|
@ -23,37 +69,39 @@ namespace toml
|
|||
|
||||
protected:
|
||||
|
||||
node(node&& other) noexcept;
|
||||
node& operator= (node&& rhs) noexcept;
|
||||
node() noexcept = default;
|
||||
node(const node&) noexcept;
|
||||
node(node&&) noexcept;
|
||||
node& operator= (const node&) noexcept;
|
||||
node& operator= (node&&) noexcept;
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
impl::node_of<T>& ref_cast() & noexcept
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
impl::wrap_node<T>& ref_cast() & noexcept
|
||||
{
|
||||
return *reinterpret_cast<impl::node_of<T>*>(this);
|
||||
return *reinterpret_cast<impl::wrap_node<T>*>(this);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
impl::node_of<T>&& ref_cast() && noexcept
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
impl::wrap_node<T>&& ref_cast() && noexcept
|
||||
{
|
||||
return std::move(*reinterpret_cast<impl::node_of<T>*>(this));
|
||||
return std::move(*reinterpret_cast<impl::wrap_node<T>*>(this));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
const impl::node_of<T>& ref_cast() const & noexcept
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
const impl::wrap_node<T>& ref_cast() const & noexcept
|
||||
{
|
||||
return *reinterpret_cast<const impl::node_of<T>*>(this);
|
||||
return *reinterpret_cast<const impl::wrap_node<T>*>(this);
|
||||
}
|
||||
|
||||
template <typename N, typename T>
|
||||
using ref_cast_type = decltype(std::declval<N>().template ref_cast<T>());
|
||||
|
||||
node() noexcept = default;
|
||||
node(const node&) = delete;
|
||||
node& operator= (const node&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~node() noexcept = default;
|
||||
|
@ -93,18 +141,19 @@ namespace toml
|
|||
///
|
||||
/// \returns Returns true if this node is an instance of the specified type.
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
bool is() const noexcept
|
||||
{
|
||||
using type = impl::unwrapped<impl::remove_cvref_t<T>>;
|
||||
using type = impl::unwrap_node<T>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Template type parameter must be one of the TOML value types, a toml::table, or a toml::array"
|
||||
(impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>,
|
||||
"The template type argument of node::is() must be one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
if constexpr (std::is_same_v<type, table>) return is_table();
|
||||
else if constexpr (std::is_same_v<type, array>) return is_array();
|
||||
else if constexpr (std::is_same_v<type, string>) return is_string();
|
||||
else if constexpr (std::is_same_v<type, std::string>) return is_string();
|
||||
else if constexpr (std::is_same_v<type, int64_t>) return is_integer();
|
||||
else if constexpr (std::is_same_v<type, double>) return is_floating_point();
|
||||
else if constexpr (std::is_same_v<type, bool>) return is_boolean();
|
||||
|
@ -118,7 +167,7 @@ namespace toml
|
|||
/// \brief Returns a pointer to the node as a toml::array, if it is one.
|
||||
[[nodiscard]] virtual array* as_array() noexcept;
|
||||
/// \brief Returns a pointer to the node as a toml::value<string>, if it is one.
|
||||
[[nodiscard]] virtual toml::value<string>* as_string() noexcept;
|
||||
[[nodiscard]] virtual toml::value<std::string>* as_string() noexcept;
|
||||
/// \brief Returns a pointer to the node as a toml::value<int64_t>, if it is one.
|
||||
[[nodiscard]] virtual toml::value<int64_t>* as_integer() noexcept;
|
||||
/// \brief Returns a pointer to the node as a toml::value<double>, if it is one.
|
||||
|
@ -134,7 +183,7 @@ namespace toml
|
|||
|
||||
[[nodiscard]] virtual const table* as_table() const noexcept;
|
||||
[[nodiscard]] virtual const array* as_array() const noexcept;
|
||||
[[nodiscard]] virtual const toml::value<string>* as_string() const noexcept;
|
||||
[[nodiscard]] virtual const toml::value<std::string>* as_string() const noexcept;
|
||||
[[nodiscard]] virtual const toml::value<int64_t>* as_integer() const noexcept;
|
||||
[[nodiscard]] virtual const toml::value<double>* as_floating_point() const noexcept;
|
||||
[[nodiscard]] virtual const toml::value<bool>* as_boolean() const noexcept;
|
||||
|
@ -142,67 +191,292 @@ namespace toml
|
|||
[[nodiscard]] virtual const toml::value<time>* as_time() const noexcept;
|
||||
[[nodiscard]] virtual const toml::value<date_time>* as_date_time() const noexcept;
|
||||
|
||||
/// \brief Gets the raw value contained by this node.
|
||||
/// \brief Checks if a node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail The optional returned by this function will only contain a value if the node was an instance of
|
||||
/// toml::value with the same value type as the template argument. Additionally, some type are allowed to
|
||||
/// convert to each other, for instance asking for an integer when the value exists as a double,
|
||||
/// or requesting a string value as a string_view: \cpp
|
||||
/// auto tbl = toml::parse(R"(
|
||||
/// int_val = 10
|
||||
/// float_val = 25.6
|
||||
/// string_val = "kek"
|
||||
/// )"sv);
|
||||
/// \detail \cpp
|
||||
/// auto cfg = toml::parse("arr = [ 1, 2, 3, 4.0 ]");
|
||||
/// toml::array& arr = *cfg["arr"].as_array();
|
||||
///
|
||||
/// if (auto val = tbl.get("int_val"sv)->value<int64_t>())
|
||||
/// std::cout << "'int_val' as int64_t: "sv << *val << std::endl;
|
||||
///
|
||||
/// if (auto val = tbl.get("int_val"sv)->value<double>())
|
||||
/// std::cout << "'int_val' as double: "sv << *val << std::endl;
|
||||
///
|
||||
/// if (auto val = tbl.get("float_val"sv)->value<int64_t>())
|
||||
/// std::cout << "'float_val' as int64_t: "sv << *val << std::endl;
|
||||
///
|
||||
/// if (auto val = tbl.get("float_val"sv)->value<double>())
|
||||
/// std::cout << "'float_val' as double: "sv << *val << std::endl;
|
||||
///
|
||||
/// if (auto val = tbl.get("string_val"sv)->value<std::string>())
|
||||
/// std::cout << "'string_val' as std::string: "sv << *val << std::endl;
|
||||
///
|
||||
/// if (auto val = tbl.get("string_val"sv)->value<std::string_view>())
|
||||
/// std::cout << "'string_val' as std::string_view: "sv << *val << std::endl;
|
||||
///
|
||||
/// if (auto val = tbl.get("string_val"sv)->value<int64_t>())
|
||||
/// std::cout << "this line won't be printed because string_val wasn't an int."sv << std::endl;
|
||||
/// toml::node* nonmatch{};
|
||||
/// if (arr.is_homogeneous(toml::node_type::integer, nonmatch))
|
||||
/// std::cout << "array was homogeneous"sv << "\n";
|
||||
/// else
|
||||
/// std::cout << "array was not homogeneous!\n"
|
||||
/// << "first non-match was a "sv << nonmatch->type() << " at " << nonmatch->source() << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 'int_val' as int64_t: 10
|
||||
/// 'int_val' as double: 10
|
||||
/// 'float_val' as int64_t: 25
|
||||
/// 'float_val' as double: 25.6
|
||||
/// 'string_val' as std::string: kek
|
||||
/// 'string_val' as std::string_view: kek
|
||||
/// array was not homogeneous!
|
||||
/// first non-match was a floating-point at line 1, column 18
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam T One of the TOML value types. Can also be a string_view.
|
||||
/// \param ntype A TOML node type. <br>
|
||||
/// <strong><em>toml::node_type::none: </em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Anything else:</em></strong> "is every element one of these?"
|
||||
/// \param first_nonmatch Reference to a pointer in which the address of the first non-matching element
|
||||
/// will be stored if the return value is false.
|
||||
///
|
||||
/// \returns The underlying value if the node was a value of the matching type (or convertible to it), or an empty optional.
|
||||
template <typename T>
|
||||
[[nodiscard]] optional<T> value() const noexcept;
|
||||
/// \returns True if the node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` for empty tables and arrays.
|
||||
[[nodiscard]] virtual bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept = 0;
|
||||
|
||||
/// \brief Gets the raw value contained by this node, or a default.
|
||||
/// \brief Checks if a node contains values/elements of only one type (const overload).
|
||||
[[nodiscard]] virtual bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept = 0;
|
||||
|
||||
/// \brief Checks if the node contains values/elements of only one type.
|
||||
///
|
||||
/// \tparam T Default value type. Must be (or be promotable to) one of the TOML value types.
|
||||
/// \param default_value The default value to return if the node wasn't a value, wasn't the
|
||||
/// correct type, or no conversion was possible.
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{ 1, 2, 3 };
|
||||
/// std::cout << "homogenous: "sv << arr.is_homogeneous(toml::node_type::none) << "\n";
|
||||
/// std::cout << "all floats: "sv << arr.is_homogeneous(toml::node_type::floating_point) << "\n";
|
||||
/// std::cout << "all arrays: "sv << arr.is_homogeneous(toml::node_type::array) << "\n";
|
||||
/// std::cout << "all ints: "sv << arr.is_homogeneous(toml::node_type::integer) << "\n";
|
||||
///
|
||||
/// \returns The node's underlying value, or the default if the node wasn't a value, wasn't the
|
||||
/// correct type, or no conversion was possible.
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all floats: false
|
||||
/// all arrays: false
|
||||
/// all ints: true
|
||||
/// \eout
|
||||
///
|
||||
/// \param ntype A TOML node type. <br>
|
||||
/// <strong><em>toml::node_type::none: </em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Anything else:</em></strong> "is every element one of these?"
|
||||
///
|
||||
/// \returns True if the node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` for empty tables and arrays.
|
||||
[[nodiscard]] virtual bool is_homogeneous(node_type ntype) const noexcept = 0;
|
||||
|
||||
/// \brief Checks if the node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{ 1, 2, 3 };
|
||||
/// std::cout << "homogenous: "sv << arr.is_homogeneous() << "\n";
|
||||
/// std::cout << "all doubles: "sv << arr.is_homogeneous<double>() << "\n";
|
||||
/// std::cout << "all arrays: "sv << arr.is_homogeneous<toml::array>() << "\n";
|
||||
/// std::cout << "all integers: "sv << arr.is_homogeneous<int64_t>() << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all floats: false
|
||||
/// all arrays: false
|
||||
/// all ints: true
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType A TOML node or value type. <br>
|
||||
/// <strong><em>Left as `void`:</em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Explicitly specified:</em></strong> "is every element a T?"
|
||||
///
|
||||
/// \returns True if the node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` for empty tables and arrays.
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
static_assert(
|
||||
std::is_void_v<type>
|
||||
|| ((impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>),
|
||||
"The template type argument of node::is_homogeneous() must be void or one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
decltype(auto) get_value_exact() const noexcept;
|
||||
|
||||
#endif // !DOXYGEN
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Gets the value contained by this node.
|
||||
///
|
||||
/// \detail This function has 'exact' retrieval semantics; the only return value types allowed are the
|
||||
/// TOML native value types, or types that can losslessly represent a native value type (e.g.
|
||||
/// std::wstring on Windows).
|
||||
///
|
||||
/// \tparam T One of the native TOML value types, or a type capable of losslessly representing one.
|
||||
///
|
||||
/// \returns The underlying value if the node was a value of the
|
||||
/// matching type (or losslessly convertible to it), or an empty optional.
|
||||
///
|
||||
/// \see node::value()
|
||||
template <typename T>
|
||||
[[nodiscard]] auto value_or(T&& default_value) const noexcept;
|
||||
[[nodiscard]]
|
||||
optional<T> value_exact() const noexcept;
|
||||
|
||||
/// \brief Gets the value contained by this node.
|
||||
///
|
||||
/// \detail This function has 'permissive' retrieval semantics; some value types are allowed
|
||||
/// to convert to others (e.g. retrieving a boolean as an integer), and the specified return value
|
||||
/// type can be any type where a reasonable conversion from a native TOML value exists
|
||||
/// (e.g. std::wstring on Windows). If the source value cannot be represented by
|
||||
/// the destination type, an empty optional is returned.
|
||||
///
|
||||
/// \godbolt{zzG81K}
|
||||
///
|
||||
/// \cpp
|
||||
/// auto tbl = toml::parse(R"(
|
||||
/// int = -10
|
||||
/// flt = 25.0
|
||||
/// pi = 3.14159
|
||||
/// bool = false
|
||||
/// huge = 9223372036854775807
|
||||
/// str = "foo"
|
||||
/// )"sv);
|
||||
///
|
||||
/// const auto print_value_with_typename =
|
||||
/// [&](std::string_view key, std::string_view type_name, auto* dummy)
|
||||
/// {
|
||||
/// std::cout << "- " << std::setw(18) << std::left << type_name;
|
||||
/// using type = std::remove_pointer_t<decltype(dummy)>;
|
||||
/// if (std::optional<type> val = tbl.get(key)->value<type>())
|
||||
/// std::cout << *val << "\n";
|
||||
/// else
|
||||
/// std::cout << "n/a\n";
|
||||
/// };
|
||||
///
|
||||
/// #define print_value(key, T) print_value_with_typename(key, #T, (T*)nullptr)
|
||||
///
|
||||
/// for (auto key : { "int", "flt", "pi", "bool", "huge", "str" })
|
||||
/// {
|
||||
/// std::cout << tbl[key].type() << " value '" << key << "' as:\n";
|
||||
/// print_value(key, bool);
|
||||
/// print_value(key, int);
|
||||
/// print_value(key, unsigned int);
|
||||
/// print_value(key, long long);
|
||||
/// print_value(key, float);
|
||||
/// print_value(key, double);
|
||||
/// print_value(key, std::string);
|
||||
/// print_value(key, std::string_view);
|
||||
/// print_value(key, const char*);
|
||||
/// std::cout << "\n";
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// integer value 'int' as:
|
||||
/// - bool true
|
||||
/// - int -10
|
||||
/// - unsigned int n/a
|
||||
/// - long long -10
|
||||
/// - float -10
|
||||
/// - double -10
|
||||
/// - std::string n/a
|
||||
/// - std::string_view n/a
|
||||
/// - const char* n/a
|
||||
///
|
||||
/// floating-point value 'flt' as:
|
||||
/// - bool n/a
|
||||
/// - int 25
|
||||
/// - unsigned int 25
|
||||
/// - long long 25
|
||||
/// - float 25
|
||||
/// - double 25
|
||||
/// - std::string n/a
|
||||
/// - std::string_view n/a
|
||||
/// - const char* n/a
|
||||
///
|
||||
/// floating-point value 'pi' as:
|
||||
/// - bool n/a
|
||||
/// - int n/a
|
||||
/// - unsigned int n/a
|
||||
/// - long long n/a
|
||||
/// - float 3.14159
|
||||
/// - double 3.14159
|
||||
/// - std::string n/a
|
||||
/// - std::string_view n/a
|
||||
/// - const char* n/a
|
||||
///
|
||||
/// boolean value 'bool' as:
|
||||
/// - bool false
|
||||
/// - int 0
|
||||
/// - unsigned int 0
|
||||
/// - long long 0
|
||||
/// - float n/a
|
||||
/// - double n/a
|
||||
/// - std::string n/a
|
||||
/// - std::string_view n/a
|
||||
/// - const char* n/a
|
||||
///
|
||||
/// integer value 'huge' as:
|
||||
/// - bool true
|
||||
/// - int n/a
|
||||
/// - unsigned int n/a
|
||||
/// - long long 9223372036854775807
|
||||
/// - float n/a
|
||||
/// - double n/a
|
||||
/// - std::string n/a
|
||||
/// - std::string_view n/a
|
||||
/// - const char* n/a
|
||||
///
|
||||
/// string value 'str' as:
|
||||
/// - bool n/a
|
||||
/// - int n/a
|
||||
/// - unsigned int n/a
|
||||
/// - long long n/a
|
||||
/// - float n/a
|
||||
/// - double n/a
|
||||
/// - std::string foo
|
||||
/// - std::string_view foo
|
||||
/// - const char* foo
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam T One of the native TOML value types, or a type capable of converting to one.
|
||||
///
|
||||
/// \returns The underlying value if the node was a value of the matching type (or convertible to it)
|
||||
/// and within the range of the output type, or an empty optional.
|
||||
///
|
||||
/// \attention If you want strict value retrieval semantics that do not allow for any type conversions,
|
||||
/// use node::value_exact() instead.
|
||||
///
|
||||
/// \see node::value_exact()
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
optional<T> value() const noexcept;
|
||||
|
||||
/// \brief Gets the raw value contained by this node, or a default.
|
||||
///
|
||||
/// \tparam T Default value type. Must be one of the native TOML value types,
|
||||
/// or convertible to it.
|
||||
/// \param default_value The default value to return if the node wasn't a value, wasn't the
|
||||
/// correct type, or no conversion was possible.
|
||||
///
|
||||
/// \returns The underlying value if the node was a value of the matching type (or convertible to it)
|
||||
/// and within the range of the output type, or the provided default.
|
||||
///
|
||||
/// \attention This function has the same permissive retrieval semantics as node::value(). If you want strict
|
||||
/// value retrieval semantics that do not allow for any type conversions, use node::value_exact()
|
||||
/// instead.
|
||||
///
|
||||
/// \see
|
||||
/// - node::value()
|
||||
/// - node::value_exact()
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto value_or(T&& default_value) const noexcept;
|
||||
|
||||
//template <typename T>
|
||||
//[[nodiscard]]
|
||||
//std::vector<T> select_exact() const noexcept;
|
||||
|
||||
//template <typename T>
|
||||
//[[nodiscard]]
|
||||
//std::vector<T> select() const noexcept;
|
||||
|
||||
/// \brief Gets a pointer to the node as a more specific node type.
|
||||
///
|
||||
|
@ -211,14 +485,14 @@ namespace toml
|
|||
/// toml::value<int64_t>* int_value = node->as<int64_t>();
|
||||
/// toml::table* tbl = node->as<toml::table>();
|
||||
/// if (int_value)
|
||||
/// std::cout << "Node is a value<int64_t>" << std::endl;
|
||||
/// std::cout << "Node is a value<int64_t>\n";
|
||||
/// else if (tbl)
|
||||
/// std::cout << "Node is a table" << std::endl;
|
||||
/// std::cout << "Node is a table\n";
|
||||
///
|
||||
/// // fully-qualified value node types also work (useful for template code):
|
||||
/// toml::value<int64_t>* int_value2 = node->as<toml::value<int64_t>>();
|
||||
/// if (int_value2)
|
||||
/// std::cout << "Node is a value<int64_t>" << std::endl;
|
||||
/// std::cout << "Node is a value<int64_t>\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -226,18 +500,19 @@ namespace toml
|
|||
///
|
||||
/// \returns A pointer to the node as the given type, or nullptr if it was a different type.
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
impl::node_of<T>* as() noexcept
|
||||
[[nodiscard]]
|
||||
impl::wrap_node<T>* as() noexcept
|
||||
{
|
||||
using type = impl::unwrapped<T>;
|
||||
using type = impl::unwrap_node<T>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Template type parameter must be one of the TOML value types, a toml::table, or a toml::array"
|
||||
(impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>,
|
||||
"The template type argument of node::as() must be one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
if constexpr (std::is_same_v<type, table>) return as_table();
|
||||
else if constexpr (std::is_same_v<type, array>) return as_array();
|
||||
else if constexpr (std::is_same_v<type, string>) return as_string();
|
||||
else if constexpr (std::is_same_v<type, std::string>) return as_string();
|
||||
else if constexpr (std::is_same_v<type, int64_t>) return as_integer();
|
||||
else if constexpr (std::is_same_v<type, double>) return as_floating_point();
|
||||
else if constexpr (std::is_same_v<type, bool>) return as_boolean();
|
||||
|
@ -248,18 +523,19 @@ namespace toml
|
|||
|
||||
/// \brief Gets a pointer to the node as a more specific node type (const overload).
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
const impl::node_of<T>* as() const noexcept
|
||||
[[nodiscard]]
|
||||
const impl::wrap_node<T>* as() const noexcept
|
||||
{
|
||||
using type = impl::unwrapped<T>;
|
||||
using type = impl::unwrap_node<T>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Template type parameter must be one of the TOML value types, a toml::table, or a toml::array"
|
||||
(impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>,
|
||||
"The template type argument of node::as() must be one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
if constexpr (std::is_same_v<type, table>) return as_table();
|
||||
else if constexpr (std::is_same_v<type, array>) return as_array();
|
||||
else if constexpr (std::is_same_v<type, string>) return as_string();
|
||||
else if constexpr (std::is_same_v<type, std::string>) return as_string();
|
||||
else if constexpr (std::is_same_v<type, int64_t>) return as_integer();
|
||||
else if constexpr (std::is_same_v<type, double>) return as_floating_point();
|
||||
else if constexpr (std::is_same_v<type, bool>) return as_boolean();
|
||||
|
@ -280,7 +556,7 @@ namespace toml
|
|||
static constexpr bool can_visit_any =
|
||||
can_visit<Func, N, table>
|
||||
|| can_visit<Func, N, array>
|
||||
|| can_visit<Func, N, string>
|
||||
|| can_visit<Func, N, std::string>
|
||||
|| can_visit<Func, N, int64_t>
|
||||
|| can_visit<Func, N, double>
|
||||
|| can_visit<Func, N, bool>
|
||||
|
@ -292,7 +568,7 @@ namespace toml
|
|||
static constexpr bool can_visit_all =
|
||||
can_visit<Func, N, table>
|
||||
&& can_visit<Func, N, array>
|
||||
&& can_visit<Func, N, string>
|
||||
&& can_visit<Func, N, std::string>
|
||||
&& can_visit<Func, N, int64_t>
|
||||
&& can_visit<Func, N, double>
|
||||
&& can_visit<Func, N, bool>
|
||||
|
@ -309,7 +585,7 @@ namespace toml
|
|||
static constexpr bool visit_is_nothrow =
|
||||
visit_is_nothrow_one<Func, N, table>
|
||||
&& visit_is_nothrow_one<Func, N, array>
|
||||
&& visit_is_nothrow_one<Func, N, string>
|
||||
&& visit_is_nothrow_one<Func, N, std::string>
|
||||
&& visit_is_nothrow_one<Func, N, int64_t>
|
||||
&& visit_is_nothrow_one<Func, N, double>
|
||||
&& visit_is_nothrow_one<Func, N, bool>
|
||||
|
@ -341,7 +617,8 @@ namespace toml
|
|||
{
|
||||
static_assert(
|
||||
can_visit_any<Func&&, N&&>,
|
||||
"Visitors must be invocable for at least one of the toml::node specializations"
|
||||
"TOML node visitors must be invocable for at least one of the toml::node specializations:"
|
||||
TOML_SA_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
switch (n.type())
|
||||
|
@ -357,8 +634,8 @@ namespace toml
|
|||
break;
|
||||
|
||||
case node_type::string:
|
||||
if constexpr (can_visit<Func&&, N&&, string>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<string>());
|
||||
if constexpr (can_visit<Func&&, N&&, std::string>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<std::string>());
|
||||
break;
|
||||
|
||||
case node_type::integer:
|
||||
|
@ -402,7 +679,7 @@ namespace toml
|
|||
using return_type =
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, table>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, array>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, string>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, std::string>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, int64_t>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, double>::type,
|
||||
nonvoid<typename visit_return_type<Func&&, N&&, bool>::type,
|
||||
|
@ -424,18 +701,20 @@ namespace toml
|
|||
|
||||
|
||||
template <typename T, typename N>
|
||||
[[nodiscard]] static decltype(auto) do_ref(N&& n) noexcept
|
||||
[[nodiscard]]
|
||||
static decltype(auto) do_ref(N&& n) noexcept
|
||||
{
|
||||
using type = impl::unwrapped<T>;
|
||||
using type = impl::unwrap_node<T>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Template type parameter must be one of the TOML value types, a toml::table, or a toml::array"
|
||||
(impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>,
|
||||
"The template type argument of node::ref() must be one of:"
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
TOML_ASSERT(
|
||||
n.template is<T>()
|
||||
&& "template type argument T provided to toml::node::ref() didn't match the node's actual type"
|
||||
);
|
||||
if constexpr (impl::is_value<type>)
|
||||
if constexpr (impl::is_native<type>)
|
||||
return std::forward<N>(n).template ref_cast<type>().get();
|
||||
else
|
||||
return std::forward<N>(n).template ref_cast<type>();
|
||||
|
@ -453,7 +732,7 @@ namespace toml
|
|||
/// node.visit([](auto&& n)
|
||||
/// {
|
||||
/// if constexpr (toml::is_string<decltype(n)>)
|
||||
/// do_something_with_a_string(*n)); //n is a toml::value<toml::string>
|
||||
/// do_something_with_a_string(*n)); //n is a toml::value<std::string>
|
||||
/// else if constexpr (toml::is_integer<decltype(n)>)
|
||||
/// do_something_with_an_int(*n); //n is a toml::value<int64_t>
|
||||
/// else
|
||||
|
@ -472,21 +751,24 @@ namespace toml
|
|||
///
|
||||
/// \see https://en.wikipedia.org/wiki/Visitor_pattern
|
||||
template <typename Func>
|
||||
decltype(auto) visit(Func&& visitor) & noexcept(visit_is_nothrow<Func&&, node&>)
|
||||
decltype(auto) visit(Func&& visitor) &
|
||||
noexcept(visit_is_nothrow<Func&&, node&>)
|
||||
{
|
||||
return do_visit(*this, std::forward<Func>(visitor));
|
||||
}
|
||||
|
||||
/// \brief Invokes a visitor on the node based on the node's concrete type (rvalue overload).
|
||||
template <typename Func>
|
||||
decltype(auto) visit(Func&& visitor) && noexcept(visit_is_nothrow<Func&&, node&&>)
|
||||
decltype(auto) visit(Func&& visitor) &&
|
||||
noexcept(visit_is_nothrow<Func&&, node&&>)
|
||||
{
|
||||
return do_visit(std::move(*this), std::forward<Func>(visitor));
|
||||
}
|
||||
|
||||
/// \brief Invokes a visitor on the node based on the node's concrete type (const lvalue overload).
|
||||
template <typename Func>
|
||||
decltype(auto) visit(Func&& visitor) const& noexcept(visit_is_nothrow<Func&&, const node&>)
|
||||
decltype(auto) visit(Func&& visitor) const&
|
||||
noexcept(visit_is_nothrow<Func&&, const node&>)
|
||||
{
|
||||
return do_visit(*this, std::forward<Func>(visitor));
|
||||
}
|
||||
|
@ -511,25 +793,33 @@ namespace toml
|
|||
///
|
||||
/// \returns A reference to the underlying data.
|
||||
template <typename T>
|
||||
[[nodiscard]] impl::unwrapped<T>& ref() & noexcept
|
||||
[[nodiscard]]
|
||||
impl::unwrap_node<T>& ref() & noexcept
|
||||
{
|
||||
return do_ref<T>(*this);
|
||||
}
|
||||
|
||||
/// \brief Gets a raw reference to a value node's underlying data (rvalue overload).
|
||||
template <typename T>
|
||||
[[nodiscard]] impl::unwrapped<T>&& ref() && noexcept
|
||||
[[nodiscard]]
|
||||
impl::unwrap_node<T>&& ref() && noexcept
|
||||
{
|
||||
return do_ref<T>(std::move(*this));
|
||||
}
|
||||
|
||||
/// \brief Gets a raw reference to a value node's underlying data (const lvalue overload).
|
||||
template <typename T>
|
||||
[[nodiscard]] const impl::unwrapped<T>& ref() const& noexcept
|
||||
[[nodiscard]]
|
||||
const impl::unwrap_node<T>& ref() const& noexcept
|
||||
{
|
||||
return do_ref<T>(*this);
|
||||
}
|
||||
|
||||
/// \brief Creates a `node_view` pointing to this node.
|
||||
[[nodiscard]] explicit operator node_view<node>() noexcept;
|
||||
|
||||
/// \brief Creates a `node_view` pointing to this node (const overload).
|
||||
[[nodiscard]] explicit operator node_view<const node>() const noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS //TOML_DISABLE_VTABLE_WARNINGS
|
||||
TOML_NAMESPACE_END
|
||||
|
|
|
@ -13,11 +13,16 @@
|
|||
|
||||
#include "toml_node.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SUGGEST_WARNINGS
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node::node(const node& /*other*/) noexcept
|
||||
{
|
||||
// does not copy source information - this is not an error
|
||||
//
|
||||
// see https://github.com/marzer/tomlplusplus/issues/49#issuecomment-665089577
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node::node(node && other) noexcept
|
||||
: source_{ std::move(other.source_) }
|
||||
|
@ -26,6 +31,17 @@ namespace toml
|
|||
other.source_.end = {};
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node& node::operator= (const node& /*rhs*/) noexcept
|
||||
{
|
||||
// does not copy source information - this is not an error
|
||||
//
|
||||
// see https://github.com/marzer/tomlplusplus/issues/49#issuecomment-665089577
|
||||
|
||||
source_ = {};
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node& node::operator= (node && rhs) noexcept
|
||||
{
|
||||
|
@ -49,7 +65,7 @@ namespace toml
|
|||
|
||||
TOML_MEMBER_ATTR(const) table* node::as_table() noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) array* node::as_array() noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) value<string>* node::as_string() noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) value<std::string>* node::as_string() noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) value<int64_t>* node::as_integer() noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) value<double>* node::as_floating_point() noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) value<bool>* node::as_boolean() noexcept { return nullptr; }
|
||||
|
@ -59,7 +75,7 @@ namespace toml
|
|||
|
||||
TOML_MEMBER_ATTR(const) const table* node::as_table() const noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) const array* node::as_array() const noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) const value<string>* node::as_string() const noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) const value<std::string>* node::as_string() const noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) const value<int64_t>* node::as_integer() const noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) const value<double>* node::as_floating_point() const noexcept { return nullptr; }
|
||||
TOML_MEMBER_ATTR(const) const value<bool>* node::as_boolean() const noexcept { return nullptr; }
|
||||
|
@ -70,6 +86,17 @@ namespace toml
|
|||
TOML_MEMBER_ATTR(const) const source_region& node::source() const noexcept { return source_; }
|
||||
|
||||
#undef TOML_MEMBER_ATTR
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node::operator node_view<node>() noexcept
|
||||
{
|
||||
return node_view<node>(this);
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SUGGEST_WARNINGS
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node::operator node_view<const node>() const noexcept
|
||||
{
|
||||
return node_view<const node>(this);
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
|
|
@ -8,19 +8,16 @@
|
|||
#include "toml_array.h"
|
||||
#include "toml_value.h"
|
||||
|
||||
namespace toml
|
||||
{
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_FLOAT_WARNINGS
|
||||
|
||||
template <typename Char, typename T>
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const node_view<T>&);
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief A view of a node.
|
||||
///
|
||||
/// \detail A node_view is like a std::optional<toml::node> with lots of toml-specific stuff built-in.
|
||||
/// It _may_ represent a node, and allows you to do many of the same operations that you'd do
|
||||
/// on nodes directly, as well as easily traversing the node tree by creating
|
||||
/// \detail A node_view is like a std::optional<toml::node&> (if such a construct were legal), with lots of
|
||||
/// toml-specific stuff built-in. It _may_ represent a node, and allows you to do many of the
|
||||
/// same operations that you'd do on nodes directly, as well as easily traversing the node tree by creating
|
||||
/// subviews (via node_view::operator[]). \cpp
|
||||
///
|
||||
/// auto tbl = toml::parse(R"(
|
||||
|
@ -39,15 +36,15 @@ namespace toml
|
|||
///
|
||||
/// )"sv);
|
||||
///
|
||||
/// std::cout << tbl["title"] << std::endl;
|
||||
/// std::cout << tbl["products"][0]["name"] << std::endl;
|
||||
/// std::cout << tbl["products"][0]["keywords"] << std::endl;
|
||||
/// std::cout << tbl["products"][0]["keywords"][2] << std::endl;
|
||||
/// std::cout << tbl["title"] << "\n";
|
||||
/// std::cout << tbl["products"][0]["name"] << "\n";
|
||||
/// std::cout << tbl["products"][0]["keywords"] << "\n";
|
||||
/// std::cout << tbl["products"][0]["keywords"][2] << "\n";
|
||||
///
|
||||
/// tbl["products"][0]["keywords"].as_array()->push_back("heavy");
|
||||
/// std::cout << tbl["products"][0]["keywords"] << std::endl;
|
||||
/// std::cout << "has product[2]: "sv << !!tbl["products"][2] << std::endl;
|
||||
/// std::cout << "product[2]: "sv << tbl["products"][2] << std::endl;
|
||||
/// std::cout << tbl["products"][0]["keywords"] << "\n";
|
||||
/// std::cout << "has product[2]: "sv << !!tbl["products"][2] << "\n";
|
||||
/// std::cout << "product[2]: "sv << tbl["products"][2] << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
|
@ -59,23 +56,22 @@ namespace toml
|
|||
/// has product[2]: false
|
||||
/// product[2]:
|
||||
/// \eout
|
||||
template <typename T>
|
||||
template <typename ViewedType>
|
||||
class TOML_API TOML_TRIVIAL_ABI node_view
|
||||
{
|
||||
static_assert(
|
||||
impl::is_one_of<ViewedType, toml::node, const toml::node>,
|
||||
"A toml::node_view<> must wrap toml::node or const toml::node."
|
||||
);
|
||||
|
||||
public:
|
||||
using viewed_type = T;
|
||||
using viewed_type = ViewedType;
|
||||
|
||||
private:
|
||||
friend class toml::table;
|
||||
template <typename U> friend class toml::node_view;
|
||||
template <typename T> friend class TOML_NAMESPACE::node_view;
|
||||
|
||||
mutable viewed_type* node_ = nullptr;
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
node_view(viewed_type* node) noexcept
|
||||
: node_{ node }
|
||||
{}
|
||||
|
||||
template <typename Func>
|
||||
static constexpr bool visit_is_nothrow
|
||||
= noexcept(std::declval<viewed_type*>()->visit(std::declval<Func&&>()));
|
||||
|
@ -86,10 +82,39 @@ namespace toml
|
|||
TOML_NODISCARD_CTOR
|
||||
node_view() noexcept = default;
|
||||
|
||||
/// \brief Constructs node_view of a specific node.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit node_view(viewed_type* node) noexcept
|
||||
: node_{ node }
|
||||
{}
|
||||
|
||||
/// \brief Constructs node_view of a specific node.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit node_view(viewed_type& node) noexcept
|
||||
: node_{ &node }
|
||||
{}
|
||||
|
||||
///// \brief Copy constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
node_view(const node_view&) noexcept = default;
|
||||
|
||||
///// \brief Copy-assignment operator.
|
||||
node_view& operator= (const node_view&) & noexcept = default;
|
||||
|
||||
///// \brief Move constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
node_view(node_view&&) noexcept = default;
|
||||
|
||||
///// \brief Move-assignment operator.
|
||||
node_view& operator= (node_view&&) & noexcept = default;
|
||||
|
||||
/// \brief Returns true if the view references a node.
|
||||
[[nodiscard]] explicit operator bool() const noexcept { return node_ != nullptr; }
|
||||
/// \brief Returns the node that's being referenced by the view.
|
||||
[[nodiscard]] viewed_type* get() const noexcept { return node_; }
|
||||
[[nodiscard]] viewed_type* node() const noexcept { return node_; }
|
||||
|
||||
[[nodiscard, deprecated("use node_view::node() instead")]]
|
||||
viewed_type* get() const noexcept { return node_; }
|
||||
|
||||
/// \brief Returns the type identifier for the viewed node.
|
||||
[[nodiscard]] node_type type() const noexcept { return node_ ? node_->type() : node_type::none; }
|
||||
|
@ -121,35 +146,30 @@ namespace toml
|
|||
|
||||
/// \brief Checks if this view references a node of a specific type.
|
||||
///
|
||||
/// \tparam U A TOML node or value type.
|
||||
/// \tparam T A TOML node or value type.
|
||||
///
|
||||
/// \returns Returns true if the viewed node is an instance of the specified type.
|
||||
///
|
||||
/// \see toml::node::is()
|
||||
template <typename U>
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
bool is() const noexcept
|
||||
{
|
||||
return node_ ? node_->template is<U>() : false;
|
||||
return node_ ? node_->template is<T>() : false;
|
||||
}
|
||||
|
||||
/// \brief Gets a pointer to the viewed node as a more specific node type.
|
||||
///
|
||||
/// \tparam U The node type or TOML value type to cast to.
|
||||
/// \tparam T The node type or TOML value type to cast to.
|
||||
///
|
||||
/// \returns A pointer to the node as the given type, or nullptr if it was a different type.
|
||||
///
|
||||
/// \see toml::node::as()
|
||||
template <typename U>
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto as() const noexcept
|
||||
{
|
||||
static_assert(
|
||||
impl::is_value_or_node<impl::unwrapped<U>>,
|
||||
"Template type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
);
|
||||
|
||||
return node_ ? node_->template as<U>() : nullptr;
|
||||
return node_ ? node_->template as<T>() : nullptr;
|
||||
}
|
||||
|
||||
/// \brief Returns a pointer to the viewed node as a toml::table, if it is one.
|
||||
|
@ -157,7 +177,7 @@ namespace toml
|
|||
/// \brief Returns a pointer to the viewed node as a toml::array, if it is one.
|
||||
[[nodiscard]] auto as_array() const noexcept { return as<array>(); }
|
||||
/// \brief Returns a pointer to the viewed node as a toml::value<string>, if it is one.
|
||||
[[nodiscard]] auto as_string() const noexcept { return as<string>(); }
|
||||
[[nodiscard]] auto as_string() const noexcept { return as<std::string>(); }
|
||||
/// \brief Returns a pointer to the viewed node as a toml::value<int64_t>, if it is one.
|
||||
[[nodiscard]] auto as_integer() const noexcept { return as<int64_t>(); }
|
||||
/// \brief Returns a pointer to the viewed node as a toml::value<double>, if it is one.
|
||||
|
@ -171,21 +191,159 @@ namespace toml
|
|||
/// \brief Returns a pointer to the viewed node as a toml::value<date_time>, if it is one.
|
||||
[[nodiscard]] auto as_date_time() const noexcept { return as<date_time>(); }
|
||||
|
||||
/// \brief Checks if the viewed node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto cfg = toml::parse("arr = [ 1, 2, 3, 4.0 ]");
|
||||
///
|
||||
/// toml::node* nonmatch{};
|
||||
/// if (cfg["arr"].is_homogeneous(toml::node_type::integer, nonmatch))
|
||||
/// std::cout << "array was homogeneous"sv << "\n";
|
||||
/// else
|
||||
/// std::cout << "array was not homogeneous!\n"
|
||||
/// << "first non-match was a "sv << nonmatch->type() << " at " << nonmatch->source() << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// array was not homogeneous!
|
||||
/// first non-match was a floating-point at line 1, column 18
|
||||
/// \eout
|
||||
///
|
||||
/// \param ntype A TOML node type. <br>
|
||||
/// <strong><em>toml::node_type::none: </em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Anything else:</em></strong> "is every element one of these?"
|
||||
/// \param first_nonmatch Reference to a pointer in which the address of the first non-matching element
|
||||
/// will be stored if the return value is false.
|
||||
///
|
||||
/// \returns True if the viewed node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
|
||||
/// an empty table or array.
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype, viewed_type*& first_nonmatch) const noexcept
|
||||
{
|
||||
if (!node_)
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
return node_->is_homogeneous(ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
/// \brief Checks if the viewed node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto cfg = toml::parse("arr = [ 1, 2, 3 ]");
|
||||
/// std::cout << "homogenous: "sv << cfg["arr"].is_homogeneous(toml::node_type::none) << "\n";
|
||||
/// std::cout << "all floats: "sv << cfg["arr"].is_homogeneous(toml::node_type::floating_point) << "\n";
|
||||
/// std::cout << "all arrays: "sv << cfg["arr"].is_homogeneous(toml::node_type::array) << "\n";
|
||||
/// std::cout << "all ints: "sv << cfg["arr"].is_homogeneous(toml::node_type::integer) << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all floats: false
|
||||
/// all arrays: false
|
||||
/// all ints: true
|
||||
/// \eout
|
||||
///
|
||||
/// \param ntype A TOML node type. <br>
|
||||
/// <strong><em>toml::node_type::none: </em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Anything else:</em></strong> "is every element one of these?"
|
||||
///
|
||||
/// \returns True if the viewed node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
|
||||
/// an empty table or array.
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
return node_ ? node_->is_homogeneous(ntype) : false;
|
||||
}
|
||||
|
||||
/// \brief Checks if the viewed node contains values/elements of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto cfg = toml::parse("arr = [ 1, 2, 3 ]");
|
||||
/// std::cout << "homogenous: "sv << cfg["arr"].is_homogeneous() << "\n";
|
||||
/// std::cout << "all doubles: "sv << cfg["arr"].is_homogeneous<double>() << "\n";
|
||||
/// std::cout << "all arrays: "sv << cfg["arr"].is_homogeneous<toml::array>() << "\n";
|
||||
/// std::cout << "all integers: "sv << cfg["arr"].is_homogeneous<int64_t>() << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// homogeneous: true
|
||||
/// all floats: false
|
||||
/// all arrays: false
|
||||
/// all ints: true
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType A TOML node or value type. <br>
|
||||
/// <strong><em>Left as `void`:</em></strong> "is every element the same type?" <br>
|
||||
/// <strong><em>Explicitly specified:</em></strong> "is every element a T?"
|
||||
///
|
||||
/// \returns True if the viewed node was homogeneous.
|
||||
///
|
||||
/// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
|
||||
/// an empty table or array.
|
||||
template <typename ElemType = void>
|
||||
[[nodiscard]]
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
return node_ ? node_->template is_homogeneous<impl::unwrap_node<ElemType>>() : false;
|
||||
}
|
||||
|
||||
/// \brief Gets the value contained by the referenced node.
|
||||
///
|
||||
/// \detail This function has 'exact' retrieval semantics; the only return value types allowed are the
|
||||
/// TOML native value types, or types that can losslessly represent a native value type (e.g.
|
||||
/// std::wstring on Windows).
|
||||
///
|
||||
/// \tparam T One of the native TOML value types, or a type capable of losslessly representing one.
|
||||
///
|
||||
/// \returns The underlying value if the node was a value of the
|
||||
/// matching type (or losslessly convertible to it), or an empty optional.
|
||||
///
|
||||
/// \see node_view::value()
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
optional<T> value_exact() const noexcept
|
||||
{
|
||||
if (node_)
|
||||
return node_->template value_exact<T>();
|
||||
return {};
|
||||
}
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
|
||||
/// \brief Gets the raw value contained by the referenced node.
|
||||
/// \brief Gets the value contained by the referenced node.
|
||||
///
|
||||
/// \tparam U One of the TOML value types. Can also be a string_view.
|
||||
/// \detail This function has 'permissive' retrieval semantics; some value types are allowed
|
||||
/// to convert to others (e.g. retrieving a boolean as an integer), and the specified return value
|
||||
/// type can be any type where a reasonable conversion from a native TOML value exists
|
||||
/// (e.g. std::wstring on Windows). If the source value cannot be represented by
|
||||
/// the destination type, an empty optional is returned. See node::value() for examples.
|
||||
///
|
||||
/// \returns The underlying value if the node was a value of the matching type (or convertible to it), or an empty optional.
|
||||
/// \tparam T One of the native TOML value types, or a type capable of convertible to one.
|
||||
///
|
||||
/// \see node::value()
|
||||
template <typename U>
|
||||
[[nodiscard]] optional<U> value() const noexcept
|
||||
/// \returns The underlying value if the node was a value of the matching type (or convertible to it)
|
||||
/// and within the range of the output type, or an empty optional.
|
||||
///
|
||||
/// \attention If you want strict value retrieval semantics that do not allow for any type conversions,
|
||||
/// use node_view::value_exact() instead.
|
||||
///
|
||||
/// \see
|
||||
/// - node_view::value()
|
||||
/// - node_view::value_exact()
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
optional<T> value() const noexcept
|
||||
{
|
||||
if (node_)
|
||||
return node_->template value<U>();
|
||||
return node_->template value<T>();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -193,21 +351,62 @@ namespace toml
|
|||
|
||||
/// \brief Gets the raw value contained by the referenced node, or a default.
|
||||
///
|
||||
/// \tparam U Default value type. Must be (or be promotable to) one of the TOML value types.
|
||||
/// \param default_value The default value to return if the view did not reference a node,
|
||||
/// or if the node wasn't a value, wasn't the correct type, or no conversion was possible.
|
||||
///
|
||||
/// \returns The node's underlying value, or the default if the node wasn't a value, wasn't the
|
||||
/// \tparam T Default value type. Must be one of the native TOML value types,
|
||||
/// or convertible to it.
|
||||
/// \param default_value The default value to return if the node wasn't a value, wasn't the
|
||||
/// correct type, or no conversion was possible.
|
||||
///
|
||||
/// \see node::value_or()
|
||||
template <typename U>
|
||||
[[nodiscard]] auto value_or(U&& default_value) const noexcept
|
||||
/// \returns The underlying value if the node was a value of the matching type (or convertible to it)
|
||||
/// and within the range of the output type, or the provided default.
|
||||
///
|
||||
/// \attention This function has the same permissive retrieval semantics as node::value(). If you want strict
|
||||
/// value retrieval semantics that do not allow for any type conversions, use node_view::value_exact()
|
||||
/// instead.
|
||||
///
|
||||
/// \see
|
||||
/// - node_view::value()
|
||||
/// - node_view::value_exact()
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto value_or(T&& default_value) const noexcept
|
||||
{
|
||||
using return_type = decltype(node_->value_or(std::forward<U>(default_value)));
|
||||
using namespace ::toml::impl;
|
||||
|
||||
static_assert(
|
||||
!is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Retrieving values as wide-character strings is only "
|
||||
"supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
if constexpr (is_wide_string<T>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
if (node_)
|
||||
return node_->value_or(std::forward<U>(default_value));
|
||||
return return_type{ std::forward<U>(default_value) };
|
||||
return node_->value_or(std::forward<T>(default_value));
|
||||
return std::wstring{ std::forward<T>(default_value) };
|
||||
|
||||
#else
|
||||
|
||||
static_assert(impl::dependent_false<T>, "Evaluated unreachable branch!");
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
using value_type = std::conditional_t<
|
||||
std::is_pointer_v<std::decay_t<T>>,
|
||||
std::add_pointer_t<std::add_const_t<std::remove_pointer_t<std::decay_t<T>>>>,
|
||||
std::decay_t<T>
|
||||
>;
|
||||
|
||||
if (node_)
|
||||
return node_->value_or(std::forward<T>(default_value));
|
||||
if constexpr (std::is_pointer_v<value_type>)
|
||||
return value_type{ default_value };
|
||||
else
|
||||
return std::forward<T>(default_value);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Invokes a visitor on the viewed node based on its concrete type.
|
||||
|
@ -243,26 +442,23 @@ namespace toml
|
|||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam U One of the TOML value types.
|
||||
/// \tparam T One of the TOML value types.
|
||||
///
|
||||
/// \returns A reference to the underlying data.
|
||||
template <typename U>
|
||||
[[nodiscard]] decltype(auto) ref() const noexcept
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
decltype(auto) ref() const noexcept
|
||||
{
|
||||
using type = impl::unwrapped<U>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Template type parameter must be one of the TOML value types, a toml::table, or a toml::array"
|
||||
);
|
||||
TOML_ASSERT(
|
||||
node_
|
||||
&& "toml::node_view::ref() called on a node_view that did not reference a node"
|
||||
);
|
||||
return node_->template ref<type>();
|
||||
return node_->template ref<impl::unwrap_node<T>>();
|
||||
}
|
||||
|
||||
/// \brief Returns true if the viewed node is a table with the same contents as RHS.
|
||||
[[nodiscard]] friend bool operator == (const node_view& lhs, const table& rhs) noexcept
|
||||
[[nodiscard]]
|
||||
friend bool operator == (const node_view& lhs, const table& rhs) noexcept
|
||||
{
|
||||
if (lhs.node_ == &rhs)
|
||||
return true;
|
||||
|
@ -272,7 +468,8 @@ namespace toml
|
|||
TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const table&, )
|
||||
|
||||
/// \brief Returns true if the viewed node is an array with the same contents as RHS.
|
||||
[[nodiscard]] friend bool operator == (const node_view& lhs, const array& rhs) noexcept
|
||||
[[nodiscard]]
|
||||
friend bool operator == (const node_view& lhs, const array& rhs) noexcept
|
||||
{
|
||||
if (lhs.node_ == &rhs)
|
||||
return true;
|
||||
|
@ -282,46 +479,73 @@ namespace toml
|
|||
TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const array&, )
|
||||
|
||||
/// \brief Returns true if the viewed node is a value with the same value as RHS.
|
||||
template <typename U>
|
||||
[[nodiscard]] friend bool operator == (const node_view& lhs, const toml::value<U>& rhs) noexcept
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
friend bool operator == (const node_view& lhs, const toml::value<T>& rhs) noexcept
|
||||
{
|
||||
if (lhs.node_ == &rhs)
|
||||
return true;
|
||||
const auto val = lhs.as<U>();
|
||||
const auto val = lhs.as<T>();
|
||||
return val && *val == rhs;
|
||||
}
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const toml::value<U>&, template <typename U>)
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const toml::value<T>&, template <typename T>)
|
||||
|
||||
/// \brief Returns true if the viewed node is a value with the same value as RHS.
|
||||
template <typename U, typename = std::enable_if_t<impl::is_value_or_promotable<U>>>
|
||||
[[nodiscard]] friend bool operator == (const node_view& lhs, const U& rhs) noexcept
|
||||
template <typename T, typename = std::enable_if_t<
|
||||
impl::is_native<T>
|
||||
|| impl::is_losslessly_convertible_to_native<T>
|
||||
>>
|
||||
[[nodiscard]]
|
||||
friend bool operator == (const node_view& lhs, const T& rhs) noexcept
|
||||
{
|
||||
const auto val = lhs.as<impl::promoted<U>>();
|
||||
static_assert(
|
||||
!impl::is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Comparison with wide-character strings is only "
|
||||
"supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
if constexpr (impl::is_wide_string<T>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return lhs == impl::narrow(rhs);
|
||||
#else
|
||||
static_assert(impl::dependent_false<T>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto val = lhs.as<impl::native_type_of<T>>();
|
||||
return val && *val == rhs;
|
||||
}
|
||||
}
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(
|
||||
const node_view&,
|
||||
const U&,
|
||||
template <typename U, typename = std::enable_if_t<impl::is_value_or_promotable<U>>>
|
||||
const T&,
|
||||
template <typename T, typename = std::enable_if_t<
|
||||
impl::is_native<T>
|
||||
|| impl::is_losslessly_convertible_to_native<T>
|
||||
>>
|
||||
)
|
||||
|
||||
/// \brief Returns true if the viewed node is an array with the same contents as the RHS initializer list.
|
||||
template <typename U>
|
||||
[[nodiscard]] friend bool operator == (const node_view& lhs, const std::initializer_list<U>& rhs) noexcept
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
friend bool operator == (const node_view& lhs, const std::initializer_list<T>& rhs) noexcept
|
||||
{
|
||||
const auto arr = lhs.as<array>();
|
||||
return arr && *arr == rhs;
|
||||
}
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const std::initializer_list<U>&, template <typename U>)
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const std::initializer_list<T>&, template <typename T>)
|
||||
|
||||
/// \brief Returns true if the viewed node is an array with the same contents as the RHS vector.
|
||||
template <typename U>
|
||||
[[nodiscard]] friend bool operator == (const node_view& lhs, const std::vector<U>& rhs) noexcept
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
friend bool operator == (const node_view& lhs, const std::vector<T>& rhs) noexcept
|
||||
{
|
||||
const auto arr = lhs.as<array>();
|
||||
return arr && *arr == rhs;
|
||||
}
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const std::vector<U>&, template <typename U>)
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const std::vector<T>&, template <typename T>)
|
||||
|
||||
/// \brief Returns a view of the selected subnode.
|
||||
///
|
||||
|
@ -329,34 +553,63 @@ namespace toml
|
|||
///
|
||||
/// \returns A view of the selected node if this node represented a table and it contained a
|
||||
/// value at the given key, or an empty view.
|
||||
[[nodiscard]] node_view operator[] (string_view key) const noexcept
|
||||
[[nodiscard]]
|
||||
node_view operator[] (std::string_view key) const noexcept
|
||||
{
|
||||
if (auto tbl = this->as_table())
|
||||
return { tbl->get(key) };
|
||||
return { nullptr };
|
||||
return node_view{ tbl->get(key) };
|
||||
return node_view{ nullptr };
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Returns a view of the selected subnode.
|
||||
///
|
||||
/// \param key The key of the node to retrieve
|
||||
///
|
||||
/// \returns A view of the selected node if this node represented a table and it contained a
|
||||
/// value at the given key, or an empty view.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]]
|
||||
node_view operator[] (std::wstring_view key) const noexcept
|
||||
{
|
||||
if (auto tbl = this->as_table())
|
||||
return node_view{ tbl->get(key) };
|
||||
return node_view{ nullptr };
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Returns a view of the selected subnode.
|
||||
///
|
||||
/// \param index The index of the node to retrieve
|
||||
///
|
||||
/// \returns A view of the selected node if this node represented an array and it contained a
|
||||
/// value at the given index, or an empty view.
|
||||
[[nodiscard]] node_view operator[] (size_t index) const noexcept
|
||||
[[nodiscard]]
|
||||
node_view operator[] (size_t index) const noexcept
|
||||
{
|
||||
if (auto arr = this->as_array())
|
||||
return { arr->get(index) };
|
||||
return { nullptr };
|
||||
return node_view{ arr->get(index) };
|
||||
return node_view{ nullptr };
|
||||
}
|
||||
|
||||
template <typename Char, typename U>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const node_view<U>&);
|
||||
template <typename Char, typename T>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const node_view<T>&);
|
||||
};
|
||||
template <typename T> node_view(const value<T>&) -> node_view<const node>;
|
||||
node_view(const table&) -> node_view<const node>;
|
||||
node_view(const array&) -> node_view<const node>;
|
||||
template <typename T> node_view(value<T>&) -> node_view<node>;
|
||||
node_view(table&) -> node_view<node>;
|
||||
node_view(array&) -> node_view<node>;
|
||||
template <typename T> node_view(const T*) -> node_view<const node>;
|
||||
template <typename T> node_view(T*) -> node_view<node>;
|
||||
|
||||
/// \brief Prints the viewed node out to a stream.
|
||||
template <typename Char, typename T>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& os, const node_view<T>& nv)
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& os, const node_view<T>& nv)
|
||||
{
|
||||
if (nv.node_)
|
||||
{
|
||||
|
@ -368,13 +621,61 @@ namespace toml
|
|||
return os;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
|
||||
extern template class TOML_API node_view<node>;
|
||||
extern template class TOML_API node_view<const node>;
|
||||
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const node_view<node>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const node_view<const node>&);
|
||||
|
||||
#define TOML_EXTERN(name, T) \
|
||||
extern template TOML_API optional<T> node_view<node>::name<T>() const noexcept; \
|
||||
extern template TOML_API optional<T> node_view<const node>::name<T>() const noexcept
|
||||
TOML_EXTERN(value_exact, std::string_view);
|
||||
TOML_EXTERN(value_exact, std::string);
|
||||
TOML_EXTERN(value_exact, const char*);
|
||||
TOML_EXTERN(value_exact, int64_t);
|
||||
TOML_EXTERN(value_exact, double);
|
||||
TOML_EXTERN(value_exact, date);
|
||||
TOML_EXTERN(value_exact, time);
|
||||
TOML_EXTERN(value_exact, date_time);
|
||||
TOML_EXTERN(value_exact, bool);
|
||||
TOML_EXTERN(value, std::string_view);
|
||||
TOML_EXTERN(value, std::string);
|
||||
TOML_EXTERN(value, const char*);
|
||||
TOML_EXTERN(value, signed char);
|
||||
TOML_EXTERN(value, signed short);
|
||||
TOML_EXTERN(value, signed int);
|
||||
TOML_EXTERN(value, signed long);
|
||||
TOML_EXTERN(value, signed long long);
|
||||
TOML_EXTERN(value, unsigned char);
|
||||
TOML_EXTERN(value, unsigned short);
|
||||
TOML_EXTERN(value, unsigned int);
|
||||
TOML_EXTERN(value, unsigned long);
|
||||
TOML_EXTERN(value, unsigned long long);
|
||||
TOML_EXTERN(value, double);
|
||||
TOML_EXTERN(value, float);
|
||||
TOML_EXTERN(value, date);
|
||||
TOML_EXTERN(value, time);
|
||||
TOML_EXTERN(value, date_time);
|
||||
TOML_EXTERN(value, bool);
|
||||
#ifdef __cpp_lib_char8_t
|
||||
TOML_EXTERN(value_exact, std::u8string_view);
|
||||
TOML_EXTERN(value_exact, std::u8string);
|
||||
TOML_EXTERN(value_exact, const char8_t*);
|
||||
TOML_EXTERN(value, std::u8string_view);
|
||||
TOML_EXTERN(value, std::u8string);
|
||||
TOML_EXTERN(value, const char8_t*);
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_EXTERN(value_exact, std::wstring);
|
||||
TOML_EXTERN(value, std::wstring);
|
||||
#endif
|
||||
#undef TOML_EXTERN
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_FLOAT_WARNINGS
|
||||
#endif // !TOML_HEADER_ONLY
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
|
|
@ -10,28 +10,20 @@
|
|||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
TOML_DISABLE_WARNINGS
|
||||
#if TOML_EXCEPTIONS
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
TOML_POP_WARNINGS
|
||||
TOML_ENABLE_WARNINGS
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
TOML_DISABLE_VTABLE_WARNINGS
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
#if TOML_LARGE_FILES
|
||||
TOML_ABI_NAMESPACE_START(lf)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(sf)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex)
|
||||
|
||||
#if TOML_DOXYGEN || !TOML_EXCEPTIONS
|
||||
|
||||
TOML_ABI_NAMESPACE_START(noex)
|
||||
#if defined(DOXYGEN) || !TOML_EXCEPTIONS
|
||||
|
||||
/// \brief An error generated when parsing fails.
|
||||
///
|
||||
|
@ -80,8 +72,6 @@ namespace toml
|
|||
|
||||
#else
|
||||
|
||||
TOML_ABI_NAMESPACE_START(ex)
|
||||
|
||||
class parse_error final
|
||||
: public std::runtime_error
|
||||
{
|
||||
|
@ -125,7 +115,6 @@ namespace toml
|
|||
#endif
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_END // TOML_LARGE_FILES
|
||||
|
||||
/// \brief Prints a parse_error to a stream.
|
||||
///
|
||||
|
@ -136,7 +125,7 @@ namespace toml
|
|||
/// }
|
||||
/// catch (const toml::parse_error & err)
|
||||
/// {
|
||||
/// std::cerr << "Parsing failed:\n"sv << err << std::endl;
|
||||
/// std::cerr << "Parsing failed:\n"sv << err << "\n";
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -152,8 +141,7 @@ namespace toml
|
|||
///
|
||||
/// \returns The input stream.
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const parse_error& rhs)
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const parse_error& rhs)
|
||||
{
|
||||
lhs << rhs.description();
|
||||
lhs << "\n\t(error occurred at "sv;
|
||||
|
@ -162,9 +150,10 @@ namespace toml
|
|||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
#endif
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_INIT_WARNINGS
|
||||
|
|
|
@ -13,14 +13,11 @@
|
|||
#include "toml_table.h"
|
||||
#include "toml_utf8_streams.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
#if TOML_DOXYGEN || !TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex)
|
||||
|
||||
TOML_ABI_NAMESPACE_START(parse_noex)
|
||||
#if defined(DOXYGEN) || !TOML_EXCEPTIONS
|
||||
|
||||
/// \brief The result of a parsing operation.
|
||||
///
|
||||
|
@ -32,7 +29,7 @@ namespace toml
|
|||
/// if (result)
|
||||
/// do_stuff_with_a_table(result); //implicitly converts to table&
|
||||
/// else
|
||||
/// std::cerr << "Parse failed:\n"sv << result.error() << std::endl;
|
||||
/// std::cerr << "Parse failed:\n"sv << result.error() << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -61,8 +58,8 @@ namespace toml
|
|||
{
|
||||
private:
|
||||
std::aligned_storage_t<
|
||||
(sizeof(table) < sizeof(parse_error) ? sizeof(parse_error) : sizeof(table)),
|
||||
(alignof(table) < alignof(parse_error) ? alignof(parse_error) : alignof(table))
|
||||
(sizeof(toml::table) < sizeof(parse_error) ? sizeof(parse_error) : sizeof(toml::table)),
|
||||
(alignof(toml::table) < alignof(parse_error) ? alignof(parse_error) : alignof(toml::table))
|
||||
> storage;
|
||||
bool is_err;
|
||||
|
||||
|
@ -71,7 +68,7 @@ namespace toml
|
|||
if (is_err)
|
||||
TOML_LAUNDER(reinterpret_cast<parse_error*>(&storage))->~parse_error();
|
||||
else
|
||||
TOML_LAUNDER(reinterpret_cast<table*>(&storage))->~table();
|
||||
TOML_LAUNDER(reinterpret_cast<toml::table*>(&storage))->~table();
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -86,53 +83,66 @@ namespace toml
|
|||
[[nodiscard]] bool succeeded() const noexcept { return !is_err; }
|
||||
/// \brief Returns true if parsing failed.
|
||||
[[nodiscard]] bool failed() const noexcept { return is_err; }
|
||||
/// \brief Returns true if parsing succeeeded.
|
||||
/// \brief Returns true if parsing succeeded.
|
||||
[[nodiscard]] explicit operator bool() const noexcept { return !is_err; }
|
||||
|
||||
/// \brief Returns the internal toml::table.
|
||||
[[nodiscard]] table& get() & noexcept
|
||||
[[nodiscard]]
|
||||
toml::table& table() & noexcept
|
||||
{
|
||||
TOML_ASSERT(!is_err);
|
||||
return *TOML_LAUNDER(reinterpret_cast<table*>(&storage));
|
||||
return *TOML_LAUNDER(reinterpret_cast<toml::table*>(&storage));
|
||||
}
|
||||
/// \brief Returns the internal toml::table (rvalue overload).
|
||||
[[nodiscard]] table&& get() && noexcept
|
||||
[[nodiscard]]
|
||||
toml::table&& table() && noexcept
|
||||
{
|
||||
TOML_ASSERT(!is_err);
|
||||
return std::move(*TOML_LAUNDER(reinterpret_cast<table*>(&storage)));
|
||||
return std::move(*TOML_LAUNDER(reinterpret_cast<toml::table*>(&storage)));
|
||||
}
|
||||
/// \brief Returns the internal toml::table (const lvalue overload).
|
||||
[[nodiscard]] const table& get() const& noexcept
|
||||
[[nodiscard]]
|
||||
const toml::table& table() const& noexcept
|
||||
{
|
||||
TOML_ASSERT(!is_err);
|
||||
return *TOML_LAUNDER(reinterpret_cast<const table*>(&storage));
|
||||
return *TOML_LAUNDER(reinterpret_cast<const toml::table*>(&storage));
|
||||
}
|
||||
|
||||
[[nodiscard, deprecated("use parse_result::table() instead")]]
|
||||
toml::table& get() & noexcept { return table(); }
|
||||
[[nodiscard, deprecated("use parse_result::table() instead")]]
|
||||
toml::table&& get() && noexcept { return std::move(table()); }
|
||||
[[nodiscard, deprecated("use parse_result::table() instead")]]
|
||||
const toml::table& get() const& noexcept { return table(); }
|
||||
|
||||
/// \brief Returns the internal toml::parse_error.
|
||||
[[nodiscard]] parse_error& error() & noexcept
|
||||
[[nodiscard]]
|
||||
parse_error& error() & noexcept
|
||||
{
|
||||
TOML_ASSERT(is_err);
|
||||
return *TOML_LAUNDER(reinterpret_cast<parse_error*>(&storage));
|
||||
}
|
||||
/// \brief Returns the internal toml::parse_error (rvalue overload).
|
||||
[[nodiscard]] parse_error&& error() && noexcept
|
||||
[[nodiscard]]
|
||||
parse_error&& error() && noexcept
|
||||
{
|
||||
TOML_ASSERT(is_err);
|
||||
return std::move(*TOML_LAUNDER(reinterpret_cast<parse_error*>(&storage)));
|
||||
}
|
||||
/// \brief Returns the internal toml::parse_error (const lvalue overload).
|
||||
[[nodiscard]] const parse_error& error() const& noexcept
|
||||
[[nodiscard]]
|
||||
const parse_error& error() const& noexcept
|
||||
{
|
||||
TOML_ASSERT(is_err);
|
||||
return *TOML_LAUNDER(reinterpret_cast<const parse_error*>(&storage));
|
||||
}
|
||||
|
||||
/// \brief Returns the internal toml::table.
|
||||
[[nodiscard]] operator table& () noexcept { return get(); }
|
||||
[[nodiscard]] operator toml::table& () noexcept { return table(); }
|
||||
/// \brief Returns the internal toml::table (rvalue overload).
|
||||
[[nodiscard]] operator table&& () noexcept { return std::move(get()); }
|
||||
[[nodiscard]] operator toml::table&& () noexcept { return std::move(table()); }
|
||||
/// \brief Returns the internal toml::table (const lvalue overload).
|
||||
[[nodiscard]] operator const table& () const noexcept { return get(); }
|
||||
[[nodiscard]] operator const toml::table& () const noexcept { return table(); }
|
||||
|
||||
/// \brief Returns the internal toml::parse_error.
|
||||
[[nodiscard]] explicit operator parse_error& () noexcept { return error(); }
|
||||
|
@ -142,10 +152,10 @@ namespace toml
|
|||
[[nodiscard]] explicit operator const parse_error& () const noexcept { return error(); }
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit parse_result(table&& tbl) noexcept
|
||||
explicit parse_result(toml::table&& tbl) noexcept
|
||||
: is_err{ false }
|
||||
{
|
||||
::new (&storage) table{ std::move(tbl) };
|
||||
::new (&storage) toml::table{ std::move(tbl) };
|
||||
}
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
|
@ -163,7 +173,7 @@ namespace toml
|
|||
if (is_err)
|
||||
::new (&storage) parse_error{ std::move(res).error() };
|
||||
else
|
||||
::new (&storage) table{ std::move(res).get() };
|
||||
::new (&storage) toml::table{ std::move(res).table() };
|
||||
}
|
||||
|
||||
/// \brief Move-assignment operator.
|
||||
|
@ -176,14 +186,14 @@ namespace toml
|
|||
if (is_err)
|
||||
::new (&storage) parse_error{ std::move(rhs).error() };
|
||||
else
|
||||
::new (&storage) table{ std::move(rhs).get() };
|
||||
::new (&storage) toml::table{ std::move(rhs).table() };
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_err)
|
||||
error() = std::move(rhs).error();
|
||||
else
|
||||
get() = std::move(rhs).get();
|
||||
table() = std::move(rhs).table();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -202,98 +212,152 @@ namespace toml
|
|||
/// or an empty node view.
|
||||
///
|
||||
/// \see toml::node_view
|
||||
[[nodiscard]] node_view<node> operator[] (string_view key) noexcept
|
||||
[[nodiscard]]
|
||||
node_view<node> operator[] (string_view key) noexcept
|
||||
{
|
||||
return is_err ? node_view<node>{} : get()[key];
|
||||
return is_err ? node_view<node>{} : table()[key];
|
||||
}
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
|
||||
[[nodiscard]] node_view<const node> operator[] (string_view key) const noexcept
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||
/// or an empty node view.
|
||||
///
|
||||
/// \see toml::node_view
|
||||
[[nodiscard]]
|
||||
node_view<const node> operator[] (string_view key) const noexcept
|
||||
{
|
||||
return is_err ? node_view<const node>{} : get()[key];
|
||||
return is_err ? node_view<const node>{} : table()[key];
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table.
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||
/// or an empty node view.
|
||||
///
|
||||
/// \see toml::node_view
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]]
|
||||
node_view<node> operator[] (std::wstring_view key) noexcept
|
||||
{
|
||||
return is_err ? node_view<node>{} : table()[key];
|
||||
}
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||
/// or an empty node view.
|
||||
///
|
||||
/// \see toml::node_view
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]]
|
||||
node_view<const node> operator[] (std::wstring_view key) const noexcept
|
||||
{
|
||||
return is_err ? node_view<const node>{} : table()[key];
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair in the wrapped table.
|
||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||
[[nodiscard]]
|
||||
table_iterator begin() noexcept
|
||||
{
|
||||
return is_err ? table_iterator{} : table().begin();
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair in the wrapped table.
|
||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||
[[nodiscard]] table_iterator begin() noexcept
|
||||
[[nodiscard]]
|
||||
const_table_iterator begin() const noexcept
|
||||
{
|
||||
return is_err ? table_iterator{} : get().begin();
|
||||
return is_err ? const_table_iterator{} : table().begin();
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair in the wrapped table.
|
||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||
[[nodiscard]] const_table_iterator begin() const noexcept
|
||||
[[nodiscard]]
|
||||
const_table_iterator cbegin() const noexcept
|
||||
{
|
||||
return is_err ? const_table_iterator{} : get().begin();
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair in the wrapped table.
|
||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||
[[nodiscard]] const_table_iterator cbegin() const noexcept
|
||||
{
|
||||
return is_err ? const_table_iterator{} : get().cbegin();
|
||||
return is_err ? const_table_iterator{} : table().cbegin();
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to one-past-the-last key-value pair in the wrapped table.
|
||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||
[[nodiscard]] table_iterator end() noexcept
|
||||
[[nodiscard]]
|
||||
table_iterator end() noexcept
|
||||
{
|
||||
return is_err ? table_iterator{} : get().end();
|
||||
return is_err ? table_iterator{} : table().end();
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to one-past-the-last key-value pair in the wrapped table.
|
||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||
[[nodiscard]] const_table_iterator end() const noexcept
|
||||
[[nodiscard]]
|
||||
const_table_iterator end() const noexcept
|
||||
{
|
||||
return is_err ? const_table_iterator{} : get().end();
|
||||
return is_err ? const_table_iterator{} : table().end();
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to one-past-the-last key-value pair in the wrapped table.
|
||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||
[[nodiscard]] const_table_iterator cend() const noexcept
|
||||
[[nodiscard]]
|
||||
const_table_iterator cend() const noexcept
|
||||
{
|
||||
return is_err ? const_table_iterator{} : get().cend();
|
||||
return is_err ? const_table_iterator{} : table().cend();
|
||||
}
|
||||
};
|
||||
|
||||
TOML_ABI_NAMESPACE_END
|
||||
|
||||
#else
|
||||
|
||||
using parse_result = table;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(impl_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(impl_noex)
|
||||
#endif
|
||||
|
||||
[[nodiscard]] TOML_API
|
||||
parse_result do_parse(utf8_reader_interface&&) TOML_MAY_THROW;
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
|
||||
namespace toml
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex)
|
||||
|
||||
[[nodiscard]] TOML_API parse_result do_parse(utf8_reader_interface&&) TOML_MAY_THROW;
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(parse_ex)
|
||||
#define TOML_THROW_PARSE_ERROR(msg, path) \
|
||||
throw parse_error{ \
|
||||
msg, source_position{}, std::make_shared<const std::string>(std::move(path)) \
|
||||
}
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(parse_noex)
|
||||
#define TOML_THROW_PARSE_ERROR(msg, path) \
|
||||
return parse_result{ parse_error{ \
|
||||
msg, source_position{}, std::make_shared<const std::string>(std::move(path)) \
|
||||
}}
|
||||
#endif
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex)
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse("a = 3"sv);
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -316,7 +380,7 @@ namespace toml
|
|||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse("a = 3"sv, "foo.toml");
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -326,6 +390,8 @@ namespace toml
|
|||
///
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
|
@ -333,13 +399,13 @@ namespace toml
|
|||
TOML_API
|
||||
parse_result parse(std::string_view doc, std::string&& source_path) TOML_MAY_THROW;
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a char8_t string view.
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse(u8"a = 3"sv);
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
/// auto tbl = toml::parse("a = 3"sv, L"foo.toml");
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -355,16 +421,20 @@ namespace toml
|
|||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
///
|
||||
/// \attention This overload is not available if your compiler does not support char8_t-based strings.
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]]
|
||||
TOML_API
|
||||
parse_result parse(std::u8string_view doc, std::string_view source_path = {}) TOML_MAY_THROW;
|
||||
parse_result parse(std::string_view doc, std::wstring_view source_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
/// \brief Parses a TOML document from a char8_t string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse(u8"a = 3"sv, "foo.toml");
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
/// auto tbl = toml::parse(u8"a = 3"sv);
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -374,14 +444,66 @@ namespace toml
|
|||
///
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
[[nodiscard]]
|
||||
TOML_API
|
||||
parse_result parse(std::u8string_view doc, std::string_view source_path = {}) TOML_MAY_THROW;
|
||||
|
||||
/// \brief Parses a TOML document from a char8_t string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse(u8"a = 3"sv, "foo.toml");
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
[[nodiscard]]
|
||||
TOML_API
|
||||
parse_result parse(std::u8string_view doc, std::string&& source_path) TOML_MAY_THROW;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a char8_t string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse(u8"a = 3"sv, L"foo.toml");
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
///
|
||||
/// \attention This overload is not available if your compiler does not support char8_t-based strings.
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]]
|
||||
TOML_API
|
||||
parse_result parse(std::u8string_view doc, std::string&& source_path) TOML_MAY_THROW;
|
||||
parse_result parse(std::u8string_view doc, std::wstring_view source_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#endif // __cpp_lib_char8_t
|
||||
|
||||
|
@ -392,7 +514,7 @@ namespace toml
|
|||
/// ss << "a = 3"sv;
|
||||
///
|
||||
/// auto tbl = toml::parse(ss);
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -410,8 +532,7 @@ namespace toml
|
|||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
template <typename Char>
|
||||
[[nodiscard]]
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::basic_istream<Char>& doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
inline parse_result parse(std::basic_istream<Char>& doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
|
@ -428,7 +549,7 @@ namespace toml
|
|||
/// ss << "a = 3"sv;
|
||||
///
|
||||
/// auto tbl = toml::parse(ss, "foo.toml");
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -439,13 +560,14 @@ namespace toml
|
|||
/// \tparam Char The stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
template <typename Char>
|
||||
[[nodiscard]]
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::basic_istream<Char>& doc, std::string&& source_path) TOML_MAY_THROW
|
||||
inline parse_result parse(std::basic_istream<Char>& doc, std::string&& source_path) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
|
@ -455,6 +577,41 @@ namespace toml
|
|||
return impl::do_parse(impl::utf8_reader{ doc, std::move(source_path) });
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a stream.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// std::stringstream ss;
|
||||
/// ss << "a = 3"sv;
|
||||
///
|
||||
/// auto tbl = toml::parse(ss);
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam Char The stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
template <typename Char>
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::basic_istream<Char>& doc, std::wstring_view source_path) TOML_MAY_THROW
|
||||
{
|
||||
return parse(doc, impl::narrow(source_path));
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
// Q: "why are the parse_file functions templated??"
|
||||
// A: I don't want to force users to drag in <fstream> if they're not going to do
|
||||
|
@ -474,7 +631,7 @@ namespace toml
|
|||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam Char The path's character type. Must be 1 byte in size.
|
||||
/// \tparam Char The path's character type.
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
|
@ -483,29 +640,35 @@ namespace toml
|
|||
/// \attention You must `#include <fstream>` to use this function (toml++ does not transitively include it for you).
|
||||
template <typename Char, typename StreamChar = char>
|
||||
[[nodiscard]]
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse_file(std::basic_string_view<Char> file_path) TOML_MAY_THROW
|
||||
inline parse_result parse_file(std::basic_string_view<Char> file_path) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
"The path's character type must be 1 byte in size."
|
||||
!std::is_same_v<Char, wchar_t> || TOML_WINDOWS_COMPAT,
|
||||
"Wide-character file paths are only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
static_assert(
|
||||
sizeof(StreamChar) == 1,
|
||||
"The stream's character type must be 1 byte in size."
|
||||
sizeof(Char) == 1 || std::is_same_v<Char, wchar_t>,
|
||||
"The file path's underlying character type must be wchar_t or be 1 byte in size."
|
||||
);
|
||||
#else
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
"The file path's underlying character type must be 1 byte in size."
|
||||
);
|
||||
#endif
|
||||
static_assert(
|
||||
std::is_same_v<StreamChar, char>,
|
||||
"StreamChar must be 'char' (it is as an instantiation-delaying hack and is not user-configurable)."
|
||||
);
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
#define TOML_PARSE_FILE_ERROR(msg, pos) \
|
||||
throw parse_error{ msg, pos, std::make_shared<const std::string>(std::move(file_path_str)) }
|
||||
#else
|
||||
#define TOML_PARSE_FILE_ERROR(msg, pos) \
|
||||
return parse_result{ \
|
||||
parse_error{ msg, pos, std::make_shared<const std::string>(std::move(file_path_str)) } \
|
||||
}
|
||||
std::string file_path_str;
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (std::is_same_v<Char, wchar_t>)
|
||||
file_path_str = impl::narrow(file_path);
|
||||
else
|
||||
#endif
|
||||
|
||||
auto file_path_str = std::string(reinterpret_cast<const char*>(file_path.data()), file_path.length());
|
||||
file_path_str = std::string_view{ reinterpret_cast<const char*>(file_path.data()), file_path.length() };
|
||||
|
||||
// open file with a custom-sized stack buffer
|
||||
using ifstream = std::basic_ifstream<StreamChar>;
|
||||
|
@ -514,13 +677,13 @@ namespace toml
|
|||
file.rdbuf()->pubsetbuf(file_buffer, sizeof(file_buffer));
|
||||
file.open(file_path_str, ifstream::in | ifstream::binary | ifstream::ate);
|
||||
if (!file.is_open())
|
||||
TOML_PARSE_FILE_ERROR("File could not be opened for reading", source_position{});
|
||||
TOML_THROW_PARSE_ERROR("File could not be opened for reading", file_path_str);
|
||||
|
||||
// get size
|
||||
const auto file_size = file.tellg();
|
||||
if (file_size == -1)
|
||||
TOML_PARSE_FILE_ERROR("Could not determine file size", source_position{});
|
||||
file.seekg(0, std::ios::beg);
|
||||
TOML_THROW_PARSE_ERROR("Could not determine file size", file_path_str);
|
||||
file.seekg(0, ifstream::beg);
|
||||
|
||||
// read the whole file into memory first if the file isn't too large
|
||||
constexpr auto large_file_threshold = 1024 * 1024 * static_cast<int>(sizeof(void*)) * 4; // 32 megabytes on 64-bit
|
||||
|
@ -535,17 +698,18 @@ namespace toml
|
|||
// otherwise parse it using the streams
|
||||
else
|
||||
return parse(file, std::move(file_path_str));
|
||||
|
||||
#undef TOML_PARSE_FILE_ERROR
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API parse_result parse(std::istream&, std::string_view) TOML_MAY_THROW;
|
||||
extern template TOML_API parse_result parse(std::istream&, std::string&&) TOML_MAY_THROW;
|
||||
extern template TOML_API parse_result parse_file(std::string_view) TOML_MAY_THROW;
|
||||
#ifdef __cpp_lib_char8_t
|
||||
extern template TOML_API parse_result parse_file(std::u8string_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
extern template TOML_API parse_result parse_file(std::wstring_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template <typename Char>
|
||||
|
@ -562,41 +726,15 @@ namespace toml
|
|||
return parse_file(std::basic_string_view<Char>{ file_path });
|
||||
}
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
|
||||
/// \brief Convenience literal operators for working with toml++.
|
||||
///
|
||||
/// \detail This namespace exists so you can safely hoist the UDL operators into another scope
|
||||
/// without dragging in everything in the toml namespace: \cpp
|
||||
///
|
||||
/// #include <toml++/toml.h>
|
||||
/// using namespace toml::literals;
|
||||
///
|
||||
/// int main()
|
||||
/// {
|
||||
/// auto tbl = "vals = [1, 2, 3]"_toml;
|
||||
///
|
||||
/// // ... do stuff with the table generated by the "_toml" UDL ...
|
||||
///
|
||||
/// return 0;
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
inline namespace literals
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(lit_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(lit_noex)
|
||||
#endif
|
||||
|
||||
/// \brief Parses TOML data from a string.
|
||||
/// \brief Parses TOML data from a string literal.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// using namespace toml::literals;
|
||||
///
|
||||
/// auto tbl = "a = 3"_toml;
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -604,7 +742,7 @@ namespace toml
|
|||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \param str The string data.
|
||||
/// \param str The string data. Must be valid UTF-8.
|
||||
/// \param len The string length.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
|
@ -615,13 +753,13 @@ namespace toml
|
|||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
/// \brief Parses TOML data from a string.
|
||||
/// \brief Parses TOML data from a UTF-8 string literal.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// using namespace toml::literals;
|
||||
///
|
||||
/// auto tbl = u8"a = 3"_toml;
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -629,21 +767,21 @@ namespace toml
|
|||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \param str The string data.
|
||||
/// \param str The string data. Must be valid UTF-8.
|
||||
/// \param len The string length.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
///
|
||||
/// \attention This overload is not available if your compiler does not support char8_t-based strings.
|
||||
[[nodiscard]]
|
||||
TOML_API
|
||||
parse_result operator"" _toml(const char8_t* str, size_t len) TOML_MAY_THROW;
|
||||
|
||||
#endif // __cpp_lib_char8_t
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
}
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_PADDING_WARNINGS
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
#undef TOML_THROW_PARSE_ERROR
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,73 +3,70 @@
|
|||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
// clang-format off
|
||||
|
||||
////////// CONFIGURATION
|
||||
|
||||
#ifdef TOML_CONFIG_HEADER
|
||||
#include TOML_CONFIG_HEADER
|
||||
#endif
|
||||
|
||||
#if !defined(TOML_ALL_INLINE) || (defined(TOML_ALL_INLINE) && TOML_ALL_INLINE) || defined(__INTELLISENSE__)
|
||||
#undef TOML_ALL_INLINE
|
||||
#define TOML_ALL_INLINE 1
|
||||
#endif
|
||||
|
||||
#if defined(TOML_IMPLEMENTATION) || TOML_ALL_INLINE
|
||||
#undef TOML_IMPLEMENTATION
|
||||
#define TOML_IMPLEMENTATION 1
|
||||
#else
|
||||
#define TOML_IMPLEMENTATION 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_API
|
||||
#define TOML_API
|
||||
#endif
|
||||
|
||||
#ifndef TOML_CHAR_8_STRINGS
|
||||
#define TOML_CHAR_8_STRINGS 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_UNRELEASED_FEATURES
|
||||
#define TOML_UNRELEASED_FEATURES 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_LARGE_FILES
|
||||
#define TOML_LARGE_FILES 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_UNDEF_MACROS
|
||||
#define TOML_UNDEF_MACROS 1
|
||||
#endif
|
||||
|
||||
#ifndef TOML_PARSER
|
||||
#define TOML_PARSER 1
|
||||
#endif
|
||||
|
||||
////////// COMPILER & ENVIRONMENT
|
||||
|
||||
#pragma once
|
||||
#ifndef __cplusplus
|
||||
#error toml++ is a C++ library.
|
||||
#endif
|
||||
#ifndef TOML_DOXYGEN
|
||||
#define TOML_DOXYGEN 0
|
||||
|
||||
//#====================================================================================================================
|
||||
//# COMPILER DETECTION
|
||||
//#====================================================================================================================
|
||||
|
||||
#ifdef __INTELLISENSE__
|
||||
#define TOML_INTELLISENSE 1
|
||||
#else
|
||||
#define TOML_INTELLISENSE 0
|
||||
#endif
|
||||
#ifdef __clang__
|
||||
#define TOML_CLANG __clang_major__
|
||||
#else
|
||||
#define TOML_CLANG 0
|
||||
#endif
|
||||
#ifdef __INTEL_COMPILER
|
||||
#define TOML_ICC __INTEL_COMPILER
|
||||
#ifdef __ICL
|
||||
#define TOML_ICC_CL TOML_ICC
|
||||
#else
|
||||
#define TOML_ICC_CL 0
|
||||
#endif
|
||||
#else
|
||||
#define TOML_ICC 0
|
||||
#define TOML_ICC_CL 0
|
||||
#endif
|
||||
#if defined(_MSC_VER) && !TOML_CLANG && !TOML_ICC
|
||||
#define TOML_MSVC _MSC_VER
|
||||
#else
|
||||
#define TOML_MSVC 0
|
||||
#endif
|
||||
#if defined(__GNUC__) && !TOML_CLANG && !TOML_ICC
|
||||
#define TOML_GCC __GNUC__
|
||||
#else
|
||||
#define TOML_GCC 0
|
||||
#endif
|
||||
|
||||
//#====================================================================================================================
|
||||
//# CLANG
|
||||
//#====================================================================================================================
|
||||
|
||||
#if TOML_CLANG
|
||||
|
||||
#define TOML_PUSH_WARNINGS _Pragma("clang diagnostic push")
|
||||
#define TOML_DISABLE_SWITCH_WARNINGS _Pragma("clang diagnostic ignored \"-Wswitch\"")
|
||||
#define TOML_DISABLE_INIT_WARNINGS _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"")
|
||||
#define TOML_DISABLE_VTABLE_WARNINGS _Pragma("clang diagnostic ignored \"-Weverything\"") \
|
||||
_Pragma("clang diagnostic ignored \"-Wweak-vtables\"")
|
||||
#define TOML_DISABLE_PADDING_WARNINGS _Pragma("clang diagnostic ignored \"-Wpadded\"")
|
||||
#define TOML_DISABLE_FLOAT_WARNINGS _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \
|
||||
_Pragma("clang diagnostic ignored \"-Wdouble-promotion\"")
|
||||
#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\"")
|
||||
#define TOML_DISABLE_SHADOW_WARNINGS _Pragma("clang diagnostic ignored \"-Wshadow\"")
|
||||
#define TOML_DISABLE_ALL_WARNINGS _Pragma("clang diagnostic ignored \"-Weverything\"")
|
||||
#define TOML_DISABLE_SPAM_WARNINGS _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \
|
||||
_Pragma("clang diagnostic ignored \"-Wweak-template-vtables\"") \
|
||||
_Pragma("clang diagnostic ignored \"-Wpadded\"")
|
||||
#define TOML_POP_WARNINGS _Pragma("clang diagnostic pop")
|
||||
|
||||
#define TOML_DISABLE_WARNINGS TOML_PUSH_WARNINGS \
|
||||
_Pragma("clang diagnostic ignored \"-Weverything\"")
|
||||
#define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS
|
||||
#define TOML_ASSUME(cond) __builtin_assume(cond)
|
||||
#define TOML_UNREACHABLE __builtin_unreachable()
|
||||
#define TOML_ATTR(...) __attribute__((__VA_ARGS__))
|
||||
|
@ -100,11 +97,6 @@
|
|||
#define TOML_TRIVIAL_ABI __attribute__((__trivial_abi__))
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __EXCEPTIONS
|
||||
#define TOML_COMPILER_EXCEPTIONS 1
|
||||
#else
|
||||
#define TOML_COMPILER_EXCEPTIONS 0
|
||||
#endif
|
||||
#define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) )
|
||||
#define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) )
|
||||
|
||||
|
@ -113,15 +105,25 @@
|
|||
#define TOML_FLOAT_CHARCONV 0
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(__ICL))
|
||||
#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 1
|
||||
|
||||
#define TOML_PUSH_WARNINGS __pragma(warning(push))
|
||||
#define TOML_DISABLE_SWITCH_WARNINGS __pragma(warning(disable: 4063))
|
||||
#define TOML_DISABLE_ALL_WARNINGS __pragma(warning(pop)) \
|
||||
__pragma(warning(push, 0))
|
||||
#define TOML_POP_WARNINGS __pragma(warning(pop))
|
||||
#endif // clang
|
||||
|
||||
//#====================================================================================================================
|
||||
//# MSVC
|
||||
//#====================================================================================================================
|
||||
|
||||
#if TOML_MSVC || TOML_ICC_CL
|
||||
|
||||
#define TOML_CPP_VERSION _MSVC_LANG
|
||||
#define TOML_PUSH_WARNINGS __pragma(warning(push))
|
||||
#if TOML_MSVC // !intel-cl
|
||||
#define TOML_PUSH_WARNINGS __pragma(warning(push))
|
||||
#define TOML_DISABLE_SWITCH_WARNINGS __pragma(warning(disable: 4063))
|
||||
#define TOML_POP_WARNINGS __pragma(warning(pop))
|
||||
#define TOML_DISABLE_WARNINGS __pragma(warning(push, 0))
|
||||
#define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_ALWAYS_INLINE
|
||||
#define TOML_ALWAYS_INLINE __forceinline
|
||||
#endif
|
||||
|
@ -130,16 +132,31 @@
|
|||
#define TOML_UNREACHABLE __assume(0)
|
||||
#define TOML_INTERFACE __declspec(novtable)
|
||||
#define TOML_EMPTY_BASES __declspec(empty_bases)
|
||||
#if !defined(TOML_RELOPS_REORDERING) && defined(__cpp_impl_three_way_comparison)
|
||||
#define TOML_RELOPS_REORDERING 1
|
||||
#endif
|
||||
#ifdef _CPPUNWIND
|
||||
#define TOML_COMPILER_EXCEPTIONS 1
|
||||
#else
|
||||
#define TOML_COMPILER_EXCEPTIONS 0
|
||||
#endif
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#endif // msvc
|
||||
|
||||
//#====================================================================================================================
|
||||
//# ICC
|
||||
//#====================================================================================================================
|
||||
|
||||
#if TOML_ICC
|
||||
|
||||
#define TOML_PUSH_WARNINGS __pragma(warning(push))
|
||||
#define TOML_DISABLE_SPAM_WARNINGS __pragma(warning(disable: 82)) /* storage class is not first */ \
|
||||
__pragma(warning(disable: 111)) /* statement unreachable (false-positive) */ \
|
||||
__pragma(warning(disable: 1011)) /* missing return (false-positive) */ \
|
||||
__pragma(warning(disable: 2261)) /* assume expr side-effects discarded */
|
||||
#define TOML_POP_WARNINGS __pragma(warning(pop))
|
||||
#define TOML_DISABLE_WARNINGS __pragma(warning(push, 0))
|
||||
#define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS
|
||||
|
||||
#endif // icc
|
||||
|
||||
//#====================================================================================================================
|
||||
//# GCC
|
||||
//#====================================================================================================================
|
||||
|
||||
#if TOML_GCC
|
||||
|
||||
#define TOML_PUSH_WARNINGS _Pragma("GCC diagnostic push")
|
||||
#define TOML_DISABLE_SWITCH_WARNINGS _Pragma("GCC diagnostic ignored \"-Wswitch\"") \
|
||||
|
@ -148,22 +165,27 @@
|
|||
#define TOML_DISABLE_INIT_WARNINGS _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wuninitialized\"")
|
||||
#define TOML_DISABLE_PADDING_WARNINGS _Pragma("GCC diagnostic ignored \"-Wpadded\"")
|
||||
#define TOML_DISABLE_FLOAT_WARNINGS _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"")
|
||||
#define TOML_DISABLE_ARITHMETIC_WARNINGS _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"")
|
||||
#define TOML_DISABLE_SHADOW_WARNINGS _Pragma("GCC diagnostic ignored \"-Wshadow\"")
|
||||
#define TOML_DISABLE_SUGGEST_WARNINGS _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"")
|
||||
#define TOML_DISABLE_ALL_WARNINGS _Pragma("GCC diagnostic ignored \"-Wall\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wextra\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \
|
||||
#define TOML_DISABLE_SPAM_WARNINGS _Pragma("GCC diagnostic ignored \"-Wpadded\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wcast-align\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wcomment\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wtype-limits\"") \
|
||||
TOML_DISABLE_SUGGEST_WARNINGS \
|
||||
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"")
|
||||
#define TOML_POP_WARNINGS _Pragma("GCC diagnostic pop")
|
||||
#define TOML_DISABLE_WARNINGS TOML_PUSH_WARNINGS \
|
||||
_Pragma("GCC diagnostic ignored \"-Wall\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wextra\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
|
||||
TOML_DISABLE_SWITCH_WARNINGS \
|
||||
TOML_DISABLE_INIT_WARNINGS \
|
||||
TOML_DISABLE_PADDING_WARNINGS \
|
||||
TOML_DISABLE_FLOAT_WARNINGS \
|
||||
TOML_DISABLE_SHADOW_WARNINGS
|
||||
#define TOML_POP_WARNINGS _Pragma("GCC diagnostic pop")
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS \
|
||||
TOML_DISABLE_SHADOW_WARNINGS \
|
||||
TOML_DISABLE_SPAM_WARNINGS
|
||||
#define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS
|
||||
|
||||
#define TOML_ATTR(...) __attribute__((__VA_ARGS__))
|
||||
#ifndef TOML_ALWAYS_INLINE
|
||||
|
@ -171,14 +193,6 @@
|
|||
#endif
|
||||
#define TOML_NEVER_INLINE __attribute__((__noinline__))
|
||||
#define TOML_UNREACHABLE __builtin_unreachable()
|
||||
#if !defined(TOML_RELOPS_REORDERING) && defined(__cpp_impl_three_way_comparison)
|
||||
#define TOML_RELOPS_REORDERING 1
|
||||
#endif
|
||||
#ifdef __cpp_exceptions
|
||||
#define TOML_COMPILER_EXCEPTIONS 1
|
||||
#else
|
||||
#define TOML_COMPILER_EXCEPTIONS 0
|
||||
#endif
|
||||
#define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) )
|
||||
#define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) )
|
||||
|
||||
|
@ -189,10 +203,86 @@
|
|||
|
||||
#endif
|
||||
|
||||
//#====================================================================================================================
|
||||
//# USER CONFIGURATION
|
||||
//#====================================================================================================================
|
||||
|
||||
#ifdef TOML_CONFIG_HEADER
|
||||
#include TOML_CONFIG_HEADER
|
||||
#endif
|
||||
|
||||
#ifdef DOXYGEN
|
||||
#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
|
||||
#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
|
||||
|
||||
#if defined(TOML_IMPLEMENTATION) || TOML_HEADER_ONLY
|
||||
#undef TOML_IMPLEMENTATION
|
||||
#define TOML_IMPLEMENTATION 1
|
||||
#else
|
||||
#define TOML_IMPLEMENTATION 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_API
|
||||
#define TOML_API
|
||||
#endif
|
||||
|
||||
#ifndef TOML_UNRELEASED_FEATURES
|
||||
#define TOML_UNRELEASED_FEATURES 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_LARGE_FILES
|
||||
#define TOML_LARGE_FILES 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_UNDEF_MACROS
|
||||
#define TOML_UNDEF_MACROS 1
|
||||
#endif
|
||||
|
||||
#ifndef TOML_PARSER
|
||||
#define TOML_PARSER 1
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN
|
||||
#if defined(_WIN32) && !defined(TOML_WINDOWS_COMPAT)
|
||||
#define TOML_WINDOWS_COMPAT 1
|
||||
#endif
|
||||
#if !defined(_WIN32) || !defined(TOML_WINDOWS_COMPAT)
|
||||
#undef TOML_WINDOWS_COMPAT
|
||||
#define TOML_WINDOWS_COMPAT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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 can now work with char8_t strings implicitly so changing the underlying string type \
|
||||
is no longer necessary.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//#====================================================================================================================
|
||||
//# ATTRIBUTES, UTILITY MACROS ETC
|
||||
//#====================================================================================================================
|
||||
|
||||
#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
|
||||
|
@ -206,12 +296,22 @@
|
|||
#elif TOML_CPP_VERSION >= 201703L
|
||||
#define TOML_CPP 17
|
||||
#endif
|
||||
#undef TOML_CPP_VERSION
|
||||
|
||||
#ifndef TOML_COMPILER_EXCEPTIONS
|
||||
#ifdef __has_include
|
||||
#define TOML_HAS_INCLUDE(header) __has_include(header)
|
||||
#else
|
||||
#define TOML_HAS_INCLUDE(header) 0
|
||||
#endif
|
||||
|
||||
#if defined(__EXCEPTIONS) || defined(_CPPUNWIND) || defined(__cpp_exceptions)
|
||||
#define TOML_COMPILER_EXCEPTIONS 1
|
||||
#else
|
||||
#define TOML_COMPILER_EXCEPTIONS 0
|
||||
#endif
|
||||
#if TOML_COMPILER_EXCEPTIONS
|
||||
#ifndef TOML_EXCEPTIONS
|
||||
#if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS)
|
||||
#undef TOML_EXCEPTIONS
|
||||
#define TOML_EXCEPTIONS 1
|
||||
#endif
|
||||
#else
|
||||
|
@ -234,7 +334,7 @@
|
|||
#ifndef TOML_FLOAT_CHARCONV
|
||||
#define TOML_FLOAT_CHARCONV 1
|
||||
#endif
|
||||
#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !__has_include(<charconv>)
|
||||
#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !TOML_HAS_INCLUDE(<charconv>)
|
||||
#undef TOML_INT_CHARCONV
|
||||
#undef TOML_FLOAT_CHARCONV
|
||||
#define TOML_INT_CHARCONV 0
|
||||
|
@ -250,27 +350,24 @@
|
|||
#ifndef TOML_DISABLE_INIT_WARNINGS
|
||||
#define TOML_DISABLE_INIT_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_DISABLE_VTABLE_WARNINGS
|
||||
#define TOML_DISABLE_VTABLE_WARNINGS
|
||||
#ifndef TOML_DISABLE_SPAM_WARNINGS
|
||||
#define TOML_DISABLE_SPAM_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_DISABLE_PADDING_WARNINGS
|
||||
#define TOML_DISABLE_PADDING_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_DISABLE_FLOAT_WARNINGS
|
||||
#define TOML_DISABLE_FLOAT_WARNINGS
|
||||
#ifndef TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
#define TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_DISABLE_SHADOW_WARNINGS
|
||||
#define TOML_DISABLE_SHADOW_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_DISABLE_SUGGEST_WARNINGS
|
||||
#define TOML_DISABLE_SUGGEST_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_DISABLE_ALL_WARNINGS
|
||||
#define TOML_DISABLE_ALL_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_POP_WARNINGS
|
||||
#define TOML_POP_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_DISABLE_WARNINGS
|
||||
#define TOML_DISABLE_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_ENABLE_WARNINGS
|
||||
#define TOML_ENABLE_WARNINGS
|
||||
#endif
|
||||
|
||||
#ifndef TOML_ATTR
|
||||
#define TOML_ATTR(...)
|
||||
|
@ -284,10 +381,6 @@
|
|||
#define TOML_EMPTY_BASES
|
||||
#endif
|
||||
|
||||
#ifndef TOML_ALWAYS_INLINE
|
||||
#define TOML_ALWAYS_INLINE inline
|
||||
#endif
|
||||
|
||||
#ifndef TOML_NEVER_INLINE
|
||||
#define TOML_NEVER_INLINE
|
||||
#endif
|
||||
|
@ -308,14 +401,20 @@
|
|||
#define TOML_CONSTEVAL constexpr
|
||||
#endif
|
||||
|
||||
#if !TOML_DOXYGEN && !defined(__INTELLISENSE__)
|
||||
#if !defined(TOML_LIKELY) && __has_cpp_attribute(likely)
|
||||
#ifdef __has_cpp_attribute
|
||||
#define TOML_HAS_ATTR(...) __has_cpp_attribute(__VA_ARGS__)
|
||||
#else
|
||||
#define TOML_HAS_ATTR(...) 0
|
||||
#endif
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_INTELLISENSE
|
||||
#if !defined(TOML_LIKELY) && TOML_HAS_ATTR(likely)
|
||||
#define TOML_LIKELY(...) (__VA_ARGS__) [[likely]]
|
||||
#endif
|
||||
#if !defined(TOML_UNLIKELY) && __has_cpp_attribute(unlikely)
|
||||
#if !defined(TOML_UNLIKELY) && TOML_HAS_ATTR(unlikely)
|
||||
#define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]]
|
||||
#endif
|
||||
#if __has_cpp_attribute(nodiscard) >= 201907L
|
||||
#if TOML_HAS_ATTR(nodiscard) >= 201907L
|
||||
#define TOML_NODISCARD_CTOR [[nodiscard]]
|
||||
#endif
|
||||
#endif
|
||||
|
@ -334,32 +433,90 @@
|
|||
#define TOML_TRIVIAL_ABI
|
||||
#endif
|
||||
|
||||
#ifndef TOML_RELOPS_REORDERING
|
||||
#define TOML_RELOPS_REORDERING 0
|
||||
#endif
|
||||
#if TOML_RELOPS_REORDERING
|
||||
#define TOML_ASYMMETRICAL_EQUALITY_OPS(...)
|
||||
#else
|
||||
#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \
|
||||
__VA_ARGS__ [[nodiscard]] friend bool operator == (RHS rhs, LHS lhs) noexcept { return lhs == rhs; } \
|
||||
__VA_ARGS__ [[nodiscard]] friend bool operator != (LHS lhs, RHS rhs) noexcept { return !(lhs == rhs); } \
|
||||
__VA_ARGS__ [[nodiscard]] friend bool operator != (RHS rhs, LHS lhs) noexcept { return !(lhs == rhs); }
|
||||
|
||||
#ifndef TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 0
|
||||
#endif
|
||||
|
||||
#if TOML_ALL_INLINE
|
||||
#define TOML_EXTERNAL_LINKAGE inline
|
||||
#define TOML_INTERNAL_LINKAGE inline
|
||||
#define TOML_INTERNAL_NAMESPACE toml::impl
|
||||
#define TOML_CONCAT_1(x, y) x##y
|
||||
#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y)
|
||||
|
||||
#define TOML_EVAL_BOOL_1(T, F) T
|
||||
#define TOML_EVAL_BOOL_0(T, F) F
|
||||
|
||||
#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || defined(__ARM_64BIT_STATE) \
|
||||
|| defined(__arm__) || defined(_M_ARM) || defined(__ARM_32BIT_STATE)
|
||||
#define TOML_ARM 1
|
||||
#else
|
||||
#define TOML_EXTERNAL_LINKAGE
|
||||
#define TOML_INTERNAL_LINKAGE static
|
||||
#define TOML_INTERNAL_NAMESPACE
|
||||
#define TOML_ARM 0
|
||||
#endif
|
||||
|
||||
#define TOML_MAKE_BITOPS(type) \
|
||||
[[nodiscard]] \
|
||||
TOML_ALWAYS_INLINE \
|
||||
TOML_ATTR(const) \
|
||||
TOML_ATTR(flatten) \
|
||||
constexpr type operator & (type lhs, type rhs) noexcept \
|
||||
{ \
|
||||
return static_cast<type>(::toml::impl::unwrap_enum(lhs) & ::toml::impl::unwrap_enum(rhs)); \
|
||||
} \
|
||||
[[nodiscard]] \
|
||||
TOML_ALWAYS_INLINE \
|
||||
TOML_ATTR(const) \
|
||||
TOML_ATTR(flatten) \
|
||||
constexpr type operator | (type lhs, type rhs) noexcept \
|
||||
{ \
|
||||
return static_cast<type>(::toml::impl::unwrap_enum(lhs) | ::toml::impl::unwrap_enum(rhs)); \
|
||||
}
|
||||
|
||||
#ifndef TOML_LIFETIME_HOOKS
|
||||
#define TOML_LIFETIME_HOOKS 0
|
||||
#endif
|
||||
|
||||
//#====================================================================================================================
|
||||
//# EXTENDED INT AND FLOAT TYPES
|
||||
//#====================================================================================================================
|
||||
|
||||
#ifdef __FLT16_MANT_DIG__
|
||||
#if __FLT_RADIX__ == 2 \
|
||||
&& __FLT16_MANT_DIG__ == 11 \
|
||||
&& __FLT16_DIG__ == 3 \
|
||||
&& __FLT16_MIN_EXP__ == -13 \
|
||||
&& __FLT16_MIN_10_EXP__ == -4 \
|
||||
&& __FLT16_MAX_EXP__ == 16 \
|
||||
&& __FLT16_MAX_10_EXP__ == 4
|
||||
#if TOML_ARM && (TOML_GCC || TOML_CLANG)
|
||||
#define TOML_FP16 __fp16
|
||||
#endif
|
||||
#if TOML_ARM && TOML_CLANG // not present in g++
|
||||
#define TOML_FLOAT16 _Float16
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__SIZEOF_FLOAT128__) \
|
||||
&& defined(__FLT128_MANT_DIG__) \
|
||||
&& defined(__LDBL_MANT_DIG__) \
|
||||
&& __FLT128_MANT_DIG__ > __LDBL_MANT_DIG__
|
||||
#define TOML_FLOAT128 __float128
|
||||
#endif
|
||||
|
||||
#ifdef __SIZEOF_INT128__
|
||||
#define TOML_INT128 __int128_t
|
||||
#define TOML_UINT128 __uint128_t
|
||||
#endif
|
||||
|
||||
//#====================================================================================================================
|
||||
//# VERSIONS AND NAMESPACES
|
||||
//#====================================================================================================================
|
||||
|
||||
#include "toml_version.h"
|
||||
//# {{
|
||||
|
||||
#define TOML_LIB_SINGLE_HEADER 0
|
||||
//# }}
|
||||
|
||||
#define TOML_MAKE_VERSION(maj, min, rev) \
|
||||
((maj) * 1000 + (min) * 25 + (rev))
|
||||
|
@ -381,37 +538,69 @@
|
|||
#define TOML_LANG_UNRELEASED \
|
||||
TOML_LANG_HIGHER_THAN(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH)
|
||||
|
||||
#if TOML_DOXYGEN || defined(__INTELLISENSE__)
|
||||
#ifndef TOML_ABI_NAMESPACES
|
||||
#ifdef DOXYGEN
|
||||
#define TOML_ABI_NAMESPACES 0
|
||||
#define TOML_ABI_NAMESPACE_START(name)
|
||||
#define TOML_ABI_NAMESPACE_END
|
||||
#else
|
||||
#define TOML_ABI_NAMESPACES 1
|
||||
#define TOML_ABI_NAMESPACE_START(name) inline namespace abi_##name {
|
||||
#endif
|
||||
#endif
|
||||
#if TOML_ABI_NAMESPACES
|
||||
#define TOML_NAMESPACE_START namespace toml { inline namespace TOML_CONCAT(v, TOML_LIB_MAJOR)
|
||||
#define TOML_NAMESPACE_END }
|
||||
#define TOML_NAMESPACE ::toml::TOML_CONCAT(v, TOML_LIB_MAJOR)
|
||||
#define TOML_ABI_NAMESPACE_START(name) inline namespace name {
|
||||
#define TOML_ABI_NAMESPACE_BOOL(cond, T, F) TOML_ABI_NAMESPACE_START(TOML_CONCAT(TOML_EVAL_BOOL_, cond)(T, F))
|
||||
#define TOML_ABI_NAMESPACE_END }
|
||||
#else
|
||||
#define TOML_NAMESPACE_START namespace toml
|
||||
#define TOML_NAMESPACE_END
|
||||
#define TOML_NAMESPACE toml
|
||||
#define TOML_ABI_NAMESPACE_START(...)
|
||||
#define TOML_ABI_NAMESPACE_BOOL(...)
|
||||
#define TOML_ABI_NAMESPACE_END
|
||||
#endif
|
||||
#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_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_END
|
||||
#define TOML_ANON_NAMESPACE
|
||||
#define TOML_USING_ANON_NAMESPACE (void)0
|
||||
#define TOML_EXTERNAL_LINKAGE
|
||||
#define TOML_INTERNAL_LINKAGE static
|
||||
#endif
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
//#====================================================================================================================
|
||||
//# ASSERT
|
||||
//#====================================================================================================================
|
||||
|
||||
TOML_DISABLE_WARNINGS
|
||||
#ifndef TOML_ASSERT
|
||||
#if defined(NDEBUG) || !defined(_DEBUG)
|
||||
#define TOML_ASSERT(expr) (void)0
|
||||
#else
|
||||
#ifndef assert
|
||||
#include <cassert>
|
||||
#endif
|
||||
#define TOML_ASSERT(expr) assert(expr)
|
||||
#endif
|
||||
#endif
|
||||
TOML_POP_WARNINGS
|
||||
TOML_ENABLE_WARNINGS
|
||||
|
||||
#if TOML_CHAR_8_STRINGS
|
||||
#define TOML_STRING_PREFIX_1(S) u8##S
|
||||
#define TOML_STRING_PREFIX(S) TOML_STRING_PREFIX_1(S)
|
||||
#else
|
||||
#define TOML_STRING_PREFIX(S) S
|
||||
#endif
|
||||
//#====================================================================================================================
|
||||
//# DOXYGEN SPAM
|
||||
//#====================================================================================================================
|
||||
|
||||
//# {{
|
||||
#if TOML_DOXYGEN
|
||||
#ifdef DOXYGEN
|
||||
|
||||
/// \addtogroup configuration Library Configuration
|
||||
/// \brief Preprocessor macros for configuring library functionality.
|
||||
|
@ -421,14 +610,14 @@ TOML_POP_WARNINGS
|
|||
/// @{
|
||||
|
||||
|
||||
/// \def TOML_ALL_INLINE
|
||||
/// \def TOML_HEADER_ONLY
|
||||
/// \brief Sets whether the library is entirely inline.
|
||||
/// \detail Defaults to `1`.
|
||||
/// \remark Disabling this means that you must define `TOML_IMPLEMENTATION` in
|
||||
/// \remark Disabling this means that you must define #TOML_IMPLEMENTATION in
|
||||
/// <strong><em>exactly one</em></strong> translation unit in your project:
|
||||
/// \cpp
|
||||
/// // global_header_that_includes_toml++.h
|
||||
/// #define TOML_ALL_INLINE 0
|
||||
/// #define TOML_HEADER_ONLY 0
|
||||
/// #include <toml.hpp>
|
||||
///
|
||||
/// // some_code_file.cpp
|
||||
|
@ -450,11 +639,6 @@ TOML_POP_WARNINGS
|
|||
/// \detail Defaults to the standard C `assert()`.
|
||||
|
||||
|
||||
/// \def TOML_CHAR_8_STRINGS
|
||||
/// \brief Uses C++20 char8_t-based strings as the toml string data type.
|
||||
/// \detail Defaults to `0`.
|
||||
|
||||
|
||||
#define TOML_CONFIG_HEADER
|
||||
/// \def TOML_CONFIG_HEADER
|
||||
/// \brief An additional header to include before any other toml++ header files.
|
||||
|
@ -467,8 +651,8 @@ TOML_POP_WARNINGS
|
|||
|
||||
|
||||
/// \def TOML_IMPLEMENTATION
|
||||
/// \brief Enables the library's implementation when #TOML_ALL_INLINE is enabled.
|
||||
/// \detail Not defined by default. Meaningless when #TOML_ALL_INLINE is disabled.
|
||||
/// \brief Enables the library's implementation when #TOML_HEADER_ONLY is enabled.
|
||||
/// \detail Not defined by default. Meaningless when #TOML_HEADER_ONLY is disabled.
|
||||
|
||||
|
||||
/// \def TOML_LARGE_FILES
|
||||
|
@ -497,7 +681,8 @@ TOML_POP_WARNINGS
|
|||
/// \def TOML_SMALL_FLOAT_TYPE
|
||||
/// \brief If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it.
|
||||
/// \detail Not defined by default.
|
||||
|
||||
/// \attention If you're building for a platform that has a built-in half precision float (e.g. `_Float16`), you don't
|
||||
/// need to use this configuration option to make toml++ aware of it; the library comes with that built-in.
|
||||
|
||||
#define TOML_SMALL_INT_TYPE
|
||||
/// \def TOML_SMALL_INT_TYPE
|
||||
|
@ -512,8 +697,21 @@ TOML_POP_WARNINGS
|
|||
/// \see [TOML Language Support](https://github.com/marzer/tomlplusplus/blob/master/README.md#toml-language-support)
|
||||
|
||||
|
||||
/// \def TOML_WINDOWS_COMPAT
|
||||
/// \brief Enables the use of wide strings (wchar_t, std::wstring) in various places throughout the library
|
||||
/// when building for Windows.
|
||||
/// \detail Defaults to `1` when building for Windows, `0` otherwise. Has no effect when building for anything other
|
||||
/// than Windows.
|
||||
/// \attention This <strong>does not</strong> change the underlying string type used to represent TOML keys and string
|
||||
/// values; that will still be std::string. This setting simply enables some narrow <=> wide string
|
||||
/// conversions when necessary at various interface boundaries.
|
||||
/// <br><br>
|
||||
/// If you're building for Windows and you have no need for Windows' "Pretends-to-be-unicode" wide strings,
|
||||
/// you can safely set this to `0`.
|
||||
|
||||
|
||||
/// @}
|
||||
#endif // TOML_DOXYGEN
|
||||
#endif // DOXYGEN
|
||||
//# }}
|
||||
|
||||
// clang-format on
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
#include "toml_date_time.h"
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
TOML_DISABLE_WARNINGS
|
||||
#include <cmath>
|
||||
#if TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV
|
||||
#include <charconv>
|
||||
|
@ -17,9 +16,12 @@ TOML_DISABLE_ALL_WARNINGS
|
|||
#if !TOML_INT_CHARCONV
|
||||
#include <iomanip>
|
||||
#endif
|
||||
TOML_POP_WARNINGS
|
||||
TOML_ENABLE_WARNINGS
|
||||
|
||||
namespace toml::impl
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
// Q: "why does print_to_stream() exist? why not just use ostream::write(), ostream::put() etc?"
|
||||
// A: - I'm supporting C++20's char8_t as well; wrapping streams allows switching string modes transparently.
|
||||
|
@ -34,8 +36,7 @@ namespace toml::impl
|
|||
// - Strings in C++. Honestly.
|
||||
|
||||
template <typename Char1, typename Char2>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(std::basic_string_view<Char1> str, std::basic_ostream<Char2>& stream)
|
||||
inline void print_to_stream(std::basic_string_view<Char1> str, std::basic_ostream<Char2>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char1) == 1);
|
||||
static_assert(sizeof(Char2) == 1);
|
||||
|
@ -43,8 +44,7 @@ namespace toml::impl
|
|||
}
|
||||
|
||||
template <typename Char1, typename Char2>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(const std::basic_string<Char1>& str, std::basic_ostream<Char2>& stream)
|
||||
inline void print_to_stream(const std::basic_string<Char1>& str, std::basic_ostream<Char2>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char1) == 1);
|
||||
static_assert(sizeof(Char2) == 1);
|
||||
|
@ -52,8 +52,7 @@ namespace toml::impl
|
|||
}
|
||||
|
||||
template <typename Char>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(char character, std::basic_ostream<Char>& stream)
|
||||
inline void print_to_stream(char character, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.put(static_cast<Char>(character));
|
||||
|
@ -61,18 +60,16 @@ namespace toml::impl
|
|||
|
||||
template <typename Char>
|
||||
TOML_ATTR(nonnull)
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(const char* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
inline void print_to_stream(const char* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.write(reinterpret_cast<const Char*>(str), static_cast<std::streamsize>(len));
|
||||
}
|
||||
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
template <typename Char>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(char8_t character, std::basic_ostream<Char>& stream)
|
||||
inline void print_to_stream(char8_t character, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.put(static_cast<Char>(character));
|
||||
|
@ -80,8 +77,7 @@ namespace toml::impl
|
|||
|
||||
template <typename Char>
|
||||
TOML_ATTR(nonnull)
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(const char8_t* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
inline void print_to_stream(const char8_t* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.write(reinterpret_cast<const Char*>(str), static_cast<std::streamsize>(len));
|
||||
|
@ -102,39 +98,85 @@ namespace toml::impl
|
|||
template <> inline constexpr size_t charconv_buffer_length<uint8_t> = 3; // strlen("255")
|
||||
|
||||
template <typename T, typename Char>
|
||||
inline void print_integer_to_stream(T val, std::basic_ostream<Char>& stream)
|
||||
inline void print_integer_to_stream(T val, std::basic_ostream<Char>& stream, value_flags format = {})
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
if (!val)
|
||||
{
|
||||
print_to_stream('0', stream);
|
||||
return;
|
||||
}
|
||||
|
||||
int base = 10;
|
||||
if (format != value_flags::none && val >= T{})
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case value_flags::format_as_binary: base = 2; break;
|
||||
case value_flags::format_as_octal: base = 8; break;
|
||||
case value_flags::format_as_hexadecimal: base = 16; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#if TOML_INT_CHARCONV
|
||||
|
||||
char buf[charconv_buffer_length<T>];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
|
||||
{
|
||||
char buf[(sizeof(T) * CHAR_BIT)];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), val, base);
|
||||
const auto len = static_cast<size_t>(res.ptr - buf);
|
||||
if (base == 16)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++)
|
||||
if (buf[i] >= 'a')
|
||||
buf[i] -= 32;
|
||||
}
|
||||
print_to_stream(buf, len, stream);
|
||||
|
||||
}
|
||||
#else
|
||||
{
|
||||
using unsigned_type = std::conditional_t<(sizeof(T) > sizeof(unsigned)), std::make_unsigned_t<T>, unsigned>;
|
||||
using cast_type = std::conditional_t<std::is_signed_v<T>, std::make_signed_t<unsigned_type>, unsigned_type>;
|
||||
|
||||
if TOML_UNLIKELY(format == value_flags::format_as_binary)
|
||||
{
|
||||
bool found_one = false;
|
||||
const auto v = static_cast<unsigned_type>(val);
|
||||
unsigned_type mask = unsigned_type{ 1 } << (sizeof(unsigned_type) * CHAR_BIT - 1u);
|
||||
for (unsigned i = 0; i < sizeof(unsigned_type) * CHAR_BIT; i++)
|
||||
{
|
||||
if ((v & mask))
|
||||
{
|
||||
print_to_stream('1', stream);
|
||||
found_one = true;
|
||||
}
|
||||
else if (found_one)
|
||||
print_to_stream('0', stream);
|
||||
mask >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
using cast_type = std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>;
|
||||
ss << std::uppercase << std::setbase(base);
|
||||
ss << static_cast<cast_type>(val);
|
||||
const auto str = std::move(ss).str();
|
||||
print_to_stream(str, stream);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define TOML_P2S_OVERLOAD(Type) \
|
||||
template <typename Char> \
|
||||
TOML_ALWAYS_INLINE \
|
||||
void print_to_stream(Type val, std::basic_ostream<Char>& stream) \
|
||||
inline void print_to_stream(Type val, std::basic_ostream<Char>& stream, value_flags format) \
|
||||
{ \
|
||||
static_assert(sizeof(Char) == 1); \
|
||||
print_integer_to_stream(val, stream); \
|
||||
print_integer_to_stream(val, stream, format); \
|
||||
}
|
||||
|
||||
TOML_P2S_OVERLOAD(int8_t)
|
||||
|
@ -149,27 +191,28 @@ namespace toml::impl
|
|||
#undef TOML_P2S_OVERLOAD
|
||||
|
||||
template <typename T, typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_floating_point_to_stream(T val, std::basic_ostream<Char>& stream, bool hexfloat = false)
|
||||
inline void print_floating_point_to_stream(T val, std::basic_ostream<Char>& stream, bool hexfloat = false)
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
switch (std::fpclassify(val))
|
||||
switch (impl::fpclassify(val))
|
||||
{
|
||||
case FP_INFINITE:
|
||||
if (val < T{})
|
||||
print_to_stream('-', stream);
|
||||
case fp_class::neg_inf:
|
||||
print_to_stream("-inf"sv, stream);
|
||||
break;
|
||||
|
||||
case fp_class::pos_inf:
|
||||
print_to_stream("inf"sv, stream);
|
||||
return;
|
||||
break;
|
||||
|
||||
case FP_NAN:
|
||||
case fp_class::nan:
|
||||
print_to_stream("nan"sv, stream);
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
case fp_class::ok:
|
||||
{
|
||||
static constexpr auto needs_decimal_point = [](auto&& s) noexcept
|
||||
{
|
||||
|
@ -204,32 +247,32 @@ namespace toml::impl
|
|||
print_to_stream(".0"sv, stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API void print_floating_point_to_stream(float, std::ostream&, bool);
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API void print_floating_point_to_stream(double, std::ostream&, bool);
|
||||
#endif
|
||||
|
||||
#define TOML_P2S_OVERLOAD(Type) \
|
||||
template <typename Char> \
|
||||
TOML_ALWAYS_INLINE \
|
||||
void print_to_stream(Type val, std::basic_ostream<Char>& stream) \
|
||||
inline void print_to_stream(Type val, std::basic_ostream<Char>& stream) \
|
||||
{ \
|
||||
static_assert(sizeof(Char) == 1); \
|
||||
print_floating_point_to_stream(val, stream); \
|
||||
}
|
||||
|
||||
TOML_P2S_OVERLOAD(float)
|
||||
TOML_P2S_OVERLOAD(double)
|
||||
|
||||
#undef TOML_P2S_OVERLOAD
|
||||
|
||||
template <typename Char>
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(bool val, std::basic_ostream<Char>& stream)
|
||||
inline void print_to_stream(bool val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
print_to_stream(val ? "true"sv : "false"sv, stream);
|
||||
|
@ -330,12 +373,12 @@ namespace toml::impl
|
|||
print_to_stream(val.date, stream);
|
||||
print_to_stream('T', stream);
|
||||
print_to_stream(val.time, stream);
|
||||
if (val.time_offset)
|
||||
print_to_stream(*val.time_offset, stream);
|
||||
if (val.offset)
|
||||
print_to_stream(*val.offset, stream);
|
||||
}
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
|
||||
template <typename T, typename Char>
|
||||
void print_to_stream_with_escapes(T && str, std::basic_ostream<Char>& stream)
|
||||
|
@ -343,24 +386,24 @@ namespace toml::impl
|
|||
static_assert(sizeof(Char) == 1);
|
||||
for (auto c : str)
|
||||
{
|
||||
if TOML_UNLIKELY(c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F'))
|
||||
if TOML_UNLIKELY(c >= '\x00' && c <= '\x1F')
|
||||
print_to_stream(low_character_escape_table[c], stream);
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('\x7F'))
|
||||
print_to_stream(TOML_STRING_PREFIX("\\u007F"sv), stream);
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('"'))
|
||||
print_to_stream(TOML_STRING_PREFIX("\\\""sv), stream);
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('\\'))
|
||||
print_to_stream(TOML_STRING_PREFIX("\\\\"sv), stream);
|
||||
else if TOML_UNLIKELY(c == '\x7F')
|
||||
print_to_stream("\\u007F"sv, stream);
|
||||
else if TOML_UNLIKELY(c == '"')
|
||||
print_to_stream("\\\""sv, stream);
|
||||
else if TOML_UNLIKELY(c == '\\')
|
||||
print_to_stream("\\\\"sv, stream);
|
||||
else
|
||||
print_to_stream(c, stream);
|
||||
}
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief Prints a source_position to a stream.
|
||||
///
|
||||
|
@ -369,7 +412,7 @@ namespace toml
|
|||
///
|
||||
/// std::cout << "The value for 'bar' was found on "sv
|
||||
/// << tbl.get("bar")->source().begin()
|
||||
/// << std::endl;
|
||||
/// << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -383,8 +426,7 @@ namespace toml
|
|||
///
|
||||
/// \returns The input stream.
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const source_position& rhs)
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const source_position& rhs)
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
|
@ -404,7 +446,7 @@ namespace toml
|
|||
///
|
||||
/// std::cout << "The value for 'bar' was found on "sv
|
||||
/// << tbl.get("bar")->source()
|
||||
/// << std::endl;
|
||||
/// << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
|
@ -418,8 +460,7 @@ namespace toml
|
|||
///
|
||||
/// \returns The input stream.
|
||||
template <typename Char>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const source_region& rhs)
|
||||
inline std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const source_region& rhs)
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
|
@ -435,8 +476,11 @@ namespace toml
|
|||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const source_position&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const source_region&);
|
||||
#endif
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,42 +14,104 @@
|
|||
#include "toml_table.h"
|
||||
#include "toml_node_view.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_SUGGEST_WARNINGS
|
||||
|
||||
namespace toml
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void table::lh_ctor() noexcept
|
||||
{
|
||||
TOML_TABLE_CREATED;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void table::lh_dtor() noexcept
|
||||
{
|
||||
TOML_TABLE_DESTROYED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table() noexcept
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_ctor();
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table(const table& other) noexcept
|
||||
: node{ std::move(other) },
|
||||
inline_{ other.inline_ }
|
||||
{
|
||||
for (auto&& [k, v] : other)
|
||||
map.emplace_hint(map.end(), k, impl::make_node(v));
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_ctor();
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table(table&& other) noexcept
|
||||
: node{ std::move(other) },
|
||||
map{ std::move(other.map) },
|
||||
inline_{ other.inline_ }
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_ctor();
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table& table::operator= (const table& rhs) noexcept
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
node::operator=(rhs);
|
||||
map.clear();
|
||||
for (auto&& [k, v] : rhs)
|
||||
map.emplace_hint(map.end(), k, impl::make_node(v));
|
||||
inline_ = rhs.inline_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table& table::operator= (table&& rhs) noexcept
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
node::operator=(std::move(rhs));
|
||||
map = std::move(rhs.map);
|
||||
inline_ = rhs.inline_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::~table() noexcept
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_dtor();
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table(impl::table_init_pair* pairs, size_t count) noexcept
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
values.insert_or_assign(
|
||||
if (!pairs[i].value) // empty node_views
|
||||
continue;
|
||||
map.insert_or_assign(
|
||||
std::move(pairs[i].key),
|
||||
std::move(pairs[i].value)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table() noexcept {}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table(table&& other) noexcept
|
||||
: node{ std::move(other) },
|
||||
values{ std::move(other.values) },
|
||||
inline_{ other.inline_ }
|
||||
{}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table& table::operator = (table&& rhs) noexcept
|
||||
{
|
||||
node::operator=(std::move(rhs));
|
||||
values = std::move(rhs.values);
|
||||
inline_ = rhs.inline_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#define TOML_MEMBER_ATTR(attr) TOML_EXTERNAL_LINKAGE TOML_ATTR(attr)
|
||||
|
||||
TOML_MEMBER_ATTR(const) node_type table::type() const noexcept { return node_type::table; }
|
||||
|
@ -62,99 +124,207 @@ namespace toml
|
|||
TOML_MEMBER_ATTR(pure) bool table::is_inline() const noexcept { return inline_; }
|
||||
TOML_EXTERNAL_LINKAGE void table::is_inline(bool val) noexcept { inline_ = val; }
|
||||
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::begin() const noexcept { return { values.begin() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::end() const noexcept { return { values.end() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::cbegin() const noexcept { return { values.cbegin() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::cend() const noexcept { return { values.cend() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::iterator table::begin() noexcept { return { values.begin() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::iterator table::end() noexcept { return { values.end() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::begin() const noexcept { return { map.begin() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::end() const noexcept { return { map.end() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::cbegin() const noexcept { return { map.cbegin() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::cend() const noexcept { return { map.cend() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::iterator table::begin() noexcept { return { map.begin() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::iterator table::end() noexcept { return { map.end() }; }
|
||||
|
||||
TOML_MEMBER_ATTR(pure) bool table::empty() const noexcept { return values.empty(); }
|
||||
TOML_MEMBER_ATTR(pure) size_t table::size() const noexcept { return values.size(); }
|
||||
TOML_EXTERNAL_LINKAGE void table::clear() noexcept { values.clear(); }
|
||||
TOML_MEMBER_ATTR(pure) bool table::empty() const noexcept { return map.empty(); }
|
||||
TOML_MEMBER_ATTR(pure) size_t table::size() const noexcept { return map.size(); }
|
||||
TOML_EXTERNAL_LINKAGE void table::clear() noexcept { map.clear(); }
|
||||
|
||||
#undef TOML_MEMBER_ATTR
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<node> table::operator[] (string_view key) noexcept
|
||||
bool table::is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
return { this->get(key) };
|
||||
if (map.empty())
|
||||
return false;
|
||||
|
||||
if (ntype == node_type::none)
|
||||
ntype = map.cbegin()->second->type();
|
||||
|
||||
for (const auto& [k, v] : map)
|
||||
{
|
||||
(void)k;
|
||||
if (v->type() != ntype)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool table_is_homogeneous(T& map, node_type ntype, U& first_nonmatch) noexcept
|
||||
{
|
||||
if (map.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = map.cbegin()->second->type();
|
||||
for (const auto& [k, v] : map)
|
||||
{
|
||||
(void)k;
|
||||
if (v->type() != ntype)
|
||||
{
|
||||
first_nonmatch = v.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype, toml::node*& first_nonmatch) noexcept
|
||||
{
|
||||
return impl::table_is_homogeneous(map, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::table_is_homogeneous(map, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<node> table::operator[] (std::string_view key) noexcept
|
||||
{
|
||||
return node_view<node>{ this->get(key) };
|
||||
}
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<const node> table::operator[] (string_view key) const noexcept
|
||||
node_view<const node> table::operator[] (std::string_view key) const noexcept
|
||||
{
|
||||
return { this->get(key) };
|
||||
return node_view<const node>{ this->get(key) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::erase(iterator pos) noexcept
|
||||
{
|
||||
return { values.erase(pos.raw_) };
|
||||
return { map.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::erase(const_iterator pos) noexcept
|
||||
{
|
||||
return { values.erase(pos.raw_) };
|
||||
return { map.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::erase(const_iterator first, const_iterator last) noexcept
|
||||
{
|
||||
return { values.erase(first.raw_, last.raw_) };
|
||||
return { map.erase(first.raw_, last.raw_) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::erase(string_view key) noexcept
|
||||
bool table::erase(std::string_view key) noexcept
|
||||
{
|
||||
if (auto it = values.find(key); it != values.end())
|
||||
if (auto it = map.find(key); it != map.end())
|
||||
{
|
||||
values.erase(it);
|
||||
map.erase(it);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node* table::get(string_view key) noexcept
|
||||
node* table::get(std::string_view key) noexcept
|
||||
{
|
||||
return do_get(values, key);
|
||||
return do_get(map, key);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const node* table::get(string_view key) const noexcept
|
||||
const node* table::get(std::string_view key) const noexcept
|
||||
{
|
||||
return do_get(values, key);
|
||||
return do_get(map, key);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::find(string_view key) noexcept
|
||||
table::iterator table::find(std::string_view key) noexcept
|
||||
{
|
||||
return { values.find(key) };
|
||||
return { map.find(key) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::const_iterator table::find(string_view key) const noexcept
|
||||
table::const_iterator table::find(std::string_view key) const noexcept
|
||||
{
|
||||
return { values.find(key) };
|
||||
return { map.find(key) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::contains(string_view key) const noexcept
|
||||
bool table::contains(std::string_view key) const noexcept
|
||||
{
|
||||
return do_contains(values, key);
|
||||
return do_contains(map, key);
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<node> table::operator[] (std::wstring_view key) noexcept
|
||||
{
|
||||
return node_view<node>{ this->get(key) };
|
||||
}
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<const node> table::operator[] (std::wstring_view key) const noexcept
|
||||
{
|
||||
return node_view<const node>{ this->get(key) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::erase(std::wstring_view key) noexcept
|
||||
{
|
||||
return erase(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node* table::get(std::wstring_view key) noexcept
|
||||
{
|
||||
return get(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const node* table::get(std::wstring_view key) const noexcept
|
||||
{
|
||||
return get(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::find(std::wstring_view key) noexcept
|
||||
{
|
||||
return find(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::const_iterator table::find(std::wstring_view key) const noexcept
|
||||
{
|
||||
return find(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::contains(std::wstring_view key) const noexcept
|
||||
{
|
||||
return contains(impl::narrow(key));
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator == (const table& lhs, const table& rhs) noexcept
|
||||
{
|
||||
if (&lhs == &rhs)
|
||||
return true;
|
||||
if (lhs.values.size() != rhs.values.size())
|
||||
if (lhs.map.size() != rhs.map.size())
|
||||
return false;
|
||||
|
||||
for (auto l = lhs.values.begin(), r = rhs.values.begin(), e = lhs.values.end(); l != e; l++, r++)
|
||||
for (auto l = lhs.map.begin(), r = rhs.map.begin(), e = lhs.map.end(); l != e; l++, r++)
|
||||
{
|
||||
if (l->first != r->first)
|
||||
return false;
|
||||
|
@ -182,5 +352,5 @@ namespace toml
|
|||
return !(lhs == rhs);
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SUGGEST_WARNINGS
|
||||
|
|
|
@ -1,26 +1,15 @@
|
|||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de> (utf8_decoder)
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
#include "toml_utf8_generated.h"
|
||||
#ifndef DOXYGEN
|
||||
|
||||
namespace toml::impl
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
template <typename... T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_match(char32_t codepoint, T... vals) noexcept
|
||||
{
|
||||
static_assert((std::is_same_v<char32_t, T> && ...));
|
||||
return ((codepoint == vals) || ...);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_ascii_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'\t' || codepoint == U' ';
|
||||
|
@ -28,7 +17,7 @@ namespace toml::impl
|
|||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_unicode_whitespace(char32_t codepoint) noexcept
|
||||
constexpr bool is_non_ascii_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
// see: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
// (characters that don't say "is a line-break")
|
||||
|
@ -46,13 +35,12 @@ namespace toml::impl
|
|||
TOML_ATTR(const)
|
||||
constexpr bool is_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_whitespace(codepoint) || is_unicode_whitespace(codepoint);
|
||||
return is_ascii_whitespace(codepoint) || is_non_ascii_whitespace(codepoint);
|
||||
}
|
||||
|
||||
template <bool IncludeCarriageReturn = true>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_ascii_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
constexpr auto low_range_end = IncludeCarriageReturn ? U'\r' : U'\f';
|
||||
|
@ -61,7 +49,7 @@ namespace toml::impl
|
|||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_unicode_line_break(char32_t codepoint) noexcept
|
||||
constexpr bool is_non_ascii_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
// see https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
// (characters that say "is a line-break")
|
||||
|
@ -77,12 +65,11 @@ namespace toml::impl
|
|||
TOML_ATTR(const)
|
||||
constexpr bool is_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_line_break<IncludeCarriageReturn>(codepoint) || is_unicode_line_break(codepoint);
|
||||
return is_ascii_line_break<IncludeCarriageReturn>(codepoint) || is_non_ascii_line_break(codepoint);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_string_delimiter(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'"' || codepoint == U'\'';
|
||||
|
@ -90,7 +77,6 @@ namespace toml::impl
|
|||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_ascii_letter(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'a' && codepoint <= U'z')
|
||||
|
@ -99,7 +85,6 @@ namespace toml::impl
|
|||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_binary_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'0' || codepoint == U'1';
|
||||
|
@ -107,7 +92,6 @@ namespace toml::impl
|
|||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_octal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'0' && codepoint <= U'7');
|
||||
|
@ -115,16 +99,21 @@ namespace toml::impl
|
|||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_decimal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'0' && codepoint <= U'9');
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_hexadecimal_digit(char32_t c) noexcept
|
||||
{
|
||||
return U'0' <= c && c <= U'f' && (1ull << (static_cast<uint_least64_t>(c) - 0x30u)) & 0x7E0000007E03FFull;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr std::uint_least32_t hex_to_dec(const T codepoint) noexcept
|
||||
{
|
||||
if constexpr (std::is_same_v<remove_cvref_t<T>, std::uint_least32_t>)
|
||||
|
@ -136,6 +125,730 @@ namespace toml::impl
|
|||
return hex_to_dec(static_cast<std::uint_least32_t>(codepoint));
|
||||
}
|
||||
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories:
|
||||
//# Ll, Lm, Lo, Lt, Lu
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_non_ascii_letter(char32_t c) noexcept
|
||||
{
|
||||
if (U'\xAA' > c || c > U'\U0003134A')
|
||||
return false;
|
||||
|
||||
const auto child_index_0 = (static_cast<uint_least64_t>(c) - 0xAAull) / 0xC4Bull;
|
||||
if ((1ull << child_index_0) & 0x26180C0000ull)
|
||||
return false;
|
||||
if ((1ull << child_index_0) & 0x8A7FFC004001CFA0ull)
|
||||
return true;
|
||||
switch (child_index_0)
|
||||
{
|
||||
case 0x00: // [0] 00AA - 0CF4
|
||||
{
|
||||
if (c > U'\u0CF2')
|
||||
return false;
|
||||
TOML_ASSUME(U'\xAA' <= c);
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFDFFFFFC10801u, 0xFFFFFFFFFFFFDFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0x07C000FFF0FFFFFFu, 0x0000000000000014u, 0x0000000000000000u, 0xFEFFFFF5D02F37C0u,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFEFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFF00FFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFC09FFFFFFFFFBFu, 0x000000007FFFFFFFu,
|
||||
0xFFFFFFC000000000u, 0xFFC00000000001E1u, 0x00000001FFFFFFFFu, 0xFFFFFFFFFFFFFFB0u,
|
||||
0x18000BFFFFFFFFFFu, 0xFFFFFF4000270030u, 0xFFFFFFF80000003Fu, 0x0FFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFF00000080u, 0x44010FFFFFC10C01u, 0xFFC07FFFFFC00000u, 0xFFC0000000000001u,
|
||||
0x000000003FFFF7FFu, 0xFFFFFFFFFC000000u, 0x00FFC0400008FFFFu, 0x7FFFFE67F87FFF80u,
|
||||
0x00EC00100008F17Fu, 0x7FFFFE61F80400C0u, 0x001780000000DB7Fu, 0x7FFFFEEFF8000700u,
|
||||
0x00C000400008FB7Fu, 0x7FFFFE67F8008000u, 0x00EC00000008FB7Fu, 0xC6358F71FA000080u,
|
||||
0x000000400000FFF1u, 0x7FFFFF77F8000000u, 0x00C1C0000008FFFFu, 0x7FFFFF77F8400000u,
|
||||
0x00D000000008FBFFu, 0x0000000000000180u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xAAull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0xAAull) % 0x40ull));
|
||||
// 1922 code units from 124 ranges (spanning a search area of 3145)
|
||||
}
|
||||
case 0x01: // [1] 0CF5 - 193F
|
||||
{
|
||||
if (U'\u0D04' > c || c > U'\u191E')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x027FFFFFFFFFDDFFu, 0x0FC0000038070400u, 0xF2FFBFFFFFC7FFFEu, 0xE000000000000007u,
|
||||
0xF000DFFFFFFFFFFFu, 0x6000000000000007u, 0xF200DFFAFFFFFF7Du, 0x100000000F000005u,
|
||||
0xF000000000000000u, 0x000001FFFFFFFFEFu, 0x00000000000001F0u, 0xF000000000000000u,
|
||||
0x0800007FFFFFFFFFu, 0x3FFE1C0623C3F000u, 0xFFFFFFFFF0000400u, 0xFF7FFFFFFFFFF20Bu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFF3D7F3DFu, 0xD7F3DFFFFFFFF3DFu, 0xFFFFFFFFFFF7FFF3u,
|
||||
0xFFFFFFFFFFF3DFFFu, 0xF0000000007FFFFFu, 0xFFFFFFFFF0000FFFu, 0xE3F3FFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xEFFFF9FFFFFFFFFFu, 0xFFFFFFFFF07FFFFFu, 0xF01FE07FFFFFFFFFu,
|
||||
0xF0003FFFF0003DFFu, 0xF0001DFFF0003FFFu, 0x0000FFFFFFFFFFFFu, 0x0000000001080000u,
|
||||
0xFFFFFFFFF0000000u, 0xF01FFFFFFFFFFFFFu, 0xFFFFF05FFFFFFFF9u, 0xF003FFFFFFFFFFFFu,
|
||||
0x0000000007FFFFFFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xD04ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0xD04ull) % 0x40ull));
|
||||
// 2239 code units from 83 ranges (spanning a search area of 3099)
|
||||
}
|
||||
case 0x02: // [2] 1940 - 258A
|
||||
{
|
||||
if (U'\u1950' > c || c > U'\u2184')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFF001F3FFFFFFFu, 0x03FFFFFF0FFFFFFFu, 0xFFFF000000000000u, 0xFFFFFFFFFFFF007Fu,
|
||||
0x000000000000001Fu, 0x0000000000800000u, 0xFFE0000000000000u, 0x0FE0000FFFFFFFFFu,
|
||||
0xFFF8000000000000u, 0xFFFFFC00C001FFFFu, 0xFFFF0000003FFFFFu, 0xE0000000000FFFFFu,
|
||||
0x01FF3FFFFFFFFC00u, 0x0000E7FFFFFFFFFFu, 0xFFFF046FDE000000u, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0x0000FFFFFFFFFFFFu, 0xFFFF000000000000u, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x3F3FFFFFFFFF3F3Fu,
|
||||
0xFFFF3FFFFFFFAAFFu, 0x1FDC5FDFFFFFFFFFu, 0x00001FDC1FFF0FCFu, 0x0000000000000000u,
|
||||
0x0000800200000000u, 0x0000000000001FFFu, 0xFC84000000000000u, 0x43E0F3FFBD503E2Fu,
|
||||
0x0018000000000000u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x1950ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0x1950ull) % 0x40ull));
|
||||
// 1184 code units from 59 ranges (spanning a search area of 2101)
|
||||
}
|
||||
case 0x03: // [3] 258B - 31D5
|
||||
{
|
||||
if (U'\u2C00' > c || c > U'\u31BF')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFF7FFFFFFFFFFFu, 0xFFFFFFFF7FFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x000C781FFFFFFFFFu,
|
||||
0xFFFF20BFFFFFFFFFu, 0x000080FFFFFFFFFFu, 0x7F7F7F7F007FFFFFu, 0x000000007F7F7F7Fu,
|
||||
0x0000800000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x183E000000000060u, 0xFFFFFFFFFFFFFFFEu, 0xFFFFFFFEE07FFFFFu, 0xF7FFFFFFFFFFFFFFu,
|
||||
0xFFFEFFFFFFFFFFE0u, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFF00007FFFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x2C00ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 771 code units from 30 ranges (spanning a search area of 1472)
|
||||
}
|
||||
case 0x04: return (U'\u31F0' <= c && c <= U'\u31FF') || U'\u3400' <= c;
|
||||
case 0x06: return c <= U'\u4DBF' || U'\u4E00' <= c;
|
||||
case 0x0C: return c <= U'\u9FFC' || U'\uA000' <= c;
|
||||
case 0x0D: // [13] A079 - ACC3
|
||||
{
|
||||
TOML_ASSUME(U'\uA079' <= c && c <= U'\uACC3');
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0x00000000000FFFFFu, 0xFFFFFFFFFF800000u, 0xFFFFFFFFFFFFFF9Fu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x0006007FFF8FFFFFu, 0x003FFFFFFFFFFF80u,
|
||||
0xFFFFFF9FFFFFFFC0u, 0x00001FFFFFFFFFFFu, 0xFFFFFE7FC0000000u, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFCFFFFu, 0xF00000000003FE7Fu, 0x000003FFFFFBDDFFu, 0x07FFFFFFFFFFFF80u,
|
||||
0x07FFFFFFFFFFFE00u, 0x7E00000000000000u, 0xFF801FFFFFFE0034u, 0xFFFFFF8000003FFFu,
|
||||
0x03FFFFFFFFFFF80Fu, 0x007FEF8000400000u, 0x0000FFFFFFFFFFBEu, 0x3FFFFF800007FB80u,
|
||||
0x317FFFFFFFFFFFE2u, 0x0E03FF9C0000029Fu, 0xFFBFBF803F3F3F00u, 0xFF81FFFBFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0x000003FFFFFFFFFFu, 0xFFFFFFFFFFFFFF80u, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0x00000000000007FFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xA079ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0xA079ull) % 0x40ull));
|
||||
// 2554 code units from 52 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x11: return c <= U'\uD7A3' || (U'\uD7B0' <= c && c <= U'\uD7C6') || (U'\uD7CB' <= c && c <= U'\uD7FB');
|
||||
case 0x14: // [20] F686 - 102D0
|
||||
{
|
||||
if (U'\uF900' > c)
|
||||
return false;
|
||||
TOML_ASSUME(c <= U'\U000102D0');
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFF3FFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x0000000003FFFFFFu,
|
||||
0x5F7FFDFFA0F8007Fu, 0xFFFFFFFFFFFFFFDBu, 0x0003FFFFFFFFFFFFu, 0xFFFFFFFFFFF80000u,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0x3FFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFF0000u, 0xFFFFFFFFFFFCFFFFu, 0x0FFF0000000000FFu,
|
||||
0x0000000000000000u, 0xFFDF000000000000u, 0xFFFFFFFFFFFFFFFFu, 0x1FFFFFFFFFFFFFFFu,
|
||||
0x07FFFFFE00000000u, 0xFFFFFFC007FFFFFEu, 0x7FFFFFFFFFFFFFFFu, 0x000000001CFCFCFCu,
|
||||
0xB7FFFF7FFFFFEFFFu, 0x000000003FFF3FFFu, 0xFFFFFFFFFFFFFFFFu, 0x07FFFFFFFFFFFFFFu,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0xFFFFFFFF1FFFFFFFu, 0x000000000001FFFFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xF900ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 1710 code units from 34 ranges (spanning a search area of 2513)
|
||||
}
|
||||
case 0x15: // [21] 102D1 - 10F1B
|
||||
{
|
||||
if (U'\U00010300' > c)
|
||||
return false;
|
||||
TOML_ASSUME(c <= U'\U00010F1B');
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFE000FFFFFFFFu, 0x003FFFFFFFFF03FDu, 0xFFFFFFFF3FFFFFFFu, 0x000000000000FF0Fu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFF00003FFFFFFFu, 0x0FFFFFFFFF0FFFFFu,
|
||||
0xFFFF00FFFFFFFFFFu, 0x0000000FFFFFFFFFu, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0x007FFFFFFFFFFFFFu, 0x000000FF003FFFFFu, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x91BFFFFFFFFFFD3Fu, 0x007FFFFF003FFFFFu, 0x000000007FFFFFFFu, 0x0037FFFF00000000u,
|
||||
0x03FFFFFF003FFFFFu, 0x0000000000000000u, 0xC0FFFFFFFFFFFFFFu, 0x0000000000000000u,
|
||||
0x003FFFFFFEEF0001u, 0x1FFFFFFF00000000u, 0x000000001FFFFFFFu, 0x0000001FFFFFFEFFu,
|
||||
0x003FFFFFFFFFFFFFu, 0x0007FFFF003FFFFFu, 0x000000000003FFFFu, 0x0000000000000000u,
|
||||
0xFFFFFFFFFFFFFFFFu, 0x00000000000001FFu, 0x0007FFFFFFFFFFFFu, 0x0007FFFFFFFFFFFFu,
|
||||
0x0000000FFFFFFFFFu, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x000303FFFFFFFFFFu, 0x0000000000000000u,
|
||||
0x000000000FFFFFFFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x10300ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 1620 code units from 48 ranges (spanning a search area of 3100)
|
||||
}
|
||||
case 0x16: // [22] 10F1C - 11B66
|
||||
{
|
||||
if (c > U'\U00011AF8')
|
||||
return false;
|
||||
TOML_ASSUME(U'\U00010F1C' <= c);
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x000003FFFFF00801u, 0x0000000000000000u, 0x000001FFFFF00000u, 0xFFFFFF8007FFFFF0u,
|
||||
0x000000000FFFFFFFu, 0xFFFFFF8000000000u, 0xFFF00000000FFFFFu, 0xFFFFFF8000001FFFu,
|
||||
0xFFF00900000007FFu, 0xFFFFFF80047FFFFFu, 0x400001E0007FFFFFu, 0xFFBFFFF000000001u,
|
||||
0x000000000000FFFFu, 0xFFFBD7F000000000u, 0xFFFFFFFFFFF01FFBu, 0xFF99FE0000000007u,
|
||||
0x001000023EDFDFFFu, 0x000000000000003Eu, 0x0000000000000000u, 0xFFFFFFF000000000u,
|
||||
0x0000780001FFFFFFu, 0xFFFFFFF000000038u, 0x00000B00000FFFFFu, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0xFFFFFFF000000000u, 0xF00000000007FFFFu, 0xFFFFFFF000000000u,
|
||||
0x00000100000FFFFFu, 0xFFFFFFF000000000u, 0x0000000010007FFFu, 0x7FFFFFF000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0xFFFFFFF000000000u,
|
||||
0x000000000000FFFFu, 0x0000000000000000u, 0xFFFFFFFFFFFFFFF0u, 0xF6FF27F80000000Fu,
|
||||
0x00000028000FFFFFu, 0x0000000000000000u, 0x001FFFFFFFFFCFF0u, 0xFFFF8010000000A0u,
|
||||
0x00100000407FFFFFu, 0x00003FFFFFFFFFFFu, 0xFFFFFFF000000002u, 0x000000001FFFFFFFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x10F1Cull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0x10F1Cull) % 0x40ull));
|
||||
// 1130 code units from 67 ranges (spanning a search area of 3037)
|
||||
}
|
||||
case 0x17: // [23] 11B67 - 127B1
|
||||
{
|
||||
if (U'\U00011C00' > c || c > U'\U00012543')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x00007FFFFFFFFDFFu, 0xFFFC000000000001u, 0x000000000000FFFFu, 0x0000000000000000u,
|
||||
0x0001FFFFFFFFFB7Fu, 0xFFFFFDBF00000040u, 0x00000000010003FFu, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0007FFFF00000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0001000000000000u, 0x0000000000000000u,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x0000000003FFFFFFu, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0x000000000000000Fu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x11C00ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 1304 code units from 16 ranges (spanning a search area of 2372)
|
||||
}
|
||||
case 0x18: return U'\U00013000' <= c;
|
||||
case 0x19: return c <= U'\U0001342E';
|
||||
case 0x1A: return U'\U00014400' <= c && c <= U'\U00014646';
|
||||
case 0x1D: // [29] 16529 - 17173
|
||||
{
|
||||
if (U'\U00016800' > c)
|
||||
return false;
|
||||
TOML_ASSUME(c <= U'\U00017173');
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0x01FFFFFFFFFFFFFFu, 0x000000007FFFFFFFu, 0x0000000000000000u, 0x00003FFFFFFF0000u,
|
||||
0x0000FFFFFFFFFFFFu, 0xE0FFFFF80000000Fu, 0x000000000000FFFFu, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0xFFFFFFFFFFFFFFFFu, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0xFFFFFFFFFFFFFFFFu, 0x00000000000107FFu, 0x00000000FFF80000u, 0x0000000B00000000u,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0x000FFFFFFFFFFFFFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x16800ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 1250 code units from 14 ranges (spanning a search area of 2420)
|
||||
}
|
||||
case 0x1F: return c <= U'\U000187F7' || U'\U00018800' <= c;
|
||||
case 0x20: return c <= U'\U00018CD5' || (U'\U00018D00' <= c && c <= U'\U00018D08');
|
||||
case 0x23: // [35] 1AEEB - 1BB35
|
||||
{
|
||||
if (U'\U0001B000' > c || c > U'\U0001B2FB')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0x000000007FFFFFFFu, 0xFFFF00F000070000u, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x0FFFFFFFFFFFFFFFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x1B000ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 690 code units from 4 ranges (spanning a search area of 764)
|
||||
}
|
||||
case 0x24: // [36] 1BB36 - 1C780
|
||||
{
|
||||
if (U'\U0001BC00' > c || c > U'\U0001BC99')
|
||||
return false;
|
||||
|
||||
switch ((static_cast<uint_least64_t>(c) - 0x1BC00ull) / 0x40ull)
|
||||
{
|
||||
case 0x01: return c <= U'\U0001BC7C' && (1ull << (static_cast<uint_least64_t>(c) - 0x1BC40u)) & 0x1FFF07FFFFFFFFFFull;
|
||||
case 0x02: return (1u << (static_cast<uint_least32_t>(c) - 0x1BC80u)) & 0x3FF01FFu;
|
||||
default: return true;
|
||||
}
|
||||
// 139 code units from 4 ranges (spanning a search area of 154)
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
case 0x26: // [38] 1D3CC - 1E016
|
||||
{
|
||||
if (U'\U0001D400' > c || c > U'\U0001D7CB')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFDFFFFFu, 0xEBFFDE64DFFFFFFFu, 0xFFFFFFFFFFFFFFEFu,
|
||||
0x7BFFFFFFDFDFE7BFu, 0xFFFFFFFFFFFDFC5Fu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFF3FFFFFFFFFu, 0xF7FFFFFFF7FFFFFDu,
|
||||
0xFFDFFFFFFFDFFFFFu, 0xFFFF7FFFFFFF7FFFu, 0xFFFFFDFFFFFFFDFFu, 0x0000000000000FF7u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x1D400ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 936 code units from 30 ranges (spanning a search area of 972)
|
||||
}
|
||||
case 0x27: // [39] 1E017 - 1EC61
|
||||
{
|
||||
if (U'\U0001E100' > c || c > U'\U0001E94B')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x3F801FFFFFFFFFFFu, 0x0000000000004000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x00000FFFFFFFFFFFu,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x000000000000001Fu,
|
||||
0xFFFFFFFFFFFFFFFFu, 0x000000000000080Fu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x1E100ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 363 code units from 7 ranges (spanning a search area of 2124)
|
||||
}
|
||||
case 0x28: // [40] 1EC62 - 1F8AC
|
||||
{
|
||||
if (U'\U0001EE00' > c || c > U'\U0001EEBB')
|
||||
return false;
|
||||
|
||||
switch ((static_cast<uint_least64_t>(c) - 0x1EE00ull) / 0x40ull)
|
||||
{
|
||||
case 0x00: return c <= U'\U0001EE3B' && (1ull << (static_cast<uint_least64_t>(c) - 0x1EE00u)) & 0xAF7FE96FFFFFFEFull;
|
||||
case 0x01: return U'\U0001EE42' <= c && c <= U'\U0001EE7E'
|
||||
&& (1ull << (static_cast<uint_least64_t>(c) - 0x1EE42u)) & 0x17BDFDE5AAA5BAA1ull;
|
||||
case 0x02: return (1ull << (static_cast<uint_least64_t>(c) - 0x1EE80u)) & 0xFFFFBEE0FFFFBFFull;
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
// 141 code units from 33 ranges (spanning a search area of 188)
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
case 0x29: return U'\U00020000' <= c;
|
||||
case 0x37: return c <= U'\U0002A6DD' || U'\U0002A700' <= c;
|
||||
case 0x38: return c <= U'\U0002B734' || (U'\U0002B740' <= c && c <= U'\U0002B81D') || U'\U0002B820' <= c;
|
||||
case 0x3A: return c <= U'\U0002CEA1' || U'\U0002CEB0' <= c;
|
||||
case 0x3C: return c <= U'\U0002EBE0';
|
||||
case 0x3D: return U'\U0002F800' <= c && c <= U'\U0002FA1D';
|
||||
case 0x3E: return U'\U00030000' <= c;
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
// 131189 code units from 620 ranges (spanning a search area of 201377)
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories:
|
||||
//# Nd, Nl
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_non_ascii_number(char32_t c) noexcept
|
||||
{
|
||||
if (U'\u0660' > c || c > U'\U0001FBF9')
|
||||
return false;
|
||||
|
||||
const auto child_index_0 = (static_cast<uint_least64_t>(c) - 0x660ull) / 0x7D7ull;
|
||||
if ((1ull << child_index_0) & 0x47FFDFE07FCFFFD0ull)
|
||||
return false;
|
||||
switch (child_index_0)
|
||||
{
|
||||
case 0x00: // [0] 0660 - 0E36
|
||||
{
|
||||
if (c > U'\u0DEF')
|
||||
return false;
|
||||
TOML_ASSUME(U'\u0660' <= c);
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFu, 0x0000000000000000u, 0x0000000003FF0000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x000003FF00000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x000000000000FFC0u, 0x0000000000000000u, 0x000000000000FFC0u, 0x0000000000000000u,
|
||||
0x000000000000FFC0u, 0x0000000000000000u, 0x000000000000FFC0u, 0x0000000000000000u,
|
||||
0x000000000000FFC0u, 0x0000000000000000u, 0x000000000000FFC0u, 0x0000000000000000u,
|
||||
0x000000000000FFC0u, 0x0000000000000000u, 0x000000000000FFC0u, 0x0000000000000000u,
|
||||
0x000000000000FFC0u, 0x0000000000000000u, 0x000000000000FFC0u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x660ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0x660ull) % 0x40ull));
|
||||
// 130 code units from 13 ranges (spanning a search area of 1936)
|
||||
}
|
||||
case 0x01: // [1] 0E37 - 160D
|
||||
{
|
||||
if (U'\u0E50' > c || c > U'\u1099')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFu, 0x0000000000000000u, 0x00000000000003FFu, 0x0000000003FF0000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x03FF000000000000u,
|
||||
0x0000000000000000u, 0x00000000000003FFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xE50ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0xE50ull) % 0x40ull));
|
||||
// 50 code units from 5 ranges (spanning a search area of 586)
|
||||
}
|
||||
case 0x02: // [2] 160E - 1DE4
|
||||
{
|
||||
if (U'\u16EE' > c || c > U'\u1C59')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x0000000000000007u, 0x0000000000000000u, 0x0000000000000000u, 0x0FFC000000000000u,
|
||||
0x00000FFC00000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x00000003FF000000u, 0x0000000000000000u, 0x00000FFC00000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x00000FFC0FFC0000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x00000FFC00000000u, 0x0000000000000000u, 0x0000000000000FFCu,
|
||||
0x0000000000000000u, 0x00000FFC0FFC0000u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x16EEull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0x16EEull) % 0x40ull));
|
||||
// 103 code units from 11 ranges (spanning a search area of 1388)
|
||||
}
|
||||
case 0x03: return U'\u2160' <= c && c <= U'\u2188' && (1ull << (static_cast<uint_least64_t>(c) - 0x2160u)) & 0x1E7FFFFFFFFull;
|
||||
case 0x05: return U'\u3007' <= c && c <= U'\u303A' && (1ull << (static_cast<uint_least64_t>(c) - 0x3007u)) & 0xE0007FC000001ull;
|
||||
case 0x14: // [20] A32C - AB02
|
||||
{
|
||||
if (U'\uA620' > c || c > U'\uAA59')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFu, 0x0000000000000000u, 0x0000000000000000u, 0x000000000000FFC0u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x03FF000000000000u, 0x000003FF00000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x03FF000000000000u, 0x0000000003FF0000u,
|
||||
0x03FF000000000000u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xA620ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0xA620ull) % 0x40ull));
|
||||
// 70 code units from 7 ranges (spanning a search area of 1082)
|
||||
}
|
||||
case 0x15: return U'\uABF0' <= c && c <= U'\uABF9';
|
||||
case 0x1F: return U'\uFF10' <= c && c <= U'\uFF19';
|
||||
case 0x20: // [32] 10140 - 10916
|
||||
{
|
||||
if (c > U'\U000104A9')
|
||||
return false;
|
||||
TOML_ASSUME(U'\U00010140' <= c);
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x001FFFFFFFFFFFFFu, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000402u, 0x0000000000000000u, 0x00000000003E0000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x000003FF00000000u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x10140ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 70 code units from 5 ranges (spanning a search area of 874)
|
||||
}
|
||||
case 0x21: return (U'\U00010D30' <= c && c <= U'\U00010D39') || (U'\U00011066' <= c && c <= U'\U0001106F');
|
||||
case 0x22: // [34] 110EE - 118C4
|
||||
{
|
||||
if (U'\U000110F0' > c || c > U'\U00011739')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFu, 0x000000000000FFC0u, 0x0000000000000000u, 0x000003FF00000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x00000000000003FFu, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x000003FF00000000u, 0x0000000000000000u, 0x000003FF00000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x000003FF00000000u, 0x0000000000000000u, 0x0000000003FF0000u,
|
||||
0x0000000000000000u, 0x00000000000003FFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x110F0ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0x110F0ull) % 0x40ull));
|
||||
// 90 code units from 9 ranges (spanning a search area of 1610)
|
||||
}
|
||||
case 0x23: // [35] 118C5 - 1209B
|
||||
{
|
||||
if (U'\U000118E0' > c || c > U'\U00011DA9')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFu, 0x03FF000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x03FF000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x03FF000000000000u, 0x0000000000000000u, 0x00000000000003FFu,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x118E0ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0x118E0ull) % 0x40ull));
|
||||
// 50 code units from 5 ranges (spanning a search area of 1226)
|
||||
}
|
||||
case 0x24: return U'\U00012400' <= c && c <= U'\U0001246E';
|
||||
case 0x2D: return (U'\U00016A60' <= c && c <= U'\U00016A69') || (U'\U00016B50' <= c && c <= U'\U00016B59');
|
||||
case 0x3B: return U'\U0001D7CE' <= c && c <= U'\U0001D7FF';
|
||||
case 0x3C: return (U'\U0001E140' <= c && c <= U'\U0001E149') || (U'\U0001E2F0' <= c && c <= U'\U0001E2F9');
|
||||
case 0x3D: return U'\U0001E950' <= c && c <= U'\U0001E959';
|
||||
case 0x3F: return U'\U0001FBF0' <= c;
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
// 876 code units from 72 ranges (spanning a search area of 128410)
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories:
|
||||
//# Mn, Mc
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_combining_mark(char32_t c) noexcept
|
||||
{
|
||||
if (U'\u0300' > c || c > U'\U000E01EF')
|
||||
return false;
|
||||
|
||||
const auto child_index_0 = (static_cast<uint_least64_t>(c) - 0x300ull) / 0x37FCull;
|
||||
if ((1ull << child_index_0) & 0x7FFFFFFFFFFFFE02ull)
|
||||
return false;
|
||||
switch (child_index_0)
|
||||
{
|
||||
case 0x00: // [0] 0300 - 3AFB
|
||||
{
|
||||
if (c > U'\u309A')
|
||||
return false;
|
||||
TOML_ASSUME(U'\u0300' <= c);
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFu, 0x0000FFFFFFFFFFFFu, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x00000000000000F8u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0xBFFFFFFFFFFE0000u, 0x00000000000000B6u,
|
||||
0x0000000007FF0000u, 0x00010000FFFFF800u, 0x0000000000000000u, 0x00003D9F9FC00000u,
|
||||
0xFFFF000000020000u, 0x00000000000007FFu, 0x0001FFC000000000u, 0x200FF80000000000u,
|
||||
0x00003EEFFBC00000u, 0x000000000E000000u, 0x0000000000000000u, 0xFFFFFFFBFFF80000u,
|
||||
0xDC0000000000000Fu, 0x0000000C00FEFFFFu, 0xD00000000000000Eu, 0x4000000C0080399Fu,
|
||||
0xD00000000000000Eu, 0x0023000000023987u, 0xD00000000000000Eu, 0xFC00000C00003BBFu,
|
||||
0xD00000000000000Eu, 0x0000000C00E0399Fu, 0xC000000000000004u, 0x0000000000803DC7u,
|
||||
0xC00000000000001Fu, 0x0000000C00603DDFu, 0xD00000000000000Eu, 0x0000000C00603DDFu,
|
||||
0xD80000000000000Fu, 0x0000000C00803DDFu, 0x000000000000000Eu, 0x000C0000FF5F8400u,
|
||||
0x07F2000000000000u, 0x0000000000007F80u, 0x1FF2000000000000u, 0x0000000000003F00u,
|
||||
0xC2A0000003000000u, 0xFFFE000000000000u, 0x1FFFFFFFFEFFE0DFu, 0x0000000000000040u,
|
||||
0x7FFFF80000000000u, 0x001E3F9DC3C00000u, 0x000000003C00BFFCu, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x00000000E0000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x001C0000001C0000u, 0x000C0000000C0000u, 0xFFF0000000000000u, 0x00000000200FFFFFu,
|
||||
0x0000000000003800u, 0x0000000000000000u, 0x0000020000000060u, 0x0000000000000000u,
|
||||
0x0FFF0FFF00000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x000000000F800000u, 0x9FFFFFFF7FE00000u, 0xBFFF000000000000u, 0x0000000000000001u,
|
||||
0xFFF000000000001Fu, 0x000FF8000000001Fu, 0x00003FFE00000007u, 0x000FFFC000000000u,
|
||||
0x00FFFFF000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x039021FFFFF70000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0xFBFFFFFFFFFFFFFFu,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0001FFE21FFF0000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0003800000000000u,
|
||||
0x0000000000000000u, 0x8000000000000000u, 0x0000000000000000u, 0xFFFFFFFF00000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000FC0000000000u, 0x0000000000000000u, 0x0000000006000000u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x300ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<uint_least64_t>(c) % 0x40ull));
|
||||
// 1106 code units from 156 ranges (spanning a search area of 11675)
|
||||
}
|
||||
case 0x02: // [2] 72F8 - AAF3
|
||||
{
|
||||
if (U'\uA66F' > c || c > U'\uAAEF')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x0001800000007FE1u, 0x0000000000000000u, 0x0000000000000006u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x21F0000010880000u, 0x0000000000000000u,
|
||||
0x0000000000060000u, 0xFFFE0000007FFFE0u, 0x7F80000000010007u, 0x0000001FFF000000u,
|
||||
0x00000000001E0000u, 0x004000000003FFF0u, 0xFC00000000000000u, 0x00000000601000FFu,
|
||||
0x0000000000007000u, 0xF00000000005833Au, 0x0000000000000001u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xA66Full) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0xA66Full) % 0x40ull));
|
||||
// 137 code units from 28 ranges (spanning a search area of 1153)
|
||||
}
|
||||
case 0x03: return (U'\uAAF5' <= c && c <= U'\uAAF6') || (U'\uABE3' <= c && c <= U'\uABEA') || (U'\uABEC' <= c && c <= U'\uABED');
|
||||
case 0x04: // [4] E2F0 - 11AEB
|
||||
{
|
||||
if (U'\uFB1E' > c || c > U'\U00011A99')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x0000000000000001u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0003FFFC00000000u,
|
||||
0x000000000003FFFCu, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000080000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000004u,
|
||||
0x0000000000000000u, 0x000000001F000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0003C1B800000000u,
|
||||
0x000000021C000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000180u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x00000000000003C0u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000006000u, 0x0000000000000000u,
|
||||
0x0007FF0000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000001C00000000u,
|
||||
0x000001FFFC000000u, 0x0000001E00000000u, 0x000000001FFC0000u, 0x0000001C00000000u,
|
||||
0x00000180007FFE00u, 0x0000001C00200000u, 0x00037807FFE00000u, 0x0000000000000000u,
|
||||
0x0000000103FFC000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000003C00001FFEu,
|
||||
0x0200E67F60000000u, 0x00000000007C7F30u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x000001FFFF800000u, 0x0000000000000001u, 0x0000003FFFFC0000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0xC0000007FCFE0000u, 0x0000000000000000u,
|
||||
0x00000007FFFC0000u, 0x0000000000000000u, 0x0000000003FFE000u, 0x8000000000000000u,
|
||||
0x0000000000003FFFu, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x000000001FFFC000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x00000035E6FC0000u, 0x0000000000000000u, 0xF3F8000000000000u, 0x00001FF800000047u,
|
||||
0x3FF80201EFE00000u, 0x0FFFF00000000000u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xFB1Eull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0xFB1Eull) % 0x40ull));
|
||||
// 402 code units from 63 ranges (spanning a search area of 8060)
|
||||
}
|
||||
case 0x05: // [5] 11AEC - 152E7
|
||||
{
|
||||
if (U'\U00011C2F' > c || c > U'\U00011EF6')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x000000000001FEFFu, 0xFDFFFFF800000000u, 0x00000000000000FFu, 0x0000000000000000u,
|
||||
0x00000000017F68FCu, 0x000001F6F8000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x00000000000000F0u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x11C2Full) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0x11C2Full) % 0x40ull));
|
||||
// 85 code units from 13 ranges (spanning a search area of 712)
|
||||
}
|
||||
case 0x06: // [6] 152E8 - 18AE3
|
||||
{
|
||||
if (U'\U00016AF0' > c || c > U'\U00016FF1')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x000000000000001Fu, 0x000000000000007Fu, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0xFFFFFFFE80000000u, 0x0000000780FFFFFFu, 0x0010000000000000u,
|
||||
0x0000000000000003u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x16AF0ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0x16AF0ull) % 0x40ull));
|
||||
// 75 code units from 7 ranges (spanning a search area of 1282)
|
||||
}
|
||||
case 0x07: return U'\U0001BC9D' <= c && c <= U'\U0001BC9E';
|
||||
case 0x08: // [8] 1C2E0 - 1FADB
|
||||
{
|
||||
if (U'\U0001D165' > c || c > U'\U0001E94A')
|
||||
return false;
|
||||
|
||||
constexpr uint_least64_t bitmask_table_1[] =
|
||||
{
|
||||
0x0000007F3FC03F1Fu, 0x00000000000001E0u, 0x0000000000000000u, 0x00000000E0000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0xFFFFFFFFF8000000u, 0xFFFFFFFFFFC3FFFFu,
|
||||
0xF7C00000800100FFu, 0x00000000000007FFu, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0xDFCFFFFBF8000000u, 0x000000000000003Eu,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x000000000003F800u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000780u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
|
||||
0x0000000000000000u, 0x0003F80000000000u, 0x0000000000000000u, 0x0000003F80000000u,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0x1D165ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<uint_least64_t>(c) - 0x1D165ull) % 0x40ull));
|
||||
// 223 code units from 21 ranges (spanning a search area of 6118)
|
||||
}
|
||||
case 0x3F: return U'\U000E0100' <= c;
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
// 2282 code units from 293 ranges (spanning a search area of 917232)
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
#endif // TOML_LANG_UNRELEASED
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_bare_key_character(char32_t codepoint) noexcept
|
||||
|
@ -146,9 +859,9 @@ namespace toml::impl
|
|||
|| codepoint == U'_'
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/644 ('+' in bare keys) & toml/issues/687 (unicode bare keys)
|
||||
|| codepoint == U'+'
|
||||
|| is_unicode_letter(codepoint)
|
||||
|| is_unicode_number(codepoint)
|
||||
|| is_unicode_combining_mark(codepoint)
|
||||
|| is_non_ascii_letter(codepoint)
|
||||
|| is_non_ascii_number(codepoint)
|
||||
|| is_combining_mark(codepoint)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
@ -163,14 +876,13 @@ namespace toml::impl
|
|||
|| codepoint == U'}'
|
||||
|| codepoint == U','
|
||||
|| codepoint == U'#'
|
||||
|| is_unicode_line_break(codepoint)
|
||||
|| is_unicode_whitespace(codepoint)
|
||||
|| is_non_ascii_line_break(codepoint)
|
||||
|| is_non_ascii_whitespace(codepoint)
|
||||
;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_control_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint <= U'\u001F' || codepoint == U'\u007F';
|
||||
|
@ -178,7 +890,6 @@ namespace toml::impl
|
|||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_nontab_control_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint <= U'\u0008'
|
||||
|
@ -188,7 +899,6 @@ namespace toml::impl
|
|||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_unicode_surrogate(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint >= 0xD800u && codepoint <= 0xDFFF;
|
||||
|
@ -196,6 +906,9 @@ namespace toml::impl
|
|||
|
||||
struct utf8_decoder final
|
||||
{
|
||||
// utf8_decoder based on this: https://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
||||
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
|
||||
uint_least32_t state{};
|
||||
char32_t codepoint{};
|
||||
|
||||
|
@ -217,19 +930,19 @@ namespace toml::impl
|
|||
12,36,12,12,12,12,12,12,12,12,12,12
|
||||
};
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
constexpr bool error() const noexcept
|
||||
{
|
||||
return state == uint_least32_t{ 12u };
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
constexpr bool has_code_point() const noexcept
|
||||
{
|
||||
return state == uint_least32_t{};
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
constexpr bool needs_more_input() const noexcept
|
||||
{
|
||||
return state > uint_least32_t{} && state != uint_least32_t{ 12u };
|
||||
|
@ -251,4 +964,6 @@ namespace toml::impl
|
|||
}
|
||||
};
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
#endif // !DOXYGEN
|
||||
|
|
|
@ -1,756 +0,0 @@
|
|||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
//#-----
|
||||
//# this file was generated by generate_unicode_functions.py - do not modify it directly
|
||||
|
||||
#pragma once
|
||||
#include "toml_preprocessor.h"
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
//# Returns true if a codepoint matches any of:
|
||||
//# 0 - 9, A - F, a - f
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_hexadecimal_digit(char32_t cp) noexcept
|
||||
{
|
||||
using ui64 = std::uint_least64_t;
|
||||
|
||||
return cp >= U'0' && cp <= U'f' && (1ull << (static_cast<ui64>(cp) - 0x30ull)) & 0x7E0000007E03FFull;
|
||||
}
|
||||
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories:
|
||||
//# Ll, Lm, Lo, Lt, Lu
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_unicode_letter(char32_t cp) noexcept
|
||||
{
|
||||
using ui64 = std::uint_least64_t;
|
||||
using ui32 = std::uint_least32_t;
|
||||
|
||||
if (cp < U'\u00AA' || cp > U'\U00031349')
|
||||
return false;
|
||||
|
||||
const auto child_index_0 = (static_cast<ui64>(cp) - 0xAAull) / 0xC4Bull;
|
||||
if ((1ull << child_index_0) & 0x8A7FFC004001CFA0ull)
|
||||
return true;
|
||||
if ((1ull << child_index_0) & 0x26180C0000ull)
|
||||
return false;
|
||||
switch (child_index_0)
|
||||
{
|
||||
case 0x00: // [0] 00AA - 0CF4
|
||||
{
|
||||
if (cp > U'\u0CF2')
|
||||
return false;
|
||||
TOML_ASSUME(cp >= U'\u00AA');
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFDFFFFFC10801ull, 0xFFFFFFFFFFFFDFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0x07C000FFF0FFFFFFull, 0x0000000000000014ull, 0x0000000000000000ull, 0xFEFFFFF5D02F37C0ull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFEFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00FFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFC09FFFFFFFFFBFull, 0x000000007FFFFFFFull,
|
||||
0xFFFFFFC000000000ull, 0xFFC00000000001E1ull, 0x00000001FFFFFFFFull, 0xFFFFFFFFFFFFFFB0ull,
|
||||
0x18000BFFFFFFFFFFull, 0xFFFFFF4000270030ull, 0xFFFFFFF80000003Full, 0x0FFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFF00000080ull, 0x44010FFFFFC10C01ull, 0xFFC07FFFFFC00000ull, 0xFFC0000000000001ull,
|
||||
0x000000003FFFF7FFull, 0xFFFFFFFFFC000000ull, 0x00FFC0400008FFFFull, 0x7FFFFE67F87FFF80ull,
|
||||
0x00EC00100008F17Full, 0x7FFFFE61F80400C0ull, 0x001780000000DB7Full, 0x7FFFFEEFF8000700ull,
|
||||
0x00C000400008FB7Full, 0x7FFFFE67F8008000ull, 0x00EC00000008FB7Full, 0xC6358F71FA000080ull,
|
||||
0x000000400000FFF1ull, 0x7FFFFF77F8000000ull, 0x00C1C0000008FFFFull, 0x7FFFFF77F8400000ull,
|
||||
0x00D000000008FBFFull, 0x0000000000000180ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0xAAull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0xAAull) % 0x40ull));
|
||||
//# chunk summary: 1922 codepoints from 124 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x01: // [1] 0CF5 - 193F
|
||||
{
|
||||
if (cp < U'\u0D04' || cp > U'\u191E')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x027FFFFFFFFFDDFFull, 0x0FC0000038070400ull, 0xF2FFBFFFFFC7FFFEull, 0xE000000000000007ull,
|
||||
0xF000DFFFFFFFFFFFull, 0x6000000000000007ull, 0xF200DFFAFFFFFF7Dull, 0x100000000F000005ull,
|
||||
0xF000000000000000ull, 0x000001FFFFFFFFEFull, 0x00000000000001F0ull, 0xF000000000000000ull,
|
||||
0x0800007FFFFFFFFFull, 0x3FFE1C0623C3F000ull, 0xFFFFFFFFF0000400ull, 0xFF7FFFFFFFFFF20Bull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFF3D7F3DFull, 0xD7F3DFFFFFFFF3DFull, 0xFFFFFFFFFFF7FFF3ull,
|
||||
0xFFFFFFFFFFF3DFFFull, 0xF0000000007FFFFFull, 0xFFFFFFFFF0000FFFull, 0xE3F3FFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xEFFFF9FFFFFFFFFFull, 0xFFFFFFFFF07FFFFFull, 0xF01FE07FFFFFFFFFull,
|
||||
0xF0003FFFF0003DFFull, 0xF0001DFFF0003FFFull, 0x0000FFFFFFFFFFFFull, 0x0000000001080000ull,
|
||||
0xFFFFFFFFF0000000ull, 0xF01FFFFFFFFFFFFFull, 0xFFFFF05FFFFFFFF9ull, 0xF003FFFFFFFFFFFFull,
|
||||
0x0000000007FFFFFFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0xD04ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0xD04ull) % 0x40ull));
|
||||
//# chunk summary: 2239 codepoints from 83 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x02: // [2] 1940 - 258A
|
||||
{
|
||||
if (cp < U'\u1950' || cp > U'\u2184')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFF001F3FFFFFFFull, 0x03FFFFFF0FFFFFFFull, 0xFFFF000000000000ull, 0xFFFFFFFFFFFF007Full,
|
||||
0x000000000000001Full, 0x0000000000800000ull, 0xFFE0000000000000ull, 0x0FE0000FFFFFFFFFull,
|
||||
0xFFF8000000000000ull, 0xFFFFFC00C001FFFFull, 0xFFFF0000003FFFFFull, 0xE0000000000FFFFFull,
|
||||
0x01FF3FFFFFFFFC00ull, 0x0000E7FFFFFFFFFFull, 0xFFFF046FDE000000ull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0x0000FFFFFFFFFFFFull, 0xFFFF000000000000ull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0x3F3FFFFFFFFF3F3Full,
|
||||
0xFFFF3FFFFFFFAAFFull, 0x1FDC5FDFFFFFFFFFull, 0x00001FDC1FFF0FCFull, 0x0000000000000000ull,
|
||||
0x0000800200000000ull, 0x0000000000001FFFull, 0xFC84000000000000ull, 0x43E0F3FFBD503E2Full,
|
||||
0x0018000000000000ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x1950ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0x1950ull) % 0x40ull));
|
||||
//# chunk summary: 1184 codepoints from 59 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x03: // [3] 258B - 31D5
|
||||
{
|
||||
if (cp < U'\u2C00' || cp > U'\u31BF')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFF7FFFFFFFFFFFull, 0xFFFFFFFF7FFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0x000C781FFFFFFFFFull,
|
||||
0xFFFF20BFFFFFFFFFull, 0x000080FFFFFFFFFFull, 0x7F7F7F7F007FFFFFull, 0x000000007F7F7F7Full,
|
||||
0x0000800000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x183E000000000060ull, 0xFFFFFFFFFFFFFFFEull, 0xFFFFFFFEE07FFFFFull, 0xF7FFFFFFFFFFFFFFull,
|
||||
0xFFFEFFFFFFFFFFE0ull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00007FFFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x2C00ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 771 codepoints from 30 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x04: return (cp >= U'\u31F0' && cp <= U'\u31FF') || (cp >= U'\u3400' && cp <= U'\u3E20');
|
||||
case 0x06: return (cp >= U'\u4A6C' && cp <= U'\u4DBE') || (cp >= U'\u4E00' && cp <= U'\u56B6');
|
||||
case 0x0C: return (cp >= U'\u942E' && cp <= U'\u9FFB') || (cp >= U'\uA000' && cp <= U'\uA078');
|
||||
case 0x0D: // [13] A079 - ACC3
|
||||
{
|
||||
TOML_ASSUME(cp >= U'\uA079' && cp <= U'\uACC3');
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0x00000000000FFFFFull, 0xFFFFFFFFFF800000ull, 0xFFFFFFFFFFFFFF9Full, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0x0006007FFF8FFFFFull, 0x003FFFFFFFFFFF80ull,
|
||||
0xFFFFFF9FFFFFFFC0ull, 0x00001FFFFFFFFFFFull, 0xFFFFFE7FC0000000ull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFCFFFFull, 0xF00000000003FE7Full, 0x000003FFFFFBDDFFull, 0x07FFFFFFFFFFFF80ull,
|
||||
0x07FFFFFFFFFFFE00ull, 0x7E00000000000000ull, 0xFF801FFFFFFE0034ull, 0xFFFFFF8000003FFFull,
|
||||
0x03FFFFFFFFFFF80Full, 0x007FEF8000400000ull, 0x0000FFFFFFFFFFBEull, 0x3FFFFF800007FB80ull,
|
||||
0x317FFFFFFFFFFFE2ull, 0x0E03FF9C0000029Full, 0xFFBFBF803F3F3F00ull, 0xFF81FFFBFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0x000003FFFFFFFFFFull, 0xFFFFFFFFFFFFFF80ull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0x00000000000007FFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0xA079ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0xA079ull) % 0x40ull));
|
||||
//# chunk summary: 2554 codepoints from 52 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x11: return (cp >= U'\uD1A5' && cp <= U'\uD7A2') || (cp >= U'\uD7B0' && cp <= U'\uD7C6')
|
||||
|| (cp >= U'\uD7CB' && cp <= U'\uD7FB');
|
||||
case 0x14: // [20] F686 - 102D0
|
||||
{
|
||||
if (cp < U'\uF900')
|
||||
return false;
|
||||
TOML_ASSUME(cp <= U'\U000102D0');
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFF3FFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0x0000000003FFFFFFull,
|
||||
0x5F7FFDFFA0F8007Full, 0xFFFFFFFFFFFFFFDBull, 0x0003FFFFFFFFFFFFull, 0xFFFFFFFFFFF80000ull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0x3FFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFF0000ull, 0xFFFFFFFFFFFCFFFFull, 0x0FFF0000000000FFull,
|
||||
0x0000000000000000ull, 0xFFDF000000000000ull, 0xFFFFFFFFFFFFFFFFull, 0x1FFFFFFFFFFFFFFFull,
|
||||
0x07FFFFFE00000000ull, 0xFFFFFFC007FFFFFEull, 0x7FFFFFFFFFFFFFFFull, 0x000000001CFCFCFCull,
|
||||
0xB7FFFF7FFFFFEFFFull, 0x000000003FFF3FFFull, 0xFFFFFFFFFFFFFFFFull, 0x07FFFFFFFFFFFFFFull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0xFFFFFFFF1FFFFFFFull, 0x000000000001FFFFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0xF900ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 1710 codepoints from 34 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x15: // [21] 102D1 - 10F1B
|
||||
{
|
||||
if (cp < U'\U00010300')
|
||||
return false;
|
||||
TOML_ASSUME(cp <= U'\U00010F1B');
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFE000FFFFFFFFull, 0x003FFFFFFFFF03FDull, 0xFFFFFFFF3FFFFFFFull, 0x000000000000FF0Full,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFF00003FFFFFFFull, 0x0FFFFFFFFF0FFFFFull,
|
||||
0xFFFF00FFFFFFFFFFull, 0x0000000FFFFFFFFFull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0x007FFFFFFFFFFFFFull, 0x000000FF003FFFFFull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x91BFFFFFFFFFFD3Full, 0x007FFFFF003FFFFFull, 0x000000007FFFFFFFull, 0x0037FFFF00000000ull,
|
||||
0x03FFFFFF003FFFFFull, 0x0000000000000000ull, 0xC0FFFFFFFFFFFFFFull, 0x0000000000000000ull,
|
||||
0x003FFFFFFEEF0001ull, 0x1FFFFFFF00000000ull, 0x000000001FFFFFFFull, 0x0000001FFFFFFEFFull,
|
||||
0x003FFFFFFFFFFFFFull, 0x0007FFFF003FFFFFull, 0x000000000003FFFFull, 0x0000000000000000ull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0x00000000000001FFull, 0x0007FFFFFFFFFFFFull, 0x0007FFFFFFFFFFFFull,
|
||||
0x0000000FFFFFFFFFull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x000303FFFFFFFFFFull, 0x0000000000000000ull,
|
||||
0x000000000FFFFFFFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x10300ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 1620 codepoints from 48 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x16: // [22] 10F1C - 11B66
|
||||
{
|
||||
if (cp > U'\U00011AF8')
|
||||
return false;
|
||||
TOML_ASSUME(cp >= U'\U00010F1C');
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x000003FFFFF00801ull, 0x0000000000000000ull, 0x000001FFFFF00000ull, 0xFFFFFF8007FFFFF0ull,
|
||||
0x000000000FFFFFFFull, 0xFFFFFF8000000000ull, 0xFFF00000000FFFFFull, 0xFFFFFF8000001FFFull,
|
||||
0xFFF00900000007FFull, 0xFFFFFF80047FFFFFull, 0x400001E0007FFFFFull, 0xFFBFFFF000000001ull,
|
||||
0x000000000000FFFFull, 0xFFFBD7F000000000ull, 0xFFFFFFFFFFF01FFBull, 0xFF99FE0000000007ull,
|
||||
0x001000023EDFDFFFull, 0x000000000000003Eull, 0x0000000000000000ull, 0xFFFFFFF000000000ull,
|
||||
0x0000780001FFFFFFull, 0xFFFFFFF000000038ull, 0x00000B00000FFFFFull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0xFFFFFFF000000000ull, 0xF00000000007FFFFull, 0xFFFFFFF000000000ull,
|
||||
0x00000100000FFFFFull, 0xFFFFFFF000000000ull, 0x0000000010007FFFull, 0x7FFFFFF000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0xFFFFFFF000000000ull,
|
||||
0x000000000000FFFFull, 0x0000000000000000ull, 0xFFFFFFFFFFFFFFF0ull, 0xF6FF27F80000000Full,
|
||||
0x00000028000FFFFFull, 0x0000000000000000ull, 0x001FFFFFFFFFCFF0ull, 0xFFFF8010000000A0ull,
|
||||
0x00100000407FFFFFull, 0x00003FFFFFFFFFFFull, 0xFFFFFFF000000002ull, 0x000000001FFFFFFFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x10F1Cull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0x10F1Cull) % 0x40ull));
|
||||
//# chunk summary: 1130 codepoints from 67 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x17: // [23] 11B67 - 127B1
|
||||
{
|
||||
if (cp < U'\U00011C00' || cp > U'\U00012543')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x00007FFFFFFFFDFFull, 0xFFFC000000000001ull, 0x000000000000FFFFull, 0x0000000000000000ull,
|
||||
0x0001FFFFFFFFFB7Full, 0xFFFFFDBF00000040ull, 0x00000000010003FFull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0007FFFF00000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0001000000000000ull, 0x0000000000000000ull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0x0000000003FFFFFFull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0x000000000000000Full,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x11C00ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 1304 codepoints from 16 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x18: return cp >= U'\U00013000';
|
||||
case 0x19: return cp <= U'\U0001342E';
|
||||
case 0x1A: return cp >= U'\U00014400' && cp <= U'\U00014646';
|
||||
case 0x1D: // [29] 16529 - 17173
|
||||
{
|
||||
if (cp < U'\U00016800')
|
||||
return false;
|
||||
TOML_ASSUME(cp <= U'\U00017173');
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0x01FFFFFFFFFFFFFFull, 0x000000007FFFFFFFull, 0x0000000000000000ull, 0x00003FFFFFFF0000ull,
|
||||
0x0000FFFFFFFFFFFFull, 0xE0FFFFF80000000Full, 0x000000000000FFFFull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0xFFFFFFFFFFFFFFFFull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0x00000000000107FFull, 0x00000000FFF80000ull, 0x0000000B00000000ull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0x000FFFFFFFFFFFFFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x16800ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 1250 codepoints from 14 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x1F: return (cp >= U'\U00017DBF' && cp <= U'\U000187F6') || (cp >= U'\U00018800' && cp <= U'\U00018A09');
|
||||
case 0x20: return (cp >= U'\U00018A0A' && cp <= U'\U00018CD5') || (cp >= U'\U00018D00' && cp <= U'\U00018D07');
|
||||
case 0x23: // [35] 1AEEB - 1BB35
|
||||
{
|
||||
if (cp < U'\U0001B000' || cp > U'\U0001B2FB')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0x000000007FFFFFFFull, 0xFFFF00F000070000ull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0x0FFFFFFFFFFFFFFFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x1B000ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 690 codepoints from 4 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x24: // [36] 1BB36 - 1C780
|
||||
{
|
||||
if (cp < U'\U0001BC00' || cp > U'\U0001BC99')
|
||||
return false;
|
||||
|
||||
switch ((static_cast<ui64>(cp) - 0x1BC00ull) / 0x40ull)
|
||||
{
|
||||
case 0x01: return cp <= U'\U0001BC7C'
|
||||
&& (1ull << (static_cast<ui64>(cp) - 0x1BC40ull)) & 0x1FFF07FFFFFFFFFFull;
|
||||
case 0x02: return (1u << (static_cast<ui32>(cp) - 0x1BC80u)) & 0x3FF01FFu;
|
||||
default: return true;
|
||||
}
|
||||
//# chunk summary: 139 codepoints from 4 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x26: // [38] 1D3CC - 1E016
|
||||
{
|
||||
if (cp < U'\U0001D400' || cp > U'\U0001D7CB')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFDFFFFFull, 0xEBFFDE64DFFFFFFFull, 0xFFFFFFFFFFFFFFEFull,
|
||||
0x7BFFFFFFDFDFE7BFull, 0xFFFFFFFFFFFDFC5Full, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFF3FFFFFFFFFull, 0xF7FFFFFFF7FFFFFDull,
|
||||
0xFFDFFFFFFFDFFFFFull, 0xFFFF7FFFFFFF7FFFull, 0xFFFFFDFFFFFFFDFFull, 0x0000000000000FF7ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x1D400ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 936 codepoints from 30 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x27: // [39] 1E017 - 1EC61
|
||||
{
|
||||
if (cp < U'\U0001E100' || cp > U'\U0001E94B')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x3F801FFFFFFFFFFFull, 0x0000000000004000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x00000FFFFFFFFFFFull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0x000000000000001Full,
|
||||
0xFFFFFFFFFFFFFFFFull, 0x000000000000080Full,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x1E100ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 363 codepoints from 7 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x28: // [40] 1EC62 - 1F8AC
|
||||
{
|
||||
if (cp < U'\U0001EE00' || cp > U'\U0001EEBB')
|
||||
return false;
|
||||
|
||||
switch ((static_cast<ui64>(cp) - 0x1EE00ull) / 0x40ull)
|
||||
{
|
||||
case 0x00: return cp <= U'\U0001EE3B'
|
||||
&& (1ull << (static_cast<ui64>(cp) - 0x1EE00ull)) & 0xAF7FE96FFFFFFEFull;
|
||||
case 0x01: return cp >= U'\U0001EE42' && cp <= U'\U0001EE7E'
|
||||
&& (1ull << (static_cast<ui64>(cp) - 0x1EE42ull)) & 0x17BDFDE5AAA5BAA1ull;
|
||||
case 0x02: return (1ull << (static_cast<ui64>(cp) - 0x1EE80ull)) & 0xFFFFBEE0FFFFBFFull;
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
//# chunk summary: 141 codepoints from 33 ranges (spanning a search area of 3147)
|
||||
}
|
||||
case 0x29: return cp >= U'\U00020000';
|
||||
case 0x37: return (cp >= U'\U0002A4C7' && cp <= U'\U0002A6DC') || (cp >= U'\U0002A700' && cp <= U'\U0002B111');
|
||||
case 0x38: return (cp >= U'\U0002B112' && cp <= U'\U0002B733') || (cp >= U'\U0002B740' && cp <= U'\U0002B81C')
|
||||
|| (cp >= U'\U0002B820' && cp <= U'\U0002BD5C');
|
||||
case 0x3A: return (cp >= U'\U0002C9A8' && cp <= U'\U0002CEA0') || (cp >= U'\U0002CEB0' && cp <= U'\U0002D5F2');
|
||||
case 0x3C: return cp <= U'\U0002EBDF';
|
||||
case 0x3D: return cp >= U'\U0002F800' && cp <= U'\U0002FA1D';
|
||||
case 0x3E: return cp >= U'\U00030000';
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
//# chunk summary: 131178 codepoints from 620 ranges (spanning a search area of 201376)
|
||||
}
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories:
|
||||
//# Nd, Nl
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_unicode_number(char32_t cp) noexcept
|
||||
{
|
||||
using ui64 = std::uint_least64_t;
|
||||
|
||||
if (cp < U'\u0660' || cp > U'\U0001FBF9')
|
||||
return false;
|
||||
|
||||
const auto child_index_0 = (static_cast<ui64>(cp) - 0x660ull) / 0x7D7ull;
|
||||
if ((1ull << child_index_0) & 0x47FFDFE07FCFFFD0ull)
|
||||
return false;
|
||||
switch (child_index_0)
|
||||
{
|
||||
case 0x00: // [0] 0660 - 0E36
|
||||
{
|
||||
if (cp > U'\u0DEF')
|
||||
return false;
|
||||
TOML_ASSUME(cp >= U'\u0660');
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFull, 0x0000000000000000ull, 0x0000000003FF0000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x000003FF00000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x000000000000FFC0ull, 0x0000000000000000ull, 0x000000000000FFC0ull, 0x0000000000000000ull,
|
||||
0x000000000000FFC0ull, 0x0000000000000000ull, 0x000000000000FFC0ull, 0x0000000000000000ull,
|
||||
0x000000000000FFC0ull, 0x0000000000000000ull, 0x000000000000FFC0ull, 0x0000000000000000ull,
|
||||
0x000000000000FFC0ull, 0x0000000000000000ull, 0x000000000000FFC0ull, 0x0000000000000000ull,
|
||||
0x000000000000FFC0ull, 0x0000000000000000ull, 0x000000000000FFC0ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x660ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0x660ull) % 0x40ull));
|
||||
//# chunk summary: 130 codepoints from 13 ranges (spanning a search area of 2007)
|
||||
}
|
||||
case 0x01: // [1] 0E37 - 160D
|
||||
{
|
||||
if (cp < U'\u0E50' || cp > U'\u1099')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFull, 0x0000000000000000ull, 0x00000000000003FFull, 0x0000000003FF0000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x03FF000000000000ull,
|
||||
0x0000000000000000ull, 0x00000000000003FFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0xE50ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0xE50ull) % 0x40ull));
|
||||
//# chunk summary: 50 codepoints from 5 ranges (spanning a search area of 2007)
|
||||
}
|
||||
case 0x02: // [2] 160E - 1DE4
|
||||
{
|
||||
if (cp < U'\u16EE' || cp > U'\u1C59')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x0000000000000007ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0FFC000000000000ull,
|
||||
0x00000FFC00000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x00000003FF000000ull, 0x0000000000000000ull, 0x00000FFC00000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x00000FFC0FFC0000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x00000FFC00000000ull, 0x0000000000000000ull, 0x0000000000000FFCull,
|
||||
0x0000000000000000ull, 0x00000FFC0FFC0000ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x16EEull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0x16EEull) % 0x40ull));
|
||||
//# chunk summary: 103 codepoints from 11 ranges (spanning a search area of 2007)
|
||||
}
|
||||
case 0x03: return cp >= U'\u2160' && cp <= U'\u2188'
|
||||
&& (1ull << (static_cast<ui64>(cp) - 0x2160ull)) & 0x1E7FFFFFFFFull;
|
||||
case 0x05: return cp >= U'\u3007' && cp <= U'\u303A'
|
||||
&& (1ull << (static_cast<ui64>(cp) - 0x3007ull)) & 0xE0007FC000001ull;
|
||||
case 0x14: // [20] A32C - AB02
|
||||
{
|
||||
if (cp < U'\uA620' || cp > U'\uAA59')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFull, 0x0000000000000000ull, 0x0000000000000000ull, 0x000000000000FFC0ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x03FF000000000000ull, 0x000003FF00000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x03FF000000000000ull, 0x0000000003FF0000ull,
|
||||
0x03FF000000000000ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0xA620ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0xA620ull) % 0x40ull));
|
||||
//# chunk summary: 70 codepoints from 7 ranges (spanning a search area of 2007)
|
||||
}
|
||||
case 0x15: return cp >= U'\uABF0' && cp <= U'\uABF9';
|
||||
case 0x1F: return cp >= U'\uFF10' && cp <= U'\uFF19';
|
||||
case 0x20: // [32] 10140 - 10916
|
||||
{
|
||||
if (cp > U'\U000104A9')
|
||||
return false;
|
||||
TOML_ASSUME(cp >= U'\U00010140');
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x001FFFFFFFFFFFFFull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000402ull, 0x0000000000000000ull, 0x00000000003E0000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x000003FF00000000ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x10140ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 70 codepoints from 5 ranges (spanning a search area of 2007)
|
||||
}
|
||||
case 0x21: return (cp >= U'\U00010D30' && cp <= U'\U00010D39') || (cp >= U'\U00011066' && cp <= U'\U0001106F');
|
||||
case 0x22: // [34] 110EE - 118C4
|
||||
{
|
||||
if (cp < U'\U000110F0' || cp > U'\U00011739')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFull, 0x000000000000FFC0ull, 0x0000000000000000ull, 0x000003FF00000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x00000000000003FFull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x000003FF00000000ull, 0x0000000000000000ull, 0x000003FF00000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x000003FF00000000ull, 0x0000000000000000ull, 0x0000000003FF0000ull,
|
||||
0x0000000000000000ull, 0x00000000000003FFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x110F0ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0x110F0ull) % 0x40ull));
|
||||
//# chunk summary: 90 codepoints from 9 ranges (spanning a search area of 2007)
|
||||
}
|
||||
case 0x23: // [35] 118C5 - 1209B
|
||||
{
|
||||
if (cp < U'\U000118E0' || cp > U'\U00011DA9')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x00000000000003FFull, 0x03FF000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x03FF000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x03FF000000000000ull, 0x0000000000000000ull, 0x00000000000003FFull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x118E0ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0x118E0ull) % 0x40ull));
|
||||
//# chunk summary: 50 codepoints from 5 ranges (spanning a search area of 2007)
|
||||
}
|
||||
case 0x24: return cp >= U'\U00012400' && cp <= U'\U0001246E';
|
||||
case 0x2D: return (cp >= U'\U00016A60' && cp <= U'\U00016A69') || (cp >= U'\U00016B50' && cp <= U'\U00016B59');
|
||||
case 0x3B: return cp >= U'\U0001D7CE' && cp <= U'\U0001D7FF';
|
||||
case 0x3C: return (cp >= U'\U0001E140' && cp <= U'\U0001E149') || (cp >= U'\U0001E2F0' && cp <= U'\U0001E2F9');
|
||||
case 0x3D: return cp >= U'\U0001E950' && cp <= U'\U0001E959';
|
||||
case 0x3F: return cp >= U'\U0001FBF0';
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
//# chunk summary: 876 codepoints from 72 ranges (spanning a search area of 128410)
|
||||
}
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories:
|
||||
//# Mn, Mc
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
constexpr bool is_unicode_combining_mark(char32_t cp) noexcept
|
||||
{
|
||||
using ui64 = std::uint_least64_t;
|
||||
|
||||
if (cp < U'\u0300' || cp > U'\U000E01EF')
|
||||
return false;
|
||||
|
||||
const auto child_index_0 = (static_cast<ui64>(cp) - 0x300ull) / 0x37FCull;
|
||||
if ((1ull << child_index_0) & 0x7FFFFFFFFFFFFE02ull)
|
||||
return false;
|
||||
switch (child_index_0)
|
||||
{
|
||||
case 0x00: // [0] 0300 - 3AFB
|
||||
{
|
||||
if (cp > U'\u309A')
|
||||
return false;
|
||||
TOML_ASSUME(cp >= U'\u0300');
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0xFFFFFFFFFFFFFFFFull, 0x0000FFFFFFFFFFFFull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x00000000000000F8ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0xBFFFFFFFFFFE0000ull, 0x00000000000000B6ull,
|
||||
0x0000000007FF0000ull, 0x00010000FFFFF800ull, 0x0000000000000000ull, 0x00003D9F9FC00000ull,
|
||||
0xFFFF000000020000ull, 0x00000000000007FFull, 0x0001FFC000000000ull, 0x200FF80000000000ull,
|
||||
0x00003EEFFBC00000ull, 0x000000000E000000ull, 0x0000000000000000ull, 0xFFFFFFFBFFF80000ull,
|
||||
0xDC0000000000000Full, 0x0000000C00FEFFFFull, 0xD00000000000000Eull, 0x4000000C0080399Full,
|
||||
0xD00000000000000Eull, 0x0023000000023987ull, 0xD00000000000000Eull, 0xFC00000C00003BBFull,
|
||||
0xD00000000000000Eull, 0x0000000C00E0399Full, 0xC000000000000004ull, 0x0000000000803DC7ull,
|
||||
0xC00000000000001Full, 0x0000000C00603DDFull, 0xD00000000000000Eull, 0x0000000C00603DDFull,
|
||||
0xD80000000000000Full, 0x0000000C00803DDFull, 0x000000000000000Eull, 0x000C0000FF5F8400ull,
|
||||
0x07F2000000000000ull, 0x0000000000007F80ull, 0x1FF2000000000000ull, 0x0000000000003F00ull,
|
||||
0xC2A0000003000000ull, 0xFFFE000000000000ull, 0x1FFFFFFFFEFFE0DFull, 0x0000000000000040ull,
|
||||
0x7FFFF80000000000ull, 0x001E3F9DC3C00000ull, 0x000000003C00BFFCull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x00000000E0000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x001C0000001C0000ull, 0x000C0000000C0000ull, 0xFFF0000000000000ull, 0x00000000200FFFFFull,
|
||||
0x0000000000003800ull, 0x0000000000000000ull, 0x0000020000000060ull, 0x0000000000000000ull,
|
||||
0x0FFF0FFF00000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x000000000F800000ull, 0x9FFFFFFF7FE00000ull, 0xBFFF000000000000ull, 0x0000000000000001ull,
|
||||
0xFFF000000000001Full, 0x000FF8000000001Full, 0x00003FFE00000007ull, 0x000FFFC000000000ull,
|
||||
0x00FFFFF000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x039021FFFFF70000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0xFBFFFFFFFFFFFFFFull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0001FFE21FFF0000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0003800000000000ull,
|
||||
0x0000000000000000ull, 0x8000000000000000ull, 0x0000000000000000ull, 0xFFFFFFFF00000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000FC0000000000ull, 0x0000000000000000ull, 0x0000000006000000ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x300ull) / 0x40ull]
|
||||
& (0x1ull << (static_cast<ui64>(cp) % 0x40ull));
|
||||
//# chunk summary: 1106 codepoints from 156 ranges (spanning a search area of 14332)
|
||||
}
|
||||
case 0x02: // [2] 72F8 - AAF3
|
||||
{
|
||||
if (cp < U'\uA66F' || cp > U'\uAAEF')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x0001800000007FE1ull, 0x0000000000000000ull, 0x0000000000000006ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x21F0000010880000ull, 0x0000000000000000ull,
|
||||
0x0000000000060000ull, 0xFFFE0000007FFFE0ull, 0x7F80000000010007ull, 0x0000001FFF000000ull,
|
||||
0x00000000001E0000ull, 0x004000000003FFF0ull, 0xFC00000000000000ull, 0x00000000601000FFull,
|
||||
0x0000000000007000ull, 0xF00000000005833Aull, 0x0000000000000001ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0xA66Full) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0xA66Full) % 0x40ull));
|
||||
//# chunk summary: 137 codepoints from 28 ranges (spanning a search area of 14332)
|
||||
}
|
||||
case 0x03: return cp == U'\uAAF5' || cp == U'\uAAF6' || (cp >= U'\uABE3' && cp <= U'\uABEA') || cp == U'\uABEC'
|
||||
|| cp == U'\uABED';
|
||||
case 0x04: // [4] E2F0 - 11AEB
|
||||
{
|
||||
if (cp < U'\uFB1E' || cp > U'\U00011A99')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x0000000000000001ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0003FFFC00000000ull,
|
||||
0x000000000003FFFCull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000080000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000004ull,
|
||||
0x0000000000000000ull, 0x000000001F000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0003C1B800000000ull,
|
||||
0x000000021C000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000180ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x00000000000003C0ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000006000ull, 0x0000000000000000ull,
|
||||
0x0007FF0000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000001C00000000ull,
|
||||
0x000001FFFC000000ull, 0x0000001E00000000ull, 0x000000001FFC0000ull, 0x0000001C00000000ull,
|
||||
0x00000180007FFE00ull, 0x0000001C00200000ull, 0x00037807FFE00000ull, 0x0000000000000000ull,
|
||||
0x0000000103FFC000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000003C00001FFEull,
|
||||
0x0200E67F60000000ull, 0x00000000007C7F30ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x000001FFFF800000ull, 0x0000000000000001ull, 0x0000003FFFFC0000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0xC0000007FCFE0000ull, 0x0000000000000000ull,
|
||||
0x00000007FFFC0000ull, 0x0000000000000000ull, 0x0000000003FFE000ull, 0x8000000000000000ull,
|
||||
0x0000000000003FFFull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x000000001FFFC000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x00000035E6FC0000ull, 0x0000000000000000ull, 0xF3F8000000000000ull, 0x00001FF800000047ull,
|
||||
0x3FF80201EFE00000ull, 0x0FFFF00000000000ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0xFB1Eull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0xFB1Eull) % 0x40ull));
|
||||
//# chunk summary: 402 codepoints from 63 ranges (spanning a search area of 14332)
|
||||
}
|
||||
case 0x05: // [5] 11AEC - 152E7
|
||||
{
|
||||
if (cp < U'\U00011C2F' || cp > U'\U00011EF6')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x000000000001FEFFull, 0xFDFFFFF800000000ull, 0x00000000000000FFull, 0x0000000000000000ull,
|
||||
0x00000000017F68FCull, 0x000001F6F8000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x00000000000000F0ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x11C2Full) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0x11C2Full) % 0x40ull));
|
||||
//# chunk summary: 85 codepoints from 13 ranges (spanning a search area of 14332)
|
||||
}
|
||||
case 0x06: // [6] 152E8 - 18AE3
|
||||
{
|
||||
if (cp < U'\U00016AF0' || cp > U'\U00016FF1')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x000000000000001Full, 0x000000000000007Full, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0xFFFFFFFE80000000ull, 0x0000000780FFFFFFull, 0x0010000000000000ull,
|
||||
0x0000000000000003ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x16AF0ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0x16AF0ull) % 0x40ull));
|
||||
//# chunk summary: 75 codepoints from 7 ranges (spanning a search area of 14332)
|
||||
}
|
||||
case 0x07: return cp >= U'\U0001BC9D' && cp <= U'\U0001BC9E';
|
||||
case 0x08: // [8] 1C2E0 - 1FADB
|
||||
{
|
||||
if (cp < U'\U0001D165' || cp > U'\U0001E94A')
|
||||
return false;
|
||||
|
||||
constexpr ui64 bitmask_table_1[] =
|
||||
{
|
||||
0x0000007F3FC03F1Full, 0x00000000000001E0ull, 0x0000000000000000ull, 0x00000000E0000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0xFFFFFFFFF8000000ull, 0xFFFFFFFFFFC3FFFFull,
|
||||
0xF7C00000800100FFull, 0x00000000000007FFull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0xDFCFFFFBF8000000ull, 0x000000000000003Eull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x000000000003F800ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000780ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0003F80000000000ull, 0x0000000000000000ull, 0x0000003F80000000ull,
|
||||
};
|
||||
return bitmask_table_1[(static_cast<ui64>(cp) - 0x1D165ull) / 0x40ull]
|
||||
& (0x1ull << ((static_cast<ui64>(cp) - 0x1D165ull) % 0x40ull));
|
||||
//# chunk summary: 223 codepoints from 21 ranges (spanning a search area of 14332)
|
||||
}
|
||||
case 0x3F: return cp >= U'\U000E0100';
|
||||
TOML_NO_DEFAULT_CASE;
|
||||
}
|
||||
//# chunk summary: 2282 codepoints from 293 ranges (spanning a search area of 917232)
|
||||
}
|
||||
|
||||
#endif // TOML_LANG_UNRELEASED
|
||||
} // toml::impl
|
|
@ -13,10 +13,7 @@
|
|||
#include "toml_utf8.h"
|
||||
#include "toml_parse_error.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
|
||||
namespace toml::impl
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
template <typename T>
|
||||
class utf8_byte_stream;
|
||||
|
@ -24,7 +21,7 @@ namespace toml::impl
|
|||
inline constexpr auto utf8_byte_order_mark = "\xEF\xBB\xBF"sv;
|
||||
|
||||
template <typename Char>
|
||||
class utf8_byte_stream<std::basic_string_view<Char>> final
|
||||
class TOML_API utf8_byte_stream<std::basic_string_view<Char>> final
|
||||
{
|
||||
static_assert(sizeof(Char) == 1_sz);
|
||||
|
||||
|
@ -37,7 +34,8 @@ namespace toml::impl
|
|||
: source{ sv }
|
||||
{
|
||||
// trim trailing nulls
|
||||
size_t actual_len = source.length();
|
||||
const size_t initial_len = source.length();
|
||||
size_t actual_len = initial_len;
|
||||
for (size_t i = actual_len; i --> 0_sz;)
|
||||
{
|
||||
if (source[i] != Char{}) // not '\0'
|
||||
|
@ -46,27 +44,30 @@ namespace toml::impl
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (source.length() != actual_len) // not '\0'
|
||||
if (initial_len != actual_len)
|
||||
source = source.substr(0_sz, actual_len);
|
||||
|
||||
// skip bom
|
||||
if (source.length() >= 3_sz && memcmp(utf8_byte_order_mark.data(), source.data(), 3_sz) == 0)
|
||||
if (actual_len >= 3_sz && memcmp(utf8_byte_order_mark.data(), source.data(), 3_sz) == 0)
|
||||
position += 3_sz;
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool eof() const noexcept
|
||||
{
|
||||
return position >= source.length();
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool peek_eof() const noexcept
|
||||
{
|
||||
return eof();
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool error() const noexcept
|
||||
{
|
||||
return false;
|
||||
|
@ -82,7 +83,7 @@ namespace toml::impl
|
|||
};
|
||||
|
||||
template <typename Char>
|
||||
class utf8_byte_stream<std::basic_istream<Char>> final
|
||||
class TOML_API utf8_byte_stream<std::basic_istream<Char>> final
|
||||
{
|
||||
static_assert(sizeof(Char) == 1_sz);
|
||||
|
||||
|
@ -103,23 +104,26 @@ namespace toml::impl
|
|||
return;
|
||||
|
||||
source->clear();
|
||||
source->seekg(initial_pos, std::ios::beg);
|
||||
source->seekg(initial_pos, std::basic_istream<Char>::beg);
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
bool eof() const noexcept
|
||||
{
|
||||
return source->eof();
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
bool peek_eof() const
|
||||
{
|
||||
using stream_traits = typename std::remove_pointer_t<decltype(source)>::traits_type;
|
||||
return eof() || source->peek() == stream_traits::eof();
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
bool error() const noexcept
|
||||
{
|
||||
return !(*source);
|
||||
|
@ -135,75 +139,41 @@ namespace toml::impl
|
|||
}
|
||||
};
|
||||
|
||||
#if TOML_LARGE_FILES
|
||||
TOML_ABI_NAMESPACE_START(impl_lf)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(impl_sf)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_LARGE_FILES, lf, sf)
|
||||
|
||||
struct utf8_codepoint final
|
||||
{
|
||||
char32_t value;
|
||||
string_char bytes[4];
|
||||
char bytes[4];
|
||||
source_position position;
|
||||
|
||||
template <typename Char = string_char>
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
std::basic_string_view<Char> as_view() const noexcept
|
||||
std::string_view as_view() const noexcept
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
"The string view's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
return bytes[3]
|
||||
? std::basic_string_view<Char>{ reinterpret_cast<const Char*>(bytes), 4_sz }
|
||||
: std::basic_string_view<Char>{ reinterpret_cast<const Char*>(bytes) };
|
||||
? std::string_view{ bytes, 4_sz }
|
||||
: std::string_view{ bytes };
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(pure)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr operator char32_t& () noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(pure)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr operator const char32_t& () const noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(pure)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr const char32_t& operator* () const noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
[[nodiscard]] TOML_ATTR(pure) constexpr operator char32_t& () noexcept { return value; }
|
||||
[[nodiscard]] TOML_ATTR(pure) constexpr operator const char32_t& () const noexcept { return value; }
|
||||
[[nodiscard]] TOML_ATTR(pure) constexpr const char32_t& operator* () const noexcept { return value; }
|
||||
};
|
||||
static_assert(std::is_trivial_v<utf8_codepoint>);
|
||||
static_assert(std::is_standard_layout_v<utf8_codepoint>);
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_LARGE_FILES
|
||||
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex)
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
#define TOML_ERROR_CHECK (void)0
|
||||
#define TOML_ERROR throw parse_error
|
||||
TOML_ABI_NAMESPACE_START(impl_ex)
|
||||
#else
|
||||
#define TOML_ERROR_CHECK if (err) return nullptr
|
||||
#define TOML_ERROR err.emplace
|
||||
TOML_ABI_NAMESPACE_START(impl_noex)
|
||||
#endif
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_VTABLE_WARNINGS
|
||||
|
||||
struct TOML_INTERFACE utf8_reader_interface
|
||||
{
|
||||
[[nodiscard]]
|
||||
|
@ -226,7 +196,7 @@ namespace toml::impl
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
class TOML_EMPTY_BASES utf8_reader final
|
||||
class TOML_EMPTY_BASES TOML_API utf8_reader final
|
||||
: public utf8_reader_interface
|
||||
{
|
||||
private:
|
||||
|
@ -329,7 +299,7 @@ namespace toml::impl
|
|||
TOML_ERROR_CHECK;
|
||||
|
||||
auto& current = codepoints[cp_idx % 2_sz];
|
||||
current.bytes[current_byte_count++] = static_cast<string_char>(next_byte);
|
||||
current.bytes[current_byte_count++] = static_cast<char>(next_byte);
|
||||
if (decoder.has_code_point())
|
||||
{
|
||||
//store codepoint
|
||||
|
@ -369,22 +339,14 @@ namespace toml::impl
|
|||
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_string_view<Char>, std::string_view) -> utf8_reader<std::basic_string_view<Char>>;
|
||||
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string_view) -> utf8_reader<std::basic_istream<Char>>;
|
||||
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_string_view<Char>, std::string&&) -> utf8_reader<std::basic_string_view<Char>>;
|
||||
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string_view) -> utf8_reader<std::basic_istream<Char>>;
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string&&) -> utf8_reader<std::basic_istream<Char>>;
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
#undef TOML_ERROR_CHECK
|
||||
#define TOML_ERROR_CHECK if (reader.error()) return nullptr
|
||||
#endif
|
||||
|
||||
class TOML_EMPTY_BASES utf8_buffered_reader final
|
||||
class TOML_EMPTY_BASES TOML_API utf8_buffered_reader final
|
||||
: public utf8_reader_interface
|
||||
{
|
||||
public:
|
||||
|
@ -404,91 +366,16 @@ namespace toml::impl
|
|||
size_t negative_offset = {};
|
||||
|
||||
public:
|
||||
|
||||
explicit utf8_buffered_reader(utf8_reader_interface& reader_) noexcept
|
||||
: reader{ reader_ }
|
||||
{}
|
||||
|
||||
[[nodiscard]]
|
||||
const source_path_ptr& source_path() const noexcept override
|
||||
{
|
||||
return reader.source_path();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const utf8_codepoint* read_next() override
|
||||
{
|
||||
TOML_ERROR_CHECK;
|
||||
|
||||
if (negative_offset)
|
||||
{
|
||||
negative_offset--;
|
||||
|
||||
// an entry negative offset of 1 just means "replay the current head"
|
||||
if (!negative_offset)
|
||||
return head;
|
||||
|
||||
// otherwise step back into the history buffer
|
||||
else
|
||||
return history.buffer + ((history.first + history.count - negative_offset) % history_buffer_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// first character read from stream
|
||||
if TOML_UNLIKELY(!history.count && !head)
|
||||
head = reader.read_next();
|
||||
|
||||
// subsequent characters and not eof
|
||||
else if (head)
|
||||
{
|
||||
if TOML_UNLIKELY(history.count < history_buffer_size)
|
||||
history.buffer[history.count++] = *head;
|
||||
else
|
||||
history.buffer[(history.first++ + history_buffer_size) % history_buffer_size] = *head;
|
||||
|
||||
head = reader.read_next();
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const utf8_codepoint* step_back(size_t count) noexcept
|
||||
{
|
||||
TOML_ERROR_CHECK;
|
||||
TOML_ASSERT(history.count);
|
||||
TOML_ASSERT(negative_offset + count <= history.count);
|
||||
|
||||
negative_offset += count;
|
||||
|
||||
return negative_offset
|
||||
? history.buffer + ((history.first + history.count - negative_offset) % history_buffer_size)
|
||||
: head;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool peek_eof() const override
|
||||
{
|
||||
return reader.peek_eof();
|
||||
}
|
||||
|
||||
explicit utf8_buffered_reader(utf8_reader_interface& reader_) noexcept;
|
||||
const source_path_ptr& source_path() const noexcept override;
|
||||
const utf8_codepoint* read_next() override;
|
||||
const utf8_codepoint* step_back(size_t count) noexcept;
|
||||
bool peek_eof() const override;
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
[[nodiscard]]
|
||||
optional<parse_error>&& error() noexcept override
|
||||
{
|
||||
return reader.error();
|
||||
}
|
||||
|
||||
optional<parse_error>&& error() noexcept override;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#undef TOML_ERROR_CHECK
|
||||
#undef TOML_ERROR
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
TOML_POP_WARNINGS
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_PADDING_WARNINGS
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
//# {{
|
||||
#include "toml_preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
#if !TOML_PARSER
|
||||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "toml_utf8_streams.h"
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
#undef TOML_ERROR_CHECK
|
||||
#define TOML_ERROR_CHECK if (reader.error()) return nullptr
|
||||
#endif
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex)
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
utf8_buffered_reader::utf8_buffered_reader(utf8_reader_interface& reader_) noexcept
|
||||
: reader{ reader_ }
|
||||
{}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const source_path_ptr& utf8_buffered_reader::source_path() const noexcept
|
||||
{
|
||||
return reader.source_path();
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const utf8_codepoint* utf8_buffered_reader::read_next()
|
||||
{
|
||||
TOML_ERROR_CHECK;
|
||||
|
||||
if (negative_offset)
|
||||
{
|
||||
negative_offset--;
|
||||
|
||||
// an entry negative offset of 1 just means "replay the current head"
|
||||
if (!negative_offset)
|
||||
return head;
|
||||
|
||||
// otherwise step back into the history buffer
|
||||
else
|
||||
return history.buffer + ((history.first + history.count - negative_offset) % history_buffer_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// first character read from stream
|
||||
if TOML_UNLIKELY(!history.count && !head)
|
||||
head = reader.read_next();
|
||||
|
||||
// subsequent characters and not eof
|
||||
else if (head)
|
||||
{
|
||||
if TOML_UNLIKELY(history.count < history_buffer_size)
|
||||
history.buffer[history.count++] = *head;
|
||||
else
|
||||
history.buffer[(history.first++ + history_buffer_size) % history_buffer_size] = *head;
|
||||
|
||||
head = reader.read_next();
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const utf8_codepoint* utf8_buffered_reader::step_back(size_t count) noexcept
|
||||
{
|
||||
TOML_ERROR_CHECK;
|
||||
TOML_ASSERT(history.count);
|
||||
TOML_ASSERT(negative_offset + count <= history.count);
|
||||
|
||||
negative_offset += count;
|
||||
|
||||
return negative_offset
|
||||
? history.buffer + ((history.first + history.count - negative_offset) % history_buffer_size)
|
||||
: head;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool utf8_buffered_reader::peek_eof() const
|
||||
{
|
||||
return reader.peek_eof();
|
||||
}
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
optional<parse_error>&& utf8_buffered_reader::error() noexcept
|
||||
{
|
||||
return reader.error();
|
||||
}
|
||||
#endif
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
#undef TOML_ERROR_CHECK
|
||||
#undef TOML_ERROR
|
File diff suppressed because it is too large
Load Diff
|
@ -5,9 +5,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define TOML_LIB_MAJOR 1
|
||||
#define TOML_LIB_MINOR 3
|
||||
#define TOML_LIB_PATCH 3
|
||||
#define TOML_LIB_MAJOR 2
|
||||
#define TOML_LIB_MINOR 2
|
||||
#define TOML_LIB_PATCH 0
|
||||
|
||||
#define TOML_LANG_MAJOR 1
|
||||
#define TOML_LANG_MINOR 0
|
||||
|
|
|
@ -165,7 +165,7 @@ void Client::run(server_handle* const localHandle) {
|
|||
reports.tris_count += pass(buffer, model, glm::vec4(pos, std::get<1>(area)), std::get<2>(area));
|
||||
};
|
||||
if (options.culling > 0) {
|
||||
state.contouring->getModels(draw, player.position, options.camera.far, occlusion, offset, options.voxel_density, true);
|
||||
state.contouring->getModels(draw, player.position, options.camera.far_dist, occlusion, offset, options.voxel_density, true);
|
||||
} else {
|
||||
state.contouring->getModels(draw, frustum, offset, options.voxel_density, true);
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ void Client::run(server_handle* const localHandle) {
|
|||
reports.tris_count += pass(buffer, model, glm::vec4(pos, std::get<1>(area)), std::get<2>(area));
|
||||
};
|
||||
if (options.culling > 0) {
|
||||
state.contouring->getModels(draw, player.position, options.camera.far, occlusion, offset, options.voxel_density, false);
|
||||
state.contouring->getModels(draw, player.position, options.camera.far_dist, occlusion, offset, options.voxel_density, false);
|
||||
} else {
|
||||
state.contouring->getModels(draw, frustum, offset, options.voxel_density, false);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,13 @@ constexpr auto MIN_HEIGHT = 480;
|
|||
|
||||
constexpr auto APP_NAME = "Univerxel";
|
||||
|
||||
static void glfw_error_callback(int error, const char* description) {
|
||||
LOG_E("[GLFW] " << error << ": " << description);
|
||||
}
|
||||
|
||||
Window::Window() : ptr(nullptr), targetFPS(60) {
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
|
||||
if (!glfwInit()) {
|
||||
FATAL("Failed to initialize GLFW");
|
||||
}
|
||||
|
@ -60,10 +66,11 @@ bool Window::create(const CreateInfo &opt) {
|
|||
LOG_E("Failed to open GLFW window");
|
||||
return false;
|
||||
}
|
||||
if (opt.client.type == CreateInfo::Client::Type::GL)
|
||||
glfwMakeContextCurrent(ptr);
|
||||
|
||||
// Hide the mouse and enable unlimited mouvement
|
||||
glfwSetInputMode(ptr, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
// glfwSetInputMode(ptr, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
|
||||
// Set the mouse at the center of the screen
|
||||
// TODO: move to input manager
|
||||
|
|
|
@ -6,14 +6,6 @@
|
|||
typedef struct GLFWwindow GLFWwindow;
|
||||
typedef void (*GLFWframebuffersizefun)(GLFWwindow*, int, int);
|
||||
|
||||
struct windowOptions {
|
||||
int targetFPS = 60;
|
||||
int sampling = -1;
|
||||
bool fullscreen = false;
|
||||
|
||||
constexpr int getSamples() const { return sampling > 0 ? (1 << (sampling - 1)) : sampling; }
|
||||
};
|
||||
|
||||
/// GLFW context and window
|
||||
class Window {
|
||||
public:
|
||||
|
@ -63,3 +55,16 @@ private:
|
|||
bool fullscreen;
|
||||
double frameStart;
|
||||
};
|
||||
|
||||
struct windowOptions {
|
||||
#ifdef _WINDOWS
|
||||
//NOTE: prefer vsync due to clock inaccuracy
|
||||
int targetFPS = Window::MIN_FPS - 1;
|
||||
#else
|
||||
int targetFPS = 60;
|
||||
#endif
|
||||
int sampling = -1;
|
||||
bool fullscreen = false;
|
||||
|
||||
constexpr int getSamples() const { return sampling > 0 ? (1 << (sampling - 1)) : sampling; }
|
||||
};
|
||||
|
|
|
@ -55,8 +55,8 @@ public:
|
|||
|
||||
contouring = config["contouring"].value_or(std::string(""));
|
||||
|
||||
camera.far = config["camera"]["far"].value_or(camera.far);
|
||||
camera.near = config["camera"]["near"].value_or(camera.near);
|
||||
camera.far_dist = config["camera"]["far"].value_or(camera.far_dist);
|
||||
camera.near_dist = config["camera"]["near"].value_or(camera.near_dist);
|
||||
camera.fov = config["camera"]["fov"].value_or(camera.fov);
|
||||
control.sensibility = config["control"]["sensibility"].value_or(control.sensibility);
|
||||
control.speed = config["control"]["speed"].value_or(control.speed);
|
||||
|
@ -132,8 +132,8 @@ public:
|
|||
}));
|
||||
config.insert_or_assign("contouring", contouring);
|
||||
config.insert_or_assign("camera", toml::table({
|
||||
{"far", camera.far},
|
||||
{"near", camera.near},
|
||||
{"far", camera.far_dist},
|
||||
{"near", camera.near_dist},
|
||||
{"fov", camera.fov}
|
||||
}));
|
||||
config.insert_or_assign("control", toml::table({
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace contouring {
|
|||
virtual void onEntityUnload(size_t id) = 0;
|
||||
/// Get options
|
||||
virtual std::string getOptions() const = 0;
|
||||
/// Get camera recommended far range
|
||||
/// Get camera recommended far_dist range
|
||||
virtual std::pair<float, float> getFarRange() const = 0;
|
||||
|
||||
/// Get pending elements
|
||||
|
@ -53,7 +53,7 @@ namespace contouring {
|
|||
virtual void getModels(draw_call draw, const std::optional<geometry::Frustum>& frustum, const glm::llvec3& offset, int density, bool solid) = 0;
|
||||
/// Get buffers hitting occlusion rays with model matrices
|
||||
/// @note buffers invalidated after update
|
||||
virtual void getModels(draw_call draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density, bool solid) = 0;
|
||||
virtual void getModels(draw_call draw, const glm::ifvec3 &from, float far_dist, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density, bool solid) = 0;
|
||||
|
||||
/// Get buffer corresponding to entity idx
|
||||
virtual render::Model* getEntityModel(size_t) = 0;
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace contouring {
|
|||
loadedLevels.push_back(LEVELS[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 1; i <= std::max<uint>(1, std::thread::hardware_concurrency() / 2 - 1); i++) {
|
||||
for (size_t i = 1; i <= std::max<size_t>(1, std::thread::hardware_concurrency() / 2 - 1); i++) {
|
||||
workers.emplace_back([&] {
|
||||
#if TRACY_ENABLE
|
||||
tracy::SetThreadName("Contouring");
|
||||
|
@ -52,7 +52,7 @@ namespace contouring {
|
|||
if (entity_area_job_t job; entityLoadQueue.pop(job)) {
|
||||
ZoneScopedN("Entity");
|
||||
render::Model::Data data;
|
||||
typeof(render::Model::Data::indices) idx;
|
||||
render::Model::Data::indices_t idx;
|
||||
for (uint8_t x = 0; x < job.size.x; x++) {
|
||||
for (uint8_t y = 0; y < job.size.y; y++) {
|
||||
for (uint8_t z = 0; z < job.size.z; z++) {
|
||||
|
@ -302,7 +302,7 @@ namespace contouring {
|
|||
}
|
||||
}
|
||||
|
||||
void FlatDualMC::render(const surrounding::corners &surrounding, typeof(render::Model::Data::indices) &out, std::vector<render::VertexData> &tmp, Layer layer) const {
|
||||
void FlatDualMC::render(const surrounding::corners &surrounding, render::Model::Data::indices_t &out, std::vector<render::VertexData> &tmp, Layer layer) const {
|
||||
const int SIZE = CHUNK_LENGTH + 3;
|
||||
std::array<dualmc::DualMC<float>::Point, SIZE * SIZE * SIZE> grid;
|
||||
{
|
||||
|
@ -338,13 +338,13 @@ namespace contouring {
|
|||
std::vector<dualmc::Tri> dmc_tris;
|
||||
|
||||
dualmc::DualMC<float> builder;
|
||||
builder.buildTris(&grid.front(), SIZE, SIZE, SIZE, iso, world::materials::textures_map.cbegin(), world::materials::roughness.cbegin(),
|
||||
builder.buildTris(&grid.front(), SIZE, SIZE, SIZE, iso, world::materials::textures_map.data(), world::materials::roughness.data(),
|
||||
manifold, dmc_vertices, dmc_tris);
|
||||
|
||||
tmp.clear();
|
||||
tmp.reserve(dmc_vertices.size());
|
||||
constexpr auto HALF_MANTISSA = 10;
|
||||
std::transform(dmc_vertices.begin(), dmc_vertices.end(), std::back_inserter(tmp), [](const dualmc::Vertex &v) {
|
||||
constexpr auto HALF_MANTISSA = 10;
|
||||
return render::VertexData(glm::vec3(meshopt_quantizeFloat(v.x, HALF_MANTISSA),meshopt_quantizeFloat(v.y, HALF_MANTISSA),
|
||||
meshopt_quantizeFloat(v.z, HALF_MANTISSA)), v.w, glm::vec3(0));
|
||||
});
|
||||
|
@ -395,10 +395,10 @@ namespace contouring {
|
|||
}}
|
||||
}
|
||||
|
||||
void FlatDualMC::getModels(draw_call out, const glm::ifvec3& from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density, bool solid) {
|
||||
void FlatDualMC::getModels(draw_call out, const glm::ifvec3& from, float far_dist, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density, bool solid) {
|
||||
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(1.f / density));
|
||||
const auto start = glm::ifvec3(glm::divide(from.as_voxel(density)));
|
||||
const auto dist = far * density / CHUNK_LENGTH;
|
||||
const auto dist = far_dist * density / CHUNK_LENGTH;
|
||||
for (const auto [_, area] : buffers) {
|
||||
const auto area_offset = glm::divide(std::get<0>(area.first).as_voxel());
|
||||
robin_hood::unordered_set<chunk_pos> done;
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace contouring {
|
|||
void getModels(draw_call draw, const std::optional<geometry::Frustum> &frustum, const glm::llvec3 &offset, int density, bool solid) override;
|
||||
/// Get buffers hitting occlusion rays with model matrices
|
||||
/// @note buffers invalidated after update
|
||||
void getModels(draw_call draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density, bool solid) override;
|
||||
void getModels(draw_call draw, const glm::ifvec3 &from, float far_dist, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density, bool solid) override;
|
||||
|
||||
render::Model* getEntityModel(size_t) override;
|
||||
|
||||
|
@ -64,8 +64,8 @@ namespace contouring {
|
|||
|
||||
void enqueue(const area_<chunk_pos> &, const chunk_pos &offset, const world::ChunkContainer &);
|
||||
|
||||
ushort loadDistance = 3;
|
||||
ushort keepDistance = 4;
|
||||
uint16_t loadDistance = 3;
|
||||
uint16_t keepDistance = 4;
|
||||
bool transparency = false;
|
||||
float iso = .1f;
|
||||
bool manifold = true;
|
||||
|
@ -85,7 +85,7 @@ namespace contouring {
|
|||
return static_cast<int>(a) & static_cast<int>(b);
|
||||
}
|
||||
|
||||
void render(const surrounding::corners &surrounding, typeof(render::Model::Data::indices)& idx, std::vector<render::VertexData>& ver, Layer layer) const;
|
||||
void render(const surrounding::corners &surrounding, render::Model::Data::indices_t& idx, std::vector<render::VertexData>& ver, Layer layer) const;
|
||||
void render(const surrounding::corners &surrounding, render::LodModel::LodData& out, std::vector<render::VertexData>& tmp, Layer layer) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace dualmc {
|
|||
|
||||
|
||||
typedef float VertexComponentsType;
|
||||
typedef uint PropertyType;
|
||||
typedef uint32_t PropertyType;
|
||||
typedef uint32_t QuadIndexType;
|
||||
typedef uint32_t TriIndexType;
|
||||
|
||||
|
@ -37,7 +37,10 @@ struct Vertex {
|
|||
Vertex(Vertex const & v);
|
||||
|
||||
// components
|
||||
VertexComponentsType x,y,z;
|
||||
VertexComponentsType x;
|
||||
VertexComponentsType y;
|
||||
VertexComponentsType z;
|
||||
|
||||
// texture
|
||||
PropertyType w;
|
||||
};
|
||||
|
@ -51,7 +54,9 @@ struct Tri {
|
|||
Tri(TriIndexType i0, TriIndexType i1, TriIndexType i2);
|
||||
|
||||
// tri indices
|
||||
TriIndexType i0, i1, i2;
|
||||
TriIndexType i0;
|
||||
TriIndexType i1;
|
||||
TriIndexType i2;
|
||||
|
||||
};
|
||||
|
||||
|
@ -101,7 +106,7 @@ public:
|
|||
Point const *data,
|
||||
int32_t const dimX, int32_t const dimY, int32_t const dimZ,
|
||||
VolumeDataType const iso,
|
||||
ushort const *textures_map,
|
||||
uint16_t const *textures_map,
|
||||
float const *roughness,
|
||||
bool const generateManifold,
|
||||
std::vector<Vertex> &vertices,
|
||||
|
@ -188,7 +193,7 @@ protected:
|
|||
Point const *data;
|
||||
|
||||
/// point to vertex property table
|
||||
ushort const *textures_map;
|
||||
uint16_t const *textures_map;
|
||||
|
||||
/// property roughness table
|
||||
float const *roughness;
|
||||
|
@ -543,7 +548,7 @@ void DualMC<T>::buildTris(
|
|||
Point const * data,
|
||||
int32_t const dimX, int32_t const dimY, int32_t const dimZ,
|
||||
VolumeDataType const iso,
|
||||
ushort const * textures_map,
|
||||
uint16_t const * textures_map,
|
||||
float const * roughness,
|
||||
bool const generateManifold,
|
||||
std::vector<Vertex> & vertices,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../core/world/forward.h"
|
||||
#include <memory>
|
||||
#include <array>
|
||||
|
||||
namespace contouring::surrounding {
|
||||
typedef std::array<std::shared_ptr<const world::client::EdittableChunk>, 8> corners;
|
||||
|
|
|
@ -9,7 +9,7 @@ Camera::Camera(const Controllable* origin, const Camera::options& opt): origin(o
|
|||
Camera::~Camera() { }
|
||||
|
||||
void Camera::updateProjection() {
|
||||
ProjectionMatrix = glm::perspective(o.fov, Window::RATIO, o.near, o.far);
|
||||
ProjectionMatrix = glm::perspective(o.fov, Window::RATIO, o.near_dist, o.far_dist);
|
||||
}
|
||||
|
||||
void Camera::update() {
|
||||
|
|
|
@ -9,8 +9,8 @@ class Camera {
|
|||
public:
|
||||
struct options {
|
||||
float fov = glm::radians(70.f);
|
||||
float near = 0.1;
|
||||
float far = 64;
|
||||
float near_dist = 0.1;
|
||||
float far_dist = 64;
|
||||
};
|
||||
|
||||
Camera(const Controllable*, const options&);
|
||||
|
@ -26,11 +26,11 @@ public:
|
|||
}
|
||||
|
||||
inline geometry::Frustum getFrustum() const { return geometry::Frustum(ViewMatrix, ProjectionMatrix); }
|
||||
inline geometry::Ray getRay() const { return geometry::Ray(origin->position, origin->getDirection(), o.far); }
|
||||
inline geometry::Ray getRay() const { return geometry::Ray(origin->position, origin->getDirection(), o.far_dist); }
|
||||
|
||||
constexpr glm::mat4 getViewMatrix() const { return ViewMatrix; }
|
||||
constexpr glm::mat4 getProjectionMatrix() const { return ProjectionMatrix; }
|
||||
constexpr float getDepth() const { return o.far; }
|
||||
constexpr float getDepth() const { return o.far_dist; }
|
||||
|
||||
private:
|
||||
const Controllable* origin;
|
||||
|
|
|
@ -17,8 +17,8 @@ namespace net::client {
|
|||
}
|
||||
}
|
||||
|
||||
Client::Client(const address& ct,
|
||||
std::function<bool(const data::out_view&, PacketFlags)> onPacket):
|
||||
Client::Client(const net::address& ct,
|
||||
std::function<bool(const data::out_view&, net::PacketFlags)> onPacket):
|
||||
Context(nullptr, nullptr), Connection(nullptr, true, queue::count), onPacket(onPacket)
|
||||
{
|
||||
const char *sni = NULL;
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
|
||||
virtual void setClearColor(glm::vec4) = 0;
|
||||
virtual void reloadShaders(const passOptions &) = 0;
|
||||
virtual void reloadTextures(const std::string &, float mipMapLOD, float anisotropy) = 0;
|
||||
virtual void reloadTextures(const std::string &, float mipMapLOD, int anisotropy) = 0;
|
||||
virtual void setFillMode(bool wireframe) = 0;
|
||||
virtual void setVSync(bool vSync) = 0;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ UI::UI() {
|
|||
|
||||
for(auto file: std::filesystem::directory_iterator("content/textures/")) {
|
||||
if(file.is_directory() && file.path().filename() != "ui")
|
||||
texturePacks.push_back(file.path().filename());
|
||||
texturePacks.push_back(file.path().filename().string());
|
||||
}
|
||||
}
|
||||
UI::~UI() {
|
||||
|
@ -76,6 +76,10 @@ UI::Actions UI::draw(config::client::options &options, state::state &state, cons
|
|||
if (ImGui::SliderInt("FPS", &options.window.targetFPS, Window::MIN_FPS-1, Window::MAX_FPS+1, options.window.targetFPS > Window::MIN_FPS ? (options.window.targetFPS < Window::MAX_FPS ? "%d" : "UNLIMITED") : "VSYNC")){
|
||||
actions |= Actions::FPS;
|
||||
}
|
||||
#ifdef _WINDOWS
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Due to windows clock inaccuracy prefer vsync or unlimited.");
|
||||
#endif
|
||||
|
||||
if (ImGui::Checkbox("Fullscreen", &options.window.fullscreen)){
|
||||
actions |= Actions::FullScreen;
|
||||
|
@ -187,17 +191,17 @@ UI::Actions UI::draw(config::client::options &options, state::state &state, cons
|
|||
{
|
||||
bool changePerspective = false;
|
||||
changePerspective |= ImGui::SliderAngle("FoV", &options.camera.fov, 30, 110);
|
||||
changePerspective |= ImGui::SliderFloat("Near", &options.camera.near, 0.01, 10);
|
||||
changePerspective |= ImGui::SliderFloat("Far", &options.camera.far, farRange.first / options.voxel_density, farRange.second / options.voxel_density);
|
||||
changePerspective |= ImGui::SliderFloat("Near", &options.camera.near_dist, 0.01, 10);
|
||||
changePerspective |= ImGui::SliderFloat("Far", &options.camera.far_dist, farRange.first / options.voxel_density, farRange.second / options.voxel_density);
|
||||
if(changePerspective) {
|
||||
actions |= Actions::Camera;
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
const auto far = std::clamp(options.camera.far, farRange.first / options.voxel_density, farRange.second / options.voxel_density);
|
||||
if(far != options.camera.far) {
|
||||
options.camera.far = far;
|
||||
const auto far_dist = std::clamp(options.camera.far_dist, farRange.first / options.voxel_density, farRange.second / options.voxel_density);
|
||||
if(far_dist != options.camera.far_dist) {
|
||||
options.camera.far_dist = far_dist;
|
||||
actions |= Actions::Camera;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ std::unique_ptr<TextureArray> (*TextureArray::loadFunc)(const std::vector<std::s
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
|
||||
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
|
||||
|
@ -66,7 +67,7 @@ std::optional<Image::properties> Image::Read(const std::string& imagepath, std::
|
|||
return {};
|
||||
}
|
||||
//WONT-FIX: miplevels with size < block size (2 last) are corrupted
|
||||
const uint maxMipmapLevels = 1 + std::floor(std::log2(std::max(info.size.height, info.size.width))) - 2;
|
||||
const uint32_t maxMipmapLevels = 1 + std::floor(std::log2(std::max(info.size.height, info.size.width))) - 2;
|
||||
info.mipmapLevels = std::min(maxMipmapLevels, info.mipmapLevels);
|
||||
|
||||
return info;
|
||||
|
|
|
@ -75,7 +75,8 @@ void indexVBO(const std::vector<PackedVertexData> &in_vertices, std::vector<glm:
|
|||
std::map<PackedVertexData, glm::u16> VertexToOutIndex;
|
||||
|
||||
auto getSimilarVertexIndex_fast = [&] (const PackedVertexData &packed, glm::u16 &out) {
|
||||
if (auto it = VertexToOutIndex.find(packed); it == VertexToOutIndex.end()) {
|
||||
auto it = VertexToOutIndex.find(packed);
|
||||
if (it == VertexToOutIndex.end()) {
|
||||
return false;
|
||||
}else{
|
||||
out = it->second;
|
||||
|
@ -85,7 +86,8 @@ void indexVBO(const std::vector<PackedVertexData> &in_vertices, std::vector<glm:
|
|||
|
||||
out_indices.reserve(in_vertices.size());
|
||||
for (const auto& vertex: in_vertices) {
|
||||
if (glm::u16 index; getSimilarVertexIndex_fast(vertex, index)) {
|
||||
glm::u16 index;
|
||||
if (getSimilarVertexIndex_fast(vertex, index)) {
|
||||
out_indices.push_back(index);
|
||||
} else {
|
||||
out_vertices.push_back(vertex);
|
||||
|
|
|
@ -64,11 +64,12 @@ public:
|
|||
|
||||
/// Preindexed buffer data
|
||||
struct Data {
|
||||
std::vector<glm::u16> indices;
|
||||
using indices_t = std::vector<glm::u16>;
|
||||
indices_t indices;
|
||||
std::vector<PackedVertexData> vertices;
|
||||
|
||||
Data() { }
|
||||
Data(const std::vector<PackedVertexData> &vertices, const std::vector<glm::u16> &indices);
|
||||
Data(const std::vector<PackedVertexData> &vertices, const indices_t &indices);
|
||||
Data(const std::vector<PackedVertexData> &vertices) { index(vertices); }
|
||||
Data(std::istream &in);
|
||||
|
||||
|
|
|
@ -12,12 +12,16 @@
|
|||
using namespace render::gl;
|
||||
|
||||
constexpr auto GL_MAJOR = 4;
|
||||
#if GL_OLD
|
||||
constexpr auto GL_MINOR = 2;
|
||||
#else
|
||||
constexpr auto GL_MINOR = 6;
|
||||
#endif
|
||||
|
||||
#define CONTENT_DIR "content/"
|
||||
#define TEXTURES_DIR CONTENT_DIR "textures/"
|
||||
|
||||
Renderer::Renderer(const renderOptions& options):
|
||||
Renderer::Renderer(const render::renderOptions& options):
|
||||
IndicatorCubeBuffer(Shape::LINE_CUBE), IndicatorSphereBuffer(Shape::LINE_SPHERE)
|
||||
{
|
||||
glGenVertexArrays(1, &VertexArrayID);
|
||||
|
@ -43,7 +47,7 @@ void framebuffer_size_callback(GLFWwindow *, int width, int height) {
|
|||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
bool Renderer::Load(Window& window, const renderOptions& opt, const windowOptions& windOpt) {
|
||||
bool Renderer::Load(Window& window, const render::renderOptions& opt, const windowOptions& windOpt) {
|
||||
Window::CreateInfo windowInfo;
|
||||
windowInfo.pfnResize = framebuffer_size_callback;
|
||||
windowInfo.client = {Window::CreateInfo::Client::Type::GL, GL_MAJOR, GL_MINOR};
|
||||
|
@ -74,7 +78,6 @@ bool Renderer::Load(Window& window, const renderOptions& opt, const windowOption
|
|||
glCullFace(GL_BACK);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
GLint smp;
|
||||
glGetIntegerv(GL_SAMPLES, &smp);
|
||||
|
@ -105,6 +108,8 @@ void Renderer::beginFrame() {
|
|||
}
|
||||
|
||||
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass(bool solid) {
|
||||
if (!solid)
|
||||
glEnable(GL_BLEND);
|
||||
WorldPass->useIt();
|
||||
WorldPass->start(this);
|
||||
return [&](render::LodModel *const buf, glm::mat4 model, glm::vec4 sph, float curv) {
|
||||
|
@ -133,6 +138,7 @@ std::function<size_t(glm::mat4, world::action::Shape, glm::vec4)> Renderer::begi
|
|||
|
||||
void Renderer::postProcess() {
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
glDisable(GL_BLEND);
|
||||
if(SkyEnable) {
|
||||
SkyPass->draw(this);
|
||||
}
|
||||
|
@ -146,15 +152,10 @@ void Renderer::swapBuffer(Window& w) {
|
|||
}
|
||||
|
||||
void Renderer::reloadShaders(const pass::VoxelProgram::options& options) {
|
||||
if (options.transparency) {
|
||||
glEnable(GL_BLEND);
|
||||
} else {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
WorldPass = std::make_unique<pass::WorldProgram>(options);
|
||||
EntityPass = std::make_unique<pass::EntityProgram>(options);
|
||||
}
|
||||
void Renderer::reloadTextures(const std::string& texturePath, float mipMapLOD, float anisotropy) {
|
||||
void Renderer::reloadTextures(const std::string& texturePath, float mipMapLOD, int anisotropy) {
|
||||
unloadTextures();
|
||||
loadTextures(texturePath, mipMapLOD, anisotropy);
|
||||
}
|
||||
|
@ -164,7 +165,7 @@ void Renderer::unloadTextures() {
|
|||
NormalAtlas.reset();
|
||||
TextureAtlas.reset();
|
||||
}
|
||||
void Renderer::loadTextures(const std::string& texturePath, float mipMapLOD, float anisotropy) {
|
||||
void Renderer::loadTextures(const std::string& texturePath, float mipMapLOD, int anisotropy) {
|
||||
std::vector<std::string> terrainTextures;
|
||||
auto makePaths = [&](const std::string& suffix) {
|
||||
terrainTextures.clear();
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
/// Apply camera matrices
|
||||
void lookFrom(const Camera&) override;
|
||||
void reloadShaders(const pass::VoxelProgram::options &) override;
|
||||
void reloadTextures(const std::string &, float mipMapLOD, float anisotropy) override;
|
||||
void reloadTextures(const std::string &, float mipMapLOD, int anisotropy) override;
|
||||
void setFillMode(bool wireframe) override;
|
||||
void setVSync(bool vSync) override;
|
||||
|
||||
|
@ -87,7 +87,7 @@ private:
|
|||
/// Draw skybox
|
||||
bool SkyEnable;
|
||||
|
||||
void loadTextures(const std::string &, float mipMapLOD, float anisotropy);
|
||||
void loadTextures(const std::string &, float mipMapLOD, int anisotropy);
|
||||
void unloadTextures();
|
||||
};
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
#include "../../../../core/utils/logger.hpp"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <array>
|
||||
|
||||
using namespace render::gl;
|
||||
|
||||
|
@ -75,7 +76,9 @@ void applySampler(GLuint textureID, const Texture::sampling& props) {
|
|||
glTextureParameteri(textureID, GL_TEXTURE_MAG_FILTER, getFilter(props.magLinear, props.mipmap));
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MIN_FILTER, getFilter(props.minLinear, props.mipmap));
|
||||
glTextureParameterf(textureID, GL_TEXTURE_LOD_BIAS, props.mipmapLod);
|
||||
#if !GL_OLD
|
||||
glTextureParameterf(textureID, GL_TEXTURE_MAX_ANISOTROPY, props.anisotropy);
|
||||
#endif
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_S, wrap);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_T, wrap);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_R, wrap);
|
||||
|
@ -116,7 +119,7 @@ std::unique_ptr<TextureCube> TextureCube::LoadFromFiles(const std::array<std::st
|
|||
glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &textureID);
|
||||
glTextureStorage2D(textureID, 1, format, header.size.width, header.size.height);
|
||||
|
||||
ushort layer = 0;
|
||||
uint16_t layer = 0;
|
||||
for (auto imagepath = paths.begin(); imagepath != paths.end(); ++imagepath, ++layer) {
|
||||
data.clear();
|
||||
if (!render::Image::Read(*imagepath, data).has_value()) {
|
||||
|
@ -163,7 +166,7 @@ std::unique_ptr<TextureArray> TextureArray::LoadFromFiles(const std::vector<std:
|
|||
glCreateTextures(GL_TEXTURE_2D_ARRAY, 1, &textureID);
|
||||
glTextureStorage3D(textureID, header.mipmapLevels, format, header.size.width, header.size.height, paths.size());
|
||||
|
||||
ushort layer = 0;
|
||||
uint16_t layer = 0;
|
||||
for (auto imagepath = paths.begin(); imagepath != paths.end(); ++imagepath, ++layer) {
|
||||
data.clear();
|
||||
if (!render::Image::Read(*imagepath, data).has_value()) {
|
||||
|
@ -172,7 +175,7 @@ std::unique_ptr<TextureArray> TextureArray::LoadFromFiles(const std::vector<std:
|
|||
GLuint subTextureID = createImage(req, data);
|
||||
auto width = header.size.width;
|
||||
auto height = header.size.height;
|
||||
for (uint level = 0; level < header.mipmapLevels; level++) {
|
||||
for (uint32_t level = 0; level < header.mipmapLevels; level++) {
|
||||
glCopyImageSubData(subTextureID, GL_TEXTURE_2D, level, 0, 0, 0, textureID, GL_TEXTURE_2D_ARRAY, level, 0, 0, layer, width, height, 1);
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
|
|
|
@ -314,16 +314,16 @@ std::optional<uint32_t> Allocator::findMemory(uint32_t typeFilter, VkMemoryPrope
|
|||
return {};
|
||||
}
|
||||
|
||||
void memory::area::write(const void* data, size_t data_size, size_t write_offset) {
|
||||
void render::vk::memory::area::write(const void* data, VkDeviceSize data_size, VkDeviceSize write_offset) {
|
||||
assert(ptr != nullptr && size >= write_offset + data_size);
|
||||
memcpy(static_cast<uint8_t*>(ptr) + write_offset, data, data_size);
|
||||
}
|
||||
void memory::area::read(void* data, size_t data_size, size_t read_offset) {
|
||||
void render::vk::memory::area::read(void* data, VkDeviceSize data_size, VkDeviceSize read_offset) {
|
||||
assert(ptr != nullptr && size >= read_offset + data_size);
|
||||
memcpy(data, static_cast<uint8_t*>(ptr) + read_offset, data_size);
|
||||
}
|
||||
|
||||
void memory::Deleter::operator()(memory::area* area) {
|
||||
void render::vk::memory::Deleter::operator()(render::vk::memory::area* area) {
|
||||
assert(area != nullptr && "Deleting null area");
|
||||
if(owner != nullptr) {
|
||||
for (auto it = owner->areas.begin(); it != owner->areas.end(); ++it) {
|
||||
|
|
|
@ -10,7 +10,7 @@ using namespace render::vk;
|
|||
#define CONTENT_DIR "content/"
|
||||
#define TEXTURES_DIR CONTENT_DIR "textures/"
|
||||
|
||||
CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, const renderOptions &opt): device(device) {
|
||||
CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, const render::renderOptions &opt): device(device) {
|
||||
{ // Graphics command pool
|
||||
vkGetDeviceQueue(device, info.queueIndices.graphicsFamily.value(), 0, &graphicsQueue);
|
||||
VkCommandPoolCreateInfo poolInfo{};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
using namespace render::vk;
|
||||
|
||||
Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const renderOptions &options): device(device) {
|
||||
Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render::renderOptions &options): device(device) {
|
||||
const auto hasSamples = info.samples > 1;
|
||||
{ // Render pass
|
||||
VkAttachmentDescription colorAttachment{};
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace render::vk {
|
|||
|
||||
struct Subpass {
|
||||
VkShaderModule vsShader;
|
||||
VkShaderModule gsShader = nullptr;
|
||||
VkShaderModule gsShader = NULL;
|
||||
VkShaderModule fsShader;
|
||||
VkPipelineLayout layout;
|
||||
VkPipeline pipeline;
|
||||
|
|
|
@ -30,7 +30,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugValidationCallback(
|
|||
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
|
||||
void *pUserData);
|
||||
|
||||
Renderer::Renderer(VkInstance instance, VkDevice device, const PhysicalDeviceInfo& info, const renderOptions& opt):
|
||||
Renderer::Renderer(VkInstance instance, VkDevice device, const PhysicalDeviceInfo& info, const render::renderOptions& opt):
|
||||
options(opt), instance(instance), surface(info.surface), device(device),
|
||||
physicalInfo(std::make_unique<PhysicalDeviceInfo>(info)) {
|
||||
if constexpr(VALIDATION_LAYER) {
|
||||
|
@ -163,7 +163,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugValidationCallback(VkDebugUtilsMessageSeveri
|
|||
return VK_FALSE;
|
||||
}
|
||||
|
||||
bool Renderer::Load(Window& window, const renderOptions& opt, const windowOptions& windOpt) {
|
||||
bool Renderer::Load(Window& window, const render::renderOptions& opt, const windowOptions& windOpt) {
|
||||
Window::CreateInfo windowInfo;
|
||||
windowInfo.pfnResize = on_resize_callback;
|
||||
windowInfo.client = {Window::CreateInfo::Client::Type::VK, 0, 0};
|
||||
|
@ -297,9 +297,9 @@ bool Renderer::Load(Window& window, const renderOptions& opt, const windowOption
|
|||
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
|
||||
|
||||
uint bestScore = 0;
|
||||
uint32_t bestScore = 0;
|
||||
for(const auto& device: devices) {
|
||||
uint score = 1;
|
||||
uint32_t score = 1;
|
||||
auto infos = PhysicalDeviceInfo(window.getPtr(), device, surface, windOpt.getSamples(), windOpt.targetFPS < Window::MIN_FPS);
|
||||
|
||||
{
|
||||
|
@ -517,11 +517,11 @@ void Renderer::swapBuffer(Window&) {
|
|||
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||
}
|
||||
|
||||
void Renderer::reloadShaders(const passOptions& opt) {
|
||||
void Renderer::reloadShaders(const render::passOptions& opt) {
|
||||
options.voxel = opt;
|
||||
recreateSwapChain();
|
||||
}
|
||||
void Renderer::reloadTextures(const std::string& textures, float mipmap, float anisotropy) {
|
||||
void Renderer::reloadTextures(const std::string& textures, float mipmap, int anisotropy) {
|
||||
vkDeviceWaitIdle(device);
|
||||
commandCenter->free();
|
||||
commandCenter->loadAtlases(textures, anisotropy, mipmap);
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
/// Apply camera matrices
|
||||
void lookFrom(const Camera &) override;
|
||||
void reloadShaders(const passOptions &) override;
|
||||
void reloadTextures(const std::string &, float mipMapLOD, float anisotropy) override;
|
||||
void reloadTextures(const std::string &, float mipMapLOD, int anisotropy) override;
|
||||
void setFillMode(bool wireframe) override;
|
||||
void setVSync(bool vSync) override;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "Buffers.hpp"
|
||||
#include "../Allocator.hpp"
|
||||
#include "../../../../core/utils/logger.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace render::vk;
|
||||
|
||||
|
@ -110,7 +111,7 @@ memory::ptr render::vk::createBuffers(const std::vector<Buffer::requirement>& re
|
|||
VkDeviceSize stagingSize = 0;
|
||||
for (auto& requirement: requirements)
|
||||
if (requirement.view)
|
||||
stagingSize = std::max(stagingSize, requirement.size);
|
||||
stagingSize = std::max<VkDeviceSize>(stagingSize, requirement.size);
|
||||
|
||||
// Copy views
|
||||
// MAYBE: allow single copy
|
||||
|
@ -141,15 +142,15 @@ memory::ptr render::vk::createBuffers(const std::vector<Buffer::requirement>& re
|
|||
|
||||
void Buffer::MakeDefault() { }
|
||||
|
||||
std::unique_ptr<WritableBuffer> WritableBuffer::Create(size_t size, Usage usage, const data_view write) {
|
||||
std::unique_ptr<WritableBuffer> WritableBuffer::Create(size_t size, Usage usage, const render::data_view write) {
|
||||
vk::Buffer::info tmp;
|
||||
auto mem = createBuffer(size, static_cast<int>(usage), memory::HOST_EASILY_WRITABLE, write, tmp);
|
||||
return std::unique_ptr<WritableBuffer>(new WritableBuffer(tmp.ref, std::move(mem), tmp.offset));
|
||||
}
|
||||
void WritableBuffer::write(const data_view view, size_t offset) {
|
||||
void WritableBuffer::write(const render::data_view view, size_t offset) {
|
||||
memory->write(view.ptr, view.size, memOffset + offset);
|
||||
}
|
||||
void WritableBuffer::read(data_ref ref, size_t offset) {
|
||||
void WritableBuffer::read(render::data_ref ref, size_t offset) {
|
||||
memory->read(ref.ptr, ref.size, memOffset + offset);
|
||||
}
|
||||
|
||||
|
@ -172,7 +173,7 @@ void ShortIndexedVertexBuffer::ClearUnused(uint32_t image) {
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<ShortIndexedVertexBuffer> ShortIndexedVertexBuffer::Create(const data_view vertices, const data_view indices) {
|
||||
std::unique_ptr<ShortIndexedVertexBuffer> ShortIndexedVertexBuffer::Create(const render::data_view vertices, const render::data_view indices) {
|
||||
std::vector<vk::Buffer::info> tmp;
|
||||
auto mem = createBuffers({{vertices.size, Usage::VERTEX, vertices}, {indices.size, Usage::INDEX, indices}}, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, tmp);
|
||||
return std::unique_ptr<ShortIndexedVertexBuffer>(new ShortIndexedVertexBuffer(tmp.at(0).ref, tmp.at(1).ref, std::move(mem)));
|
||||
|
@ -193,6 +194,6 @@ void BufferGroup::free() {
|
|||
refs.clear();
|
||||
memory = memory::GetNull();
|
||||
}
|
||||
void BufferGroup::write(size_t i, const data_view view) {
|
||||
void BufferGroup::write(size_t i, const render::data_view view) {
|
||||
memory->write(view.ptr, view.size, refs.at(i).offset);
|
||||
}
|
|
@ -16,7 +16,7 @@ public:
|
|||
static void MakeDefault();
|
||||
|
||||
struct info {
|
||||
VkBuffer ref = nullptr;
|
||||
VkBuffer ref = NULL;
|
||||
VkDeviceSize offset = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ public:
|
|||
static void MakeDefault();
|
||||
|
||||
struct info {
|
||||
VkImage ref = nullptr;
|
||||
VkImageView view = nullptr;
|
||||
VkImage ref = NULL;
|
||||
VkImageView view = NULL;
|
||||
VkDeviceSize offset = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "../forward.hpp"
|
||||
#include <memory>
|
||||
#include <array>
|
||||
|
||||
namespace render::vk { struct Allocation; }
|
||||
namespace render::vk::memory {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../../core/utils/logger.hpp"
|
||||
#include "Chunk.hpp"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace world::client;
|
||||
|
||||
|
@ -31,7 +32,7 @@ void DistantUniverse::update(voxel_pos pos, float deltaTime) {
|
|||
{ // Update alive areas
|
||||
ZoneScopedN("World");
|
||||
auto rng = std::mt19937(std::rand());
|
||||
const auto contouringThreshold = rng.max() / (1 + contouring->getQueueSize());
|
||||
const auto contouringThreshold = UINT32_MAX / (1 + contouring->getQueueSize());
|
||||
for (auto& area: areas) {
|
||||
ZoneScopedN("Area");
|
||||
const bool chunkChangeArea = (false && area.second->move(glm::vec3(deltaTime))) || chunkChange; // TODO: area.velocity
|
||||
|
@ -59,7 +60,7 @@ void DistantUniverse::update(voxel_pos pos, float deltaTime) {
|
|||
std::vector<long> missingDist;
|
||||
const auto cl_area = std::dynamic_pointer_cast<Area>(area.second);
|
||||
//TODO: use easy sphere fill
|
||||
const int queryDistance = std::min(options.loadDistance, serverDistance);
|
||||
const auto queryDistance = std::min<int>(options.loadDistance, serverDistance);
|
||||
for (int x = -queryDistance; x <= queryDistance; x++) {
|
||||
for (int y = -queryDistance; y <= queryDistance; y++) {
|
||||
for (int z = -queryDistance; z <= queryDistance; z++) {
|
||||
|
@ -225,8 +226,8 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
}
|
||||
// MAYBE: use Voxel swag bit to flag full void/air chunks to avoiding MISSING_CHUNKS
|
||||
// MAYBE: then create virtual or non chunk of single material
|
||||
ushort full = 0;
|
||||
ushort total = 0;
|
||||
uint16_t full = 0;
|
||||
uint16_t total = 0;
|
||||
while (!packet.isFull()) {
|
||||
region_chunk_pos cpos;
|
||||
Voxel voxel;
|
||||
|
@ -455,12 +456,12 @@ bool DistantUniverse::onPacket(const data::out_view& buf, net::PacketFlags) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void DistantUniverse::emit(const action::packet &action) {
|
||||
if(const auto move = std::get_if<action::Move>(&action)) {
|
||||
void DistantUniverse::emit(const world::action::packet &action) {
|
||||
if(const auto move = std::get_if<world::action::Move>(&action)) {
|
||||
peer.send(net::PacketWriter::Of(net::client_packet_type::MOVE, move->pos), net::client::queue::MOVE, 1);
|
||||
} else if(const auto message = std::get_if<action::Message>(&action)) {
|
||||
} else if(const auto message = std::get_if<world::action::Message>(&action)) {
|
||||
peer.send(net::PacketWriter::Of(net::client_packet_type::MESSAGE, message->text.data(), message->text.size()));
|
||||
} else if(const auto fill = std::get_if<action::FillShape>(&action)) {
|
||||
} else if(const auto fill = std::get_if<world::action::FillShape>(&action)) {
|
||||
peer.send(net::PacketWriter::Of(net::client_packet_type::FILL_SHAPE, *fill));
|
||||
if (options.editPrediction) {
|
||||
ZoneScopedN("Fill");
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace world::client {
|
|||
uint64_t moveCounter = 0;
|
||||
|
||||
options options;
|
||||
ushort serverDistance;
|
||||
uint16_t serverDistance;
|
||||
size_t floodfillLimit = CHUNK_SIZE;
|
||||
|
||||
net::client::Client peer;
|
||||
|
|
|
@ -67,7 +67,7 @@ void LocalUniverse::update(voxel_pos pos, float) {
|
|||
contouring->update(pos, *handle->areas);
|
||||
}
|
||||
|
||||
void LocalUniverse::emit(const action::packet &packet) {
|
||||
void LocalUniverse::emit(const world::action::packet &packet) {
|
||||
handle->emit(packet);
|
||||
}
|
||||
Universe::ray_result LocalUniverse::raycast(const geometry::Ray& ray) const {
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace world::client {
|
|||
bool editHandling = true;
|
||||
};
|
||||
struct connection: net::address {
|
||||
connection(): net::address{"localhost", 4242} { }
|
||||
connection(): net::address{"127.0.0.1", 4242} { }
|
||||
};
|
||||
|
||||
/// Update edits and contouring
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "math.hpp"
|
||||
|
||||
using namespace glm;
|
||||
ifvec3::ifvec3(const llvec3 &pos, uint density) {
|
||||
ifvec3::ifvec3(const llvec3 &pos, u32 density) {
|
||||
const auto d = IDX_LENGTH2 * density;
|
||||
raw = glm::divide(pos, glm::uvec3(d));
|
||||
offset = glm::vec3(rem(pos.x, d), rem(pos.y, d), rem(pos.z, d));
|
||||
|
@ -22,6 +22,6 @@ void ifvec3::center() {
|
|||
double ifvec3::dist(const ifvec3& p) const {
|
||||
return glm::length(glm::dvec3(raw - p.raw)) + glm::length(offset - p.offset);
|
||||
}
|
||||
ifvec3 ifvec3::divide(uint m) const {
|
||||
ifvec3 ifvec3::divide(u32 m) const {
|
||||
return ifvec3(glm::divide(raw, glm::ucvec3(m)), glm::divide(offset, glm::uvec3(m)), false);
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
namespace glm {
|
||||
typedef vec<3, long long> llvec3;
|
||||
typedef vec<3, long> lvec3;
|
||||
typedef vec<3, ushort> usvec3;
|
||||
typedef vec<3, uint16_t> usvec3;
|
||||
typedef vec<3, unsigned char> ucvec3;
|
||||
|
||||
const auto IDX_LENGTH = 32;
|
||||
|
@ -23,7 +23,7 @@ namespace glm {
|
|||
ifvec3(const raw_t &raw, const offset_t &offset, bool recenter = true) : raw(raw), offset(offset) {
|
||||
if(recenter) center();
|
||||
}
|
||||
ifvec3(const glm::llvec3 &pos, uint density = 1);
|
||||
ifvec3(const glm::llvec3 &pos, glm::u32 density = 1);
|
||||
|
||||
raw_t raw;
|
||||
offset_t offset;
|
||||
|
@ -33,7 +33,7 @@ namespace glm {
|
|||
glm::llvec3 raw_as_long() const;
|
||||
double dist(const ifvec3 &p) const;
|
||||
|
||||
ifvec3 divide(uint m = IDX_LENGTH) const;
|
||||
ifvec3 divide(glm::u32 m = IDX_LENGTH) const;
|
||||
|
||||
inline const ifvec3 &operator+=(const offset_t &v) {
|
||||
offset += v;
|
||||
|
|
|
@ -26,13 +26,13 @@ namespace glm {
|
|||
return glm::abs(glm::abs(a) - glm::abs(b));
|
||||
}
|
||||
|
||||
constexpr uint inline rem(long long value, uint m) {
|
||||
constexpr glm::u32 inline rem(long long value, glm::u32 m) {
|
||||
return value < 0 ? ((value+1) % (long long)m) + m - 1 : value % (long long)m;
|
||||
}
|
||||
constexpr long inline div(long long value, uint m) {
|
||||
constexpr long inline div(long long value, glm::u32 m) {
|
||||
return value < 0 ? ((value+1) / (long long)m) - 1 : value / (long long)m;
|
||||
}
|
||||
constexpr float inline div(float value, uint m) {
|
||||
constexpr float inline div(float value, glm::u32 m) {
|
||||
return value < 0 ? ((value+1) / m) - 1 : value / m;
|
||||
}
|
||||
constexpr ucvec3 inline modulo(const llvec3& value, const ucvec3& m = ucvec3(IDX_LENGTH)) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Box.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace geometry {
|
||||
/// Bounding frustum
|
||||
|
@ -72,9 +73,9 @@ namespace geometry {
|
|||
for (int i = 0; i<6; i++) {
|
||||
//pick closest point to plane and check if it behind the plane
|
||||
//if yes - object outside frustum
|
||||
float d = std::max(box.Min.x * planes[i].x, box.Max.x * planes[i].x)
|
||||
+ std::max(box.Min.y * planes[i].y, box.Max.y * planes[i].y)
|
||||
+ std::max(box.Min.z * planes[i].z, box.Max.z * planes[i].z)
|
||||
float d = std::max<float>(box.Min.x * planes[i].x, box.Max.x * planes[i].x)
|
||||
+ std::max<float>(box.Min.y * planes[i].y, box.Max.y * planes[i].y)
|
||||
+ std::max<float>(box.Min.z * planes[i].z, box.Max.z * planes[i].z)
|
||||
+ planes[i].w;
|
||||
inside &= d > 0;
|
||||
//return false; //with flag works faster
|
||||
|
|
|
@ -46,7 +46,7 @@ enum class server_packet_type: uint8_t {
|
|||
/// empty: all sent
|
||||
CHUNK = 18,
|
||||
/// Uncompressed chunk changes
|
||||
/// {area_id, {chunk_pos, ushort(count), Chunk::Edit[]}[]}
|
||||
/// {area_id, {chunk_pos, uint16_t(count), Chunk::Edit[]}[]}
|
||||
RAW_EDITS = 19,
|
||||
/// Chunk changes instruction
|
||||
/// action::FillShape
|
||||
|
@ -68,7 +68,7 @@ enum class server_packet_type: uint8_t {
|
|||
/// zstd dict
|
||||
COMPRESSION = 64,
|
||||
/// Server capabilities
|
||||
/// ushort(loadDistance), bool(predictable), (if predictable) size_t(floodfillLimit)
|
||||
/// uint16_t(loadDistance), bool(predictable), (if predictable) size_t(floodfillLimit)
|
||||
//MAYBE: use uint8_t flags
|
||||
CAPABILITIES = 65,
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#include "logger.hpp"
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
|
||||
namespace logger {
|
||||
std::_Put_time<char> now() {
|
||||
const auto tp = std::chrono::system_clock::now();
|
||||
const auto timet = std::chrono::system_clock::to_time_t(tp);
|
||||
return std::put_time(std::localtime(&timet), "%Y-%m-%d %X");
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "colors.h"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
|
||||
#define _OUT(expr) {std::ostringstream oss; oss << expr << std::endl; std::cout << oss.str();}
|
||||
#define LOG(expr) _OUT("[" << BOLD << logger::now() << END_COLOR << "] " << BOLD << expr << END_COLOR)
|
||||
|
@ -22,5 +25,9 @@
|
|||
#define FATAL(expr) LOG_E(expr); exit(EXIT_FAILURE)
|
||||
|
||||
namespace logger {
|
||||
std::_Put_time<char> now();
|
||||
inline auto now() {
|
||||
const auto tp = std::chrono::system_clock::now();
|
||||
const auto timet = std::chrono::system_clock::to_time_t(tp);
|
||||
return std::put_time(std::localtime(&timet), "%Y-%m-%d %X");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ using namespace world;
|
|||
|
||||
Chunk::Chunk(std::istream& str, bool rle) {
|
||||
if(rle) {
|
||||
ushort i = 0;
|
||||
uint16_t i = 0;
|
||||
while(!str.eof()) {
|
||||
ushort count;
|
||||
uint16_t count;
|
||||
Voxel voxel;
|
||||
str.read(reinterpret_cast<char *>(&count), sizeof(count));
|
||||
str.read(reinterpret_cast<char *>(&voxel), sizeof(voxel));
|
||||
|
|
|
@ -29,7 +29,7 @@ std::optional<Faces> EdittableChunk::update(float deltaTime, bool animate) {
|
|||
}
|
||||
}
|
||||
|
||||
void EdittableChunk::invalidate(ushort idx) {
|
||||
void EdittableChunk::invalidate(uint16_t idx) {
|
||||
invalidate(
|
||||
((!getNeighborIdx(idx, Face::Up).has_value()) & Faces::Up) |
|
||||
((!getNeighborIdx(idx, Face::Down).has_value()) & Faces::Down) |
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace world {
|
|||
/// Distance management
|
||||
struct options {
|
||||
/// Radius in chunks to load if missing
|
||||
ushort loadDistance = 5;
|
||||
uint16_t loadDistance = 5;
|
||||
/// Radius in chunks to keep in memory
|
||||
ushort keepDistance = 6;
|
||||
uint16_t keepDistance = 6;
|
||||
};
|
||||
|
||||
/// Universe voxel ray intersection
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace world {
|
|||
return (value & MATERIAL_MASK) >> 3;
|
||||
}
|
||||
/// Texture idx
|
||||
constexpr inline ushort texture() const {
|
||||
constexpr inline uint16_t texture() const {
|
||||
return materials::textures_map[material()];
|
||||
}
|
||||
|
||||
|
|
|
@ -179,8 +179,10 @@ public:
|
|||
|
||||
private:
|
||||
const uint16_t radius;
|
||||
const uint max_i, max_j;
|
||||
uint i, j;
|
||||
const uint32_t max_i;
|
||||
const uint32_t max_j;
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
};
|
||||
|
||||
/// Anti-aliased sphere
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace world::materials {
|
|||
std::string texture;
|
||||
float roughness;
|
||||
bool solid;
|
||||
//ushort break_to
|
||||
//uint16_t break_to
|
||||
};
|
||||
|
||||
//MAYBE: index name enum
|
||||
|
@ -24,11 +24,11 @@ namespace world::materials {
|
|||
|
||||
/// Materials count
|
||||
static const auto count = 9;
|
||||
static_assert(count < (USHRT_MAX >> 4)); //NOTE: for byte packing see Voxel
|
||||
static_assert(count < (USHRT_MAX >> 4), "for byte packing see Voxel");
|
||||
/// Materials names
|
||||
static const std::array<std::string, count> names = {{"Air", "Dirt", "Grass", "Sand", "Rock", "Wall", "Path", "Alien metal", "Water"}};
|
||||
/// Materials textures
|
||||
static const std::array<ushort, count> textures_map = {{0, 2, 9, 1, 7, 6, 3, 8, 12}};
|
||||
static const std::array<uint16_t, count> textures_map = {{0, 2, 9, 1, 7, 6, 3, 8, 12}};
|
||||
/// Materials roughness.
|
||||
/// -1: slope, 0: normal, 1: cube
|
||||
static const std::array<float, count> roughness = {{0, 0, 0, 0, 0, 0, -1, .8, 0}};
|
||||
|
|
|
@ -23,8 +23,12 @@ int main(int argc, char *argv[]){
|
|||
auto options = config::options(argc > 1 ? argv[1] : config::DEFAULT_FILE);
|
||||
options.save();
|
||||
|
||||
std::optional<Server> server = options.hasServer() ? std::make_optional<Server>(options.getServer()) : std::nullopt;
|
||||
std::optional<Client> client = options.hasClient() ? std::make_optional<Client>(options.getClient()) : std::nullopt;
|
||||
std::optional<Server> server;
|
||||
if (options.hasServer())
|
||||
server.emplace(options.getServer());
|
||||
std::optional<Client> client;
|
||||
if (options.hasClient())
|
||||
client.emplace(options.getClient());
|
||||
|
||||
const auto serverTask = [&] {
|
||||
#if TRACY_ENABLE
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
world.loadDistance = config["world"]["load_distance"].value_or(world.loadDistance);
|
||||
world.keepDistance = config["world"]["keep_distance"].value_or(world.keepDistance);
|
||||
world.folderPath = config["world"]["path"].value_or(world.folderPath);
|
||||
world.floodFillLimit = config["world"]["max_part_size"].value_or<int64_t>(world.floodFillLimit);
|
||||
world.floodFillLimit = config["world"]["max_part_size"].value_or((int64_t)world.floodFillLimit);
|
||||
}
|
||||
|
||||
toml::table save() {
|
||||
|
|
|
@ -25,10 +25,10 @@ namespace net::server {
|
|||
}
|
||||
}
|
||||
|
||||
Server::Server(const exposure& ct,
|
||||
Server::Server(const net::exposure& ct,
|
||||
std::function<std::optional<uint16_t>(Peer*)> onConnect,
|
||||
std::function<bool(Peer*, bool, uint16_t)> onDisconnect,
|
||||
std::function<bool(Peer*, const data::out_view&, PacketFlags)> onPacket):
|
||||
std::function<bool(Peer*, const data::out_view&, net::PacketFlags)> onPacket):
|
||||
Context(ct.max_connections, ct.cert.c_str(), ct.key.c_str(), connection_callback, this),
|
||||
onConnect(onConnect), onDisconnect(onDisconnect), onPacket(onPacket), max_connections(ct.max_connections)
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
using namespace world::server;
|
||||
|
||||
Chunk::Chunk(const chunk_pos& pos, const std::unique_ptr<generator::Abstract>& rnd): world::Chunk() {
|
||||
Chunk::Chunk(const chunk_pos& pos, const std::unique_ptr<world::generator::Abstract>& rnd): world::Chunk() {
|
||||
rnd->generate(pos, voxels);
|
||||
}
|
||||
#include <iostream>
|
||||
|
@ -15,7 +15,7 @@ Chunk::~Chunk() { }
|
|||
|
||||
world::Voxel Chunk::write(std::ostream& str, bool rle) const {
|
||||
Voxel::material_t majMat = UINT16_MAX;
|
||||
ushort majCounter = 1;
|
||||
uint16_t majCounter = 1;
|
||||
size_t visibleDensity = 0;
|
||||
const auto doMaj = [&](const Voxel& current) {
|
||||
if (current.material() == majMat) {
|
||||
|
@ -30,8 +30,8 @@ world::Voxel Chunk::write(std::ostream& str, bool rle) const {
|
|||
visibleDensity += current.density() * current.is_visible();
|
||||
};
|
||||
if (rle) {
|
||||
const auto *it = voxels.begin();
|
||||
ushort counter = 1;
|
||||
auto it = voxels.begin();
|
||||
uint16_t counter = 1;
|
||||
Voxel current = *it;
|
||||
while(true) {
|
||||
++it;
|
||||
|
@ -61,14 +61,14 @@ world::Voxel Chunk::write(std::ostream& str, bool rle) const {
|
|||
return Voxel(majMat, visibleDensity / CHUNK_SIZE);
|
||||
}
|
||||
|
||||
void Chunk::set(ushort idx, const Voxel& val) {
|
||||
void Chunk::set(uint16_t idx, const world::Voxel& val) {
|
||||
modified = modified || (voxels[idx].value != val.value);
|
||||
voxels[idx] = val;
|
||||
}
|
||||
void Chunk::setAt(const chunk_voxel_pos& pos, const Voxel& val) {
|
||||
void Chunk::setAt(const chunk_voxel_pos& pos, const world::Voxel& val) {
|
||||
set(glm::toIdx(pos), val);
|
||||
}
|
||||
std::optional<world::Item> Chunk::replace(chunk_voxel_idx idx, const Voxel& val, float) {
|
||||
std::optional<world::Item> Chunk::replace(chunk_voxel_idx idx, const world::Voxel& val, float) {
|
||||
const auto res = voxels[idx];
|
||||
set(idx, val);
|
||||
return {world::Item{res.density(), res.material()}};
|
||||
|
|
|
@ -56,7 +56,7 @@ void SharedUniverse::broadcastEntities() {
|
|||
Universe::broadcastEntities();
|
||||
}
|
||||
|
||||
std::shared_ptr<Chunk> SharedUniverse::createChunk(const chunk_pos &pos, const std::unique_ptr<generator::Abstract> &rnd) const {
|
||||
std::shared_ptr<Chunk> SharedUniverse::createChunk(const chunk_pos &pos, const std::unique_ptr<world::generator::Abstract> &rnd) const {
|
||||
return std::make_shared<SharedChunk>(pos, rnd);
|
||||
}
|
||||
std::shared_ptr<Chunk> SharedUniverse::createChunk(std::istream &str) const {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../../core/world/actions.hpp"
|
||||
#include "../../core/world/models.hpp"
|
||||
#include "../../core/net/io.hpp"
|
||||
#include <glm/common.hpp>
|
||||
|
||||
using namespace world::server;
|
||||
|
||||
|
@ -72,7 +73,7 @@ Universe::Universe(const Universe::options &options): host(options.connection,
|
|||
}
|
||||
|
||||
// Workers
|
||||
for (size_t i = 0; i < std::max<uint>(1, std::thread::hardware_concurrency() / 2 - 1); i++) {
|
||||
for (size_t i = 0; i < std::max<size_t>(1, std::thread::hardware_concurrency() / 2 - 1); i++) {
|
||||
workers.emplace_back([&] {
|
||||
#if TRACY_ENABLE
|
||||
tracy::SetThreadName("Chunks");
|
||||
|
@ -471,7 +472,7 @@ std::optional<uint16_t> Universe::onConnect(net::server::Peer* peer) {
|
|||
peer->ctx = client;
|
||||
|
||||
{
|
||||
auto packet = PacketWriter(server_packet_type::CAPABILITIES, sizeof(loadDistance) + sizeof(bool));
|
||||
auto packet = PacketWriter(server_packet_type::CAPABILITIES, sizeof(loadDistance) + sizeof(bool) + sizeof(floodFillLimit) * PREDICTABLE);
|
||||
packet.write(loadDistance);
|
||||
packet.write(PREDICTABLE);
|
||||
if constexpr (PREDICTABLE) {
|
||||
|
@ -741,7 +742,7 @@ bool Universe::isAreaFree(const area_<voxel_pos> &pos, const geometry::Shape sha
|
|||
return false;
|
||||
}
|
||||
|
||||
world::ItemList Universe::set(const area_<voxel_pos>& pos, int radius, action::Shape shape, const Voxel& val) {
|
||||
world::ItemList Universe::set(const area_<voxel_pos>& pos, int radius, world::action::Shape shape, const world::Voxel& val) {
|
||||
ZoneScopedN("Fill");
|
||||
ItemList list;
|
||||
const bool stupidClient = host.anyPeer([&](net::server::Peer *peer) {
|
||||
|
@ -764,8 +765,8 @@ world::ItemList Universe::set(const area_<voxel_pos>& pos, int radius, action::S
|
|||
voxel_pos min = voxel_pos(INT64_MAX);
|
||||
voxel_pos max = voxel_pos(INT64_MIN);
|
||||
for(auto full: part) {
|
||||
min = glm::min(min, full);
|
||||
max = glm::max(max, full);
|
||||
min = glm::min<3, long long>(min, full);
|
||||
max = glm::max<3, long long>(max, full);
|
||||
}
|
||||
const auto size = max - min;
|
||||
const chunk_pos scale = chunk_pos(1) + glm::divide(size);
|
||||
|
@ -877,7 +878,7 @@ bool Universe::movePlayer(data::generational::id id, glm::ifvec3 pos) {
|
|||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<Chunk> Universe::createChunk(const chunk_pos &pos, const std::unique_ptr<generator::Abstract> &rnd) const {
|
||||
std::shared_ptr<Chunk> Universe::createChunk(const chunk_pos &pos, const std::unique_ptr<world::generator::Abstract> &rnd) const {
|
||||
return std::make_shared<Chunk>(pos, rnd);
|
||||
}
|
||||
std::shared_ptr<Chunk> Universe::createChunk(std::istream &str) const {
|
||||
|
|
|
@ -111,8 +111,8 @@ namespace world::server {
|
|||
using save_task_t = std::pair<area_it_t, robin_hood::pair<chunk_pos, std::shared_ptr<world::server::Chunk>>>;
|
||||
data::safe_queue<save_task_t> saveQueue; //NOTE: consider Area and Chunk const
|
||||
|
||||
ushort loadDistance;
|
||||
ushort keepDistance;
|
||||
uint16_t loadDistance;
|
||||
uint16_t keepDistance;
|
||||
std::string folderPath;
|
||||
size_t floodFillLimit;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "File.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
|
||||
using namespace world::server;
|
||||
|
||||
|
@ -24,7 +25,7 @@ void FileRegion::load() {
|
|||
return;
|
||||
}
|
||||
// Read header
|
||||
ushort chunkCount; //NOTE: pretty useless
|
||||
uint16_t chunkCount; //NOTE: pretty useless
|
||||
file.read(reinterpret_cast<char *>(&chunkCount), sizeof(chunkCount));
|
||||
|
||||
while (!file.eof()) {
|
||||
|
@ -44,7 +45,7 @@ void FileRegion::load() {
|
|||
}
|
||||
|
||||
// Read size
|
||||
ushort size = 0;
|
||||
uint16_t size = 0;
|
||||
if (!(flags & Flags::EMPTY)) {
|
||||
file.read(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
}
|
||||
|
@ -88,7 +89,7 @@ bool FileRegion::read(const region_chunk_pos& pos, const zstd::read_ctx& ctx, st
|
|||
}
|
||||
return true;
|
||||
}
|
||||
void FileRegion::write(const region_chunk_pos& pos, const zstd::write_ctx& ctx, const std::string_view& in, const std::optional<Voxel>& avg) {
|
||||
void FileRegion::write(const region_chunk_pos& pos, const zstd::write_ctx& ctx, const std::string_view& in, const std::optional<world::Voxel>& avg) {
|
||||
std::unique_ptr<std::vector<char>> buffer = nullptr;
|
||||
if (!in.empty()) {
|
||||
buffer = std::make_unique<std::vector<char>>();
|
||||
|
@ -113,7 +114,7 @@ void FileRegion::save(std::optional<to_save> added) {
|
|||
}
|
||||
|
||||
{ // Write header
|
||||
ushort size = index.size() + (added.has_value() ? 1 : 0);
|
||||
uint16_t size = index.size() + (added.has_value() ? 1 : 0);
|
||||
tmpFile.write(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
}
|
||||
|
||||
|
|
|
@ -52,10 +52,10 @@ namespace world::server {
|
|||
std::shared_mutex mutex;
|
||||
std::ifstream file;
|
||||
struct node {
|
||||
node(const std::optional<Voxel>& a, ushort s, std::streampos o):
|
||||
node(const std::optional<Voxel>& a, uint16_t s, std::streampos o):
|
||||
average(a), size(s), offset(o) { }
|
||||
std::optional<Voxel> average;
|
||||
ushort size;
|
||||
uint16_t size;
|
||||
std::streampos offset;
|
||||
};
|
||||
robin_hood::unordered_map<region_chunk_pos, node> index;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "Memory.hpp"
|
||||
|
||||
#include <optional>
|
||||
|
||||
using namespace world::server;
|
||||
|
||||
#define REMOVE_CORRUPTED 1
|
||||
|
@ -26,7 +28,7 @@ void MemoryRegion::load() {
|
|||
}
|
||||
|
||||
// Read header
|
||||
ushort chunkCount; //NOTE: pretty useless
|
||||
uint16_t chunkCount; //NOTE: pretty useless
|
||||
file.read(reinterpret_cast<char *>(&chunkCount), sizeof(chunkCount));
|
||||
|
||||
while (!file.eof()) {
|
||||
|
@ -47,7 +49,7 @@ void MemoryRegion::load() {
|
|||
}
|
||||
|
||||
// Read size
|
||||
ushort size = 0;
|
||||
uint16_t size = 0;
|
||||
if (!(flags & Flags::EMPTY)) {
|
||||
file.read(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
}
|
||||
|
@ -94,7 +96,7 @@ bool MemoryRegion::read(const region_chunk_pos& pos, const zstd::read_ctx& ctx,
|
|||
}
|
||||
return true;
|
||||
}
|
||||
void MemoryRegion::write(const region_chunk_pos& pos, const zstd::write_ctx& ctx, const std::string_view& in, const std::optional<Voxel>& avg) {
|
||||
void MemoryRegion::write(const region_chunk_pos& pos, const zstd::write_ctx& ctx, const std::string_view& in, const std::optional<world::Voxel>& avg) {
|
||||
std::unique_ptr<std::vector<char>> buffer = nullptr;
|
||||
if (!in.empty()) {
|
||||
buffer = std::make_unique<std::vector<char>>();
|
||||
|
@ -134,7 +136,7 @@ void MemoryRegion::save(bool force) {
|
|||
}
|
||||
|
||||
{ // Write header
|
||||
ushort size = (ushort)content.size();
|
||||
uint16_t size = (uint16_t)content.size();
|
||||
file.write(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
}
|
||||
|
||||
|
@ -160,7 +162,7 @@ void MemoryRegion::save(bool force) {
|
|||
|
||||
if (!(flags & Flags::EMPTY)) {
|
||||
assert(chunk.second.data->size() < USHRT_MAX);
|
||||
auto size = (ushort)chunk.second.data->size();
|
||||
auto size = (uint16_t)chunk.second.data->size();
|
||||
const auto out = chunk.second.data->data();
|
||||
|
||||
// Write size
|
||||
|
|
Loading…
Reference in New Issue