diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d2ac316..52a8441 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,10 +9,13 @@ jobs: matrix: # g++-4.8 and 4.9 are tested on Travis.CI. compiler: ['g++-9', 'g++-8', 'g++-7', 'g++-6', 'g++-5'] - standard: ['11', '14', '17'] + standard: ['11', '14', '17', '20'] exclude: - {compiler: 'g++-5', standard: '17'} - {compiler: 'g++-6', standard: '17'} + - {compiler: 'g++-5', standard: '20'} + - {compiler: 'g++-6', standard: '20'} + - {compiler: 'g++-7', standard: '20'} steps: - name: Checkout uses: actions/checkout@v2 @@ -31,10 +34,10 @@ jobs: - name: Configure run: | mkdir build && cd build - if [[ "${{ matrix.compiler }}" == "g++-8" && "${{ matrix.standard }}" == "17" ]] ; then - cmake .. -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_REQUIRE_FILESYSTEM_LIBRARY=ON + if [[ "${{ matrix.compiler }}" == "g++-8" && ( "${{ matrix.standard }}" == "17" || "${{ matrix.standard }}" == "20" ) ]] ; then + cmake .. -Dtoml11_BUILD_TEST=ON -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_REQUIRE_FILESYSTEM_LIBRARY=ON 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 - name: Build run: | @@ -47,11 +50,14 @@ jobs: strategy: matrix: compiler: ['10', '9', '8', '7', '6.0', '5.0', '4.0', '3.9'] - standard: ['11', '14', '17'] + standard: ['11', '14', '17', '20'] exclude: - {compiler: '3.9', standard: '17'} - {compiler: '4.0', standard: '17'} - {compiler: '5.0', standard: '17'} + - {compiler: '3.9', standard: '20'} + - {compiler: '4.0', standard: '20'} + - {compiler: '5.0', standard: '20'} steps: - name: Checkout uses: actions/checkout@v2 @@ -70,7 +76,7 @@ jobs: - name: Configure run: | 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 run: | cd build && cmake --build . @@ -81,7 +87,7 @@ jobs: runs-on: windows-2019 strategy: matrix: - standard: ['11', '14', '17'] + standard: ['11', '14', '17', '20'] config: ['Release', 'Debug'] steps: - name: Checkout @@ -92,9 +98,10 @@ jobs: - name: Configure shell: cmd run: | + file --mime-encoding tests/test_literals.cpp mkdir 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 working-directory: ./build run: | @@ -102,6 +109,7 @@ jobs: - name: Test working-directory: ./build run: | + ./tests/test_literals --log_level=all file --mime-encoding tests/toml/tests/example.toml file --mime-encoding tests/toml/tests/fruit.toml file --mime-encoding tests/toml/tests/hard_example.toml diff --git a/.travis.yml b/.travis.yml index dc05b74..ce291a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -332,6 +332,6 @@ script: - cd build - echo "COMPILER = ${COMPILER}" - 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 - ctest --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index 340ae4b..2aa6a6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ enable_testing() 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_UBSAN "use LLVM undefined behavior sanitizer" OFF) @@ -37,6 +37,11 @@ else() 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 include(GNUInstallDirs) set(toml11_install_cmake_dir ${CMAKE_INSTALL_LIBDIR}/cmake/toml11) diff --git a/README.md b/README.md index 8dcba4d..38e0ab8 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ int main() Just include the file after adding it to the include path. ```cpp -#include // that's all! now you can use it. +#include // that's all! now you can use it. #include int main() @@ -1798,7 +1798,7 @@ for automating test set fetching!). ```sh $ mkdir build $ cd build -$ cmake .. +$ cmake .. -Dtoml11_BUILD_TEST=ON $ make $ make test ``` diff --git a/appveyor.yml b/appveyor.yml index a0504ac..9fc6a73 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,7 +17,7 @@ build_script: - cd C:\toml11 - mkdir 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%" - file --mime-encoding tests/toml/tests/hard_example_unicode.toml diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2feb9b1..a19c9b0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -182,7 +182,7 @@ foreach(TEST_NAME ${TEST_NAMES}) target_link_libraries(${TEST_NAME} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} toml11::toml11) # to compile tests with ... - if(TOML11_REQUIRE_FILESYSTEM_LIBRARY AND ${CMAKE_CXX_STANDARD} STREQUAL "17") + if(TOML11_REQUIRE_FILESYSTEM_LIBRARY) if(TOML11_WITH_LIBCXX_LIBRARY) target_link_libraries(${TEST_NAME} "c++fs") else() diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 797c39d..5ae1e0d 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -11,7 +11,7 @@ BOOST_AUTO_TEST_CASE(test_comment_before) { { - const std::string file = u8R"( + const std::string file = R"( # comment for a. a = 42 # comment for b. @@ -24,12 +24,12 @@ BOOST_AUTO_TEST_CASE(test_comment_before) const auto& b = toml::find(v, "b"); 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().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. # another comment for a. a = 42 @@ -45,18 +45,18 @@ BOOST_AUTO_TEST_CASE(test_comment_before) const auto& b = toml::find(v, "b"); BOOST_TEST(a.comments().size() == 2u); - BOOST_TEST(a.comments().front() == u8" comment for a."); - BOOST_TEST(a.comments().back() == u8" another comment for a."); + BOOST_TEST(a.comments().front() == " comment for a."); + BOOST_TEST(a.comments().back() == " another comment for a."); BOOST_TEST(b.comments().size() == 2u); - BOOST_TEST(b.comments().front() == u8" comment for b."); - BOOST_TEST(b.comments().back() == u8" also comment for b."); + BOOST_TEST(b.comments().front() == " comment for b."); + BOOST_TEST(b.comments().back() == " also comment for b."); } } BOOST_AUTO_TEST_CASE(test_comment_inline) { { - const std::string file = u8R"( + const std::string file = R"( a = 42 # comment for a. b = "baz" # comment for b. )"; @@ -68,12 +68,12 @@ BOOST_AUTO_TEST_CASE(test_comment_inline) const auto& b = toml::find(v, "b"); 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().front() == u8" comment for b."); + BOOST_TEST(b.comments().front() == " comment for b."); } { - const std::string file = u8R"( + const std::string file = R"( a = [ 42, ] # comment for a. @@ -90,18 +90,18 @@ BOOST_AUTO_TEST_CASE(test_comment_inline) const auto& b0 = b.as_array().at(0); 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().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().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) { { - const std::string file = u8R"( + const std::string file = R"( # comment for a. a = 42 # inline comment for a. # comment for b. @@ -122,25 +122,25 @@ BOOST_AUTO_TEST_CASE(test_comment_both) const auto& c0 = c.as_array().at(0); BOOST_TEST(a.comments().size() == 2u); - BOOST_TEST(a.comments().front() == u8" comment for a."); - BOOST_TEST(a.comments().back() == u8" inline comment for a."); + BOOST_TEST(a.comments().front() == " comment for a."); + BOOST_TEST(a.comments().back() == " inline comment for a."); BOOST_TEST(b.comments().size() == 2u); - BOOST_TEST(b.comments().front() == u8" comment for b."); - BOOST_TEST(b.comments().back() == u8" inline comment for b."); + BOOST_TEST(b.comments().front() == " comment for b."); + BOOST_TEST(b.comments().back() == " inline comment for b."); BOOST_TEST(c.comments().size() == 2u); - BOOST_TEST(c.comments().front() == u8" comment for c."); - BOOST_TEST(c.comments().back() == u8" another comment for c."); + BOOST_TEST(c.comments().front() == " comment for c."); + BOOST_TEST(c.comments().back() == " another comment for c."); BOOST_TEST(c0.comments().size() == 2u); - BOOST_TEST(c0.comments().front() == u8" comment for the first element."); - BOOST_TEST(c0.comments().back() == u8" this also."); + BOOST_TEST(c0.comments().front() == " comment for the first element."); + BOOST_TEST(c0.comments().back() == " this also."); } } BOOST_AUTO_TEST_CASE(test_discard_comment) { - const std::string file = u8R"( + const std::string file = R"( # comment for a. a = 42 # inline comment for a. # comment for b. diff --git a/tests/test_lex_key_comment.cpp b/tests/test_lex_key_comment.cpp index be4b176..0921bd6 100644 --- a/tests/test_lex_key_comment.cpp +++ b/tests/test_lex_key_comment.cpp @@ -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, "\"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\"", "\"\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, "'quoted \"value\"'", "'quoted \"value\"'"); } diff --git a/tests/test_lex_string.cpp b/tests/test_lex_string.cpp index dadfcde..643ab31 100644 --- a/tests/test_lex_string.cpp +++ b/tests/test_lex_string.cpp @@ -31,15 +31,9 @@ BOOST_AUTO_TEST_CASE(test_basic_string) "\"192.168.1.1\"", "\"192.168.1.1\""); -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) TOML11_TEST_LEX_ACCEPT(lex_string, - "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", - "\"\xE4\xB8\xAD\xE5\x9B\xBD\""); -#else - TOML11_TEST_LEX_ACCEPT(lex_string, - u8"\"中国\"", - u8"\"中国\""); -#endif + "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", // UTF-8 string (means "China" in + "\"\xE4\xB8\xAD\xE5\x9B\xBD\""); // Chinese characters) TOML11_TEST_LEX_ACCEPT(lex_string, "\"You'll hate me after this - #\"", diff --git a/tests/test_literals.cpp b/tests/test_literals.cpp index 076ef57..5aaf928 100644 --- a/tests/test_literals.cpp +++ b/tests/test_literals.cpp @@ -12,6 +12,170 @@ BOOST_AUTO_TEST_CASE(test_file_as_literal) { 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(v1)); + BOOST_TEST(!toml::get(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(v1) == 123456); + BOOST_TEST(toml::get(v2) == 2); + BOOST_TEST(toml::get(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(v1) == 3.1415, boost::test_tools::tolerance(0.00001)); + BOOST_TEST(toml::get(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(v1) == "foo"); + BOOST_TEST(toml::get(v2) == "foo"); + BOOST_TEST(toml::get(v3) == "foo"); + BOOST_TEST(toml::get(v4) == "foo"); + } + { + { + const toml::value v1 = R"([1,2,3])"_toml; + BOOST_TEST(v1.is_array()); + const bool result = (toml::get>(v1) == std::vector{1,2,3}); + BOOST_TEST(result); + } + { + const toml::value v2 = R"([1,])"_toml; + BOOST_TEST(v2.is_array()); + const bool result = (toml::get>(v2) == std::vector{1}); + BOOST_TEST(result); + } + { + const toml::value v3 = R"([[1,]])"_toml; + BOOST_TEST(v3.is_array()); + const bool result = (toml::get>(toml::get(v3).front()) == std::vector{1}); + BOOST_TEST(result); + } + { + const toml::value v4 = R"([[1],])"_toml; + BOOST_TEST(v4.is_array()); + const bool result = (toml::get>(toml::get(v4).front()) == std::vector{1}); + BOOST_TEST(result); + } + } + { + const toml::value v1 = R"({a = 42})"_toml; + + BOOST_TEST(v1.is_table()); + const bool result = toml::get>(v1) == + std::map{{"a", 42}}; + BOOST_TEST(result); + } + { + const toml::value v1 = "1979-05-27"_toml; + + BOOST_TEST(v1.is_local_date()); + BOOST_TEST(toml::get(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(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(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(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 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; @@ -98,15 +262,18 @@ BOOST_AUTO_TEST_CASE(test_value_as_literal) const toml::value v2 = u8R"('foo')"_toml; const toml::value v3 = u8R"("""foo""")"_toml; const toml::value v4 = u8R"('''foo''')"_toml; + const toml::value v5 = u8R"("ひらがな")"_toml; BOOST_TEST(v1.is_string()); BOOST_TEST(v2.is_string()); BOOST_TEST(v3.is_string()); BOOST_TEST(v4.is_string()); + BOOST_TEST(v5.is_string()); BOOST_TEST(toml::get(v1) == "foo"); BOOST_TEST(toml::get(v2) == "foo"); BOOST_TEST(toml::get(v3) == "foo"); BOOST_TEST(toml::get(v4) == "foo"); + BOOST_TEST(toml::get(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))); } { - 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(toml::get(v1) == toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index fd49114..f6e4512 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -779,6 +779,22 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) BOOST_TEST(toml::find(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(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); + } + // CRLF diff --git a/tests/test_parse_unicode.cpp b/tests/test_parse_unicode.cpp index dbfe601..e3797a6 100644 --- a/tests/test_parse_unicode.cpp +++ b/tests/test_parse_unicode.cpp @@ -9,7 +9,6 @@ #include #include -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) BOOST_AUTO_TEST_CASE(test_hard_example_unicode) { 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>(bit.at("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(data, "the"); - BOOST_TEST(toml::get(the.at("test_string")) == - std::string(u8"Ýôú'ℓℓ λáƭè ₥è áƒƭèř ƭλïƨ - #")); - - const auto hard = toml::get(the.at("hard")); - const std::vector expected_the_hard_test_array{"] ", " # "}; - BOOST_CHECK(toml::get>(hard.at("test_array")) == - expected_the_hard_test_array); - const std::vector expected_the_hard_test_array2{ - std::string(u8"Tèƨƭ #11 ]ƥřôƲèδ ƭλáƭ"), - std::string(u8"Éжƥèřï₥èñƭ #9 ωáƨ á ƨúççèƨƨ")}; - BOOST_CHECK(toml::get>(hard.at("test_array2")) == - expected_the_hard_test_array2); - BOOST_TEST(toml::get(hard.at("another_test_string")) == - std::string(u8"§á₥è ƭλïñϱ, βúƭ ωïƭλ á ƨƭřïñϱ #")); - BOOST_TEST(toml::get(hard.at("harder_test_string")) == - std::string(u8" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \"")); - - const auto bit = toml::get(hard.at(std::string(u8"βïƭ#"))); - BOOST_TEST(toml::get(bit.at(std::string(u8"ωλáƭ?"))) == - std::string(u8"Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?")); - const std::vector expected_multi_line_array{"]"}; - BOOST_CHECK(toml::get>(bit.at("multi_line_array")) == - expected_multi_line_array); - -} -#endif diff --git a/tests/test_windows.cpp b/tests/test_windows.cpp index 158c115..b178a26 100644 --- a/tests/test_windows.cpp +++ b/tests/test_windows.cpp @@ -5,7 +5,7 @@ int main() { 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(data, "windows") << std::endl; return 0; diff --git a/toml/literal.hpp b/toml/literal.hpp index 5292b3d..2c3d18c 100644 --- a/toml/literal.hpp +++ b/toml/literal.hpp @@ -11,12 +11,9 @@ inline namespace 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(str, str + len)); - // if there are some comments or empty lines, skip them. using skip_line = ::toml::detail::repeat, @@ -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)); } + } +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(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(reinterpret_cast(str), + reinterpret_cast(str) + len)); + return literal_internal_impl(std::move(loc)); +} +#endif + } // toml_literals } // literals } // toml diff --git a/toml/parser.hpp b/toml/parser.hpp index 3f31a97..a52d8c9 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -125,6 +125,7 @@ parse_integer(location& loc) const auto second = std::next(first); if(second == loc.end()) // the token is just zero. { + loc.advance(); return ok(std::make_pair(0, region(loc, first, second))); }