added printing for arrays
also - added many member functions to `array` - added more documentation - added format_flags - added some additional cleaning steps to `generate_single_header.py` - made formatters work for any node type, not just tables - fixed documentation header obscuring content during jumps
This commit is contained in:
parent
56f6b21b7d
commit
635dec5c8e
@ -1,24 +1,18 @@
|
|||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
linux_build:
|
develop_build:
|
||||||
docker:
|
docker:
|
||||||
- image: debian:bullseye
|
- image: marzer/misc_cpp17_dev:latest
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
|
||||||
name: Installing python
|
|
||||||
command: |
|
|
||||||
apt-get -qq update && apt-get install --upgrade -y python3
|
|
||||||
- run:
|
- run:
|
||||||
name: Checking toml.hpp
|
name: Checking toml.hpp
|
||||||
command: |
|
command: |
|
||||||
cd python && python3 ci_single_header_check.py
|
cd python && python3 ci_single_header_check.py
|
||||||
- run:
|
- run:
|
||||||
name: Installing dependencies
|
name: Pulling Catch2
|
||||||
command: |
|
command: |
|
||||||
apt-get -qq update && apt-get install --upgrade -y git clang-9 g++-9 python3-pip ninja-build
|
|
||||||
pip3 install meson
|
|
||||||
git submodule update --init --recursive extern/Catch2
|
git submodule update --init --recursive extern/Catch2
|
||||||
- run:
|
- run:
|
||||||
name: Building with clang
|
name: Building with clang
|
||||||
@ -35,29 +29,38 @@ jobs:
|
|||||||
command: |
|
command: |
|
||||||
cd build-clang && ninja test && cd ../build-gcc && ninja test
|
cd build-clang && ninja test && cd ../build-gcc && ninja test
|
||||||
|
|
||||||
generate_dox:
|
|
||||||
|
master_build:
|
||||||
docker:
|
docker:
|
||||||
- image: debian:bullseye
|
- image: marzer/misc_cpp17_dev:latest
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
name: Installing dependencies
|
name: Checking toml.hpp
|
||||||
command: |
|
command: |
|
||||||
apt-get -qq update && apt-get install --upgrade -y python3 python3-pip make cmake clang-9 flex bison git wget tar
|
cd python && python3 ci_single_header_check.py
|
||||||
pip3 install beautifulsoup4 jinja2 pygments html5lib
|
|
||||||
git submodule update --init extern/mcss
|
|
||||||
- run:
|
- run:
|
||||||
name: Building and installing Doxygen 1.8.17
|
name: Pulling Catch2
|
||||||
command: |
|
command: |
|
||||||
wget http://doxygen.nl/files/doxygen-1.8.17.src.tar.gz
|
git submodule update --init --recursive extern/Catch2
|
||||||
tar xvzf doxygen-1.8.17.src.tar.gz
|
- run:
|
||||||
rm doxygen-1.8.17.src.tar.gz
|
name: Building with clang
|
||||||
cd doxygen-1.8.17
|
command: |
|
||||||
CC=clang-9 CXX=clang++-9 cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -Wno-dev -Wno-deprecated
|
CXX=clang++-9 meson build-clang
|
||||||
make install
|
cd build-clang && ninja -v -j 4
|
||||||
|
- run:
|
||||||
|
name: Building with gcc
|
||||||
|
command: |
|
||||||
|
CXX=g++-9 meson build-gcc
|
||||||
|
cd build-gcc && ninja -v -j 4
|
||||||
|
- run:
|
||||||
|
name: Running tests
|
||||||
|
command: |
|
||||||
|
cd build-clang && ninja test && cd ../build-gcc && ninja test
|
||||||
- run:
|
- run:
|
||||||
name: Generating documentation
|
name: Generating documentation
|
||||||
command: |
|
command: |
|
||||||
|
git submodule update --init extern/mcss
|
||||||
cd python && python3 generate_documentation.py
|
cd python && python3 generate_documentation.py
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: docs
|
root: docs
|
||||||
@ -91,14 +94,15 @@ workflows:
|
|||||||
version: 2
|
version: 2
|
||||||
build:
|
build:
|
||||||
jobs:
|
jobs:
|
||||||
- linux_build
|
- master_build:
|
||||||
- generate_dox:
|
|
||||||
requires:
|
|
||||||
- linux_build
|
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only: master
|
only: master
|
||||||
- deploy_dox:
|
- deploy_dox:
|
||||||
requires:
|
requires:
|
||||||
- generate_dox
|
- master_build
|
||||||
|
|
||||||
|
- develop_build:
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore: master
|
||||||
|
@ -13,5 +13,5 @@ indent_style = space
|
|||||||
charset = utf-8
|
charset = utf-8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[*.{c, cpp, cxx, h, hpp, hxx, inl, py, md}]
|
[*.{c, cpp, cxx, h, hpp, hxx, inl, py, md, css}]
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
DOXYFILE_ENCODING = UTF-8
|
DOXYFILE_ENCODING = UTF-8
|
||||||
PROJECT_NAME = toml++
|
PROJECT_NAME = toml++
|
||||||
PROJECT_NUMBER =
|
PROJECT_NUMBER =
|
||||||
PROJECT_BRIEF =
|
PROJECT_BRIEF = TOML Parser for C++17
|
||||||
PROJECT_LOGO =
|
PROJECT_LOGO =
|
||||||
OUTPUT_DIRECTORY = ./
|
OUTPUT_DIRECTORY = ./
|
||||||
CREATE_SUBDIRS = NO
|
CREATE_SUBDIRS = NO
|
||||||
@ -27,7 +27,7 @@ ABBREVIATE_BRIEF = "The $name class" \
|
|||||||
an \
|
an \
|
||||||
the
|
the
|
||||||
ALWAYS_DETAILED_SEC = NO
|
ALWAYS_DETAILED_SEC = NO
|
||||||
INLINE_INHERITED_MEMB = YES
|
INLINE_INHERITED_MEMB = NO
|
||||||
FULL_PATH_NAMES = YES
|
FULL_PATH_NAMES = YES
|
||||||
STRIP_FROM_PATH = ../
|
STRIP_FROM_PATH = ../
|
||||||
STRIP_FROM_INC_PATH =
|
STRIP_FROM_INC_PATH =
|
||||||
@ -53,7 +53,7 @@ EXTENSION_MAPPING =
|
|||||||
MARKDOWN_SUPPORT = YES
|
MARKDOWN_SUPPORT = YES
|
||||||
TOC_INCLUDE_HEADINGS = 0
|
TOC_INCLUDE_HEADINGS = 0
|
||||||
AUTOLINK_SUPPORT = YES
|
AUTOLINK_SUPPORT = YES
|
||||||
BUILTIN_STL_SUPPORT = YES
|
BUILTIN_STL_SUPPORT = NO
|
||||||
CPP_CLI_SUPPORT = NO
|
CPP_CLI_SUPPORT = NO
|
||||||
SIP_SUPPORT = NO
|
SIP_SUPPORT = NO
|
||||||
IDL_PROPERTY_SUPPORT = NO
|
IDL_PROPERTY_SUPPORT = NO
|
||||||
@ -330,10 +330,13 @@ PERLMOD_MAKEVAR_PREFIX =
|
|||||||
ENABLE_PREPROCESSING = YES
|
ENABLE_PREPROCESSING = YES
|
||||||
MACRO_EXPANSION = YES
|
MACRO_EXPANSION = YES
|
||||||
EXPAND_ONLY_PREDEF = NO
|
EXPAND_ONLY_PREDEF = NO
|
||||||
SEARCH_INCLUDES = YES
|
SEARCH_INCLUDES = NO
|
||||||
INCLUDE_PATH =
|
INCLUDE_PATH =
|
||||||
INCLUDE_FILE_PATTERNS =
|
INCLUDE_FILE_PATTERNS =
|
||||||
PREDEFINED = __cplusplus=201703L
|
PREDEFINED = TOML_DOXYGEN=1 \
|
||||||
|
__cplusplus=201703L \
|
||||||
|
TOML_ALWAYS_INLINE=inline \
|
||||||
|
TOML_MAY_THROW=
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
SKIP_FUNCTION_MACROS = NO
|
SKIP_FUNCTION_MACROS = NO
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
@ -8,14 +8,14 @@ HTML_EXTRA_STYLESHEET = https://fonts.googleapis.com/css?family=Source+Sans+Pr
|
|||||||
WARN_AS_ERROR = NO
|
WARN_AS_ERROR = NO
|
||||||
TAB_SIZE = 4
|
TAB_SIZE = 4
|
||||||
HTML_EXTRA_FILES = tomlplusplus.js
|
HTML_EXTRA_FILES = tomlplusplus.js
|
||||||
##! M_THEME_COLOR = #2d2d30
|
SHOW_INCLUDE_FILES = NO
|
||||||
##! M_LINKS_NAVBAR1 = namespaces
|
##! M_THEME_COLOR = #22272e
|
||||||
|
##! M_LINKS_NAVBAR1 = pages
|
||||||
##! M_LINKS_NAVBAR2 = annotated
|
##! M_LINKS_NAVBAR2 = annotated
|
||||||
##! M_SEARCH_DOWNLOAD_BINARY = NO
|
##! M_SEARCH_DOWNLOAD_BINARY = NO
|
||||||
##! M_CLASS_TREE_EXPAND_LEVELS = 1
|
##! M_CLASS_TREE_EXPAND_LEVELS = 3
|
||||||
##! M_FILE_TREE_EXPAND_LEVELS = 3
|
##! M_FILE_TREE_EXPAND_LEVELS = 3
|
||||||
##! M_PAGE_FINE_PRINT = \
|
##! M_PAGE_FINE_PRINT = <a target="_blank" href="https://github.com/marzer/tomlplusplus/">Github</a> • \
|
||||||
##! <a target="_blank" href="https://github.com/marzer/tomlplusplus/">Github</a> • \
|
|
||||||
##! <a target="_blank" href="https://github.com/marzer/tomlplusplus/issues">Report an issue</a> \
|
##! <a target="_blank" href="https://github.com/marzer/tomlplusplus/issues">Report an issue</a> \
|
||||||
##! <br><br><div id="tpp-custom-footer"></div>
|
##! <br><br>Documentation generated using <a href="https://mcss.mosra.cz/">m.css</a>
|
||||||
##! M_HTML_HEADER = <script src="tomlplusplus.js"></script>
|
##! M_HTML_HEADER = <script src="tomlplusplus.js"></script>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/*
|
||||||
table.m-table th
|
table.m-table th
|
||||||
{
|
{
|
||||||
color: #ffe698;
|
color: #ffe698;
|
||||||
@ -49,11 +50,6 @@ dl.m-doc dd
|
|||||||
margin-bottom: 0.8rem;
|
margin-bottom: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.tpp-external
|
|
||||||
{
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.m-doc-template a, dl.m-doc dd a, ul.m-doc li > span.m-doc a
|
.m-doc-template a, dl.m-doc dd a, ul.m-doc li > span.m-doc a
|
||||||
{
|
{
|
||||||
color: #858585;
|
color: #858585;
|
||||||
@ -66,56 +62,6 @@ a.tpp-external
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.tpp-swatch, .tpp-enable-if > *
|
|
||||||
{
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tpp-enable-if
|
|
||||||
{
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tpp-enable-if > *
|
|
||||||
{
|
|
||||||
background-clip: padding-box !important;
|
|
||||||
padding: 0px 2px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tpp-enable-if > a
|
|
||||||
{
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
font-weight: bold;
|
|
||||||
background-color: #858585;
|
|
||||||
color: #050505;
|
|
||||||
padding-bottom: 0px;
|
|
||||||
margin: 0px 1px;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tpp-enable-if > a:hover
|
|
||||||
{
|
|
||||||
background-color: #747474;
|
|
||||||
color: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tpp-enable-if > span
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
padding-left: 2em;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.tpp-swatch
|
|
||||||
{
|
|
||||||
min-width: 3em;
|
|
||||||
min-height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
body > header > nav
|
body > header > nav
|
||||||
{
|
{
|
||||||
background-color: #1e1e1e;
|
background-color: #1e1e1e;
|
||||||
@ -126,12 +72,12 @@ html
|
|||||||
background-color: #2d2d30;
|
background-color: #2d2d30;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre, code, .m-label/*.m-flat.m-success*/, .tpp-enable-if > a
|
pre, code, .m-label, .tpp-enable-if > a
|
||||||
{
|
{
|
||||||
font-family: 'Consolas', monospace;
|
font-family: 'Consolas', monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre, .m-doc-search-content /*, .tpp-enable-if > full*/
|
pre, .m-doc-search-content
|
||||||
{
|
{
|
||||||
background-color: #1e1e1e;
|
background-color: #1e1e1e;
|
||||||
}
|
}
|
||||||
@ -141,31 +87,6 @@ pre.m-code, code
|
|||||||
background-color: #1e1e1e88;
|
background-color: #1e1e1e88;
|
||||||
}
|
}
|
||||||
|
|
||||||
.m-code .c1 /* comments */
|
|
||||||
{
|
|
||||||
color: rgb(87,166,74);
|
|
||||||
}
|
|
||||||
|
|
||||||
.m-code .mi, .m-code .mf /* literals */
|
|
||||||
{
|
|
||||||
color: rgb(181,206,168);
|
|
||||||
}
|
|
||||||
|
|
||||||
.m-code .k /* keywords */
|
|
||||||
{
|
|
||||||
color: rgb(86,156,214);
|
|
||||||
}
|
|
||||||
|
|
||||||
.m-code .n /* names */
|
|
||||||
{
|
|
||||||
color: rgb(220,220,220);
|
|
||||||
}
|
|
||||||
|
|
||||||
.m-code .p /* punctuation */
|
|
||||||
{
|
|
||||||
color: rgb(120,120,120);
|
|
||||||
}
|
|
||||||
|
|
||||||
article section.m-doc-details > div > h3:first-child, article section > h2, body > footer > nav
|
article section.m-doc-details > div > h3:first-child, article section > h2, body > footer > nav
|
||||||
{
|
{
|
||||||
background-color: #252526;
|
background-color: #252526;
|
||||||
@ -181,20 +102,6 @@ article section.m-doc-details > div > h3:first-child, article section > h2, body
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
header
|
|
||||||
{
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
body
|
|
||||||
{
|
|
||||||
margin-top: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.m-doc-include
|
div.m-doc-include
|
||||||
{
|
{
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
@ -210,9 +117,91 @@ div.m-doc-include
|
|||||||
color: #9999AA;
|
color: #9999AA;
|
||||||
}
|
}
|
||||||
|
|
||||||
article, article > header, article section
|
*/
|
||||||
|
|
||||||
|
html, body
|
||||||
{
|
{
|
||||||
margin-bottom: 3em;
|
scroll-padding-top: 3.5rem;
|
||||||
background-color: red;
|
}
|
||||||
background-color: inherit;
|
|
||||||
|
body
|
||||||
|
{
|
||||||
|
margin-top: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
article, article > header, article section {
|
||||||
|
margin-bottom: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre, code, .tpp-enable-if > a {
|
||||||
|
font-family: 'Consolas', 'Source Sans Pro', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.tpp-external {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tpp-enable-if {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tpp-enable-if > * {
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 0.2rem;
|
||||||
|
background-clip: padding-box !important;
|
||||||
|
padding: 0px 2px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tpp-enable-if > a {
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: #858585;
|
||||||
|
color: #050505;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
margin: 0px 1px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tpp-enable-if > a:hover {
|
||||||
|
background-color: #747474;
|
||||||
|
color: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tpp-enable-if > span {
|
||||||
|
display: none;
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav .m-thin {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-code .c1 {
|
||||||
|
color: rgb(87,166,74);
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-code .mi, .m-code .mf {
|
||||||
|
color: rgb(181,206,168);
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-code .k {
|
||||||
|
color: rgb(86,156,214);
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-code .n {
|
||||||
|
color: rgb(220,220,220);
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-code .p {
|
||||||
|
color: rgb(120,120,120);
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//const auto table = toml::parse(file); //works but parse_errors would not include the source path
|
|
||||||
|
|
||||||
const auto table = toml::parse(file, std::move(path));
|
const auto table = toml::parse(file, std::move(path));
|
||||||
|
|
||||||
std::cout << table << std::endl;
|
std::cout << table << std::endl;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "toml_common.h"
|
#include "toml_common.h"
|
||||||
#include "toml_date_time.h"
|
#include "toml_date_time.h"
|
||||||
|
#include "toml_print_to_stream.h"
|
||||||
#include "toml_node.h"
|
#include "toml_node.h"
|
||||||
#include "toml_table.h"
|
#include "toml_table.h"
|
||||||
#include "toml_array.h"
|
#include "toml_array.h"
|
||||||
@ -13,7 +14,6 @@
|
|||||||
#include "toml_node_view.h"
|
#include "toml_node_view.h"
|
||||||
#include "toml_utf8.h"
|
#include "toml_utf8.h"
|
||||||
#include "toml_parser.h"
|
#include "toml_parser.h"
|
||||||
#include "toml_print_to_stream.h"
|
|
||||||
#include "toml_formatter.h"
|
#include "toml_formatter.h"
|
||||||
#include "toml_default_formatter.h"
|
#include "toml_default_formatter.h"
|
||||||
#include "toml_json_formatter.h"
|
#include "toml_json_formatter.h"
|
||||||
@ -51,4 +51,5 @@
|
|||||||
#undef TOML_STRING_PREFIX_1
|
#undef TOML_STRING_PREFIX_1
|
||||||
#undef TOML_STRING_PREFIX
|
#undef TOML_STRING_PREFIX
|
||||||
#undef TOML_UNDEF_MACROS
|
#undef TOML_UNDEF_MACROS
|
||||||
|
#undef TOML_DOXYGEN
|
||||||
#endif
|
#endif
|
||||||
|
@ -79,6 +79,25 @@ namespace toml::impl
|
|||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
/// \brief A TOML array.
|
||||||
|
/// \detail The interface of this type is modeled after std::vector so things
|
||||||
|
/// mostly work as you'd expect them to with a vector: \cpp
|
||||||
|
///
|
||||||
|
/// auto table = toml::parse("arr = [1, 2, 3, 4, 'five']"sv);
|
||||||
|
///
|
||||||
|
/// auto& arr = *table.get_as<toml::array>("arr");
|
||||||
|
///
|
||||||
|
/// for (size_t i = 0; i < arr.size(); i++)
|
||||||
|
/// {
|
||||||
|
/// arr[i].visit([=](auto&& el) noexcept
|
||||||
|
/// {
|
||||||
|
/// std::cout << el << ", ";
|
||||||
|
/// });
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // prints: 1, 2, 3, 4, "five"
|
||||||
|
///
|
||||||
|
/// \ecpp
|
||||||
class array final
|
class array final
|
||||||
: public node
|
: public node
|
||||||
{
|
{
|
||||||
@ -88,6 +107,11 @@ namespace toml
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
using value_type = node;
|
||||||
|
using size_type = size_t;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
using reference = node&;
|
||||||
|
using const_reference = const node&;
|
||||||
using iterator = impl::array_iterator<false>;
|
using iterator = impl::array_iterator<false>;
|
||||||
using const_iterator = impl::array_iterator<true>;
|
using const_iterator = impl::array_iterator<true>;
|
||||||
|
|
||||||
@ -108,23 +132,20 @@ namespace toml
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] node_type type() const noexcept override { return node_type::array; }
|
[[nodiscard]] node_type type() const noexcept override { return node_type::array; }
|
||||||
|
|
||||||
[[nodiscard]] bool is_table() const noexcept override { return false; }
|
[[nodiscard]] bool is_table() const noexcept override { return false; }
|
||||||
[[nodiscard]] bool is_array() const noexcept override { return true; }
|
[[nodiscard]] bool is_array() const noexcept override { return true; }
|
||||||
[[nodiscard]] bool is_value() const noexcept override { return false; }
|
[[nodiscard]] bool is_value() const noexcept override { return false; }
|
||||||
|
[[nodiscard]] array* as_array() noexcept override { return this; }
|
||||||
|
[[nodiscard]] const array* as_array() const noexcept override { return this; }
|
||||||
|
|
||||||
[[nodiscard]] bool is_array_of_tables() const noexcept override
|
/// \brief Checks if the array contains values of only one type.
|
||||||
{
|
///
|
||||||
if (values.empty())
|
/// \tparam T A TOML node type. Provide an explicit type for "is every element a T?".
|
||||||
return false;
|
/// Leave it as the default `void` for "is every element the same type?".
|
||||||
|
///
|
||||||
for (auto& val : values)
|
/// \returns True if the array was homogeneous.
|
||||||
if (!val->is_table())
|
///
|
||||||
return false;
|
/// \attention Empty arrays are _not_ regarded as homogeneous.
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T = void>
|
template <typename T = void>
|
||||||
[[nodiscard]] bool is_homogeneous() const noexcept
|
[[nodiscard]] bool is_homogeneous() const noexcept
|
||||||
{
|
{
|
||||||
@ -147,34 +168,102 @@ namespace toml
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] array* as_array() noexcept override { return this; }
|
/// \brief Returns true if this array contains only tables.
|
||||||
[[nodiscard]] const array* as_array() const noexcept override { return this; }
|
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||||
|
bool is_array_of_tables() const noexcept override
|
||||||
|
{
|
||||||
|
return is_homogeneous<toml::table>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Gets a reference to the node element at a specific index.
|
||||||
|
[[nodiscard]] node& operator[] (size_t index) noexcept { return *values[index]; }
|
||||||
|
/// \brief Gets a reference to the node element at a specific index.
|
||||||
|
[[nodiscard]] const node& operator[] (size_t index) const noexcept { return *values[index]; }
|
||||||
|
|
||||||
|
/// \brief Returns a reference to the first element in the array.
|
||||||
|
[[nodiscard]] node& front() noexcept { return *values.front(); }
|
||||||
|
/// \brief Returns a reference to the first element in the array.
|
||||||
|
[[nodiscard]] const node& front() const noexcept { return *values.front(); }
|
||||||
|
/// \brief Returns a reference to the last element in the array.
|
||||||
|
[[nodiscard]] node& back() noexcept { return *values.back(); }
|
||||||
|
/// \brief Returns a reference to the last element in the array.
|
||||||
|
[[nodiscard]] const node& back() const noexcept { return *values.back(); }
|
||||||
|
|
||||||
|
/// \brief Returns an iterator to the first element.
|
||||||
|
[[nodiscard]] iterator begin() noexcept { return { values.begin() }; }
|
||||||
|
/// \brief Returns an iterator to the first element.
|
||||||
|
[[nodiscard]] const_iterator begin() const noexcept { return { values.begin() }; }
|
||||||
|
/// \brief Returns an iterator to the first element.
|
||||||
|
[[nodiscard]] const_iterator cbegin() const noexcept { return { values.cbegin() }; }
|
||||||
|
|
||||||
|
/// \brief Returns an iterator to one-past-the-last element.
|
||||||
|
[[nodiscard]] iterator end() noexcept { return { values.end() }; }
|
||||||
|
/// \brief Returns an iterator to one-past-the-last element.
|
||||||
|
[[nodiscard]] const_iterator end() const noexcept { return { values.end() }; }
|
||||||
|
/// \brief Returns an iterator to one-past-the-last element.
|
||||||
|
[[nodiscard]] const_iterator cend() const noexcept { return { values.cend() }; }
|
||||||
|
|
||||||
|
/// \brief Returns true if the array is empty.
|
||||||
[[nodiscard]] bool empty() const noexcept { return values.empty(); }
|
[[nodiscard]] bool empty() const noexcept { return values.empty(); }
|
||||||
|
/// \brief Returns the number of elements in the array.
|
||||||
[[nodiscard]] size_t size() const noexcept { return values.size(); }
|
[[nodiscard]] size_t size() const noexcept { return values.size(); }
|
||||||
|
/// \brief Reserves internal storage capacity up to a pre-determined number of elements.
|
||||||
|
void reserve(size_t new_capacity) TOML_MAY_THROW { values.reserve(new_capacity); }
|
||||||
|
|
||||||
[[nodiscard]] node& operator[] (size_t index) & noexcept { return *values[index].get(); }
|
|
||||||
[[nodiscard]] node&& operator[] (size_t index) && noexcept { return std::move(*values[index].get()); }
|
|
||||||
[[nodiscard]] const node& operator[] (size_t index) const& noexcept { return *values[index].get(); }
|
|
||||||
|
|
||||||
|
/// \brief Removes all elements from the array.
|
||||||
|
void clear() noexcept { values.clear(); }
|
||||||
|
|
||||||
|
// insert()
|
||||||
|
// emplace()
|
||||||
|
|
||||||
|
/// \brief Removes the specified element from the array.
|
||||||
|
///
|
||||||
|
/// \returns The position following the Iterator following the removed element.
|
||||||
|
iterator erase(const_iterator pos) noexcept
|
||||||
|
{
|
||||||
|
return iterator{ values.erase(pos.raw_) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Removes the specified range of elements elements from the array.
|
||||||
|
///
|
||||||
|
/// \returns The position following the Iterator following the last removed element.
|
||||||
|
iterator erase(const_iterator first, const_iterator last) noexcept
|
||||||
|
{
|
||||||
|
return iterator{ values.erase(first.raw_, last.raw_) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// push_back()
|
||||||
|
// emplace_back()
|
||||||
|
|
||||||
|
/// \brief Removes the last element from the array.
|
||||||
|
void pop_back() noexcept { values.pop_back(); }
|
||||||
|
|
||||||
|
/// \brief Gets an element at a specific index if it is a particular type.
|
||||||
|
///
|
||||||
|
/// \tparam T The node's type.
|
||||||
|
/// \param index The element index.
|
||||||
|
///
|
||||||
|
/// \returns A pointer to the selected element if it was of the specified type, or nullptr.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]] node_of<T>* get_as(size_t index) noexcept
|
[[nodiscard]] node_of<T>* get_as(size_t index) noexcept
|
||||||
{
|
{
|
||||||
return values[index]->as<T>();
|
return values[index]->as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Gets an element at a specific index if it is a particular type.
|
||||||
|
///
|
||||||
|
/// \tparam T The node's type.
|
||||||
|
/// \param index The element index.
|
||||||
|
///
|
||||||
|
/// \returns A pointer to the selected element if it was of the specified type, or nullptr.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]] const node_of<T>* get_as(size_t index) const noexcept
|
[[nodiscard]] const node_of<T>* get_as(size_t index) const noexcept
|
||||||
{
|
{
|
||||||
return values[index]->as<T>();
|
return values[index]->as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] iterator begin() noexcept { return { values.begin() }; }
|
template <typename CHAR>
|
||||||
[[nodiscard]] const_iterator begin() const noexcept { return { values.begin() }; }
|
friend inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const array&) TOML_MAY_THROW;
|
||||||
[[nodiscard]] const_iterator cbegin() const noexcept { return { values.cbegin() }; }
|
|
||||||
|
|
||||||
[[nodiscard]] iterator end() noexcept { return { values.end() }; }
|
|
||||||
[[nodiscard]] const_iterator end() const noexcept { return { values.end() }; }
|
|
||||||
[[nodiscard]] const_iterator cend() const noexcept { return { values.cend() }; }
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -114,8 +114,6 @@
|
|||||||
#define TOML_USE_STREAMS_FOR_FLOATS 1
|
#define TOML_USE_STREAMS_FOR_FLOATS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined (DOXYGEN)
|
|
||||||
#define TOML_EXCEPTIONS 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TOML_CPP_VERSION
|
#ifndef TOML_CPP_VERSION
|
||||||
@ -138,6 +136,9 @@
|
|||||||
#ifndef TOML_EXCEPTIONS
|
#ifndef TOML_EXCEPTIONS
|
||||||
#define TOML_EXCEPTIONS 1
|
#define TOML_EXCEPTIONS 1
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef TOML_DOXYGEN
|
||||||
|
#define TOML_DOXYGEN 0
|
||||||
|
#endif
|
||||||
#if TOML_EXCEPTIONS
|
#if TOML_EXCEPTIONS
|
||||||
#define TOML_CONDITIONAL_NOEXCEPT(...) noexcept(__VA_ARGS__)
|
#define TOML_CONDITIONAL_NOEXCEPT(...) noexcept(__VA_ARGS__)
|
||||||
#define TOML_MAY_THROW
|
#define TOML_MAY_THROW
|
||||||
@ -273,20 +274,17 @@ TOML_POP_WARNINGS
|
|||||||
/// \brief The root namespace for all toml++ functions and types.
|
/// \brief The root namespace for all toml++ functions and types.
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
/// \brief User-defined literals.
|
|
||||||
inline namespace literals
|
inline namespace literals
|
||||||
{
|
{
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
|
|
||||||
/// \brief Specifies a uint8_t literal.
|
|
||||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||||
TOML_CONSTEVAL uint8_t operator"" _u8(unsigned long long n) noexcept
|
TOML_CONSTEVAL uint8_t operator"" _u8(unsigned long long n) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<uint8_t>(n);
|
return static_cast<uint8_t>(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Specifies a size_t literal.
|
|
||||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||||
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
|
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
|
||||||
{
|
{
|
||||||
@ -302,16 +300,16 @@ namespace toml
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/// \brief The base character type for toml++ keys and string values.
|
/// \brief The base character type for keys and string values.
|
||||||
/// \remarks This will be `char8_t` if `TOML_CHAR_8_STRINGS = 1`, otherwise it will be `char`.
|
/// \attention This will be `char8_t` if `TOML_CHAR_8_STRINGS` is `1`.
|
||||||
using string_char = char;
|
using string_char = char;
|
||||||
|
|
||||||
/// \brief The string type for toml++ keys and string values.
|
/// \brief The string type for keys and string values.
|
||||||
/// \remarks This will be `std::u8string` if `TOML_CHAR_8_STRINGS = 1`, otherwise it will be `std::string`.
|
/// \attention This will be `std::u8string` if `TOML_CHAR_8_STRINGS` is `1`.
|
||||||
using string = std::string;
|
using string = std::string;
|
||||||
|
|
||||||
/// \brief The string type for toml++ keys and string values.
|
/// \brief The string type for keys and string values.
|
||||||
/// \remarks This will be `std::u8string_view` if `TOML_CHAR_8_STRINGS = 1`, otherwise it will be `std::string_view`.
|
/// \attention This will be `std::u8string_view` if `TOML_CHAR_8_STRINGS` is `1`.
|
||||||
using string_view = std::string_view;
|
using string_view = std::string_view;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -348,13 +346,13 @@ namespace toml
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
/// \brief The integer type used to tally line numbers and columns.
|
/// \brief The integer type used to tally line numbers and columns.
|
||||||
/// \remarks This will be `uint32_t` if `TOML_LARGE_FILES = 1`, otherwise it will be `uint16_t`.
|
/// \attention This will be `uint32_t` if `TOML_LARGE_FILES` is `1`.
|
||||||
using source_index = uint16_t;
|
using source_index = uint16_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \brief A source document line-and-column pair.
|
/// \brief A source document line-and-column pair.
|
||||||
struct source_position final
|
struct source_position
|
||||||
{
|
{
|
||||||
/// \brief The line number.
|
/// \brief The line number.
|
||||||
/// \remarks Valid line numbers start at 1.
|
/// \remarks Valid line numbers start at 1.
|
||||||
@ -371,7 +369,6 @@ namespace toml
|
|||||||
return line > source_index{} && column > source_index{};
|
return line > source_index{} && column > source_index{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
friend constexpr bool operator == (const source_position& lhs, const source_position& rhs) noexcept
|
friend constexpr bool operator == (const source_position& lhs, const source_position& rhs) noexcept
|
||||||
{
|
{
|
||||||
@ -412,7 +409,7 @@ namespace toml
|
|||||||
using source_path_ptr = std::shared_ptr<const std::string>;
|
using source_path_ptr = std::shared_ptr<const std::string>;
|
||||||
|
|
||||||
/// \brief A source document region.
|
/// \brief A source document region.
|
||||||
struct source_region final
|
struct source_region
|
||||||
{
|
{
|
||||||
/// \brief The beginning of the region (inclusive).
|
/// \brief The beginning of the region (inclusive).
|
||||||
source_position begin;
|
source_position begin;
|
||||||
@ -429,7 +426,7 @@ namespace toml
|
|||||||
TOML_PUSH_WARNINGS
|
TOML_PUSH_WARNINGS
|
||||||
TOML_DISABLE_INIT_WARNINGS
|
TOML_DISABLE_INIT_WARNINGS
|
||||||
|
|
||||||
#if TOML_EXCEPTIONS
|
#if !TOML_DOXYGEN && TOML_EXCEPTIONS
|
||||||
|
|
||||||
class parse_error final
|
class parse_error final
|
||||||
: public std::runtime_error
|
: public std::runtime_error
|
||||||
@ -472,8 +469,8 @@ namespace toml
|
|||||||
|
|
||||||
/// \brief An error thrown/returned when parsing fails.
|
/// \brief An error thrown/returned when parsing fails.
|
||||||
///
|
///
|
||||||
/// \remarks This will inherit from `std::runtime_exception` when `TOML_EXCEPTIONS = 1`.
|
/// \remarks This class inherits from `std::runtime_error` when `TOML_EXCEPTIONS` is `1`.
|
||||||
/// The public interface will be exactly the same either way.
|
/// The public interface remains the same regardless of exception mode.
|
||||||
class parse_error final
|
class parse_error final
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -537,6 +534,13 @@ namespace toml::impl
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||||
|
constexpr std::underlying_type_t<T> unwrap_enum(T val) noexcept
|
||||||
|
{
|
||||||
|
return static_cast<std::underlying_type_t<T>>(val);
|
||||||
|
}
|
||||||
|
|
||||||
// Q: "why not use std::find??"
|
// Q: "why not use std::find??"
|
||||||
// A: Because <algorithm> is _huge_ and std::find would be the only thing I used from it.
|
// A: Because <algorithm> is _huge_ and std::find would be the only thing I used from it.
|
||||||
// I don't want to impose such a heavy burden on users.
|
// I don't want to impose such a heavy burden on users.
|
||||||
@ -551,20 +555,6 @@ namespace toml::impl
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct is_generic_invocable
|
|
||||||
{
|
|
||||||
template <typename U>
|
|
||||||
static constexpr auto test(U&&) -> decltype(std::declval<T>()(std::declval<U&&>()), std::true_type{});
|
|
||||||
static constexpr std::false_type test(...);
|
|
||||||
|
|
||||||
struct tester {};
|
|
||||||
static constexpr auto value = decltype(test(tester{}))::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline constexpr bool is_generic_invocable_v = is_generic_invocable<T>::value;
|
|
||||||
|
|
||||||
class parser;
|
class parser;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -692,12 +682,17 @@ namespace toml::impl
|
|||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// \brief Helper alias that wraps a type up as it's TOML node equivalent.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using node_of = typename impl::node_wrapper<T>::type;
|
using node_of = typename impl::node_wrapper<T>::type;
|
||||||
|
|
||||||
|
/// \brief Helper alias that unwraps TOML node type to it's raw value equivalent.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using value_of = typename impl::node_unwrapper<T>::type;
|
using value_of = typename impl::node_unwrapper<T>::type;
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Pretty-prints the value of a node_type to a stream.
|
||||||
template <typename CHAR>
|
template <typename CHAR>
|
||||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, node_type rhs) TOML_MAY_THROW
|
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, node_type rhs) TOML_MAY_THROW
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
namespace toml::impl
|
namespace toml::impl
|
||||||
{
|
{
|
||||||
|
TOML_PUSH_WARNINGS
|
||||||
|
TOML_DISABLE_ALL_WARNINGS
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline toml::string default_formatter_make_key_segment(const toml::string& str) noexcept
|
inline toml::string default_formatter_make_key_segment(const toml::string& str) noexcept
|
||||||
{
|
{
|
||||||
@ -32,7 +35,16 @@ namespace toml::impl
|
|||||||
s.reserve(str.length() + 2_sz);
|
s.reserve(str.length() + 2_sz);
|
||||||
s += TOML_STRING_PREFIX('"');
|
s += TOML_STRING_PREFIX('"');
|
||||||
for (auto c : str)
|
for (auto c : str)
|
||||||
s.append(escape_string_character(c));
|
{
|
||||||
|
if (c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F')) TOML_UNLIKELY
|
||||||
|
s.append(low_character_escape_table[c]);
|
||||||
|
else if (c == TOML_STRING_PREFIX('\x7F')) TOML_UNLIKELY
|
||||||
|
s.append(TOML_STRING_PREFIX("\\u007F"sv));
|
||||||
|
else if (c == TOML_STRING_PREFIX('"')) TOML_UNLIKELY
|
||||||
|
s.append(TOML_STRING_PREFIX("\\\""sv));
|
||||||
|
else
|
||||||
|
s += c;
|
||||||
|
}
|
||||||
s += TOML_STRING_PREFIX('"');
|
s += TOML_STRING_PREFIX('"');
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -41,6 +53,8 @@ namespace toml::impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TOML_POP_WARNINGS
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline size_t default_formatter_inline_columns(const node& node) noexcept
|
inline size_t default_formatter_inline_columns(const node& node) noexcept
|
||||||
{
|
{
|
||||||
@ -177,7 +191,7 @@ namespace toml
|
|||||||
const auto original_indent = base::indent();
|
const auto original_indent = base::indent();
|
||||||
const auto multiline = impl::default_formatter_forces_multiline(
|
const auto multiline = impl::default_formatter_forces_multiline(
|
||||||
arr,
|
arr,
|
||||||
base::indent_columns() * static_cast<size_t>(original_indent < 0 ? 0 : original_indent)
|
base::indent_columns * static_cast<size_t>(original_indent < 0 ? 0 : original_indent)
|
||||||
);
|
);
|
||||||
impl::print_to_stream("["sv, base::stream());
|
impl::print_to_stream("["sv, base::stream());
|
||||||
if (multiline)
|
if (multiline)
|
||||||
@ -341,17 +355,37 @@ namespace toml
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print() TOML_MAY_THROW
|
||||||
|
{
|
||||||
|
switch (auto source_type = base::source().type())
|
||||||
|
{
|
||||||
|
case node_type::table:
|
||||||
|
{
|
||||||
|
auto& tbl = *reinterpret_cast<const table*>(&base::source());
|
||||||
|
if (tbl.is_inline() || (base::flags() & format_flags::always_print_as_inline) != format_flags::none)
|
||||||
|
print_inline(tbl);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base::decrease_indent(); // so root kvps and tables have the same indent
|
||||||
|
print(tbl);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case node_type::array:
|
||||||
|
print(*reinterpret_cast<const array*>(&base::source()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
base::print(base::source(), source_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TOML_NODISCARD_CTOR
|
TOML_NODISCARD_CTOR
|
||||||
default_formatter(const toml::table& source_, toml::string_view indent_string = {}) noexcept
|
explicit default_formatter(const toml::node& source, format_flags flags = {}) noexcept
|
||||||
: base{
|
: base{ source, flags }
|
||||||
source_,
|
|
||||||
impl::formatter_options{
|
|
||||||
indent_string,
|
|
||||||
false //quote_dates_and_times
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -359,9 +393,8 @@ namespace toml
|
|||||||
TOML_MAY_THROW
|
TOML_MAY_THROW
|
||||||
{
|
{
|
||||||
rhs.attach(lhs);
|
rhs.attach(lhs);
|
||||||
rhs.base::decrease_indent(); //starts at -1 so root kvps and first-level child tables have the same indent
|
|
||||||
rhs.key_path.clear();
|
rhs.key_path.clear();
|
||||||
rhs.print(rhs.source());
|
rhs.print();
|
||||||
rhs.detach();
|
rhs.detach();
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
@ -413,4 +446,10 @@ namespace toml
|
|||||||
{
|
{
|
||||||
return lhs << default_formatter<CHAR>{ rhs };
|
return lhs << default_formatter<CHAR>{ rhs };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename CHAR>
|
||||||
|
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const array& rhs) TOML_MAY_THROW
|
||||||
|
{
|
||||||
|
return lhs << default_formatter<CHAR>{ rhs };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,53 +1,45 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "toml_print_to_stream.h"
|
#include "toml_print_to_stream.h"
|
||||||
|
|
||||||
namespace toml::impl
|
namespace toml
|
||||||
{
|
{
|
||||||
TOML_PUSH_WARNINGS
|
enum class format_flags : uint8_t
|
||||||
TOML_DISABLE_ALL_WARNINGS // some compilers will complain about a tautological unsigned >= 0.
|
|
||||||
// TINAE - char can have signed _or_ unsigned semantics and I can't
|
|
||||||
// be arsed handling this differently
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
inline toml::string_view escape_string_character(const toml::string_char& c) noexcept
|
|
||||||
{
|
{
|
||||||
if (c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F')) TOML_UNLIKELY
|
none,
|
||||||
return low_character_escape_table[c];
|
always_print_as_inline = 1,
|
||||||
else if (c == TOML_STRING_PREFIX('\x7F')) TOML_UNLIKELY
|
quote_dates_and_times = 2
|
||||||
return TOML_STRING_PREFIX("\\u007F"sv);
|
};
|
||||||
else if (c == TOML_STRING_PREFIX('"')) TOML_UNLIKELY
|
[[nodiscard]] constexpr format_flags operator & (format_flags lhs, format_flags rhs) noexcept
|
||||||
return TOML_STRING_PREFIX("\\\""sv);
|
{
|
||||||
else
|
return static_cast<format_flags>(impl::unwrap_enum(lhs) & impl::unwrap_enum(rhs));
|
||||||
return toml::string_view{ &c, 1_sz };
|
}
|
||||||
|
[[nodiscard]] constexpr format_flags operator | (format_flags lhs, format_flags rhs) noexcept
|
||||||
|
{
|
||||||
|
return static_cast<format_flags>( impl::unwrap_enum(lhs) | impl::unwrap_enum(rhs) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TOML_POP_WARNINGS
|
namespace toml::impl
|
||||||
|
|
||||||
struct formatter_options final
|
|
||||||
{
|
{
|
||||||
toml::string_view indent_string;
|
|
||||||
bool quote_dates_and_times;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename CHAR = char>
|
template <typename CHAR = char>
|
||||||
class formatter
|
class formatter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const toml::table& source_;
|
const toml::node* source_;
|
||||||
std::basic_ostream<CHAR>* stream_ = nullptr;
|
format_flags flags_;
|
||||||
formatter_options options_;
|
|
||||||
int indent_;
|
int indent_;
|
||||||
bool naked_newline_;
|
bool naked_newline_;
|
||||||
size_t indent_columns_;
|
std::basic_ostream<CHAR>* stream_ = nullptr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
[[nodiscard]] const toml::table& source() const noexcept { return source_; }
|
[[nodiscard]] const toml::node& source() const noexcept { return *source_; }
|
||||||
[[nodiscard]] const formatter_options& options() const noexcept { return options_; }
|
[[nodiscard]] format_flags flags() const noexcept { return flags_; }
|
||||||
[[nodiscard]] std::basic_ostream<CHAR>& stream() const noexcept { return *stream_; }
|
[[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]] int indent() const noexcept { return indent_; }
|
[[nodiscard]] int indent() const noexcept { return indent_; }
|
||||||
[[nodiscard]] size_t indent_columns() const noexcept { return indent_columns_; }
|
|
||||||
void indent(int level) noexcept { indent_ = level; }
|
void indent(int level) noexcept { indent_ = level; }
|
||||||
void increase_indent() noexcept { indent_++; }
|
void increase_indent() noexcept { indent_++; }
|
||||||
void decrease_indent() noexcept { indent_--; }
|
void decrease_indent() noexcept { indent_--; }
|
||||||
@ -79,7 +71,7 @@ namespace toml::impl
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < indent_; i++)
|
for (int i = 0; i < indent_; i++)
|
||||||
{
|
{
|
||||||
print_to_stream(options_.indent_string, *stream_);
|
print_to_stream(indent_string, *stream_);
|
||||||
naked_newline_ = false;
|
naked_newline_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,8 +83,7 @@ namespace toml::impl
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
print_to_stream('"', *stream_);
|
print_to_stream('"', *stream_);
|
||||||
for (auto c : str)
|
print_to_stream_with_escapes(str, *stream_);
|
||||||
print_to_stream(escape_string_character(c), *stream_);
|
|
||||||
print_to_stream('"', *stream_);
|
print_to_stream('"', *stream_);
|
||||||
}
|
}
|
||||||
naked_newline_ = false;
|
naked_newline_ = false;
|
||||||
@ -114,7 +105,7 @@ namespace toml::impl
|
|||||||
|
|
||||||
if constexpr (is_date_time)
|
if constexpr (is_date_time)
|
||||||
{
|
{
|
||||||
if (options_.quote_dates_and_times)
|
if ((flags_ & format_flags::quote_dates_and_times) != format_flags::none)
|
||||||
print_to_stream('"', *stream_);
|
print_to_stream('"', *stream_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +113,7 @@ namespace toml::impl
|
|||||||
|
|
||||||
if constexpr (is_date_time)
|
if constexpr (is_date_time)
|
||||||
{
|
{
|
||||||
if (options_.quote_dates_and_times)
|
if ((flags_ & format_flags::quote_dates_and_times) != format_flags::none)
|
||||||
print_to_stream('"', *stream_);
|
print_to_stream('"', *stream_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,22 +136,9 @@ namespace toml::impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formatter(const toml::table& source, formatter_options&& options) noexcept
|
formatter(const toml::node& source, format_flags flags) noexcept
|
||||||
: source_{ source },
|
: source_{ &source },
|
||||||
options_{ std::move(options) }
|
flags_{ flags }
|
||||||
|
{}
|
||||||
{
|
|
||||||
if (options_.indent_string.empty())
|
|
||||||
{
|
|
||||||
options_.indent_string = TOML_STRING_PREFIX(" "sv);
|
|
||||||
indent_columns_ = 4_sz;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
indent_columns_ = {};
|
|
||||||
for (auto c : options_.indent_string)
|
|
||||||
indent_columns_ += c == '\t' ? 4_sz : 1_sz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -45,17 +45,23 @@ namespace toml
|
|||||||
base::clear_naked_newline();
|
base::clear_naked_newline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print() TOML_MAY_THROW
|
||||||
|
{
|
||||||
|
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(base::source(), source_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TOML_NODISCARD_CTOR
|
TOML_NODISCARD_CTOR
|
||||||
json_formatter(const toml::table& source_, toml::string_view indent_string = {}) noexcept
|
explicit json_formatter(
|
||||||
: base{
|
const toml::node& source,
|
||||||
source_,
|
format_flags flags = format_flags::quote_dates_and_times) noexcept
|
||||||
impl::formatter_options{
|
: base{ source, flags }
|
||||||
indent_string,
|
|
||||||
true //quote_dates_and_times
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -63,7 +69,7 @@ namespace toml
|
|||||||
TOML_MAY_THROW
|
TOML_MAY_THROW
|
||||||
{
|
{
|
||||||
rhs.attach(lhs);
|
rhs.attach(lhs);
|
||||||
rhs.print(rhs.source());
|
rhs.print();
|
||||||
rhs.detach();
|
rhs.detach();
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
/// \brief A TOML node.
|
||||||
|
///
|
||||||
|
/// \detail A parsed TOML document forms a tree made up of tables, arrays and values.
|
||||||
|
/// This type is the base of each of those, providing a lot of the polymorphic plumbing.
|
||||||
class TOML_INTERFACE node
|
class TOML_INTERFACE node
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -43,25 +47,46 @@ namespace toml
|
|||||||
|
|
||||||
virtual ~node() noexcept = default;
|
virtual ~node() noexcept = default;
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Returns the node's type identifier.
|
||||||
[[nodiscard]] virtual node_type type() const noexcept = 0;
|
[[nodiscard]] virtual node_type type() const noexcept = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Returns true if this node is a table.
|
||||||
[[nodiscard]] virtual bool is_table() const noexcept = 0;
|
[[nodiscard]] virtual bool is_table() const noexcept = 0;
|
||||||
|
/// \brief Returns true if this node is an array.
|
||||||
[[nodiscard]] virtual bool is_array() const noexcept = 0;
|
[[nodiscard]] virtual bool is_array() const noexcept = 0;
|
||||||
|
/// \brief Returns true if this node is a value.
|
||||||
[[nodiscard]] virtual bool is_value() const noexcept = 0;
|
[[nodiscard]] virtual bool is_value() const noexcept = 0;
|
||||||
|
|
||||||
|
/// \brief Returns true if this node is a string value.
|
||||||
[[nodiscard]] virtual bool is_string() const noexcept { return false; }
|
[[nodiscard]] virtual bool is_string() const noexcept { return false; }
|
||||||
|
/// \brief Returns true if this node is an integer value.
|
||||||
[[nodiscard]] virtual bool is_integer() const noexcept { return false; }
|
[[nodiscard]] virtual bool is_integer() const noexcept { return false; }
|
||||||
|
/// \brief Returns true if this node is an floating-point value.
|
||||||
[[nodiscard]] virtual bool is_floating_point() const noexcept { return false; }
|
[[nodiscard]] virtual bool is_floating_point() const noexcept { return false; }
|
||||||
|
/// \brief Returns true if this node is a boolean value.
|
||||||
[[nodiscard]] virtual bool is_boolean() const noexcept { return false; }
|
[[nodiscard]] virtual bool is_boolean() const noexcept { return false; }
|
||||||
|
/// \brief Returns true if this node is a local date value.
|
||||||
[[nodiscard]] virtual bool is_date() const noexcept { return false; }
|
[[nodiscard]] virtual bool is_date() const noexcept { return false; }
|
||||||
|
/// \brief Returns true if this node is a local time value.
|
||||||
[[nodiscard]] virtual bool is_time() const noexcept { return false; }
|
[[nodiscard]] virtual bool is_time() const noexcept { return false; }
|
||||||
|
/// \brief Returns true if this node is a date-time value.
|
||||||
[[nodiscard]] virtual bool is_date_time() const noexcept { return false; }
|
[[nodiscard]] virtual bool is_date_time() const noexcept { return false; }
|
||||||
|
/// \brief Returns true if this node is an array containing only tables.
|
||||||
[[nodiscard]] virtual bool is_array_of_tables() const noexcept { return false; }
|
[[nodiscard]] virtual bool is_array_of_tables() const noexcept { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Checks if a node is a specific type.
|
||||||
|
///
|
||||||
|
/// \tparam T The
|
||||||
|
///
|
||||||
|
/// \returns Returns true if this node is an instance
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]] bool is() const noexcept
|
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||||
|
bool is() const noexcept
|
||||||
{
|
{
|
||||||
using type = value_of<T>;
|
using type = value_of<impl::remove_cvref_t<T>>;
|
||||||
static_assert(
|
static_assert(
|
||||||
impl::is_value_or_node<type>,
|
impl::is_value_or_node<type>,
|
||||||
"Template type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
"Template type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||||
@ -155,8 +180,7 @@ namespace toml
|
|||||||
static decltype(auto) do_visit(N* node, FUNC&& visitor) TOML_MAY_THROW
|
static decltype(auto) do_visit(N* node, FUNC&& visitor) TOML_MAY_THROW
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
impl::is_generic_invocable_v<FUNC&&>
|
std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<table>())>
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<table>())>
|
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<array>())>
|
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<array>())>
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<string>())>
|
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<string>())>
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<int64_t>())>
|
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<int64_t>())>
|
||||||
@ -168,7 +192,7 @@ namespace toml
|
|||||||
"Visitors must be invocable for at least one of the toml::node specializations"
|
"Visitors must be invocable for at least one of the toml::node specializations"
|
||||||
);
|
);
|
||||||
|
|
||||||
static constexpr auto is_exhaustive = impl::is_generic_invocable_v<FUNC&&> || (
|
static constexpr auto is_exhaustive =
|
||||||
std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<table>())>
|
std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<table>())>
|
||||||
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<array>())>
|
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<array>())>
|
||||||
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<string>())>
|
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<string>())>
|
||||||
@ -177,54 +201,44 @@ namespace toml
|
|||||||
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<bool>())>
|
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<bool>())>
|
||||||
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<date>())>
|
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<date>())>
|
||||||
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<time>())>
|
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<time>())>
|
||||||
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<date_time>())>
|
&& std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<date_time>())>;
|
||||||
);
|
|
||||||
|
|
||||||
switch (node->type())
|
switch (node->type())
|
||||||
{
|
{
|
||||||
case node_type::table:
|
case node_type::table:
|
||||||
if constexpr (impl::is_generic_invocable_v<FUNC&&>
|
if constexpr (std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<table>())>)
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<table>())>)
|
|
||||||
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<table>());
|
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<table>());
|
||||||
break;
|
break;
|
||||||
case node_type::array:
|
case node_type::array:
|
||||||
if constexpr (impl::is_generic_invocable_v<FUNC&&>
|
if constexpr (std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<array>())>)
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<array>())>)
|
|
||||||
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<array>());
|
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<array>());
|
||||||
break;
|
break;
|
||||||
case node_type::string:
|
case node_type::string:
|
||||||
if constexpr (impl::is_generic_invocable_v<FUNC&&>
|
if constexpr (std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<string>())>)
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<string>())>)
|
|
||||||
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<string>());
|
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<string>());
|
||||||
break;
|
break;
|
||||||
case node_type::integer:
|
case node_type::integer:
|
||||||
if constexpr (impl::is_generic_invocable_v<FUNC&&>
|
if constexpr (std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<int64_t>())>)
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<int64_t>())>)
|
|
||||||
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<int64_t>());
|
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<int64_t>());
|
||||||
break;
|
break;
|
||||||
case node_type::floating_point:
|
case node_type::floating_point:
|
||||||
if constexpr (impl::is_generic_invocable_v<FUNC&&>
|
if constexpr (std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<double>())>)
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<double>())>)
|
|
||||||
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<double>());
|
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<double>());
|
||||||
break;
|
break;
|
||||||
case node_type::boolean:
|
case node_type::boolean:
|
||||||
if constexpr (impl::is_generic_invocable_v<FUNC&&>
|
if constexpr (std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<bool>())>)
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<bool>())>)
|
|
||||||
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<bool>());
|
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<bool>());
|
||||||
break;
|
break;
|
||||||
case node_type::date:
|
case node_type::date:
|
||||||
if constexpr (impl::is_generic_invocable_v<FUNC&&>
|
if constexpr (std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<date>())>)
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<date>())>)
|
|
||||||
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<date>());
|
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<date>());
|
||||||
break;
|
break;
|
||||||
case node_type::time:
|
case node_type::time:
|
||||||
if constexpr (impl::is_generic_invocable_v<FUNC&&>
|
if constexpr (std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<time>())>)
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<time>())>)
|
|
||||||
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<time>());
|
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<time>());
|
||||||
break;
|
break;
|
||||||
case node_type::date_time:
|
case node_type::date_time:
|
||||||
if constexpr (impl::is_generic_invocable_v<FUNC&&>
|
if constexpr (std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<date_time>())>)
|
||||||
|| std::is_invocable_v<FUNC&&, decltype(*node->template reinterpret_as<date_time>())>)
|
|
||||||
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<date_time>());
|
return std::forward<FUNC>(visitor)(*node->template reinterpret_as<date_time>());
|
||||||
break;
|
break;
|
||||||
TOML_NO_DEFAULT_CASE;
|
TOML_NO_DEFAULT_CASE;
|
||||||
|
@ -252,4 +252,26 @@ namespace toml::impl
|
|||||||
if (val.time_offset)
|
if (val.time_offset)
|
||||||
print_to_stream(*val.time_offset, stream);
|
print_to_stream(*val.time_offset, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TOML_PUSH_WARNINGS
|
||||||
|
TOML_DISABLE_ALL_WARNINGS
|
||||||
|
|
||||||
|
template <typename T, typename CHAR>
|
||||||
|
void print_to_stream_with_escapes(T && str, std::basic_ostream<CHAR>& stream) TOML_MAY_THROW
|
||||||
|
{
|
||||||
|
static_assert(sizeof(CHAR) == 1);
|
||||||
|
for (auto c : str)
|
||||||
|
{
|
||||||
|
if (c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F')) TOML_UNLIKELY
|
||||||
|
print_to_stream(low_character_escape_table[c], stream);
|
||||||
|
else if (c == TOML_STRING_PREFIX('\x7F')) TOML_UNLIKELY
|
||||||
|
print_to_stream(TOML_STRING_PREFIX("\\u007F"sv), stream);
|
||||||
|
else if (c == TOML_STRING_PREFIX('"')) TOML_UNLIKELY
|
||||||
|
print_to_stream(TOML_STRING_PREFIX("\\\""sv), stream);
|
||||||
|
else
|
||||||
|
print_to_stream(c, stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_POP_WARNINGS
|
||||||
}
|
}
|
||||||
|
@ -224,5 +224,8 @@ namespace toml
|
|||||||
|
|
||||||
[[nodiscard]] inline node_view<table> operator[] (string_view) noexcept;
|
[[nodiscard]] inline node_view<table> operator[] (string_view) noexcept;
|
||||||
[[nodiscard]] inline node_view<const table> operator[] (string_view) const noexcept;
|
[[nodiscard]] inline node_view<const table> operator[] (string_view) const noexcept;
|
||||||
|
|
||||||
|
template <typename CHAR>
|
||||||
|
friend inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const table&) TOML_MAY_THROW;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "toml_node.h"
|
#include "toml_node.h"
|
||||||
|
#include "toml_print_to_stream.h"
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
@ -102,7 +103,18 @@ namespace toml
|
|||||||
template <typename CHAR>
|
template <typename CHAR>
|
||||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const value& rhs) TOML_MAY_THROW
|
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const value& rhs) TOML_MAY_THROW
|
||||||
{
|
{
|
||||||
|
// this is the same behaviour as default_formatter, but it's so simple that there's
|
||||||
|
// no need to spin up a new instance of it just for individual values.
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<T, string>)
|
||||||
|
{
|
||||||
|
impl::print_to_stream('"', lhs);
|
||||||
|
impl::print_to_stream_with_escapes(rhs.val_, lhs);
|
||||||
|
impl::print_to_stream('"', lhs);
|
||||||
|
}
|
||||||
|
else
|
||||||
impl::print_to_stream(rhs.val_, lhs);
|
impl::print_to_stream(rhs.val_, lhs);
|
||||||
|
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ def get_script_folder():
|
|||||||
|
|
||||||
def read_all_text_from_file(path):
|
def read_all_text_from_file(path):
|
||||||
print("Reading {}".format(path))
|
print("Reading {}".format(path))
|
||||||
with open(path, 'r') as file:
|
with open(path, 'r', encoding='utf-8') as file:
|
||||||
text = file.read()
|
text = file.read()
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
@ -57,28 +57,6 @@ def get_all_files(dir, all=None, any=None):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def print_value(name, val):
|
|
||||||
print('{}:\n {}'.format(name, val))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def error_message(err, prefix="Error"):
|
|
||||||
if (isinstance(err, Exception) or (is_collection(err) and isinstance(err[0], Exception))):
|
|
||||||
exc = err[0] if is_collection(err) else err
|
|
||||||
trace = err[1] if (is_collection(err) and len(err) > 1) else traceback.format_exc(err)
|
|
||||||
print('{}: [{}] {}\n{}'.format(
|
|
||||||
prefix,
|
|
||||||
type(err).__name__,
|
|
||||||
str(err),
|
|
||||||
traceback.format_exc(err)
|
|
||||||
),
|
|
||||||
file=sys.stderr
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
print("{}: {}".format(prefix, err), file=sys.stderr)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HTMLDocument(object):
|
class HTMLDocument(object):
|
||||||
|
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
@ -257,14 +235,14 @@ class NavBarFix(object):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# changes any links to index.html to link to namespaces.html instead (index.html is blank/unused)
|
# changes any links to index.html to link to annotated.html instead (index.html is blank/unused)
|
||||||
class IndexHrefFix(object):
|
class IndexHrefFix(object):
|
||||||
|
|
||||||
def __call__(self, file, doc):
|
def __call__(self, file, doc):
|
||||||
links = doc.body('a', href='index.html')
|
links = doc.body('a', href='index.html')
|
||||||
if (len(links) > 0):
|
if (len(links) > 0):
|
||||||
for link in links:
|
for link in links:
|
||||||
link['href'] = 'namespaces.html'
|
link['href'] = 'annotated.html'
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -475,31 +453,11 @@ class InlineNamespaceFix3(InlineNamespaceFixBase):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# adds a custom footer to the main index pages.
|
|
||||||
class FooterFix(object):
|
|
||||||
__replacement = '<div id="tpp-custom-footer tpp-injected">Documentation generated {} using ' \
|
|
||||||
+ '<a href="https://mcss.mosra.cz/">m.css</a></div>'.format(
|
|
||||||
datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
|
|
||||||
)
|
|
||||||
|
|
||||||
def __call__(self, file, doc):
|
|
||||||
footer = doc.body.find(id='tpp-custom-footer')
|
|
||||||
if (footer is None):
|
|
||||||
return False
|
|
||||||
html_replace_tag(footer, self.__replacement)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#=======================================================================================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# adds links to external sources where appropriate
|
# adds links to external sources where appropriate
|
||||||
class ExtDocLinksFix(object):
|
class ExtDocLinksFix(object):
|
||||||
__types = [
|
__types = [
|
||||||
(r'(?:std::)?size_t', 'https://en.cppreference.com/w/cpp/types/size_t'),
|
(r'(?:std::)?size_t', 'https://en.cppreference.com/w/cpp/types/size_t'),
|
||||||
(r'(?:std::)?u?int(?:8|16|32|64)_ts?', 'https://en.cppreference.com/w/cpp/types/integer'),
|
(r'(?:std::)?u?int(?:8|16|32|64)(fast|least)?_ts?', 'https://en.cppreference.com/w/cpp/types/integer'),
|
||||||
(r'std::pairs?', 'https://en.cppreference.com/w/cpp/utility/pair'),
|
(r'std::pairs?', 'https://en.cppreference.com/w/cpp/utility/pair'),
|
||||||
(r'std::bytes?', 'https://en.cppreference.com/w/cpp/types/byte'),
|
(r'std::bytes?', 'https://en.cppreference.com/w/cpp/types/byte'),
|
||||||
(r'std::optionals?', 'https://en.cppreference.com/w/cpp/utility/optional'),
|
(r'std::optionals?', 'https://en.cppreference.com/w/cpp/utility/optional'),
|
||||||
@ -554,6 +512,8 @@ class ExtDocLinksFix(object):
|
|||||||
(r'std::add_[lr]value_reference(?:_t)?', 'https://en.cppreference.com/w/cpp/types/add_reference'),
|
(r'std::add_[lr]value_reference(?:_t)?', 'https://en.cppreference.com/w/cpp/types/add_reference'),
|
||||||
(r'std::remove_reference(?:_t)?', 'https://en.cppreference.com/w/cpp/types/remove_reference'),
|
(r'std::remove_reference(?:_t)?', 'https://en.cppreference.com/w/cpp/types/remove_reference'),
|
||||||
(r'std::remove_cv(?:_t)?', 'https://en.cppreference.com/w/cpp/types/remove_cv'),
|
(r'std::remove_cv(?:_t)?', 'https://en.cppreference.com/w/cpp/types/remove_cv'),
|
||||||
|
(r'std::exceptions?', 'https://en.cppreference.com/w/cpp/error/exception'),
|
||||||
|
(r'std::runtime_errors?', 'https://en.cppreference.com/w/cpp/error/runtime_error'),
|
||||||
(
|
(
|
||||||
r'(?:L?P)?(?:'
|
r'(?:L?P)?(?:'
|
||||||
+ r'D?WORD(?:32|64|_PTR)?|HANDLE|HMODULE|BOOL(?:EAN)?'
|
+ r'D?WORD(?:32|64|_PTR)?|HANDLE|HMODULE|BOOL(?:EAN)?'
|
||||||
@ -661,27 +621,44 @@ class EnableIfFix(object):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
_threadError = None
|
_threadError = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def postprocess_file(dir, file, fixes):
|
def postprocess_file(dir, file, fixes):
|
||||||
|
|
||||||
global _threadError
|
global _threadError
|
||||||
if (_threadError is not None):
|
if (_threadError):
|
||||||
return False
|
return False
|
||||||
print("Post-processing {}".format(file))
|
print("Post-processing {}".format(file))
|
||||||
|
changed = False
|
||||||
|
|
||||||
|
try:
|
||||||
doc = HTMLDocument(path.join(dir, file))
|
doc = HTMLDocument(path.join(dir, file))
|
||||||
file = file.lower()
|
file = file.lower()
|
||||||
changed = False
|
|
||||||
for fix in fixes:
|
for fix in fixes:
|
||||||
if (fix(file, doc)):
|
if (fix(file, doc)):
|
||||||
changed = True
|
changed = True
|
||||||
if (changed):
|
if (changed):
|
||||||
doc.flush()
|
doc.flush()
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
print(
|
||||||
|
'Error: [{}] {}'.format(
|
||||||
|
type(err).__name__,
|
||||||
|
str(err)
|
||||||
|
),
|
||||||
|
file=sys.stderr
|
||||||
|
)
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
_threadError = True
|
||||||
|
|
||||||
return changed
|
return changed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def delete_directory(dir_path):
|
def delete_directory(dir_path):
|
||||||
if (path.exists(dir_path)):
|
if (path.exists(dir_path)):
|
||||||
print('Deleting {}'.format(dir_path))
|
print('Deleting {}'.format(dir_path))
|
||||||
@ -712,12 +689,6 @@ def main():
|
|||||||
mcss_dir = path.join(root_dir, 'extern', 'mcss')
|
mcss_dir = path.join(root_dir, 'extern', 'mcss')
|
||||||
doxygen = path.join(mcss_dir, 'documentation', 'doxygen.py')
|
doxygen = path.join(mcss_dir, 'documentation', 'doxygen.py')
|
||||||
|
|
||||||
print_value('doc', docs_dir)
|
|
||||||
print_value('xml', xml_dir)
|
|
||||||
print_value('html', html_dir)
|
|
||||||
print_value('m.css', mcss_dir)
|
|
||||||
print_value('doxygen', doxygen)
|
|
||||||
|
|
||||||
# delete any previously generated html and xml
|
# delete any previously generated html and xml
|
||||||
delete_directory(xml_dir)
|
delete_directory(xml_dir)
|
||||||
delete_directory(html_dir)
|
delete_directory(html_dir)
|
||||||
@ -744,26 +715,22 @@ def main():
|
|||||||
, InlineNamespaceFix1()
|
, InlineNamespaceFix1()
|
||||||
, InlineNamespaceFix2()
|
, InlineNamespaceFix2()
|
||||||
, InlineNamespaceFix3()
|
, InlineNamespaceFix3()
|
||||||
, FooterFix()
|
|
||||||
, ExtDocLinksFix()
|
, ExtDocLinksFix()
|
||||||
, EnableIfFix()
|
, EnableIfFix()
|
||||||
]
|
]
|
||||||
files = [path.split(f) for f in get_all_files(html_dir, any=('*.html', '*.htm'))]
|
files = [path.split(f) for f in get_all_files(html_dir, any=('*.html', '*.htm'))]
|
||||||
print_value("Files", files)
|
|
||||||
if files:
|
if files:
|
||||||
with concurrent.futures.ThreadPoolExecutor(max_workers=min(len(files), num_threads)) as executor:
|
with concurrent.futures.ThreadPoolExecutor(max_workers=min(len(files), num_threads)) as executor:
|
||||||
jobs = { executor.submit(postprocess_file, dir, file, fixes) : file for dir, file in files }
|
jobs = { executor.submit(postprocess_file, dir, file, fixes) : file for dir, file in files }
|
||||||
for job in concurrent.futures.as_completed(jobs):
|
for job in concurrent.futures.as_completed(jobs):
|
||||||
file = jobs[job]
|
if _threadError:
|
||||||
try:
|
|
||||||
print('Finished processing {}.'.format(file))
|
|
||||||
except Exception as e:
|
|
||||||
_threadError = (e, traceback.format_exc(e))
|
|
||||||
executor.shutdown(False)
|
executor.shutdown(False)
|
||||||
break
|
break
|
||||||
if (_threadError is not None):
|
else:
|
||||||
error_message(_threadError, prefix="Fatal error")
|
file = jobs[job]
|
||||||
sys.exit(-1)
|
print('Finished processing {}.'.format(file))
|
||||||
|
if _threadError:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -772,7 +739,7 @@ if __name__ == '__main__':
|
|||||||
main()
|
main()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print(
|
print(
|
||||||
'Fatal error: [{}] {}'.format(
|
'Error: [{}] {}'.format(
|
||||||
type(err).__name__,
|
type(err).__name__,
|
||||||
str(err)
|
str(err)
|
||||||
),
|
),
|
||||||
|
@ -16,7 +16,7 @@ def get_script_folder():
|
|||||||
|
|
||||||
def read_all_text_from_file(path):
|
def read_all_text_from_file(path):
|
||||||
print("Reading {}".format(path))
|
print("Reading {}".format(path))
|
||||||
with open(path, 'r') as file:
|
with open(path, 'r', encoding='utf-8') as file:
|
||||||
text = file.read()
|
text = file.read()
|
||||||
return text
|
return text
|
||||||
|
|
||||||
@ -78,11 +78,19 @@ def main():
|
|||||||
source_text = Preprocessor()('toml.h')
|
source_text = Preprocessor()('toml.h')
|
||||||
source_text = re.sub('\r\n', '\n', source_text, 0, re.I | re.M) # convert windows newlines
|
source_text = re.sub('\r\n', '\n', source_text, 0, re.I | re.M) # convert windows newlines
|
||||||
source_text = re.sub('(?:\n[ \t]*//[/#!<]+[^\n]*)+\n', '\n', source_text, 0, re.I | re.M) # remove 'magic' comment blocks
|
source_text = re.sub('(?:\n[ \t]*//[/#!<]+[^\n]*)+\n', '\n', source_text, 0, re.I | re.M) # remove 'magic' comment blocks
|
||||||
source_text = re.sub('^[ \t]*//[/#!<]+.+?$', '', source_text, 0, re.I | re.M) # remove 'magic' comments
|
source_text = re.sub('\n(?:[ \t]*\n[ \t]*)+\n', '\n\n', source_text, 0, re.I | re.M) # remove double newlines
|
||||||
source_text = re.sub('\n([ \t]*\n[ \t]*)+\n', '\n\n', source_text, 0, re.I | re.M) # remove double newlines
|
|
||||||
source_text = re.sub('([^ \t])[ \t]+\n', '\\1\n', source_text, 0, re.I | re.M) # remove trailing whitespace
|
source_text = re.sub('([^ \t])[ \t]+\n', '\\1\n', source_text, 0, re.I | re.M) # remove trailing whitespace
|
||||||
|
for i in range(0, 5): # remove blank lines between simple one-liner definitions
|
||||||
|
source_text = re.sub('(using .+?;)\n\n([ \t]*using)', '\\1\n\\2', source_text, 0, re.I | re.M)
|
||||||
|
source_text = re.sub(
|
||||||
|
'([a-zA-Z_][a-zA-Z0-9_]*[ \t]+[a-zA-Z_][a-zA-Z0-9_]*[ \t]*;)' \
|
||||||
|
+ '\n\n([ \t]*[a-zA-Z_][a-zA-Z0-9_]*[ \t]+[a-zA-Z_][a-zA-Z0-9_]*[ \t]*;)', '\\1\n\\2',
|
||||||
|
source_text, 0, re.I | re.M)
|
||||||
|
source_text = re.sub('(\[\[nodiscard\]\][^\n]+)\n\n([ \t]*\[\[nodiscard\]\])', '\\1\n\\2', source_text, 0, re.I | re.M)
|
||||||
source_text = source_text.strip()
|
source_text = source_text.strip()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# extract library version
|
# extract library version
|
||||||
library_version = [0,0,0]
|
library_version = [0,0,0]
|
||||||
match = re.search(r'^\s*#\s*define\s+TOML_LIB_MAJOR\s+([0-9]+)\s*$', source_text, re.I | re.M)
|
match = re.search(r'^\s*#\s*define\s+TOML_LIB_MAJOR\s+([0-9]+)\s*$', source_text, re.I | re.M)
|
||||||
|
@ -467,7 +467,7 @@ def main():
|
|||||||
print(codepoint_list, end='', file=codepoint_file)
|
print(codepoint_list, end='', file=codepoint_file)
|
||||||
else:
|
else:
|
||||||
print("Reading unicode database file into memory")
|
print("Reading unicode database file into memory")
|
||||||
with open(codepoint_file_path, 'r') as codepoint_file:
|
with open(codepoint_file_path, 'r', encoding='utf-8') as codepoint_file:
|
||||||
codepoint_list = codepoint_file.read()
|
codepoint_list = codepoint_file.read()
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,6 +75,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\.editorconfig" />
|
<None Include="..\.editorconfig" />
|
||||||
|
<None Include="..\docs\Doxyfile" />
|
||||||
|
<None Include="..\docs\Doxyfile-mcss" />
|
||||||
|
<None Include="..\docs\tomlplusplus.css" />
|
||||||
|
<None Include="..\docs\tomlplusplus.js" />
|
||||||
<None Include="..\python\ci_single_header_check.py" />
|
<None Include="..\python\ci_single_header_check.py" />
|
||||||
<None Include="..\python\generate_documentation.py" />
|
<None Include="..\python\generate_documentation.py" />
|
||||||
<None Include="..\python\generate_single_header.py" />
|
<None Include="..\python\generate_single_header.py" />
|
||||||
|
@ -1,29 +1,92 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\include\toml++\toml_array.h" />
|
<ClInclude Include="..\include\toml++\toml.h">
|
||||||
<ClInclude Include="..\include\toml++\toml_value.h" />
|
<Filter>include</Filter>
|
||||||
<ClInclude Include="..\include\toml++\toml_parser.h" />
|
</ClInclude>
|
||||||
<ClInclude Include="..\include\toml++\toml_table.h" />
|
<ClInclude Include="..\include\toml++\toml_array.h">
|
||||||
<ClInclude Include="..\include\toml++\toml_common.h" />
|
<Filter>include</Filter>
|
||||||
<ClInclude Include="..\include\toml++\toml.h" />
|
</ClInclude>
|
||||||
<ClInclude Include="..\include\toml++\toml_utf8.h" />
|
<ClInclude Include="..\include\toml++\toml_common.h">
|
||||||
<ClInclude Include="..\include\toml++\toml_node.h" />
|
<Filter>include</Filter>
|
||||||
<ClInclude Include="..\include\toml++\toml_node_view.h" />
|
</ClInclude>
|
||||||
<ClInclude Include="..\include\toml++\toml_utf8_generated.h" />
|
<ClInclude Include="..\include\toml++\toml_date_time.h">
|
||||||
<ClInclude Include="..\include\toml++\toml_default_formatter.h" />
|
<Filter>include</Filter>
|
||||||
<ClInclude Include="..\include\toml++\toml_json_formatter.h" />
|
</ClInclude>
|
||||||
<ClInclude Include="..\include\toml++\toml_formatter.h" />
|
<ClInclude Include="..\include\toml++\toml_default_formatter.h">
|
||||||
<ClInclude Include="..\include\toml++\toml_version.h" />
|
<Filter>include</Filter>
|
||||||
<ClInclude Include="..\include\toml++\toml_print_to_stream.h" />
|
</ClInclude>
|
||||||
<ClInclude Include="..\include\toml++\toml_date_time.h" />
|
<ClInclude Include="..\include\toml++\toml_formatter.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_json_formatter.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_node.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_node_view.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_parser.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_print_to_stream.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_table.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_utf8.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_utf8_generated.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_value.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\toml++\toml_version.h">
|
||||||
|
<Filter>include</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\.editorconfig" />
|
<None Include="..\.editorconfig" />
|
||||||
<None Include="..\README.md" />
|
<None Include="..\README.md" />
|
||||||
<None Include="..\python\generate_single_header.py" />
|
<None Include="..\python\ci_single_header_check.py">
|
||||||
<None Include="..\python\generate_unicode_functions.py" />
|
<Filter>python</Filter>
|
||||||
<None Include="..\python\generate_documentation.py" />
|
</None>
|
||||||
<None Include="..\python\ci_single_header_check.py" />
|
<None Include="..\python\generate_documentation.py">
|
||||||
|
<Filter>python</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\python\generate_single_header.py">
|
||||||
|
<Filter>python</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\python\generate_unicode_functions.py">
|
||||||
|
<Filter>python</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\docs\Doxyfile">
|
||||||
|
<Filter>doc</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\docs\Doxyfile-mcss">
|
||||||
|
<Filter>doc</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\docs\tomlplusplus.css">
|
||||||
|
<Filter>doc</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\docs\tomlplusplus.js">
|
||||||
|
<Filter>doc</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="include">
|
||||||
|
<UniqueIdentifier>{98f8e2f6-ce87-435a-bd9a-4f02b8ac66e7}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="python">
|
||||||
|
<UniqueIdentifier>{5ba46476-31a3-484e-aee7-f840dd2202b1}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="doc">
|
||||||
|
<UniqueIdentifier>{5ed0949f-6855-4664-ad86-2b38ceeb400b}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue
Block a user