added insertion operations for tables and arrays
also: - fixed column numbers being wrong when a value ended at EOF - fixed some `print_to_stream` overloads for `char8_t` - fixed a minor preprocessor snafu on MSVC - fixed '\' not being escaped when printing string values - added an initializer list constructor for tables - added `array::flatten` - added `table::find` - added `table::is_inline` setter - added `TOML_SMALL_INT_TYPE` - added `parse_file` - added stream operator for source_region - added proper license notice for the utf8 decoder - added lots more documentation and tests
This commit is contained in:
parent
c4f30c2ffa
commit
c7483cb92c
2
LICENSE
2
LICENSE
@ -14,3 +14,5 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
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.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
14
LICENSE-utf8-decoder
Normal file
14
LICENSE-utf8-decoder
Normal file
@ -0,0 +1,14 @@
|
||||
Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
|
||||
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.
|
49
README.md
49
README.md
@ -1,5 +1,5 @@
|
||||
# toml++ (tomlplusplus)
|
||||
![c++version](https://img.shields.io/badge/c%2B%2B-17%2C%2020-informational)
|
||||
[![c++version](https://img.shields.io/badge/c%2B%2B-17%2C%2020-informational)][cpp_compilers]
|
||||
[![tomlversion](https://img.shields.io/badge/TOML-v0.5.0-informational)][v0.5.0]
|
||||
[![CircleCI](https://circleci.com/gh/marzer/tomlplusplus.svg?style=shield)](https://circleci.com/gh/marzer/tomlplusplus)
|
||||
[![GitHub](https://img.shields.io/github/license/marzer/tomlplusplus)](https://github.com/marzer/tomlplusplus/blob/master/LICENSE)
|
||||
@ -10,11 +10,32 @@
|
||||
|
||||
# Example
|
||||
|
||||
```cpp
|
||||
/// example goes here.
|
||||
Given a TOML file `configuration.toml` containing the following:
|
||||
```toml
|
||||
[library]
|
||||
name = "toml++"
|
||||
version = "0.1.0"
|
||||
authors = ["Mark Gillard <mark@notarealwebsite.com>"]
|
||||
|
||||
[dependencies]
|
||||
cpp = 17
|
||||
```
|
||||
You'll find some more code examples in
|
||||
`examples` directory and plenty more as part of the [API documentation].
|
||||
Reading it in C++ is easy with `toml++`:
|
||||
```cpp
|
||||
auto config = toml::parse_file( "configuration.toml" );
|
||||
|
||||
// get key-value pairs
|
||||
std::string_view library_name = config["library"]["name"].as_string()->get();
|
||||
std::string_view library_version = config["library"]["version"].as_string()->get();
|
||||
std::string_view library_author = config["library"]["authors"][0].as_string()->get();
|
||||
int64_t depends_on_cpp_version = config["dependencies"]["cpp"].as_integer()->get();
|
||||
|
||||
// re-serialize as JSON
|
||||
std::cout << toml::json_formatter{ config } << std::endl;
|
||||
|
||||
|
||||
```
|
||||
You'll find some more code examples in the `examples` directory, and plenty more as part of the [API documentation].
|
||||
|
||||
<br>
|
||||
|
||||
@ -32,9 +53,8 @@ You'll find some more code examples in
|
||||
The API is the same regardless of how you consume the library.
|
||||
|
||||
### Configuration
|
||||
A number of configurable options are exposed in the form of preprocessor macros. Most likely you
|
||||
won't need to mess with these at all, but in the event you do, set your overrides prior to including
|
||||
toml++.
|
||||
A number of configurable options are exposed in the form of preprocessor `#defines`. Most likely you
|
||||
won't need to mess with these at all, butif you do, set them before including toml++.
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|----------------------------|:--------------:|-----------------------------------|----------------------------------------------------------------------------------------------------------|
|
||||
@ -43,6 +63,7 @@ toml++.
|
||||
| `TOML_CONFIG_HEADER` | string literal | undefined | Includes the given header file before the rest of the library. |
|
||||
| `TOML_LARGE_FILES` | boolean | `0` | Uses 32-bit integers for line and column indices (instead of 16-bit). |
|
||||
| `TOML_SMALL_FLOAT_TYPE` | type name | undefined | If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it. |
|
||||
| `TOML_SMALL_INT_TYPE` | type name | undefined | If your codebase has an additional 'small' integer type (e.g. 24-bits), this tells toml++ about it. |
|
||||
| `TOML_UNDEF_MACROS` | boolean | `1` | `#undefs` the library's internal macros at the end of the header. |
|
||||
| `TOML_UNRELEASED_FEATURES` | boolean | `1` | Enables support for [unreleased TOML language features] not yet part of a [numbered version]. |
|
||||
|
||||
@ -72,7 +93,7 @@ _These can be disabled (and thus strict [TOML v0.5.0] compliance enforced) by sp
|
||||
`TOML_UNRELEASED_FEATURES = 0` (see [Configuration](#Configuration))._
|
||||
|
||||
### **🔹TOML v0.5.0 and earlier:**
|
||||
- All features as of `<< release date >>`.
|
||||
- All features supported.
|
||||
|
||||
<br>
|
||||
|
||||
@ -104,7 +125,7 @@ Install [Visual Studio 2019] and [Test Adapter for Catch2], then open `vs/toml++
|
||||
projects in the `tests` solution folder. Visual Studio's Test Explorer should pick these up and
|
||||
allow you to run the tests directly.
|
||||
|
||||
If test discovery fails, you can usually fix it by clicking enabling
|
||||
If test discovery fails you can usually fix it by clicking enabling
|
||||
`Auto Detect runsettings Files` (settings gear icon > `Configure Run Settings`).
|
||||
|
||||
#### Linux
|
||||
@ -120,12 +141,10 @@ cd ../build-clang && ninja && ninja test
|
||||
|
||||
# License and Attribution
|
||||
|
||||
`toml++` is licensed under the terms of the MIT license - See [LICENSE].
|
||||
`toml++` is licensed under the terms of the MIT license - see [LICENSE].
|
||||
|
||||
UTF-8 decoding is performed using a state machine based on Bjoern Hoehrmann's '[Flexible and Economical UTF-8 Decoder]',
|
||||
which is itself subject to the terms of (what appears to be) the MIT license. The license text is included in the
|
||||
[relevant part](https://github.com/marzer/tomlplusplus/blob/master/include/toml%2B%2B/toml_utf8.h)
|
||||
of the toml++ source.
|
||||
which is also subject to the terms of the MIT license - see [LICENSE-utf8-decoder].
|
||||
|
||||
[API documentation]: https://marzer.github.io/tomlplusplus/namespacetoml.html
|
||||
[unreleased TOML language features]: https://github.com/marzer/tomlplusplus#unreleased-features
|
||||
@ -142,6 +161,7 @@ of the toml++ source.
|
||||
[Catch2]: https://github.com/catchorg/Catch2
|
||||
[Test Adapter for Catch2]: https://marketplace.visualstudio.com/items?itemName=JohnnyHendriks.ext01
|
||||
[Visual Studio 2019]: https://visualstudio.microsoft.com/vs/
|
||||
[cpp_compilers]: https://en.cppreference.com/w/cpp/compiler_support
|
||||
[#356]: https://github.com/toml-lang/toml/issues/356
|
||||
[#516]: https://github.com/toml-lang/toml/issues/516
|
||||
[#562]: https://github.com/toml-lang/toml/issues/562
|
||||
@ -152,3 +172,4 @@ of the toml++ source.
|
||||
[#665]: https://github.com/toml-lang/toml/issues/665
|
||||
[#671]: https://github.com/toml-lang/toml/issues/671
|
||||
[#687]: https://github.com/toml-lang/toml/issues/687
|
||||
[LICENSE-utf8-decoder]: https://github.com/marzer/tomlplusplus/blob/master/LICENSE-utf8-decoder
|
||||
|
@ -41,7 +41,6 @@ SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 4
|
||||
ALIASES = "cpp=@code{.cpp}" \
|
||||
"ecpp=@endcode" \
|
||||
"epp=@endcode" \
|
||||
"detail=@details"
|
||||
TCL_SUBST =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
@ -336,7 +335,8 @@ INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = TOML_DOXYGEN=1 \
|
||||
__cplusplus=201703L \
|
||||
TOML_ALWAYS_INLINE=inline \
|
||||
TOML_MAY_THROW=
|
||||
TOML_MAY_THROW= \
|
||||
TOML_NODISCARD_CTOR=
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -11,9 +11,8 @@ HTML_EXTRA_FILES = tomlplusplus.js
|
||||
SHOW_INCLUDE_FILES = NO
|
||||
##! M_THEME_COLOR = #22272e
|
||||
##! M_LINKS_NAVBAR1 = \
|
||||
##! pages
|
||||
##! namespaces
|
||||
##! M_LINKS_NAVBAR2 = \
|
||||
##! namespaces \
|
||||
##! annotated \
|
||||
##! "<a target="_blank" href="https://github.com/marzer/tomlplusplus/">Github</a>"
|
||||
##! M_SEARCH_DOWNLOAD_BINARY = NO
|
||||
|
@ -205,3 +205,9 @@ nav .m-thin {
|
||||
.m-code .p {
|
||||
color: rgb(120,120,120);
|
||||
}
|
||||
|
||||
.m-doc-details div table.m-table.m-fullwidth.m-flat thead tr th,
|
||||
.m-doc-details div table.m-table.m-fullwidth.m-flat tfoot tr th
|
||||
{
|
||||
color: #a5c9ea;
|
||||
}
|
||||
|
@ -27,7 +27,10 @@ namespace toml::impl
|
||||
|
||||
public:
|
||||
|
||||
using reference = std::conditional_t<is_const, const node&, node&>;
|
||||
using value_type = std::conditional_t<is_const, const node, node>;
|
||||
using reference = value_type&;
|
||||
using pointer = value_type*;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
array_iterator() noexcept = default;
|
||||
|
||||
@ -58,11 +61,53 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
reference operator* () const noexcept
|
||||
reference operator * () const noexcept
|
||||
{
|
||||
return *raw_->get();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
pointer operator -> () const noexcept
|
||||
{
|
||||
return raw_->get();
|
||||
}
|
||||
|
||||
array_iterator& operator += (ptrdiff_t rhs) noexcept
|
||||
{
|
||||
raw_ += rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
array_iterator& operator -= (ptrdiff_t rhs) noexcept
|
||||
{
|
||||
raw_ -= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr array_iterator operator + (const array_iterator& lhs, ptrdiff_t rhs) noexcept
|
||||
{
|
||||
return { lhs.raw_ + rhs };
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr array_iterator operator + (ptrdiff_t lhs, const array_iterator& rhs) noexcept
|
||||
{
|
||||
return { rhs.raw_ + lhs };
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr array_iterator operator - (const array_iterator& lhs, ptrdiff_t rhs) noexcept
|
||||
{
|
||||
return { lhs.raw_ - rhs };
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr ptrdiff_t operator - (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
||||
{
|
||||
return lhs.raw_ - rhs.raw_;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator == (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
||||
{
|
||||
@ -74,7 +119,60 @@ namespace toml::impl
|
||||
{
|
||||
return lhs.raw_ != rhs.raw_;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator < (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
||||
{
|
||||
return lhs.raw_ < rhs.raw_;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator <= (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
||||
{
|
||||
return lhs.raw_ <= rhs.raw_;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator > (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
||||
{
|
||||
return lhs.raw_ > rhs.raw_;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator >= (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
||||
{
|
||||
return lhs.raw_ >= rhs.raw_;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
reference operator[] (ptrdiff_t idx) const noexcept
|
||||
{
|
||||
return *(raw_ + idx)->get();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
auto make_node(T&& val) noexcept
|
||||
{
|
||||
using type = impl::unwrapped<remove_cvref_t<T>>;
|
||||
if constexpr (is_one_of<type, array, table>)
|
||||
{
|
||||
static_assert(
|
||||
std::is_rvalue_reference_v<decltype(val)>,
|
||||
"Tables and arrays may only be moved (not copied)."
|
||||
);
|
||||
return new type{ std::forward<T>(val) };
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(
|
||||
is_value_or_promotable<type>,
|
||||
"Value initializers must be (or be promotable to) one of the TOML value types"
|
||||
);
|
||||
return new value{ std::forward<T>(val) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace toml
|
||||
@ -83,23 +181,43 @@ namespace toml
|
||||
[[nodiscard]] bool operator != (const table& lhs, const table& rhs) noexcept;
|
||||
|
||||
/// \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: \cpp
|
||||
///
|
||||
/// auto table = toml::parse("arr = [1, 2, 3, 4, 'five']"sv);
|
||||
///
|
||||
/// \remarks The interface of this type is modeled after std::vector, with some
|
||||
/// additional considerations made for the heterogeneous nature of a
|
||||
/// TOML array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
///
|
||||
/// auto table = toml::parse("arr = [1, 2, 3, 4, 'five']"sv);
|
||||
/// auto& arr = *table.get_as<toml::array>("arr");
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// for (size_t i = 0; i < arr.size(); i++)
|
||||
/// {
|
||||
/// arr[i].visit([=](auto&& el) noexcept
|
||||
/// {
|
||||
/// std::cout << el << ", ";
|
||||
/// if constexpr (toml::is_integer<decltype(el)>)
|
||||
/// el++;
|
||||
/// else
|
||||
/// el = "six"sv;
|
||||
/// });
|
||||
/// }
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // prints: 1, 2, 3, 4, "five"
|
||||
/// arr.push_back(7);
|
||||
/// arr.push_back(8.0f);
|
||||
/// arr.push_back("nine"sv);
|
||||
/// arr.erase(arr.cbegin());
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// arr.emplace_back<toml::array>(10, 11.0);
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [1, 2, 3, 4, "five"]
|
||||
/// // [2, 3, 4, 5, "six"]
|
||||
/// // [3, 4, 5, "six", 7, 8.0, "nine"]
|
||||
/// // [3, 4, 5, "six", 7, 8.0, "nine", [10, 11.0]]
|
||||
/// \ecpp
|
||||
class array final
|
||||
: public node
|
||||
@ -108,6 +226,18 @@ namespace toml
|
||||
friend class impl::parser;
|
||||
std::vector<std::unique_ptr<node>> values;
|
||||
|
||||
void preinsertion_resize(size_t idx, size_t count) 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]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
using value_type = node;
|
||||
@ -115,18 +245,58 @@ namespace toml
|
||||
using difference_type = ptrdiff_t;
|
||||
using reference = node&;
|
||||
using const_reference = const node&;
|
||||
|
||||
/// \brief A RandomAccessIterator for iterating over the nodes in an array.
|
||||
using iterator = impl::array_iterator<false>;
|
||||
/// \brief A const RandomAccessIterator for iterating over the nodes in an array.
|
||||
using const_iterator = impl::array_iterator<true>;
|
||||
|
||||
/// \brief Default constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
array() noexcept = default;
|
||||
|
||||
/// \brief Move constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
array(array&& other) noexcept
|
||||
: node{ std::move(other) },
|
||||
values{ std::move(other.values) }
|
||||
{}
|
||||
|
||||
/// \brief Constructs an array with one or more initial values.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2.0,
|
||||
/// "three"sv,
|
||||
/// toml::array{ 4, 5 }
|
||||
/// };
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [1, 2.0, "three", [4, 5]]
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam U One of the TOML node or value types (or a type promotable to one).
|
||||
/// \tparam V One of the TOML node or value types (or a type promotable to one).
|
||||
/// \param val The value used to initialize node 0.
|
||||
/// \param vals The values used to initialize nodes 1...N.
|
||||
template <typename U, typename... V>
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit array(U&& val, V&&... vals) TOML_MAY_THROW
|
||||
{
|
||||
values.reserve(sizeof...(V) + 1_sz);
|
||||
values.emplace_back(impl::make_node(std::forward<U>(val)));
|
||||
if constexpr (sizeof...(V) > 0)
|
||||
{
|
||||
(
|
||||
values.emplace_back(impl::make_node(std::forward<V>(vals))),
|
||||
...
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Move-assignment operator.
|
||||
array& operator= (array&& rhs) noexcept
|
||||
{
|
||||
node::operator=(std::move(rhs));
|
||||
@ -134,21 +304,44 @@ namespace toml
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Always returns `node_type::array` for array nodes.
|
||||
[[nodiscard]] node_type type() const noexcept override { return node_type::array; }
|
||||
/// \brief Always returns `false` for array nodes.
|
||||
[[nodiscard]] bool is_table() const noexcept override { return false; }
|
||||
/// \brief Always returns `true` for array nodes.
|
||||
[[nodiscard]] bool is_array() const noexcept override { return true; }
|
||||
/// \brief Always returns `false` for array nodes.
|
||||
[[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; }
|
||||
|
||||
/// \brief Checks if the array contains values of only one type.
|
||||
/// \brief Checks if the array contains nodes of only one type.
|
||||
///
|
||||
/// \tparam T A TOML node type. Provide an explicit type for "is every element a T?".
|
||||
/// Leave it as the default `void` for "is every element the same type?".
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2,
|
||||
/// 3
|
||||
/// };
|
||||
/// std::cout << "homogenous: "sv << arr.is_homogeneous() << std::endl;
|
||||
/// std::cout << "all doubles: "sv << arr.is_homogeneous<double>() << std::endl;
|
||||
/// std::cout << "all arrays: "sv << arr.is_homogeneous<toml::array>() << std::endl;
|
||||
/// std::cout << "all integers: "sv << arr.is_homogeneous<int64_t>() << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // homogeneous: true
|
||||
/// // all doubles: false
|
||||
/// // all arrays: false
|
||||
/// // all integers: true
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam T A TOML node type.
|
||||
/// - Provide an explicit type for "is every node a T?"
|
||||
/// - Leave it as `void` for "is every node the same type?"
|
||||
///
|
||||
/// \returns True if the array was homogeneous.
|
||||
///
|
||||
/// \attention Empty arrays are _not_ regarded as homogeneous.
|
||||
/// \remarks Always returns `false` for empty arrays.
|
||||
template <typename T = void>
|
||||
[[nodiscard]] bool is_homogeneous() const noexcept
|
||||
{
|
||||
@ -178,88 +371,362 @@ namespace toml
|
||||
return is_homogeneous<toml::table>();
|
||||
}
|
||||
|
||||
/// \brief Gets a reference to the node element at a specific index.
|
||||
/// \brief Gets a reference to the node 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.
|
||||
/// \brief Gets a reference to the node 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.
|
||||
/// \brief Returns a reference to the first node in the array.
|
||||
[[nodiscard]] node& front() noexcept { return *values.front(); }
|
||||
/// \brief Returns a reference to the first element in the array.
|
||||
/// \brief Returns a reference to the first node in the array.
|
||||
[[nodiscard]] const node& front() const noexcept { return *values.front(); }
|
||||
/// \brief Returns a reference to the last element in the array.
|
||||
/// \brief Returns a reference to the last node in the array.
|
||||
[[nodiscard]] node& back() noexcept { return *values.back(); }
|
||||
/// \brief Returns a reference to the last element in the array.
|
||||
/// \brief Returns a reference to the last node in the array.
|
||||
[[nodiscard]] const node& back() const noexcept { return *values.back(); }
|
||||
|
||||
/// \brief Returns an iterator to the first element.
|
||||
/// \brief Returns an iterator to the first node.
|
||||
[[nodiscard]] iterator begin() noexcept { return { values.begin() }; }
|
||||
/// \brief Returns an iterator to the first element.
|
||||
/// \brief Returns an iterator to the first node.
|
||||
[[nodiscard]] const_iterator begin() const noexcept { return { values.begin() }; }
|
||||
/// \brief Returns an iterator to the first element.
|
||||
/// \brief Returns an iterator to the first node.
|
||||
[[nodiscard]] const_iterator cbegin() const noexcept { return { values.cbegin() }; }
|
||||
|
||||
/// \brief Returns an iterator to one-past-the-last element.
|
||||
/// \brief Returns an iterator to one-past-the-last node.
|
||||
[[nodiscard]] iterator end() noexcept { return { values.end() }; }
|
||||
/// \brief Returns an iterator to one-past-the-last element.
|
||||
/// \brief Returns an iterator to one-past-the-last node.
|
||||
[[nodiscard]] const_iterator end() const noexcept { return { values.end() }; }
|
||||
/// \brief Returns an iterator to one-past-the-last element.
|
||||
/// \brief Returns an iterator to one-past-the-last node.
|
||||
[[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(); }
|
||||
/// \brief Returns the number of elements in the array.
|
||||
/// \brief Returns the number of nodes in the array.
|
||||
[[nodiscard]] size_t size() const noexcept { return values.size(); }
|
||||
/// \brief Reserves internal storage capacity up to a pre-determined number of elements.
|
||||
/// \brief Reserves internal storage capacity up to a pre-determined number of nodes.
|
||||
void reserve(size_t new_capacity) TOML_MAY_THROW { values.reserve(new_capacity); }
|
||||
|
||||
|
||||
/// \brief Removes all elements from the array.
|
||||
/// \brief Removes all nodes from the array.
|
||||
void clear() noexcept { values.clear(); }
|
||||
|
||||
// insert()
|
||||
// emplace()
|
||||
/// \brief Inserts a new node at a specific position in the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 3
|
||||
/// };
|
||||
/// arr.insert(arr.cbegin() + 1, "two");
|
||||
/// arr.insert(arr.cend(), toml::array{ 4, 5 });
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [1, "two", 3, [4, 5]]
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam U One of the TOML node or value types (or a type promotable to one).
|
||||
/// \param pos The insertion position.
|
||||
/// \param val The value being inserted.
|
||||
///
|
||||
/// \returns An iterator to the inserted value.
|
||||
template <typename U>
|
||||
iterator insert(const_iterator pos, U&& val) noexcept
|
||||
{
|
||||
return { values.emplace(pos.raw_, impl::make_node(std::forward<U>(val))) };
|
||||
}
|
||||
|
||||
/// \brief Removes the specified element from the array.
|
||||
///
|
||||
/// \returns The position following the Iterator following the removed element.
|
||||
/// \brief Repeatedly inserts a value starting at a specific position in the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// "with an evil twinkle in its eye the goose said",
|
||||
/// "and immediately we knew peace was never an option."
|
||||
/// };
|
||||
/// arr.insert(arr.cbegin() + 1, 3, "honk");
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [
|
||||
/// // "with an evil twinkle in its eye the goose said",
|
||||
/// // "honk",
|
||||
/// // "honk",
|
||||
/// // "honk",
|
||||
/// // "and immediately we knew peace was never an option."
|
||||
/// // ]
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam U One of the TOML value types (or a type promotable to one).
|
||||
/// \param pos The insertion position.
|
||||
/// \param count The number of times the value should be inserted.
|
||||
/// \param val The value being inserted.
|
||||
///
|
||||
/// \returns An iterator to the first inserted value (or a copy of `pos` if count was 0).
|
||||
template <typename U>
|
||||
iterator insert(const_iterator pos, size_t count, U&& val) noexcept
|
||||
{
|
||||
switch (count)
|
||||
{
|
||||
case 0: return { values.begin() + (pos.raw_ - values.cbegin()) };
|
||||
case 1: return insert(pos, std::forward<U>(val));
|
||||
default:
|
||||
{
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - values.cbegin());
|
||||
preinsertion_resize(start_idx, count);
|
||||
size_t i = start_idx;
|
||||
for (size_t e = start_idx + count - 1_sz; i < e; i++)
|
||||
values[i].reset(impl::make_node(val));
|
||||
|
||||
//# potentially move the initial value into the last element
|
||||
values[i].reset(impl::make_node(std::forward<U>(val)));
|
||||
return { values.begin() + start_idx };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Inserts a range of values into the array at a specific position.
|
||||
///
|
||||
/// \tparam ITER An iterator type. Must satisfy ForwardIterator.
|
||||
/// \param pos The insertion position.
|
||||
/// \param first Iterator to the first value being inserted.
|
||||
/// \param last Iterator to the one-past-the-last value being inserted.
|
||||
///
|
||||
/// \returns An iterator to the first inserted value (or a copy of `pos` if `first` == `last`).
|
||||
template <typename ITER>
|
||||
iterator insert(const_iterator pos, ITER first, ITER last) noexcept
|
||||
{
|
||||
const auto count = std::distance(first, last);
|
||||
switch (count)
|
||||
{
|
||||
case 0: return { values.begin() + (pos.raw_ - values.cbegin()) };
|
||||
case 1: return insert(pos, *first);
|
||||
default:
|
||||
{
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - values.cbegin());
|
||||
preinsertion_resize(start_idx, count);
|
||||
size_t i = start_idx;
|
||||
for (auto it = first; it != last; it++)
|
||||
values[i].reset(impl::make_node(*it));
|
||||
return { values.begin() + start_idx };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Inserts a range of values into the array at a specific position.
|
||||
///
|
||||
/// \tparam U One of the TOML node or value types (or a type promotable to one).
|
||||
/// \param pos The insertion position.
|
||||
/// \param ilist An initializer list containing the values to be inserted.
|
||||
///
|
||||
/// \returns An iterator to the first inserted value (or a copy of `pos` if `ilist` was empty).
|
||||
template <typename U>
|
||||
iterator insert(const_iterator pos, std::initializer_list<U> ilist) noexcept
|
||||
{
|
||||
switch (ilist.size())
|
||||
{
|
||||
case 0: return { values.begin() + (pos.raw_ - values.cbegin()) };
|
||||
case 1: return insert(pos, *ilist.begin());
|
||||
default:
|
||||
{
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - values.cbegin());
|
||||
preinsertion_resize(start_idx, ilist.size());
|
||||
size_t i = start_idx;
|
||||
for (auto& val : ilist)
|
||||
values[i].reset(impl::make_node(val));
|
||||
return { values.begin() + start_idx };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Emplaces a new value at a specific position in the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2
|
||||
/// };
|
||||
///
|
||||
/// //add a string using std::string's substring constructor
|
||||
/// arr.emplace<std::string>(arr.cbegin() + 1, "this is not a drill"sv, 14, 5);
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [1, "drill" 2]
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam U One of the TOML node or value types.
|
||||
/// \tparam V Value constructor argument types.
|
||||
/// \param pos The insertion position.
|
||||
/// \param args Arguments to pass to the value constructor.
|
||||
///
|
||||
/// \returns An iterator to the inserted value.
|
||||
///
|
||||
/// \remarks There is no difference between insert and emplace
|
||||
/// For trivial value types (floats, ints, bools).
|
||||
template <typename U, typename... V>
|
||||
iterator emplace(const_iterator pos, V&&... args) noexcept
|
||||
{
|
||||
using type = impl::unwrapped<U>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Emplacement type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
);
|
||||
|
||||
return { values.emplace(pos.raw_, new node_of<type>{ std::forward<V>(args)...} ) };
|
||||
}
|
||||
|
||||
/// \brief Removes the specified node from the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2,
|
||||
/// 3
|
||||
/// };
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// arr.erase(arr.cbegin() + 1);
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [1, 2, 3]
|
||||
/// // [1, 3]
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param pos Iterator to the node being erased.
|
||||
///
|
||||
/// \returns Iterator to the first node immediately following the removed node.
|
||||
iterator erase(const_iterator pos) noexcept
|
||||
{
|
||||
return iterator{ values.erase(pos.raw_) };
|
||||
return { values.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
/// \brief Removes the specified range of elements elements from the array.
|
||||
/// \brief Removes the nodes in the range [first, last) from the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// "bad",
|
||||
/// "karma"
|
||||
/// 2,
|
||||
/// };
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// \returns The position following the Iterator following the last removed element.
|
||||
/// arr.erase(arr.cbegin() + 1, arr.cbegin() + 3);
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [1, "bad", "karma", 3]
|
||||
/// // [1, 3]
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param first Iterator to the first node being erased.
|
||||
/// \param last Iterator to the one-past-the-last node being erased.
|
||||
///
|
||||
/// \returns Iterator to the first node immediately following the last removed node.
|
||||
iterator erase(const_iterator first, const_iterator last) noexcept
|
||||
{
|
||||
return iterator{ values.erase(first.raw_, last.raw_) };
|
||||
return { 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.
|
||||
/// \brief Appends a new value to the end of the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2
|
||||
/// };
|
||||
/// arr.push_back(3);
|
||||
/// arr.push_back(4.0);
|
||||
/// arr.push_back(array{ 5, "six"sv });
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [1, 2, 3, 4.0, [5, "six"]]
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam U One of the TOML value types (or a type promotable to one).
|
||||
/// \param val The value being added.
|
||||
///
|
||||
/// \returns A reference to the newly-constructed value node.
|
||||
template <typename U>
|
||||
decltype(auto) push_back(U&& val) noexcept
|
||||
{
|
||||
auto nde = impl::make_node(std::forward<U>(val));
|
||||
values.emplace_back(nde);
|
||||
return *nde;
|
||||
}
|
||||
|
||||
/// \brief Emplaces a new value at the end of the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2
|
||||
/// };
|
||||
/// arr.emplace_back<array>(3, "four"sv);
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [1, 2, [3, "four"]]
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam U One of the TOML value types.
|
||||
/// \tparam V Value constructor argument types.
|
||||
/// \param args Arguments to pass to the value constructor.
|
||||
///
|
||||
/// \returns A reference to the newly-constructed value node.
|
||||
///
|
||||
/// \remarks There is no difference between push_back and emplace_back
|
||||
/// For trivial value types (floats, ints, bools).
|
||||
template <typename U, typename... V>
|
||||
decltype(auto) emplace_back(V&&... args) noexcept
|
||||
{
|
||||
using type = impl::unwrapped<U>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Emplacement type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
);
|
||||
|
||||
auto nde = new node_of<type>{ std::forward<V>(args)... };
|
||||
values.emplace_back(nde);
|
||||
return *nde;
|
||||
}
|
||||
|
||||
/// \brief Removes the last node from the array.
|
||||
void pop_back() noexcept
|
||||
{
|
||||
values.pop_back();
|
||||
}
|
||||
|
||||
/// \brief Gets the node at a specific index if it is a particular type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 42,
|
||||
/// "is the meaning of life, apparently."sv
|
||||
/// };
|
||||
/// if (auto val = arr.get_as<int64_t>(0))
|
||||
/// std::cout << "node [0] was an integer with value "sv << **val << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // node [0] was an integer with value 42
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam T The node's type.
|
||||
/// \param index The element index.
|
||||
/// \param index The node's index.
|
||||
///
|
||||
/// \returns A pointer to the selected element if it was of the specified type, or nullptr.
|
||||
/// \returns A pointer to the selected node if it was of the specified type, or nullptr.
|
||||
template <typename T>
|
||||
[[nodiscard]] node_of<T>* get_as(size_t index) noexcept
|
||||
{
|
||||
return values[index]->as<T>();
|
||||
}
|
||||
|
||||
/// \brief Gets an element at a specific index if it is a particular type.
|
||||
/// \brief Gets the node at a specific index if it is a particular type (const overload).
|
||||
///
|
||||
/// \tparam T The node's type.
|
||||
/// \param index The element index.
|
||||
/// \param index The node's index.
|
||||
///
|
||||
/// \returns A pointer to the selected element if it was of the specified type, or nullptr.
|
||||
/// \returns A pointer to the selected node if it was of the specified type, or nullptr.
|
||||
template <typename T>
|
||||
[[nodiscard]] const node_of<T>* get_as(size_t index) const noexcept
|
||||
{
|
||||
@ -307,6 +774,111 @@ namespace toml
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
[[nodiscard]] size_t total_leaf_count() const noexcept
|
||||
{
|
||||
size_t leaves{};
|
||||
for (size_t i = 0, e = values.size(); i < e; i++)
|
||||
{
|
||||
auto arr = values[i]->as_array();
|
||||
leaves += arr ? arr->total_leaf_count() : 1_sz;
|
||||
}
|
||||
return leaves;
|
||||
}
|
||||
|
||||
void flatten_child(array&& child, size_t& dest_index) noexcept
|
||||
{
|
||||
for (size_t i = 0, e = child.size(); i < e; i++)
|
||||
{
|
||||
auto type = child.values[i]->type();
|
||||
if (type == node_type::array)
|
||||
{
|
||||
array& arr = *reinterpret_cast<array*>(child.values[i].get());
|
||||
if (!arr.empty())
|
||||
flatten_child(std::move(arr), dest_index);
|
||||
}
|
||||
else
|
||||
values[dest_index++] = std::move(child.values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Flattens this array, recursively hoisting the contents of child arrays up into itself.
|
||||
///
|
||||
/// \detail \cpp
|
||||
///
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2,
|
||||
/// toml::array{
|
||||
/// 3,
|
||||
/// 4,
|
||||
/// toml::array{ 5 }
|
||||
/// },
|
||||
/// 6,
|
||||
/// toml::array{}
|
||||
/// };
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// arr.flatten();
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // [1, 2, [3, 4, [5]], 6, []]
|
||||
/// // [1, 2, 3, 4, 5, 6]
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \remarks Arrays inside child tables are not flattened.
|
||||
void flatten() TOML_MAY_THROW
|
||||
{
|
||||
if (values.empty())
|
||||
return;
|
||||
|
||||
bool requires_flattening = false;
|
||||
size_t size_after_flattening = values.size();
|
||||
for (size_t i = values.size(); i --> 0_sz;)
|
||||
{
|
||||
auto arr = values[i]->as_array();
|
||||
if (!arr)
|
||||
continue;
|
||||
size_after_flattening--; //discount the array itself
|
||||
const auto leaf_count = arr->total_leaf_count();
|
||||
if (leaf_count > 0_sz)
|
||||
{
|
||||
requires_flattening = true;
|
||||
size_after_flattening += leaf_count;
|
||||
}
|
||||
else
|
||||
values.erase(values.cbegin() + i);
|
||||
}
|
||||
|
||||
if (!requires_flattening)
|
||||
return;
|
||||
|
||||
values.reserve(size_after_flattening);
|
||||
|
||||
size_t i = 0;
|
||||
while (i < values.size())
|
||||
{
|
||||
auto arr = values[i]->as_array();
|
||||
if (!arr)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<node> arr_storage = std::move(values[i]);
|
||||
const auto leaf_count = arr->total_leaf_count();
|
||||
if (leaf_count > 1_sz)
|
||||
preinsertion_resize(i + 1_sz, leaf_count - 1_sz);
|
||||
flatten_child(std::move(*arr), i); //increments i
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
friend inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const array&) TOML_MAY_THROW;
|
||||
};
|
||||
|
@ -279,12 +279,6 @@ namespace toml
|
||||
using namespace std::string_literals;
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
TOML_CONSTEVAL uint8_t operator"" _u8(unsigned long long n) noexcept
|
||||
{
|
||||
return static_cast<uint8_t>(n);
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
|
||||
{
|
||||
@ -301,15 +295,15 @@ namespace toml
|
||||
#else
|
||||
|
||||
/// \brief The base character type for keys and string values.
|
||||
/// \attention This will be `char8_t` if `TOML_CHAR_8_STRINGS` is `1`.
|
||||
/// \remarks This will be an alias for char8_t if `TOML_CHAR_8_STRINGS` is `1`.
|
||||
using string_char = char;
|
||||
|
||||
/// \brief The string type for keys and string values.
|
||||
/// \attention This will be `std::u8string` if `TOML_CHAR_8_STRINGS` is `1`.
|
||||
/// \remarks This will be an alias for std::u8string if `TOML_CHAR_8_STRINGS` is `1`.
|
||||
using string = std::string;
|
||||
|
||||
/// \brief The string type for keys and string values.
|
||||
/// \attention This will be `std::u8string_view` if `TOML_CHAR_8_STRINGS` is `1`.
|
||||
/// \remarks This will be an alias for std::u8string_view if `TOML_CHAR_8_STRINGS` is `1`.
|
||||
using string_view = std::string_view;
|
||||
|
||||
#endif
|
||||
@ -346,12 +340,32 @@ namespace toml
|
||||
#else
|
||||
|
||||
/// \brief The integer type used to tally line numbers and columns.
|
||||
/// \attention This will be `uint32_t` if `TOML_LARGE_FILES` is `1`.
|
||||
/// \remarks This will be an alias for uint32_t if `TOML_LARGE_FILES` is `1`.
|
||||
using source_index = uint16_t;
|
||||
|
||||
#endif
|
||||
|
||||
/// \brief A source document line-and-column pair.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto table = toml::parse_file("config.toml"sv);
|
||||
/// std::cout << "The node 'description' was defined at "sv
|
||||
/// << table.get("description")->source().begin()
|
||||
/// << std::endl;
|
||||
///
|
||||
/// // possible output:
|
||||
/// // The value 'description' was defined at line 7, column 15
|
||||
/// \ecpp
|
||||
///
|
||||
/// \remarks toml++'s parser is unicode-aware insofar as it knows how to handle
|
||||
/// various non-conventional whitespace and newline characters, but it doesn't give
|
||||
/// much thought to combining marks, grapheme clusters vs. characters, et cetera.
|
||||
/// If a TOML document contains lots of codepoints outside of the ASCII range
|
||||
/// you may find that your source_positions don't match those given by a text editor
|
||||
/// (typically the line numbers will be accurate but column numbers will be too high).
|
||||
/// <br><br>
|
||||
/// This Is Not An Error (tm). I've chosen this behaviour as a deliberate trade-off
|
||||
/// between parser complexity and correctness.
|
||||
struct source_position
|
||||
{
|
||||
/// \brief The line number.
|
||||
@ -369,6 +383,7 @@ namespace toml
|
||||
return line > source_index{} && column > source_index{};
|
||||
}
|
||||
|
||||
/// \brief Returns true if two source_positions represent the same line and column.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator == (const source_position& lhs, const source_position& rhs) noexcept
|
||||
{
|
||||
@ -376,6 +391,7 @@ namespace toml
|
||||
&& lhs.column == rhs.column;
|
||||
}
|
||||
|
||||
/// \brief Returns true if two source_positions do not represent the same line and column.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator != (const source_position& lhs, const source_position& rhs) noexcept
|
||||
{
|
||||
@ -383,6 +399,7 @@ namespace toml
|
||||
|| lhs.column != rhs.column;
|
||||
}
|
||||
|
||||
/// \brief Returns true if the LHS position is before the RHS position.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator < (const source_position& lhs, const source_position& rhs) noexcept
|
||||
{
|
||||
@ -390,6 +407,7 @@ namespace toml
|
||||
|| (lhs.line == rhs.line && lhs.column < rhs.column);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the LHS position is before the RHS position or equal to it.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator <= (const source_position& lhs, const source_position& rhs) noexcept
|
||||
{
|
||||
@ -397,18 +415,37 @@ namespace toml
|
||||
|| (lhs.line == rhs.line && lhs.column <= rhs.column);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Prints a source_position to a stream.
|
||||
template <typename CHAR>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const source_position& rhs)
|
||||
TOML_MAY_THROW
|
||||
{
|
||||
return lhs << "line " << rhs.line << ", column " << rhs.column;
|
||||
}
|
||||
TOML_MAY_THROW;
|
||||
};
|
||||
|
||||
/// \brief A pointer to a shared string resource containing a source path.
|
||||
using source_path_ptr = std::shared_ptr<const std::string>;
|
||||
|
||||
/// \brief A source document region.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto table = toml::parse_file("config.toml"sv);
|
||||
/// std::cout << "The node 'server' was defined at "sv
|
||||
/// << table.get("server")->source()
|
||||
/// << std::endl;
|
||||
///
|
||||
/// // possible output:
|
||||
/// // The node 'server' was defined at line 3, column 1 - line 10, column 25 of 'config.toml'
|
||||
/// \ecpp
|
||||
///
|
||||
/// \remarks toml++'s parser is unicode-aware insofar as it knows how to handle
|
||||
/// various non-conventional whitespace and newline characters, but it doesn't give
|
||||
/// much thought to combining marks, grapheme clusters vs. characters, et cetera.
|
||||
/// If a TOML document contains lots of codepoints outside of the ASCII range
|
||||
/// you may find that your source_positions don't match those given by a text editor
|
||||
/// (typically the line numbers will be accurate but column numbers will be too high).
|
||||
/// <br><br>
|
||||
/// This Is Not An Error (tm). I've chosen this behaviour as a deliberate trade-off
|
||||
/// between parser complexity and correctness.
|
||||
struct source_region
|
||||
{
|
||||
/// \brief The beginning of the region (inclusive).
|
||||
@ -421,6 +458,11 @@ namespace toml
|
||||
///
|
||||
/// \remarks This will be `nullptr` if no path was provided to toml::parse().
|
||||
source_path_ptr path;
|
||||
|
||||
/// \brief Prints a source_region to a stream.
|
||||
template <typename CHAR>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const source_region& rhs)
|
||||
TOML_MAY_THROW;
|
||||
};
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
@ -522,7 +564,7 @@ namespace toml::impl
|
||||
template <typename T>
|
||||
using string_map = std::map<string, T, std::less<>>; //heterogeneous lookup
|
||||
|
||||
#if defined(__cpp_lib_remove_cvref) || (defined(_MSC_VER) && defined(_HAS_CXX20))
|
||||
#if defined(__cpp_lib_remove_cvref) || (defined(_MSC_VER) && defined(_HAS_CXX20) && _HAS_CXX20)
|
||||
|
||||
template <typename T>
|
||||
using remove_cvref_t = std::remove_cvref_t<T>;
|
||||
@ -550,7 +592,7 @@ namespace toml::impl
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr std::underlying_type_t<T> unwrap_enum(T val) noexcept
|
||||
constexpr std::underlying_type_t<T> unbox_enum(T val) noexcept
|
||||
{
|
||||
return static_cast<std::underlying_type_t<T>>(val);
|
||||
}
|
||||
@ -584,6 +626,7 @@ namespace toml::impl
|
||||
template <typename T>
|
||||
inline constexpr bool is_value_or_promotable =
|
||||
is_value<T>
|
||||
|| std::is_same_v<std::decay_t<T>, string_char*>
|
||||
|| std::is_same_v<T, string_view>
|
||||
|| std::is_same_v<T, int32_t>
|
||||
|| std::is_same_v<T, int16_t>
|
||||
@ -595,7 +638,10 @@ namespace toml::impl
|
||||
#ifdef TOML_SMALL_FLOAT_TYPE
|
||||
|| std::is_same_v<T, TOML_SMALL_FLOAT_TYPE>
|
||||
#endif
|
||||
;
|
||||
#ifdef TOML_SMALL_INT_TYPE
|
||||
|| std::is_same_v<T, TOML_SMALL_INT_TYPE>
|
||||
#endif
|
||||
;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_value_or_node =
|
||||
@ -615,7 +661,17 @@ namespace toml::impl
|
||||
template <typename T> struct node_unwrapper { using type = T; };
|
||||
template <typename T> struct node_unwrapper<value<T>> { using type = T; };
|
||||
|
||||
template <typename T> using unwrapped = typename impl::node_unwrapper<T>::type;
|
||||
|
||||
template <typename T> struct value_promoter { using type = T; };
|
||||
template <size_t N> struct value_promoter<const string_char[N]> { using type = string; };
|
||||
template <size_t N> struct value_promoter<const string_char(&)[N]> { using type = string; };
|
||||
template <size_t N> struct value_promoter<const string_char(&&)[N]> { using type = string; };
|
||||
template <> struct value_promoter<const string_char*> { using type = string; };
|
||||
template <size_t N> struct value_promoter<string_char[N]> { using type = string; };
|
||||
template <size_t N> struct value_promoter<string_char(&)[N]> { using type = string; };
|
||||
template <size_t N> struct value_promoter<string_char(&&)[N]> { using type = string; };
|
||||
template <> struct value_promoter<string_char*> { using type = string; };
|
||||
template <> struct value_promoter<string_view> { using type = string; };
|
||||
template <> struct value_promoter<int32_t> { using type = int64_t; };
|
||||
template <> struct value_promoter<int16_t> { using type = int64_t; };
|
||||
@ -627,6 +683,9 @@ namespace toml::impl
|
||||
#ifdef TOML_SMALL_FLOAT_TYPE
|
||||
template <> struct value_promoter<TOML_SMALL_FLOAT_TYPE> { using type = double; };
|
||||
#endif
|
||||
#ifdef TOML_SMALL_INT_TYPE
|
||||
template <> struct value_promoter<TOML_SMALL_INT_TYPE> { using type = int64_t; };
|
||||
#endif
|
||||
template <typename T> using promoted = typename impl::value_promoter<T>::type;
|
||||
|
||||
template <typename T> struct node_type_of_;
|
||||
@ -721,10 +780,6 @@ namespace toml
|
||||
template <typename T>
|
||||
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>
|
||||
using value_of = typename impl::node_unwrapper<T>::type;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a toml::table.
|
||||
template <typename T>
|
||||
inline constexpr bool is_table = std::is_same_v<impl::remove_cvref_t<T>, table>;
|
||||
|
@ -13,6 +13,13 @@ namespace toml
|
||||
/// \brief The day component, from 1 - 31.
|
||||
uint8_t day;
|
||||
|
||||
|
||||
/// \brief Equality operator.
|
||||
///
|
||||
/// \param lhs The LHS date.
|
||||
/// \param rhs The RHS date.
|
||||
///
|
||||
/// \returns True if the dates represented the same value.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator == (date lhs, date rhs) noexcept
|
||||
{
|
||||
@ -21,6 +28,12 @@ namespace toml
|
||||
&& lhs.day == rhs.day;
|
||||
}
|
||||
|
||||
/// \brief Inequality operator.
|
||||
///
|
||||
/// \param lhs The LHS date.
|
||||
/// \param rhs The RHS date.
|
||||
///
|
||||
/// \returns True if the dates did not represent the same value.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator != (date lhs, date rhs) noexcept
|
||||
{
|
||||
@ -29,6 +42,8 @@ namespace toml
|
||||
|| lhs.day != rhs.day;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Prints a date out to a stream as `YYYY-MM-DD` (per RFC 3339).
|
||||
template <typename CHAR>
|
||||
friend inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const date& rhs)
|
||||
TOML_MAY_THROW
|
||||
@ -50,6 +65,12 @@ namespace toml
|
||||
/// \brief The fractional nanoseconds component, from 0 - 999999999.
|
||||
uint32_t nanosecond;
|
||||
|
||||
/// \brief Equality operator.
|
||||
///
|
||||
/// \param lhs The LHS time.
|
||||
/// \param rhs The RHS time.
|
||||
///
|
||||
/// \returns True if the times represented the same value.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator == (const time& lhs, const time& rhs) noexcept
|
||||
{
|
||||
@ -59,12 +80,19 @@ namespace toml
|
||||
&& lhs.nanosecond == rhs.nanosecond;
|
||||
}
|
||||
|
||||
/// \brief Inequality operator.
|
||||
///
|
||||
/// \param lhs The LHS time.
|
||||
/// \param rhs The RHS time.
|
||||
///
|
||||
/// \returns True if the times did not represent the same value.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator != (const time& lhs, const time& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
/// \brief Prints a time out to a stream as `HH:MM:SS.FFFFFF` (per RFC 3339).
|
||||
template <typename CHAR>
|
||||
friend inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const time& rhs)
|
||||
TOML_MAY_THROW
|
||||
@ -80,24 +108,56 @@ namespace toml
|
||||
/// \brief Offset from UTC+0, in minutes.
|
||||
int16_t minutes;
|
||||
|
||||
/// \brief Creates a timezone offset from separate hour and minute totals.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// std::cout << time_offset::from_hh_mm(2, 30) << std::endl;
|
||||
/// std::cout << time_offset::from_hh_mm(-2, 30) << std::endl;
|
||||
/// std::cout << time_offset::from_hh_mm(-2, -30) << std::endl;
|
||||
/// std::cout << time_offset::from_hh_mm(0,0) << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // +02:30
|
||||
/// // -01:30
|
||||
/// // -02:30
|
||||
/// // Z
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param hours The total hours.
|
||||
/// \param minutes The total minutes.
|
||||
///
|
||||
/// \returns A time_offset.
|
||||
[[nodiscard]]
|
||||
static constexpr time_offset from_hh_mm(int8_t hours, int8_t minutes) noexcept
|
||||
{
|
||||
return time_offset{ static_cast<int16_t>(hours * 60 + minutes) };
|
||||
}
|
||||
|
||||
/// \brief Equality operator.
|
||||
///
|
||||
/// \param lhs The LHS time_offset.
|
||||
/// \param rhs The RHS time_offset.
|
||||
///
|
||||
/// \returns True if the time_offsets represented the same value.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator == (time_offset lhs, time_offset rhs) noexcept
|
||||
{
|
||||
return lhs.minutes == rhs.minutes;
|
||||
}
|
||||
|
||||
/// \brief Inequality operator.
|
||||
///
|
||||
/// \param lhs The LHS time_offset.
|
||||
/// \param rhs The RHS time_offset.
|
||||
///
|
||||
/// \returns True if the time_offsets did not represent the same value.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator != (time_offset lhs, time_offset rhs) noexcept
|
||||
{
|
||||
return lhs.minutes != rhs.minutes;
|
||||
}
|
||||
|
||||
/// \brief Prints a time_offset out to a stream as `+-HH:MM or Z` (per RFC 3339).
|
||||
template <typename CHAR>
|
||||
friend inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const time_offset& rhs)
|
||||
TOML_MAY_THROW
|
||||
@ -115,14 +175,23 @@ namespace toml
|
||||
/// \brief The time component.
|
||||
toml::time time;
|
||||
/// \brief The timezone offset component.
|
||||
///
|
||||
/// \remarks The date_time is said to be 'local' if the time_offset is empty.
|
||||
std::optional<toml::time_offset> time_offset;
|
||||
|
||||
/// \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();
|
||||
}
|
||||
|
||||
/// \brief Equality operator.
|
||||
///
|
||||
/// \param lhs The LHS date_time.
|
||||
/// \param rhs The RHS date_time.
|
||||
///
|
||||
/// \returns True if the date_times represented the same value.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator == (const date_time& lhs, const date_time& rhs) noexcept
|
||||
{
|
||||
@ -131,6 +200,12 @@ namespace toml
|
||||
&& lhs.time_offset == rhs.time_offset;
|
||||
}
|
||||
|
||||
/// \brief Inequality operator.
|
||||
///
|
||||
/// \param lhs The LHS date_time.
|
||||
/// \param rhs The RHS date_time.
|
||||
///
|
||||
/// \returns True if the date_times did not represent the same value.
|
||||
[[nodiscard]]
|
||||
friend constexpr bool operator != (const date_time& lhs, const date_time& rhs) noexcept
|
||||
{
|
||||
@ -139,6 +214,7 @@ namespace toml
|
||||
|| lhs.time_offset != rhs.time_offset;
|
||||
}
|
||||
|
||||
/// \brief Prints a date_time out to a stream in RFC 3339 format.
|
||||
template <typename CHAR>
|
||||
friend inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const date_time& rhs)
|
||||
TOML_MAY_THROW
|
||||
|
@ -134,6 +134,33 @@ namespace toml::impl
|
||||
|
||||
namespace toml
|
||||
{
|
||||
/// \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
|
||||
/// operators of the TOML node types already print themselves out using this formatter.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "description", "This is some TOML, yo." },
|
||||
/// { "fruit", toml::array{ "apple", "orange", "pear" } },
|
||||
/// { "numbers", toml::array{ 1, 2, 3, 4, 5 } },
|
||||
/// { "table", toml::table{{ { "foo", "bar" } }} }
|
||||
/// }};
|
||||
///
|
||||
/// // these two lines are equivalent:
|
||||
/// std::cout << toml::default_formatter{ tbl } << std::endl;
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// // output (twice):
|
||||
/// // description = "This is some TOML, yo."
|
||||
/// // fruit = ["apple", "orange", "pear"]
|
||||
/// // numbers = [1, 2, 3, 4, 5]
|
||||
/// //
|
||||
/// // [table]
|
||||
/// // foo = "bar"
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam CHAR The underlying character type of the output stream. Must be 1 byte in size.
|
||||
template <typename CHAR = char>
|
||||
class default_formatter final : impl::formatter<CHAR>
|
||||
{
|
||||
@ -243,12 +270,20 @@ namespace toml
|
||||
|
||||
void print(const table& tbl) TOML_MAY_THROW
|
||||
{
|
||||
//values, arrays, and inline tables
|
||||
static constexpr auto is_non_inline_array_of_tables = [](auto&& nde) noexcept
|
||||
{
|
||||
auto arr = nde.as_array();
|
||||
return arr
|
||||
&& arr->is_array_of_tables()
|
||||
&& !arr->template get_as<table>(0_sz)->is_inline();
|
||||
};
|
||||
|
||||
//values, arrays, and inline tables/table arrays
|
||||
for (auto [k, v] : tbl)
|
||||
{
|
||||
const auto type = v.type();
|
||||
if ((type == node_type::table && !reinterpret_cast<const table*>(&v)->is_inline())
|
||||
|| (type == node_type::array && reinterpret_cast<const array*>(&v)->is_array_of_tables()))
|
||||
|| (type == node_type::array && is_non_inline_array_of_tables(v)))
|
||||
continue;
|
||||
|
||||
base::print_newline();
|
||||
@ -290,7 +325,7 @@ namespace toml
|
||||
break;
|
||||
|
||||
case node_type::array:
|
||||
if (reinterpret_cast<const array*>(&child_v)->is_array_of_tables())
|
||||
if (is_non_inline_array_of_tables(child_v))
|
||||
child_table_array_count++;
|
||||
else
|
||||
child_value_count++;
|
||||
@ -329,8 +364,7 @@ namespace toml
|
||||
//table arrays
|
||||
for (auto [k, v] : tbl)
|
||||
{
|
||||
const auto type = v.type();
|
||||
if (type != node_type::array || !reinterpret_cast<const array*>(&v)->is_array_of_tables())
|
||||
if (!is_non_inline_array_of_tables(v))
|
||||
continue;
|
||||
auto& arr = *reinterpret_cast<const array*>(&v);
|
||||
|
||||
@ -382,11 +416,16 @@ namespace toml
|
||||
|
||||
public:
|
||||
|
||||
/// \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
|
||||
: base{ source, flags }
|
||||
{}
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML.
|
||||
template <typename T>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<T>& lhs, default_formatter& rhs)
|
||||
TOML_MAY_THROW
|
||||
@ -398,6 +437,7 @@ namespace toml
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML (rvalue overload).
|
||||
template <typename T>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<T>& lhs, default_formatter&& rhs)
|
||||
TOML_MAY_THROW
|
||||
|
@ -11,11 +11,11 @@ namespace toml
|
||||
};
|
||||
[[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));
|
||||
return static_cast<format_flags>(impl::unbox_enum(lhs) & impl::unbox_enum(rhs));
|
||||
}
|
||||
[[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) );
|
||||
return static_cast<format_flags>( impl::unbox_enum(lhs) | impl::unbox_enum(rhs) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,36 @@
|
||||
|
||||
namespace toml
|
||||
{
|
||||
/// \brief A wrapper for printing TOML objects out to a stream as formatted JSON.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto some_toml = toml::parse(R"(
|
||||
/// [fruit]
|
||||
/// apple.color = "red"
|
||||
/// apple.taste.sweet = true
|
||||
///
|
||||
/// [fruit.apple.texture]
|
||||
/// smooth = true
|
||||
/// )"sv);
|
||||
/// std::cout << toml::json_formatter{ some_toml } << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // {
|
||||
/// // "fruit" : {
|
||||
/// // "apple" : {
|
||||
/// // "color" : "red",
|
||||
/// // "taste" : {
|
||||
/// // "sweet" : true
|
||||
/// // },
|
||||
/// // "texture" : {
|
||||
/// // "smooth" : true
|
||||
/// // }
|
||||
/// // }
|
||||
/// // }
|
||||
/// // }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam CHAR The underlying character type of the output stream. Must be 1 byte in size.
|
||||
template <typename CHAR = char>
|
||||
class json_formatter final : impl::formatter<CHAR>
|
||||
{
|
||||
@ -57,6 +87,10 @@ namespace toml
|
||||
|
||||
public:
|
||||
|
||||
/// \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,
|
||||
@ -64,6 +98,8 @@ namespace toml
|
||||
: base{ source, flags }
|
||||
{}
|
||||
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON.
|
||||
template <typename T>
|
||||
friend std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter& rhs)
|
||||
TOML_MAY_THROW
|
||||
@ -74,6 +110,7 @@ namespace toml
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON (rvalue overload).
|
||||
template <typename T>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<T>& lhs, json_formatter&& rhs)
|
||||
TOML_MAY_THROW
|
||||
|
@ -17,11 +17,16 @@ namespace toml
|
||||
|
||||
node(node&& other) noexcept
|
||||
: source_{ std::move(other.source_) }
|
||||
{}
|
||||
{
|
||||
other.source_.begin = {};
|
||||
other.source_.end = {};
|
||||
}
|
||||
|
||||
node& operator= (node&& rhs) noexcept
|
||||
{
|
||||
source_ = std::move(rhs.source_);
|
||||
rhs.source_.begin = {};
|
||||
rhs.source_.end = {};
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -84,7 +89,7 @@ namespace toml
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
bool is() const noexcept
|
||||
{
|
||||
using type = value_of<impl::remove_cvref_t<T>>;
|
||||
using type = impl::unwrapped<impl::remove_cvref_t<T>>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Template type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
@ -155,7 +160,7 @@ namespace toml
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
node_of<T>* as() noexcept
|
||||
{
|
||||
using type = value_of<T>;
|
||||
using type = impl::unwrapped<T>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Template type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
@ -177,7 +182,7 @@ namespace toml
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
const node_of<T>* as() const noexcept
|
||||
{
|
||||
using type = value_of<T>;
|
||||
using type = impl::unwrapped<T>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Template type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
|
@ -156,7 +156,7 @@ namespace toml
|
||||
[[nodiscard]] auto as() noexcept
|
||||
{
|
||||
static_assert(
|
||||
impl::is_value_or_node<U>,
|
||||
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"
|
||||
);
|
||||
|
||||
@ -167,7 +167,7 @@ namespace toml
|
||||
[[nodiscard]] const node_of<U>* as() const noexcept
|
||||
{
|
||||
static_assert(
|
||||
impl::is_value_or_node<U>,
|
||||
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"
|
||||
);
|
||||
|
||||
@ -207,10 +207,9 @@ namespace toml
|
||||
[[nodiscard]] static bool container_equality(const node_view& lhs, const U& rhs) noexcept
|
||||
{
|
||||
using elem_t = std::remove_const_t<typename U::value_type>;
|
||||
|
||||
static_assert(
|
||||
impl::is_value_or_promotable<elem_t>,
|
||||
"Container element type must be (or be promotable to) one of the basic value types"
|
||||
"Container element type must be (or be promotable to) one of the TOML value types"
|
||||
);
|
||||
|
||||
const array* arr = lhs.as<array>();
|
||||
|
@ -10,8 +10,25 @@ namespace toml
|
||||
|
||||
/// \brief The result of a parsing operation.
|
||||
///
|
||||
/// \remarks This type only exists when exceptions are disabled,
|
||||
/// otherwise `parse_result` is a simple alias for `toml::table`.
|
||||
/// \attention This type only exists when exceptions are disabled.
|
||||
/// When exceptions are enabled parse_result is just an alias for toml::table
|
||||
/// and parsing failures are indicated by raising a toml::parse_error as an exception.
|
||||
///
|
||||
/// \detail A parse_result is effectively a discriminated union containing either a toml::table
|
||||
/// or a toml::parse_error. Most member functions assume a particular one of these two states,
|
||||
/// and calling them when in the wrong state will cause errors (e.g. attempting to access the
|
||||
/// error object when parsing was successful). \cpp
|
||||
/// parse_result result = toml::parse_file("config.toml");
|
||||
/// if (result)
|
||||
/// do_stuff_with_a_table(result); //implicitly converts to table&
|
||||
/// else
|
||||
/// std::cerr
|
||||
/// << "Error parsing file '"sv << *result.error().source().path
|
||||
/// << "':\n"sv << result.error().description()
|
||||
/// << "\n ("sv << result.error().source().begin << ")"sv
|
||||
/// << std::endl;
|
||||
///
|
||||
/// \ecpp
|
||||
class parse_result final
|
||||
{
|
||||
private:
|
||||
@ -31,55 +48,65 @@ namespace toml
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/// \brief Returns true if parsing succeeeded.
|
||||
[[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.
|
||||
[[nodiscard]] explicit operator bool() const noexcept { return !is_err; }
|
||||
|
||||
|
||||
/// \brief Returns the internal toml::table.
|
||||
[[nodiscard]] table& get() & noexcept
|
||||
{
|
||||
TOML_ASSERT(!is_err);
|
||||
return *std::launder(reinterpret_cast<table*>(&storage));
|
||||
}
|
||||
/// \brief Returns the internal toml::table (rvalue overload).
|
||||
[[nodiscard]] table&& get() && noexcept
|
||||
{
|
||||
TOML_ASSERT(!is_err);
|
||||
return std::move(*std::launder(reinterpret_cast<table*>(&storage)));
|
||||
}
|
||||
/// \brief Returns the internal toml::table (const lvalue overload).
|
||||
[[nodiscard]] const table& get() const& noexcept
|
||||
{
|
||||
TOML_ASSERT(!is_err);
|
||||
return *std::launder(reinterpret_cast<const table*>(&storage));
|
||||
}
|
||||
|
||||
/// \brief Returns the internal toml::parse_error.
|
||||
[[nodiscard]] parse_error& error() & noexcept
|
||||
{
|
||||
TOML_ASSERT(is_err);
|
||||
return *std::launder(reinterpret_cast<parse_error*>(&storage));
|
||||
}
|
||||
/// \brief Returns the internal toml::parse_error (rvalue overload).
|
||||
[[nodiscard]] parse_error&& error() && noexcept
|
||||
{
|
||||
TOML_ASSERT(is_err);
|
||||
return std::move(*std::launder(reinterpret_cast<parse_error*>(&storage)));
|
||||
}
|
||||
/// \brief Returns the internal toml::parse_error (const lvalue overload).
|
||||
[[nodiscard]] const parse_error& error() const& noexcept
|
||||
{
|
||||
TOML_ASSERT(is_err);
|
||||
return *std::launder(reinterpret_cast<const parse_error*>(&storage));
|
||||
}
|
||||
|
||||
[[nodiscard]] table& operator* () & noexcept { return get(); }
|
||||
[[nodiscard]] table&& operator* () && noexcept { return std::move(get()); }
|
||||
[[nodiscard]] const table& operator* () const& noexcept { return get(); }
|
||||
|
||||
[[nodiscard]] table* operator-> () noexcept { return &get(); }
|
||||
[[nodiscard]] const table* operator-> () const noexcept { return &get(); }
|
||||
|
||||
/// \brief Returns the internal toml::table.
|
||||
[[nodiscard]] operator table& () noexcept { return get(); }
|
||||
/// \brief Returns the internal toml::table (rvalue overload).
|
||||
[[nodiscard]] operator table&& () noexcept { return std::move(get()); }
|
||||
/// \brief Returns the internal toml::table (const lvalue overload).
|
||||
[[nodiscard]] operator const table& () const noexcept { return get(); }
|
||||
|
||||
/// \brief Returns the internal toml::parse_error.
|
||||
[[nodiscard]] explicit operator parse_error& () noexcept { return error(); }
|
||||
/// \brief Returns the internal toml::parse_error (rvalue overload).
|
||||
[[nodiscard]] explicit operator parse_error && () noexcept { return std::move(error()); }
|
||||
/// \brief Returns the internal toml::parse_error (const lvalue overload).
|
||||
[[nodiscard]] explicit operator const parse_error& () const noexcept { return error(); }
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
@ -209,11 +236,11 @@ namespace toml::impl
|
||||
#endif
|
||||
|
||||
[[nodiscard]]
|
||||
source_position current_position_or_assumed_next() const noexcept
|
||||
source_position current_position(source_index fallback_offset = 0) const noexcept
|
||||
{
|
||||
if (cp)
|
||||
return cp->position;
|
||||
return { prev_pos.line, static_cast<source_index>(prev_pos.column + 1u) };
|
||||
return { prev_pos.line, static_cast<source_index>(prev_pos.column + fallback_offset) };
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
@ -223,7 +250,7 @@ namespace toml::impl
|
||||
TOML_ERROR_CHECK();
|
||||
|
||||
if constexpr (sizeof...(T) == 0_sz)
|
||||
TOML_ERROR( "An unspecified error occurred", current_position_or_assumed_next(), reader.source_path() );
|
||||
TOML_ERROR( "An unspecified error occurred", current_position(1), reader.source_path() );
|
||||
else
|
||||
{
|
||||
static constexpr auto buf_size = 512_sz;
|
||||
@ -294,9 +321,9 @@ namespace toml::impl
|
||||
(concatenator(std::forward<T>(args)), ...);
|
||||
*ptr = '\0';
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ERROR( buf, current_position_or_assumed_next(), reader.source_path() );
|
||||
TOML_ERROR( buf, current_position(1), reader.source_path() );
|
||||
#else
|
||||
TOML_ERROR( std::string(buf, ptr - buf), current_position_or_assumed_next(), reader.source_path());
|
||||
TOML_ERROR( std::string(buf, ptr - buf), current_position(1), reader.source_path());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1123,8 +1150,8 @@ namespace toml::impl
|
||||
}
|
||||
#else
|
||||
{
|
||||
auto parse_result = std::from_chars(chars, chars + length, result);
|
||||
switch (parse_result.ec)
|
||||
auto fc_result = std::from_chars(chars, chars + length, result);
|
||||
switch (fc_result.ec)
|
||||
{
|
||||
case std::errc{}: //ok
|
||||
return result * sign;
|
||||
@ -1298,8 +1325,8 @@ namespace toml::impl
|
||||
|
||||
// convert to double
|
||||
TOML_GCC_ATTR(uninitialized) double result;
|
||||
auto parse_result = std::from_chars(chars, chars + length, result, std::chars_format::hex);
|
||||
switch (parse_result.ec)
|
||||
auto fc_result = std::from_chars(chars, chars + length, result, std::chars_format::hex);
|
||||
switch (fc_result.ec)
|
||||
{
|
||||
case std::errc{}: //ok
|
||||
return result;
|
||||
@ -1469,23 +1496,23 @@ namespace toml::impl
|
||||
|
||||
// otherwise invoke charconv
|
||||
TOML_GCC_ATTR(uninitialized) uint64_t result;
|
||||
auto parse_result = std::from_chars(chars, chars + length, result, base);
|
||||
auto fc_result = std::from_chars(chars, chars + length, result, base);
|
||||
if constexpr (traits::is_signed)
|
||||
{
|
||||
if (parse_result.ec == std::errc{} && (
|
||||
if (fc_result.ec == std::errc{} && (
|
||||
(sign < 0 && result > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1ull)
|
||||
|| (sign > 0 && result > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))
|
||||
))
|
||||
parse_result.ec = std::errc::result_out_of_range;
|
||||
fc_result.ec = std::errc::result_out_of_range;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parse_result.ec == std::errc{} &&
|
||||
if (fc_result.ec == std::errc{} &&
|
||||
result > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())
|
||||
)
|
||||
parse_result.ec = std::errc::result_out_of_range;
|
||||
fc_result.ec = std::errc::result_out_of_range;
|
||||
}
|
||||
switch (parse_result.ec)
|
||||
switch (fc_result.ec)
|
||||
{
|
||||
case std::errc{}: //ok
|
||||
if constexpr (traits::is_signed)
|
||||
@ -2286,7 +2313,7 @@ namespace toml::impl
|
||||
TOML_ERROR_CHECK({});
|
||||
}
|
||||
|
||||
val->source_ = { begin_pos, current_position_or_assumed_next(), reader.source_path() };
|
||||
val->source_ = { begin_pos, current_position(1), reader.source_path() };
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -2484,7 +2511,7 @@ namespace toml::impl
|
||||
);
|
||||
advance();
|
||||
}
|
||||
header_end_pos = current_position_or_assumed_next();
|
||||
header_end_pos = current_position(1);
|
||||
|
||||
// handle the rest of the line after the header
|
||||
consume_leading_whitespace();
|
||||
@ -2726,8 +2753,7 @@ namespace toml::impl
|
||||
}
|
||||
while (cp);
|
||||
|
||||
auto eof_pos = current_position_or_assumed_next();
|
||||
eof_pos.column++;
|
||||
auto eof_pos = current_position(1);
|
||||
root.source_.end = eof_pos;
|
||||
if (current_table
|
||||
&& current_table != &root
|
||||
@ -2873,7 +2899,6 @@ namespace toml::impl
|
||||
else if (*cp == U']')
|
||||
{
|
||||
advance();
|
||||
arr->source_.end = current_position_or_assumed_next();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2976,7 +3001,6 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
advance();
|
||||
tab->source_.end = current_position_or_assumed_next();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3023,12 +3047,29 @@ namespace toml::impl
|
||||
|
||||
namespace toml
|
||||
{
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::string_view doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
{
|
||||
return impl::parser{ impl::utf8_reader{ doc, source_path } };
|
||||
}
|
||||
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \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`.
|
||||
///
|
||||
/// \returns A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::string_view doc, std::string&& source_path) TOML_MAY_THROW
|
||||
{
|
||||
@ -3037,12 +3078,28 @@ namespace toml
|
||||
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::u8string_view doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
{
|
||||
return impl::parser{ impl::utf8_reader{ doc, source_path } };
|
||||
}
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \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`.
|
||||
///
|
||||
/// \returns A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::u8string_view doc, std::string&& source_path) TOML_MAY_THROW
|
||||
{
|
||||
@ -3051,6 +3108,16 @@ namespace toml
|
||||
|
||||
#endif
|
||||
|
||||
/// \brief Parses a TOML document from a stream.
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
template <typename CHAR>
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::basic_istream<CHAR>& doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
@ -3063,6 +3130,14 @@ namespace toml
|
||||
return impl::parser{ impl::utf8_reader{ doc, source_path } };
|
||||
}
|
||||
|
||||
/// \brief Parses a TOML document from a stream.
|
||||
///
|
||||
/// \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`.
|
||||
///
|
||||
/// \returns A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
template <typename CHAR>
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::basic_istream<CHAR>& doc, std::string&& source_path) TOML_MAY_THROW
|
||||
@ -3074,4 +3149,33 @@ namespace toml
|
||||
|
||||
return impl::parser{ impl::utf8_reader{ doc, std::move(source_path) } };
|
||||
}
|
||||
|
||||
/// \brief Parses a TOML document from a file.
|
||||
///
|
||||
/// \tparam CHAR The path's character type. Must be 1 byte in size.
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
///
|
||||
/// \remarks You must `#include <fstream>` to use this function (toml++
|
||||
/// does not transitively include it for you).
|
||||
template <typename CHAR>
|
||||
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."
|
||||
);
|
||||
|
||||
// Q: "why is this function templated??"
|
||||
// A: I don't want to force users to drag in <fstream> if they're not going to do
|
||||
// any parsing directly from files.
|
||||
|
||||
auto ifs = std::basic_ifstream<CHAR>{ file_path };
|
||||
return parse(
|
||||
ifs,
|
||||
std::string_view{ reinterpret_cast<const char*>(file_path.data()), file_path.length() }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,16 +5,23 @@ namespace toml::impl
|
||||
{
|
||||
// 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.
|
||||
// - <charconv> is locale-independent.
|
||||
// - I'm using <charconv> to format numerics. Faster and locale-independent.
|
||||
// - I can avoid forcing users to drag in <sstream> and <iomanip>.
|
||||
|
||||
// Q: "there's a lot of reinterpret_casting here, is any of it UB?"
|
||||
// A: - If the source string data is char and the output string is char8_t, then technically yes,
|
||||
// but not in the other direction. I test in both modes on Clang, GCC and MSVC and have yet to
|
||||
// see it actually causing an issue, but in the event it does present a problem it's not going to
|
||||
// be a show-stopper since all it means is I need to do duplicate some code.
|
||||
// - 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) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(sizeof(CHAR1) == 1);
|
||||
static_assert(sizeof(CHAR2) == 1);
|
||||
stream.write(str.data(), str.length());
|
||||
stream.write(reinterpret_cast<const CHAR2*>(str.data()), str.length());
|
||||
}
|
||||
|
||||
template <typename CHAR1, typename CHAR2>
|
||||
@ -23,7 +30,7 @@ namespace toml::impl
|
||||
{
|
||||
static_assert(sizeof(CHAR1) == 1);
|
||||
static_assert(sizeof(CHAR2) == 1);
|
||||
stream.write(str.data(), str.length());
|
||||
stream.write(reinterpret_cast<const CHAR2*>(str.data()), str.length());
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
@ -65,14 +72,14 @@ namespace toml::impl
|
||||
template <typename T> inline constexpr size_t charconv_buffer_length = 0;
|
||||
template <> inline constexpr size_t charconv_buffer_length<double> = 60;
|
||||
template <> inline constexpr size_t charconv_buffer_length<float> = 40;
|
||||
template <> inline constexpr size_t charconv_buffer_length<uint64_t> = 20; //strlen("18446744073709551615")
|
||||
template <> inline constexpr size_t charconv_buffer_length<int64_t> = 20; //strlen("-9223372036854775808")
|
||||
template <> inline constexpr size_t charconv_buffer_length<int32_t> = 11; //strlen("-2147483648")
|
||||
template <> inline constexpr size_t charconv_buffer_length<int16_t> = 6; //strlen("-32768")
|
||||
template <> inline constexpr size_t charconv_buffer_length<int8_t> = 4; //strlen("-128")
|
||||
template <> inline constexpr size_t charconv_buffer_length<uint32_t> = 10; //strlen("4294967295")
|
||||
template <> inline constexpr size_t charconv_buffer_length<uint16_t> = 5; //strlen("65535")
|
||||
template <> inline constexpr size_t charconv_buffer_length<uint8_t> = 3; //strlen("255")
|
||||
template <> inline constexpr size_t charconv_buffer_length<uint64_t> = 20; // strlen("18446744073709551615")
|
||||
template <> inline constexpr size_t charconv_buffer_length<int64_t> = 20; // strlen("-9223372036854775808")
|
||||
template <> inline constexpr size_t charconv_buffer_length<int32_t> = 11; // strlen("-2147483648")
|
||||
template <> inline constexpr size_t charconv_buffer_length<int16_t> = 6; // strlen("-32768")
|
||||
template <> inline constexpr size_t charconv_buffer_length<int8_t> = 4; // strlen("-128")
|
||||
template <> inline constexpr size_t charconv_buffer_length<uint32_t> = 10; // strlen("4294967295")
|
||||
template <> inline constexpr size_t charconv_buffer_length<uint16_t> = 5; // strlen("65535")
|
||||
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) TOML_MAY_THROW
|
||||
@ -245,7 +252,6 @@ namespace toml::impl
|
||||
inline void print_to_stream(const toml::date_time& val, std::basic_ostream<CHAR>& stream) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(sizeof(CHAR) == 1);
|
||||
|
||||
print_to_stream(val.date, stream);
|
||||
print_to_stream('T', stream);
|
||||
print_to_stream(val.time, stream);
|
||||
@ -268,6 +274,8 @@ namespace toml::impl
|
||||
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 if (c == TOML_STRING_PREFIX('\\')) TOML_UNLIKELY
|
||||
print_to_stream(TOML_STRING_PREFIX("\\\\"sv), stream);
|
||||
else
|
||||
print_to_stream(c, stream);
|
||||
}
|
||||
@ -275,3 +283,45 @@ namespace toml::impl
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
}
|
||||
|
||||
namespace toml
|
||||
{
|
||||
template <typename CHAR>
|
||||
std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const source_position& rhs)
|
||||
TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
impl::print_to_stream("line "sv, lhs);
|
||||
impl::print_to_stream(rhs.line, lhs);
|
||||
impl::print_to_stream(", column ", lhs);
|
||||
impl::print_to_stream(rhs.column, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename CHAR>
|
||||
std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const source_region& rhs)
|
||||
TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
sizeof(CHAR) == 1,
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
lhs << rhs.begin;
|
||||
if (rhs.begin < rhs.end
|
||||
&& (rhs.end.line != rhs.begin.line || rhs.end.column > rhs.begin.column + source_index{1}))
|
||||
{
|
||||
impl::print_to_stream(" - "sv, lhs);
|
||||
lhs << rhs.end;
|
||||
}
|
||||
if (rhs.path)
|
||||
{
|
||||
impl::print_to_stream(" of '"sv, lhs);
|
||||
impl::print_to_stream(*rhs.path, lhs);
|
||||
impl::print_to_stream('\'', lhs);
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
namespace toml::impl
|
||||
{
|
||||
template <bool is_const>
|
||||
struct table_iterator_ref_proxy final
|
||||
struct table_proxy_pair final
|
||||
{
|
||||
using value_type = std::conditional_t<is_const, const node, node>;
|
||||
|
||||
@ -38,7 +38,8 @@ namespace toml::impl
|
||||
|
||||
table_iterator() noexcept = default;
|
||||
|
||||
using reference = table_iterator_ref_proxy<is_const>;
|
||||
using reference = table_proxy_pair<is_const>;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
table_iterator& operator++() noexcept // ++pre
|
||||
{
|
||||
@ -83,10 +84,46 @@ namespace toml::impl
|
||||
return lhs.raw_ != rhs.raw_;
|
||||
}
|
||||
};
|
||||
|
||||
struct table_init_pair final
|
||||
{
|
||||
string key;
|
||||
std::unique_ptr<node> value;
|
||||
|
||||
template <typename T>
|
||||
table_init_pair(string&& k, T && v) noexcept
|
||||
: key{ std::move(k) },
|
||||
value{ make_node(std::forward<T>(v)) }
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
table_init_pair(string_view k, T&& v) noexcept
|
||||
: key{ k },
|
||||
value{ make_node(std::forward<T>(v)) }
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
table_init_pair(const string_char* k, T&& v) noexcept
|
||||
: key{ k },
|
||||
value{ make_node(std::forward<T>(v)) }
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
namespace toml
|
||||
{
|
||||
/// \brief A TOML table.
|
||||
///
|
||||
/// \remarks The interface of this type is modeled after std::map, with some
|
||||
/// additional considerations made for the heterogeneous nature of a
|
||||
/// TOML table, and for the removal of some cruft (the public interface of
|
||||
/// std::map is, simply, _a hot mess_).
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// // example
|
||||
/// // code
|
||||
/// // here
|
||||
/// \ecpp
|
||||
class table final
|
||||
: public node
|
||||
{
|
||||
@ -99,12 +136,56 @@ namespace toml
|
||||
|
||||
public:
|
||||
|
||||
/// \brief A BidirectionalIterator for iterating over the key-value pairs in a table.
|
||||
using iterator = impl::table_iterator<false>;
|
||||
/// \brief A const BidirectionalIterator for iterating over the key-value pairs in a table.
|
||||
using const_iterator = impl::table_iterator<true>;
|
||||
|
||||
/// \brief Default constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
table() noexcept {}
|
||||
|
||||
/// \brief Constructs a table with one or more initial key-value pairs.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{ //double braces required :( - see Remarks
|
||||
/// { "foo", 1 },
|
||||
/// { "bar", 2.0 },
|
||||
/// { "kek", "three" }
|
||||
/// }};
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // { foo = 1, bar = 2.0, kek = "three" }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam N Number of key-value pairs used to initialize the table.
|
||||
/// \param arr An array of key-value pairs used to initialize the table.
|
||||
///
|
||||
/// \remarks C++ std::initializer_lists represent their member elements as
|
||||
/// const even if the list's value type is non-const. This is great for
|
||||
/// compiler writers, I guess, but pretty annoying for me since
|
||||
/// TOML key-value pairs are polymorphic. This means that for the
|
||||
/// human-friendly braced init list syntax to work I can't use
|
||||
/// std::initializer_list and must instead invent an annoying proxy type,
|
||||
/// which means an extra level of nesting.
|
||||
/// <br><br>
|
||||
/// See https://en.cppreference.com/w/cpp/utility/initializer_list
|
||||
/// if you'd like to be more annoyed about this.
|
||||
template <size_t N>
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit table(impl::table_init_pair(&& arr)[N]) noexcept
|
||||
{
|
||||
for (auto&& kvp : arr)
|
||||
{
|
||||
values.insert_or_assign(
|
||||
std::move(kvp.key),
|
||||
std::move(kvp.value)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Move constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
table(table&& other) noexcept
|
||||
: node{ std::move(other) },
|
||||
@ -112,6 +193,7 @@ namespace toml
|
||||
inline_ { other.inline_ }
|
||||
{}
|
||||
|
||||
/// \brief Move-assignment operator.
|
||||
table& operator= (table&& rhs) noexcept
|
||||
{
|
||||
node::operator=(std::move(rhs));
|
||||
@ -120,41 +202,268 @@ namespace toml
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Always returns `node_type::table` for table nodes.
|
||||
[[nodiscard]] node_type type() const noexcept override { return node_type::table; }
|
||||
|
||||
/// \brief Always returns `true` for table nodes.
|
||||
[[nodiscard]] bool is_table() const noexcept override { return true; }
|
||||
/// \brief Always returns `false` for table nodes.
|
||||
[[nodiscard]] bool is_array() const noexcept override { return false; }
|
||||
/// \brief Always returns `false` for table nodes.
|
||||
[[nodiscard]] bool is_value() const noexcept override { return false; }
|
||||
|
||||
[[nodiscard]] bool is_inline() const noexcept { return inline_; }
|
||||
|
||||
[[nodiscard]] table* as_table() noexcept override { return this; }
|
||||
[[nodiscard]] const table* as_table() const noexcept override { return this; }
|
||||
|
||||
[[nodiscard]] bool empty() const noexcept { return values.empty(); }
|
||||
|
||||
[[nodiscard]] size_t size() const noexcept { return values.size(); }
|
||||
/// \brief Returns true if this table is an inline table.
|
||||
///
|
||||
/// \remarks Runtime-constructed tables (i.e. those not created during
|
||||
/// parsing) are not inline by default.
|
||||
[[nodiscard]] bool is_inline() const noexcept { return inline_; }
|
||||
|
||||
/// \brief Sets whether this table is a TOML inline table.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 1 },
|
||||
/// { "b", 2 },
|
||||
/// { "c", 3 },
|
||||
/// { "d", toml::table{{ { "e", 4 } }} }
|
||||
/// }};
|
||||
/// std::cout << "is inline? "sv << tbl.is_inline() << std::endl;
|
||||
/// std::cout << tbl << std::endl << std::endl;
|
||||
///
|
||||
/// tbl.is_inline(!tbl.is_inline());
|
||||
/// std::cout << "is inline? "sv << tbl.is_inline() << std::endl;
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// // example output:
|
||||
/// // is inline? false
|
||||
/// // a = 1
|
||||
/// // b = 2
|
||||
/// // c = 3
|
||||
/// // [d]
|
||||
/// // e = 4
|
||||
/// //
|
||||
/// // is inline? true
|
||||
/// // { a = 1, b = 2, c = 3, d = { e = 4 } }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \remarks A table being 'inline' is only relevent during printing;
|
||||
/// it has no effect on the general functionality of the table
|
||||
/// object.
|
||||
///
|
||||
/// \param val The new value for 'inline'.
|
||||
void is_inline(bool val) noexcept { inline_ = val; }
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair.
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A node_view.
|
||||
///
|
||||
/// \remarks std::map::operator[]'s behaviour of constructing an element at a key if it
|
||||
/// didn't exist is terribad, so I've deliberately chosen not to emulate that
|
||||
/// insane bug-factory. This Is Not An Error (tm).
|
||||
///
|
||||
/// \see toml::node_view
|
||||
[[nodiscard]] inline node_view<table> operator[] (string_view key) noexcept;
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair (const overload).
|
||||
[[nodiscard]] inline node_view<const table> operator[] (string_view key) const noexcept;
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair.
|
||||
[[nodiscard]] iterator begin() noexcept { return { values.begin() }; }
|
||||
/// \brief Returns an iterator to the first key-value pair.
|
||||
[[nodiscard]] const_iterator begin() const noexcept { return { values.begin() }; }
|
||||
/// \brief Returns an iterator to the first key-value pair.
|
||||
[[nodiscard]] const_iterator cbegin() const noexcept { return { values.cbegin() }; }
|
||||
|
||||
/// \brief Returns an iterator to one-past-the-last key-value pair.
|
||||
[[nodiscard]] iterator end() noexcept { return { values.end() }; }
|
||||
[[nodiscard]] const_iterator end() const noexcept { return { values.end() };}
|
||||
/// \brief Returns an iterator to one-past-the-last key-value pair.
|
||||
[[nodiscard]] const_iterator end() const noexcept { return { values.end() }; }
|
||||
/// \brief Returns an iterator to one-past-the-last key-value pair.
|
||||
[[nodiscard]] const_iterator cend() const noexcept { return { values.cend() }; }
|
||||
|
||||
/// \brief Returns true if the table is empty.
|
||||
[[nodiscard]] bool empty() const noexcept { return values.empty(); }
|
||||
/// \brief Returns the number of key-value pairs in the table.
|
||||
[[nodiscard]] size_t size() const noexcept { return values.size(); }
|
||||
/// \brief Removes all key-value pairs from the table.
|
||||
void clear() noexcept { values.clear(); }
|
||||
|
||||
template <typename K, typename V, typename = std::enable_if_t<
|
||||
std::is_convertible_v<K&&, string_view>
|
||||
>>
|
||||
std::pair<iterator, bool> insert(K&& key, V&& val) noexcept
|
||||
{
|
||||
auto ipos = values.lower_bound(key);
|
||||
if (ipos == values.end() || ipos->first != key)
|
||||
{
|
||||
ipos = values.emplace_hint(ipos, std::forward<K>(key), impl::make_node(std::forward<V>(val)));
|
||||
return { ipos, true };
|
||||
}
|
||||
return { ipos, false };
|
||||
}
|
||||
|
||||
template <typename ITER, typename = std::enable_if_t<
|
||||
!std::is_convertible_v<ITER&&, string_view>
|
||||
>>
|
||||
void insert(ITER first, ITER last) noexcept
|
||||
{
|
||||
if (first == last)
|
||||
return;
|
||||
for (auto it = first; it != last; it++)
|
||||
{
|
||||
if constexpr (std::is_rvalue_reference_v<decltype(*it)>)
|
||||
insert(std::move((*it).first), std::move((*it).second));
|
||||
else
|
||||
insert((*it).first, (*it).second);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
std::pair<iterator, bool> insert_or_assign(K&& key, V&& val) noexcept
|
||||
{
|
||||
auto ipos = values.lower_bound(key);
|
||||
if (ipos == values.end() || ipos->first != key)
|
||||
{
|
||||
ipos = values.emplace_hint(ipos, std::forward<K>(key), impl::make_node(std::forward<V>(val)));
|
||||
return { ipos, true };
|
||||
}
|
||||
else
|
||||
{
|
||||
(*ipos).second.reset(impl::make_node(std::forward<V>(val)));
|
||||
return { ipos, false };
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U, typename K, typename... V>
|
||||
std::pair<iterator, bool> emplace(K&& key, V&&... args) noexcept
|
||||
{
|
||||
using type = impl::unwrapped<U>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Emplacement type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
);
|
||||
|
||||
auto ipos = values.lower_bound(key);
|
||||
if (ipos == values.end() || ipos->first != key)
|
||||
{
|
||||
ipos = values.emplace_hint(
|
||||
ipos,
|
||||
std::forward<K>(key),
|
||||
new node_of<type>{ std::forward<V>(args)... }
|
||||
);
|
||||
return { ipos, true };
|
||||
}
|
||||
return { ipos, false };
|
||||
}
|
||||
|
||||
/// \brief Removes the specified key-value pair from the table.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 1 },
|
||||
/// { "b", 2 },
|
||||
/// { "c", 3 }
|
||||
/// }};
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// tbl.erase(tbl.begin() + 1);
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // { a = 1, b = 2, c = 3 }
|
||||
/// // { a = 1, c = 3 }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param pos Iterator to the key-value pair being erased.
|
||||
///
|
||||
/// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
|
||||
iterator erase(iterator pos) noexcept
|
||||
{
|
||||
return { values.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
/// \brief Removes the specified key-value pair from the table (const iterator overload).
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 1 },
|
||||
/// { "b", 2 },
|
||||
/// { "c", 3 }
|
||||
/// }};
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// tbl.erase(tbl.cbegin() + 1);
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // { a = 1, b = 2, c = 3 }
|
||||
/// // { a = 1, c = 3 }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param pos Iterator to the key-value pair being erased.
|
||||
///
|
||||
/// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
|
||||
iterator erase(const_iterator pos) noexcept
|
||||
{
|
||||
return { values.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
/// \brief Removes the key-value pairs in the range [first, last) from the table.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 1 },
|
||||
/// { "b", "bad" },
|
||||
/// { "c", "karma" },
|
||||
/// { "d", 2 }
|
||||
/// }};
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// tbl.erase(tbl.cbegin() + 1, tbl.cbegin() + 3);
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // { a = 1, b = "bad", c = "karma", d = 2 }
|
||||
/// // { a = 1, d = 2 }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param first Iterator to the first key-value pair being erased.
|
||||
/// \param last Iterator to the one-past-the-last key-value pair being erased.
|
||||
///
|
||||
/// \returns Iterator to the first key-value pair immediately following the last removed key-value pair.
|
||||
iterator erase(const_iterator first, const_iterator last) noexcept
|
||||
{
|
||||
return { values.erase(first.raw_, last.raw_) };
|
||||
}
|
||||
|
||||
/// \brief Removes the value with the given key from the table.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 1 },
|
||||
/// { "b", 2 },
|
||||
/// { "c", 3 }
|
||||
/// }};
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// std::cout << tbl.erase("b") << std::endl;
|
||||
/// std::cout << tbl.erase("not an existing key") << std::endl;
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // { a = 1, b = 2, c = 3 }
|
||||
/// // true
|
||||
/// // false
|
||||
/// // { a = 1, c = 3 }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param key Key to erase.
|
||||
///
|
||||
/// \returns True if any values with matching keys were found and erased.
|
||||
bool erase(string_view key) noexcept
|
||||
{
|
||||
if (auto it = values.find(key); it != values.end())
|
||||
@ -204,16 +513,42 @@ namespace toml
|
||||
[[nodiscard]] node* get(string_view key) noexcept { return do_get(values, key); }
|
||||
[[nodiscard]] const node* get(string_view key) const noexcept { return do_get(values, key); }
|
||||
|
||||
[[nodiscard]] iterator find(string_view key) noexcept { return { values.find(key) }; }
|
||||
[[nodiscard]] const_iterator find(string_view key) const noexcept { return { values.find(key) }; }
|
||||
|
||||
/// \brief Gets the node at a specific key if it is a particular type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 42, },
|
||||
/// { "b", "is the meaning of life, apparently." }
|
||||
/// }};
|
||||
/// if (auto val = arr.get_as<int64_t>("a"))
|
||||
/// std::cout << node [\"a\"] was an integer with value "sv << **val << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // node ["a"] was an integer with value 42
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam T The node's type.
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the selected node if it was of the specified type, or nullptr.
|
||||
template <typename T>
|
||||
[[nodiscard]] node_of<T>* get_as(string_view key) noexcept { return do_get_as<T>(values, key); }
|
||||
|
||||
/// \brief Gets the node at a specific key if it is a particular type (const overload).
|
||||
///
|
||||
/// \tparam T The node's type.
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the selected node if it was of the specified type, or nullptr.
|
||||
template <typename T>
|
||||
[[nodiscard]] const node_of<T>* get_as(string_view key) const noexcept { return do_get_as<T>(values, key); }
|
||||
|
||||
/// \brief Returns true if the table contains a node at the given key.
|
||||
[[nodiscard]] bool contains(string_view key) const noexcept { return do_contains(values, key); }
|
||||
|
||||
[[nodiscard]] inline node_view<table> operator[] (string_view) noexcept;
|
||||
[[nodiscard]] inline node_view<const table> operator[] (string_view) const noexcept;
|
||||
|
||||
/// \brief Equality operator.
|
||||
///
|
||||
/// \param lhs The LHS table.
|
||||
|
@ -6,15 +6,19 @@
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr bool is_ascii_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'\t' || codepoint == U' ';
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool is_whitespace(char32_t codepoint) noexcept
|
||||
constexpr bool is_unicode_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
// see: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
// (characters that don't say "is a line-break")
|
||||
|
||||
return codepoint == U'\t'
|
||||
|| codepoint == U' '
|
||||
|| codepoint == U'\u00A0' // no-break space
|
||||
return codepoint == U'\u00A0' // no-break space
|
||||
|| codepoint == U'\u1680' // ogham space mark
|
||||
|| (codepoint >= U'\u2000' && codepoint <= U'\u200A') // em quad -> hair space
|
||||
|| codepoint == U'\u202F' // narrow no-break space
|
||||
@ -23,22 +27,39 @@ namespace toml::impl
|
||||
;
|
||||
}
|
||||
|
||||
template <bool CR = true>
|
||||
[[nodiscard]]
|
||||
constexpr bool is_line_break(char32_t codepoint) noexcept
|
||||
constexpr bool is_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_whitespace(codepoint) || is_unicode_whitespace(codepoint);
|
||||
}
|
||||
|
||||
template <bool CR = true>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr bool is_ascii_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
constexpr auto low_range_end = CR ? U'\r' : U'\f';
|
||||
return (codepoint >= U'\n' && codepoint <= low_range_end);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool is_unicode_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
// see https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
// (characters that say "is a line-break")
|
||||
|
||||
constexpr auto low_range_end = CR ? U'\r' : U'\f';
|
||||
|
||||
return (codepoint >= U'\n' && codepoint <= low_range_end)
|
||||
|| codepoint == U'\u0085' // next line
|
||||
return codepoint == U'\u0085' // next line
|
||||
|| codepoint == U'\u2028' // line separator
|
||||
|| codepoint == U'\u2029' // paragraph separator
|
||||
;
|
||||
}
|
||||
|
||||
template <bool CR = true>
|
||||
[[nodiscard]]
|
||||
constexpr bool is_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_line_break<CR>(codepoint) || is_unicode_line_break(codepoint);
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr bool is_string_delimiter(char32_t codepoint) noexcept
|
||||
{
|
||||
@ -75,7 +96,8 @@ namespace toml::impl
|
||||
{
|
||||
return (codepoint >= U'a' && codepoint <= U'f')
|
||||
|| (codepoint >= U'A' && codepoint <= U'F')
|
||||
|| is_decimal_digit(codepoint);
|
||||
|| is_decimal_digit(codepoint)
|
||||
;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -106,38 +128,22 @@ namespace toml::impl
|
||||
[[nodiscard]]
|
||||
constexpr bool is_value_terminator(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_line_break(codepoint)
|
||||
|| is_whitespace(codepoint)
|
||||
return is_ascii_line_break(codepoint)
|
||||
|| is_ascii_whitespace(codepoint)
|
||||
|| codepoint == U']'
|
||||
|| codepoint == U'}'
|
||||
|| codepoint == U','
|
||||
|| codepoint == U'#'
|
||||
|| is_unicode_line_break(codepoint)
|
||||
|| is_unicode_whitespace(codepoint)
|
||||
;
|
||||
}
|
||||
|
||||
struct utf8_decoder final
|
||||
{
|
||||
// This decoder is based on code from here: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
//
|
||||
// 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.
|
||||
//# This decoder is based on the 'Flexible and Economical UTF-8 Decoder'
|
||||
//# Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
//# See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
|
||||
uint_least32_t state{};
|
||||
char32_t codepoint{};
|
||||
@ -211,9 +217,9 @@ namespace toml::impl
|
||||
: source{ sv }
|
||||
{
|
||||
if (source.length() >= 3_sz
|
||||
&& static_cast<uint8_t>(source[0]) == 0xEF_u8
|
||||
&& static_cast<uint8_t>(source[1]) == 0xBB_u8
|
||||
&& static_cast<uint8_t>(source[2]) == 0xBF_u8)
|
||||
&& static_cast<uint8_t>(source[0]) == static_cast<uint8_t>(0xEFu)
|
||||
&& static_cast<uint8_t>(source[1]) == static_cast<uint8_t>(0xBBu)
|
||||
&& static_cast<uint8_t>(source[2]) == static_cast<uint8_t>(0xBFu))
|
||||
{
|
||||
position += 3_sz;
|
||||
}
|
||||
@ -255,9 +261,9 @@ namespace toml::impl
|
||||
if (*source)
|
||||
{
|
||||
static constexpr uint8_t bom[] {
|
||||
0xEF_u8,
|
||||
0xBB_u8,
|
||||
0xBF_u8
|
||||
0xEF,
|
||||
0xBB,
|
||||
0xBF
|
||||
};
|
||||
|
||||
using stream_traits = typename std::remove_pointer_t<decltype(source)>::traits_type;
|
||||
@ -472,7 +478,6 @@ namespace toml::impl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
[[nodiscard]]
|
||||
|
@ -124,11 +124,11 @@ namespace toml
|
||||
[[nodiscard]] const T& operator* () const& noexcept { return val_; }
|
||||
|
||||
/// \brief Returns a reference to the underlying value.
|
||||
[[nodiscard]] operator T& () & noexcept { return val_; }
|
||||
[[nodiscard]] explicit operator T& () & noexcept { return val_; }
|
||||
/// \brief Returns a reference to the underlying value (rvalue overload).
|
||||
[[nodiscard]] operator T&& () && noexcept { return std::move(val_); }
|
||||
[[nodiscard]] explicit operator T&& () && noexcept { return std::move(val_); }
|
||||
/// \brief Returns a reference to the underlying value (const overload).
|
||||
[[nodiscard]] operator const T& () const& noexcept { return val_; }
|
||||
[[nodiscard]] explicit operator const T& () const& noexcept { return val_; }
|
||||
|
||||
template <typename CHAR>
|
||||
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const value& rhs) TOML_MAY_THROW
|
||||
@ -277,7 +277,12 @@ namespace toml
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t N> value(const string_char(&)[N]) -> value<string>;
|
||||
template <size_t N> value(const string_char(&&)[N]) -> value<string>;
|
||||
value(const string_char*) -> value<string>;
|
||||
template <size_t N> value(string_char(&)[N]) -> value<string>;
|
||||
template <size_t N> value(string_char(&&)[N]) -> value<string>;
|
||||
value(string_char*) -> value<string>;
|
||||
value(string_view) -> value<string>;
|
||||
value(string) -> value<string>;
|
||||
value(bool) -> value<bool>;
|
||||
@ -293,4 +298,7 @@ namespace toml
|
||||
#ifdef TOML_SMALL_FLOAT_TYPE
|
||||
value(TOML_SMALL_FLOAT_TYPE) -> value<double>;
|
||||
#endif
|
||||
#ifdef TOML_SMALL_INT_TYPE
|
||||
value(TOML_SMALL_INT_TYPE) -> value<int64_t>;
|
||||
#endif
|
||||
}
|
||||
|
@ -235,14 +235,14 @@ class NavBarFix(object):
|
||||
|
||||
|
||||
|
||||
# changes any links to index.html to link to annotated.html instead (index.html is blank/unused)
|
||||
# changes any links to index.html to link to namespacetoml.html instead (index.html is blank/unused)
|
||||
class IndexHrefFix(object):
|
||||
|
||||
def __call__(self, file, doc):
|
||||
links = doc.body('a', href='index.html')
|
||||
if (len(links) > 0):
|
||||
for link in links:
|
||||
link['href'] = 'annotated.html'
|
||||
link['href'] = 'namespacetoml.html'
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -496,6 +496,15 @@ class ExtDocLinksFix(object):
|
||||
(r'std::(?:basic_|w)?stringstreams?', 'https://en.cppreference.com/w/cpp/io/basic_stringstream'),
|
||||
(r'std::(?:basic_|w|u8)?string_views?', 'https://en.cppreference.com/w/cpp/string/basic_string_view'),
|
||||
(r'std::(?:basic_|w|u8)?strings?', 'https://en.cppreference.com/w/cpp/string/basic_string'),
|
||||
|
||||
(r'(?:<|<)fstream(?:>|>)', 'https://en.cppreference.com/w/cpp/header/fstream'),
|
||||
(r'(?:<|<)sstream(?:>|>)', 'https://en.cppreference.com/w/cpp/header/sstream'),
|
||||
(r'(?:<|<)iostream(?:>|>)', 'https://en.cppreference.com/w/cpp/header/iostream'),
|
||||
(r'(?:<|<)iosfwd(?:>|>)', 'https://en.cppreference.com/w/cpp/header/iosfwd'),
|
||||
(r'(?:<|<)string(?:>|>)', 'https://en.cppreference.com/w/cpp/header/string'),
|
||||
(r'(?:<|<)string_view(?:>|>)', 'https://en.cppreference.com/w/cpp/header/string_view'),
|
||||
|
||||
|
||||
(r'char(?:8|16|32)_ts?', 'https://en.cppreference.com/w/cpp/language/types'),
|
||||
(r'std::is_(?:nothrow_)?convertible(?:_v)?', 'https://en.cppreference.com/w/cpp/types/is_convertible'),
|
||||
(r'std::is_same(?:_v)?', 'https://en.cppreference.com/w/cpp/types/is_same'),
|
||||
@ -514,6 +523,7 @@ class ExtDocLinksFix(object):
|
||||
(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'std::initializer_lists?', 'https://en.cppreference.com/w/cpp/utility/initializer_list'),
|
||||
(
|
||||
r'(?:L?P)?(?:'
|
||||
+ r'D?WORD(?:32|64|_PTR)?|HANDLE|HMODULE|BOOL(?:EAN)?'
|
||||
@ -525,7 +535,14 @@ class ExtDocLinksFix(object):
|
||||
(
|
||||
r'(?:__INTELLISENSE__|_MSC_FULL_VER|_MSC_VER|_MSVC_LANG|_WIN32|_WIN64)',
|
||||
'https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019'
|
||||
)
|
||||
),
|
||||
(r'(?:Legacy)?InputIterators?', 'https://en.cppreference.com/w/cpp/named_req/InputIterator'),
|
||||
(r'(?:Legacy)?OutputIterators?', 'https://en.cppreference.com/w/cpp/named_req/OutputIterator'),
|
||||
(r'(?:Legacy)?ForwardIterators?', 'https://en.cppreference.com/w/cpp/named_req/ForwardIterator'),
|
||||
(r'(?:Legacy)?BidirectionalIterators?', 'https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator'),
|
||||
(r'(?:Legacy)?RandomAccessIterators?', 'https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator'),
|
||||
(r'(?:Legacy)?ContiguousIterators?', 'https://en.cppreference.com/w/cpp/named_req/ContiguousIterator'),
|
||||
(r'(?:Legacy)?Iterators?', 'https://en.cppreference.com/w/cpp/named_req/Iterator')
|
||||
]
|
||||
__allowedNames = ['dd', 'p', 'dt', 'h3', 'td']
|
||||
|
||||
@ -709,7 +726,7 @@ def main():
|
||||
fixes = [
|
||||
CustomTagsFix()
|
||||
# , NavBarFix()
|
||||
# , IndexHrefFix()
|
||||
, IndexHrefFix()
|
||||
, ModifiersFix1()
|
||||
, ModifiersFix2()
|
||||
, InlineNamespaceFix1()
|
||||
@ -732,6 +749,23 @@ def main():
|
||||
if _threadError:
|
||||
sys.exit(1)
|
||||
|
||||
# replace index.html with a redirect
|
||||
index_html_path = path.join(html_dir, 'index.html')
|
||||
with open(index_html_path,'w', encoding='utf-8', newline='\n') as output_file:
|
||||
print('''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Refresh" content="0; url=./namespacetoml.html" />
|
||||
</head>
|
||||
<body>
|
||||
<p>Please follow <a href="namespacetoml.html">this link</a>.</p>
|
||||
</body>
|
||||
</html>
|
||||
''',
|
||||
file=output_file
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -81,13 +81,27 @@ def main():
|
||||
source_text = re.sub('(?:///[<].*?)\n', '\n', source_text, 0, re.I | re.M) # remove inline doxy briefs
|
||||
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
|
||||
return_type_pattern \
|
||||
= r'(?:' \
|
||||
+ r'(?:\[\[nodiscard\]\]\s*)?' \
|
||||
+ r'(?:(?:friend|explicit|virtual|inline|const|operator)\s+)*' \
|
||||
+ r'(?:' \
|
||||
+ r'bool|int64_t|(?:const_)?iterator|double|void' \
|
||||
+ r'|node(?:_(?:view|of)<.+?>|)?|table|array|value(?:<.+?>)?' \
|
||||
+ r'|T|U|parse_(?:error|result)' \
|
||||
+ r')' \
|
||||
+ r'(?:\s*[&*]+)?' \
|
||||
+ r'(?:\s*[(]\s*[)])?' \
|
||||
+ r'\s+' \
|
||||
+ r')'
|
||||
blank_lines_between_returns_pattern = '({}[^\n]+)\n\n([ \t]*{})'.format(return_type_pattern, return_type_pattern)
|
||||
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 = re.sub(blank_lines_between_returns_pattern, '\\1\n\\2', source_text, 0, re.I | re.M)
|
||||
source_text = source_text.strip()
|
||||
|
||||
|
||||
@ -121,6 +135,15 @@ TOML language specification:
|
||||
Latest: https://github.com/toml-lang/toml/blob/master/README.md
|
||||
v0.5.0: https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md''')
|
||||
preamble.append(read_all_text_from_file(path.join(get_script_folder(), '..', 'LICENSE')))
|
||||
preamble.append('''
|
||||
UTF-8 decoding is performed using a derivative of Bjoern Hoehrmann's 'Flexible and Economical UTF-8 Decoder'
|
||||
See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
|
||||
{}
|
||||
'''.format(
|
||||
read_all_text_from_file(path.join(get_script_folder(), '..', 'LICENSE-utf8-decoder'))
|
||||
))
|
||||
|
||||
|
||||
# write the output file
|
||||
output_file_path = path.join(get_script_folder(), '..', 'toml.hpp')
|
||||
|
@ -1,40 +0,0 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("lifetime - tables")
|
||||
{
|
||||
static constexpr auto filename = "foo.toml"sv;
|
||||
|
||||
parsing_should_succeed(
|
||||
S(R"(test = { val1 = "foo" })"sv),
|
||||
[&](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.source().begin == source_position{ 1, 1 });
|
||||
CHECK(tbl.source().end == source_position{ 1, 25 });
|
||||
CHECK(tbl.source().path);
|
||||
CHECK(*tbl.source().path == filename);
|
||||
CHECK(tbl.size() == 1_sz);
|
||||
REQUIRE(tbl[S("test")].as<table>());
|
||||
CHECK(tbl[S("test")].as<table>()->size() == 1_sz);
|
||||
CHECK(tbl[S("test")][S("val1")] == S("foo"sv));
|
||||
|
||||
table test_table;
|
||||
CHECK(test_table.source().begin == source_position{});
|
||||
CHECK(test_table.source().end == source_position{});
|
||||
CHECK(!test_table.source().path);
|
||||
CHECK(test_table.size() == 0_sz);
|
||||
CHECK(!test_table[S("test")].as<table>());
|
||||
|
||||
test_table = std::move(tbl);
|
||||
CHECK(test_table.source().begin == source_position{ 1, 1 });
|
||||
CHECK(test_table.source().end == source_position{ 1, 25 });
|
||||
CHECK(test_table.source().path);
|
||||
CHECK(*test_table.source().path == filename);
|
||||
CHECK(test_table.size() == 1_sz);
|
||||
REQUIRE(test_table[S("test")].as<table>());
|
||||
CHECK(test_table[S("test")].as<table>()->size() == 1_sz);
|
||||
CHECK(test_table[S("test")][S("val1")] == S("foo"sv));
|
||||
},
|
||||
filename
|
||||
);
|
||||
|
||||
}
|
214
tests/manipulating_arrays.cpp
Normal file
214
tests/manipulating_arrays.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("arrays - moving")
|
||||
{
|
||||
static constexpr auto filename = "foo.toml"sv;
|
||||
|
||||
parsing_should_succeed(
|
||||
S(R"(test = [ "foo" ])"sv),
|
||||
[&](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.source().begin == source_position{ 1, 1 });
|
||||
CHECK(tbl.source().end == source_position{ 1, 17 });
|
||||
CHECK(tbl.source().path);
|
||||
CHECK(*tbl.source().path == filename);
|
||||
CHECK(tbl.size() == 1_sz);
|
||||
|
||||
auto arr1 = tbl[S("test")].as<array>();
|
||||
REQUIRE(arr1);
|
||||
CHECK(arr1->size() == 1_sz);
|
||||
CHECK(arr1->source().begin == source_position{ 1, 8 });
|
||||
CHECK(arr1->source().end == source_position{ 1, 17 });
|
||||
CHECK(arr1->source().path);
|
||||
CHECK(*arr1->source().path == filename);
|
||||
REQUIRE(arr1->get_as<string>(0_sz));
|
||||
CHECK(*arr1->get_as<string>(0_sz) == S("foo"sv));
|
||||
|
||||
array arr2;
|
||||
CHECK(arr2.source().begin == source_position{});
|
||||
CHECK(arr2.source().end == source_position{});
|
||||
CHECK(!arr2.source().path);
|
||||
CHECK(arr2.size() == 0_sz);
|
||||
|
||||
arr2 = std::move(*arr1);
|
||||
CHECK(arr2.source().begin == source_position{ 1, 8 });
|
||||
CHECK(arr2.source().end == source_position{ 1, 17 });
|
||||
CHECK(arr2.source().path);
|
||||
CHECK(*arr2.source().path == filename);
|
||||
CHECK(arr2.size() == 1_sz);
|
||||
REQUIRE(arr2.get_as<string>(0_sz));
|
||||
CHECK(*arr2.get_as<string>(0_sz) == S("foo"sv));
|
||||
|
||||
CHECK(arr1->source().begin == source_position{});
|
||||
CHECK(arr1->source().end == source_position{});
|
||||
CHECK(!arr1->source().path);
|
||||
CHECK(arr1->size() == 0_sz);
|
||||
},
|
||||
filename
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("arrays - construction")
|
||||
{
|
||||
{
|
||||
array arr;
|
||||
CHECK(arr.size() == 0_sz);
|
||||
CHECK(arr.empty());
|
||||
CHECK(arr.begin() == arr.end());
|
||||
CHECK(arr.cbegin() == arr.cend());
|
||||
CHECK(arr.source().begin == source_position{});
|
||||
CHECK(arr.source().end == source_position{});
|
||||
CHECK(!arr.source().path);
|
||||
CHECK(!arr.is_homogeneous());
|
||||
}
|
||||
|
||||
{
|
||||
array arr{ 42 };
|
||||
CHECK(arr.size() == 1_sz);
|
||||
CHECK(!arr.empty());
|
||||
CHECK(arr.begin() != arr.end());
|
||||
CHECK(arr.cbegin() != arr.cend());
|
||||
REQUIRE(arr.get_as<int64_t>(0_sz));
|
||||
CHECK(*arr.get_as<int64_t>(0_sz) == 42);
|
||||
CHECK(arr.is_homogeneous());
|
||||
CHECK(arr.is_homogeneous<int64_t>());
|
||||
}
|
||||
|
||||
{
|
||||
array arr{ 42, S("test"sv), 10.0f, array{}, value{ 3 } };
|
||||
CHECK(arr.size() == 5_sz);
|
||||
CHECK(!arr.empty());
|
||||
REQUIRE(arr.get_as<int64_t>(0_sz));
|
||||
CHECK(*arr.get_as<int64_t>(0_sz) == 42);
|
||||
REQUIRE(arr.get_as<string>(1_sz));
|
||||
CHECK(*arr.get_as<string>(1_sz) == S("test"sv));
|
||||
REQUIRE(arr.get_as<double>(2_sz));
|
||||
CHECK(*arr.get_as<double>(2_sz) == 10.0);
|
||||
REQUIRE(arr.get_as<array>(3_sz));
|
||||
REQUIRE(arr.get_as<int64_t>(4_sz));
|
||||
CHECK(*arr.get_as<int64_t>(4_sz) == 3);
|
||||
CHECK(!arr.is_homogeneous());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("arrays - equality")
|
||||
{
|
||||
array arr1{ 1, 2, 3 };
|
||||
CHECK(arr1 == arr1);
|
||||
|
||||
array arr2{ 1, 2, 3 };
|
||||
CHECK(arr1 == arr2);
|
||||
|
||||
array arr3{ 1, 2 };
|
||||
CHECK(arr1 != arr3);
|
||||
|
||||
array arr4{ 1, 2, 3, 4 };
|
||||
CHECK(arr1 != arr4);
|
||||
|
||||
array arr5{ 1, 2, 3.0 };
|
||||
CHECK(arr1 != arr5);
|
||||
|
||||
array arr6{};
|
||||
CHECK(arr1 != arr6);
|
||||
CHECK(arr6 == arr6);
|
||||
|
||||
array arr7{};
|
||||
CHECK(arr6 == arr7);
|
||||
}
|
||||
|
||||
TEST_CASE("arrays - insertion and erasure")
|
||||
{
|
||||
array arr;
|
||||
auto it = arr.insert(arr.cbegin(), 42);
|
||||
CHECK(it == arr.begin());
|
||||
CHECK(arr.size() == 1_sz);
|
||||
CHECK(!arr.empty());
|
||||
REQUIRE(arr.get_as<int64_t>(0_sz));
|
||||
CHECK(*arr.get_as<int64_t>(0_sz) == 42);
|
||||
REQUIRE(arr == array{ 42 });
|
||||
|
||||
it = arr.insert(arr.cend(), 3, 10.0f);
|
||||
CHECK(it == arr.begin() + 1);
|
||||
CHECK(arr.size() == 4_sz);
|
||||
REQUIRE(arr.get_as<double>(1_sz));
|
||||
CHECK(*arr.get_as<double>(1_sz) == 10.0);
|
||||
REQUIRE(arr.get_as<double>(2_sz));
|
||||
CHECK(*arr.get_as<double>(2_sz) == 10.0);
|
||||
REQUIRE(arr.get_as<double>(3_sz));
|
||||
CHECK(*arr.get_as<double>(3_sz) == 10.0);
|
||||
REQUIRE(arr == array{ 42, 10.0, 10.0, 10.0 });
|
||||
|
||||
it = arr.emplace<array>(arr.cbegin(), 1, 2, 3);
|
||||
CHECK(it == arr.begin());
|
||||
CHECK(arr.size() == 5_sz);
|
||||
REQUIRE(arr.get_as<array>(0_sz));
|
||||
CHECK(arr.get_as<array>(0_sz)->size() == 3_sz);
|
||||
REQUIRE(arr == array{ array{ 1, 2, 3 }, 42, 10.0, 10.0, 10.0 });
|
||||
|
||||
{
|
||||
decltype(auto) val = arr.push_back(S("test"sv));
|
||||
CHECK(arr.size() == 6_sz);
|
||||
REQUIRE(arr.get_as<string>(5_sz));
|
||||
CHECK(*arr.get_as<string>(5_sz) == S("test"sv));
|
||||
CHECK(val == S("test"sv));
|
||||
CHECK(&val == &arr.back());
|
||||
REQUIRE(arr == array{ array{ 1, 2, 3 }, 42, 10.0, 10.0, 10.0, S("test"sv) });
|
||||
}
|
||||
|
||||
{
|
||||
decltype(auto) val = arr.emplace_back<string>(S("test2"sv));
|
||||
CHECK(arr.size() == 7_sz);
|
||||
REQUIRE(arr.get_as<string>(6_sz));
|
||||
CHECK(*arr.get_as<string>(6_sz) == S("test2"sv));
|
||||
CHECK(val == S("test2"sv));
|
||||
CHECK(&val == &arr.back());
|
||||
REQUIRE(arr == array{ array{ 1, 2, 3 }, 42, 10.0, 10.0, 10.0, S("test"sv), S("test2"sv) });
|
||||
}
|
||||
|
||||
it = arr.erase(arr.cbegin());
|
||||
REQUIRE(arr == array{ 42, 10.0, 10.0, 10.0, S("test"sv), S("test2"sv) });
|
||||
CHECK(it == arr.begin());
|
||||
CHECK(arr.size() == 6_sz);
|
||||
|
||||
|
||||
it = arr.erase(arr.cbegin() + 2, arr.cbegin() + 4);
|
||||
REQUIRE(arr == array{ 42, 10.0, S("test"sv), S("test2"sv) });
|
||||
CHECK(it == arr.begin() + 2);
|
||||
CHECK(arr.size() == 4_sz);
|
||||
|
||||
arr.pop_back();
|
||||
REQUIRE(arr == array{ 42, 10.0, S("test"sv) });
|
||||
CHECK(arr.size() == 3_sz);
|
||||
|
||||
arr.clear();
|
||||
REQUIRE(arr == array{});
|
||||
CHECK(arr.size() == 0_sz);
|
||||
CHECK(arr.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("arrays - flattening")
|
||||
{
|
||||
{
|
||||
array arr{
|
||||
1, 2, 3,
|
||||
array{ 4, 5 },
|
||||
6,
|
||||
array{},
|
||||
array{ 7, array{ 8, array{ 9 }, 10, array{}, }, 11 },
|
||||
};
|
||||
arr.flatten();
|
||||
REQUIRE(arr == array{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 });
|
||||
}
|
||||
|
||||
{
|
||||
array arr{
|
||||
array{},
|
||||
array{array{}},
|
||||
array{array{},array{array{},array{}},array{}},
|
||||
array{array{array{array{array{array{ 1 }}}}}}
|
||||
};
|
||||
arr.flatten();
|
||||
REQUIRE(arr == array{ 1 });
|
||||
}
|
||||
}
|
229
tests/manipulating_tables.cpp
Normal file
229
tests/manipulating_tables.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("tables - moving")
|
||||
{
|
||||
static constexpr auto filename = "foo.toml"sv;
|
||||
|
||||
parsing_should_succeed(
|
||||
S(R"(test = { val1 = "foo" })"sv),
|
||||
[&](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.source().begin == source_position{ 1, 1 });
|
||||
CHECK(tbl.source().end == source_position{ 1, 24 });
|
||||
CHECK(tbl.source().path);
|
||||
CHECK(*tbl.source().path == filename);
|
||||
CHECK(tbl.size() == 1_sz);
|
||||
|
||||
REQUIRE(tbl[S("test")].as<table>());
|
||||
CHECK(tbl[S("test")].as<table>()->size() == 1_sz);
|
||||
CHECK(tbl[S("test")].as<table>()->source().begin == source_position{ 1, 8 });
|
||||
CHECK(tbl[S("test")].as<table>()->source().end == source_position{ 1, 24 });
|
||||
CHECK(tbl[S("test")][S("val1")] == S("foo"sv));
|
||||
|
||||
table tbl2 = std::move(tbl);
|
||||
CHECK(tbl2.source().begin == source_position{ 1, 1 });
|
||||
CHECK(tbl2.source().end == source_position{ 1, 24 });
|
||||
CHECK(tbl2.source().path);
|
||||
CHECK(*tbl2.source().path == filename);
|
||||
CHECK(tbl2.size() == 1_sz);
|
||||
REQUIRE(tbl2[S("test")].as<table>());
|
||||
CHECK(tbl2[S("test")].as<table>()->size() == 1_sz);
|
||||
CHECK(tbl2[S("test")][S("val1")] == S("foo"sv));
|
||||
|
||||
CHECK(tbl.source().begin == source_position{});
|
||||
CHECK(tbl.source().end == source_position{});
|
||||
CHECK(!tbl.source().path);
|
||||
CHECK(tbl.size() == 0_sz);
|
||||
CHECK(!tbl[S("test")].as<table>());
|
||||
},
|
||||
filename
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE("tables - construction")
|
||||
{
|
||||
{
|
||||
table tbl;
|
||||
CHECK(tbl.size() == 0_sz);
|
||||
CHECK(tbl.empty());
|
||||
CHECK(tbl.begin() == tbl.end());
|
||||
CHECK(tbl.cbegin() == tbl.cend());
|
||||
CHECK(tbl.source().begin == source_position{});
|
||||
CHECK(tbl.source().end == source_position{});
|
||||
CHECK(!tbl.source().path);
|
||||
}
|
||||
|
||||
{
|
||||
table tbl{{
|
||||
{ S("foo"sv), 42 }
|
||||
}};
|
||||
CHECK(tbl.size() == 1_sz);
|
||||
CHECK(!tbl.empty());
|
||||
CHECK(tbl.begin() != tbl.end());
|
||||
CHECK(tbl.cbegin() != tbl.cend());
|
||||
REQUIRE(tbl.get_as<int64_t>(S("foo"sv)));
|
||||
CHECK(*tbl.get_as<int64_t>(S("foo"sv)) == 42);
|
||||
}
|
||||
|
||||
{
|
||||
table tbl{{
|
||||
{ S("foo"sv), 42 },
|
||||
{ S("bar"sv), 10.0 },
|
||||
{ S("kek"sv), false },
|
||||
{ S("qux"sv), array{ 1 } }
|
||||
}};
|
||||
CHECK(tbl.size() == 4_sz);
|
||||
CHECK(!tbl.empty());
|
||||
REQUIRE(tbl.get_as<int64_t>(S("foo"sv)));
|
||||
CHECK(*tbl.get_as<int64_t>(S("foo"sv)) == 42);
|
||||
REQUIRE(tbl.get_as<double>(S("bar"sv)));
|
||||
CHECK(*tbl.get_as<double>(S("bar"sv)) == 10.0);
|
||||
REQUIRE(tbl.get_as<bool>(S("kek"sv)));
|
||||
CHECK(*tbl.get_as<bool>(S("kek"sv)) == false);
|
||||
REQUIRE(tbl.get_as<array>(S("qux"sv)));
|
||||
CHECK(*tbl.get_as<array>(S("qux"sv)) == array{ 1 });
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("tables - equality")
|
||||
{
|
||||
static constexpr const string_char* one = S("one");
|
||||
|
||||
table tbl1{{
|
||||
{ one, 1 },
|
||||
{ S("two"), 2 },
|
||||
{ S("three"), 3 }
|
||||
}};
|
||||
CHECK(tbl1 == tbl1);
|
||||
|
||||
table tbl2{{
|
||||
{ S("one"sv), 1 },
|
||||
{ S("two"sv), 2 },
|
||||
{ S("three"sv), 3 }
|
||||
}};
|
||||
CHECK(tbl1 == tbl2);
|
||||
|
||||
table tbl3{{
|
||||
{ S("one"sv), 1 },
|
||||
{ S("two"sv), 2 }
|
||||
}};
|
||||
CHECK(tbl1 != tbl3);
|
||||
|
||||
table tbl4{{
|
||||
{ S("one"sv), 1 },
|
||||
{ S("two"sv), 2 },
|
||||
{ S("three"sv), 3 },
|
||||
{ S("four"sv), 4 }
|
||||
}};
|
||||
CHECK(tbl1 != tbl4);
|
||||
|
||||
table tbl5{{
|
||||
{ S("one"sv), 1 },
|
||||
{ S("two"sv), 2 },
|
||||
{ S("three"sv), 3.0 }
|
||||
}};
|
||||
CHECK(tbl1 != tbl5);
|
||||
|
||||
table tbl6{};
|
||||
CHECK(tbl1 != tbl6);
|
||||
CHECK(tbl6 == tbl6);
|
||||
|
||||
table tbl7{};
|
||||
CHECK(tbl6 == tbl7);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
static auto advance(T iter, ptrdiff_t offset) noexcept
|
||||
{
|
||||
while (offset > 0)
|
||||
{
|
||||
iter++;
|
||||
offset--;
|
||||
}
|
||||
while (offset < 0)
|
||||
{
|
||||
iter--;
|
||||
offset++;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("tables - insertion and erasure")
|
||||
{
|
||||
table tbl;
|
||||
auto res = tbl.insert(S("a"), 42);
|
||||
CHECK(res.first == tbl.begin());
|
||||
CHECK(res.second == true);
|
||||
CHECK(tbl.size() == 1_sz);
|
||||
CHECK(!tbl.empty());
|
||||
REQUIRE(tbl.get_as<int64_t>(S("a"sv)));
|
||||
CHECK(*tbl.get_as<int64_t>(S("a"sv)) == 42);
|
||||
REQUIRE(tbl == table{{ { S("a"sv), 42 } }});
|
||||
|
||||
res = tbl.insert(S("a"), 69);
|
||||
CHECK(res.first == tbl.begin());
|
||||
CHECK(res.second == false);
|
||||
CHECK(tbl.size() == 1_sz);
|
||||
REQUIRE(tbl.get_as<int64_t>(S("a")));
|
||||
CHECK(*tbl.get_as<int64_t>(S("a")) == 42);
|
||||
REQUIRE(tbl == table{{ { S("a"sv), 42 } }});
|
||||
|
||||
static constexpr const string_char* a = S("a");
|
||||
res = tbl.insert_or_assign(a, 69);
|
||||
CHECK(res.first == tbl.begin());
|
||||
CHECK(res.second == false); //should assign
|
||||
CHECK(tbl.size() == 1_sz);
|
||||
REQUIRE(tbl.get_as<int64_t>(S("a")));
|
||||
CHECK(*tbl.get_as<int64_t>(S("a")) == 69);
|
||||
REQUIRE(tbl == table{{ { S("a"sv), 69 } }});
|
||||
|
||||
res = tbl.insert_or_assign(S("b"), S("kek"));
|
||||
CHECK(res.first == advance(tbl.begin(), 1));
|
||||
CHECK(res.second == true); //should insert
|
||||
CHECK(tbl.size() == 2_sz);
|
||||
REQUIRE(tbl.get_as<string>(S("b")));
|
||||
CHECK(*tbl.get_as<string>(S("b")) == S("kek"sv));
|
||||
REQUIRE(tbl == table{{ { S("a"sv), 69 }, { S("b"sv), S("kek") } }});
|
||||
|
||||
res = tbl.emplace<array>(S("c"), 1, 2, 3);
|
||||
CHECK(res.first == advance(tbl.begin(), 2));
|
||||
CHECK(res.second == true);
|
||||
CHECK(tbl.size() == 3_sz);
|
||||
REQUIRE(tbl.get_as<array>(S("c")));
|
||||
CHECK(*tbl.get_as<array>(S("c")) == array{ 1, 2, 3 });
|
||||
REQUIRE(tbl == table{{ { S("a"sv), 69 }, { S("b"sv), S("kek"sv) }, { S("c"sv), array{ 1, 2, 3 } } }});
|
||||
|
||||
res = tbl.emplace<int64_t>(S("c"), 1);
|
||||
CHECK(res.first == advance(tbl.begin(), 2));
|
||||
CHECK(res.second == false);
|
||||
CHECK(tbl.size() == 3_sz);
|
||||
REQUIRE(!tbl.get_as<int64_t>(S("c")));
|
||||
REQUIRE(tbl.get_as<array>(S("c")));
|
||||
REQUIRE(tbl == table{{ { S("a"sv), 69 }, { S("b"sv), S("kek"s) }, { S("c"sv), array{ 1, 2, 3 } } }});
|
||||
|
||||
auto it = tbl.erase(tbl.cbegin());
|
||||
REQUIRE(tbl == table{{ { S("b"sv), S("kek") }, { S("c"sv), array{ 1, 2, 3 } } }});
|
||||
CHECK(it == tbl.begin());
|
||||
CHECK(tbl.size() == 2_sz);
|
||||
|
||||
res = tbl.insert_or_assign(S("a"sv), 69);
|
||||
CHECK(res.first == tbl.begin());
|
||||
CHECK(res.second == true); //should insert
|
||||
CHECK(tbl.size() == 3_sz);
|
||||
REQUIRE(tbl.get_as<int64_t>(S("a")));
|
||||
CHECK(*tbl.get_as<int64_t>(S("a")) == 69);
|
||||
REQUIRE(tbl == table{{ { S("a"sv), 69 }, { S("b"sv), S("kek") }, { S("c"sv), array{ 1, 2, 3 } } }});
|
||||
|
||||
it = tbl.erase(advance(tbl.cbegin(), 1), advance(tbl.cbegin(), 3));
|
||||
REQUIRE(tbl == table{{ { S("a"sv), 69 } }});
|
||||
CHECK(it == tbl.end());
|
||||
CHECK(tbl.size() == 1_sz);
|
||||
|
||||
tbl.clear();
|
||||
REQUIRE(tbl == table{});
|
||||
CHECK(tbl.size() == 0_sz);
|
||||
CHECK(tbl.empty());
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
test_sources = [
|
||||
'lifetimes.cpp',
|
||||
'main.cpp',
|
||||
'parsing_arrays.cpp',
|
||||
'parsing_booleans.cpp',
|
||||
@ -10,7 +9,9 @@ test_sources = [
|
||||
'parsing_key_value_pairs.cpp',
|
||||
'parsing_spec_example.cpp',
|
||||
'parsing_strings.cpp',
|
||||
'parsing_tables.cpp'
|
||||
'parsing_tables.cpp',
|
||||
'manipulating_arrays.cpp',
|
||||
'manipulating_tables.cpp'
|
||||
]
|
||||
|
||||
disable_exceptions = 'cpp_eh=none'
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("parsing arrays")
|
||||
TEST_CASE("parsing - arrays")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
integers = [ 1, 2, 3 ]
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("parsing booleans")
|
||||
TEST_CASE("parsing - booleans")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
bool1 = true
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("parsing comments")
|
||||
TEST_CASE("parsing - comments")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
# This is a full-line comment
|
||||
|
@ -3,7 +3,7 @@
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
|
||||
TEST_CASE("parsing dates and times")
|
||||
TEST_CASE("parsing - dates and times")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
odt1 = 1979-05-27T07:32:00Z
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("parsing floats - normal")
|
||||
TEST_CASE("parsing - floats")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
# fractional
|
||||
@ -114,7 +114,7 @@ flt8 = 224_617.445_991_228
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("parsing floats - inf and nan")
|
||||
TEST_CASE("parsing - inf and nan")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
# infinity
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("parsing integers - decimal")
|
||||
TEST_CASE("parsing - integers (decimal)")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
int1 = +99
|
||||
@ -67,7 +67,7 @@ int7 = 1_2_3_4_5 # VALID but discouraged
|
||||
parse_expected_value( "123_456_789"sv, 123456789 );
|
||||
}
|
||||
|
||||
TEST_CASE("parsing integers - hex, bin, oct")
|
||||
TEST_CASE("parsing - integers (hex, bin, oct)")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
# hexadecimal with prefix `0x`
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("parsing key-value pairs")
|
||||
TEST_CASE("parsing - key-value pairs")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
key = "value"
|
||||
@ -48,7 +48,7 @@ name = "Pradyun"
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("parsing key-value pairs - dotted")
|
||||
TEST_CASE("parsing - key-value pairs (dotted)")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
name = "Orange"
|
||||
|
@ -3,7 +3,7 @@
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
|
||||
TEST_CASE("parsing TOML spec example")
|
||||
TEST_CASE("parsing - TOML spec example")
|
||||
{
|
||||
static constexpr auto toml_text =
|
||||
S(R"(# This is a TOML document.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("parsing strings")
|
||||
TEST_CASE("parsing - strings")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "tests.h"
|
||||
|
||||
TEST_CASE("parsing tables")
|
||||
TEST_CASE("parsing - tables")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
[table]
|
||||
@ -158,7 +158,7 @@ apple.taste.sweet = true
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE("parsing inline tables")
|
||||
TEST_CASE("parsing - inline tables")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
name = { first = "Tom", last = "Preston-Werner" }
|
||||
@ -264,7 +264,7 @@ name = {
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("parsing arrays-of-tables")
|
||||
TEST_CASE("parsing - arrays-of-tables")
|
||||
{
|
||||
parsing_should_succeed(S(R"(
|
||||
points = [ { x = 1, y = 2, z = 3 },
|
||||
|
@ -54,7 +54,7 @@ void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&& func,
|
||||
{
|
||||
toml::parse_result result = toml::parse(toml_str, source_path);
|
||||
if (result)
|
||||
std::forward<FUNC>(func)(validate_table(*std::move(result), source_path));
|
||||
std::forward<FUNC>(func)(validate_table(std::move(result), source_path));
|
||||
else
|
||||
{
|
||||
FAIL(
|
||||
@ -71,7 +71,7 @@ void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&& func,
|
||||
ss.write(toml_str.data(), toml_str.length());
|
||||
toml::parse_result result = toml::parse(ss, source_path);
|
||||
if (result)
|
||||
std::forward<FUNC>(func)(validate_table(*std::move(result), source_path));
|
||||
std::forward<FUNC>(func)(validate_table(std::move(result), source_path));
|
||||
else
|
||||
{
|
||||
FAIL(
|
||||
|
@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
@ -68,10 +60,11 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\lifetimes.cpp" />
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
|
@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
@ -68,10 +60,11 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\lifetimes.cpp" />
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
|
@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
@ -70,10 +62,11 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\lifetimes.cpp" />
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
|
@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
@ -70,10 +62,11 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\lifetimes.cpp" />
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
|
@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
@ -69,10 +61,11 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\lifetimes.cpp" />
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
|
@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
@ -69,10 +61,11 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\lifetimes.cpp" />
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
|
@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
@ -71,10 +63,11 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\lifetimes.cpp" />
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
|
@ -1,14 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
@ -71,10 +63,11 @@
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\lifetimes.cpp" />
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
|
89
vs/test_x86_char.vcxproj
Normal file
89
vs/test_x86_char.vcxproj
Normal file
@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{150FA82E-0E9F-4449-82A6-811BFFE6B5FE}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<Import Project="toml++.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TOML_CHAR_8_STRINGS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions Condition="'%(PrecompiledHeader)'=='Use'">USING_PCH=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_dates_and_times.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_floats.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_integers.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_key_value_pairs.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_spec_example.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_strings.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_tables.cpp" />
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tests\tests.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
89
vs/test_x86_char8.vcxproj
Normal file
89
vs/test_x86_char8.vcxproj
Normal file
@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{1ED2F590-1DE8-457D-97BD-38ECF0955F7F}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<Import Project="toml++.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TOML_CHAR_8_STRINGS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions Condition="'%(PrecompiledHeader)'=='Use'">USING_PCH=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_dates_and_times.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_floats.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_integers.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_key_value_pairs.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_spec_example.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_strings.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_tables.cpp" />
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tests\tests.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
91
vs/test_x86_char8_noexcept.vcxproj
Normal file
91
vs/test_x86_char8_noexcept.vcxproj
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{BE980D05-770C-4420-B59B-EAD7A63468D2}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<Import Project="toml++.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TOML_CHAR_8_STRINGS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions Condition="'%(PrecompiledHeader)'=='Use'">USING_PCH=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_dates_and_times.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_floats.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_integers.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_key_value_pairs.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_spec_example.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_strings.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_tables.cpp" />
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tests\tests.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
91
vs/test_x86_char_noexcept.vcxproj
Normal file
91
vs/test_x86_char_noexcept.vcxproj
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{54DD1412-20C0-4700-96D7-3FD445E70996}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<Import Project="toml++.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TOML_CHAR_8_STRINGS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions Condition="'%(PrecompiledHeader)'=='Use'">USING_PCH=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_dates_and_times.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_floats.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_integers.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_key_value_pairs.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_spec_example.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_strings.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_tables.cpp" />
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tests\tests.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
90
vs/test_x86_strict_char.vcxproj
Normal file
90
vs/test_x86_strict_char.vcxproj
Normal file
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{3B05742A-6512-4B11-8842-A1B9D1465B1F}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<Import Project="toml++.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TOML_CHAR_8_STRINGS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>TOML_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions Condition="'%(PrecompiledHeader)'=='Use'">USING_PCH=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_dates_and_times.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_floats.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_integers.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_key_value_pairs.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_spec_example.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_strings.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_tables.cpp" />
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tests\tests.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
90
vs/test_x86_strict_char8.vcxproj
Normal file
90
vs/test_x86_strict_char8.vcxproj
Normal file
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{A4F27C6F-601D-45C0-9F81-7C100BD93B9A}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<Import Project="toml++.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TOML_CHAR_8_STRINGS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>TOML_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions Condition="'%(PrecompiledHeader)'=='Use'">USING_PCH=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_dates_and_times.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_floats.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_integers.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_key_value_pairs.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_spec_example.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_strings.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_tables.cpp" />
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tests\tests.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
92
vs/test_x86_strict_char8_noexcept.vcxproj
Normal file
92
vs/test_x86_strict_char8_noexcept.vcxproj
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{0CAD095A-C9F2-49FC-9C9F-4508498BE488}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<Import Project="toml++.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TOML_CHAR_8_STRINGS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>TOML_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions Condition="'%(PrecompiledHeader)'=='Use'">USING_PCH=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_dates_and_times.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_floats.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_integers.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_key_value_pairs.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_spec_example.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_strings.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_tables.cpp" />
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tests\tests.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
92
vs/test_x86_strict_char_noexcept.vcxproj
Normal file
92
vs/test_x86_strict_char_noexcept.vcxproj
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{0BBEE569-536D-452C-808C-61843FECCC7E}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<Import Project="toml++.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TOML_CHAR_8_STRINGS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>TOML_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions Condition="'%(PrecompiledHeader)'=='Use'">USING_PCH=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
<LocalDebuggerWorkingDirectory>..\tests\</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tests\main.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\manipulating_tables.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_arrays.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_booleans.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_comments.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_dates_and_times.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_floats.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_integers.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_key_value_pairs.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_spec_example.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_strings.cpp" />
|
||||
<ClCompile Include="..\tests\parsing_tables.cpp" />
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tests\tests.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
102
vs/toml++.sln
102
vs/toml++.sln
@ -29,102 +29,104 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parse_file", "parse_file.vc
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toml_to_json_transcoder", "toml_to_json_transcoder.vcxproj", "{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_char", "test_x86_char.vcxproj", "{150FA82E-0E9F-4449-82A6-811BFFE6B5FE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_char_noexcept", "test_x86_char_noexcept.vcxproj", "{54DD1412-20C0-4700-96D7-3FD445E70996}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_char8", "test_x86_char8.vcxproj", "{1ED2F590-1DE8-457D-97BD-38ECF0955F7F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_char8_noexcept", "test_x86_char8_noexcept.vcxproj", "{BE980D05-770C-4420-B59B-EAD7A63468D2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_strict_char", "test_x86_strict_char.vcxproj", "{3B05742A-6512-4B11-8842-A1B9D1465B1F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_strict_char_noexcept", "test_x86_strict_char_noexcept.vcxproj", "{0BBEE569-536D-452C-808C-61843FECCC7E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_strict_char8", "test_x86_strict_char8.vcxproj", "{A4F27C6F-601D-45C0-9F81-7C100BD93B9A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_strict_char8_noexcept", "test_x86_strict_char8_noexcept.vcxproj", "{0CAD095A-C9F2-49FC-9C9F-4508498BE488}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0E287B5A-1168-43FD-B067-F6BE8E182A57}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0E287B5A-1168-43FD-B067-F6BE8E182A57}.Debug|x64.Build.0 = Debug|x64
|
||||
{0E287B5A-1168-43FD-B067-F6BE8E182A57}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{0E287B5A-1168-43FD-B067-F6BE8E182A57}.Debug|x86.Build.0 = Debug|Win32
|
||||
{0E287B5A-1168-43FD-B067-F6BE8E182A57}.Release|x64.ActiveCfg = Release|x64
|
||||
{0E287B5A-1168-43FD-B067-F6BE8E182A57}.Release|x64.Build.0 = Release|x64
|
||||
{0E287B5A-1168-43FD-B067-F6BE8E182A57}.Release|x86.ActiveCfg = Release|Win32
|
||||
{0E287B5A-1168-43FD-B067-F6BE8E182A57}.Release|x86.Build.0 = Release|Win32
|
||||
{54532B93-A2F9-49AC-886E-767A6D78E2F2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{54532B93-A2F9-49AC-886E-767A6D78E2F2}.Debug|x64.Build.0 = Debug|x64
|
||||
{54532B93-A2F9-49AC-886E-767A6D78E2F2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{54532B93-A2F9-49AC-886E-767A6D78E2F2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{54532B93-A2F9-49AC-886E-767A6D78E2F2}.Release|x64.ActiveCfg = Release|x64
|
||||
{54532B93-A2F9-49AC-886E-767A6D78E2F2}.Release|x64.Build.0 = Release|x64
|
||||
{54532B93-A2F9-49AC-886E-767A6D78E2F2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{54532B93-A2F9-49AC-886E-767A6D78E2F2}.Release|x86.Build.0 = Release|Win32
|
||||
{E888E99C-734D-44C4-B917-0AC8D3E2F48F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E888E99C-734D-44C4-B917-0AC8D3E2F48F}.Debug|x64.Build.0 = Debug|x64
|
||||
{E888E99C-734D-44C4-B917-0AC8D3E2F48F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{E888E99C-734D-44C4-B917-0AC8D3E2F48F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{E888E99C-734D-44C4-B917-0AC8D3E2F48F}.Release|x64.ActiveCfg = Release|x64
|
||||
{E888E99C-734D-44C4-B917-0AC8D3E2F48F}.Release|x64.Build.0 = Release|x64
|
||||
{E888E99C-734D-44C4-B917-0AC8D3E2F48F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{E888E99C-734D-44C4-B917-0AC8D3E2F48F}.Release|x86.Build.0 = Release|Win32
|
||||
{3E4018CE-CCA2-48E6-B11E-732A1B59C672}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3E4018CE-CCA2-48E6-B11E-732A1B59C672}.Debug|x64.Build.0 = Debug|x64
|
||||
{3E4018CE-CCA2-48E6-B11E-732A1B59C672}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3E4018CE-CCA2-48E6-B11E-732A1B59C672}.Debug|x86.Build.0 = Debug|Win32
|
||||
{3E4018CE-CCA2-48E6-B11E-732A1B59C672}.Release|x64.ActiveCfg = Release|x64
|
||||
{3E4018CE-CCA2-48E6-B11E-732A1B59C672}.Release|x64.Build.0 = Release|x64
|
||||
{3E4018CE-CCA2-48E6-B11E-732A1B59C672}.Release|x86.ActiveCfg = Release|Win32
|
||||
{3E4018CE-CCA2-48E6-B11E-732A1B59C672}.Release|x86.Build.0 = Release|Win32
|
||||
{F094F967-42B5-4AD7-AB44-EA044CD9837E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F094F967-42B5-4AD7-AB44-EA044CD9837E}.Debug|x64.Build.0 = Debug|x64
|
||||
{F094F967-42B5-4AD7-AB44-EA044CD9837E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{F094F967-42B5-4AD7-AB44-EA044CD9837E}.Debug|x86.Build.0 = Debug|Win32
|
||||
{F094F967-42B5-4AD7-AB44-EA044CD9837E}.Release|x64.ActiveCfg = Release|x64
|
||||
{F094F967-42B5-4AD7-AB44-EA044CD9837E}.Release|x64.Build.0 = Release|x64
|
||||
{F094F967-42B5-4AD7-AB44-EA044CD9837E}.Release|x86.ActiveCfg = Release|Win32
|
||||
{F094F967-42B5-4AD7-AB44-EA044CD9837E}.Release|x86.Build.0 = Release|Win32
|
||||
{89FF67C6-94C0-4C46-8411-7549A36584FB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{89FF67C6-94C0-4C46-8411-7549A36584FB}.Debug|x64.Build.0 = Debug|x64
|
||||
{89FF67C6-94C0-4C46-8411-7549A36584FB}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{89FF67C6-94C0-4C46-8411-7549A36584FB}.Debug|x86.Build.0 = Debug|Win32
|
||||
{89FF67C6-94C0-4C46-8411-7549A36584FB}.Release|x64.ActiveCfg = Release|x64
|
||||
{89FF67C6-94C0-4C46-8411-7549A36584FB}.Release|x64.Build.0 = Release|x64
|
||||
{89FF67C6-94C0-4C46-8411-7549A36584FB}.Release|x86.ActiveCfg = Release|Win32
|
||||
{89FF67C6-94C0-4C46-8411-7549A36584FB}.Release|x86.Build.0 = Release|Win32
|
||||
{F05F8C1B-7E23-4147-901E-AD91092E5752}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F05F8C1B-7E23-4147-901E-AD91092E5752}.Debug|x64.Build.0 = Debug|x64
|
||||
{F05F8C1B-7E23-4147-901E-AD91092E5752}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{F05F8C1B-7E23-4147-901E-AD91092E5752}.Debug|x86.Build.0 = Debug|Win32
|
||||
{F05F8C1B-7E23-4147-901E-AD91092E5752}.Release|x64.ActiveCfg = Release|x64
|
||||
{F05F8C1B-7E23-4147-901E-AD91092E5752}.Release|x64.Build.0 = Release|x64
|
||||
{F05F8C1B-7E23-4147-901E-AD91092E5752}.Release|x86.ActiveCfg = Release|Win32
|
||||
{F05F8C1B-7E23-4147-901E-AD91092E5752}.Release|x86.Build.0 = Release|Win32
|
||||
{EAC419E9-0C72-4625-B2B9-E879F697021A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{EAC419E9-0C72-4625-B2B9-E879F697021A}.Debug|x64.Build.0 = Debug|x64
|
||||
{EAC419E9-0C72-4625-B2B9-E879F697021A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{EAC419E9-0C72-4625-B2B9-E879F697021A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{EAC419E9-0C72-4625-B2B9-E879F697021A}.Release|x64.ActiveCfg = Release|x64
|
||||
{EAC419E9-0C72-4625-B2B9-E879F697021A}.Release|x64.Build.0 = Release|x64
|
||||
{EAC419E9-0C72-4625-B2B9-E879F697021A}.Release|x86.ActiveCfg = Release|Win32
|
||||
{EAC419E9-0C72-4625-B2B9-E879F697021A}.Release|x86.Build.0 = Release|Win32
|
||||
{9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Debug|x64.Build.0 = Debug|x64
|
||||
{9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Debug|x86.Build.0 = Debug|Win32
|
||||
{9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Release|x64.ActiveCfg = Release|x64
|
||||
{9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Release|x64.Build.0 = Release|x64
|
||||
{9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Release|x86.ActiveCfg = Release|Win32
|
||||
{9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Release|x86.Build.0 = Release|Win32
|
||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|x64.Build.0 = Debug|x64
|
||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|x86.Build.0 = Debug|Win32
|
||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|x64.ActiveCfg = Release|x64
|
||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|x64.Build.0 = Release|x64
|
||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|x86.ActiveCfg = Release|Win32
|
||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|x86.Build.0 = Release|Win32
|
||||
{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Debug|x64.Build.0 = Debug|x64
|
||||
{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Debug|x86.Build.0 = Debug|Win32
|
||||
{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Release|x64.ActiveCfg = Release|x64
|
||||
{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Release|x64.Build.0 = Release|x64
|
||||
{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Release|x86.ActiveCfg = Release|Win32
|
||||
{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Release|x86.Build.0 = Release|Win32
|
||||
{150FA82E-0E9F-4449-82A6-811BFFE6B5FE}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{150FA82E-0E9F-4449-82A6-811BFFE6B5FE}.Debug|x64.Build.0 = Debug|Win32
|
||||
{150FA82E-0E9F-4449-82A6-811BFFE6B5FE}.Release|x64.ActiveCfg = Release|Win32
|
||||
{150FA82E-0E9F-4449-82A6-811BFFE6B5FE}.Release|x64.Build.0 = Release|Win32
|
||||
{54DD1412-20C0-4700-96D7-3FD445E70996}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{54DD1412-20C0-4700-96D7-3FD445E70996}.Debug|x64.Build.0 = Debug|Win32
|
||||
{54DD1412-20C0-4700-96D7-3FD445E70996}.Release|x64.ActiveCfg = Release|Win32
|
||||
{54DD1412-20C0-4700-96D7-3FD445E70996}.Release|x64.Build.0 = Release|Win32
|
||||
{1ED2F590-1DE8-457D-97BD-38ECF0955F7F}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{1ED2F590-1DE8-457D-97BD-38ECF0955F7F}.Debug|x64.Build.0 = Debug|Win32
|
||||
{1ED2F590-1DE8-457D-97BD-38ECF0955F7F}.Release|x64.ActiveCfg = Release|Win32
|
||||
{1ED2F590-1DE8-457D-97BD-38ECF0955F7F}.Release|x64.Build.0 = Release|Win32
|
||||
{BE980D05-770C-4420-B59B-EAD7A63468D2}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{BE980D05-770C-4420-B59B-EAD7A63468D2}.Debug|x64.Build.0 = Debug|Win32
|
||||
{BE980D05-770C-4420-B59B-EAD7A63468D2}.Release|x64.ActiveCfg = Release|Win32
|
||||
{BE980D05-770C-4420-B59B-EAD7A63468D2}.Release|x64.Build.0 = Release|Win32
|
||||
{3B05742A-6512-4B11-8842-A1B9D1465B1F}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{3B05742A-6512-4B11-8842-A1B9D1465B1F}.Debug|x64.Build.0 = Debug|Win32
|
||||
{3B05742A-6512-4B11-8842-A1B9D1465B1F}.Release|x64.ActiveCfg = Release|Win32
|
||||
{3B05742A-6512-4B11-8842-A1B9D1465B1F}.Release|x64.Build.0 = Release|Win32
|
||||
{0BBEE569-536D-452C-808C-61843FECCC7E}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{0BBEE569-536D-452C-808C-61843FECCC7E}.Debug|x64.Build.0 = Debug|Win32
|
||||
{0BBEE569-536D-452C-808C-61843FECCC7E}.Release|x64.ActiveCfg = Release|Win32
|
||||
{0BBEE569-536D-452C-808C-61843FECCC7E}.Release|x64.Build.0 = Release|Win32
|
||||
{A4F27C6F-601D-45C0-9F81-7C100BD93B9A}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{A4F27C6F-601D-45C0-9F81-7C100BD93B9A}.Debug|x64.Build.0 = Debug|Win32
|
||||
{A4F27C6F-601D-45C0-9F81-7C100BD93B9A}.Release|x64.ActiveCfg = Release|Win32
|
||||
{A4F27C6F-601D-45C0-9F81-7C100BD93B9A}.Release|x64.Build.0 = Release|Win32
|
||||
{0CAD095A-C9F2-49FC-9C9F-4508498BE488}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{0CAD095A-C9F2-49FC-9C9F-4508498BE488}.Debug|x64.Build.0 = Debug|Win32
|
||||
{0CAD095A-C9F2-49FC-9C9F-4508498BE488}.Release|x64.ActiveCfg = Release|Win32
|
||||
{0CAD095A-C9F2-49FC-9C9F-4508498BE488}.Release|x64.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -140,6 +142,14 @@ Global
|
||||
{9ADB61D3-FDFA-4A9C-A34F-663007BB70F6} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735}
|
||||
{BE34AA99-BEE6-4B50-B237-217E7C88FCB5} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735}
|
||||
{150FA82E-0E9F-4449-82A6-811BFFE6B5FE} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||
{54DD1412-20C0-4700-96D7-3FD445E70996} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||
{1ED2F590-1DE8-457D-97BD-38ECF0955F7F} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||
{BE980D05-770C-4420-B59B-EAD7A63468D2} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||
{3B05742A-6512-4B11-8842-A1B9D1465B1F} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||
{0BBEE569-536D-452C-808C-61843FECCC7E} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||
{A4F27C6F-601D-45C0-9F81-7C100BD93B9A} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||
{0CAD095A-C9F2-49FC-9C9F-4508498BE488} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0926DDCC-88CD-4839-A82D-D9B99E02A0B1}
|
||||
|
Loading…
Reference in New Issue
Block a user