Merge branch 'master' into allow-comment-before-comma

This commit is contained in:
ToruNiina
2020-09-19 18:10:45 +09:00
15 changed files with 270 additions and 92 deletions

View File

@@ -9,10 +9,13 @@ jobs:
matrix: matrix:
# g++-4.8 and 4.9 are tested on Travis.CI. # g++-4.8 and 4.9 are tested on Travis.CI.
compiler: ['g++-9', 'g++-8', 'g++-7', 'g++-6', 'g++-5'] compiler: ['g++-9', 'g++-8', 'g++-7', 'g++-6', 'g++-5']
standard: ['11', '14', '17'] standard: ['11', '14', '17', '20']
exclude: exclude:
- {compiler: 'g++-5', standard: '17'} - {compiler: 'g++-5', standard: '17'}
- {compiler: 'g++-6', standard: '17'} - {compiler: 'g++-6', standard: '17'}
- {compiler: 'g++-5', standard: '20'}
- {compiler: 'g++-6', standard: '20'}
- {compiler: 'g++-7', standard: '20'}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
@@ -31,10 +34,10 @@ jobs:
- name: Configure - name: Configure
run: | run: |
mkdir build && cd build mkdir build && cd build
if [[ "${{ matrix.compiler }}" == "g++-8" && "${{ matrix.standard }}" == "17" ]] ; then if [[ "${{ matrix.compiler }}" == "g++-8" && ( "${{ matrix.standard }}" == "17" || "${{ matrix.standard }}" == "20" ) ]] ; then
cmake .. -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_REQUIRE_FILESYSTEM_LIBRARY=ON cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_REQUIRE_FILESYSTEM_LIBRARY=ON
else else
cmake .. -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }}
fi fi
- name: Build - name: Build
run: | run: |
@@ -47,11 +50,14 @@ jobs:
strategy: strategy:
matrix: matrix:
compiler: ['10', '9', '8', '7', '6.0', '5.0', '4.0', '3.9'] compiler: ['10', '9', '8', '7', '6.0', '5.0', '4.0', '3.9']
standard: ['11', '14', '17'] standard: ['11', '14', '17', '20']
exclude: exclude:
- {compiler: '3.9', standard: '17'} - {compiler: '3.9', standard: '17'}
- {compiler: '4.0', standard: '17'} - {compiler: '4.0', standard: '17'}
- {compiler: '5.0', standard: '17'} - {compiler: '5.0', standard: '17'}
- {compiler: '3.9', standard: '20'}
- {compiler: '4.0', standard: '20'}
- {compiler: '5.0', standard: '20'}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
@@ -70,7 +76,7 @@ jobs:
- name: Configure - name: Configure
run: | run: |
mkdir build && cd build mkdir build && cd build
cmake .. -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_COMPILER=clang++-${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }}
- name: Build - name: Build
run: | run: |
cd build && cmake --build . cd build && cmake --build .
@@ -81,7 +87,7 @@ jobs:
runs-on: windows-2019 runs-on: windows-2019
strategy: strategy:
matrix: matrix:
standard: ['11', '14', '17'] standard: ['11', '14', '17', '20']
config: ['Release', 'Debug'] config: ['Release', 'Debug']
steps: steps:
- name: Checkout - name: Checkout
@@ -92,9 +98,10 @@ jobs:
- name: Configure - name: Configure
shell: cmd shell: cmd
run: | run: |
file --mime-encoding tests/test_literals.cpp
mkdir build mkdir build
cd build cd build
cmake ../ -G "NMake Makefiles" -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DBoost_ADDITIONAL_VERSIONS=1.72.0 -DBoost_USE_MULTITHREADED=ON -DBoost_ARCHITECTURE=-x64 -DBoost_NO_BOOST_CMAKE=ON -DBOOST_ROOT=%BOOST_ROOT_1_72_0% cmake ../ -G "NMake Makefiles" -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DBoost_ADDITIONAL_VERSIONS=1.72.0 -DBoost_USE_MULTITHREADED=ON -DBoost_ARCHITECTURE=-x64 -DBoost_NO_BOOST_CMAKE=ON -DBOOST_ROOT=%BOOST_ROOT_1_72_0%
- name: Build - name: Build
working-directory: ./build working-directory: ./build
run: | run: |
@@ -102,6 +109,7 @@ jobs:
- name: Test - name: Test
working-directory: ./build working-directory: ./build
run: | run: |
./tests/test_literals --log_level=all
file --mime-encoding tests/toml/tests/example.toml file --mime-encoding tests/toml/tests/example.toml
file --mime-encoding tests/toml/tests/fruit.toml file --mime-encoding tests/toml/tests/fruit.toml
file --mime-encoding tests/toml/tests/hard_example.toml file --mime-encoding tests/toml/tests/hard_example.toml

View File

@@ -332,6 +332,6 @@ script:
- cd build - cd build
- echo "COMPILER = ${COMPILER}" - echo "COMPILER = ${COMPILER}"
- echo "CXX_STANDARD = ${CXX_STANDARD}" - echo "CXX_STANDARD = ${CXX_STANDARD}"
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_CXX_STANDARD=$CXX_STANDARD -DTOML11_REQUIRE_FILESYSTEM_LIBRARY=${REQUIRE_FILESYSTEM_LIBRARY} -DTOML11_USE_UNRELEASED_TOML_FEATURES=${TOML_HEAD} -Dtoml11_TEST_WITH_ASAN=${WITH_ASAN} -Dtoml11_TEST_WITH_UBSAN=${WITH_UBSAN} .. - cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_CXX_STANDARD=$CXX_STANDARD -DTOML11_REQUIRE_FILESYSTEM_LIBRARY=${REQUIRE_FILESYSTEM_LIBRARY} -Dtoml11_BUILD_TEST=ON -DTOML11_USE_UNRELEASED_TOML_FEATURES=${TOML_HEAD} -Dtoml11_TEST_WITH_ASAN=${WITH_ASAN} -Dtoml11_TEST_WITH_UBSAN=${WITH_UBSAN} ..
- make - make
- ctest --output-on-failure - ctest --output-on-failure

View File

@@ -3,7 +3,7 @@ enable_testing()
project(toml11 VERSION 3.5.0) project(toml11 VERSION 3.5.0)
option(toml11_BUILD_TEST "Build toml tests" ON) option(toml11_BUILD_TEST "Build toml tests" OFF)
option(toml11_TEST_WITH_ASAN "use LLVM address sanitizer" OFF) option(toml11_TEST_WITH_ASAN "use LLVM address sanitizer" OFF)
option(toml11_TEST_WITH_UBSAN "use LLVM undefined behavior sanitizer" OFF) option(toml11_TEST_WITH_UBSAN "use LLVM undefined behavior sanitizer" OFF)
@@ -37,6 +37,11 @@ else()
endif() endif()
endif() endif()
if(MSVC)
add_definitions("/Zc:__cplusplus") # define __cplusplus value correctly
add_definitions("/utf-8") # enable to use u8"" literal
endif()
# Set some common directories # Set some common directories
include(GNUInstallDirs) include(GNUInstallDirs)
set(toml11_install_cmake_dir ${CMAKE_INSTALL_LIBDIR}/cmake/toml11) set(toml11_install_cmake_dir ${CMAKE_INSTALL_LIBDIR}/cmake/toml11)

View File

@@ -95,7 +95,7 @@ int main()
Just include the file after adding it to the include path. Just include the file after adding it to the include path.
```cpp ```cpp
#include <toml11/toml.hpp> // that's all! now you can use it. #include <toml.hpp> // that's all! now you can use it.
#include <iostream> #include <iostream>
int main() int main()
@@ -1798,7 +1798,7 @@ for automating test set fetching!).
```sh ```sh
$ mkdir build $ mkdir build
$ cd build $ cd build
$ cmake .. $ cmake .. -Dtoml11_BUILD_TEST=ON
$ make $ make
$ make test $ make test
``` ```

View File

@@ -17,7 +17,7 @@ build_script:
- cd C:\toml11 - cd C:\toml11
- mkdir build - mkdir build
- cd build - cd build
- cmake -G"%generator%" -DBOOST_ROOT=C:/Libraries/boost_1_69_0 .. - cmake -G"%generator%" -DBOOST_ROOT=C:/Libraries/boost_1_69_0 -Dtoml11_BUILD_TEST=ON ..
- cmake --build . --config "%configuration%" - cmake --build . --config "%configuration%"
- file --mime-encoding tests/toml/tests/hard_example_unicode.toml - file --mime-encoding tests/toml/tests/hard_example_unicode.toml

View File

@@ -182,7 +182,7 @@ foreach(TEST_NAME ${TEST_NAMES})
target_link_libraries(${TEST_NAME} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} toml11::toml11) target_link_libraries(${TEST_NAME} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} toml11::toml11)
# to compile tests with <filesystem>... # to compile tests with <filesystem>...
if(TOML11_REQUIRE_FILESYSTEM_LIBRARY AND ${CMAKE_CXX_STANDARD} STREQUAL "17") if(TOML11_REQUIRE_FILESYSTEM_LIBRARY)
if(TOML11_WITH_LIBCXX_LIBRARY) if(TOML11_WITH_LIBCXX_LIBRARY)
target_link_libraries(${TEST_NAME} "c++fs") target_link_libraries(${TEST_NAME} "c++fs")
else() else()

View File

@@ -11,7 +11,7 @@
BOOST_AUTO_TEST_CASE(test_comment_before) BOOST_AUTO_TEST_CASE(test_comment_before)
{ {
{ {
const std::string file = u8R"( const std::string file = R"(
# comment for a. # comment for a.
a = 42 a = 42
# comment for b. # comment for b.
@@ -24,12 +24,12 @@ BOOST_AUTO_TEST_CASE(test_comment_before)
const auto& b = toml::find(v, "b"); const auto& b = toml::find(v, "b");
BOOST_TEST(a.comments().size() == 1u); BOOST_TEST(a.comments().size() == 1u);
BOOST_TEST(a.comments().front() == u8" comment for a."); BOOST_TEST(a.comments().front() == " comment for a.");
BOOST_TEST(b.comments().size() == 1u); BOOST_TEST(b.comments().size() == 1u);
BOOST_TEST(b.comments().front() == u8" comment for b."); BOOST_TEST(b.comments().front() == " comment for b.");
} }
{ {
const std::string file = u8R"( const std::string file = R"(
# comment for a. # comment for a.
# another comment for a. # another comment for a.
a = 42 a = 42
@@ -45,18 +45,18 @@ BOOST_AUTO_TEST_CASE(test_comment_before)
const auto& b = toml::find(v, "b"); const auto& b = toml::find(v, "b");
BOOST_TEST(a.comments().size() == 2u); BOOST_TEST(a.comments().size() == 2u);
BOOST_TEST(a.comments().front() == u8" comment for a."); BOOST_TEST(a.comments().front() == " comment for a.");
BOOST_TEST(a.comments().back() == u8" another comment for a."); BOOST_TEST(a.comments().back() == " another comment for a.");
BOOST_TEST(b.comments().size() == 2u); BOOST_TEST(b.comments().size() == 2u);
BOOST_TEST(b.comments().front() == u8" comment for b."); BOOST_TEST(b.comments().front() == " comment for b.");
BOOST_TEST(b.comments().back() == u8" also comment for b."); BOOST_TEST(b.comments().back() == " also comment for b.");
} }
} }
BOOST_AUTO_TEST_CASE(test_comment_inline) BOOST_AUTO_TEST_CASE(test_comment_inline)
{ {
{ {
const std::string file = u8R"( const std::string file = R"(
a = 42 # comment for a. a = 42 # comment for a.
b = "baz" # comment for b. b = "baz" # comment for b.
)"; )";
@@ -68,12 +68,12 @@ BOOST_AUTO_TEST_CASE(test_comment_inline)
const auto& b = toml::find(v, "b"); const auto& b = toml::find(v, "b");
BOOST_TEST(a.comments().size() == 1u); BOOST_TEST(a.comments().size() == 1u);
BOOST_TEST(a.comments().front() == u8" comment for a."); BOOST_TEST(a.comments().front() == " comment for a.");
BOOST_TEST(b.comments().size() == 1u); BOOST_TEST(b.comments().size() == 1u);
BOOST_TEST(b.comments().front() == u8" comment for b."); BOOST_TEST(b.comments().front() == " comment for b.");
} }
{ {
const std::string file = u8R"( const std::string file = R"(
a = [ a = [
42, 42,
] # comment for a. ] # comment for a.
@@ -90,18 +90,18 @@ BOOST_AUTO_TEST_CASE(test_comment_inline)
const auto& b0 = b.as_array().at(0); const auto& b0 = b.as_array().at(0);
BOOST_TEST(a.comments().size() == 1u); BOOST_TEST(a.comments().size() == 1u);
BOOST_TEST(a.comments().front() == u8" comment for a."); BOOST_TEST(a.comments().front() == " comment for a.");
BOOST_TEST(b.comments().size() == 1u); BOOST_TEST(b.comments().size() == 1u);
BOOST_TEST(b.comments().front() == u8" this is a comment for b."); BOOST_TEST(b.comments().front() == " this is a comment for b.");
BOOST_TEST(b0.comments().size() == 1u); BOOST_TEST(b0.comments().size() == 1u);
BOOST_TEST(b0.comments().front() == u8" this is not a comment for b, but \"bar\""); BOOST_TEST(b0.comments().front() == " this is not a comment for b, but \"bar\"");
} }
} }
BOOST_AUTO_TEST_CASE(test_comment_both) BOOST_AUTO_TEST_CASE(test_comment_both)
{ {
{ {
const std::string file = u8R"( const std::string file = R"(
# comment for a. # comment for a.
a = 42 # inline comment for a. a = 42 # inline comment for a.
# comment for b. # comment for b.
@@ -122,25 +122,25 @@ BOOST_AUTO_TEST_CASE(test_comment_both)
const auto& c0 = c.as_array().at(0); const auto& c0 = c.as_array().at(0);
BOOST_TEST(a.comments().size() == 2u); BOOST_TEST(a.comments().size() == 2u);
BOOST_TEST(a.comments().front() == u8" comment for a."); BOOST_TEST(a.comments().front() == " comment for a.");
BOOST_TEST(a.comments().back() == u8" inline comment for a."); BOOST_TEST(a.comments().back() == " inline comment for a.");
BOOST_TEST(b.comments().size() == 2u); BOOST_TEST(b.comments().size() == 2u);
BOOST_TEST(b.comments().front() == u8" comment for b."); BOOST_TEST(b.comments().front() == " comment for b.");
BOOST_TEST(b.comments().back() == u8" inline comment for b."); BOOST_TEST(b.comments().back() == " inline comment for b.");
BOOST_TEST(c.comments().size() == 2u); BOOST_TEST(c.comments().size() == 2u);
BOOST_TEST(c.comments().front() == u8" comment for c."); BOOST_TEST(c.comments().front() == " comment for c.");
BOOST_TEST(c.comments().back() == u8" another comment for c."); BOOST_TEST(c.comments().back() == " another comment for c.");
BOOST_TEST(c0.comments().size() == 2u); BOOST_TEST(c0.comments().size() == 2u);
BOOST_TEST(c0.comments().front() == u8" comment for the first element."); BOOST_TEST(c0.comments().front() == " comment for the first element.");
BOOST_TEST(c0.comments().back() == u8" this also."); BOOST_TEST(c0.comments().back() == " this also.");
} }
} }
BOOST_AUTO_TEST_CASE(test_discard_comment) BOOST_AUTO_TEST_CASE(test_discard_comment)
{ {
const std::string file = u8R"( const std::string file = R"(
# comment for a. # comment for a.
a = 42 # inline comment for a. a = 42 # inline comment for a.
# comment for b. # comment for b.

View File

@@ -18,12 +18,11 @@ BOOST_AUTO_TEST_CASE(test_quoted_key)
{ {
TOML11_TEST_LEX_ACCEPT(lex_key, "\"127.0.0.1\"", "\"127.0.0.1\""); TOML11_TEST_LEX_ACCEPT(lex_key, "\"127.0.0.1\"", "\"127.0.0.1\"");
TOML11_TEST_LEX_ACCEPT(lex_key, "\"character encoding\"", "\"character encoding\""); TOML11_TEST_LEX_ACCEPT(lex_key, "\"character encoding\"", "\"character encoding\"");
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
// UTF-8 codepoint of characters that looks like "key" written upside down
TOML11_TEST_LEX_ACCEPT(lex_key, "\"\xCA\x8E\xC7\x9D\xCA\x9E\"", TOML11_TEST_LEX_ACCEPT(lex_key, "\"\xCA\x8E\xC7\x9D\xCA\x9E\"",
"\"\xCA\x8E\xC7\x9D\xCA\x9E\""); "\"\xCA\x8E\xC7\x9D\xCA\x9E\"");
#else
TOML11_TEST_LEX_ACCEPT(lex_key, u8"\"ʎǝʞ\"", u8"\"ʎǝʞ\"");
#endif
TOML11_TEST_LEX_ACCEPT(lex_key, "'key2'", "'key2'"); TOML11_TEST_LEX_ACCEPT(lex_key, "'key2'", "'key2'");
TOML11_TEST_LEX_ACCEPT(lex_key, "'quoted \"value\"'", "'quoted \"value\"'"); TOML11_TEST_LEX_ACCEPT(lex_key, "'quoted \"value\"'", "'quoted \"value\"'");
} }

View File

@@ -31,15 +31,9 @@ BOOST_AUTO_TEST_CASE(test_basic_string)
"\"192.168.1.1\"", "\"192.168.1.1\"",
"\"192.168.1.1\""); "\"192.168.1.1\"");
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
TOML11_TEST_LEX_ACCEPT(lex_string, TOML11_TEST_LEX_ACCEPT(lex_string,
"\"\xE4\xB8\xAD\xE5\x9B\xBD\"", "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", // UTF-8 string (means "China" in
"\"\xE4\xB8\xAD\xE5\x9B\xBD\""); "\"\xE4\xB8\xAD\xE5\x9B\xBD\""); // Chinese characters)
#else
TOML11_TEST_LEX_ACCEPT(lex_string,
u8"\"中国\"",
u8"\"中国\"");
#endif
TOML11_TEST_LEX_ACCEPT(lex_string, TOML11_TEST_LEX_ACCEPT(lex_string,
"\"You'll hate me after this - #\"", "\"You'll hate me after this - #\"",

View File

@@ -12,6 +12,170 @@ BOOST_AUTO_TEST_CASE(test_file_as_literal)
{ {
using namespace toml::literals::toml_literals; using namespace toml::literals::toml_literals;
{
const toml::value r{{"a", 42}, {"b", "baz"}};
const toml::value v = R"(
a = 42
b = "baz"
)"_toml;
BOOST_TEST(r == v);
}
{
const toml::value r{
{"c", 3.14},
{"table", toml::table{{"a", 42}, {"b", "baz"}}}
};
const toml::value v = R"(
c = 3.14
[table]
a = 42
b = "baz"
)"_toml;
BOOST_TEST(r == v);
}
{
const toml::value r{
{"table", toml::table{{"a", 42}, {"b", "baz"}}}
};
const toml::value v = R"(
[table]
a = 42
b = "baz"
)"_toml;
BOOST_TEST(r == v);
}
{
const toml::value r{
{"array_of_tables", toml::array{toml::table{}}}
};
const toml::value v = R"(
[[array_of_tables]]
)"_toml;
BOOST_TEST(r == v);
}
}
BOOST_AUTO_TEST_CASE(test_value_as_literal)
{
using namespace toml::literals::toml_literals;
{
const toml::value v1 = "true"_toml;
const toml::value v2 = "false"_toml;
BOOST_TEST(v1.is_boolean());
BOOST_TEST(v2.is_boolean());
BOOST_TEST(toml::get<bool>(v1));
BOOST_TEST(!toml::get<bool>(v2));
}
{
const toml::value v1 = "123_456"_toml;
const toml::value v2 = "0b0010"_toml;
const toml::value v3 = "0xDEADBEEF"_toml;
BOOST_TEST(v1.is_integer());
BOOST_TEST(v2.is_integer());
BOOST_TEST(v3.is_integer());
BOOST_TEST(toml::get<toml::integer>(v1) == 123456);
BOOST_TEST(toml::get<toml::integer>(v2) == 2);
BOOST_TEST(toml::get<toml::integer>(v3) == 0xDEADBEEF);
}
{
const toml::value v1 = "3.1415"_toml;
const toml::value v2 = "6.02e+23"_toml;
BOOST_TEST(v1.is_floating());
BOOST_TEST(v2.is_floating());
BOOST_TEST(toml::get<double>(v1) == 3.1415, boost::test_tools::tolerance(0.00001));
BOOST_TEST(toml::get<double>(v2) == 6.02e23, boost::test_tools::tolerance(0.0001));
}
{
const toml::value v1 = R"("foo")"_toml;
const toml::value v2 = R"('foo')"_toml;
const toml::value v3 = R"("""foo""")"_toml;
const toml::value v4 = R"('''foo''')"_toml;
BOOST_TEST(v1.is_string());
BOOST_TEST(v2.is_string());
BOOST_TEST(v3.is_string());
BOOST_TEST(v4.is_string());
BOOST_TEST(toml::get<std::string>(v1) == "foo");
BOOST_TEST(toml::get<std::string>(v2) == "foo");
BOOST_TEST(toml::get<std::string>(v3) == "foo");
BOOST_TEST(toml::get<std::string>(v4) == "foo");
}
{
{
const toml::value v1 = R"([1,2,3])"_toml;
BOOST_TEST(v1.is_array());
const bool result = (toml::get<std::vector<int>>(v1) == std::vector<int>{1,2,3});
BOOST_TEST(result);
}
{
const toml::value v2 = R"([1,])"_toml;
BOOST_TEST(v2.is_array());
const bool result = (toml::get<std::vector<int>>(v2) == std::vector<int>{1});
BOOST_TEST(result);
}
{
const toml::value v3 = R"([[1,]])"_toml;
BOOST_TEST(v3.is_array());
const bool result = (toml::get<std::vector<int>>(toml::get<toml::array>(v3).front()) == std::vector<int>{1});
BOOST_TEST(result);
}
{
const toml::value v4 = R"([[1],])"_toml;
BOOST_TEST(v4.is_array());
const bool result = (toml::get<std::vector<int>>(toml::get<toml::array>(v4).front()) == std::vector<int>{1});
BOOST_TEST(result);
}
}
{
const toml::value v1 = R"({a = 42})"_toml;
BOOST_TEST(v1.is_table());
const bool result = toml::get<std::map<std::string,int>>(v1) ==
std::map<std::string,int>{{"a", 42}};
BOOST_TEST(result);
}
{
const toml::value v1 = "1979-05-27"_toml;
BOOST_TEST(v1.is_local_date());
BOOST_TEST(toml::get<toml::local_date>(v1) ==
toml::local_date(1979, toml::month_t::May, 27));
}
{
const toml::value v1 = "12:00:00"_toml;
BOOST_TEST(v1.is_local_time());
const bool result = toml::get<std::chrono::hours>(v1) == std::chrono::hours(12);
BOOST_TEST(result);
}
{
const toml::value v1 = "1979-05-27T07:32:00"_toml;
BOOST_TEST(v1.is_local_datetime());
BOOST_TEST(toml::get<toml::local_datetime>(v1) ==
toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27),
toml::local_time(7, 32, 0)));
}
{
const toml::value v1 = "1979-05-27T07:32:00Z"_toml;
BOOST_TEST(v1.is_offset_datetime());
BOOST_TEST(toml::get<toml::offset_datetime>(v1) ==
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
toml::local_time(7, 32, 0), toml::time_offset(0, 0)));
}
}
BOOST_AUTO_TEST_CASE(test_file_as_u8_literal)
{
using namespace toml::literals::toml_literals;
{ {
const toml::value r{{"a", 42}, {"b", "baz"}}; const toml::value r{{"a", 42}, {"b", "baz"}};
const toml::value v = u8R"( const toml::value v = u8R"(
@@ -59,7 +223,7 @@ BOOST_AUTO_TEST_CASE(test_file_as_literal)
} }
} }
BOOST_AUTO_TEST_CASE(test_value_as_literal) BOOST_AUTO_TEST_CASE(test_value_as_u8_literal)
{ {
using namespace toml::literals::toml_literals; using namespace toml::literals::toml_literals;
@@ -98,15 +262,18 @@ BOOST_AUTO_TEST_CASE(test_value_as_literal)
const toml::value v2 = u8R"('foo')"_toml; const toml::value v2 = u8R"('foo')"_toml;
const toml::value v3 = u8R"("""foo""")"_toml; const toml::value v3 = u8R"("""foo""")"_toml;
const toml::value v4 = u8R"('''foo''')"_toml; const toml::value v4 = u8R"('''foo''')"_toml;
const toml::value v5 = u8R"("")"_toml;
BOOST_TEST(v1.is_string()); BOOST_TEST(v1.is_string());
BOOST_TEST(v2.is_string()); BOOST_TEST(v2.is_string());
BOOST_TEST(v3.is_string()); BOOST_TEST(v3.is_string());
BOOST_TEST(v4.is_string()); BOOST_TEST(v4.is_string());
BOOST_TEST(v5.is_string());
BOOST_TEST(toml::get<std::string>(v1) == "foo"); BOOST_TEST(toml::get<std::string>(v1) == "foo");
BOOST_TEST(toml::get<std::string>(v2) == "foo"); BOOST_TEST(toml::get<std::string>(v2) == "foo");
BOOST_TEST(toml::get<std::string>(v3) == "foo"); BOOST_TEST(toml::get<std::string>(v3) == "foo");
BOOST_TEST(toml::get<std::string>(v4) == "foo"); BOOST_TEST(toml::get<std::string>(v4) == "foo");
BOOST_TEST(toml::get<std::string>(v5) == "\xE3\x81\xB2\xE3\x82\x89\xE3\x81\x8C\xE3\x81\xAA");
} }
{ {
{ {
@@ -164,7 +331,7 @@ BOOST_AUTO_TEST_CASE(test_value_as_literal)
toml::local_time(7, 32, 0))); toml::local_time(7, 32, 0)));
} }
{ {
const toml::value v1 = "1979-05-27T07:32:00Z"_toml; const toml::value v1 = u8"1979-05-27T07:32:00Z"_toml;
BOOST_TEST(v1.is_offset_datetime()); BOOST_TEST(v1.is_offset_datetime());
BOOST_TEST(toml::get<toml::offset_datetime>(v1) == BOOST_TEST(toml::get<toml::offset_datetime>(v1) ==
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),

View File

@@ -779,6 +779,22 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines)
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value"); BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
} }
// without newline
{
const std::string table(
"key = \"value\"\n"
"[table]\n"
"key = \"value\"\n"
"a = 0"
);
std::istringstream iss(table);
const auto data = toml::parse(iss,
"test_files_end_with_newline.toml");
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
}
// CRLF // CRLF

View File

@@ -9,7 +9,6 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
BOOST_AUTO_TEST_CASE(test_hard_example_unicode) BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
{ {
const auto data = toml::parse("toml/tests/hard_example_unicode.toml"); const auto data = toml::parse("toml/tests/hard_example_unicode.toml");
@@ -40,35 +39,3 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) == BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
expected_multi_line_array); expected_multi_line_array);
} }
#else
BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
{
const auto data = toml::parse("toml/tests/hard_example_unicode.toml");
const auto the = toml::find<toml::table>(data, "the");
BOOST_TEST(toml::get<std::string>(the.at("test_string")) ==
std::string(u8"Ýôú' λáƭè ₥è áƒƭèř ƭλïƨ - #"));
const auto hard = toml::get<toml::table>(the.at("hard"));
const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array")) ==
expected_the_hard_test_array);
const std::vector<std::string> expected_the_hard_test_array2{
std::string(u8"Tèƨƭ #11 ]ƥřôƲèδ ƭλáƭ"),
std::string(u8"Éжƥèřï₥èñƭ #9 ωáƨ á ƨúççèƨƨ")};
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array2")) ==
expected_the_hard_test_array2);
BOOST_TEST(toml::get<std::string>(hard.at("another_test_string")) ==
std::string(u8"§á₥è ƭλïñϱ, βúƭ ωïƭλ á ƨƭřïñϱ #"));
BOOST_TEST(toml::get<std::string>(hard.at("harder_test_string")) ==
std::string(u8" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \""));
const auto bit = toml::get<toml::table>(hard.at(std::string(u8"βïƭ#")));
BOOST_TEST(toml::get<std::string>(bit.at(std::string(u8"ωλáƭ?"))) ==
std::string(u8"Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?"));
const std::vector<std::string> expected_multi_line_array{"]"};
BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
expected_multi_line_array);
}
#endif

View File

@@ -5,7 +5,7 @@
int main() int main()
{ {
using namespace toml::literals::toml_literals; using namespace toml::literals::toml_literals;
const auto data = u8R"(windows = "defines min and max as a macro")"_toml; const auto data = R"(windows = "defines min and max as a macro")"_toml;
std::cout << toml::find<std::string>(data, "windows") << std::endl; std::cout << toml::find<std::string>(data, "windows") << std::endl;
return 0; return 0;

View File

@@ -11,12 +11,9 @@ inline namespace literals
inline namespace toml_literals inline namespace toml_literals
{ {
inline ::toml::value operator"" _toml(const char* str, std::size_t len) // implementation
inline ::toml::value literal_internal_impl(::toml::detail::location loc)
{ {
::toml::detail::location
loc(/* filename = */ std::string("TOML literal encoded in a C++ code"),
/* contents = */ std::vector<char>(str, str + len));
// if there are some comments or empty lines, skip them. // if there are some comments or empty lines, skip them.
using skip_line = ::toml::detail::repeat<toml::detail::sequence< using skip_line = ::toml::detail::repeat<toml::detail::sequence<
::toml::detail::maybe<::toml::detail::lex_ws>, ::toml::detail::maybe<::toml::detail::lex_ws>,
@@ -78,8 +75,32 @@ inline ::toml::value operator"" _toml(const char* str, std::size_t len)
{ {
throw ::toml::syntax_error(data.unwrap_err(), source_location(loc)); throw ::toml::syntax_error(data.unwrap_err(), source_location(loc));
} }
} }
inline ::toml::value operator"" _toml(const char* str, std::size_t len)
{
::toml::detail::location loc(
std::string("TOML literal encoded in a C++ code"),
std::vector<char>(str, str + len));
return literal_internal_impl(std::move(loc));
}
// value of __cplusplus in C++2a/20 mode is not fixed yet along compilers.
// So here we use the feature test macro for `char8_t` itself.
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
// value of u8"" literal has been changed from char to char8_t and char8_t is
// NOT compatible to char
inline ::toml::value operator"" _toml(const char8_t* str, std::size_t len)
{
::toml::detail::location loc(
std::string("TOML literal encoded in a C++ code"),
std::vector<char>(reinterpret_cast<const char*>(str),
reinterpret_cast<const char*>(str) + len));
return literal_internal_impl(std::move(loc));
}
#endif
} // toml_literals } // toml_literals
} // literals } // literals
} // toml } // toml

View File

@@ -125,6 +125,7 @@ parse_integer(location& loc)
const auto second = std::next(first); const auto second = std::next(first);
if(second == loc.end()) // the token is just zero. if(second == loc.end()) // the token is just zero.
{ {
loc.advance();
return ok(std::make_pair(0, region(loc, first, second))); return ok(std::make_pair(0, region(loc, first, second)));
} }