Merge branch 'master' into std-filesystem

This commit is contained in:
ToruNiina
2020-06-06 17:25:26 +09:00
6 changed files with 45 additions and 92 deletions

View File

@@ -12,7 +12,7 @@ jobs:
command: | command: |
g++ --version g++ --version
cd tests/ cd tests/
g++ -std=c++11 -O2 -Wall -Wextra -Werror -DTOML11_COLORIZE_ERROR_MESSAGE -I../ check_toml_test.cpp -o check_toml_test g++ -std=c++11 -O2 -Wall -Wextra -Werror -DTOML11_DISALLOW_HETEROGENEOUS_ARRAYS -I../ check_toml_test.cpp -o check_toml_test
go get github.com/BurntSushi/toml-test go get github.com/BurntSushi/toml-test
$GOPATH/bin/toml-test ./check_toml_test $GOPATH/bin/toml-test ./check_toml_test
test_serialization: test_serialization:
@@ -24,7 +24,7 @@ jobs:
command: | command: |
g++ --version g++ --version
cd tests/ cd tests/
g++ -std=c++11 -O2 -Wall -Wextra -Wpedantic -Werror -DTOML11_COLORIZE_ERROR_MESSAGE -I../ check_serialization.cpp -o check_serialization g++ -std=c++11 -O2 -Wall -Wextra -Wpedantic -Werror -DTOML11_DISALLOW_HETEROGENEOUS_ARRAYS -I../ check_serialization.cpp -o check_serialization
git clone https://github.com/BurntSushi/toml-test.git git clone https://github.com/BurntSushi/toml-test.git
cp check_serialization toml-test/tests/valid cp check_serialization toml-test/tests/valid
cd toml-test/tests/valid cd toml-test/tests/valid
@@ -47,7 +47,7 @@ jobs:
command: | command: |
g++ --version g++ --version
cd tests/ cd tests/
g++ -std=c++11 -O2 -Wall -Wextra -Wpedantic -Werror -DTOML11_COLORIZE_ERROR_MESSAGE -I../ check.cpp -o check g++ -std=c++11 -O2 -Wall -Wextra -Wpedantic -Werror -DTOML11_DISALLOW_HETEROGENEOUS_ARRAYS -I../ check.cpp -o check
git clone https://github.com/BurntSushi/toml-test.git git clone https://github.com/BurntSushi/toml-test.git
cp check toml-test/tests/invalid cp check toml-test/tests/invalid
cp check toml-test/tests/valid cp check toml-test/tests/valid

View File

@@ -10,8 +10,7 @@ toml11
toml11 is a C++11 (or later) header-only toml parser/encoder depending only on C++ standard library. toml11 is a C++11 (or later) header-only toml parser/encoder depending only on C++ standard library.
- It is compatible to the latest version of [TOML v0.5.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md). - It is compatible to the latest version of [TOML v1.0.0-rc.1](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v1.0.0-rc.1.md).
- It optionally supports the [unreleased features](#unreleased-toml-features) in the master branch of toml-lang/toml.
- It is one of the most TOML standard compliant libraries, tested with [the language agnostic test suite for TOML parsers by BurntSushi](https://github.com/BurntSushi/toml-test). - It is one of the most TOML standard compliant libraries, tested with [the language agnostic test suite for TOML parsers by BurntSushi](https://github.com/BurntSushi/toml-test).
- It shows highly informative error messages. You can see the error messages about invalid files at [CircleCI](https://circleci.com/gh/ToruNiina/toml11). - It shows highly informative error messages. You can see the error messages about invalid files at [CircleCI](https://circleci.com/gh/ToruNiina/toml11).
- It has configurable container. You can use any random-access containers and key-value maps as backend containers. - It has configurable container. You can use any random-access containers and key-value maps as backend containers.
@@ -267,11 +266,11 @@ shape = "round"
``` cpp ``` cpp
const auto data = toml::parse("fruit.toml"); const auto data = toml::parse("fruit.toml");
const auto& fruit = toml::find(data, "fruit"); const auto& fruit = toml::find(data, "fruit");
const auto name = toml::find<std::string>(fruit, "apple"); const auto name = toml::find<std::string>(fruit, "name");
const auto& physical = toml::find(fruit, "physical"); const auto& physical = toml::find(fruit, "physical");
const auto color = toml::find<std::string>(fruit, "color"); const auto color = toml::find<std::string>(physical, "color");
const auto shape = toml::find<std::string>(fruit, "shape"); const auto shape = toml::find<std::string>(physical, "shape");
``` ```
Here, variable `fruit` is a `toml::value` and can be used as the first argument Here, variable `fruit` is a `toml::value` and can be used as the first argument
@@ -1652,13 +1651,8 @@ not capable of representing a Local Time independent from a specific day.
## Unreleased TOML features ## Unreleased TOML features
There are some unreleased features in toml-lang/toml:master. Since TOML v1.0.0-rc.1 has been released, those features are now activated by
Currently, the following features are available after defining default. We no longer need to define `TOML11_USE_UNRELEASED_FEATURES`.
`TOML11_USE_UNRELEASED_TOML_FEATURES` macro flag.
To use those features, `#define` `TOML11_USE_UNRELEASED_TOML_FEATURES` before
including `toml.hpp` or pass `-DTOML11_USE_UNRELEASED_TOML_FEATURES` to your
compiler.
- Leading zeroes in exponent parts of floats are permitted. - Leading zeroes in exponent parts of floats are permitted.
- e.g. `1.0e+01`, `5e+05` - e.g. `1.0e+01`, `5e+05`
@@ -1668,10 +1662,10 @@ compiler.
- Allow heterogeneous arrays - Allow heterogeneous arrays
- [toml-lang/toml/PR/676](https://github.com/toml-lang/toml/pull/676) - [toml-lang/toml/PR/676](https://github.com/toml-lang/toml/pull/676)
### Note about heterogeneous arrays ## Note about heterogeneous arrays
Although `toml::parse` allows heterogeneous arrays, constructor of `toml::value` Although `toml::parse` allows heterogeneous arrays, constructor of `toml::value`
does not. does not. Here the reason is explained.
```cpp ```cpp
// this won't be compiled // this won't be compiled
@@ -1680,8 +1674,10 @@ toml::value v{
} }
``` ```
There is a workaround for this issue. By explicitly converting values into There is a workaround for this. By explicitly converting values into
`toml::value`, you can initialize `toml::value` with a heterogeneous array. `toml::value`, you can initialize `toml::value` with a heterogeneous array.
Also, you can first initialize a `toml::value` with an array and then
`push_back` into it.
```cpp ```cpp
// OK! // OK!
@@ -1689,6 +1685,17 @@ toml::value v{
toml::value("foo"), toml::value(3.14), toml::value(42), toml::value("foo"), toml::value(3.14), toml::value(42),
toml::value{1,2,3,4,5}, toml::value{{"key", "value"}} toml::value{1,2,3,4,5}, toml::value{{"key", "value"}}
} }
// OK!
toml::value v(toml::array{});
v.push_back("foo");
v.push_back(3.14);
// OK!
toml::array a;
a.push_back("foo");
a.push_back(3.14);
toml::value v(std::move(a));
``` ```
The reason why the first example is not allowed is the following. The reason why the first example is not allowed is the following.
@@ -1717,15 +1724,14 @@ This means that the above C++ code makes constructor's overload resolution
ambiguous. So a constructor that allows both "table as an initializer-list" and ambiguous. So a constructor that allows both "table as an initializer-list" and
"heterogeneous array as an initializer-list" cannot be implemented. "heterogeneous array as an initializer-list" cannot be implemented.
Thus, although it is painful, you need to explicitly cast values into Thus, although it is painful, we need to explicitly cast values into
`toml::value` when you initialize heterogeneous array in C++ code. `toml::value` when you initialize heterogeneous array in a C++ code.
```cpp ```cpp
// You need to do this when you want to initialize hetero array.
toml::value v{ toml::value v{
toml::value("foo"), toml::value(3.14), toml::value(42), toml::value("foo"), toml::value(3.14), toml::value(42),
toml::value{1,2,3,4,5}, toml::value{{"key", "value"}} toml::value{1,2,3,4,5}, toml::value{{"key", "value"}}
} };
``` ```
## Breaking Changes from v2 ## Breaking Changes from v2

View File

@@ -80,13 +80,13 @@ BOOST_AUTO_TEST_CASE(test_detect_conflicting_value)
BOOST_AUTO_TEST_CASE(test_detect_inhomogeneous_array) BOOST_AUTO_TEST_CASE(test_detect_inhomogeneous_array)
{ {
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES #ifdef TOML11_DISALLOW_HETEROGENEOUS_ARRAYS
BOOST_TEST_MESSAGE("heterogeneous array will be allowed in the next release");
#else
std::istringstream stream(std::string( std::istringstream stream(std::string(
"a = [1, 1.0]\n" "a = [1, 1.0]\n"
)); ));
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
#else
BOOST_TEST_MESSAGE("After v1.0.0-rc.1, heterogeneous arrays are allowed");
#endif #endif
} }

View File

@@ -69,15 +69,8 @@ using lex_zero_prefixable_int = sequence<lex_digit, repeat<either<lex_digit,
using lex_fractional_part = sequence<character<'.'>, lex_zero_prefixable_int>; using lex_fractional_part = sequence<character<'.'>, lex_zero_prefixable_int>;
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
// use toml-lang/toml HEAD
using lex_exponent_part = sequence<either<character<'e'>, character<'E'>>, using lex_exponent_part = sequence<either<character<'e'>, character<'E'>>,
maybe<lex_sign>, lex_zero_prefixable_int>; maybe<lex_sign>, lex_zero_prefixable_int>;
#else
// strictly TOML v0.5.0
using lex_exponent_part = sequence<either<character<'e'>, character<'E'>>,
lex_dec_int>;
#endif
using lex_float = either<lex_special_float, using lex_float = either<lex_special_float,
sequence<lex_dec_int, either<lex_exponent_part, sequence<lex_dec_int, either<lex_exponent_part,
@@ -125,17 +118,11 @@ using lex_local_time = lex_partial_time;
// =========================================================================== // ===========================================================================
using lex_quotation_mark = character<'"'>; using lex_quotation_mark = character<'"'>;
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
using lex_basic_unescaped = exclude<either<in_range<0x00, 0x08>, // 0x09 (tab) using lex_basic_unescaped = exclude<either<in_range<0x00, 0x08>, // 0x09 (tab)
in_range<0x0a, 0x1F>, // is allowed in_range<0x0a, 0x1F>, // is allowed
character<0x22>, character<0x5C>, character<0x22>, character<0x5C>,
character<0x7F>>>; character<0x7F>>>;
#else
using lex_basic_unescaped = exclude<either<in_range<0x00, 0x1F>,
character<0x22>, character<0x5C>,
character<0x7F>>>;
#endif
using lex_escape = character<'\\'>; using lex_escape = character<'\\'>;
using lex_escape_unicode_short = sequence<character<'u'>, using lex_escape_unicode_short = sequence<character<'u'>,
repeat<lex_hex_dig, exactly<4>>>; repeat<lex_hex_dig, exactly<4>>>;
@@ -183,12 +170,6 @@ using lex_basic_string = sequence<lex_quotation_mark,
// In parse_ml_basic_string() function, the trailing `"`s will be attached to // In parse_ml_basic_string() function, the trailing `"`s will be attached to
// the string body. // the string body.
// //
// Note: This feature is a "clarification". Therefore this change is considered
// as a spec that has been defined since the time when the multi-line
// basic string was introduced. Although it is a post-v0.5.0 changes,
// this change will be activated regardless of the flag,
// `TOML11_USE_UNRELEASED_TOML_FEATURES`.
//
using lex_ml_basic_string_delim = repeat<lex_quotation_mark, exactly<3>>; using lex_ml_basic_string_delim = repeat<lex_quotation_mark, exactly<3>>;
using lex_ml_basic_string_open = lex_ml_basic_string_delim; using lex_ml_basic_string_open = lex_ml_basic_string_delim;
using lex_ml_basic_string_close = sequence< using lex_ml_basic_string_close = sequence<
@@ -196,18 +177,11 @@ using lex_ml_basic_string_close = sequence<
maybe<lex_quotation_mark>, maybe<lex_quotation_mark> maybe<lex_quotation_mark>, maybe<lex_quotation_mark>
>; >;
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
using lex_ml_basic_unescaped = exclude<either<in_range<0x00, 0x08>, // 0x09 using lex_ml_basic_unescaped = exclude<either<in_range<0x00, 0x08>, // 0x09
in_range<0x0a, 0x1F>, // is tab in_range<0x0a, 0x1F>, // is tab
character<0x5C>, // backslash character<0x5C>, // backslash
character<0x7F>, // DEL character<0x7F>, // DEL
lex_ml_basic_string_delim>>; lex_ml_basic_string_delim>>;
#else // TOML v0.5.0
using lex_ml_basic_unescaped = exclude<either<in_range<0x00,0x1F>,
character<0x5C>,
character<0x7F>,
lex_ml_basic_string_delim>>;
#endif
using lex_ml_basic_escaped_newline = sequence< using lex_ml_basic_escaped_newline = sequence<
lex_escape, maybe<lex_ws>, lex_newline, lex_escape, maybe<lex_ws>, lex_newline,

View File

@@ -740,7 +740,13 @@ parse_local_time(location<Container>& loc)
case 0: break; case 0: break;
default: break; default: break;
} }
if(sf.size() >= 6) if(sf.size() >= 9)
{
time.millisecond = from_string<std::uint16_t>(sf.substr(0, 3), 0u);
time.microsecond = from_string<std::uint16_t>(sf.substr(3, 3), 0u);
time.nanosecond = from_string<std::uint16_t>(sf.substr(6, 3), 0u);
}
else if(sf.size() >= 6)
{ {
time.millisecond = from_string<std::uint16_t>(sf.substr(0, 3), 0u); time.millisecond = from_string<std::uint16_t>(sf.substr(0, 3), 0u);
time.microsecond = from_string<std::uint16_t>(sf.substr(3, 3), 0u); time.microsecond = from_string<std::uint16_t>(sf.substr(3, 3), 0u);
@@ -984,7 +990,12 @@ parse_array(location<Container>& loc)
if(auto val = parse_value<value_type>(loc)) if(auto val = parse_value<value_type>(loc))
{ {
#ifndef TOML11_USE_UNRELEASED_TOML_FEATURES // After TOML v1.0.0-rc.1, array becomes to be able to have values
// with different types. So here we will omit this by default.
//
// But some of the test-suite checks if the parser accepts a hetero-
// geneous arrays, so we keep this for a while.
#ifdef TOML11_DISALLOW_HETEROGENEOUS_ARRAYS
if(!retval.empty() && retval.front().type() != val.as_ok().type()) if(!retval.empty() && retval.front().type() != val.as_ok().type())
{ {
auto array_start_loc = loc; auto array_start_loc = loc;
@@ -1396,9 +1407,6 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
// According to toml-lang/toml:36d3091b3 "Clarify that inline // According to toml-lang/toml:36d3091b3 "Clarify that inline
// tables are immutable", check if it adds key-value pair to an // tables are immutable", check if it adds key-value pair to an
// inline table. // inline table.
// This is one of the unreleased (after-0.5.0) toml feature.
// But this is marked as "Clarify", so TOML-lang intended that
// inline tables are immutable in all version.
{ {
// here, if the value is a (multi-line) table, the region // here, if the value is a (multi-line) table, the region
// should be something like `[table-name]`. // should be something like `[table-name]`.

View File

@@ -135,43 +135,8 @@ struct serializer
{ {
// the resulting value does not have any float specific part! // the resulting value does not have any float specific part!
token += ".0"; token += ".0";
return token;
}
if(!has_exponent)
{
return token; // there is no exponent part. just return it.
}
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
// Although currently it is not released yet as a tagged version,
// TOML will allow zero-prefix in an exponent part, such as `1.234e+01`.
// ```toml
// num1 = 1.234e+1 # OK in TOML v0.5.0
// num2 = 1.234e+01 # error in TOML v0.5.0 but will be allowed soon
// ```
// To avoid `e+01`, the following `else` section removes the zero
// prefixes in the exponent part.
// If the feature is activated, it can be skipped.
return token;
#else
// zero-prefix in an exponent is NOT allowed in TOML v0.5.0.
// remove it if it exists.
bool sign_exists = false;
std::size_t zero_prefix = 0;
for(auto iter = std::next(e), iend = token.cend(); iter != iend; ++iter)
{
if(*iter == '+' || *iter == '-'){sign_exists = true; continue;}
if(*iter == '0'){zero_prefix += 1;}
else {break;}
}
if(zero_prefix != 0)
{
const auto offset = std::distance(token.cbegin(), e) +
(sign_exists ? 2 : 1);
token.erase(static_cast<typename std::string::size_type>(offset),
zero_prefix);
} }
return token; return token;
#endif
} }
std::string operator()(const string_type& s) const std::string operator()(const string_type& s) const
{ {