diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index c31141e8..566258d8 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -52,32 +52,6 @@ jobs: working-directory: ${{github.workspace}}/build run: ctest -C ${{matrix.build_type}} --output-on-failure -j ${{env.JOBS}} - xcode_for_macos12: - timeout-minutes: 10 - runs-on: macos-12 - strategy: - matrix: - xcode: [ '13.1', '13.2.1', '13.3.1', '13.4.1', '14.0.1', '14.1', '14.2' ] - build_type: [ Debug, Release ] - env: - DEVELOPER_DIR: /Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer - JOBS: 2 - - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Configure CMake - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DFK_YAML_BUILD_TEST=ON - - - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{matrix.build_type}} -j ${{env.JOBS}} - - - name: Test - working-directory: ${{github.workspace}}/build - run: ctest -C ${{matrix.build_type}} --output-on-failure -j ${{env.JOBS}} - xcode_for_macos13: timeout-minutes: 10 runs-on: macos-13 @@ -109,7 +83,10 @@ jobs: runs-on: macos-14 strategy: matrix: - xcode: [ '14.3.1', '15.0.1', '15.1', '15.2', '15.3', '15.4', '16' ] + # The macos-14 runner image will contain only Xcode 15.x versions due to support policy changes. + # Xcode 16.x versions are tested with the macos-15 runner image. + # See https://github.com/actions/runner-images/issues/10703 for more details. + xcode: [ '15.0.1', '15.1', '15.2', '15.3', '15.4' ] build_type: [ Debug, Release ] env: DEVELOPER_DIR: /Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer @@ -135,7 +112,9 @@ jobs: runs-on: macos-15 strategy: matrix: - xcode: [ '16' ] + # The macos-14 runner image will contain only Xcode 16.x versions. + # See https://github.com/actions/runner-images/issues/10703 for more details. + xcode: [ '16', '16.1' ] build_type: [ Debug, Release ] env: DEVELOPER_DIR: /Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 903f5972..8e8b36fc 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -200,7 +200,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - compiler: [ "3.5", "3.6", "3.7", "3.8", "3.9", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", latest ] + compiler: [ "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19" ] build_type: [ Debug, Release ] container: silkeh/clang:${{matrix.compiler}} @@ -270,6 +270,63 @@ jobs: cd ${{github.workspace}}/build ctest -C ${{matrix.build_type}} --output-on-failure -j ${{env.JOBS}} + ci_test_older_gcc_versions: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + build_type: [ Debug, Release ] + gcc_ver: [ '4.8', '5', '6' ] + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: add repository commonly needed to install GCC + run: | + sudo apt-get update + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + sudo apt-get update + + - name: add repository for GCC 4.8 or 5 + run: | + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5 + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32 + sudo apt-get update + + # for g++-4.8, g++-5 + sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu/ xenial main' + sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu/ xenial universe' + + sudo apt-get update + if: ${{ matrix.gcc_ver == '4.8' || matrix.gcc_ver == '5' }} + + - name: add repository for GCC 6 + run: | + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5 + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32 + sudo apt-get update + + # for g++-6 + sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu/ bionic main' + sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu/ bionic universe' + + sudo apt-get update + if: ${{ matrix.gcc_ver == '6' }} + + - name: install GCC + run: sudo apt-get install --no-install-recommends -y g++-${{matrix.gcc_ver}} + + - name: Configure CMake + run: CXX=g++-${{matrix.gcc_ver}} cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DFK_YAML_BUILD_TEST=ON + + - name: Build & Test + run: | + cmake --build ${{github.workspace}}/build --config ${{matrix.build_type}} -j ${{env.JOBS}} + cd ${{github.workspace}}/build + ctest -C ${{matrix.build_type}} --output-on-failure -j ${{env.JOBS}} + ci_test_icpx: runs-on: ubuntu-latest strategy: diff --git a/.reuse/templates/fkYAML.jinja2 b/.reuse/templates/fkYAML.jinja2 index 16e0d107..96628f7f 100644 --- a/.reuse/templates/fkYAML.jinja2 +++ b/.reuse/templates/fkYAML.jinja2 @@ -1,6 +1,6 @@ _______ __ __ __ _____ __ __ __ | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -| __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +| __| _ < \_ _/| ___ | _ | |___ version 0.4.0 |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML {% for copyright_line in copyright_lines %} diff --git a/.reuse/templates/fkYAML_support.jinja2 b/.reuse/templates/fkYAML_support.jinja2 index 10b1bd93..bb3fe2e2 100644 --- a/.reuse/templates/fkYAML_support.jinja2 +++ b/.reuse/templates/fkYAML_support.jinja2 @@ -1,6 +1,6 @@ _______ __ __ __ _____ __ __ __ | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -| __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +| __| _ < \_ _/| ___ | _ | |___ version 0.4.0 |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML {% for copyright_line in copyright_lines %} diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b604439..cbea1011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [v0.4.0](https://github.com/fktn-k/fkYAML/releases/tag/v0.4.0) (2024-12-10) + +[Full Changelog](https://github.com/fktn-k/fkYAML/compare/v0.3.14...v0.4.0) + +- Fix round-trip issue in float serialization using scientific notation [\#439](https://github.com/fktn-k/fkYAML/pull/439) ([fktn-k](https://github.com/fktn-k)) +- Fix parsing input which begins with a newline & indentation [\#437](https://github.com/fktn-k/fkYAML/pull/437) ([fktn-k](https://github.com/fktn-k)) +- Fixed bugs in parsing block scalars [\#435](https://github.com/fktn-k/fkYAML/pull/435) ([fktn-k](https://github.com/fktn-k)) +- Emit error if an anchor is specified to an alias [\#434](https://github.com/fktn-k/fkYAML/pull/434) ([fktn-k](https://github.com/fktn-k)) +- Stop throwing parse\_error on string-to-int/float conversion failures if not forced with tag [\#431](https://github.com/fktn-k/fkYAML/pull/431) ([fktn-k](https://github.com/fktn-k)) +- Resolve the C4800 warning when compiled with MSVC [\#430](https://github.com/fktn-k/fkYAML/pull/430) ([fktn-k](https://github.com/fktn-k)) + +- Support reverse iterations over sequence/mapping nodes [\#440](https://github.com/fktn-k/fkYAML/pull/440) ([fktn-k](https://github.com/fktn-k)) +- Make node iterators compatible with different value type const-ness [\#438](https://github.com/fktn-k/fkYAML/pull/438) ([fktn-k](https://github.com/fktn-k)) +- Add more GCC & Clang versions to use in GitHub Actions workflows [\#436](https://github.com/fktn-k/fkYAML/pull/436) ([fktn-k](https://github.com/fktn-k)) +- Update GitHub Actions workflow jobs using macOS related runner images [\#433](https://github.com/fktn-k/fkYAML/pull/433) ([fktn-k](https://github.com/fktn-k)) +- Support parsing multiline plain scalars [\#432](https://github.com/fktn-k/fkYAML/pull/432) ([fktn-k](https://github.com/fktn-k)) + ## [v0.3.14](https://github.com/fktn-k/fkYAML/releases/tag/v0.3.14) (2024-11-16) [Full Changelog](https://github.com/fktn-k/fkYAML/compare/v0.3.13...v0.3.14) diff --git a/CMakeLists.txt b/CMakeLists.txt index e655e0b4..c2a7896f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.8) project( fkYAML - VERSION 0.3.14 + VERSION 0.4.0 LANGUAGES CXX) ############################################################# diff --git a/Makefile b/Makefile index ca615282..f5c18590 100644 --- a/Makefile +++ b/Makefile @@ -15,13 +15,13 @@ TOOL_SRCS = $(shell find tool -type f -name '*.cpp' | sort) # target version definition TARGET_MAJOR_VERSION := 0 -TARGET_MINOR_VERSION := 3 -TARGET_PATCH_VERSION := 14 +TARGET_MINOR_VERSION := 4 +TARGET_PATCH_VERSION := 0 TARGET_VERSION_FULL := $(TARGET_MAJOR_VERSION).$(TARGET_MINOR_VERSION).$(TARGET_PATCH_VERSION) VERSION_MACRO_FILE := include/fkYAML/detail/macros/version_macros.hpp # system -JOBS = $(($(shell grep cpu.cores /proc/cpuinfo | sort -u | sed 's/[^0-9]//g') + 1)) +JOBS = $(($(shell grep cpu.cores /proc/cpuinfo | sort -u | sed 's/[^0-9]//g') - 1)) ############################################### # documentation of the Makefile's targets # diff --git a/README.md b/README.md index 36a4d02b..adf16d50 100644 --- a/README.md +++ b/README.md @@ -90,19 +90,15 @@ Currently, the following compilers are known to work and used in GitHub Actions | Compiler | Operating System | | -------------------------- | -------------------------------------------------------------------------------------------------------------- | -| AppleClang 13.0.0.13000029 | [macOS 12](https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md) | -| AppleClang 13.1.6.13160021 | [macOS 12](https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md) | -| AppleClang 14.0.0.14000029 | [macOS 12](https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md) | | AppleClang 14.0.0.14000029 | [macOS 13](https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md) | | AppleClang 14.0.3.14030022 | [macOS 13](https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md) | -| AppleClang 14.0.3.14030022 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | | AppleClang 15.0.0.15000040 | [macOS 13](https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md) | | AppleClang 15.0.0.15000040 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | | AppleClang 15.0.0.15000100 | [macOS 13](https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md) | | AppleClang 15.0.0.15000100 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | | AppleClang 15.0.0.15000309 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | -| AppleClang 16.0.0.16000026 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | | AppleClang 16.0.0.16000026 | [macOS 15](https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md) | +| Clang 3.4.2 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 3.5.2 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 3.6.2 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 3.7.1 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | @@ -122,6 +118,10 @@ Currently, the following compilers are known to work and used in GitHub Actions | Clang 16.0.6 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 17.0.6 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 18.1.6 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| Clang 19.1.4 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| GCC 4.8.5 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| GCC 5.3.1 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| GCC 6.4.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 7.5.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 8.5.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 9.5.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | @@ -129,7 +129,7 @@ Currently, the following compilers are known to work and used in GitHub Actions | GCC 11.4.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 12.3.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 13.3.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | -| GCC 14.1.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| GCC 14.2.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | IntelLLVM 2024.1.2 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | MinGW-64 8.1.0 | [Windows Server 2019](https://github.com/actions/runner-images/blob/main/images/windows/Windows2019-Readme.md) | | MinGW-64 12.2.0 | [Windows Server 2022](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md) | diff --git a/docs/examples/CMakeLists.txt b/docs/examples/CMakeLists.txt index 72042c2e..e10b028f 100644 --- a/docs/examples/CMakeLists.txt +++ b/docs/examples/CMakeLists.txt @@ -3,15 +3,26 @@ ############################# add_library(example_common_config INTERFACE) -target_include_directories( +target_link_libraries( example_common_config INTERFACE - ${CMAKE_CURRENT_BINARY_DIR}/include + ${FK_YAML_TARGET_NAME} ) -target_link_libraries( +target_compile_options( example_common_config INTERFACE - ${FK_YAML_TARGET_NAME} + # MSVC + $<$: + /wd4996 # examples contain deprecated APIs. + > + # GNU + $<$: + -Wno-deprecated-declarations # examples contain deprecated APIs. + > + # Clang + $<$: + -Wno-deprecated-declarations #examples contain deprecated APIs. + > ) ############################### @@ -23,13 +34,14 @@ foreach(TUT_SRC_FILE ${TUT_SRC_FILES}) file(RELATIVE_PATH REL_TUT_SRC_FILE ${CMAKE_CURRENT_SOURCE_DIR} ${TUT_SRC_FILE}) string(REPLACE ".cpp" "" TUT_SRC_FILE_BASE ${REL_TUT_SRC_FILE}) add_executable(${TUT_SRC_FILE_BASE} ${TUT_SRC_FILE}) - target_link_libraries(${TUT_SRC_FILE_BASE} ${FK_YAML_TARGET_NAME}) + target_link_libraries(${TUT_SRC_FILE_BASE} example_common_config) add_custom_command( TARGET ${TUT_SRC_FILE_BASE} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/example.yaml $ COMMAND $ > ${CMAKE_CURRENT_SOURCE_DIR}/${TUT_SRC_FILE_BASE}.output + WORKING_DIRECTORY $ ) endforeach() @@ -44,7 +56,7 @@ foreach(EX_SRC_FILE ${EX_SRC_FILES}) file(RELATIVE_PATH REL_EX_SRC_FILE ${CMAKE_CURRENT_SOURCE_DIR} ${EX_SRC_FILE}) string(REPLACE ".cpp" "" EX_SRC_FILE_BASE ${REL_EX_SRC_FILE}) add_executable(${EX_SRC_FILE_BASE} ${EX_SRC_FILE}) - target_link_libraries(${EX_SRC_FILE_BASE} ${FK_YAML_TARGET_NAME}) + target_link_libraries(${EX_SRC_FILE_BASE} example_common_config) add_custom_command( TARGET ${EX_SRC_FILE_BASE} @@ -52,5 +64,6 @@ foreach(EX_SRC_FILE ${EX_SRC_FILES}) COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/input.yaml $ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/input_multi.yaml $ COMMAND $ > ${CMAKE_CURRENT_SOURCE_DIR}/${EX_SRC_FILE_BASE}.output + WORKING_DIRECTORY $ ) endforeach() diff --git a/docs/examples/ex_basic_node_add_anchor_name.cpp b/docs/examples/ex_basic_node_add_anchor_name.cpp index 578ee6bb..7b350804 100644 --- a/docs/examples/ex_basic_node_add_anchor_name.cpp +++ b/docs/examples/ex_basic_node_add_anchor_name.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_add_tag_name.cpp b/docs/examples/ex_basic_node_add_tag_name.cpp index 83fcc2f6..6fbee168 100644 --- a/docs/examples/ex_basic_node_add_tag_name.cpp +++ b/docs/examples/ex_basic_node_add_tag_name.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_alias_of.cpp b/docs/examples/ex_basic_node_alias_of.cpp index 7f3786cc..ccc12dde 100644 --- a/docs/examples/ex_basic_node_alias_of.cpp +++ b/docs/examples/ex_basic_node_alias_of.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_at_basic_node.cpp b/docs/examples/ex_basic_node_at_basic_node.cpp index 38185ba8..43307dc5 100644 --- a/docs/examples/ex_basic_node_at_basic_node.cpp +++ b/docs/examples/ex_basic_node_at_basic_node.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_at_compatible_type.cpp b/docs/examples/ex_basic_node_at_compatible_type.cpp index 7dce0749..02210d6e 100644 --- a/docs/examples/ex_basic_node_at_compatible_type.cpp +++ b/docs/examples/ex_basic_node_at_compatible_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_begin.cpp b/docs/examples/ex_basic_node_begin.cpp index 10c7ef8a..2bb05c3a 100644 --- a/docs/examples/ex_basic_node_begin.cpp +++ b/docs/examples/ex_basic_node_begin.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_boolean_type.cpp b/docs/examples/ex_basic_node_boolean_type.cpp index ba4bdd5b..3f05fdd8 100644 --- a/docs/examples/ex_basic_node_boolean_type.cpp +++ b/docs/examples/ex_basic_node_boolean_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_const_iterator.output b/docs/examples/ex_basic_node_const_iterator.output deleted file mode 100644 index d00491fd..00000000 --- a/docs/examples/ex_basic_node_const_iterator.output +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/docs/examples/ex_basic_node_constructor_1.cpp b/docs/examples/ex_basic_node_constructor_1.cpp index 159c1864..306584be 100644 --- a/docs/examples/ex_basic_node_constructor_1.cpp +++ b/docs/examples/ex_basic_node_constructor_1.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_constructor_2.cpp b/docs/examples/ex_basic_node_constructor_2.cpp index 8722c362..4969c04a 100644 --- a/docs/examples/ex_basic_node_constructor_2.cpp +++ b/docs/examples/ex_basic_node_constructor_2.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_constructor_3.cpp b/docs/examples/ex_basic_node_constructor_3.cpp index 79ff6bc2..5d541e8c 100644 --- a/docs/examples/ex_basic_node_constructor_3.cpp +++ b/docs/examples/ex_basic_node_constructor_3.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_constructor_4.cpp b/docs/examples/ex_basic_node_constructor_4.cpp index b9c8c915..8f1f1fc7 100644 --- a/docs/examples/ex_basic_node_constructor_4.cpp +++ b/docs/examples/ex_basic_node_constructor_4.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_constructor_5.cpp b/docs/examples/ex_basic_node_constructor_5.cpp index 1e103244..c3276dbf 100644 --- a/docs/examples/ex_basic_node_constructor_5.cpp +++ b/docs/examples/ex_basic_node_constructor_5.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_constructor_6.cpp b/docs/examples/ex_basic_node_constructor_6.cpp index 28102d96..8f07fc48 100644 --- a/docs/examples/ex_basic_node_constructor_6.cpp +++ b/docs/examples/ex_basic_node_constructor_6.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_constructor_7.cpp b/docs/examples/ex_basic_node_constructor_7.cpp index cf3d32a2..831533de 100644 --- a/docs/examples/ex_basic_node_constructor_7.cpp +++ b/docs/examples/ex_basic_node_constructor_7.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_constructor_8.cpp b/docs/examples/ex_basic_node_constructor_8.cpp index 9d777cc2..e0482113 100644 --- a/docs/examples/ex_basic_node_constructor_8.cpp +++ b/docs/examples/ex_basic_node_constructor_8.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_contains.cpp b/docs/examples/ex_basic_node_contains.cpp index 32989914..67d6c337 100644 --- a/docs/examples/ex_basic_node_contains.cpp +++ b/docs/examples/ex_basic_node_contains.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_copy_assignment_operator.cpp b/docs/examples/ex_basic_node_copy_assignment_operator.cpp index 09f448c0..885fd49a 100644 --- a/docs/examples/ex_basic_node_copy_assignment_operator.cpp +++ b/docs/examples/ex_basic_node_copy_assignment_operator.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_deserialize_char_array.cpp b/docs/examples/ex_basic_node_deserialize_char_array.cpp index be74a955..27600611 100644 --- a/docs/examples/ex_basic_node_deserialize_char_array.cpp +++ b/docs/examples/ex_basic_node_deserialize_char_array.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_deserialize_docs_char_array.cpp b/docs/examples/ex_basic_node_deserialize_docs_char_array.cpp index 9714cc3e..65201dd1 100644 --- a/docs/examples/ex_basic_node_deserialize_docs_char_array.cpp +++ b/docs/examples/ex_basic_node_deserialize_docs_char_array.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_deserialize_docs_file_pointer.cpp b/docs/examples/ex_basic_node_deserialize_docs_file_pointer.cpp index fc307c99..8d71408e 100644 --- a/docs/examples/ex_basic_node_deserialize_docs_file_pointer.cpp +++ b/docs/examples/ex_basic_node_deserialize_docs_file_pointer.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_deserialize_docs_iterators.cpp b/docs/examples/ex_basic_node_deserialize_docs_iterators.cpp index 8ef4ecd7..b530ecd7 100644 --- a/docs/examples/ex_basic_node_deserialize_docs_iterators.cpp +++ b/docs/examples/ex_basic_node_deserialize_docs_iterators.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_deserialize_docs_string.cpp b/docs/examples/ex_basic_node_deserialize_docs_string.cpp index 2fd5028d..897f69b7 100644 --- a/docs/examples/ex_basic_node_deserialize_docs_string.cpp +++ b/docs/examples/ex_basic_node_deserialize_docs_string.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_deserialize_file_pointer.cpp b/docs/examples/ex_basic_node_deserialize_file_pointer.cpp index 9fdb1bf4..6e436eb8 100644 --- a/docs/examples/ex_basic_node_deserialize_file_pointer.cpp +++ b/docs/examples/ex_basic_node_deserialize_file_pointer.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_deserialize_iterators.cpp b/docs/examples/ex_basic_node_deserialize_iterators.cpp index 8b850945..705a3586 100644 --- a/docs/examples/ex_basic_node_deserialize_iterators.cpp +++ b/docs/examples/ex_basic_node_deserialize_iterators.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_deserialize_string.cpp b/docs/examples/ex_basic_node_deserialize_string.cpp index 18c99589..570b5d82 100644 --- a/docs/examples/ex_basic_node_deserialize_string.cpp +++ b/docs/examples/ex_basic_node_deserialize_string.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_empty.cpp b/docs/examples/ex_basic_node_empty.cpp index a955d86a..1adb7e61 100644 --- a/docs/examples/ex_basic_node_empty.cpp +++ b/docs/examples/ex_basic_node_empty.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -28,7 +28,7 @@ int main() { std::cout << std::boolalpha << n.empty() << std::endl; } catch (const fkyaml::exception& e) { - std::cout << "The node does not have a container nor string value." << std::endl; + std::cout << e.what() << std::endl; } } diff --git a/docs/examples/ex_basic_node_empty.output b/docs/examples/ex_basic_node_empty.output index f987b956..7a9bde2e 100644 --- a/docs/examples/ex_basic_node_empty.output +++ b/docs/examples/ex_basic_node_empty.output @@ -1,8 +1,8 @@ true false false -The node does not have a container nor string value. -The node does not have a container nor string value. -The node does not have a container nor string value. -The node does not have a container nor string value. +type_error: The target node is not of a container type. type=NULL_OBJECT +type_error: The target node is not of a container type. type=BOOLEAN +type_error: The target node is not of a container type. type=INTEGER +type_error: The target node is not of a container type. type=FLOAT false diff --git a/docs/examples/ex_basic_node_end.cpp b/docs/examples/ex_basic_node_end.cpp index a1ca0b4a..14f1c062 100644 --- a/docs/examples/ex_basic_node_end.cpp +++ b/docs/examples/ex_basic_node_end.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_extraction_operator.cpp b/docs/examples/ex_basic_node_extraction_operator.cpp index 9b072bdc..d622b586 100644 --- a/docs/examples/ex_basic_node_extraction_operator.cpp +++ b/docs/examples/ex_basic_node_extraction_operator.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_float_number_type.cpp b/docs/examples/ex_basic_node_float_number_type.cpp index c1c54b8b..89da57ce 100644 --- a/docs/examples/ex_basic_node_float_number_type.cpp +++ b/docs/examples/ex_basic_node_float_number_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_get_anchor_name.cpp b/docs/examples/ex_basic_node_get_anchor_name.cpp index e7e83f9a..1a9e765f 100644 --- a/docs/examples/ex_basic_node_get_anchor_name.cpp +++ b/docs/examples/ex_basic_node_get_anchor_name.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_get_tag_name.cpp b/docs/examples/ex_basic_node_get_tag_name.cpp index b280c7d9..5312a93b 100644 --- a/docs/examples/ex_basic_node_get_tag_name.cpp +++ b/docs/examples/ex_basic_node_get_tag_name.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_get_type.cpp b/docs/examples/ex_basic_node_get_type.cpp index 5eb15b00..65a59076 100644 --- a/docs/examples/ex_basic_node_get_type.cpp +++ b/docs/examples/ex_basic_node_get_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_get_value.cpp b/docs/examples/ex_basic_node_get_value.cpp index 7a7d9c78..bbedb18e 100644 --- a/docs/examples/ex_basic_node_get_value.cpp +++ b/docs/examples/ex_basic_node_get_value.cpp @@ -1,12 +1,16 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani // SPDX-License-Identifier: MIT #include +#include +#include +#include +#include #include int main() { diff --git a/docs/examples/ex_basic_node_get_value_ref.cpp b/docs/examples/ex_basic_node_get_value_ref.cpp index 2cb53bed..2265017f 100644 --- a/docs/examples/ex_basic_node_get_value_ref.cpp +++ b/docs/examples/ex_basic_node_get_value_ref.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_get_yaml_version.cpp b/docs/examples/ex_basic_node_get_yaml_version.cpp index 9f8b26cf..9e58267a 100644 --- a/docs/examples/ex_basic_node_get_yaml_version.cpp +++ b/docs/examples/ex_basic_node_get_yaml_version.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_get_yaml_version_type.cpp b/docs/examples/ex_basic_node_get_yaml_version_type.cpp index bcb6abca..d3c416a9 100644 --- a/docs/examples/ex_basic_node_get_yaml_version_type.cpp +++ b/docs/examples/ex_basic_node_get_yaml_version_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_has_anchor_name.cpp b/docs/examples/ex_basic_node_has_anchor_name.cpp index fc716a6d..b970e30b 100644 --- a/docs/examples/ex_basic_node_has_anchor_name.cpp +++ b/docs/examples/ex_basic_node_has_anchor_name.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_has_tag_name.cpp b/docs/examples/ex_basic_node_has_tag_name.cpp index f6ae5acf..57f99af2 100644 --- a/docs/examples/ex_basic_node_has_tag_name.cpp +++ b/docs/examples/ex_basic_node_has_tag_name.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_insertion_operator.cpp b/docs/examples/ex_basic_node_insertion_operator.cpp index 21b527f2..6b2c889b 100644 --- a/docs/examples/ex_basic_node_insertion_operator.cpp +++ b/docs/examples/ex_basic_node_insertion_operator.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_integer_type.cpp b/docs/examples/ex_basic_node_integer_type.cpp index 99c3bebf..797dc5e4 100644 --- a/docs/examples/ex_basic_node_integer_type.cpp +++ b/docs/examples/ex_basic_node_integer_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_alias.cpp b/docs/examples/ex_basic_node_is_alias.cpp index 88b565b6..5a9bf39f 100644 --- a/docs/examples/ex_basic_node_is_alias.cpp +++ b/docs/examples/ex_basic_node_is_alias.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_anchor.cpp b/docs/examples/ex_basic_node_is_anchor.cpp index bab7630e..a4a3fa3e 100644 --- a/docs/examples/ex_basic_node_is_anchor.cpp +++ b/docs/examples/ex_basic_node_is_anchor.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_boolean.cpp b/docs/examples/ex_basic_node_is_boolean.cpp index d0c4ebb4..805656b4 100644 --- a/docs/examples/ex_basic_node_is_boolean.cpp +++ b/docs/examples/ex_basic_node_is_boolean.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_float_number.cpp b/docs/examples/ex_basic_node_is_float_number.cpp index c48790d9..0ec5c4c5 100644 --- a/docs/examples/ex_basic_node_is_float_number.cpp +++ b/docs/examples/ex_basic_node_is_float_number.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_integer.cpp b/docs/examples/ex_basic_node_is_integer.cpp index 2080b6e8..f8bb0f28 100644 --- a/docs/examples/ex_basic_node_is_integer.cpp +++ b/docs/examples/ex_basic_node_is_integer.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_mapping.cpp b/docs/examples/ex_basic_node_is_mapping.cpp index 3320e514..31d20721 100644 --- a/docs/examples/ex_basic_node_is_mapping.cpp +++ b/docs/examples/ex_basic_node_is_mapping.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_null.cpp b/docs/examples/ex_basic_node_is_null.cpp index 872fa2f9..e743656a 100644 --- a/docs/examples/ex_basic_node_is_null.cpp +++ b/docs/examples/ex_basic_node_is_null.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_scalar.cpp b/docs/examples/ex_basic_node_is_scalar.cpp index 9f8630f6..ce41409c 100644 --- a/docs/examples/ex_basic_node_is_scalar.cpp +++ b/docs/examples/ex_basic_node_is_scalar.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_sequence.cpp b/docs/examples/ex_basic_node_is_sequence.cpp index 2951499e..76e3c2e8 100644 --- a/docs/examples/ex_basic_node_is_sequence.cpp +++ b/docs/examples/ex_basic_node_is_sequence.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_is_string.cpp b/docs/examples/ex_basic_node_is_string.cpp index b278107b..ab97101a 100644 --- a/docs/examples/ex_basic_node_is_string.cpp +++ b/docs/examples/ex_basic_node_is_string.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_iterator.cpp b/docs/examples/ex_basic_node_iterator.cpp index e3162885..3fff55f8 100644 --- a/docs/examples/ex_basic_node_iterator.cpp +++ b/docs/examples/ex_basic_node_iterator.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -11,10 +11,26 @@ #include int main() { - // create YAML nodes. + // create a container node. fkyaml::node sequence_node = {1, 2, 3}; // get an iterator to the first sequence element. fkyaml::node::iterator it = sequence_node.begin(); - std::cout << *it << std::endl; + fkyaml::node::const_iterator end_it = sequence_node.cend(); + + // print all the elements. + // note `iterator` and `const_iterator` are comparable. + for (; it != end_it; ++it) { + std::cout << *it << std::endl; + } + + it = sequence_node.begin(); + try { + // key() cannot be called on an iterator pointing to a sequence element. + std::cout << it.key() << std::endl; + } + catch (const fkyaml::exception& e) { + std::cout << e.what() << std::endl; + } + return 0; } diff --git a/docs/examples/ex_basic_node_iterator.output b/docs/examples/ex_basic_node_iterator.output index d00491fd..ef879471 100644 --- a/docs/examples/ex_basic_node_iterator.output +++ b/docs/examples/ex_basic_node_iterator.output @@ -1 +1,4 @@ 1 +2 +3 +Cannot retrieve key from non-mapping iterators. diff --git a/docs/examples/ex_basic_node_mapping.cpp b/docs/examples/ex_basic_node_mapping.cpp index 4614822f..f38fc735 100644 --- a/docs/examples/ex_basic_node_mapping.cpp +++ b/docs/examples/ex_basic_node_mapping.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_mapping_type.cpp b/docs/examples/ex_basic_node_mapping_type.cpp index e5e19cd5..7f38ef7b 100644 --- a/docs/examples/ex_basic_node_mapping_type.cpp +++ b/docs/examples/ex_basic_node_mapping_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_node.cpp b/docs/examples/ex_basic_node_node.cpp index d2581845..526f12a0 100644 --- a/docs/examples/ex_basic_node_node.cpp +++ b/docs/examples/ex_basic_node_node.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_node_t.cpp b/docs/examples/ex_basic_node_node_t.cpp index e9fc9cdc..451ba827 100644 --- a/docs/examples/ex_basic_node_node_t.cpp +++ b/docs/examples/ex_basic_node_node_t.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_operator_eq.cpp b/docs/examples/ex_basic_node_operator_eq.cpp index 2d19b663..fbee6424 100644 --- a/docs/examples/ex_basic_node_operator_eq.cpp +++ b/docs/examples/ex_basic_node_operator_eq.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_operator_ge.cpp b/docs/examples/ex_basic_node_operator_ge.cpp index a90f30d1..9c5e554c 100644 --- a/docs/examples/ex_basic_node_operator_ge.cpp +++ b/docs/examples/ex_basic_node_operator_ge.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_operator_gt.cpp b/docs/examples/ex_basic_node_operator_gt.cpp index a704a422..b421d25d 100644 --- a/docs/examples/ex_basic_node_operator_gt.cpp +++ b/docs/examples/ex_basic_node_operator_gt.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_operator_le.cpp b/docs/examples/ex_basic_node_operator_le.cpp index d73cbfc7..7de64ce9 100644 --- a/docs/examples/ex_basic_node_operator_le.cpp +++ b/docs/examples/ex_basic_node_operator_le.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_operator_lt.cpp b/docs/examples/ex_basic_node_operator_lt.cpp index 48c9c3a0..4353348b 100644 --- a/docs/examples/ex_basic_node_operator_lt.cpp +++ b/docs/examples/ex_basic_node_operator_lt.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_operator_ne.cpp b/docs/examples/ex_basic_node_operator_ne.cpp index 0609c882..820a17ea 100644 --- a/docs/examples/ex_basic_node_operator_ne.cpp +++ b/docs/examples/ex_basic_node_operator_ne.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_const_iterator.cpp b/docs/examples/ex_basic_node_rbegin.cpp similarity index 62% rename from docs/examples/ex_basic_node_const_iterator.cpp rename to docs/examples/ex_basic_node_rbegin.cpp index 2d06a046..a3d413e2 100644 --- a/docs/examples/ex_basic_node_const_iterator.cpp +++ b/docs/examples/ex_basic_node_rbegin.cpp @@ -1,20 +1,19 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani // SPDX-License-Identifier: MIT -#include #include #include int main() { - // create YAML nodes. - const fkyaml::node sequence_node = {1, 2, 3}; - // get an iterator to the first sequence element. - fkyaml::node::const_iterator it = sequence_node.begin(); + // create a sequence node. + fkyaml::node n = {"foo", "bar"}; + // get an iterator to the reverse-beginning (= last) element. + fkyaml::node::reverse_iterator it = n.rbegin(); std::cout << *it << std::endl; return 0; } diff --git a/docs/examples/ex_basic_node_rbegin.output b/docs/examples/ex_basic_node_rbegin.output new file mode 100644 index 00000000..5716ca59 --- /dev/null +++ b/docs/examples/ex_basic_node_rbegin.output @@ -0,0 +1 @@ +bar diff --git a/docs/examples/ex_basic_node_rend.cpp b/docs/examples/ex_basic_node_rend.cpp new file mode 100644 index 00000000..e0f0b438 --- /dev/null +++ b/docs/examples/ex_basic_node_rend.cpp @@ -0,0 +1,21 @@ +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#include +#include + +int main() { + // create a sequence node. + fkyaml::node n = {"foo", "bar"}; + // get an iterator to the reverse-end (= one before the first) element. + fkyaml::node::reverse_iterator it = n.rend(); + // decrement the iterator to point to the first element. + --it; + std::cout << *it << std::endl; + return 0; +} diff --git a/docs/examples/ex_basic_node_rend.output b/docs/examples/ex_basic_node_rend.output new file mode 100644 index 00000000..257cc564 --- /dev/null +++ b/docs/examples/ex_basic_node_rend.output @@ -0,0 +1 @@ +foo diff --git a/docs/examples/ex_basic_node_reverse_iterator.cpp b/docs/examples/ex_basic_node_reverse_iterator.cpp new file mode 100644 index 00000000..e8c1cbc6 --- /dev/null +++ b/docs/examples/ex_basic_node_reverse_iterator.cpp @@ -0,0 +1,36 @@ +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#include +#include +#include + +int main() { + // create a container node. + fkyaml::node sequence_node = {1, 2, 3}; + // get an iterator to the first sequence element. + fkyaml::node::reverse_iterator it = sequence_node.rbegin(); + fkyaml::node::const_reverse_iterator end_it = sequence_node.crend(); + + // print all the elements. + // note `reverse_iterator` and `const_reverse_iterator` are comparable. + for (; it != end_it; ++it) { + std::cout << *it << std::endl; + } + + it = sequence_node.rbegin(); + try { + // key() cannot be called on an iterator pointing to a sequence element. + std::cout << it.key() << std::endl; + } + catch (const fkyaml::exception& e) { + std::cout << e.what() << std::endl; + } + + return 0; +} diff --git a/docs/examples/ex_basic_node_reverse_iterator.output b/docs/examples/ex_basic_node_reverse_iterator.output new file mode 100644 index 00000000..f9f37752 --- /dev/null +++ b/docs/examples/ex_basic_node_reverse_iterator.output @@ -0,0 +1,4 @@ +3 +2 +1 +Cannot retrieve key from non-mapping iterators. diff --git a/docs/examples/ex_basic_node_sequence.cpp b/docs/examples/ex_basic_node_sequence.cpp index e79479af..1a25ee65 100644 --- a/docs/examples/ex_basic_node_sequence.cpp +++ b/docs/examples/ex_basic_node_sequence.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_sequence_type.cpp b/docs/examples/ex_basic_node_sequence_type.cpp index 9228ca8f..dcc50e26 100644 --- a/docs/examples/ex_basic_node_sequence_type.cpp +++ b/docs/examples/ex_basic_node_sequence_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_serialize.cpp b/docs/examples/ex_basic_node_serialize.cpp index 119fafb3..1ef9dca7 100644 --- a/docs/examples/ex_basic_node_serialize.cpp +++ b/docs/examples/ex_basic_node_serialize.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_serialize_docs.cpp b/docs/examples/ex_basic_node_serialize_docs.cpp index fa25aa37..baea8d56 100644 --- a/docs/examples/ex_basic_node_serialize_docs.cpp +++ b/docs/examples/ex_basic_node_serialize_docs.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_set_yaml_version.cpp b/docs/examples/ex_basic_node_set_yaml_version.cpp index c671dd95..35a7ea78 100644 --- a/docs/examples/ex_basic_node_set_yaml_version.cpp +++ b/docs/examples/ex_basic_node_set_yaml_version.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_set_yaml_version_type.cpp b/docs/examples/ex_basic_node_set_yaml_version_type.cpp index 672b2e3c..9c89c966 100644 --- a/docs/examples/ex_basic_node_set_yaml_version_type.cpp +++ b/docs/examples/ex_basic_node_set_yaml_version_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_size.cpp b/docs/examples/ex_basic_node_size.cpp index 7f96014b..0231dcb0 100644 --- a/docs/examples/ex_basic_node_size.cpp +++ b/docs/examples/ex_basic_node_size.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -21,7 +21,7 @@ int main() { std::cout << n.size() << std::endl; } catch (const fkyaml::exception& e) { - std::cout << "The node does not have a container nor string value." << std::endl; + std::cout << e.what() << std::endl; } } diff --git a/docs/examples/ex_basic_node_size.output b/docs/examples/ex_basic_node_size.output index 681a3fcb..62a7bc4f 100644 --- a/docs/examples/ex_basic_node_size.output +++ b/docs/examples/ex_basic_node_size.output @@ -1,7 +1,7 @@ 3 3 -The node does not have a container nor string value. -The node does not have a container nor string value. -The node does not have a container nor string value. -The node does not have a container nor string value. +type_error: The target node is not of a container type. type=NULL_OBJECT +type_error: The target node is not of a container type. type=BOOLEAN +type_error: The target node is not of a container type. type=INTEGER +type_error: The target node is not of a container type. type=FLOAT 3 diff --git a/docs/examples/ex_basic_node_string_type.cpp b/docs/examples/ex_basic_node_string_type.cpp index 759c9d39..c5a86a62 100644 --- a/docs/examples/ex_basic_node_string_type.cpp +++ b/docs/examples/ex_basic_node_string_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_subscript_operator_basic_node.cpp b/docs/examples/ex_basic_node_subscript_operator_basic_node.cpp index 002d98a9..ed562afd 100644 --- a/docs/examples/ex_basic_node_subscript_operator_basic_node.cpp +++ b/docs/examples/ex_basic_node_subscript_operator_basic_node.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_subscript_operator_compatible_type.cpp b/docs/examples/ex_basic_node_subscript_operator_compatible_type.cpp index a36f97d7..82020b21 100644 --- a/docs/examples/ex_basic_node_subscript_operator_compatible_type.cpp +++ b/docs/examples/ex_basic_node_subscript_operator_compatible_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_swap_member.cpp b/docs/examples/ex_basic_node_swap_member.cpp index 061ea98e..7645026f 100644 --- a/docs/examples/ex_basic_node_swap_member.cpp +++ b/docs/examples/ex_basic_node_swap_member.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_swap_std.cpp b/docs/examples/ex_basic_node_swap_std.cpp index 247a2e69..bec802da 100644 --- a/docs/examples/ex_basic_node_swap_std.cpp +++ b/docs/examples/ex_basic_node_swap_std.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_type.cpp b/docs/examples/ex_basic_node_type.cpp index e9fc9cdc..451ba827 100644 --- a/docs/examples/ex_basic_node_type.cpp +++ b/docs/examples/ex_basic_node_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_value_converter_type.cpp b/docs/examples/ex_basic_node_value_converter_type.cpp index 22989b1f..4c94c669 100644 --- a/docs/examples/ex_basic_node_value_converter_type.cpp +++ b/docs/examples/ex_basic_node_value_converter_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_yaml_version_t.cpp b/docs/examples/ex_basic_node_yaml_version_t.cpp index a3efec50..7c59531d 100644 --- a/docs/examples/ex_basic_node_yaml_version_t.cpp +++ b/docs/examples/ex_basic_node_yaml_version_t.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_exception_constructor_msg.cpp b/docs/examples/ex_exception_constructor_msg.cpp index 2050a0cc..d3369a99 100644 --- a/docs/examples/ex_exception_constructor_msg.cpp +++ b/docs/examples/ex_exception_constructor_msg.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_exception_constructor_noarg.cpp b/docs/examples/ex_exception_constructor_noarg.cpp index 34fd0a1e..dce59ce9 100644 --- a/docs/examples/ex_exception_constructor_noarg.cpp +++ b/docs/examples/ex_exception_constructor_noarg.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_exception_what.cpp b/docs/examples/ex_exception_what.cpp index 7057783b..d398537c 100644 --- a/docs/examples/ex_exception_what.cpp +++ b/docs/examples/ex_exception_what.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_macros_versions.cpp b/docs/examples/ex_macros_versions.cpp index 67b53866..63ebe02c 100644 --- a/docs/examples/ex_macros_versions.cpp +++ b/docs/examples/ex_macros_versions.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_macros_versions.output b/docs/examples/ex_macros_versions.output index 25ca8acb..58500139 100644 --- a/docs/examples/ex_macros_versions.output +++ b/docs/examples/ex_macros_versions.output @@ -1 +1 @@ -fkYAML version 0.3.14 +fkYAML version 0.4.0 diff --git a/docs/examples/ex_node_type.cpp b/docs/examples/ex_node_type.cpp index fd5aa2d2..286ea4d7 100644 --- a/docs/examples/ex_node_type.cpp +++ b/docs/examples/ex_node_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_node_value_converter_from_node.cpp b/docs/examples/ex_node_value_converter_from_node.cpp index 7b445bd9..f74f6116 100644 --- a/docs/examples/ex_node_value_converter_from_node.cpp +++ b/docs/examples/ex_node_value_converter_from_node.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_node_value_converter_to_node.cpp b/docs/examples/ex_node_value_converter_to_node.cpp index 6622df56..dc1075cc 100644 --- a/docs/examples/ex_node_value_converter_to_node.cpp +++ b/docs/examples/ex_node_value_converter_to_node.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_operator_literal_yaml.cpp b/docs/examples/ex_operator_literal_yaml.cpp index 715fb038..083ec285 100644 --- a/docs/examples/ex_operator_literal_yaml.cpp +++ b/docs/examples/ex_operator_literal_yaml.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_ordered_map_at.cpp b/docs/examples/ex_ordered_map_at.cpp index 446b6e65..19fddaef 100644 --- a/docs/examples/ex_ordered_map_at.cpp +++ b/docs/examples/ex_ordered_map_at.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_ordered_map_constructor_initializer_list.cpp b/docs/examples/ex_ordered_map_constructor_initializer_list.cpp index d08c1bcd..fb66f29f 100644 --- a/docs/examples/ex_ordered_map_constructor_initializer_list.cpp +++ b/docs/examples/ex_ordered_map_constructor_initializer_list.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_ordered_map_constructor_noarg.cpp b/docs/examples/ex_ordered_map_constructor_noarg.cpp index 12f68ebb..3af1a41d 100644 --- a/docs/examples/ex_ordered_map_constructor_noarg.cpp +++ b/docs/examples/ex_ordered_map_constructor_noarg.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_ordered_map_emplace.cpp b/docs/examples/ex_ordered_map_emplace.cpp index 2540b469..930c0ef7 100644 --- a/docs/examples/ex_ordered_map_emplace.cpp +++ b/docs/examples/ex_ordered_map_emplace.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_ordered_map_find.cpp b/docs/examples/ex_ordered_map_find.cpp index 858a2241..01de8a8f 100644 --- a/docs/examples/ex_ordered_map_find.cpp +++ b/docs/examples/ex_ordered_map_find.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_ordered_map_subscript_operator.cpp b/docs/examples/ex_ordered_map_subscript_operator.cpp index a22f212b..7a6932e6 100644 --- a/docs/examples/ex_ordered_map_subscript_operator.cpp +++ b/docs/examples/ex_ordered_map_subscript_operator.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_yaml_version_type.cpp b/docs/examples/ex_yaml_version_type.cpp index 41938cfe..0458b783 100644 --- a/docs/examples/ex_yaml_version_type.cpp +++ b/docs/examples/ex_yaml_version_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/tutorial_1.cpp b/docs/examples/tutorial_1.cpp index 97969cd2..2ec3200f 100644 --- a/docs/examples/tutorial_1.cpp +++ b/docs/examples/tutorial_1.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/tutorial_2.cpp b/docs/examples/tutorial_2.cpp index 2c1ccddf..d03e5492 100644 --- a/docs/examples/tutorial_2.cpp +++ b/docs/examples/tutorial_2.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/tutorial_3.cpp b/docs/examples/tutorial_3.cpp index 38fe6643..e4a7e812 100644 --- a/docs/examples/tutorial_3.cpp +++ b/docs/examples/tutorial_3.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/tutorial_4.cpp b/docs/examples/tutorial_4.cpp index 60c06486..38bf730a 100644 --- a/docs/examples/tutorial_4.cpp +++ b/docs/examples/tutorial_4.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/mkdocs/docs/api/basic_node/begin.md b/docs/mkdocs/docs/api/basic_node/begin.md index dbeaf971..5c71383b 100644 --- a/docs/mkdocs/docs/api/basic_node/begin.md +++ b/docs/mkdocs/docs/api/basic_node/begin.md @@ -1,20 +1,21 @@ Defined in header [``](https://github.com/fktn-k/fkYAML/blob/develop/include/fkYAML/node.hpp) -# fkyaml::basic_node::begin +# fkyaml::basic_node::begin, fkyaml::basic_node::cbegin ```cpp iterator begin(); const_iterator begin() const; +const_iterator cbegin() const; ``` -Returns an iterator to the first element of a container node value. -Throws a [`fkyaml::exception`](../exception/index.md) if a basic_node does not have a sequence nor mapping value. +Returns an iterator to the first element of a container node. +Throws a [`fkyaml::type_error`](../exception/type_error.md) if a basic_node is neither a sequence nor mapping node. ![Image from https://en.cppreference.com/w/cpp/iterator/begin](../../img/range-begin-end.svg) ### **Return Value** -An iterator to the first element of a container node value (either sequence or mapping). +An iterator to the first element of a container node. ???+ Example @@ -31,6 +32,6 @@ An iterator to the first element of a container node value (either sequence or m * [basic_node](index.md) * [node](node.md) -* [iterator](iterator.md) -* [const_iterator](const_iterator.md) -* [end](end.md) +* [iterator, const_iterator](iterator.md) +* [end, cend](end.md) +* [operator<<](insertion_operator.md) diff --git a/docs/mkdocs/docs/api/basic_node/const_iterator.md b/docs/mkdocs/docs/api/basic_node/const_iterator.md deleted file mode 100644 index 33c5ab86..00000000 --- a/docs/mkdocs/docs/api/basic_node/const_iterator.md +++ /dev/null @@ -1,27 +0,0 @@ -Defined in header [``](https://github.com/fktn-k/fkYAML/blob/develop/include/fkYAML/node.hpp) - -# fkyaml::basic_node::const_iterator - -```cpp -using const_iterator = detail::iterator; -``` - -The type for constant iterators of [`basic_node`](index.md) containers. -This iterator type is commonly used for sequence and mapping container values. - -???+ Example - - ```cpp - --8<-- "examples/ex_basic_node_const_iterator.cpp:9" - ``` - - output: - ```bash - --8<-- "examples/ex_basic_node_const_iterator.output" - ``` - -### **See Also** - -* [basic_node](index.md) -* [begin](begin.md) -* [iterator](iterator.md) diff --git a/docs/mkdocs/docs/api/basic_node/end.md b/docs/mkdocs/docs/api/basic_node/end.md index 00bedf7e..1b966468 100644 --- a/docs/mkdocs/docs/api/basic_node/end.md +++ b/docs/mkdocs/docs/api/basic_node/end.md @@ -1,20 +1,21 @@ Defined in header [``](https://github.com/fktn-k/fkYAML/blob/develop/include/fkYAML/node.hpp) -# fkyaml::basic_node::end +# fkyaml::basic_node::end, fkyaml::basic_node::cend ```cpp iterator end(); const_iterator end() const; +const_iterator cend() const; ``` -Returns an iterator to the past-the-last element of a container node value. -Throws a [`fkyaml::exception`](../exception/index.md) if a basic_node does not have a sequence nor mapping value. +Returns an iterator to the past-the-last element of a container node. +Throws a [`fkyaml::type_error`](../exception/type_error.md) if a basic_node is neither a sequence nor mapping node. ![Image from https://en.cppreference.com/w/cpp/iterator/end](../../img/range-begin-end.svg) ### **Return Value** -An iterator to the past-the-last element of a container node value (either sequence or mapping). +An iterator to the past-the-last element of a container node. ???+ Example @@ -31,7 +32,6 @@ An iterator to the past-the-last element of a container node value (either seque * [basic_node](index.md) * [node](node.md) -* [iterator](iterator.md) -* [const_iterator](const_iterator.md) -* [begin](begin.md) +* [iterator, const_iterator](iterator.md) +* [begin, cbegin](begin.md) * [operator<<](insertion_operator.md) diff --git a/docs/mkdocs/docs/api/basic_node/index.md b/docs/mkdocs/docs/api/basic_node/index.md index 8b9ad0ea..2a5e7f24 100644 --- a/docs/mkdocs/docs/api/basic_node/index.md +++ b/docs/mkdocs/docs/api/basic_node/index.md @@ -34,17 +34,35 @@ This class provides features to handle YAML nodes. ## Member Types +### Node Value Types +| Name | Description | +| ----------------------------------------- | ------------------------------------------------------ | +| [sequence_type](sequence_type.md) | The type used to store sequence node value containers. | +| [mapping_type](mapping_type.md) | The type used to store mapping node value containers. | +| [boolean_type](boolean_type.md) | The type used to store boolean node values. | +| [integer_type](integer_type.md) | The type used to store integer node values. | +| [float_number_type](float_number_type.md) | The type used to store float number node values. | +| [string_type](string_type.md) | The type used to store string node values. | + +### Container Types +| Name | Description | +| --------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| value_type | `basic_node` | +| reference | `basic_node&` | +| const_reference | `const basic_node&` | +| pointer | `basic_node*` | +| const_pointer | `const basic_node*` | +| size_type | [`std::size_t`](https://en.cppreference.com/w/cpp/types/size_t) | +| difference_type | [`std::ptrdiff_t`](https://en.cppreference.com/w/cpp/types/ptrdiff_t) | +| [iterator](iterator.md) | [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) | +| [const_iterator](iterator.md) | constant [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) | +| [reverse_iterator](reverse_iterator.md) | reverse iterator derived from `iterator` | +| [const_reverse_iterator](reverse_iterator.md) | reverse iterator derived from `const_iterator` | + +### Miscellaneous | Name | Description | | ----------------------------------------------- | ------------------------------------------------------------------- | -| [sequence_type](sequence_type.md) | The type used to store sequence node value containers. | -| [mapping_type](mapping_type.md) | The type used to store mapping node value containers. | -| [boolean_type](boolean_type.md) | The type used to store boolean node values. | -| [integer_type](integer_type.md) | The type used to store integer node values. | -| [float_number_type](float_number_type.md) | The type used to store float number node values. | -| [string_type](string_type.md) | The type used to store string node values. | | [value_converter_type](value_converter_type.md) | The type used to convert between node and native data. | -| [iterator](iterator.md) | The type for non-constant iterators. | -| [const_iterator](const_iterator.md) | The type for constant iterators. | | [node_t](node_t.md) | **(DEPRECATED)** The type used to store the internal value type. | | [yaml_version_t](yaml_version_t.md) | **(DEPRECATED)** The type used to store the enable version of YAML. | @@ -87,10 +105,16 @@ This class provides features to handle YAML nodes. | [get_value_ref](get_value_ref.md) | | converts a basic_node into reference to a target native data type. | ### Iterators -| Name | Description | -|-------------------|----------------------------------------------------------| -| [begin](begin.md) | returns an iterator to the beginning of mapping/sequence | -| [end](end.md) | returns an iterator to the end of mapping/sequence | +| Name | Description | +| -------------------- | ---------------------------------------------------------------------------- | +| [begin](begin.md) | returns a (const) iterator to the beginning of mapping/sequence | +| [cbegin](begin.md) | returns a const iterator to the beginning of mapping/sequence | +| [end](end.md) | returns a (const) iterator to the past-the-last of mapping/sequence | +| [cend](end.md) | returns a const iterator to the past-the-last of mapping/sequence | +| [rbegin](rbegin.md) | returns a (const) iterator to the first of reversed mapping/sequence | +| [crbegin](rbegin.md) | returns a const iterator to the first of reversed mapping/sequence | +| [rend](rend.md) | returns a (const) iterator to the past-the-last of reversed mapping/sequence | +| [crend](rend.md) | returns a const iterator to the past-the-last of reversed mapping/sequence | ### Inspection for Container Node Values | Name | Description | diff --git a/docs/mkdocs/docs/api/basic_node/iterator.md b/docs/mkdocs/docs/api/basic_node/iterator.md index e7e90d09..75e3e877 100644 --- a/docs/mkdocs/docs/api/basic_node/iterator.md +++ b/docs/mkdocs/docs/api/basic_node/iterator.md @@ -1,13 +1,40 @@ Defined in header [``](https://github.com/fktn-k/fkYAML/blob/develop/include/fkYAML/node.hpp) -# fkyaml::basic_node::iterator +# fkyaml::basic_node::iterator, fkyaml::basic_node::const_iterator ```cpp using iterator = detail::iterator; +using iterator = detail::iterator; ``` -The type for iterators of [`basic_node`](index.md) containers. -This iterator type is commonly used for sequence and mapping container values. +The types of non-const/const iterators for [`basic_node`](index.md) containers. +They satisfies [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) and are commonly used for sequence and mapping container nodes. + +## Member Types + +* iterator + | Type | Definition | + | ------------------- | --------------------------------------------------------------------------------------------- | + | `value_type` | `basic_node` | + | `reference` | `basic_node&` | + | `pointer` | `basic_node*` | + | `difference_type` | [`std::ptrdiff_t`](https://en.cppreference.com/w/cpp/types/ptrdiff_t) | + | `iterator_category` | [`std::bidirectional_iterator_tag`](https://en.cppreference.com/w/cpp/iterator/iterator_tags) | +* const_iterator + | Type | Definition | + | ------------------- | --------------------------------------------------------------------------------------------- | + | `value_type` | `basic_node` | + | `reference` | `const basic_node&` | + | `pointer` | `const basic_node*` | + | `difference_type` | [`std::ptrdiff_t`](https://en.cppreference.com/w/cpp/types/ptrdiff_t) | + | `iterator_category` | [`std::bidirectional_iterator_tag`](https://en.cppreference.com/w/cpp/iterator/iterator_tags) | + +## Member Functions + +| Name | Description | +| ----- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| key | Returns const reference to a key node of the current key-value pair.
`fkyaml::exception` is thrown if an iterator points to a sequence element. | +| value | Returns reference to a sequence element if an element points to a sequence element, or a mapping value otherwise. | ???+ Example @@ -23,6 +50,6 @@ This iterator type is commonly used for sequence and mapping container values. ### **See Also** * [basic_node](index.md) -* [begin](begin.md) -* [const_iterator](const_iterator.md) +* [begin, cbegin](begin.md) +* [end, cend](end.md) * [operator<<](insertion_operator.md) diff --git a/docs/mkdocs/docs/api/basic_node/rbegin.md b/docs/mkdocs/docs/api/basic_node/rbegin.md new file mode 100644 index 00000000..b3e2cf6a --- /dev/null +++ b/docs/mkdocs/docs/api/basic_node/rbegin.md @@ -0,0 +1,36 @@ +Defined in header [``](https://github.com/fktn-k/fkYAML/blob/develop/include/fkYAML/node.hpp) + +# fkyaml::basic_node::rbegin, fkyaml::basic_node::crbegin + +```cpp +reverse_iterator rbegin(); +const_reverse_iterator rbegin() const; +const_reverse_iterator crbegin() const; +``` + +Returns an iterator to the reverse-beginning (= last) element of a container node. +Throws a [`fkyaml::type_error`](../exception/type_error.md) if a basic_node is neither a sequence nor mapping node. + +![Image from https://en.cppreference.com/w/cpp/iterator/reverse_iterator](../../img/range-rbegin-rend.svg) + +### **Return Value** + +A (constant) reverse iterator to the reverse-beginning (= last) element of a container node. + +???+ Example + + ```cpp + --8<-- "examples/ex_basic_node_rbegin.cpp:9" + ``` + + output: + ```bash + --8<-- "examples/ex_basic_node_rbegin.output" + ``` + +### **See Also** + +* [basic_node](index.md) +* [node](node.md) +* [reverse_iterator, const_reverse_iterator](reverse_iterator.md) +* [rend, crend](rend.md) diff --git a/docs/mkdocs/docs/api/basic_node/rend.md b/docs/mkdocs/docs/api/basic_node/rend.md new file mode 100644 index 00000000..8ac5e93f --- /dev/null +++ b/docs/mkdocs/docs/api/basic_node/rend.md @@ -0,0 +1,36 @@ +Defined in header [``](https://github.com/fktn-k/fkYAML/blob/develop/include/fkYAML/node.hpp) + +# fkyaml::basic_node::rend, fkyaml::basic_node::crend + +```cpp +reverse_iterator rend(); +const_reverse_iterator rend() const; +const_reverse_iterator crend() const; +``` + +Returns an iterator to the reverse-end (= one before the first) element of a container node. +Throws a [`fkyaml::type_error`](../exception/type_error.md) if a basic_node is neither a sequence nor mapping node. + +![Image from https://en.cppreference.com/w/cpp/iterator/reverse_iterator](../../img/range-rbegin-rend.svg) + +### **Return Value** + +A (constant) reverse iterator to the reverse-end (= one before the first) element of a container node. + +???+ Example + + ```cpp + --8<-- "examples/ex_basic_node_rend.cpp:9" + ``` + + output: + ```bash + --8<-- "examples/ex_basic_node_rend.output" + ``` + +### **See Also** + +* [basic_node](index.md) +* [node](node.md) +* [reverse_iterator, const_reverse_iterator](reverse_iterator.md) +* [rend, crend](rend.md) diff --git a/docs/mkdocs/docs/api/basic_node/reverse_iterator.md b/docs/mkdocs/docs/api/basic_node/reverse_iterator.md new file mode 100644 index 00000000..d0ebe24a --- /dev/null +++ b/docs/mkdocs/docs/api/basic_node/reverse_iterator.md @@ -0,0 +1,59 @@ +Defined in header [``](https://github.com/fktn-k/fkYAML/blob/develop/include/fkYAML/node.hpp) + +# fkyaml::basic_node::reverse_iterator, fkyaml::basic_node::const_reverse_iterator + +```cpp +using reverse_iterator = detail::reverse_iterator; +using const_reverse_iterator = detail::reverse_iterator; +``` + +The types of non-const/const reverse iterators for [`basic_node`](index.md) containers. +They satisfies [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) and are commonly used for sequence and mapping container nodes. + +## Member Types + +### reverse_iterator +| Type | Definition | +| ------------------- | --------------------------------------------------------------------------------------------- | +| `iterator_type` | `basic_node::iterator` | +| `value_type` | `basic_node` | +| `reference` | `basic_node&` | +| `pointer` | `basic_node*` | +| `difference_type` | [`std::ptrdiff_t`](https://en.cppreference.com/w/cpp/types/ptrdiff_t) | +| `iterator_category` | [`std::bidirectional_iterator_tag`](https://en.cppreference.com/w/cpp/iterator/iterator_tags) | + +### const_reverse_iterator +| Type | Definition | +| ------------------- | --------------------------------------------------------------------------------------------- | +| `iterator_type` | `basic_node::const_iterator` | +| `value_type` | `basic_node` | +| `reference` | `const basic_node&` | +| `pointer` | `const basic_node*` | +| `difference_type` | [`std::ptrdiff_t`](https://en.cppreference.com/w/cpp/types/ptrdiff_t) | +| `iterator_category` | [`std::bidirectional_iterator_tag`](https://en.cppreference.com/w/cpp/iterator/iterator_tags) | + +## Member Functions + +| Name | Description | +| ----- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| key | Returns const reference to a key node of the current key-value pair.
`fkyaml::exception` is thrown if an iterator points to a sequence element. | +| value | Returns reference to a sequence element if an element points to a sequence element, or a mapping value otherwise. | + +???+ Example + + ```cpp + --8<-- "examples/ex_basic_node_reverse_iterator.cpp:9" + ``` + + output: + ```bash + --8<-- "examples/ex_basic_node_reverse_iterator.output" + ``` + +### **See Also** + +* [basic_node](index.md) +* [iterator, const_iterator](iterator.md) +* [rbegin, crbegin](rbegin.md) +* [rend, crend](rend.md) +* [operator<<](insertion_operator.md) diff --git a/docs/mkdocs/docs/home/releases.md b/docs/mkdocs/docs/home/releases.md index 4c56836b..5c6747fc 100644 --- a/docs/mkdocs/docs/home/releases.md +++ b/docs/mkdocs/docs/home/releases.md @@ -1,5 +1,77 @@ # Releases +## **fkYAML version 0.4.0** + +!!! abstract "Release Packages" + + * [fkYAML.zip](https://github.com/fktn-k/fkYAML/releases/download/v0.4.0/fkYAML.zip) + * [fkYAML.tgz](https://github.com/fktn-k/fkYAML/releases/download/v0.4.0/fkYAML.tgz) + * [fkYAML_single_header.zip](https://github.com/fktn-k/fkYAML/releases/download/v0.4.0/fkYAML_single_header.zip) + * [fkYAML_single_header.tgz](https://github.com/fktn-k/fkYAML/releases/download/v0.4.0/fkYAML_single_header.tgz) + * [node.hpp](https://github.com/fktn-k/fkYAML/releases/download/v0.4.0/node.hpp) (single header) + * [fkyaml_fwd.hpp](https://github.com/fktn-k/fkYAML/releases/download/v0.4.0/fkyaml_fwd.hpp) (single header) + +### Summary +This release adds new features: parsing multi-line plain scalars & reverse iterations over sequence/mapping node elements. +See the related pull requests and documentations for more details. + +A number of bugs (mostly in the deserialization feature) have also been resolved. +Note that a breaking change has been made in the way of error handling when deserializing an int or float scalar fail. The library now emits no error on such a scalar and treats it as a string scalar instead. + +### What's Changed + +#### :boom: Breaking Changes +- Stop throwing parse\_error on string-to-int/float conversion failures if not forced with tag ([\#431](https://github.com/fktn-k/fkYAML/pull/431), [fktn-k](https://github.com/fktn-k)) + - reported by [tomwpid](https://github.com/tomwpid) in the issue [\#428](https://github.com/fktn-k/fkYAML/issues/428) + - The library used to throw a `fkyaml::parse_error` upon conversion failures from a scalar to an integer or floating point value while parsing a YAML like this: + ```yaml + id: 6E-578 # "6E-578" is interpreted as a floating point value but not expressible as a `double` + # --> `fkyaml::parse_error` gets thrown due to the conversion failure. + ``` + - Such a conversion failure is now internally recovered by treating the scalar as a string scalar instead. + +#### :sparkles: New Features +- Support parsing multiline plain scalars ([\#432](https://github.com/fktn-k/fkYAML/pull/432), [fktn-k](https://github.com/fktn-k)) + - Parsing a YAML which contains multi-line plain (unquoted) scalars are now supported. + ```yaml + foo: this is + a multi-line + plain scalar # interpreted as "this is a multi-line plain scalar" + ``` +- Support reverse iterations over sequence/mapping nodes ([\#440](https://github.com/fktn-k/fkYAML/pull/440), [fktn-k](https://github.com/fktn-k)) + - You can now iterate over sequence/mapping elements in a reversed order like this: + ```cpp + // node is [1, 2, 3] + for (auto rit = node.rbegin(); rit != node.rend(); ++rit) { + std::cout << *rit << std::endl; + } + + // output: + // 3 + // 2 + // 1 + ``` + +#### :zap: Improvements +- Resolve the C4800 warning when compiled with MSVC ([\#430](https://github.com/fktn-k/fkYAML/pull/430), [fktn-k](https://github.com/fktn-k)) + - reported by [tomwpid](https://github.com/tomwpid) in the issue [\#429](https://github.com/fktn-k/fkYAML/issues/429) +- Make node iterators compatible with different value type const-ness ([\#438](https://github.com/fktn-k/fkYAML/pull/438), [fktn-k](https://github.com/fktn-k)) + - `fkyaml::node::iterator` and `fkyaml::node::const_iterator` are compatible in constructions, assignments and comparisons. + +#### :bug: Bug Fixes +- Emit error if an anchor is specified to an alias ([\#434](https://github.com/fktn-k/fkYAML/pull/434), [fktn-k](https://github.com/fktn-k)) +- Fixed bugs in parsing block scalars ([\#435](https://github.com/fktn-k/fkYAML/pull/435), [fktn-k](https://github.com/fktn-k)) +- Fix parsing input which begins with a newline & indentation ([\#437](https://github.com/fktn-k/fkYAML/pull/437), [fktn-k](https://github.com/fktn-k)) +- Fix round-trip issue in float serialization using scientific notation ([\#439](https://github.com/fktn-k/fkYAML/pull/439), [fktn-k](https://github.com/fktn-k)) + - reported by [dyerbod](https://github.com/dyerbod) in the issue [\#405](https://github.com/fktn-k/fkYAML/issues/405) + +#### :robot: CI +- Update GitHub Actions workflow jobs using macOS related runner images ([\#433](https://github.com/fktn-k/fkYAML/pull/433), [fktn-k](https://github.com/fktn-k)) +- Add more GCC & Clang versions to use in GitHub Actions workflows ([\#436](https://github.com/fktn-k/fkYAML/pull/436), [fktn-k](https://github.com/fktn-k)) + +### Full Changelog +https://github.com/fktn-k/fkYAML/compare/v0.3.14...v0.4.0 + ## **fkYAML version 0.3.14** !!! abstract "Release Packages" @@ -9,7 +81,7 @@ * [fkYAML_single_header.zip](https://github.com/fktn-k/fkYAML/releases/download/v0.3.14/fkYAML_single_header.zip) * [fkYAML_single_header.tgz](https://github.com/fktn-k/fkYAML/releases/download/v0.3.14/fkYAML_single_header.tgz) * [node.hpp](https://github.com/fktn-k/fkYAML/releases/download/v0.3.14/node.hpp) (single header) - * [fkyaml_fwd.hpp](https://github.com/fktn-k/fkYAML/releases/download/v0.3.14/node.hpp) (single header) + * [fkyaml_fwd.hpp](https://github.com/fktn-k/fkYAML/releases/download/v0.3.14/fkyaml_fwd.hpp) (single header) ### Summary This release adds the new header file *fkyaml_fwd.hpp* which provides the library's namespace macros and forward declarations of the library's API classes. With the file, you can reduce the compile time cost of including the full library header if some source files do not actually use the library features. diff --git a/docs/mkdocs/docs/home/supported_compilers.md b/docs/mkdocs/docs/home/supported_compilers.md index ada073a0..45957f07 100644 --- a/docs/mkdocs/docs/home/supported_compilers.md +++ b/docs/mkdocs/docs/home/supported_compilers.md @@ -4,19 +4,15 @@ Currently, the following compilers are known to work and used in GitHub Actions | Compiler | Operating System | | -------------------------- | -------------------------------------------------------------------------------------------------------------- | -| AppleClang 13.0.0.13000029 | [macOS 12](https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md) | -| AppleClang 13.1.6.13160021 | [macOS 12](https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md) | -| AppleClang 14.0.0.14000029 | [macOS 12](https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md) | | AppleClang 14.0.0.14000029 | [macOS 13](https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md) | | AppleClang 14.0.3.14030022 | [macOS 13](https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md) | -| AppleClang 14.0.3.14030022 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | | AppleClang 15.0.0.15000040 | [macOS 13](https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md) | | AppleClang 15.0.0.15000040 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | | AppleClang 15.0.0.15000100 | [macOS 13](https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md) | | AppleClang 15.0.0.15000100 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | | AppleClang 15.0.0.15000309 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | -| AppleClang 16.0.0.16000026 | [macOS 14](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md) | | AppleClang 16.0.0.16000026 | [macOS 15](https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md) | +| Clang 3.4.2 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 3.5.2 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 3.6.2 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 3.7.1 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | @@ -36,6 +32,10 @@ Currently, the following compilers are known to work and used in GitHub Actions | Clang 16.0.6 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 17.0.6 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | Clang 18.1.6 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| Clang 19.1.4 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| GCC 4.8.5 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| GCC 5.3.1 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| GCC 6.4.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 7.5.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 8.5.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 9.5.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | @@ -43,7 +43,7 @@ Currently, the following compilers are known to work and used in GitHub Actions | GCC 11.4.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 12.3.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | GCC 13.3.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | -| GCC 14.1.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | +| GCC 14.2.0 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | IntelLLVM 2024.1.2 | [Ubuntu 22.04](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md) | | MinGW-64 8.1.0 | [Windows Server 2019](https://github.com/actions/runner-images/blob/main/images/windows/Windows2019-Readme.md) | | MinGW-64 12.2.0 | [Windows Server 2022](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md) | diff --git a/docs/mkdocs/docs/img/range-rbegin-rend.svg b/docs/mkdocs/docs/img/range-rbegin-rend.svg new file mode 100644 index 00000000..dc6045fc --- /dev/null +++ b/docs/mkdocs/docs/img/range-rbegin-rend.svg @@ -0,0 +1,1232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Past-the-last element + + + + begin + + + + end + + + + + + + + + + + + + + + + + + + + + + + + + Reversed sequence + + Reverse past-the-last element + + + + + + + + rend + + + + rbegin + + + Reverse iterator stores an iterator to the nextelement than the one it actually refers to + + + + + + + + + diff --git a/docs/mkdocs/docs/tutorials/cmake_integration.md b/docs/mkdocs/docs/tutorials/cmake_integration.md index 47510025..d46f56f8 100644 --- a/docs/mkdocs/docs/tutorials/cmake_integration.md +++ b/docs/mkdocs/docs/tutorials/cmake_integration.md @@ -57,7 +57,7 @@ Since CMake v3.11, [`FetchContent`](https://cmake.org/cmake/help/latest/module/F FetchContent_Declare( fkYAML GIT_REPOSITORY https://github.com/fktn-k/fkYAML.git - GIT_TAG v0.3.14 + GIT_TAG v0.4.0 ) FetchContent_MakeAvailable(fkYAML) diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml index 1d404255..d6dc322b 100644 --- a/docs/mkdocs/mkdocs.yml +++ b/docs/mkdocs/mkdocs.yml @@ -107,7 +107,12 @@ nav: - at: api/basic_node/at.md - begin: api/basic_node/begin.md - boolean_type: api/basic_node/boolean_type.md - - const_iterator: api/basic_node/const_iterator.md + - cbegin: api/basic_node/begin.md + - cend: api/basic_node/end.md + - crbegin: api/basic_node/rbegin.md + - crend: api/basic_node/rend.md + - const_iterator: api/basic_node/iterator.md + - const_reverse_iterator: api/basic_node/reverse_iterator.md - contains: api/basic_node/contains.md - deserialize: api/basic_node/deserialize.md - deserialize_docs: api/basic_node/deserialize_docs.md @@ -139,6 +144,9 @@ nav: - mapping: api/basic_node/mapping.md - node_t: api/basic_node/node_t.md - node: api/basic_node/node.md + - rbegin: api/basic_node/rbegin.md + - rend: api/basic_node/rend.md + - reverse_iterator: api/basic_node/reverse_iterator.md - sequence_type: api/basic_node/sequence_type.md - sequence: api/basic_node/sequence.md - serialize: api/basic_node/serialize.md diff --git a/fkYAML.natvis b/fkYAML.natvis index 8a59861b..bb929a19 100644 --- a/fkYAML.natvis +++ b/fkYAML.natvis @@ -4,26 +4,26 @@ - - - {*(m_node_value.p_sequence)} - {*(m_node_value.p_mapping)} - nullptr - {m_node_value.boolean} - {m_node_value.integer} - {m_node_value.float_val} - {*(m_node_value.p_string)} + + + {*(m_node_value.p_sequence)} + {*(m_node_value.p_mapping)} + nullptr + {m_node_value.boolean} + {m_node_value.integer} + {m_node_value.float_val} + {*(m_node_value.p_string)} - + *(m_node_value.p_sequence),view(simple) - + *(m_node_value.p_mapping),view(simple) - + {second} second diff --git a/include/fkYAML/detail/assert.hpp b/include/fkYAML/detail/assert.hpp index c4e1ec18..d439d5b8 100644 --- a/include/fkYAML/detail/assert.hpp +++ b/include/fkYAML/detail/assert.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/conversions/from_node.hpp b/include/fkYAML/detail/conversions/from_node.hpp index 55333be7..4e1801b6 100644 --- a/include/fkYAML/detail/conversions/from_node.hpp +++ b/include/fkYAML/detail/conversions/from_node.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/conversions/scalar_conv.hpp b/include/fkYAML/detail/conversions/scalar_conv.hpp index 70918217..e694c671 100644 --- a/include/fkYAML/detail/conversions/scalar_conv.hpp +++ b/include/fkYAML/detail/conversions/scalar_conv.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/conversions/to_node.hpp b/include/fkYAML/detail/conversions/to_node.hpp index a2d01059..9ff2aa1b 100644 --- a/include/fkYAML/detail/conversions/to_node.hpp +++ b/include/fkYAML/detail/conversions/to_node.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/conversions/to_string.hpp b/include/fkYAML/detail/conversions/to_string.hpp index 9c06a61e..4aa0eaf0 100644 --- a/include/fkYAML/detail/conversions/to_string.hpp +++ b/include/fkYAML/detail/conversions/to_string.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -79,10 +79,10 @@ inline enable_if_t::value> to_string(FloatType oss << v; s = oss.str(); - // If `f` is actually an integer, ".0" must be appended. The result would cause roundtrip issue otherwise. - // https://github.com/fktn-k/fkYAML/issues/405 - const FloatType diff = v - std::floor(v); - if (diff < std::numeric_limits::min()) { + // If `v` is actually an integer and no scientific notation is used for serialization, ".0" must be appended. + // The result would cause a roundtrip issue otherwise. https://github.com/fktn-k/fkYAML/issues/405 + const std::size_t pos = s.find_first_of(".e"); + if (pos == std::string::npos) { s += ".0"; } } diff --git a/include/fkYAML/detail/document_metainfo.hpp b/include/fkYAML/detail/document_metainfo.hpp index df9ec7e4..5f25a4a7 100644 --- a/include/fkYAML/detail/document_metainfo.hpp +++ b/include/fkYAML/detail/document_metainfo.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/encodings/uri_encoding.hpp b/include/fkYAML/detail/encodings/uri_encoding.hpp index f70f8740..d70485fa 100644 --- a/include/fkYAML/detail/encodings/uri_encoding.hpp +++ b/include/fkYAML/detail/encodings/uri_encoding.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -115,7 +115,7 @@ class uri_encoding { return true; default: // alphabets and numbers are also allowed. - return std::isalnum(c); + return static_cast(std::isalnum(c)); } } }; diff --git a/include/fkYAML/detail/encodings/utf_encode_detector.hpp b/include/fkYAML/detail/encodings/utf_encode_detector.hpp index 80e72045..1b75d068 100644 --- a/include/fkYAML/detail/encodings/utf_encode_detector.hpp +++ b/include/fkYAML/detail/encodings/utf_encode_detector.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -100,7 +100,8 @@ struct utf_encode_detector::v return utf_encode_t::UTF_8; } - std::array bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; bytes.fill(0xFFu); for (int i = 0; i < 4 && begin + i != end; i++) { bytes[i] = static_cast(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) @@ -182,7 +183,8 @@ struct utf_encode_detector bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; bytes.fill(0xFFu); for (int i = 0; i < 2 && begin + i != end; i++) { // NOLINTBEGIN(cppcoreguidelines-pro-bounds-constant-array-index) @@ -222,7 +224,8 @@ struct utf_encode_detector bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; const char32_t elem = *begin; bytes[0] = static_cast((elem & 0xFF000000u) >> 24); bytes[1] = static_cast((elem & 0x00FF0000u) >> 16); @@ -251,7 +254,8 @@ struct file_utf_encode_detector { /// @param p_file The input file handle. /// @return A detected encoding type. static utf_encode_t detect(std::FILE* p_file) noexcept { - std::array bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; bytes.fill(0xFFu); for (int i = 0; i < 4; i++) { char byte = 0; @@ -294,7 +298,8 @@ struct stream_utf_encode_detector { /// @param p_file The input file handle. /// @return A detected encoding type. static utf_encode_t detect(std::istream& is) noexcept { - std::array bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; bytes.fill(0xFFu); for (int i = 0; i < 4; i++) { char ch = 0; diff --git a/include/fkYAML/detail/encodings/utf_encode_t.hpp b/include/fkYAML/detail/encodings/utf_encode_t.hpp index 446271a3..ac753490 100644 --- a/include/fkYAML/detail/encodings/utf_encode_t.hpp +++ b/include/fkYAML/detail/encodings/utf_encode_t.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/encodings/utf_encodings.hpp b/include/fkYAML/detail/encodings/utf_encodings.hpp index dc5cdaf2..12b8e52c 100644 --- a/include/fkYAML/detail/encodings/utf_encodings.hpp +++ b/include/fkYAML/detail/encodings/utf_encodings.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/encodings/yaml_escaper.hpp b/include/fkYAML/detail/encodings/yaml_escaper.hpp index 5a7f5a41..9cbbd50d 100644 --- a/include/fkYAML/detail/encodings/yaml_escaper.hpp +++ b/include/fkYAML/detail/encodings/yaml_escaper.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -333,7 +333,8 @@ class yaml_escaper { } static void unescape_escaped_unicode(char32_t codepoint, std::string& buff) { - std::array encode_buff {}; + // the inner curly braces are necessary to build with older compilers. + std::array encode_buff {{}}; uint32_t encoded_size {0}; utf8::from_utf32(codepoint, encode_buff, encoded_size); buff.append(reinterpret_cast(encode_buff.data()), encoded_size); diff --git a/include/fkYAML/detail/input/block_scalar_header.hpp b/include/fkYAML/detail/input/block_scalar_header.hpp index cb50aa9a..cbead4a1 100644 --- a/include/fkYAML/detail/input/block_scalar_header.hpp +++ b/include/fkYAML/detail/input/block_scalar_header.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -26,7 +26,7 @@ enum class chomping_indicator_t : std::uint8_t { struct block_scalar_header { /// Chomping indicator type. chomping_indicator_t chomp {chomping_indicator_t::CLIP}; - /// Indentation for block scalar contents. + /// Content indentation level of a block scalar. uint32_t indent {0}; }; diff --git a/include/fkYAML/detail/input/deserializer.hpp b/include/fkYAML/detail/input/deserializer.hpp index bb79e155..36c84fb7 100644 --- a/include/fkYAML/detail/input/deserializer.hpp +++ b/include/fkYAML/detail/input/deserializer.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -909,9 +909,14 @@ class basic_deserializer { m_flow_token_state = flow_token_state_t::NEEDS_VALUE_OR_SUFFIX; break; case lexical_token_t::ALIAS_PREFIX: { + // An alias node must not specify any properties (tag, anchor). + // https://yaml.org/spec/1.2.2/#71-alias-nodes if FK_YAML_UNLIKELY (m_needs_tag_impl) { throw parse_error("Tag cannot be specified to an alias node", line, indent); } + if FK_YAML_UNLIKELY (m_needs_anchor_impl) { + throw parse_error("Anchor cannot be specified to an alias node.", line, indent); + } std::string token_str = std::string(token.str.begin(), token.str.end()); diff --git a/include/fkYAML/detail/input/input_adapter.hpp b/include/fkYAML/detail/input/input_adapter.hpp index 044ca4fc..58c447d7 100644 --- a/include/fkYAML/detail/input/input_adapter.hpp +++ b/include/fkYAML/detail/input/input_adapter.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/input/lexical_analyzer.hpp b/include/fkYAML/detail/input/lexical_analyzer.hpp index 29e0acf1..5717ed70 100644 --- a/include/fkYAML/detail/input/lexical_analyzer.hpp +++ b/include/fkYAML/detail/input/lexical_analyzer.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -221,16 +221,22 @@ class lexical_analyzer { case '>': { const str_view sv {m_token_begin_itr, m_end_itr}; const std::size_t header_end_pos = sv.find('\n'); + FK_YAML_ASSERT(header_end_pos != str_view::npos); + const uint32_t base_indent = get_current_indent_level(&sv[header_end_pos]); - FK_YAML_ASSERT(!sv.empty()); - token.type = (sv[0] == '|') ? lexical_token_t::BLOCK_LITERAL_SCALAR : lexical_token_t::BLOCK_FOLDED_SCALAR; + if (*m_token_begin_itr == '|') { + token.type = lexical_token_t::BLOCK_LITERAL_SCALAR; + } + else { + token.type = lexical_token_t::BLOCK_FOLDED_SCALAR; + } - FK_YAML_ASSERT(header_end_pos != str_view::npos); const str_view header_line = sv.substr(1, header_end_pos - 1); m_block_scalar_header = convert_to_block_scalar_header(header_line); m_token_begin_itr = sv.begin() + (header_end_pos + 1); - scan_block_style_string_token(m_block_scalar_header.indent, token.str); + m_block_scalar_header.indent = + determine_block_scalar_content_range(base_indent, m_block_scalar_header.indent, token.str); return token; } @@ -299,6 +305,100 @@ class lexical_analyzer { } private: + uint32_t get_current_indent_level(const char* p_line_end) { + // get the beginning position of the current line. + std::size_t line_begin_pos = str_view(m_input_buffer.begin(), p_line_end - 1).find_last_of('\n'); + if (line_begin_pos == str_view::npos) { + line_begin_pos = 0; + } + else { + ++line_begin_pos; + } + const char* p_line_begin = m_input_buffer.begin() + line_begin_pos; + const char* cur_itr = p_line_begin; + + // get the indentation of the current line. + uint32_t indent = 0; + bool indent_found = false; + // 0: none, 1: block seq item, 2: explicit map key, 3: explicit map value + uint32_t context = 0; + while (cur_itr != p_line_end && !indent_found) { + switch (*cur_itr) { + case ' ': + ++indent; + ++cur_itr; + break; + case '-': + switch (*(cur_itr + 1)) { + case ' ': + case '\t': + indent += 2; + cur_itr += 2; + context = 1; + break; + default: + indent_found = true; + break; + } + break; + case '?': + if (*(cur_itr + 1) == ' ') { + indent += 2; + cur_itr += 2; + context = 2; + break; + } + + indent_found = true; + break; + case ':': + switch (*(cur_itr + 1)) { + case ' ': + case '\t': + indent += 2; + cur_itr += 2; + context = 3; + break; + default: + indent_found = true; + break; + } + break; + default: + indent_found = true; + break; + } + } + + // If "- ", "? " and/or ": " occur in the first line of this plain scalar content. + if (context > 0) { + // Check if the first line contains the key separator ": ". + // If so, the indent value remains the current one. + // Otherwise, the indent value is changed based on the last ocurrence of the above 3. + // In any case, multiline plain scalar content must be indented more than the indent value. + const str_view line_content_part {p_line_begin + indent, p_line_end}; + std::size_t key_sep_pos = line_content_part.find(": "); + if (key_sep_pos == str_view::npos) { + key_sep_pos = line_content_part.find(":\t"); + } + + if (key_sep_pos == str_view::npos) { + constexpr char targets[] = "-?:"; + FK_YAML_ASSERT(context - 1 < sizeof(targets)); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) + const char target_char = targets[context - 1]; + + // Find the position of the last ocuurence of "- ", "? " or ": ". + const str_view line_indent_part {p_line_begin, indent}; + const std::size_t block_seq_item_begin_pos = line_indent_part.find_last_of(target_char); + FK_YAML_ASSERT(block_seq_item_begin_pos != str_view::npos); + indent = static_cast(block_seq_item_begin_pos); + } + } + + return indent; + } + /// @brief Skip until a newline code or a null character is found. void scan_comment() { FK_YAML_ASSERT(*m_cur_itr == '#'); @@ -711,7 +811,7 @@ class lexical_analyzer { void determine_plain_scalar_range(str_view& token) { const str_view sv {m_token_begin_itr, m_end_itr}; - constexpr str_view filter = "\n :{}[],"; + constexpr str_view filter {"\n :{}[],"}; std::size_t pos = sv.find_first_of(filter); if FK_YAML_UNLIKELY (pos == str_view::npos) { token = sv; @@ -720,12 +820,28 @@ class lexical_analyzer { } bool ends_loop = false; + uint32_t indent = std::numeric_limits::max(); do { FK_YAML_ASSERT(pos < sv.size()); switch (sv[pos]) { - case '\n': - ends_loop = true; + case '\n': { + if (indent == std::numeric_limits::max()) { + indent = get_current_indent_level(&sv[pos]); + } + + constexpr str_view space_filter {" \t\n"}; + const std::size_t non_space_pos = sv.find_first_not_of(space_filter, pos); + const std::size_t last_newline_pos = sv.find_last_of('\n', non_space_pos); + FK_YAML_ASSERT(last_newline_pos != str_view::npos); + + if (non_space_pos == str_view::npos || non_space_pos - last_newline_pos - 1 <= indent) { + ends_loop = true; + break; + } + + pos = non_space_pos; break; + } case ' ': if FK_YAML_UNLIKELY (pos == sv.size() - 1) { // trim trailing space. @@ -796,56 +912,71 @@ class lexical_analyzer { } /// @brief Scan a block style string token either in the literal or folded style. - /// @param style The style of the given token, either literal or folded. - /// @param chomp The chomping indicator type of the given token, either strip, keep or clip. - /// @param indent The indent size specified for the given token. - void scan_block_style_string_token(uint32_t& indent, str_view& token) { + /// @param base_indent The base indent level of the block scalar. + /// @param indicated_indent The indicated indent level in the block scalar header. 0 means it's not indicated. + /// @param token Storage for the scanned block scalar range. + /// @return The content indentation level of the block scalar. + uint32_t determine_block_scalar_content_range(uint32_t base_indent, uint32_t indicated_indent, str_view& token) { const str_view sv {m_token_begin_itr, m_end_itr}; // Handle leading all-space lines. - constexpr str_view space_filter = " \t\n"; - const std::size_t first_non_space_pos = sv.find_first_not_of(space_filter); - if (first_non_space_pos == str_view::npos) { - // empty block scalar with no subsequent tokens. - indent = static_cast(sv.size()); - token = sv; + uint32_t cur_indent = 0; + uint32_t max_leading_indent = 0; + const char* cur_itr = m_token_begin_itr; + for (bool stop_increment = false; cur_itr != m_end_itr; ++cur_itr) { + const char c = *cur_itr; + if (c == ' ') { + if (!stop_increment) { + ++cur_indent; + } + continue; + } + if (c == '\n') { + max_leading_indent = std::max(cur_indent, max_leading_indent); + cur_indent = 0; + stop_increment = false; + continue; + } + if (c == '\t') { + // Tabs are not counted as an indent character but still part of an empty line. + // See https://yaml.org/spec/1.2.2/#rule-s-indent and https://yaml.org/spec/1.2.2/#64-empty-lines. + stop_increment = true; + continue; + } + break; + } + // all the block scalar contents are empty lines, and no subsequent token exists. + if FK_YAML_UNLIKELY (cur_itr == m_end_itr) { // Without the following iterator update, lexer cannot reach the end of input buffer and causes infinite // loops from the next loop. (https://github.com/fktn-k/fkYAML/pull/410) m_cur_itr = m_end_itr; - return; + + token = sv; + // If there's no non-empty line, the content indentation level is equal to the number of spaces on the + // longest line. https://yaml.org/spec/1.2.2/#8111-block-indentation-indicator + return indicated_indent == 0 ? std::max(cur_indent, max_leading_indent) : base_indent + indicated_indent; } - // get indentation of the first non-space character. - std::size_t last_newline_pos = sv.substr(0, first_non_space_pos).find_last_of('\n'); - if (last_newline_pos == str_view::npos) { - // first_non_space_pos in on the first line. - const auto cur_indent = static_cast(first_non_space_pos); - if (indent == 0) { - indent = cur_indent; - } - else if FK_YAML_UNLIKELY (cur_indent < indent) { - emit_error("A block style scalar is less indented than the indicated level."); - } + // Any leading empty line must not contain more spaces than the first non-empty line. + if FK_YAML_UNLIKELY (cur_indent < max_leading_indent) { + emit_error("Any leading empty line must not be more indented than the first non-empty line."); } - else { - FK_YAML_ASSERT(last_newline_pos < first_non_space_pos); - const auto cur_indent = static_cast(first_non_space_pos - last_newline_pos - 1); - // TODO: preserve and compare the last indentation with `cur_indent` - if (indent == 0) { - indent = cur_indent; - } - else if FK_YAML_UNLIKELY (cur_indent < indent) { - emit_error("A block style scalar is less indented than the indicated level."); - } + if (indicated_indent == 0) { + FK_YAML_ASSERT(base_indent < cur_indent); + indicated_indent = cur_indent - base_indent; + } + else if FK_YAML_UNLIKELY (cur_indent < base_indent + indicated_indent) { + emit_error("The first non-empty line in the block scalar is less indented."); } - last_newline_pos = sv.find('\n', first_non_space_pos + 1); + std::size_t last_newline_pos = sv.find('\n', cur_itr - m_token_begin_itr + 1); if (last_newline_pos == str_view::npos) { last_newline_pos = sv.size(); } + const uint32_t content_indent = base_indent + indicated_indent; while (last_newline_pos < sv.size()) { std::size_t cur_line_end_pos = sv.find('\n', last_newline_pos + 1); if (cur_line_end_pos == str_view::npos) { @@ -859,8 +990,20 @@ class lexical_analyzer { } FK_YAML_ASSERT(last_newline_pos < cur_line_content_begin_pos); - const auto cur_indent = static_cast(cur_line_content_begin_pos - last_newline_pos - 1); - if (cur_indent < indent && sv[cur_line_content_begin_pos] != '\n') { + cur_indent = static_cast(cur_line_content_begin_pos - last_newline_pos - 1); + if (cur_indent < content_indent && sv[cur_line_content_begin_pos] != '\n') { + if FK_YAML_UNLIKELY (cur_indent > base_indent) { + // This path assumes an input like the following: + // ```yaml + // foo: | + // text + // invalid # this line is less indented than the content indent level (2) + // # but more indented than the base indent level (0) + // ``` + // In such cases, the less indented line cannot be the start of the next token. + emit_error("A content line of the block scalar is less indented."); + } + // Interpret less indented non-space characters as the start of the next token. break; } @@ -875,6 +1018,8 @@ class lexical_analyzer { token = sv.substr(0, last_newline_pos); m_cur_itr = token.end(); + + return content_indent; } /// @brief Handle unescaped control characters. @@ -965,7 +1110,7 @@ class lexical_analyzer { /// @param indent A variable to store the retrieved indent size. /// @return Block scalar header information converted from the header line. block_scalar_header convert_to_block_scalar_header(str_view line) { - constexpr str_view comment_prefix = " #"; + constexpr str_view comment_prefix {" #"}; const std::size_t comment_begin_pos = line.find(comment_prefix); if (comment_begin_pos != str_view::npos) { line = line.substr(0, comment_begin_pos); diff --git a/include/fkYAML/detail/input/position_tracker.hpp b/include/fkYAML/detail/input/position_tracker.hpp index dd3ff025..1424600a 100644 --- a/include/fkYAML/detail/input/position_tracker.hpp +++ b/include/fkYAML/detail/input/position_tracker.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/input/scalar_parser.hpp b/include/fkYAML/detail/input/scalar_parser.hpp index cc3c92e6..495faa7e 100644 --- a/include/fkYAML/detail/input/scalar_parser.hpp +++ b/include/fkYAML/detail/input/scalar_parser.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -60,7 +60,7 @@ class scalar_parser { scalar_parser& operator=(const scalar_parser&) = default; scalar_parser(scalar_parser&&) noexcept = default; - scalar_parser& operator=(scalar_parser&&) noexcept = default; + scalar_parser& operator=(scalar_parser&&) noexcept(std::is_nothrow_move_assignable::value) = default; /// @brief Parses a token into a flow scalar (either plain, single quoted or double quoted) /// @param lex_type Lexical token type for the scalar. @@ -75,7 +75,7 @@ class scalar_parser { token = parse_flow_scalar_token(lex_type, token); const node_type value_type = decide_value_type(lex_type, tag_type, token); - return create_scalar_node(value_type, token); + return create_scalar_node(value_type, tag_type, token); } /// @brief Parses a token into a block scalar (either literal or folded) @@ -98,7 +98,7 @@ class scalar_parser { } const node_type value_type = decide_value_type(lex_type, tag_type, token); - return create_scalar_node(value_type, token); + return create_scalar_node(value_type, tag_type, token); } private: @@ -108,20 +108,50 @@ class scalar_parser { /// @return View into the parsed scalar contents. str_view parse_flow_scalar_token(lexical_token_t lex_type, str_view token) { switch (lex_type) { + case lexical_token_t::PLAIN_SCALAR: + token = parse_plain_scalar(token); + break; case lexical_token_t::SINGLE_QUOTED_SCALAR: token = parse_single_quoted_scalar(token); break; case lexical_token_t::DOUBLE_QUOTED_SCALAR: token = parse_double_quoted_scalar(token); break; - case lexical_token_t::PLAIN_SCALAR: - default: - break; + default: // LCOV_EXCL_LINE + unreachable(); // LCOV_EXCL_LINE } return token; } + /// @brief Parses plain scalar contents. + /// @param token Scalar contents. + /// @return View into the parsed scalar contents. + str_view parse_plain_scalar(str_view token) noexcept { + // plain scalars cannot be empty. + FK_YAML_ASSERT(!token.empty()); + + std::size_t newline_pos = token.find('\n'); + if (newline_pos == str_view::npos) { + return token; + } + + m_use_owned_buffer = true; + + if (m_buffer.capacity() < token.size()) { + m_buffer.reserve(token.size()); + } + + do { + process_line_folding(token, newline_pos); + newline_pos = token.find('\n'); + } while (newline_pos != str_view::npos); + + m_buffer.append(token.begin(), token.size()); + + return {m_buffer}; + } + /// @brief Parses single quoted scalar contents. /// @param token Scalar contents. /// @return View into the parsed scalar contents. @@ -130,7 +160,7 @@ class scalar_parser { return token; } - constexpr str_view filter = "\'\n"; + constexpr str_view filter {"\'\n"}; std::size_t pos = token.find_first_of(filter); if (pos == str_view::npos) { return token; @@ -174,7 +204,7 @@ class scalar_parser { return token; } - constexpr str_view filter = "\\\n"; + constexpr str_view filter {"\\\n"}; std::size_t pos = token.find_first_of(filter); if (pos == str_view::npos) { return token; @@ -281,6 +311,8 @@ class scalar_parser { m_use_owned_buffer = true; m_buffer.reserve(token.size()); + constexpr str_view white_space_filter {" \t"}; + std::size_t cur_line_begin_pos = 0; bool has_newline_at_end = true; bool can_be_folded = false; @@ -293,14 +325,21 @@ class scalar_parser { const std::size_t line_size = cur_line_end_pos - cur_line_begin_pos; const str_view line = token.substr(cur_line_begin_pos, line_size); + const bool is_empty = line.find_first_not_of(white_space_filter) == str_view::npos; if (line.size() <= header.indent) { - // empty or less-indented lines are turned into a newline + // A less-indented line is turned into a newline. m_buffer.push_back('\n'); can_be_folded = false; } + else if (is_empty) { + // more-indented empty lines are not folded. + m_buffer.push_back('\n'); + m_buffer.append(line.begin() + header.indent, line.end()); + m_buffer.push_back('\n'); + } else { - const std::size_t non_space_pos = line.find_first_not_of(' '); + const std::size_t non_space_pos = line.find_first_not_of(white_space_filter); const bool is_more_indented = (non_space_pos != str_view::npos) && (non_space_pos > header.indent); if (can_be_folded) { @@ -470,18 +509,16 @@ class scalar_parser { /// @param type Scalar value type. /// @param token Scalar contents. /// @return A YAML scalar object. - basic_node_type create_scalar_node(node_type type, str_view token) { - basic_node_type node {}; - - switch (type) { + basic_node_type create_scalar_node(node_type val_type, tag_t tag_type, str_view token) { + switch (val_type) { case node_type::NULL_OBJECT: { std::nullptr_t null = nullptr; const bool converted = detail::aton(token.begin(), token.end(), null); if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to a null.", m_line, m_indent); } - // The above `node` variable is already null, so no instance creation is needed. - break; + // The default basic_node object is a null scalar node. + return basic_node_type {}; } case node_type::BOOLEAN: { auto boolean = static_cast(false); @@ -489,41 +526,45 @@ class scalar_parser { if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to a boolean.", m_line, m_indent); } - node = basic_node_type(boolean); - break; + return basic_node_type(boolean); } case node_type::INTEGER: { integer_type integer = 0; const bool converted = detail::atoi(token.begin(), token.end(), integer); - if FK_YAML_UNLIKELY (!converted) { + if FK_YAML_LIKELY (converted) { + return basic_node_type(integer); + } + if FK_YAML_UNLIKELY (tag_type == tag_t::INTEGER) { throw parse_error("Failed to convert a scalar to an integer.", m_line, m_indent); } - node = basic_node_type(integer); - break; + + // conversion error from a scalar which is not tagged with !!int is recovered by treating it as a string + // scalar. See https://github.com/fktn-k/fkYAML/issues/428. + return basic_node_type(string_type(token.begin(), token.end())); } case node_type::FLOAT: { float_number_type float_val = 0; const bool converted = detail::atof(token.begin(), token.end(), float_val); - if FK_YAML_UNLIKELY (!converted) { + if FK_YAML_LIKELY (converted) { + return basic_node_type(float_val); + } + if FK_YAML_UNLIKELY (tag_type == tag_t::FLOATING_NUMBER) { throw parse_error("Failed to convert a scalar to a floating point value", m_line, m_indent); } - node = basic_node_type(float_val); - break; + + // conversion error from a scalar which is not tagged with !!float is recovered by treating it as a string + // scalar. See https://github.com/fktn-k/fkYAML/issues/428. + return basic_node_type(string_type(token.begin(), token.end())); } case node_type::STRING: - if (m_use_owned_buffer) { - node = basic_node_type(std::move(m_buffer)); - m_use_owned_buffer = false; - } - else { - node = basic_node_type(std::string(token.begin(), token.end())); + if (!m_use_owned_buffer) { + return basic_node_type(string_type(token.begin(), token.end())); } - break; + m_use_owned_buffer = false; + return basic_node_type(std::move(m_buffer)); default: // LCOV_EXCL_LINE detail::unreachable(); // LCOV_EXCL_LINE } - - return node; } /// Current line diff --git a/include/fkYAML/detail/input/scalar_scanner.hpp b/include/fkYAML/detail/input/scalar_scanner.hpp index 46e00d42..2c2992bb 100644 --- a/include/fkYAML/detail/input/scalar_scanner.hpp +++ b/include/fkYAML/detail/input/scalar_scanner.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/input/tag_resolver.hpp b/include/fkYAML/detail/input/tag_resolver.hpp index 1d56460d..3ced8054 100644 --- a/include/fkYAML/detail/input/tag_resolver.hpp +++ b/include/fkYAML/detail/input/tag_resolver.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -22,8 +22,8 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN -static constexpr str_view default_primary_handle_prefix = "!"; -static constexpr str_view default_secondary_handle_prefix = "tag:yaml.org,2002:"; +static constexpr str_view default_primary_handle_prefix {"!"}; +static constexpr str_view default_secondary_handle_prefix {"tag:yaml.org,2002:"}; template class tag_resolver { diff --git a/include/fkYAML/detail/input/tag_t.hpp b/include/fkYAML/detail/input/tag_t.hpp index 607e8ba6..5a155f95 100644 --- a/include/fkYAML/detail/input/tag_t.hpp +++ b/include/fkYAML/detail/input/tag_t.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/iterator.hpp b/include/fkYAML/detail/iterator.hpp index 43fcda9b..4da676b2 100644 --- a/include/fkYAML/detail/iterator.hpp +++ b/include/fkYAML/detail/iterator.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -18,26 +18,18 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN -/// @brief A tag which tells Iterator will contain sequence value iterator. -struct sequence_iterator_tag {}; - -/// @brief A tag which tells Iterator will contain mapping value iterator. -struct mapping_iterator_tag {}; - /// @brief The template definitions of type information used in @ref Iterator class /// @tparam ValueType The type of iterated elements. template struct iterator_traits { /// A type of iterated elements. - using value_type = ValueType; + using value_type = typename ValueType::value_type; /// A type to represent difference between iterators. - using difference_type = std::ptrdiff_t; - /// A type to represent iterator sizes. - using size_type = std::size_t; + using difference_type = typename ValueType::difference_type; /// A type of an element pointer. - using pointer = value_type*; + using pointer = typename ValueType::pointer; /// A type of reference to an element. - using reference = value_type&; + using reference = typename ValueType::reference; }; /// @brief A specialization of @ref iterator_traits for constant value types. @@ -45,15 +37,13 @@ struct iterator_traits { template struct iterator_traits { /// A type of iterated elements. - using value_type = ValueType; + using value_type = typename ValueType::value_type; /// A type to represent difference between iterators. - using difference_type = std::ptrdiff_t; - /// A type to represent iterator sizes. - using size_type = std::size_t; + using difference_type = typename ValueType::difference_type; /// A type of a constant element pointer. - using pointer = const value_type*; + using pointer = typename ValueType::const_pointer; /// A type of constant reference to an element. - using reference = const value_type&; + using reference = typename ValueType::const_reference; }; /// @brief Definitions of iterator types for iterators internally held. @@ -62,128 +52,100 @@ enum class iterator_t : std::uint8_t { MAPPING, //!< mapping iterator type. }; +/// @brief The actual storage for iterators internally held in iterator. +template +struct iterator_holder { + static_assert( + is_basic_node::value, + "iterator_holder class only accepts a basic_node as its template parameter."); + + /// A sequence iterator object. + typename BasicNodeType::sequence_type::iterator sequence_iterator {}; + /// A mapping iterator object. + typename BasicNodeType::mapping_type::iterator mapping_iterator {}; +}; + /// @brief A class which holds iterators either of sequence or mapping type /// @tparam ValueType The type of iterated elements. template class iterator { + /// @brief The iterator type with ValueType of different const-ness. + using other_iterator_type = typename std::conditional< + std::is_const::value, iterator::type>, + iterator>::type; + + friend other_iterator_type; + public: /// A type for iterator traits of instantiated @Iterator template class. - using ItrTraitsType = iterator_traits; + using iterator_traits_type = iterator_traits; /// A type for iterator category tag. using iterator_category = std::bidirectional_iterator_tag; /// A type of iterated element. - using value_type = typename ItrTraitsType::value_type; + using value_type = typename iterator_traits_type::value_type; /// A type to represent differences between iterators. - using difference_type = typename ItrTraitsType::difference_type; - /// A type to represent container sizes. - using size_type = typename ItrTraitsType::size_type; + using difference_type = typename iterator_traits_type::difference_type; /// A type of an element pointer. - using pointer = typename ItrTraitsType::pointer; + using pointer = typename iterator_traits_type::pointer; /// A type of reference to an element. - using reference = typename ItrTraitsType::reference; + using reference = typename iterator_traits_type::reference; -private: - /// A type of non-const version of iterated elements. - using NonConstValueType = typename std::remove_const::type; + static_assert(is_basic_node::value, "iterator class only accepts a basic_node as its value type."); - static_assert(is_basic_node::value, "Iterator only accepts basic_node<...>"); + /// @brief Constructs an iterator object. + iterator() = default; - /// @brief The actual storage for iterators internally held in @ref Iterator. - struct iterator_holder { - /// A sequence iterator object. - typename NonConstValueType::sequence_type::iterator sequence_iterator {}; - /// A mapping iterator object. - typename NonConstValueType::mapping_type::iterator mapping_iterator {}; - }; - -public: /// @brief Construct a new iterator object with sequence iterator object. /// @param[in] itr An sequence iterator object. - iterator(sequence_iterator_tag /* unused */, const typename ValueType::sequence_type::iterator& itr) noexcept { + iterator(const typename value_type::sequence_type::iterator& itr) noexcept { m_iterator_holder.sequence_iterator = itr; } /// @brief Construct a new iterator object with mapping iterator object. /// @param[in] itr An mapping iterator object. - iterator(mapping_iterator_tag /* unused */, const typename ValueType::mapping_type::iterator& itr) noexcept + iterator(const typename value_type::mapping_type::iterator& itr) noexcept : m_inner_iterator_type(iterator_t::MAPPING) { m_iterator_holder.mapping_iterator = itr; } - /// @brief Copy constructor of the iterator class. - /// @param other An iterator object to be copied with. - iterator(const iterator& other) noexcept - : m_inner_iterator_type(other.m_inner_iterator_type) { - switch (m_inner_iterator_type) { - case iterator_t::SEQUENCE: - m_iterator_holder.sequence_iterator = other.m_iterator_holder.sequence_iterator; - break; - case iterator_t::MAPPING: - m_iterator_holder.mapping_iterator = other.m_iterator_holder.mapping_iterator; - break; - } - } - - /// @brief Move constructor of the iterator class. - /// @param other An iterator object to be moved from. - iterator(iterator&& other) noexcept - : m_inner_iterator_type(other.m_inner_iterator_type) { - switch (m_inner_iterator_type) { - case iterator_t::SEQUENCE: - m_iterator_holder.sequence_iterator = std::move(other.m_iterator_holder.sequence_iterator); - break; - case iterator_t::MAPPING: - m_iterator_holder.mapping_iterator = std::move(other.m_iterator_holder.mapping_iterator); - break; - } + /// @brief Copy constructs an iterator. + iterator(const iterator&) = default; + + /// @brief Copy constructs an iterator from another iterator with different const-ness in ValueType. + /// @note This copy constructor is not defined if ValueType is not const to avoid const removal from ValueType. + /// @tparam OtherIterator The iterator type to copy from. + /// @param other An iterator to copy from with different const-ness in ValueType. + template < + typename OtherIterator, + enable_if_t< + conjunction, std::is_const>::value, int> = 0> + iterator(const OtherIterator& other) noexcept + : m_inner_iterator_type(other.m_inner_iterator_type), + m_iterator_holder(other.m_iterator_holder) { } - /// @brief Destroys an iterator. - ~iterator() = default; - -public: /// @brief A copy assignment operator of the iterator class. - /// @param rhs An iterator object to be copied with. - /// @return iterator& Reference to this iterator object. - iterator& operator=(const iterator& rhs) noexcept { - if FK_YAML_UNLIKELY (&rhs == this) { - return *this; - } - - m_inner_iterator_type = rhs.m_inner_iterator_type; - switch (m_inner_iterator_type) { - case iterator_t::SEQUENCE: - m_iterator_holder.sequence_iterator = rhs.m_iterator_holder.sequence_iterator; - break; - case iterator_t::MAPPING: - m_iterator_holder.mapping_iterator = rhs.m_iterator_holder.mapping_iterator; - break; - } - + iterator& operator=(const iterator&) = default; + + template < + typename OtherIterator, + enable_if_t< + conjunction, std::is_const>::value, int> = 0> + iterator& operator=(const OtherIterator& other) noexcept { + m_inner_iterator_type = other.m_inner_iterator_type; + m_iterator_holder = other.m_iterator_holder; return *this; } - /// @brief A move assignment operator of the iterator class. - /// @param rhs An iterator object to be moved from. - /// @return iterator& Reference to this iterator object. - iterator& operator=(iterator&& rhs) noexcept { - if FK_YAML_UNLIKELY (&rhs == this) { - return *this; - } + /// @brief Move constructs an iterator. + iterator(iterator&&) = default; - m_inner_iterator_type = rhs.m_inner_iterator_type; - switch (m_inner_iterator_type) { - case iterator_t::SEQUENCE: - m_iterator_holder.sequence_iterator = std::move(rhs.m_iterator_holder.sequence_iterator); - break; - case iterator_t::MAPPING: - m_iterator_holder.mapping_iterator = std::move(rhs.m_iterator_holder.mapping_iterator); - break; - } + /// @brief A move assignment operator of the iterator class. + iterator& operator=(iterator&&) = default; - return *this; - } + /// @brief Destroys an iterator. + ~iterator() = default; /// @brief An arrow operator of the iterator class. /// @return pointer A pointer to the BasicNodeType object internally referenced by the actual iterator object. @@ -263,7 +225,7 @@ class iterator { /// @brief A minus operator of the iterator class. /// @param i The difference from this iterator object. /// @return iterator An iterator object from which has been subtracted @ i. - iterator operator-(difference_type i) noexcept { + iterator operator-(difference_type i) const noexcept { auto result = *this; result -= i; return result; @@ -295,7 +257,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is equal to the other. /// @return false This iterator object is not equal to the other. - bool operator==(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator==(const Iterator& rhs) const { if FK_YAML_UNLIKELY (m_inner_iterator_type != rhs.m_inner_iterator_type) { throw fkyaml::exception("Cannot compare iterators of different container types."); } @@ -312,7 +278,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is not equal to the other. /// @return false This iterator object is equal to the other. - bool operator!=(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator!=(const Iterator& rhs) const { return !operator==(rhs); } @@ -320,7 +290,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is less than the other. /// @return false This iterator object is not less than the other. - bool operator<(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator<(const Iterator& rhs) const { if FK_YAML_UNLIKELY (m_inner_iterator_type != rhs.m_inner_iterator_type) { throw fkyaml::exception("Cannot compare iterators of different container types."); } @@ -336,7 +310,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is either less than or equal to the other. /// @return false This iterator object is neither less than nor equal to the other. - bool operator<=(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator<=(const Iterator& rhs) const { return !rhs.operator<(*this); } @@ -344,7 +322,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is greater than the other. /// @return false This iterator object is not greater than the other. - bool operator>(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator>(const Iterator& rhs) const { return !operator<=(rhs); } @@ -352,7 +334,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is either greater than or equal to the other. /// @return false This iterator object is neither greater than nor equal to the other. - bool operator>=(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator>=(const Iterator& rhs) const { return !operator<(rhs); } @@ -363,9 +349,9 @@ class iterator { return m_inner_iterator_type; } - /// @brief Get the key string of the YAML mapping node for the current iterator. - /// @return const std::string& The key string of the YAML mapping node for the current iterator. - const typename ValueType::mapping_type::key_type& key() const { + /// @brief Get the mapping key node of the current iterator. + /// @return The mapping key node of the current iterator. + const typename value_type::mapping_type::key_type& key() const { if FK_YAML_UNLIKELY (m_inner_iterator_type == iterator_t::SEQUENCE) { throw fkyaml::exception("Cannot retrieve key from non-mapping iterators."); } @@ -373,8 +359,8 @@ class iterator { return m_iterator_holder.mapping_iterator->first; } - /// @brief Get the reference of the YAML node for the current iterator. - /// @return reference A reference to the YAML node for the current iterator. + /// @brief Get reference to the YAML node of the current iterator. + /// @return Reference to the YAML node of the current iterator. reference value() noexcept { return operator*(); } @@ -383,7 +369,7 @@ class iterator { /// A type of the internally-held iterator. iterator_t m_inner_iterator_type {iterator_t::SEQUENCE}; /// A holder of actual iterators. - mutable iterator_holder m_iterator_holder {}; + iterator_holder m_iterator_holder {}; }; FK_YAML_DETAIL_NAMESPACE_END diff --git a/include/fkYAML/detail/macros/cpp_config_macros.hpp b/include/fkYAML/detail/macros/cpp_config_macros.hpp index c829c8c4..3706019f 100644 --- a/include/fkYAML/detail/macros/cpp_config_macros.hpp +++ b/include/fkYAML/detail/macros/cpp_config_macros.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/macros/define_macros.hpp b/include/fkYAML/detail/macros/define_macros.hpp index a202ab4d..dc5e7316 100644 --- a/include/fkYAML/detail/macros/define_macros.hpp +++ b/include/fkYAML/detail/macros/define_macros.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/macros/version_macros.hpp b/include/fkYAML/detail/macros/version_macros.hpp index 9d05c6fa..5e5b9481 100644 --- a/include/fkYAML/detail/macros/version_macros.hpp +++ b/include/fkYAML/detail/macros/version_macros.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -8,7 +8,7 @@ // Check version definitions if already defined. #if defined(FK_YAML_MAJOR_VERSION) && defined(FK_YAML_MINOR_VERSION) && defined(FK_YAML_PATCH_VERSION) -#if FK_YAML_MAJOR_VERSION != 0 || FK_YAML_MINOR_VERSION != 3 || FK_YAML_PATCH_VERSION != 14 +#if FK_YAML_MAJOR_VERSION != 0 || FK_YAML_MINOR_VERSION != 4 || FK_YAML_PATCH_VERSION != 0 #warning Already included a different version of the fkYAML library! #else // define macros to skip defining macros down below. @@ -19,8 +19,8 @@ #ifndef FK_YAML_VERCHECK_SUCCEEDED #define FK_YAML_MAJOR_VERSION 0 -#define FK_YAML_MINOR_VERSION 3 -#define FK_YAML_PATCH_VERSION 14 +#define FK_YAML_MINOR_VERSION 4 +#define FK_YAML_PATCH_VERSION 0 #define FK_YAML_NAMESPACE_VERSION_CONCAT_IMPL(major, minor, patch) v##major##_##minor##_##patch diff --git a/include/fkYAML/detail/meta/detect.hpp b/include/fkYAML/detail/meta/detect.hpp index a9b90524..b70f145e 100644 --- a/include/fkYAML/detail/meta/detect.hpp +++ b/include/fkYAML/detail/meta/detect.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/meta/input_adapter_traits.hpp b/include/fkYAML/detail/meta/input_adapter_traits.hpp index b1b5fa6a..28f6c102 100644 --- a/include/fkYAML/detail/meta/input_adapter_traits.hpp +++ b/include/fkYAML/detail/meta/input_adapter_traits.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/meta/node_traits.hpp b/include/fkYAML/detail/meta/node_traits.hpp index ff1f963d..e07e2e4d 100644 --- a/include/fkYAML/detail/meta/node_traits.hpp +++ b/include/fkYAML/detail/meta/node_traits.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/meta/stl_supplement.hpp b/include/fkYAML/detail/meta/stl_supplement.hpp index 5b25d68f..42f8598d 100644 --- a/include/fkYAML/detail/meta/stl_supplement.hpp +++ b/include/fkYAML/detail/meta/stl_supplement.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/meta/type_traits.hpp b/include/fkYAML/detail/meta/type_traits.hpp index 649b7a78..8b223308 100644 --- a/include/fkYAML/detail/meta/type_traits.hpp +++ b/include/fkYAML/detail/meta/type_traits.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/node_attrs.hpp b/include/fkYAML/detail/node_attrs.hpp index 08c95caf..f2b350f5 100644 --- a/include/fkYAML/detail/node_attrs.hpp +++ b/include/fkYAML/detail/node_attrs.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/node_property.hpp b/include/fkYAML/detail/node_property.hpp index cfe72f92..6b448b71 100644 --- a/include/fkYAML/detail/node_property.hpp +++ b/include/fkYAML/detail/node_property.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -17,9 +17,9 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN struct node_property { /// The tag name property. - std::string tag; + std::string tag {}; // NOLINT(readability-redundant-member-init) necessary for older compilers /// The anchor name property. - std::string anchor; + std::string anchor {}; // NOLINT(readability-redundant-member-init) necessary for older compilers }; FK_YAML_DETAIL_NAMESPACE_END diff --git a/include/fkYAML/detail/node_ref_storage.hpp b/include/fkYAML/detail/node_ref_storage.hpp index 38a8fa0e..66350ee8 100644 --- a/include/fkYAML/detail/node_ref_storage.hpp +++ b/include/fkYAML/detail/node_ref_storage.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/output/serializer.hpp b/include/fkYAML/detail/output/serializer.hpp index 9029c6f4..4b795d81 100644 --- a/include/fkYAML/detail/output/serializer.hpp +++ b/include/fkYAML/detail/output/serializer.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/reverse_iterator.hpp b/include/fkYAML/detail/reverse_iterator.hpp new file mode 100644 index 00000000..5eeb5a25 --- /dev/null +++ b/include/fkYAML/detail/reverse_iterator.hpp @@ -0,0 +1,210 @@ +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#ifndef FK_YAML_DETAIL_REVERSE_ITERATOR_HPP +#define FK_YAML_DETAIL_REVERSE_ITERATOR_HPP + +#include + +#include +#include + +FK_YAML_DETAIL_NAMESPACE_BEGIN + +/// @brief An iterator adapter class that reverses the direction of a given node iterator. +/// @tparam Iterator The base iterator type. +template +class reverse_iterator { + static_assert( + is_basic_node::type>::value, + "reverse_iterator only accepts a basic_node type as the underlying iterator's value type"); + +public: + /// @brief The base iterator type. + using iterator_type = Iterator; + + /// @brief The base iterator category. + using iterator_category = typename Iterator::iterator_category; + + /// @brief The type of the pointed-to elements by base iterators. + using value_type = typename Iterator::value_type; + + /// @brief The type to represent differences between the pointed-to elements by the base iterators. + using difference_type = typename Iterator::difference_type; + + /// @brief The type of the pointed-to element pointers by base iterators. + using pointer = typename Iterator::pointer; + + /// @brief The type of the pointed-to element references by base iterators. + using reference = typename Iterator::reference; + + /// @brief Constructs a reverse_iterator object. + reverse_iterator() = default; + + /// @brief Copy constructs a reverse_iterator object. + reverse_iterator(const reverse_iterator&) = default; + + /// @brief Copy assignments a reverse_iterator object. + reverse_iterator& operator=(const reverse_iterator&) = default; + + /// @brief Move constructs a reverse_iterator object. + reverse_iterator(reverse_iterator&&) = default; + + /// @brief Move assignments a reverse_iterator object. + reverse_iterator& operator=(reverse_iterator&&) = default; + + /// @brief Constructs a reverse_iterator object with an underlying iterator object. + /// @param i A base iterator object. + reverse_iterator(const Iterator& i) noexcept + : m_current(i) { + } + + template >::value, int> = 0> + reverse_iterator(const reverse_iterator& other) noexcept + : m_current(other.base()) { + } + + template >::value, int> = 0> + reverse_iterator& operator=(const reverse_iterator& other) noexcept { + m_current = other.base(); + return *this; + } + + /// @brief Destructs a reverse_iterator object. + ~reverse_iterator() = default; + + /// @brief Accesses the underlying iterator object. + /// @return The underlying iterator object. + Iterator base() const noexcept { + return m_current; + } + + /// @brief Get reference to the pointed-to element. + /// @return Reference to the pointed-to element. + reference operator*() const noexcept { + Iterator tmp = m_current; + return *--tmp; + } + + /// @brief Get pointer to the pointed-to element. + /// @return Pointer to the pointed-to element. + pointer operator->() const noexcept { + return &(operator*()); + } + + /// @brief Pre-increments the underlying iterator object. + /// @return Reference to this reverse_iterator object with its underlying iterator incremented. + reverse_iterator& operator++() noexcept { + --m_current; + return *this; + } + + /// @brief Post-increments the underlying iterator object. + /// @return A reverse_iterator object with the underlying iterator as-is. + reverse_iterator operator++(int) & noexcept { + auto result = *this; + --m_current; + return result; + } + + /// @brief Pre-decrements the underlying iterator object. + /// @return Reference to this reverse_iterator with its underlying iterator decremented. + reverse_iterator& operator--() noexcept { + ++m_current; + return *this; + } + + /// @brief Post-decrements the underlying iterator object. + /// @return A reverse_iterator object with the underlying iterator as-is. + reverse_iterator operator--(int) & noexcept { + auto result = *this; + ++m_current; + return result; + } + + /// @brief Advances the underlying iterator object by `n`. + /// @param n The distance by which the underlying iterator is advanced. + /// @return A reverse_iterator object with the underlying iterator advanced by `n`. + reverse_iterator operator+(difference_type n) const noexcept { + return reverse_iterator(m_current - n); + } + + /// @brief Advances the underlying iterator object by `n`. + /// @param n The distance by which the underlying iterator is advanced. + /// @return Reference to this reverse_iterator object with the underlying iterator advanced by `n`. + reverse_iterator& operator+=(difference_type n) noexcept { + m_current -= n; + return *this; + } + + /// @brief Decrements the underlying iterator object by `n`. + /// @param n The distance by which the underlying iterator is decremented. + /// @return A reverse_iterator object with the underlying iterator decremented by `n`. + reverse_iterator operator-(difference_type n) const noexcept { + return reverse_iterator(m_current + n); + } + + /// @brief Decrements the underlying iterator object by `n`. + /// @param n The distance by which the underlying iterator is decremented. + /// @return Reference to this reverse_iterator object with the underlying iterator decremented by `n`. + reverse_iterator& operator-=(difference_type n) noexcept { + m_current += n; + return *this; + } + + /// @brief Get the mapping key node of the underlying iterator. + /// @return The mapping key node of the underlying iterator. + auto key() const -> decltype(std::declval().key()) { + Iterator itr = --(base()); + return itr.key(); + } + + /// @brief Get reference to the underlying iterator's value. + /// @return Reference to the underlying iterator's value. + reference value() noexcept { + Iterator itr = --(base()); + return *itr; + } + +private: + Iterator m_current; +}; + +template +inline bool operator==(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() == rhs.base(); +} + +template +inline bool operator!=(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() != rhs.base(); +} + +template +inline bool operator<(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() > rhs.base(); +} + +template +inline bool operator<=(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() >= rhs.base(); +} + +template +inline bool operator>(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() < rhs.base(); +} + +template +inline bool operator>=(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() <= rhs.base(); +} + +FK_YAML_DETAIL_NAMESPACE_END + +#endif /* FK_YAML_DETAIL_REVERSE_ITERATOR_HPP */ diff --git a/include/fkYAML/detail/str_view.hpp b/include/fkYAML/detail/str_view.hpp index 1be1f5cd..ee0afbd5 100644 --- a/include/fkYAML/detail/str_view.hpp +++ b/include/fkYAML/detail/str_view.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -88,8 +88,10 @@ class basic_str_view { template < typename CharPtrT, enable_if_t< - disjunction, std::is_same>::value, int> = - 0> + conjunction< + negation>, std::is_pointer, + disjunction, std::is_same>>::value, + int> = 0> FK_YAML_CXX17_CONSTEXPR basic_str_view(CharPtrT p_str) noexcept : m_len(traits_type::length(p_str)), mp_str(p_str) { diff --git a/include/fkYAML/detail/string_formatter.hpp b/include/fkYAML/detail/string_formatter.hpp index 90edc50b..5ca5099a 100644 --- a/include/fkYAML/detail/string_formatter.hpp +++ b/include/fkYAML/detail/string_formatter.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/types/lexical_token_t.hpp b/include/fkYAML/detail/types/lexical_token_t.hpp index 372ff159..0fa6d555 100644 --- a/include/fkYAML/detail/types/lexical_token_t.hpp +++ b/include/fkYAML/detail/types/lexical_token_t.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/types/node_t.hpp b/include/fkYAML/detail/types/node_t.hpp index 75149a03..301d5719 100644 --- a/include/fkYAML/detail/types/node_t.hpp +++ b/include/fkYAML/detail/types/node_t.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/types/yaml_version_t.hpp b/include/fkYAML/detail/types/yaml_version_t.hpp index fbeb9413..ea7f590d 100644 --- a/include/fkYAML/detail/types/yaml_version_t.hpp +++ b/include/fkYAML/detail/types/yaml_version_t.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/exception.hpp b/include/fkYAML/exception.hpp index f88ea281..1fa614be 100644 --- a/include/fkYAML/exception.hpp +++ b/include/fkYAML/exception.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/fkyaml_fwd.hpp b/include/fkYAML/fkyaml_fwd.hpp index fc9d2175..863f089b 100644 --- a/include/fkYAML/fkyaml_fwd.hpp +++ b/include/fkYAML/fkyaml_fwd.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/node.hpp b/include/fkYAML/node.hpp index 032c7b39..c9218d43 100644 --- a/include/fkYAML/node.hpp +++ b/include/fkYAML/node.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -49,14 +50,6 @@ template < template class ConverterType> class basic_node { public: - /// @brief A type for iterators of basic_node containers. - /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/iterator/ - using iterator = fkyaml::detail::iterator; - - /// @brief A type for constant iterators of basic_node containers. - /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/const_iterator/ - using const_iterator = fkyaml::detail::iterator; - /// @brief A type for sequence basic_node values. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/sequence_type/ using sequence_type = SequenceType>; @@ -82,6 +75,50 @@ class basic_node { /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/string_type/ using string_type = StringType; + /// @brief A type of elements in a basic_node container. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using value_type = basic_node; + + /// @brief A type of reference to a basic_node element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using reference = value_type&; + + /// @brief A type of constant reference to a basic_node element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using const_reference = const value_type&; + + /// @brief A type of a pointer to a basic_node element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using pointer = value_type*; + + /// @brief A type of a constant pointer to a basic_node element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using const_pointer = const value_type*; + + /// @brief A type to represent basic_node container sizes. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using size_type = std::size_t; + + /// @brief A type to represent differences between basic_node iterators. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using difference_type = std::ptrdiff_t; + + /// @brief A type for iterators of basic_node containers. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/iterator/ + using iterator = fkyaml::detail::iterator; + + /// @brief A type for constant iterators of basic_node containers. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/iterator/ + using const_iterator = fkyaml::detail::iterator; + + /// @brief A type for reverse iterators of basic_node containers. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/reverse_iterator/ + using reverse_iterator = fkyaml::detail::reverse_iterator; + + /// @brief A type for constant reverse iterators of basic_node containers. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/reverse_iterator/ + using const_reverse_iterator = fkyaml::detail::reverse_iterator; + /// @brief A helper alias to determine converter type for the given target native data type. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/value_converter_type/ template @@ -1383,90 +1420,160 @@ class basic_node { swap(m_prop.anchor, rhs.m_prop.anchor); } - /// @brief Returns the first iterator of basic_node values of container types (sequence or mapping) from a non-const - /// basic_node object. Throws exception if the basic_node value is not of container types. - /// @return An iterator to the first element of a YAML node value (either sequence or mapping). + /// @brief Returns an iterator to the first element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return An iterator to the first element of a container node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/begin/ iterator begin() { switch (get_node_attrs() & detail::node_attr_mask::value) { case detail::node_attr_bits::seq_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_sequence != nullptr); - return {detail::sequence_iterator_tag(), p_node_value->p_sequence->begin()}; + return {p_node_value->p_sequence->begin()}; } case detail::node_attr_bits::map_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_mapping != nullptr); - return {detail::mapping_iterator_tag(), p_node_value->p_mapping->begin()}; + return {p_node_value->p_mapping->begin()}; } default: throw fkyaml::type_error("The target node is neither of sequence nor mapping types.", get_type()); } } - /// @brief Returns the first iterator of basic_node values of container types (sequence or mapping) from a const - /// basic_node object. Throws exception if the basic_node value is not of container types. - /// @return A constant iterator to the first element of a YAML node value (either sequence or mapping). + /// @brief Returns a const iterator to the first element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the first element of a container node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/begin/ const_iterator begin() const { switch (get_node_attrs() & detail::node_attr_mask::value) { case detail::node_attr_bits::seq_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_sequence != nullptr); - return {detail::sequence_iterator_tag(), p_node_value->p_sequence->begin()}; + return {p_node_value->p_sequence->begin()}; } case detail::node_attr_bits::map_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_mapping != nullptr); - return {detail::mapping_iterator_tag(), p_node_value->p_mapping->begin()}; + return {p_node_value->p_mapping->begin()}; } default: throw fkyaml::type_error("The target node is neither of sequence nor mapping types.", get_type()); } } - /// @brief Returns the last iterator of basic_node values of container types (sequence or mapping) from a non-const - /// basic_node object. Throws exception if the basic_node value is not of container types. - /// @return An iterator to the past-the end element of a YAML node value (either sequence or mapping). + /// @brief Returns a const iterator to the first element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the first element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/begin/ + const_iterator cbegin() const { + return begin(); + } + + /// @brief Returns an iterator to the past-the-last element of a container node (sequence or mapping). + /// @throw `type_error` if the basic_node value is not of container types. + /// @return An iterator to the past-the-last element of a container node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/end/ iterator end() { switch (get_node_attrs() & detail::node_attr_mask::value) { case detail::node_attr_bits::seq_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_sequence != nullptr); - return {detail::sequence_iterator_tag(), p_node_value->p_sequence->end()}; + return {p_node_value->p_sequence->end()}; } case detail::node_attr_bits::map_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_mapping != nullptr); - return {detail::mapping_iterator_tag(), p_node_value->p_mapping->end()}; + return {p_node_value->p_mapping->end()}; } default: throw fkyaml::type_error("The target node is neither of sequence nor mapping types.", get_type()); } } - /// @brief Returns the last iterator of basic_node values of container types (sequence or mapping) from a const - /// basic_node object. Throws exception if the basic_node value is not of container types. - /// @return A constant iterator to the past-the end element of a YAML node value (either sequence or mapping). + /// @brief Returns a const iterator to the past-the-last element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the past-the-last element of a container node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/end/ const_iterator end() const { switch (get_node_attrs() & detail::node_attr_mask::value) { case detail::node_attr_bits::seq_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_sequence != nullptr); - return {detail::sequence_iterator_tag(), p_node_value->p_sequence->end()}; + return {p_node_value->p_sequence->end()}; } case detail::node_attr_bits::map_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_mapping != nullptr); - return {detail::mapping_iterator_tag(), p_node_value->p_mapping->end()}; + return {p_node_value->p_mapping->end()}; } default: throw fkyaml::type_error("The target node is neither of sequence nor mapping types.", get_type()); } } + /// @brief Returns a const iterator to the past-the-last element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the past-the-last element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/end/ + const_iterator cend() const { + return end(); + } + + /// @brief Returns an iterator to the reverse-beginning (i.e., last) element of a container node (sequence or + /// mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return An iterator to the reverse-beginning element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rbegin/ + reverse_iterator rbegin() { + return {end()}; + } + + /// @brief Returns a const iterator to the reverse-beginning (i.e., last) element of a container node (sequence or + /// mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the reverse-beginning element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rbegin/ + const_reverse_iterator rbegin() const { + return {end()}; + } + + /// @brief Returns a const iterator to the reverse-beginning (i.e., last) element of a container node (sequence or + /// mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the reverse-beginning element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rbegin/ + const_reverse_iterator crbegin() const { + return rbegin(); + } + + /// @brief Returns an iterator to the reverse-end (i.e., one before the first) element of a container node (sequence + /// or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return An iterator to the reverse-end element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rend/ + reverse_iterator rend() { + return {begin()}; + } + + /// @brief Returns a const iterator to the reverse-end (i.e., one before the first) element of a container node + /// (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the reverse-end element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rend/ + const_reverse_iterator rend() const { + return {begin()}; + } + + /// @brief Returns a const iterator to the reverse-end (i.e., one before the first) element of a container node + /// (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the reverse-end element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rend/ + const_reverse_iterator crend() const { + return rend(); + } + private: /// @brief Returns the pointer to the node_value object of either this node or the associated anchor node. /// @return The pointer to the node_value object of either this node or the associated anchor node. diff --git a/include/fkYAML/node_type.hpp b/include/fkYAML/node_type.hpp index 50d5868d..d2e42964 100644 --- a/include/fkYAML/node_type.hpp +++ b/include/fkYAML/node_type.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/node_value_converter.hpp b/include/fkYAML/node_value_converter.hpp index 04ee8303..69e33386 100644 --- a/include/fkYAML/node_value_converter.hpp +++ b/include/fkYAML/node_value_converter.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/ordered_map.hpp b/include/fkYAML/ordered_map.hpp index 3c086e94..6051d07c 100644 --- a/include/fkYAML/ordered_map.hpp +++ b/include/fkYAML/ordered_map.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/yaml_version_type.hpp b/include/fkYAML/yaml_version_type.hpp index 9e938f44..e5817f03 100644 --- a/include/fkYAML/yaml_version_type.hpp +++ b/include/fkYAML/yaml_version_type.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/single_include/fkYAML/fkyaml_fwd.hpp b/single_include/fkYAML/fkyaml_fwd.hpp index 23ce75d6..3565407f 100644 --- a/single_include/fkYAML/fkyaml_fwd.hpp +++ b/single_include/fkYAML/fkyaml_fwd.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -17,7 +17,7 @@ // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -25,7 +25,7 @@ // Check version definitions if already defined. #if defined(FK_YAML_MAJOR_VERSION) && defined(FK_YAML_MINOR_VERSION) && defined(FK_YAML_PATCH_VERSION) -#if FK_YAML_MAJOR_VERSION != 0 || FK_YAML_MINOR_VERSION != 3 || FK_YAML_PATCH_VERSION != 14 +#if FK_YAML_MAJOR_VERSION != 0 || FK_YAML_MINOR_VERSION != 4 || FK_YAML_PATCH_VERSION != 0 #warning Already included a different version of the fkYAML library! #else // define macros to skip defining macros down below. @@ -36,8 +36,8 @@ #ifndef FK_YAML_VERCHECK_SUCCEEDED #define FK_YAML_MAJOR_VERSION 0 -#define FK_YAML_MINOR_VERSION 3 -#define FK_YAML_PATCH_VERSION 14 +#define FK_YAML_MINOR_VERSION 4 +#define FK_YAML_PATCH_VERSION 0 #define FK_YAML_NAMESPACE_VERSION_CONCAT_IMPL(major, minor, patch) v##major##_##minor##_##patch diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index 749a9bbb..77badf72 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -22,7 +22,7 @@ // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -34,7 +34,7 @@ // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -42,7 +42,7 @@ // Check version definitions if already defined. #if defined(FK_YAML_MAJOR_VERSION) && defined(FK_YAML_MINOR_VERSION) && defined(FK_YAML_PATCH_VERSION) -#if FK_YAML_MAJOR_VERSION != 0 || FK_YAML_MINOR_VERSION != 3 || FK_YAML_PATCH_VERSION != 14 +#if FK_YAML_MAJOR_VERSION != 0 || FK_YAML_MINOR_VERSION != 4 || FK_YAML_PATCH_VERSION != 0 #warning Already included a different version of the fkYAML library! #else // define macros to skip defining macros down below. @@ -53,8 +53,8 @@ #ifndef FK_YAML_VERCHECK_SUCCEEDED #define FK_YAML_MAJOR_VERSION 0 -#define FK_YAML_MINOR_VERSION 3 -#define FK_YAML_PATCH_VERSION 14 +#define FK_YAML_MINOR_VERSION 4 +#define FK_YAML_PATCH_VERSION 0 #define FK_YAML_NAMESPACE_VERSION_CONCAT_IMPL(major, minor, patch) v##major##_##minor##_##patch @@ -84,7 +84,7 @@ // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -243,7 +243,7 @@ // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -267,7 +267,7 @@ // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -284,7 +284,7 @@ // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -298,7 +298,7 @@ // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -315,7 +315,7 @@ // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -767,7 +767,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -937,7 +937,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1127,7 +1127,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1192,7 +1192,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1212,7 +1212,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1232,7 +1232,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1348,7 +1348,7 @@ class uri_encoding { return true; default: // alphabets and numbers are also allowed. - return std::isalnum(c); + return static_cast(std::isalnum(c)); } } }; @@ -1360,7 +1360,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1377,7 +1377,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1396,7 +1396,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1446,7 +1446,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1462,7 +1462,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -2034,7 +2034,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -2061,7 +2061,7 @@ enum class chomping_indicator_t : std::uint8_t { struct block_scalar_header { /// Chomping indicator type. chomping_indicator_t chomp {chomping_indicator_t::CLIP}; - /// Indentation for block scalar contents. + /// Content indentation level of a block scalar. uint32_t indent {0}; }; @@ -2072,7 +2072,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -2088,7 +2088,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -2180,8 +2180,10 @@ class basic_str_view { template < typename CharPtrT, enable_if_t< - disjunction, std::is_same>::value, int> = - 0> + conjunction< + negation>, std::is_pointer, + disjunction, std::is_same>>::value, + int> = 0> FK_YAML_CXX17_CONSTEXPR basic_str_view(CharPtrT p_str) noexcept : m_len(traits_type::length(p_str)), mp_str(p_str) { @@ -3156,7 +3158,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -3402,16 +3404,22 @@ class lexical_analyzer { case '>': { const str_view sv {m_token_begin_itr, m_end_itr}; const std::size_t header_end_pos = sv.find('\n'); + FK_YAML_ASSERT(header_end_pos != str_view::npos); + const uint32_t base_indent = get_current_indent_level(&sv[header_end_pos]); - FK_YAML_ASSERT(!sv.empty()); - token.type = (sv[0] == '|') ? lexical_token_t::BLOCK_LITERAL_SCALAR : lexical_token_t::BLOCK_FOLDED_SCALAR; + if (*m_token_begin_itr == '|') { + token.type = lexical_token_t::BLOCK_LITERAL_SCALAR; + } + else { + token.type = lexical_token_t::BLOCK_FOLDED_SCALAR; + } - FK_YAML_ASSERT(header_end_pos != str_view::npos); const str_view header_line = sv.substr(1, header_end_pos - 1); m_block_scalar_header = convert_to_block_scalar_header(header_line); m_token_begin_itr = sv.begin() + (header_end_pos + 1); - scan_block_style_string_token(m_block_scalar_header.indent, token.str); + m_block_scalar_header.indent = + determine_block_scalar_content_range(base_indent, m_block_scalar_header.indent, token.str); return token; } @@ -3480,6 +3488,100 @@ class lexical_analyzer { } private: + uint32_t get_current_indent_level(const char* p_line_end) { + // get the beginning position of the current line. + std::size_t line_begin_pos = str_view(m_input_buffer.begin(), p_line_end - 1).find_last_of('\n'); + if (line_begin_pos == str_view::npos) { + line_begin_pos = 0; + } + else { + ++line_begin_pos; + } + const char* p_line_begin = m_input_buffer.begin() + line_begin_pos; + const char* cur_itr = p_line_begin; + + // get the indentation of the current line. + uint32_t indent = 0; + bool indent_found = false; + // 0: none, 1: block seq item, 2: explicit map key, 3: explicit map value + uint32_t context = 0; + while (cur_itr != p_line_end && !indent_found) { + switch (*cur_itr) { + case ' ': + ++indent; + ++cur_itr; + break; + case '-': + switch (*(cur_itr + 1)) { + case ' ': + case '\t': + indent += 2; + cur_itr += 2; + context = 1; + break; + default: + indent_found = true; + break; + } + break; + case '?': + if (*(cur_itr + 1) == ' ') { + indent += 2; + cur_itr += 2; + context = 2; + break; + } + + indent_found = true; + break; + case ':': + switch (*(cur_itr + 1)) { + case ' ': + case '\t': + indent += 2; + cur_itr += 2; + context = 3; + break; + default: + indent_found = true; + break; + } + break; + default: + indent_found = true; + break; + } + } + + // If "- ", "? " and/or ": " occur in the first line of this plain scalar content. + if (context > 0) { + // Check if the first line contains the key separator ": ". + // If so, the indent value remains the current one. + // Otherwise, the indent value is changed based on the last ocurrence of the above 3. + // In any case, multiline plain scalar content must be indented more than the indent value. + const str_view line_content_part {p_line_begin + indent, p_line_end}; + std::size_t key_sep_pos = line_content_part.find(": "); + if (key_sep_pos == str_view::npos) { + key_sep_pos = line_content_part.find(":\t"); + } + + if (key_sep_pos == str_view::npos) { + constexpr char targets[] = "-?:"; + FK_YAML_ASSERT(context - 1 < sizeof(targets)); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) + const char target_char = targets[context - 1]; + + // Find the position of the last ocuurence of "- ", "? " or ": ". + const str_view line_indent_part {p_line_begin, indent}; + const std::size_t block_seq_item_begin_pos = line_indent_part.find_last_of(target_char); + FK_YAML_ASSERT(block_seq_item_begin_pos != str_view::npos); + indent = static_cast(block_seq_item_begin_pos); + } + } + + return indent; + } + /// @brief Skip until a newline code or a null character is found. void scan_comment() { FK_YAML_ASSERT(*m_cur_itr == '#'); @@ -3892,7 +3994,7 @@ class lexical_analyzer { void determine_plain_scalar_range(str_view& token) { const str_view sv {m_token_begin_itr, m_end_itr}; - constexpr str_view filter = "\n :{}[],"; + constexpr str_view filter {"\n :{}[],"}; std::size_t pos = sv.find_first_of(filter); if FK_YAML_UNLIKELY (pos == str_view::npos) { token = sv; @@ -3901,12 +4003,28 @@ class lexical_analyzer { } bool ends_loop = false; + uint32_t indent = std::numeric_limits::max(); do { FK_YAML_ASSERT(pos < sv.size()); switch (sv[pos]) { - case '\n': - ends_loop = true; + case '\n': { + if (indent == std::numeric_limits::max()) { + indent = get_current_indent_level(&sv[pos]); + } + + constexpr str_view space_filter {" \t\n"}; + const std::size_t non_space_pos = sv.find_first_not_of(space_filter, pos); + const std::size_t last_newline_pos = sv.find_last_of('\n', non_space_pos); + FK_YAML_ASSERT(last_newline_pos != str_view::npos); + + if (non_space_pos == str_view::npos || non_space_pos - last_newline_pos - 1 <= indent) { + ends_loop = true; + break; + } + + pos = non_space_pos; break; + } case ' ': if FK_YAML_UNLIKELY (pos == sv.size() - 1) { // trim trailing space. @@ -3977,56 +4095,71 @@ class lexical_analyzer { } /// @brief Scan a block style string token either in the literal or folded style. - /// @param style The style of the given token, either literal or folded. - /// @param chomp The chomping indicator type of the given token, either strip, keep or clip. - /// @param indent The indent size specified for the given token. - void scan_block_style_string_token(uint32_t& indent, str_view& token) { + /// @param base_indent The base indent level of the block scalar. + /// @param indicated_indent The indicated indent level in the block scalar header. 0 means it's not indicated. + /// @param token Storage for the scanned block scalar range. + /// @return The content indentation level of the block scalar. + uint32_t determine_block_scalar_content_range(uint32_t base_indent, uint32_t indicated_indent, str_view& token) { const str_view sv {m_token_begin_itr, m_end_itr}; // Handle leading all-space lines. - constexpr str_view space_filter = " \t\n"; - const std::size_t first_non_space_pos = sv.find_first_not_of(space_filter); - if (first_non_space_pos == str_view::npos) { - // empty block scalar with no subsequent tokens. - indent = static_cast(sv.size()); - token = sv; + uint32_t cur_indent = 0; + uint32_t max_leading_indent = 0; + const char* cur_itr = m_token_begin_itr; + for (bool stop_increment = false; cur_itr != m_end_itr; ++cur_itr) { + const char c = *cur_itr; + if (c == ' ') { + if (!stop_increment) { + ++cur_indent; + } + continue; + } + if (c == '\n') { + max_leading_indent = std::max(cur_indent, max_leading_indent); + cur_indent = 0; + stop_increment = false; + continue; + } + if (c == '\t') { + // Tabs are not counted as an indent character but still part of an empty line. + // See https://yaml.org/spec/1.2.2/#rule-s-indent and https://yaml.org/spec/1.2.2/#64-empty-lines. + stop_increment = true; + continue; + } + break; + } + // all the block scalar contents are empty lines, and no subsequent token exists. + if FK_YAML_UNLIKELY (cur_itr == m_end_itr) { // Without the following iterator update, lexer cannot reach the end of input buffer and causes infinite // loops from the next loop. (https://github.com/fktn-k/fkYAML/pull/410) m_cur_itr = m_end_itr; - return; + + token = sv; + // If there's no non-empty line, the content indentation level is equal to the number of spaces on the + // longest line. https://yaml.org/spec/1.2.2/#8111-block-indentation-indicator + return indicated_indent == 0 ? std::max(cur_indent, max_leading_indent) : base_indent + indicated_indent; } - // get indentation of the first non-space character. - std::size_t last_newline_pos = sv.substr(0, first_non_space_pos).find_last_of('\n'); - if (last_newline_pos == str_view::npos) { - // first_non_space_pos in on the first line. - const auto cur_indent = static_cast(first_non_space_pos); - if (indent == 0) { - indent = cur_indent; - } - else if FK_YAML_UNLIKELY (cur_indent < indent) { - emit_error("A block style scalar is less indented than the indicated level."); - } + // Any leading empty line must not contain more spaces than the first non-empty line. + if FK_YAML_UNLIKELY (cur_indent < max_leading_indent) { + emit_error("Any leading empty line must not be more indented than the first non-empty line."); } - else { - FK_YAML_ASSERT(last_newline_pos < first_non_space_pos); - const auto cur_indent = static_cast(first_non_space_pos - last_newline_pos - 1); - // TODO: preserve and compare the last indentation with `cur_indent` - if (indent == 0) { - indent = cur_indent; - } - else if FK_YAML_UNLIKELY (cur_indent < indent) { - emit_error("A block style scalar is less indented than the indicated level."); - } + if (indicated_indent == 0) { + FK_YAML_ASSERT(base_indent < cur_indent); + indicated_indent = cur_indent - base_indent; + } + else if FK_YAML_UNLIKELY (cur_indent < base_indent + indicated_indent) { + emit_error("The first non-empty line in the block scalar is less indented."); } - last_newline_pos = sv.find('\n', first_non_space_pos + 1); + std::size_t last_newline_pos = sv.find('\n', cur_itr - m_token_begin_itr + 1); if (last_newline_pos == str_view::npos) { last_newline_pos = sv.size(); } + const uint32_t content_indent = base_indent + indicated_indent; while (last_newline_pos < sv.size()) { std::size_t cur_line_end_pos = sv.find('\n', last_newline_pos + 1); if (cur_line_end_pos == str_view::npos) { @@ -4040,8 +4173,20 @@ class lexical_analyzer { } FK_YAML_ASSERT(last_newline_pos < cur_line_content_begin_pos); - const auto cur_indent = static_cast(cur_line_content_begin_pos - last_newline_pos - 1); - if (cur_indent < indent && sv[cur_line_content_begin_pos] != '\n') { + cur_indent = static_cast(cur_line_content_begin_pos - last_newline_pos - 1); + if (cur_indent < content_indent && sv[cur_line_content_begin_pos] != '\n') { + if FK_YAML_UNLIKELY (cur_indent > base_indent) { + // This path assumes an input like the following: + // ```yaml + // foo: | + // text + // invalid # this line is less indented than the content indent level (2) + // # but more indented than the base indent level (0) + // ``` + // In such cases, the less indented line cannot be the start of the next token. + emit_error("A content line of the block scalar is less indented."); + } + // Interpret less indented non-space characters as the start of the next token. break; } @@ -4056,6 +4201,8 @@ class lexical_analyzer { token = sv.substr(0, last_newline_pos); m_cur_itr = token.end(); + + return content_indent; } /// @brief Handle unescaped control characters. @@ -4146,7 +4293,7 @@ class lexical_analyzer { /// @param indent A variable to store the retrieved indent size. /// @return Block scalar header information converted from the header line. block_scalar_header convert_to_block_scalar_header(str_view line) { - constexpr str_view comment_prefix = " #"; + constexpr str_view comment_prefix {" #"}; const std::size_t comment_begin_pos = line.find(comment_prefix); if (comment_begin_pos != str_view::npos) { line = line.substr(0, comment_begin_pos); @@ -4274,7 +4421,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -4290,7 +4437,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -5130,7 +5277,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -5467,7 +5614,8 @@ class yaml_escaper { } static void unescape_escaped_unicode(char32_t codepoint, std::string& buff) { - std::array encode_buff {}; + // the inner curly braces are necessary to build with older compilers. + std::array encode_buff {{}}; uint32_t encoded_size {0}; utf8::from_utf32(codepoint, encode_buff, encoded_size); buff.append(reinterpret_cast(encode_buff.data()), encoded_size); @@ -5483,7 +5631,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -5819,7 +5967,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -5902,7 +6050,7 @@ class scalar_parser { scalar_parser& operator=(const scalar_parser&) = default; scalar_parser(scalar_parser&&) noexcept = default; - scalar_parser& operator=(scalar_parser&&) noexcept = default; + scalar_parser& operator=(scalar_parser&&) noexcept(std::is_nothrow_move_assignable::value) = default; /// @brief Parses a token into a flow scalar (either plain, single quoted or double quoted) /// @param lex_type Lexical token type for the scalar. @@ -5917,7 +6065,7 @@ class scalar_parser { token = parse_flow_scalar_token(lex_type, token); const node_type value_type = decide_value_type(lex_type, tag_type, token); - return create_scalar_node(value_type, token); + return create_scalar_node(value_type, tag_type, token); } /// @brief Parses a token into a block scalar (either literal or folded) @@ -5940,7 +6088,7 @@ class scalar_parser { } const node_type value_type = decide_value_type(lex_type, tag_type, token); - return create_scalar_node(value_type, token); + return create_scalar_node(value_type, tag_type, token); } private: @@ -5950,20 +6098,50 @@ class scalar_parser { /// @return View into the parsed scalar contents. str_view parse_flow_scalar_token(lexical_token_t lex_type, str_view token) { switch (lex_type) { + case lexical_token_t::PLAIN_SCALAR: + token = parse_plain_scalar(token); + break; case lexical_token_t::SINGLE_QUOTED_SCALAR: token = parse_single_quoted_scalar(token); break; case lexical_token_t::DOUBLE_QUOTED_SCALAR: token = parse_double_quoted_scalar(token); break; - case lexical_token_t::PLAIN_SCALAR: - default: - break; + default: // LCOV_EXCL_LINE + unreachable(); // LCOV_EXCL_LINE } return token; } + /// @brief Parses plain scalar contents. + /// @param token Scalar contents. + /// @return View into the parsed scalar contents. + str_view parse_plain_scalar(str_view token) noexcept { + // plain scalars cannot be empty. + FK_YAML_ASSERT(!token.empty()); + + std::size_t newline_pos = token.find('\n'); + if (newline_pos == str_view::npos) { + return token; + } + + m_use_owned_buffer = true; + + if (m_buffer.capacity() < token.size()) { + m_buffer.reserve(token.size()); + } + + do { + process_line_folding(token, newline_pos); + newline_pos = token.find('\n'); + } while (newline_pos != str_view::npos); + + m_buffer.append(token.begin(), token.size()); + + return {m_buffer}; + } + /// @brief Parses single quoted scalar contents. /// @param token Scalar contents. /// @return View into the parsed scalar contents. @@ -5972,7 +6150,7 @@ class scalar_parser { return token; } - constexpr str_view filter = "\'\n"; + constexpr str_view filter {"\'\n"}; std::size_t pos = token.find_first_of(filter); if (pos == str_view::npos) { return token; @@ -6016,7 +6194,7 @@ class scalar_parser { return token; } - constexpr str_view filter = "\\\n"; + constexpr str_view filter {"\\\n"}; std::size_t pos = token.find_first_of(filter); if (pos == str_view::npos) { return token; @@ -6123,6 +6301,8 @@ class scalar_parser { m_use_owned_buffer = true; m_buffer.reserve(token.size()); + constexpr str_view white_space_filter {" \t"}; + std::size_t cur_line_begin_pos = 0; bool has_newline_at_end = true; bool can_be_folded = false; @@ -6135,14 +6315,21 @@ class scalar_parser { const std::size_t line_size = cur_line_end_pos - cur_line_begin_pos; const str_view line = token.substr(cur_line_begin_pos, line_size); + const bool is_empty = line.find_first_not_of(white_space_filter) == str_view::npos; if (line.size() <= header.indent) { - // empty or less-indented lines are turned into a newline + // A less-indented line is turned into a newline. m_buffer.push_back('\n'); can_be_folded = false; } + else if (is_empty) { + // more-indented empty lines are not folded. + m_buffer.push_back('\n'); + m_buffer.append(line.begin() + header.indent, line.end()); + m_buffer.push_back('\n'); + } else { - const std::size_t non_space_pos = line.find_first_not_of(' '); + const std::size_t non_space_pos = line.find_first_not_of(white_space_filter); const bool is_more_indented = (non_space_pos != str_view::npos) && (non_space_pos > header.indent); if (can_be_folded) { @@ -6312,18 +6499,16 @@ class scalar_parser { /// @param type Scalar value type. /// @param token Scalar contents. /// @return A YAML scalar object. - basic_node_type create_scalar_node(node_type type, str_view token) { - basic_node_type node {}; - - switch (type) { + basic_node_type create_scalar_node(node_type val_type, tag_t tag_type, str_view token) { + switch (val_type) { case node_type::NULL_OBJECT: { std::nullptr_t null = nullptr; const bool converted = detail::aton(token.begin(), token.end(), null); if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to a null.", m_line, m_indent); } - // The above `node` variable is already null, so no instance creation is needed. - break; + // The default basic_node object is a null scalar node. + return basic_node_type {}; } case node_type::BOOLEAN: { auto boolean = static_cast(false); @@ -6331,41 +6516,45 @@ class scalar_parser { if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to a boolean.", m_line, m_indent); } - node = basic_node_type(boolean); - break; + return basic_node_type(boolean); } case node_type::INTEGER: { integer_type integer = 0; const bool converted = detail::atoi(token.begin(), token.end(), integer); - if FK_YAML_UNLIKELY (!converted) { + if FK_YAML_LIKELY (converted) { + return basic_node_type(integer); + } + if FK_YAML_UNLIKELY (tag_type == tag_t::INTEGER) { throw parse_error("Failed to convert a scalar to an integer.", m_line, m_indent); } - node = basic_node_type(integer); - break; + + // conversion error from a scalar which is not tagged with !!int is recovered by treating it as a string + // scalar. See https://github.com/fktn-k/fkYAML/issues/428. + return basic_node_type(string_type(token.begin(), token.end())); } case node_type::FLOAT: { float_number_type float_val = 0; const bool converted = detail::atof(token.begin(), token.end(), float_val); - if FK_YAML_UNLIKELY (!converted) { + if FK_YAML_LIKELY (converted) { + return basic_node_type(float_val); + } + if FK_YAML_UNLIKELY (tag_type == tag_t::FLOATING_NUMBER) { throw parse_error("Failed to convert a scalar to a floating point value", m_line, m_indent); } - node = basic_node_type(float_val); - break; + + // conversion error from a scalar which is not tagged with !!float is recovered by treating it as a string + // scalar. See https://github.com/fktn-k/fkYAML/issues/428. + return basic_node_type(string_type(token.begin(), token.end())); } case node_type::STRING: - if (m_use_owned_buffer) { - node = basic_node_type(std::move(m_buffer)); - m_use_owned_buffer = false; + if (!m_use_owned_buffer) { + return basic_node_type(string_type(token.begin(), token.end())); } - else { - node = basic_node_type(std::string(token.begin(), token.end())); - } - break; + m_use_owned_buffer = false; + return basic_node_type(std::move(m_buffer)); default: // LCOV_EXCL_LINE detail::unreachable(); // LCOV_EXCL_LINE } - - return node; } /// Current line @@ -6385,7 +6574,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -6414,8 +6603,8 @@ FK_YAML_DETAIL_NAMESPACE_END FK_YAML_DETAIL_NAMESPACE_BEGIN -static constexpr str_view default_primary_handle_prefix = "!"; -static constexpr str_view default_secondary_handle_prefix = "tag:yaml.org,2002:"; +static constexpr str_view default_primary_handle_prefix {"!"}; +static constexpr str_view default_secondary_handle_prefix {"tag:yaml.org,2002:"}; template class tag_resolver { @@ -6570,7 +6759,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -6683,7 +6872,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -6824,7 +7013,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -6842,9 +7031,9 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN struct node_property { /// The tag name property. - std::string tag; + std::string tag {}; // NOLINT(readability-redundant-member-init) necessary for older compilers /// The anchor name property. - std::string anchor; + std::string anchor {}; // NOLINT(readability-redundant-member-init) necessary for older compilers }; FK_YAML_DETAIL_NAMESPACE_END @@ -7739,9 +7928,14 @@ class basic_deserializer { m_flow_token_state = flow_token_state_t::NEEDS_VALUE_OR_SUFFIX; break; case lexical_token_t::ALIAS_PREFIX: { + // An alias node must not specify any properties (tag, anchor). + // https://yaml.org/spec/1.2.2/#71-alias-nodes if FK_YAML_UNLIKELY (m_needs_tag_impl) { throw parse_error("Tag cannot be specified to an alias node", line, indent); } + if FK_YAML_UNLIKELY (m_needs_anchor_impl) { + throw parse_error("Anchor cannot be specified to an alias node.", line, indent); + } std::string token_str = std::string(token.str.begin(), token.str.end()); @@ -8119,7 +8313,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -8142,7 +8336,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -8159,7 +8353,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -8278,7 +8472,8 @@ struct utf_encode_detector::v return utf_encode_t::UTF_8; } - std::array bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; bytes.fill(0xFFu); for (int i = 0; i < 4 && begin + i != end; i++) { bytes[i] = static_cast(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) @@ -8360,7 +8555,8 @@ struct utf_encode_detector bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; bytes.fill(0xFFu); for (int i = 0; i < 2 && begin + i != end; i++) { // NOLINTBEGIN(cppcoreguidelines-pro-bounds-constant-array-index) @@ -8400,7 +8596,8 @@ struct utf_encode_detector bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; const char32_t elem = *begin; bytes[0] = static_cast((elem & 0xFF000000u) >> 24); bytes[1] = static_cast((elem & 0x00FF0000u) >> 16); @@ -8429,7 +8626,8 @@ struct file_utf_encode_detector { /// @param p_file The input file handle. /// @return A detected encoding type. static utf_encode_t detect(std::FILE* p_file) noexcept { - std::array bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; bytes.fill(0xFFu); for (int i = 0; i < 4; i++) { char byte = 0; @@ -8472,7 +8670,8 @@ struct stream_utf_encode_detector { /// @param p_file The input file handle. /// @return A detected encoding type. static utf_encode_t detect(std::istream& is) noexcept { - std::array bytes {}; + // the inner curly braces are necessary for older compilers + std::array bytes {{}}; bytes.fill(0xFFu); for (int i = 0; i < 4; i++) { char ch = 0; @@ -9556,7 +9755,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -9577,26 +9776,18 @@ FK_YAML_DETAIL_NAMESPACE_END FK_YAML_DETAIL_NAMESPACE_BEGIN -/// @brief A tag which tells Iterator will contain sequence value iterator. -struct sequence_iterator_tag {}; - -/// @brief A tag which tells Iterator will contain mapping value iterator. -struct mapping_iterator_tag {}; - /// @brief The template definitions of type information used in @ref Iterator class /// @tparam ValueType The type of iterated elements. template struct iterator_traits { /// A type of iterated elements. - using value_type = ValueType; + using value_type = typename ValueType::value_type; /// A type to represent difference between iterators. - using difference_type = std::ptrdiff_t; - /// A type to represent iterator sizes. - using size_type = std::size_t; + using difference_type = typename ValueType::difference_type; /// A type of an element pointer. - using pointer = value_type*; + using pointer = typename ValueType::pointer; /// A type of reference to an element. - using reference = value_type&; + using reference = typename ValueType::reference; }; /// @brief A specialization of @ref iterator_traits for constant value types. @@ -9604,15 +9795,13 @@ struct iterator_traits { template struct iterator_traits { /// A type of iterated elements. - using value_type = ValueType; + using value_type = typename ValueType::value_type; /// A type to represent difference between iterators. - using difference_type = std::ptrdiff_t; - /// A type to represent iterator sizes. - using size_type = std::size_t; + using difference_type = typename ValueType::difference_type; /// A type of a constant element pointer. - using pointer = const value_type*; + using pointer = typename ValueType::const_pointer; /// A type of constant reference to an element. - using reference = const value_type&; + using reference = typename ValueType::const_reference; }; /// @brief Definitions of iterator types for iterators internally held. @@ -9621,128 +9810,100 @@ enum class iterator_t : std::uint8_t { MAPPING, //!< mapping iterator type. }; +/// @brief The actual storage for iterators internally held in iterator. +template +struct iterator_holder { + static_assert( + is_basic_node::value, + "iterator_holder class only accepts a basic_node as its template parameter."); + + /// A sequence iterator object. + typename BasicNodeType::sequence_type::iterator sequence_iterator {}; + /// A mapping iterator object. + typename BasicNodeType::mapping_type::iterator mapping_iterator {}; +}; + /// @brief A class which holds iterators either of sequence or mapping type /// @tparam ValueType The type of iterated elements. template class iterator { + /// @brief The iterator type with ValueType of different const-ness. + using other_iterator_type = typename std::conditional< + std::is_const::value, iterator::type>, + iterator>::type; + + friend other_iterator_type; + public: /// A type for iterator traits of instantiated @Iterator template class. - using ItrTraitsType = iterator_traits; + using iterator_traits_type = iterator_traits; /// A type for iterator category tag. using iterator_category = std::bidirectional_iterator_tag; /// A type of iterated element. - using value_type = typename ItrTraitsType::value_type; + using value_type = typename iterator_traits_type::value_type; /// A type to represent differences between iterators. - using difference_type = typename ItrTraitsType::difference_type; - /// A type to represent container sizes. - using size_type = typename ItrTraitsType::size_type; + using difference_type = typename iterator_traits_type::difference_type; /// A type of an element pointer. - using pointer = typename ItrTraitsType::pointer; + using pointer = typename iterator_traits_type::pointer; /// A type of reference to an element. - using reference = typename ItrTraitsType::reference; - -private: - /// A type of non-const version of iterated elements. - using NonConstValueType = typename std::remove_const::type; + using reference = typename iterator_traits_type::reference; - static_assert(is_basic_node::value, "Iterator only accepts basic_node<...>"); + static_assert(is_basic_node::value, "iterator class only accepts a basic_node as its value type."); - /// @brief The actual storage for iterators internally held in @ref Iterator. - struct iterator_holder { - /// A sequence iterator object. - typename NonConstValueType::sequence_type::iterator sequence_iterator {}; - /// A mapping iterator object. - typename NonConstValueType::mapping_type::iterator mapping_iterator {}; - }; + /// @brief Constructs an iterator object. + iterator() = default; -public: /// @brief Construct a new iterator object with sequence iterator object. /// @param[in] itr An sequence iterator object. - iterator(sequence_iterator_tag /* unused */, const typename ValueType::sequence_type::iterator& itr) noexcept { + iterator(const typename value_type::sequence_type::iterator& itr) noexcept { m_iterator_holder.sequence_iterator = itr; } /// @brief Construct a new iterator object with mapping iterator object. /// @param[in] itr An mapping iterator object. - iterator(mapping_iterator_tag /* unused */, const typename ValueType::mapping_type::iterator& itr) noexcept + iterator(const typename value_type::mapping_type::iterator& itr) noexcept : m_inner_iterator_type(iterator_t::MAPPING) { m_iterator_holder.mapping_iterator = itr; } - /// @brief Copy constructor of the iterator class. - /// @param other An iterator object to be copied with. - iterator(const iterator& other) noexcept - : m_inner_iterator_type(other.m_inner_iterator_type) { - switch (m_inner_iterator_type) { - case iterator_t::SEQUENCE: - m_iterator_holder.sequence_iterator = other.m_iterator_holder.sequence_iterator; - break; - case iterator_t::MAPPING: - m_iterator_holder.mapping_iterator = other.m_iterator_holder.mapping_iterator; - break; - } - } + /// @brief Copy constructs an iterator. + iterator(const iterator&) = default; - /// @brief Move constructor of the iterator class. - /// @param other An iterator object to be moved from. - iterator(iterator&& other) noexcept - : m_inner_iterator_type(other.m_inner_iterator_type) { - switch (m_inner_iterator_type) { - case iterator_t::SEQUENCE: - m_iterator_holder.sequence_iterator = std::move(other.m_iterator_holder.sequence_iterator); - break; - case iterator_t::MAPPING: - m_iterator_holder.mapping_iterator = std::move(other.m_iterator_holder.mapping_iterator); - break; - } + /// @brief Copy constructs an iterator from another iterator with different const-ness in ValueType. + /// @note This copy constructor is not defined if ValueType is not const to avoid const removal from ValueType. + /// @tparam OtherIterator The iterator type to copy from. + /// @param other An iterator to copy from with different const-ness in ValueType. + template < + typename OtherIterator, + enable_if_t< + conjunction, std::is_const>::value, int> = 0> + iterator(const OtherIterator& other) noexcept + : m_inner_iterator_type(other.m_inner_iterator_type), + m_iterator_holder(other.m_iterator_holder) { } - /// @brief Destroys an iterator. - ~iterator() = default; - -public: /// @brief A copy assignment operator of the iterator class. - /// @param rhs An iterator object to be copied with. - /// @return iterator& Reference to this iterator object. - iterator& operator=(const iterator& rhs) noexcept { - if FK_YAML_UNLIKELY (&rhs == this) { - return *this; - } - - m_inner_iterator_type = rhs.m_inner_iterator_type; - switch (m_inner_iterator_type) { - case iterator_t::SEQUENCE: - m_iterator_holder.sequence_iterator = rhs.m_iterator_holder.sequence_iterator; - break; - case iterator_t::MAPPING: - m_iterator_holder.mapping_iterator = rhs.m_iterator_holder.mapping_iterator; - break; - } + iterator& operator=(const iterator&) = default; + template < + typename OtherIterator, + enable_if_t< + conjunction, std::is_const>::value, int> = 0> + iterator& operator=(const OtherIterator& other) noexcept { + m_inner_iterator_type = other.m_inner_iterator_type; + m_iterator_holder = other.m_iterator_holder; return *this; } - /// @brief A move assignment operator of the iterator class. - /// @param rhs An iterator object to be moved from. - /// @return iterator& Reference to this iterator object. - iterator& operator=(iterator&& rhs) noexcept { - if FK_YAML_UNLIKELY (&rhs == this) { - return *this; - } + /// @brief Move constructs an iterator. + iterator(iterator&&) = default; - m_inner_iterator_type = rhs.m_inner_iterator_type; - switch (m_inner_iterator_type) { - case iterator_t::SEQUENCE: - m_iterator_holder.sequence_iterator = std::move(rhs.m_iterator_holder.sequence_iterator); - break; - case iterator_t::MAPPING: - m_iterator_holder.mapping_iterator = std::move(rhs.m_iterator_holder.mapping_iterator); - break; - } + /// @brief A move assignment operator of the iterator class. + iterator& operator=(iterator&&) = default; - return *this; - } + /// @brief Destroys an iterator. + ~iterator() = default; /// @brief An arrow operator of the iterator class. /// @return pointer A pointer to the BasicNodeType object internally referenced by the actual iterator object. @@ -9822,7 +9983,7 @@ class iterator { /// @brief A minus operator of the iterator class. /// @param i The difference from this iterator object. /// @return iterator An iterator object from which has been subtracted @ i. - iterator operator-(difference_type i) noexcept { + iterator operator-(difference_type i) const noexcept { auto result = *this; result -= i; return result; @@ -9854,7 +10015,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is equal to the other. /// @return false This iterator object is not equal to the other. - bool operator==(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator==(const Iterator& rhs) const { if FK_YAML_UNLIKELY (m_inner_iterator_type != rhs.m_inner_iterator_type) { throw fkyaml::exception("Cannot compare iterators of different container types."); } @@ -9871,7 +10036,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is not equal to the other. /// @return false This iterator object is equal to the other. - bool operator!=(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator!=(const Iterator& rhs) const { return !operator==(rhs); } @@ -9879,7 +10048,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is less than the other. /// @return false This iterator object is not less than the other. - bool operator<(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator<(const Iterator& rhs) const { if FK_YAML_UNLIKELY (m_inner_iterator_type != rhs.m_inner_iterator_type) { throw fkyaml::exception("Cannot compare iterators of different container types."); } @@ -9895,7 +10068,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is either less than or equal to the other. /// @return false This iterator object is neither less than nor equal to the other. - bool operator<=(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator<=(const Iterator& rhs) const { return !rhs.operator<(*this); } @@ -9903,7 +10080,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is greater than the other. /// @return false This iterator object is not greater than the other. - bool operator>(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator>(const Iterator& rhs) const { return !operator<=(rhs); } @@ -9911,7 +10092,11 @@ class iterator { /// @param rhs An iterator object to be compared with this iterator object. /// @return true This iterator object is either greater than or equal to the other. /// @return false This iterator object is neither greater than nor equal to the other. - bool operator>=(const iterator& rhs) const { + template < + typename Iterator, + enable_if_t< + disjunction, std::is_same>::value, int> = 0> + bool operator>=(const Iterator& rhs) const { return !operator<(rhs); } @@ -9922,9 +10107,9 @@ class iterator { return m_inner_iterator_type; } - /// @brief Get the key string of the YAML mapping node for the current iterator. - /// @return const std::string& The key string of the YAML mapping node for the current iterator. - const typename ValueType::mapping_type::key_type& key() const { + /// @brief Get the mapping key node of the current iterator. + /// @return The mapping key node of the current iterator. + const typename value_type::mapping_type::key_type& key() const { if FK_YAML_UNLIKELY (m_inner_iterator_type == iterator_t::SEQUENCE) { throw fkyaml::exception("Cannot retrieve key from non-mapping iterators."); } @@ -9932,8 +10117,8 @@ class iterator { return m_iterator_holder.mapping_iterator->first; } - /// @brief Get the reference of the YAML node for the current iterator. - /// @return reference A reference to the YAML node for the current iterator. + /// @brief Get reference to the YAML node of the current iterator. + /// @return Reference to the YAML node of the current iterator. reference value() noexcept { return operator*(); } @@ -9942,7 +10127,7 @@ class iterator { /// A type of the internally-held iterator. iterator_t m_inner_iterator_type {iterator_t::SEQUENCE}; /// A holder of actual iterators. - mutable iterator_holder m_iterator_holder {}; + iterator_holder m_iterator_holder {}; }; FK_YAML_DETAIL_NAMESPACE_END @@ -9962,7 +10147,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10055,7 +10240,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10074,7 +10259,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10156,10 +10341,10 @@ inline enable_if_t::value> to_string(FloatType oss << v; s = oss.str(); - // If `f` is actually an integer, ".0" must be appended. The result would cause roundtrip issue otherwise. - // https://github.com/fktn-k/fkYAML/issues/405 - const FloatType diff = v - std::floor(v); - if (diff < std::numeric_limits::min()) { + // If `v` is actually an integer and no scientific notation is used for serialization, ".0" must be appended. + // The result would cause a roundtrip issue otherwise. https://github.com/fktn-k/fkYAML/issues/405 + const std::size_t pos = s.find_first_of(".e"); + if (pos == std::string::npos) { s += ".0"; } } @@ -10512,12 +10697,226 @@ FK_YAML_DETAIL_NAMESPACE_END #endif /* FK_YAML_DETAIL_OUTPUT_SERIALIZER_HPP */ +// #include +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#ifndef FK_YAML_DETAIL_REVERSE_ITERATOR_HPP +#define FK_YAML_DETAIL_REVERSE_ITERATOR_HPP + +#include + +// #include + +// #include + + +FK_YAML_DETAIL_NAMESPACE_BEGIN + +/// @brief An iterator adapter class that reverses the direction of a given node iterator. +/// @tparam Iterator The base iterator type. +template +class reverse_iterator { + static_assert( + is_basic_node::type>::value, + "reverse_iterator only accepts a basic_node type as the underlying iterator's value type"); + +public: + /// @brief The base iterator type. + using iterator_type = Iterator; + + /// @brief The base iterator category. + using iterator_category = typename Iterator::iterator_category; + + /// @brief The type of the pointed-to elements by base iterators. + using value_type = typename Iterator::value_type; + + /// @brief The type to represent differences between the pointed-to elements by the base iterators. + using difference_type = typename Iterator::difference_type; + + /// @brief The type of the pointed-to element pointers by base iterators. + using pointer = typename Iterator::pointer; + + /// @brief The type of the pointed-to element references by base iterators. + using reference = typename Iterator::reference; + + /// @brief Constructs a reverse_iterator object. + reverse_iterator() = default; + + /// @brief Copy constructs a reverse_iterator object. + reverse_iterator(const reverse_iterator&) = default; + + /// @brief Copy assignments a reverse_iterator object. + reverse_iterator& operator=(const reverse_iterator&) = default; + + /// @brief Move constructs a reverse_iterator object. + reverse_iterator(reverse_iterator&&) = default; + + /// @brief Move assignments a reverse_iterator object. + reverse_iterator& operator=(reverse_iterator&&) = default; + + /// @brief Constructs a reverse_iterator object with an underlying iterator object. + /// @param i A base iterator object. + reverse_iterator(const Iterator& i) noexcept + : m_current(i) { + } + + template >::value, int> = 0> + reverse_iterator(const reverse_iterator& other) noexcept + : m_current(other.base()) { + } + + template >::value, int> = 0> + reverse_iterator& operator=(const reverse_iterator& other) noexcept { + m_current = other.base(); + return *this; + } + + /// @brief Destructs a reverse_iterator object. + ~reverse_iterator() = default; + + /// @brief Accesses the underlying iterator object. + /// @return The underlying iterator object. + Iterator base() const noexcept { + return m_current; + } + + /// @brief Get reference to the pointed-to element. + /// @return Reference to the pointed-to element. + reference operator*() const noexcept { + Iterator tmp = m_current; + return *--tmp; + } + + /// @brief Get pointer to the pointed-to element. + /// @return Pointer to the pointed-to element. + pointer operator->() const noexcept { + return &(operator*()); + } + + /// @brief Pre-increments the underlying iterator object. + /// @return Reference to this reverse_iterator object with its underlying iterator incremented. + reverse_iterator& operator++() noexcept { + --m_current; + return *this; + } + + /// @brief Post-increments the underlying iterator object. + /// @return A reverse_iterator object with the underlying iterator as-is. + reverse_iterator operator++(int) & noexcept { + auto result = *this; + --m_current; + return result; + } + + /// @brief Pre-decrements the underlying iterator object. + /// @return Reference to this reverse_iterator with its underlying iterator decremented. + reverse_iterator& operator--() noexcept { + ++m_current; + return *this; + } + + /// @brief Post-decrements the underlying iterator object. + /// @return A reverse_iterator object with the underlying iterator as-is. + reverse_iterator operator--(int) & noexcept { + auto result = *this; + ++m_current; + return result; + } + + /// @brief Advances the underlying iterator object by `n`. + /// @param n The distance by which the underlying iterator is advanced. + /// @return A reverse_iterator object with the underlying iterator advanced by `n`. + reverse_iterator operator+(difference_type n) const noexcept { + return reverse_iterator(m_current - n); + } + + /// @brief Advances the underlying iterator object by `n`. + /// @param n The distance by which the underlying iterator is advanced. + /// @return Reference to this reverse_iterator object with the underlying iterator advanced by `n`. + reverse_iterator& operator+=(difference_type n) noexcept { + m_current -= n; + return *this; + } + + /// @brief Decrements the underlying iterator object by `n`. + /// @param n The distance by which the underlying iterator is decremented. + /// @return A reverse_iterator object with the underlying iterator decremented by `n`. + reverse_iterator operator-(difference_type n) const noexcept { + return reverse_iterator(m_current + n); + } + + /// @brief Decrements the underlying iterator object by `n`. + /// @param n The distance by which the underlying iterator is decremented. + /// @return Reference to this reverse_iterator object with the underlying iterator decremented by `n`. + reverse_iterator& operator-=(difference_type n) noexcept { + m_current += n; + return *this; + } + + /// @brief Get the mapping key node of the underlying iterator. + /// @return The mapping key node of the underlying iterator. + auto key() const -> decltype(std::declval().key()) { + Iterator itr = --(base()); + return itr.key(); + } + + /// @brief Get reference to the underlying iterator's value. + /// @return Reference to the underlying iterator's value. + reference value() noexcept { + Iterator itr = --(base()); + return *itr; + } + +private: + Iterator m_current; +}; + +template +inline bool operator==(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() == rhs.base(); +} + +template +inline bool operator!=(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() != rhs.base(); +} + +template +inline bool operator<(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() > rhs.base(); +} + +template +inline bool operator<=(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() >= rhs.base(); +} + +template +inline bool operator>(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() < rhs.base(); +} + +template +inline bool operator>=(const reverse_iterator& lhs, const reverse_iterator& rhs) { + return lhs.base() <= rhs.base(); +} + +FK_YAML_DETAIL_NAMESPACE_END + +#endif /* FK_YAML_DETAIL_REVERSE_ITERATOR_HPP */ + // #include // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10572,7 +10971,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10588,7 +10987,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -11169,7 +11568,7 @@ FK_YAML_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -11556,7 +11955,7 @@ FK_YAML_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -11743,14 +12142,6 @@ template < template class ConverterType> class basic_node { public: - /// @brief A type for iterators of basic_node containers. - /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/iterator/ - using iterator = fkyaml::detail::iterator; - - /// @brief A type for constant iterators of basic_node containers. - /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/const_iterator/ - using const_iterator = fkyaml::detail::iterator; - /// @brief A type for sequence basic_node values. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/sequence_type/ using sequence_type = SequenceType>; @@ -11776,6 +12167,50 @@ class basic_node { /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/string_type/ using string_type = StringType; + /// @brief A type of elements in a basic_node container. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using value_type = basic_node; + + /// @brief A type of reference to a basic_node element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using reference = value_type&; + + /// @brief A type of constant reference to a basic_node element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using const_reference = const value_type&; + + /// @brief A type of a pointer to a basic_node element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using pointer = value_type*; + + /// @brief A type of a constant pointer to a basic_node element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using const_pointer = const value_type*; + + /// @brief A type to represent basic_node container sizes. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using size_type = std::size_t; + + /// @brief A type to represent differences between basic_node iterators. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/#container-types + using difference_type = std::ptrdiff_t; + + /// @brief A type for iterators of basic_node containers. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/iterator/ + using iterator = fkyaml::detail::iterator; + + /// @brief A type for constant iterators of basic_node containers. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/iterator/ + using const_iterator = fkyaml::detail::iterator; + + /// @brief A type for reverse iterators of basic_node containers. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/reverse_iterator/ + using reverse_iterator = fkyaml::detail::reverse_iterator; + + /// @brief A type for constant reverse iterators of basic_node containers. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/reverse_iterator/ + using const_reverse_iterator = fkyaml::detail::reverse_iterator; + /// @brief A helper alias to determine converter type for the given target native data type. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/value_converter_type/ template @@ -13077,90 +13512,160 @@ class basic_node { swap(m_prop.anchor, rhs.m_prop.anchor); } - /// @brief Returns the first iterator of basic_node values of container types (sequence or mapping) from a non-const - /// basic_node object. Throws exception if the basic_node value is not of container types. - /// @return An iterator to the first element of a YAML node value (either sequence or mapping). + /// @brief Returns an iterator to the first element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return An iterator to the first element of a container node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/begin/ iterator begin() { switch (get_node_attrs() & detail::node_attr_mask::value) { case detail::node_attr_bits::seq_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_sequence != nullptr); - return {detail::sequence_iterator_tag(), p_node_value->p_sequence->begin()}; + return {p_node_value->p_sequence->begin()}; } case detail::node_attr_bits::map_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_mapping != nullptr); - return {detail::mapping_iterator_tag(), p_node_value->p_mapping->begin()}; + return {p_node_value->p_mapping->begin()}; } default: throw fkyaml::type_error("The target node is neither of sequence nor mapping types.", get_type()); } } - /// @brief Returns the first iterator of basic_node values of container types (sequence or mapping) from a const - /// basic_node object. Throws exception if the basic_node value is not of container types. - /// @return A constant iterator to the first element of a YAML node value (either sequence or mapping). + /// @brief Returns a const iterator to the first element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the first element of a container node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/begin/ const_iterator begin() const { switch (get_node_attrs() & detail::node_attr_mask::value) { case detail::node_attr_bits::seq_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_sequence != nullptr); - return {detail::sequence_iterator_tag(), p_node_value->p_sequence->begin()}; + return {p_node_value->p_sequence->begin()}; } case detail::node_attr_bits::map_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_mapping != nullptr); - return {detail::mapping_iterator_tag(), p_node_value->p_mapping->begin()}; + return {p_node_value->p_mapping->begin()}; } default: throw fkyaml::type_error("The target node is neither of sequence nor mapping types.", get_type()); } } - /// @brief Returns the last iterator of basic_node values of container types (sequence or mapping) from a non-const - /// basic_node object. Throws exception if the basic_node value is not of container types. - /// @return An iterator to the past-the end element of a YAML node value (either sequence or mapping). + /// @brief Returns a const iterator to the first element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the first element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/begin/ + const_iterator cbegin() const { + return begin(); + } + + /// @brief Returns an iterator to the past-the-last element of a container node (sequence or mapping). + /// @throw `type_error` if the basic_node value is not of container types. + /// @return An iterator to the past-the-last element of a container node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/end/ iterator end() { switch (get_node_attrs() & detail::node_attr_mask::value) { case detail::node_attr_bits::seq_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_sequence != nullptr); - return {detail::sequence_iterator_tag(), p_node_value->p_sequence->end()}; + return {p_node_value->p_sequence->end()}; } case detail::node_attr_bits::map_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_mapping != nullptr); - return {detail::mapping_iterator_tag(), p_node_value->p_mapping->end()}; + return {p_node_value->p_mapping->end()}; } default: throw fkyaml::type_error("The target node is neither of sequence nor mapping types.", get_type()); } } - /// @brief Returns the last iterator of basic_node values of container types (sequence or mapping) from a const - /// basic_node object. Throws exception if the basic_node value is not of container types. - /// @return A constant iterator to the past-the end element of a YAML node value (either sequence or mapping). + /// @brief Returns a const iterator to the past-the-last element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the past-the-last element of a container node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/end/ const_iterator end() const { switch (get_node_attrs() & detail::node_attr_mask::value) { case detail::node_attr_bits::seq_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_sequence != nullptr); - return {detail::sequence_iterator_tag(), p_node_value->p_sequence->end()}; + return {p_node_value->p_sequence->end()}; } case detail::node_attr_bits::map_bit: { const node_value* p_node_value = get_node_value_ptr(); FK_YAML_ASSERT(p_node_value->p_mapping != nullptr); - return {detail::mapping_iterator_tag(), p_node_value->p_mapping->end()}; + return {p_node_value->p_mapping->end()}; } default: throw fkyaml::type_error("The target node is neither of sequence nor mapping types.", get_type()); } } + /// @brief Returns a const iterator to the past-the-last element of a container node (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the past-the-last element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/end/ + const_iterator cend() const { + return end(); + } + + /// @brief Returns an iterator to the reverse-beginning (i.e., last) element of a container node (sequence or + /// mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return An iterator to the reverse-beginning element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rbegin/ + reverse_iterator rbegin() { + return {end()}; + } + + /// @brief Returns a const iterator to the reverse-beginning (i.e., last) element of a container node (sequence or + /// mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the reverse-beginning element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rbegin/ + const_reverse_iterator rbegin() const { + return {end()}; + } + + /// @brief Returns a const iterator to the reverse-beginning (i.e., last) element of a container node (sequence or + /// mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the reverse-beginning element of a container node. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rbegin/ + const_reverse_iterator crbegin() const { + return rbegin(); + } + + /// @brief Returns an iterator to the reverse-end (i.e., one before the first) element of a container node (sequence + /// or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return An iterator to the reverse-end element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rend/ + reverse_iterator rend() { + return {begin()}; + } + + /// @brief Returns a const iterator to the reverse-end (i.e., one before the first) element of a container node + /// (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the reverse-end element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rend/ + const_reverse_iterator rend() const { + return {begin()}; + } + + /// @brief Returns a const iterator to the reverse-end (i.e., one before the first) element of a container node + /// (sequence or mapping). + /// @throw `type_error` if this basic_node is neither a sequence nor mapping node. + /// @return A const iterator to the reverse-end element. + /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/rend/ + const_reverse_iterator crend() const { + return rend(); + } + private: /// @brief Returns the pointer to the node_value object of either this node or the associated anchor node. /// @return The pointer to the node_value object of either this node or the associated anchor node. diff --git a/test/cmake_add_subdirectory_test/project/main.cpp b/test/cmake_add_subdirectory_test/project/main.cpp index 052c3ca7..25e7d96a 100644 --- a/test/cmake_add_subdirectory_test/project/main.cpp +++ b/test/cmake_add_subdirectory_test/project/main.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/cmake_fetch_content_test/project/CMakeLists.txt b/test/cmake_fetch_content_test/project/CMakeLists.txt index 1a9875f3..f05dc93c 100644 --- a/test/cmake_fetch_content_test/project/CMakeLists.txt +++ b/test/cmake_fetch_content_test/project/CMakeLists.txt @@ -6,7 +6,7 @@ include(FetchContent) FetchContent_Declare( fkYAML GIT_REPOSITORY https://github.com/fktn-k/fkYAML.git - GIT_TAG v0.3.14) + GIT_TAG v0.4.0) FetchContent_MakeAvailable(fkYAML) add_executable( diff --git a/test/cmake_fetch_content_test/project/main.cpp b/test/cmake_fetch_content_test/project/main.cpp index 052c3ca7..25e7d96a 100644 --- a/test/cmake_fetch_content_test/project/main.cpp +++ b/test/cmake_fetch_content_test/project/main.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/cmake_find_package_test/project/main.cpp b/test/cmake_find_package_test/project/main.cpp index 052c3ca7..25e7d96a 100644 --- a/test/cmake_find_package_test/project/main.cpp +++ b/test/cmake_find_package_test/project/main.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/cmake_target_include_directories_test/project/main.cpp b/test/cmake_target_include_directories_test/project/main.cpp index 052c3ca7..25e7d96a 100644 --- a/test/cmake_target_include_directories_test/project/main.cpp +++ b/test/cmake_target_include_directories_test/project/main.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/CMakeLists.txt b/test/unit_test/CMakeLists.txt index 3649052e..7ced66b8 100644 --- a/test/unit_test/CMakeLists.txt +++ b/test/unit_test/CMakeLists.txt @@ -111,6 +111,7 @@ target_compile_options( /W4 /WX /EHsc /utf-8 /permissive- /wd4709 # comma operator within array index expression /wd4996 # for testing deprecated functions + /w44800 # https://github.com/fktn-k/fkYAML/issues/429 $<$:/Z7> $<$:/Od> > @@ -229,6 +230,7 @@ add_executable( test_node_type.cpp test_ordered_map_class.cpp test_position_tracker_class.cpp + test_reverse_iterator_class.cpp test_scalar_conv.cpp test_scalar_parser_class.cpp test_scalar_scanner_class.cpp diff --git a/test/unit_test/main.cpp b/test/unit_test/main.cpp index 7ef2e622..2c5e10da 100644 --- a/test/unit_test/main.cpp +++ b/test/unit_test/main.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_custom_from_node.cpp b/test/unit_test/test_custom_from_node.cpp index 2efdc087..1970db62 100644 --- a/test/unit_test/test_custom_from_node.cpp +++ b/test/unit_test/test_custom_from_node.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_deserializer_class.cpp b/test/unit_test/test_deserializer_class.cpp index 2180bfdd..373119b7 100644 --- a/test/unit_test/test_deserializer_class.cpp +++ b/test/unit_test/test_deserializer_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -732,6 +732,33 @@ TEST_CASE("Deserializer_BlockMapping") { REQUIRE(pi_node.get_value() == 3.14); } + // regression test for https://github.com/fktn-k/fkYAML/pull/437 + SECTION("indented block mapping beginning with a newline") { + std::string input = R"( + foo: true + bar: 123 + baz: 3.14)"; + + REQUIRE_NOTHROW(root = deserializer.deserialize(fkyaml::detail::input_adapter(input))); + REQUIRE(root.is_mapping()); + REQUIRE(root.size() == 3); + REQUIRE(root.contains("foo")); + REQUIRE(root.contains("bar")); + REQUIRE(root.contains("baz")); + + fkyaml::node& foo_node = root["foo"]; + REQUIRE(foo_node.is_boolean()); + REQUIRE(foo_node.get_value() == true); + + fkyaml::node& bar_node = root["bar"]; + REQUIRE(bar_node.is_integer()); + REQUIRE(bar_node.get_value() == 123); + + fkyaml::node& baz_node = root["baz"]; + REQUIRE(baz_node.is_float_number()); + REQUIRE(baz_node.get_value() == 3.14); + }; + SECTION("nested block mapping") { std::string input = "test:\n" " bool: true\n" @@ -2880,6 +2907,11 @@ TEST_CASE("Deserializer_NodeProperties") { REQUIRE_THROWS_AS(deserializer.deserialize(fkyaml::detail::input_adapter(input)), fkyaml::parse_error); } + SECTION("alias node with anchor") { + std::string input = "&anchor foo: &anchor2 *anchor"; + REQUIRE_THROWS_AS(deserializer.deserialize(fkyaml::detail::input_adapter(input)), fkyaml::parse_error); + } + SECTION("parse anchored child block mapping as a block sequence entry") { std::string input = "values:\n" "- &anchor !XXX\n" diff --git a/test/unit_test/test_exception_class.cpp b/test/unit_test/test_exception_class.cpp index 03a5a2e0..f8e46067 100644 --- a/test/unit_test/test_exception_class.cpp +++ b/test/unit_test/test_exception_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_input_adapter.cpp b/test/unit_test/test_input_adapter.cpp index bb1d385b..2a15f020 100644 --- a/test/unit_test/test_input_adapter.cpp +++ b/test/unit_test/test_input_adapter.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_iterator_class.cpp b/test/unit_test/test_iterator_class.cpp index 7b5c1205..9ced0000 100644 --- a/test/unit_test/test_iterator_class.cpp +++ b/test/unit_test/test_iterator_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -12,22 +12,19 @@ TEST_CASE("Iterator_SequenceCtor") { fkyaml::node sequence = fkyaml::node::sequence(); - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.get_value_ref().begin()); REQUIRE(iterator.type() == fkyaml::detail::iterator_t::SEQUENCE); } TEST_CASE("Iterator_MappingCtor") { fkyaml::node mapping = fkyaml::node::mapping(); - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator iterator(mapping.get_value_ref().begin()); REQUIRE(iterator.type() == fkyaml::detail::iterator_t::MAPPING); } TEST_CASE("Iterator_SequenceCopyCtor") { fkyaml::node sequence = fkyaml::node::sequence({fkyaml::node()}); - fkyaml::detail::iterator copied( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator copied(sequence.begin()); fkyaml::detail::iterator iterator(copied); REQUIRE(iterator.type() == fkyaml::detail::iterator_t::SEQUENCE); REQUIRE(iterator->is_null()); @@ -35,18 +32,24 @@ TEST_CASE("Iterator_SequenceCopyCtor") { TEST_CASE("Iterator_MappingCopyCtor") { fkyaml::node mapping = fkyaml::node::mapping({{"test", fkyaml::node()}}); - fkyaml::detail::iterator copied( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator copied(mapping.begin()); fkyaml::detail::iterator iterator(copied); REQUIRE(iterator.type() == fkyaml::detail::iterator_t::MAPPING); REQUIRE(iterator.key().get_value_ref() == "test"); REQUIRE(iterator.value().is_null()); } +TEST_CASE("Iterator_CtorDifferentConstness") { + fkyaml::node seq = {nullptr, 123}; + fkyaml::detail::iterator const_itr = seq.begin(); + + REQUIRE(const_itr.type() == fkyaml::detail::iterator_t::SEQUENCE); + REQUIRE(const_itr->is_null()); +} + TEST_CASE("Iterator_SequenceMoveCtor") { fkyaml::node sequence = {"test"}; - fkyaml::detail::iterator moved( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator moved(sequence.begin()); fkyaml::detail::iterator iterator(std::move(moved)); REQUIRE(iterator.type() == fkyaml::detail::iterator_t::SEQUENCE); REQUIRE(iterator->is_string()); @@ -55,8 +58,7 @@ TEST_CASE("Iterator_SequenceMoveCtor") { TEST_CASE("Iterator_MappingMoveCtor") { fkyaml::node mapping = fkyaml::node::mapping({{"test", fkyaml::node()}}); - fkyaml::detail::iterator moved( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator moved(mapping.begin()); fkyaml::detail::iterator iterator(std::move(moved)); REQUIRE(iterator.type() == fkyaml::detail::iterator_t::MAPPING); REQUIRE(iterator.key().get_value_ref() == "test"); @@ -66,8 +68,7 @@ TEST_CASE("Iterator_MappingMoveCtor") { TEST_CASE("Iterator_AssignmentOperator") { SECTION("self assignment.") { fkyaml::node sequence = fkyaml::node::sequence({fkyaml::node()}); - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.begin()); SECTION("lvalue iterator") { iterator = *&iterator; @@ -85,10 +86,9 @@ TEST_CASE("Iterator_AssignmentOperator") { SECTION("sequence iterators") { fkyaml::node copied_seq = {"test"}; fkyaml::detail::iterator copied_itr( - fkyaml::detail::sequence_iterator_tag {}, copied_seq.get_value_ref().begin()); + copied_seq.get_value_ref().begin()); fkyaml::node sequence = {false}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.begin()); SECTION("lvalue iterator") { iterator = copied_itr; @@ -108,10 +108,9 @@ TEST_CASE("Iterator_AssignmentOperator") { SECTION("mapping iterators") { fkyaml::node copied_map = {{"key", "test"}}; fkyaml::detail::iterator copied_itr( - fkyaml::detail::mapping_iterator_tag {}, copied_map.get_value_ref().begin()); + copied_map.get_value_ref().begin()); fkyaml::node map = {{"foo", false}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, map.get_value_ref().begin()); + fkyaml::detail::iterator iterator(map.get_value_ref().begin()); SECTION("lvalue iterator") { iterator = copied_itr; @@ -129,20 +128,29 @@ TEST_CASE("Iterator_AssignmentOperator") { REQUIRE(iterator.value().get_value_ref().compare("test") == 0); } } + + SECTION("different const-ness") { + fkyaml::node seq = {nullptr, 123}; + const fkyaml::node const_seq = {true, 3.14}; + fkyaml::detail::iterator const_itr = const_seq.begin(); + + const_itr = seq.begin(); + + REQUIRE(const_itr.type() == fkyaml::detail::iterator_t::SEQUENCE); + REQUIRE(const_itr->is_null()); + } } TEST_CASE("Iterator_ArrowOperator") { SECTION("sequence iterator") { fkyaml::node seq = {"test"}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, seq.get_value_ref().begin()); + fkyaml::detail::iterator iterator(seq.get_value_ref().begin()); REQUIRE(iterator.operator->() == &(seq.get_value_ref().operator[](0))); } SECTION("mapping iterator") { fkyaml::node map = {{"key", "test"}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, map.get_value_ref().begin()); + fkyaml::detail::iterator iterator(map.get_value_ref().begin()); REQUIRE(iterator.operator->() == &(map.get_value_ref().operator[]("key"))); } } @@ -150,15 +158,13 @@ TEST_CASE("Iterator_ArrowOperator") { TEST_CASE("Iterator_DereferenceOperator") { SECTION("sequence iterator") { fkyaml::node seq = {"test"}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, seq.get_value_ref().begin()); + fkyaml::detail::iterator iterator(seq.get_value_ref().begin()); REQUIRE(&(iterator.operator*()) == &(seq.get_value_ref().operator[](0))); } SECTION("mapping iterator") { fkyaml::node map = fkyaml::node::mapping({{"key", "test"}}); - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, map.get_value_ref().begin()); + fkyaml::detail::iterator iterator(map.get_value_ref().begin()); REQUIRE(&(iterator.operator*()) == &(map.get_value_ref().operator[]("key"))); } } @@ -166,8 +172,7 @@ TEST_CASE("Iterator_DereferenceOperator") { TEST_CASE("Iterator_CompoundAssignmentOperatorBySum") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.begin()); iterator += 1; REQUIRE(iterator->is_boolean()); REQUIRE(iterator->get_value() == true); @@ -175,8 +180,7 @@ TEST_CASE("Iterator_CompoundAssignmentOperatorBySum") { SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator iterator(mapping.begin()); iterator += 1; REQUIRE(iterator.key().get_value_ref() == "test1"); REQUIRE(iterator.value().is_boolean()); @@ -187,8 +191,7 @@ TEST_CASE("Iterator_CompoundAssignmentOperatorBySum") { TEST_CASE("Iterator_PlusOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.begin()); fkyaml::detail::iterator after_plus_itr = iterator + 1; REQUIRE(after_plus_itr->is_boolean()); REQUIRE(after_plus_itr->get_value() == true); @@ -196,8 +199,7 @@ TEST_CASE("Iterator_PlusOperator") { SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator iterator(mapping.begin()); fkyaml::detail::iterator after_plus_itr = iterator + 1; REQUIRE(after_plus_itr.key().get_value_ref() == "test1"); REQUIRE(after_plus_itr.value().is_boolean()); @@ -208,8 +210,7 @@ TEST_CASE("Iterator_PlusOperator") { TEST_CASE("Iterator_PreIncrementOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.begin()); ++iterator; REQUIRE(iterator->is_boolean()); REQUIRE(iterator->get_value() == true); @@ -217,8 +218,7 @@ TEST_CASE("Iterator_PreIncrementOperator") { SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator iterator(mapping.begin()); ++iterator; REQUIRE(iterator.key().get_value_ref() == "test1"); REQUIRE(iterator.value().is_boolean()); @@ -229,8 +229,7 @@ TEST_CASE("Iterator_PreIncrementOperator") { TEST_CASE("Iterator_PostIncrementOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.begin()); iterator++; REQUIRE(iterator->is_boolean()); REQUIRE(iterator->get_value() == true); @@ -238,8 +237,7 @@ TEST_CASE("Iterator_PostIncrementOperator") { SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator iterator(mapping.begin()); iterator++; REQUIRE(iterator.key().get_value_ref() == "test1"); REQUIRE(iterator.value().is_boolean()); @@ -250,8 +248,7 @@ TEST_CASE("Iterator_PostIncrementOperator") { TEST_CASE("Iterator_CompoundAssignmentOperatorByDifference") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().end()); + fkyaml::detail::iterator iterator(sequence.end()); iterator -= 1; REQUIRE(iterator->is_boolean()); REQUIRE(iterator->get_value() == true); @@ -259,8 +256,7 @@ TEST_CASE("Iterator_CompoundAssignmentOperatorByDifference") { SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().end()); + fkyaml::detail::iterator iterator(mapping.end()); iterator -= 1; REQUIRE(iterator.key().get_value_ref() == "test1"); REQUIRE(iterator.value().is_boolean()); @@ -271,8 +267,7 @@ TEST_CASE("Iterator_CompoundAssignmentOperatorByDifference") { TEST_CASE("Iterator_MinusOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().end()); + fkyaml::detail::iterator iterator(sequence.end()); fkyaml::detail::iterator after_minus_itr = iterator - 1; REQUIRE(after_minus_itr->is_boolean()); REQUIRE(after_minus_itr->get_value() == true); @@ -280,8 +275,7 @@ TEST_CASE("Iterator_MinusOperator") { SECTION("mapping iterator.") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().end()); + fkyaml::detail::iterator iterator(mapping.end()); fkyaml::detail::iterator after_minus_itr = iterator - 1; REQUIRE(after_minus_itr.key().get_value_ref() == "test1"); REQUIRE(after_minus_itr.value().is_boolean()); @@ -292,8 +286,7 @@ TEST_CASE("Iterator_MinusOperator") { TEST_CASE("Iterator_PreDecrementOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().end()); + fkyaml::detail::iterator iterator(sequence.end()); --iterator; REQUIRE(iterator->is_boolean()); REQUIRE(iterator->get_value() == true); @@ -301,8 +294,7 @@ TEST_CASE("Iterator_PreDecrementOperator") { SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().end()); + fkyaml::detail::iterator iterator(mapping.end()); --iterator; REQUIRE(iterator.key().get_value_ref() == "test1"); REQUIRE(iterator.value().is_boolean()); @@ -313,8 +305,7 @@ TEST_CASE("Iterator_PreDecrementOperator") { TEST_CASE("Iterator_PostDecrementOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().end()); + fkyaml::detail::iterator iterator(sequence.end()); iterator--; REQUIRE(iterator->is_boolean()); REQUIRE(iterator->get_value() == true); @@ -322,8 +313,7 @@ TEST_CASE("Iterator_PostDecrementOperator") { SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().end()); + fkyaml::detail::iterator iterator(mapping.end()); iterator--; REQUIRE(iterator.key().get_value_ref() == "test1"); REQUIRE(iterator.value().is_boolean()); @@ -334,29 +324,35 @@ TEST_CASE("Iterator_PostDecrementOperator") { TEST_CASE("Iterator_EqualToOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - REQUIRE(lhs == rhs); + fkyaml::detail::iterator itr(sequence.begin()); + fkyaml::detail::iterator itr2(sequence.begin()); + fkyaml::detail::iterator const_itr(sequence.begin()); + fkyaml::detail::iterator const_itr2(sequence.begin()); + + REQUIRE(itr == itr2); + REQUIRE(const_itr == const_itr2); + REQUIRE(itr == const_itr); + REQUIRE(const_itr == itr); } SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator lhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); - REQUIRE(lhs == rhs); + fkyaml::detail::iterator itr(mapping.begin()); + fkyaml::detail::iterator itr2(mapping.begin()); + fkyaml::detail::iterator const_itr(mapping.begin()); + fkyaml::detail::iterator const_itr2(mapping.begin()); + + REQUIRE(itr == itr2); + REQUIRE(const_itr == const_itr2); + REQUIRE(itr == const_itr); + REQUIRE(const_itr == itr); } SECTION("equality check between different type iterators") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator lhs(sequence.begin()); fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator rhs(mapping.begin()); REQUIRE_THROWS_AS(lhs == rhs, fkyaml::exception); } } @@ -364,63 +360,71 @@ TEST_CASE("Iterator_EqualToOperator") { TEST_CASE("Iterator_NotEqualToOperator") { SECTION("sequence iterator.") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - ++rhs; + fkyaml::detail::iterator lhs(sequence.begin()); + fkyaml::detail::iterator rhs(sequence.begin() + 1); + fkyaml::detail::iterator const_lhs(sequence.begin()); + fkyaml::detail::iterator const_rhs(sequence.begin() + 1); + REQUIRE(lhs != rhs); + REQUIRE(const_lhs != const_rhs); + REQUIRE(lhs != const_rhs); + REQUIRE(const_lhs != rhs); } SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator lhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); - ++rhs; + fkyaml::detail::iterator lhs(mapping.begin()); + fkyaml::detail::iterator rhs(mapping.begin() + 1); + fkyaml::detail::iterator const_lhs(mapping.begin()); + fkyaml::detail::iterator const_rhs(mapping.begin() + 1); + REQUIRE(lhs != rhs); + REQUIRE(const_lhs != const_rhs); + REQUIRE(lhs != const_rhs); + REQUIRE(const_lhs != rhs); } SECTION("equality check between different type iterators") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator lhs(sequence.begin()); fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); - REQUIRE_THROWS_AS(lhs == rhs, fkyaml::exception); + fkyaml::detail::iterator rhs(mapping.begin()); + REQUIRE_THROWS_AS(lhs != rhs, fkyaml::exception); } } TEST_CASE("Iterator_LessThanOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator lhs(sequence.begin()); + fkyaml::detail::iterator rhs(sequence.begin()); + fkyaml::detail::iterator const_lhs(sequence.begin()); + fkyaml::detail::iterator const_rhs(sequence.begin()); + REQUIRE_FALSE(lhs < rhs); + REQUIRE_FALSE(const_lhs < const_rhs); + REQUIRE_FALSE(lhs < const_rhs); + REQUIRE_FALSE(const_lhs < rhs); ++rhs; + ++const_rhs; REQUIRE(lhs < rhs); + REQUIRE(const_lhs < const_rhs); + REQUIRE(lhs < const_rhs); + REQUIRE(const_lhs < rhs); } SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator lhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator lhs(mapping.begin()); + fkyaml::detail::iterator rhs(mapping.begin()); REQUIRE_THROWS_AS(lhs < rhs, fkyaml::exception); } SECTION("less-than check between different type iterators") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator lhs(sequence.begin()); fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator rhs(mapping.begin()); REQUIRE_THROWS_AS(lhs < rhs, fkyaml::exception); } } @@ -428,34 +432,41 @@ TEST_CASE("Iterator_LessThanOperator") { TEST_CASE("Iterator_LessThanOrEqualToOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - ++lhs; + fkyaml::detail::iterator lhs(sequence.begin() + 1); + fkyaml::detail::iterator rhs(sequence.begin()); + fkyaml::detail::iterator const_lhs(sequence.begin() + 1); + fkyaml::detail::iterator const_rhs(sequence.begin()); + REQUIRE_FALSE(lhs <= rhs); + REQUIRE_FALSE(const_lhs <= const_rhs); + REQUIRE_FALSE(lhs <= const_rhs); + REQUIRE_FALSE(const_lhs <= rhs); --lhs; + --const_lhs; REQUIRE(lhs <= rhs); + REQUIRE(const_lhs <= const_rhs); + REQUIRE(lhs <= const_rhs); + REQUIRE(const_lhs <= rhs); ++rhs; - REQUIRE(lhs < rhs); + ++const_rhs; + REQUIRE(lhs <= rhs); + REQUIRE(const_lhs <= const_rhs); + REQUIRE(lhs <= const_rhs); + REQUIRE(const_lhs <= rhs); } SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator lhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator lhs(mapping.begin()); + fkyaml::detail::iterator rhs(mapping.begin()); REQUIRE_THROWS_AS(lhs <= rhs, fkyaml::exception); } SECTION("less-than-or-equal-to check between different type iterators") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator lhs(sequence.begin()); fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator rhs(mapping.begin()); REQUIRE_THROWS_AS(lhs <= rhs, fkyaml::exception); } } @@ -463,31 +474,35 @@ TEST_CASE("Iterator_LessThanOrEqualToOperator") { TEST_CASE("Iterator_GreaterThanOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator lhs(sequence.begin()); + fkyaml::detail::iterator rhs(sequence.begin()); + fkyaml::detail::iterator const_lhs(sequence.begin()); + fkyaml::detail::iterator const_rhs(sequence.begin()); + REQUIRE_FALSE(lhs > rhs); + REQUIRE_FALSE(const_lhs > const_rhs); + REQUIRE_FALSE(lhs > const_rhs); + REQUIRE_FALSE(const_lhs > rhs); ++lhs; + ++const_lhs; REQUIRE(lhs > rhs); + REQUIRE(const_lhs > const_rhs); + REQUIRE(lhs > const_rhs); + REQUIRE(const_lhs > rhs); } SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator lhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator lhs(mapping.begin()); + fkyaml::detail::iterator rhs(mapping.begin()); REQUIRE_THROWS_AS(lhs > rhs, fkyaml::exception); } SECTION("greater-than check between different type iterators") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator lhs(sequence.begin()); fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator rhs(mapping.begin()); REQUIRE_THROWS_AS(lhs > rhs, fkyaml::exception); } } @@ -495,34 +510,41 @@ TEST_CASE("Iterator_GreaterThanOperator") { TEST_CASE("Iterator_GreaterThanOrEqualToOperator") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); - ++rhs; + fkyaml::detail::iterator lhs(sequence.begin()); + fkyaml::detail::iterator rhs(sequence.begin() + 1); + fkyaml::detail::iterator const_lhs(sequence.begin()); + fkyaml::detail::iterator const_rhs(sequence.begin() + 1); + REQUIRE_FALSE(lhs >= rhs); + REQUIRE_FALSE(const_lhs >= const_rhs); + REQUIRE_FALSE(lhs >= const_rhs); + REQUIRE_FALSE(const_lhs >= rhs); --rhs; + --const_rhs; REQUIRE(lhs >= rhs); + REQUIRE(const_lhs >= const_rhs); + REQUIRE(lhs >= const_rhs); + REQUIRE(const_lhs >= rhs); ++lhs; + ++const_lhs; REQUIRE(lhs >= rhs); + REQUIRE(const_lhs >= const_rhs); + REQUIRE(lhs >= const_rhs); + REQUIRE(const_lhs >= rhs); } SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator lhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator lhs(mapping.begin()); + fkyaml::detail::iterator rhs(mapping.begin()); REQUIRE_THROWS_AS(lhs >= rhs, fkyaml::exception); } SECTION("greater-than-or-equal-to check between different type iterators") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator lhs( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator lhs(sequence.begin()); fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator rhs( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator rhs(mapping.begin()); REQUIRE_THROWS_AS(lhs >= rhs, fkyaml::exception); } } @@ -530,15 +552,13 @@ TEST_CASE("Iterator_GreaterThanOrEqualToOperator") { TEST_CASE("Iterator_TypeGetter") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.begin()); REQUIRE(iterator.type() == fkyaml::detail::iterator_t::SEQUENCE); } SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator iterator(mapping.begin()); REQUIRE(iterator.type() == fkyaml::detail::iterator_t::MAPPING); } } @@ -546,15 +566,13 @@ TEST_CASE("Iterator_TypeGetter") { TEST_CASE("Iterator_KeyGetter") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.begin()); REQUIRE_THROWS_AS(iterator.key(), fkyaml::exception); } SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator iterator(mapping.begin()); REQUIRE_NOTHROW(iterator.key()); REQUIRE(iterator.key().get_value_ref() == "test0"); } @@ -563,16 +581,14 @@ TEST_CASE("Iterator_KeyGetter") { TEST_CASE("Iterator_ValueGetter") { SECTION("sequence iterator") { fkyaml::node sequence = {false, true}; - fkyaml::detail::iterator iterator( - fkyaml::detail::sequence_iterator_tag {}, sequence.get_value_ref().begin()); + fkyaml::detail::iterator iterator(sequence.begin()); REQUIRE(iterator.value().is_boolean()); REQUIRE(iterator.value().get_value() == false); } SECTION("mapping iterator") { fkyaml::node mapping = {{"test0", false}, {"test1", true}}; - fkyaml::detail::iterator iterator( - fkyaml::detail::mapping_iterator_tag {}, mapping.get_value_ref().begin()); + fkyaml::detail::iterator iterator(mapping.begin()); REQUIRE(iterator.value().is_boolean()); REQUIRE(iterator.value().get_value() == false); } diff --git a/test/unit_test/test_lexical_analyzer_class.cpp b/test/unit_test/test_lexical_analyzer_class.cpp index 072e5e00..9c2eb919 100644 --- a/test/unit_test/test_lexical_analyzer_class.cpp +++ b/test/unit_test/test_lexical_analyzer_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -330,60 +330,298 @@ TEST_CASE("LexicalAnalzer_BlockSequenceEntryPrefix") { } TEST_CASE("LexicalAnalyzer_PlainScalar") { - auto input = GENERATE( - fkyaml::detail::str_view("test"), - fkyaml::detail::str_view("test "), - fkyaml::detail::str_view("test:"), - fkyaml::detail::str_view("nop"), - fkyaml::detail::str_view("none"), - fkyaml::detail::str_view("?test"), - fkyaml::detail::str_view(".NET"), - fkyaml::detail::str_view(".on"), - fkyaml::detail::str_view(".n"), - fkyaml::detail::str_view("-t"), - fkyaml::detail::str_view("-foo"), - fkyaml::detail::str_view("-.test"), - fkyaml::detail::str_view("?"), - fkyaml::detail::str_view("--foo"), - fkyaml::detail::str_view("+123"), - fkyaml::detail::str_view("1.2.3"), - fkyaml::detail::str_view("foo,bar"), - fkyaml::detail::str_view("foo[bar"), - fkyaml::detail::str_view("foo]bar"), - fkyaml::detail::str_view("foo{bar"), - fkyaml::detail::str_view("foo}bar"), - fkyaml::detail::str_view("foo:bar"), - fkyaml::detail::str_view("foo bar"), - fkyaml::detail::str_view("foo\"bar"), - fkyaml::detail::str_view("foo\'s bar"), - fkyaml::detail::str_view("foo\\bar"), - fkyaml::detail::str_view("nullValue"), - fkyaml::detail::str_view("NullValue"), - fkyaml::detail::str_view("NULL_VALUE"), - fkyaml::detail::str_view("~Value"), - fkyaml::detail::str_view("trueValue"), - fkyaml::detail::str_view("TrueValue"), - fkyaml::detail::str_view("TRUE_VALUE"), - fkyaml::detail::str_view("falseValue"), - fkyaml::detail::str_view("FalseValue"), - fkyaml::detail::str_view("FALSE_VALUE"), - fkyaml::detail::str_view(".infValue"), - fkyaml::detail::str_view(".InfValue"), - fkyaml::detail::str_view(".INF_VALUE"), - fkyaml::detail::str_view("-.infValue"), - fkyaml::detail::str_view("-.InfValue"), - fkyaml::detail::str_view("-.INF_VALUE"), - fkyaml::detail::str_view(".nanValue"), - fkyaml::detail::str_view(".NaNValue"), - fkyaml::detail::str_view(".NAN_VALUE")); - - fkyaml::detail::lexical_analyzer lexer(input); fkyaml::detail::lexical_token token; - REQUIRE_NOTHROW(token = lexer.get_next_token()); - REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); - REQUIRE(token.str.begin() == input.begin()); - REQUIRE(token.str.end() == input.begin() + input.find_last_not_of(' ') + 1); + SECTION("single line") { + auto input = GENERATE( + fkyaml::detail::str_view("test"), + fkyaml::detail::str_view("test "), + fkyaml::detail::str_view("test:"), + fkyaml::detail::str_view("nop"), + fkyaml::detail::str_view("none"), + fkyaml::detail::str_view("?test"), + fkyaml::detail::str_view(".NET"), + fkyaml::detail::str_view(".on"), + fkyaml::detail::str_view(".n"), + fkyaml::detail::str_view("-t"), + fkyaml::detail::str_view("-foo"), + fkyaml::detail::str_view("-.test"), + fkyaml::detail::str_view("?"), + fkyaml::detail::str_view("--foo"), + fkyaml::detail::str_view("+123"), + fkyaml::detail::str_view("1.2.3"), + fkyaml::detail::str_view("foo,bar"), + fkyaml::detail::str_view("foo[bar"), + fkyaml::detail::str_view("foo]bar"), + fkyaml::detail::str_view("foo{bar"), + fkyaml::detail::str_view("foo}bar"), + fkyaml::detail::str_view("foo:bar"), + fkyaml::detail::str_view("foo bar"), + fkyaml::detail::str_view("foo\"bar"), + fkyaml::detail::str_view("foo\'s bar"), + fkyaml::detail::str_view("foo\\bar"), + fkyaml::detail::str_view("nullValue"), + fkyaml::detail::str_view("NullValue"), + fkyaml::detail::str_view("NULL_VALUE"), + fkyaml::detail::str_view("~Value"), + fkyaml::detail::str_view("trueValue"), + fkyaml::detail::str_view("TrueValue"), + fkyaml::detail::str_view("TRUE_VALUE"), + fkyaml::detail::str_view("falseValue"), + fkyaml::detail::str_view("FalseValue"), + fkyaml::detail::str_view("FALSE_VALUE"), + fkyaml::detail::str_view(".infValue"), + fkyaml::detail::str_view(".InfValue"), + fkyaml::detail::str_view(".INF_VALUE"), + fkyaml::detail::str_view("-.infValue"), + fkyaml::detail::str_view("-.InfValue"), + fkyaml::detail::str_view("-.INF_VALUE"), + fkyaml::detail::str_view(".nanValue"), + fkyaml::detail::str_view(".NaNValue"), + fkyaml::detail::str_view(".NAN_VALUE")); + + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin()); + REQUIRE(token.str.end() == input.begin() + input.find_last_not_of(' ') + 1); + } + + SECTION("multiline without final newline") { + fkyaml::detail::str_view input = " foo\n" + " bar\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 2); + REQUIRE(token.str.end() == input.end()); + } + + SECTION("multiline with final newline") { + fkyaml::detail::str_view input = " foo\n" + " bar\n" + " baz\n"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 2); + REQUIRE(token.str.end() == input.end() - 1); + } + + SECTION("multiline as an implicit mapping value") { + fkyaml::detail::str_view input = " foo: foo\n" + " bar\n" + " baz\n" + " qux"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 2); + REQUIRE(token.str.end() == input.begin() + 5); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::KEY_SEPARATOR); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 7); + REQUIRE(token.str.end() == input.end() - 6); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.end() - 3); + REQUIRE(token.str.end() == input.end()); + } + + SECTION("multiline as a block sequence item") { + fkyaml::detail::str_view input = " - foo\n" + " bar\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::SEQUENCE_BLOCK_PREFIX); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 4); + REQUIRE(token.str.end() == input.end()); + } + + SECTION("multiline as a block sequence item and an implicit mapping value") { + fkyaml::detail::str_view input = " - -foo: bar\n" + " baz\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::SEQUENCE_BLOCK_PREFIX); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 4); + REQUIRE(token.str.end() == input.begin() + 8); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::KEY_SEPARATOR); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 10); + REQUIRE(token.str.end() == input.end() - 7); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.end() - 3); + REQUIRE(token.str.end() == input.end()); + } + + SECTION("multiline as an explicit mapping key") { + fkyaml::detail::str_view input = " ? foo\n" + " bar\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::EXPLICIT_KEY_PREFIX); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 4); + REQUIRE(token.str.end() == input.end()); + } + + SECTION("multiline as an explicit mapping key and an implicit mapping value") { + fkyaml::detail::str_view input = " ? ?foo: bar\n" + " baz\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::EXPLICIT_KEY_PREFIX); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 4); + REQUIRE(token.str.end() == input.begin() + 8); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::KEY_SEPARATOR); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 10); + REQUIRE(token.str.end() == input.end() - 7); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.end() - 3); + REQUIRE(token.str.end() == input.end()); + } + + SECTION("multiline as an explicit mapping value") { + fkyaml::detail::str_view input = " : foo\n" + " bar\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::KEY_SEPARATOR); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 4); + REQUIRE(token.str.end() == input.end()); + } + + SECTION("multiline as an explicit mapping value and an implicit mapping value") { + fkyaml::detail::str_view input = " : :foo: bar\n" + " bar\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::KEY_SEPARATOR); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 4); + REQUIRE(token.str.end() == input.begin() + 8); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::KEY_SEPARATOR); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 10); + REQUIRE(token.str.end() == input.end() - 7); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.end() - 3); + REQUIRE(token.str.end() == input.end()); + } + + SECTION("multiline as a block sequence item and an explicit mapping value") { + fkyaml::detail::str_view input = " ? - foo\n" + " bar\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::EXPLICIT_KEY_PREFIX); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::SEQUENCE_BLOCK_PREFIX); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 6); + REQUIRE(token.str.end() == input.end()); + } + + SECTION("multiline with less indented line") { + fkyaml::detail::str_view input = " foo\n" + " bar\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 2); + REQUIRE(token.str.end() == input.end() - 5); + } + + SECTION("multiline with equally indented line") { + fkyaml::detail::str_view input = " foo\n" + " bar\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 2); + REQUIRE(token.str.end() == input.end() - 6); + } + + SECTION("multiline with empty line") { + fkyaml::detail::str_view input = " foo\n" + " \t \n" + " bar\n" + "\n" + " baz"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::PLAIN_SCALAR); + REQUIRE(token.str.begin() == input.begin() + 2); + REQUIRE(token.str.end() == input.end()); + } } TEST_CASE("LexicalAnalyzer_SingleQuotedScalar") { @@ -611,7 +849,7 @@ TEST_CASE("LexicalAnalyzer_LiteralStringScalar") { REQUIRE(token.str.begin() == &input[3]); REQUIRE(token.str.end() == &input[0] + 6); REQUIRE(lexer.get_block_scalar_header().chomp == fkyaml::detail::chomping_indicator_t::STRIP); - REQUIRE(lexer.get_block_scalar_header().indent == 3); // lexer returns content size if empty. + REQUIRE(lexer.get_block_scalar_header().indent == 2); REQUIRE_NOTHROW(token = lexer.get_next_token()); REQUIRE(token.type == fkyaml::detail::lexical_token_t::END_OF_BUFFER); @@ -627,7 +865,7 @@ TEST_CASE("LexicalAnalyzer_LiteralStringScalar") { REQUIRE(token.str.begin() == &input[2]); REQUIRE(token.str.end() == &input[0] + 5); REQUIRE(lexer.get_block_scalar_header().chomp == fkyaml::detail::chomping_indicator_t::CLIP); - REQUIRE(lexer.get_block_scalar_header().indent == 3); // lexer returns content size if empty. + REQUIRE(lexer.get_block_scalar_header().indent == 2); REQUIRE_NOTHROW(token = lexer.get_next_token()); REQUIRE(token.type == fkyaml::detail::lexical_token_t::END_OF_BUFFER); @@ -643,7 +881,7 @@ TEST_CASE("LexicalAnalyzer_LiteralStringScalar") { REQUIRE(token.str.begin() == &input[3]); REQUIRE(token.str.end() == &input[0] + 6); REQUIRE(lexer.get_block_scalar_header().chomp == fkyaml::detail::chomping_indicator_t::KEEP); - REQUIRE(lexer.get_block_scalar_header().indent == 3); // lexer returns content size if empty. + REQUIRE(lexer.get_block_scalar_header().indent == 2); REQUIRE_NOTHROW(token = lexer.get_next_token()); REQUIRE(token.type == fkyaml::detail::lexical_token_t::END_OF_BUFFER); @@ -657,6 +895,41 @@ TEST_CASE("LexicalAnalyzer_LiteralStringScalar") { REQUIRE_THROWS_AS(lexer.get_next_token(), fkyaml::parse_error); } + SECTION("a leading empty line is more indented") { + const char input[] = "|\n" + " \n" + " foo"; + + fkyaml::detail::lexical_analyzer lexer(input); + REQUIRE_THROWS_AS(lexer.get_next_token(), fkyaml::parse_error); + } + + SECTION("a leading empty line contains a tab") { + const char input[] = "|\n" + " \t \n" + " foo"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::BLOCK_LITERAL_SCALAR); + REQUIRE(token.str.begin() == &input[2]); + REQUIRE(token.str.end() == &input[0] + 12); + REQUIRE(lexer.get_block_scalar_header().chomp == fkyaml::detail::chomping_indicator_t::CLIP); + REQUIRE(lexer.get_block_scalar_header().indent == 2); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::END_OF_BUFFER); + } + + SECTION("a following content line is less indented") { + const char input[] = "|\n" + " foo\n" + " bar"; + + fkyaml::detail::lexical_analyzer lexer(input); + REQUIRE_THROWS_AS(lexer.get_next_token(), fkyaml::parse_error); + } + SECTION("less indented literal string scalar") { const char input[] = "|2\n" " foo"; @@ -913,7 +1186,7 @@ TEST_CASE("LexicalAnalyzer_FoldedString") { REQUIRE(token.str.begin() == &input[3]); REQUIRE(token.str.end() == &input[0] + 6); REQUIRE(lexer.get_block_scalar_header().chomp == fkyaml::detail::chomping_indicator_t::STRIP); - REQUIRE(lexer.get_block_scalar_header().indent == 3); // lexer returns content size if empty. + REQUIRE(lexer.get_block_scalar_header().indent == 2); REQUIRE_NOTHROW(token = lexer.get_next_token()); REQUIRE(token.type == fkyaml::detail::lexical_token_t::END_OF_BUFFER); @@ -929,7 +1202,7 @@ TEST_CASE("LexicalAnalyzer_FoldedString") { REQUIRE(token.str.begin() == &input[2]); REQUIRE(token.str.end() == &input[0] + 5); REQUIRE(lexer.get_block_scalar_header().chomp == fkyaml::detail::chomping_indicator_t::CLIP); - REQUIRE(lexer.get_block_scalar_header().indent == 3); // lexer returns content size if empty. + REQUIRE(lexer.get_block_scalar_header().indent == 2); REQUIRE_NOTHROW(token = lexer.get_next_token()); REQUIRE(token.type == fkyaml::detail::lexical_token_t::END_OF_BUFFER); @@ -945,20 +1218,55 @@ TEST_CASE("LexicalAnalyzer_FoldedString") { REQUIRE(token.str.begin() == &input[3]); REQUIRE(token.str.end() == &input[0] + 6); REQUIRE(lexer.get_block_scalar_header().chomp == fkyaml::detail::chomping_indicator_t::KEEP); - REQUIRE(lexer.get_block_scalar_header().indent == 3); // lexer returns content size if empty. + REQUIRE(lexer.get_block_scalar_header().indent == 2); REQUIRE_NOTHROW(token = lexer.get_next_token()); REQUIRE(token.type == fkyaml::detail::lexical_token_t::END_OF_BUFFER); } SECTION("folded string scalar with 0 indent level") { - const char input[] = "|0\n" + const char input[] = ">0\n" "foo"; fkyaml::detail::lexical_analyzer lexer(input); REQUIRE_THROWS_AS(lexer.get_next_token(), fkyaml::parse_error); } + SECTION("a leading empty line is more indented") { + const char input[] = ">\n" + " \n" + " foo"; + + fkyaml::detail::lexical_analyzer lexer(input); + REQUIRE_THROWS_AS(lexer.get_next_token(), fkyaml::parse_error); + } + + SECTION("a leading empty line contains a tab") { + const char input[] = ">\n" + " \t \n" + " foo"; + fkyaml::detail::lexical_analyzer lexer(input); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::BLOCK_FOLDED_SCALAR); + REQUIRE(token.str.begin() == &input[2]); + REQUIRE(token.str.end() == &input[0] + 12); + REQUIRE(lexer.get_block_scalar_header().chomp == fkyaml::detail::chomping_indicator_t::CLIP); + REQUIRE(lexer.get_block_scalar_header().indent == 2); + + REQUIRE_NOTHROW(token = lexer.get_next_token()); + REQUIRE(token.type == fkyaml::detail::lexical_token_t::END_OF_BUFFER); + } + + SECTION("a following content line is less indented") { + const char input[] = ">\n" + " foo\n" + " bar"; + + fkyaml::detail::lexical_analyzer lexer(input); + REQUIRE_THROWS_AS(lexer.get_next_token(), fkyaml::parse_error); + } + SECTION("less indented folded string scalar") { const char input[] = ">2\n" " foo"; diff --git a/test/unit_test/test_node_attrs.cpp b/test/unit_test/test_node_attrs.cpp index 5dace365..dba783d0 100644 --- a/test/unit_test/test_node_attrs.cpp +++ b/test/unit_test/test_node_attrs.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_node_class.cpp b/test/unit_test/test_node_class.cpp index b9b5be46..1773361a 100644 --- a/test/unit_test/test_node_class.cpp +++ b/test/unit_test/test_node_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -3425,6 +3425,46 @@ TEST_CASE("Node_Begin") { } } +TEST_CASE("Node_ConstBegin") { + SECTION("container nodes") { + auto node = GENERATE(fkyaml::node::sequence(), fkyaml::node::mapping()); + + SECTION("non-const non-alias container node") { + REQUIRE_NOTHROW(node.cbegin()); + } + + SECTION("const non-alias container node") { + const fkyaml::node const_node = node; + REQUIRE_NOTHROW(const_node.cbegin()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.cbegin()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + const fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.cbegin()); + } + } + + SECTION("scalar nodes") { + auto node = GENERATE(fkyaml::node(), fkyaml::node(false), fkyaml::node(0), fkyaml::node(0.0), fkyaml::node("")); + + SECTION("non-const node") { + REQUIRE_THROWS_AS(node.cbegin(), fkyaml::type_error); + } + + SECTION("const node") { + const fkyaml::node const_node = node; + REQUIRE_THROWS_AS(const_node.cbegin(), fkyaml::type_error); + } + } +} + TEST_CASE("Node_End") { SECTION("container nodes") { auto node = GENERATE(fkyaml::node::sequence(), fkyaml::node::mapping()); @@ -3449,14 +3489,45 @@ TEST_CASE("Node_End") { const fkyaml::node alias = fkyaml::node::alias_of(node); REQUIRE_NOTHROW(alias.end()); } + } - SECTION("non-const range-based for-loop compatibility") { - REQUIRE_NOTHROW(node.end()); + SECTION("scalar nodes") { + auto node = GENERATE(fkyaml::node(), fkyaml::node(false), fkyaml::node(0), fkyaml::node(0.0), fkyaml::node("")); + + SECTION("non-const throwing node") { + REQUIRE_THROWS_AS(node.end(), fkyaml::type_error); } - SECTION("const range-based for-loop compatibility") { + SECTION("const throwing node") { const fkyaml::node const_node = node; - REQUIRE_NOTHROW(const_node.end()); + REQUIRE_THROWS_AS(const_node.end(), fkyaml::type_error); + } + } +} + +TEST_CASE("Node_ConstEnd") { + SECTION("container nodes") { + auto node = GENERATE(fkyaml::node::sequence(), fkyaml::node::mapping()); + + SECTION("non-const non-alias container node") { + REQUIRE_NOTHROW(node.cend()); + } + + SECTION("const non-alias container node") { + const fkyaml::node const_node = node; + REQUIRE_NOTHROW(const_node.cend()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.cend()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + const fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.cend()); } } @@ -3464,12 +3535,172 @@ TEST_CASE("Node_End") { auto node = GENERATE(fkyaml::node(), fkyaml::node(false), fkyaml::node(0), fkyaml::node(0.0), fkyaml::node("")); SECTION("non-const throwing node") { - REQUIRE_THROWS_AS(node.end(), fkyaml::type_error); + REQUIRE_THROWS_AS(node.cend(), fkyaml::type_error); } SECTION("const throwing node") { const fkyaml::node const_node = node; - REQUIRE_THROWS_AS(const_node.end(), fkyaml::type_error); + REQUIRE_THROWS_AS(const_node.cend(), fkyaml::type_error); + } + } +} + +TEST_CASE("Node_ReverseBegin") { + SECTION("container nodes") { + auto node = GENERATE(fkyaml::node::sequence(), fkyaml::node::mapping()); + + SECTION("non-const non-alias container node") { + REQUIRE_NOTHROW(node.rbegin()); + } + + SECTION("const non-alias container node") { + const fkyaml::node const_node = node; + REQUIRE_NOTHROW(const_node.rbegin()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.rbegin()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + const fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.rbegin()); + } + } + + SECTION("scalar nodes") { + auto node = GENERATE(fkyaml::node(), fkyaml::node(false), fkyaml::node(0), fkyaml::node(0.0), fkyaml::node("")); + + SECTION("non-const throwing node") { + REQUIRE_THROWS_AS(node.rbegin(), fkyaml::type_error); + } + + SECTION("const throwing node") { + const fkyaml::node const_node = node; + REQUIRE_THROWS_AS(const_node.rbegin(), fkyaml::type_error); + } + } +} + +TEST_CASE("Node_ConstReverseBegin") { + SECTION("container nodes") { + auto node = GENERATE(fkyaml::node::sequence(), fkyaml::node::mapping()); + + SECTION("non-const non-alias container node") { + REQUIRE_NOTHROW(node.crbegin()); + } + + SECTION("const non-alias container node") { + const fkyaml::node const_node = node; + REQUIRE_NOTHROW(const_node.crbegin()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.crbegin()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + const fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.crbegin()); + } + } + + SECTION("scalar nodes") { + auto node = GENERATE(fkyaml::node(), fkyaml::node(false), fkyaml::node(0), fkyaml::node(0.0), fkyaml::node("")); + + SECTION("non-const throwing node") { + REQUIRE_THROWS_AS(node.crbegin(), fkyaml::type_error); + } + + SECTION("const throwing node") { + const fkyaml::node const_node = node; + REQUIRE_THROWS_AS(const_node.crbegin(), fkyaml::type_error); + } + } +} + +TEST_CASE("Node_ReverseEnd") { + SECTION("container nodes") { + auto node = GENERATE(fkyaml::node::sequence(), fkyaml::node::mapping()); + + SECTION("non-const non-alias container node") { + REQUIRE_NOTHROW(node.rend()); + } + + SECTION("const non-alias container node") { + const fkyaml::node const_node = node; + REQUIRE_NOTHROW(const_node.rend()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.rend()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + const fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.rend()); + } + } + + SECTION("scalar nodes") { + auto node = GENERATE(fkyaml::node(), fkyaml::node(false), fkyaml::node(0), fkyaml::node(0.0), fkyaml::node("")); + + SECTION("non-const throwing node") { + REQUIRE_THROWS_AS(node.rend(), fkyaml::type_error); + } + + SECTION("const throwing node") { + const fkyaml::node const_node = node; + REQUIRE_THROWS_AS(const_node.rend(), fkyaml::type_error); + } + } +} + +TEST_CASE("Node_ConstReverseEnd") { + SECTION("container nodes") { + auto node = GENERATE(fkyaml::node::sequence(), fkyaml::node::mapping()); + + SECTION("non-const non-alias container node") { + REQUIRE_NOTHROW(node.crend()); + } + + SECTION("const non-alias container node") { + const fkyaml::node const_node = node; + REQUIRE_NOTHROW(const_node.crend()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.crend()); + } + + SECTION("non-const alias container node") { + node.add_anchor_name("anchor_name"); + const fkyaml::node alias = fkyaml::node::alias_of(node); + REQUIRE_NOTHROW(alias.crend()); + } + } + + SECTION("scalar nodes") { + auto node = GENERATE(fkyaml::node(), fkyaml::node(false), fkyaml::node(0), fkyaml::node(0.0), fkyaml::node("")); + + SECTION("non-const throwing node") { + REQUIRE_THROWS_AS(node.crend(), fkyaml::type_error); + } + + SECTION("const throwing node") { + const fkyaml::node const_node = node; + REQUIRE_THROWS_AS(const_node.crend(), fkyaml::type_error); } } } diff --git a/test/unit_test/test_node_ref_storage_class.cpp b/test/unit_test/test_node_ref_storage_class.cpp index e0c46ed7..f091ec0f 100644 --- a/test/unit_test/test_node_ref_storage_class.cpp +++ b/test/unit_test/test_node_ref_storage_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_node_type.cpp b/test/unit_test/test_node_type.cpp index eb4fe5c9..1eb5058d 100644 --- a/test/unit_test/test_node_type.cpp +++ b/test/unit_test/test_node_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_ordered_map_class.cpp b/test/unit_test/test_ordered_map_class.cpp index 76aae24f..51928e0f 100644 --- a/test/unit_test/test_ordered_map_class.cpp +++ b/test/unit_test/test_ordered_map_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_position_tracker_class.cpp b/test/unit_test/test_position_tracker_class.cpp index d17bdf08..7ca3362c 100644 --- a/test/unit_test/test_position_tracker_class.cpp +++ b/test/unit_test/test_position_tracker_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_reverse_iterator_class.cpp b/test/unit_test/test_reverse_iterator_class.cpp new file mode 100644 index 00000000..25ab63f3 --- /dev/null +++ b/test/unit_test/test_reverse_iterator_class.cpp @@ -0,0 +1,396 @@ +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#include + +#include + +TEST_CASE("ReverseIterator_Ctor") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + SECTION("with base iterator") { + fkyaml::detail::reverse_iterator rit = sequence.begin(); + REQUIRE(rit.base() == sequence.begin()); + fkyaml::detail::reverse_iterator rit2 = mapping.begin(); + REQUIRE(rit2.base() == mapping.begin()); + } + + SECTION("with compatible reverse_iterator") { + fkyaml::detail::reverse_iterator rit = sequence.rbegin(); + REQUIRE(rit.base() == sequence.end()); + fkyaml::detail::reverse_iterator rit2 = mapping.rbegin(); + REQUIRE(rit2.base() == mapping.end()); + } +} + +TEST_CASE("ReverseIterator_AssignmentOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + SECTION("with compatible reverse_iterator") { + fkyaml::detail::reverse_iterator rit = sequence.rbegin(); + fkyaml::detail::reverse_iterator rit2 = mapping.rbegin(); + + fkyaml::detail::reverse_iterator crit; + crit = rit; + REQUIRE(crit.base() == sequence.end()); + + fkyaml::detail::reverse_iterator crit2; + crit2 = rit2; + REQUIRE(crit2.base() == mapping.end()); + } +} + +TEST_CASE("ReverseIterator_DereferenceOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.end(); + REQUIRE(&(*rit) == &sequence[1]); + + fkyaml::detail::reverse_iterator rit2 = mapping.end(); + REQUIRE(&(*rit2) == &mapping["foo"]); +} + +TEST_CASE("ReverseIterator_ArrowOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.end(); + REQUIRE(rit.operator->() == &sequence[1]); + + fkyaml::detail::reverse_iterator rit2 = mapping.end(); + REQUIRE(rit2.operator->() == &mapping["foo"]); +} + +TEST_CASE("ReverseIterator_CompoundAssignmentOperatorBySum") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.end(); + rit += 1; + REQUIRE(rit.operator->() == &sequence[0]); + + fkyaml::detail::reverse_iterator rit2 = mapping.end(); + rit2 += 1; + REQUIRE(rit2.operator->() == &mapping["bar"]); +} + +TEST_CASE("ReverseIterator_PlusOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.end(); + fkyaml::detail::reverse_iterator rit_plus = rit + 1; + REQUIRE(rit.operator->() == &sequence[1]); + REQUIRE(rit_plus.operator->() == &sequence[0]); + + fkyaml::detail::reverse_iterator rit2 = mapping.end(); + fkyaml::detail::reverse_iterator rit2_plus = rit2 + 1; + REQUIRE(rit2.operator->() == &mapping["foo"]); + REQUIRE(rit2_plus.operator->() == &mapping["bar"]); +} + +TEST_CASE("ReverseIterator_CompoundAssignmentOperatorByDifference") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.begin(); + rit -= 1; + REQUIRE(rit.operator->() == &sequence[0]); + + fkyaml::detail::reverse_iterator rit2 = mapping.begin(); + rit2 -= 1; + REQUIRE(rit2.operator->() == &mapping["bar"]); +} + +TEST_CASE("ReverseIterator_MinusOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.begin(); + fkyaml::detail::reverse_iterator rit_minus = rit - 1; + REQUIRE(rit.base() == sequence.begin()); + REQUIRE(rit_minus.operator->() == &sequence[0]); + + fkyaml::detail::reverse_iterator rit2 = mapping.begin(); + fkyaml::detail::reverse_iterator rit2_minus = rit2 - 1; + REQUIRE(rit2.base() == mapping.begin()); + REQUIRE(rit2_minus.operator->() == &mapping["bar"]); +} + +TEST_CASE("ReverseIterator_PreDecrementOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.begin(); + fkyaml::detail::reverse_iterator rit_predcr = --rit; + REQUIRE(rit == rit_predcr); + + fkyaml::detail::reverse_iterator rit2 = mapping.begin(); + fkyaml::detail::reverse_iterator rit2_predcr = --rit2; + REQUIRE(rit2 == rit2_predcr); +} + +TEST_CASE("ReverseIterator_PostDecrementOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.begin(); + fkyaml::detail::reverse_iterator rit_postdcr = rit--; + REQUIRE(rit + 1 == rit_postdcr); + + fkyaml::detail::reverse_iterator rit2 = mapping.begin(); + fkyaml::detail::reverse_iterator rit2_postdcr = rit2--; + REQUIRE(rit2 + 1 == rit2_postdcr); +} + +TEST_CASE("ReverseIterator_PreIncrementOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.end(); + fkyaml::detail::reverse_iterator rit_preincr = ++rit; + REQUIRE(rit == rit_preincr); + + fkyaml::detail::reverse_iterator rit2 = mapping.end(); + fkyaml::detail::reverse_iterator rit2_preincr = ++rit2; + REQUIRE(rit2 == rit2_preincr); +} + +TEST_CASE("ReverseIterator_PostIncrementOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + fkyaml::detail::reverse_iterator rit = sequence.end(); + fkyaml::detail::reverse_iterator rit_postincr = rit++; + REQUIRE(rit - 1 == rit_postincr); + + fkyaml::detail::reverse_iterator rit2 = mapping.end(); + fkyaml::detail::reverse_iterator rit2_postincr = rit2++; + REQUIRE(rit2 - 1 == rit2_postincr); +} + +TEST_CASE("ReverseIterator_EqualToOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + SECTION("sequence iterator") { + fkyaml::detail::reverse_iterator lhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator rhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator clhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator crhs = sequence.rbegin(); + + REQUIRE(lhs == rhs); + REQUIRE(clhs == crhs); + REQUIRE(lhs == crhs); + REQUIRE(clhs == rhs); + } + + SECTION("sequence iterator") { + fkyaml::detail::reverse_iterator lhs = mapping.rbegin(); + fkyaml::detail::reverse_iterator rhs = mapping.rbegin(); + fkyaml::detail::reverse_iterator clhs = mapping.rbegin(); + fkyaml::detail::reverse_iterator crhs = mapping.rbegin(); + + REQUIRE(lhs == rhs); + REQUIRE(clhs == crhs); + REQUIRE(lhs == crhs); + REQUIRE(clhs == rhs); + } + + SECTION("equality check between different type reverse iterators") { + REQUIRE_THROWS_AS(sequence.rbegin() == mapping.rbegin(), fkyaml::exception); + } +} + +TEST_CASE("ReverseIterator_NotEqualToOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + SECTION("sequence iterator") { + fkyaml::detail::reverse_iterator lhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator rhs = sequence.rbegin() + 1; + fkyaml::detail::reverse_iterator clhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator crhs = sequence.rbegin() + 1; + + REQUIRE(lhs != rhs); + REQUIRE(clhs != crhs); + REQUIRE(lhs != crhs); + REQUIRE(clhs != rhs); + } + + SECTION("mapping iterator") { + fkyaml::detail::reverse_iterator lhs = mapping.rbegin(); + fkyaml::detail::reverse_iterator rhs = mapping.rbegin() + 1; + fkyaml::detail::reverse_iterator clhs = mapping.rbegin(); + fkyaml::detail::reverse_iterator crhs = mapping.rbegin() + 1; + + REQUIRE(lhs != rhs); + REQUIRE(clhs != crhs); + REQUIRE(lhs != crhs); + REQUIRE(clhs != rhs); + } + + SECTION("equality check between different type reverse iterators") { + REQUIRE_THROWS_AS(sequence.rbegin() != mapping.rbegin(), fkyaml::exception); + } +} + +TEST_CASE("ReverseIterator_LessThanOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + SECTION("sequence iterator") { + fkyaml::detail::reverse_iterator lhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator rhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator clhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator crhs = sequence.rbegin(); + + REQUIRE_FALSE(lhs < rhs); + REQUIRE_FALSE(clhs < crhs); + REQUIRE_FALSE(lhs < crhs); + REQUIRE_FALSE(clhs < rhs); + ++rhs; + ++crhs; + REQUIRE(lhs < rhs); + REQUIRE(clhs < crhs); + REQUIRE(lhs < crhs); + REQUIRE(clhs < rhs); + } + + SECTION("mapping iterator") { + REQUIRE_THROWS_AS(mapping.rbegin() < mapping.rbegin() + 1, fkyaml::exception); + } + + SECTION("equality check between different type reverse iterators") { + REQUIRE_THROWS_AS(sequence.rbegin() < mapping.rbegin(), fkyaml::exception); + } +} + +TEST_CASE("ReverseIterator_LessThanOrEqualToOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + SECTION("sequence iterator") { + fkyaml::detail::reverse_iterator lhs = sequence.rbegin() + 1; + fkyaml::detail::reverse_iterator rhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator clhs = sequence.rbegin() + 1; + fkyaml::detail::reverse_iterator crhs = sequence.rbegin(); + + REQUIRE_FALSE(lhs <= rhs); + REQUIRE_FALSE(clhs <= crhs); + REQUIRE_FALSE(lhs <= crhs); + REQUIRE_FALSE(clhs <= rhs); + --lhs; + --clhs; + REQUIRE(lhs <= rhs); + REQUIRE(clhs <= crhs); + REQUIRE(lhs <= crhs); + REQUIRE(clhs <= rhs); + ++rhs; + ++crhs; + REQUIRE(lhs <= rhs); + REQUIRE(clhs <= crhs); + REQUIRE(lhs <= crhs); + REQUIRE(clhs <= rhs); + } + + SECTION("mapping iterator") { + REQUIRE_THROWS_AS(mapping.rbegin() <= mapping.rbegin() + 1, fkyaml::exception); + } + + SECTION("equality check between different type reverse iterators") { + REQUIRE_THROWS_AS(sequence.rbegin() <= mapping.rbegin(), fkyaml::exception); + } +} + +TEST_CASE("ReverseIterator_GreaterThanOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + SECTION("sequence iterator") { + fkyaml::detail::reverse_iterator lhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator rhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator clhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator crhs = sequence.rbegin(); + + REQUIRE_FALSE(lhs > rhs); + REQUIRE_FALSE(clhs > crhs); + REQUIRE_FALSE(lhs > crhs); + REQUIRE_FALSE(clhs > rhs); + ++lhs; + ++clhs; + REQUIRE(lhs > rhs); + REQUIRE(clhs > crhs); + REQUIRE(lhs > crhs); + REQUIRE(clhs > rhs); + } + + SECTION("mapping iterator") { + REQUIRE_THROWS_AS(mapping.rbegin() + 1 > mapping.rbegin(), fkyaml::exception); + } + + SECTION("equality check between different type reverse iterators") { + REQUIRE_THROWS_AS(sequence.rbegin() > mapping.rbegin(), fkyaml::exception); + } +} + +TEST_CASE("ReverseIterator_GreaterThanOrEqualToOperator") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + SECTION("sequence iterator") { + fkyaml::detail::reverse_iterator lhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator rhs = sequence.rbegin() + 1; + fkyaml::detail::reverse_iterator clhs = sequence.rbegin(); + fkyaml::detail::reverse_iterator crhs = sequence.rbegin() + 1; + + REQUIRE_FALSE(lhs >= rhs); + REQUIRE_FALSE(clhs >= crhs); + REQUIRE_FALSE(lhs >= crhs); + REQUIRE_FALSE(clhs >= rhs); + --rhs; + --crhs; + REQUIRE(lhs >= rhs); + REQUIRE(clhs >= crhs); + REQUIRE(lhs >= crhs); + REQUIRE(clhs >= rhs); + ++lhs; + ++clhs; + REQUIRE(lhs >= rhs); + REQUIRE(clhs >= crhs); + REQUIRE(lhs >= crhs); + REQUIRE(clhs >= rhs); + } + + SECTION("mapping iterator") { + REQUIRE_THROWS_AS(mapping.rbegin() + 1 >= mapping.rbegin(), fkyaml::exception); + } + + SECTION("equality check between different type reverse iterators") { + REQUIRE_THROWS_AS(sequence.rbegin() >= mapping.rbegin(), fkyaml::exception); + } +} + +TEST_CASE("ReverseIterator_KeyGetter") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + REQUIRE_THROWS_AS(sequence.rbegin().key(), fkyaml::exception); + REQUIRE(mapping.rbegin().key() == (mapping.end() - 1).key()); +} + +TEST_CASE("ReverseIterator_ValueGetter") { + fkyaml::node sequence = {nullptr, 123}; + fkyaml::node mapping = {{"foo", 123}, {"bar", true}}; + + REQUIRE(sequence.rbegin().value() == (sequence.end() - 1).value()); + REQUIRE(mapping.rbegin().value() == (mapping.end() - 1).value()); +} diff --git a/test/unit_test/test_scalar_conv.cpp b/test/unit_test/test_scalar_conv.cpp index a35e113f..18cd86e8 100644 --- a/test/unit_test/test_scalar_conv.cpp +++ b/test/unit_test/test_scalar_conv.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_scalar_parser_class.cpp b/test/unit_test/test_scalar_parser_class.cpp index 8a0ef795..369ecc43 100644 --- a/test/unit_test/test_scalar_parser_class.cpp +++ b/test/unit_test/test_scalar_parser_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -204,7 +204,7 @@ TEST_CASE("ScalarParser_FlowPlainScalar_string") { fkyaml::detail::scalar_parser scalar_parser {0, 0}; fkyaml::detail::tag_t tag_type {fkyaml::detail::tag_t::NONE}; - SECTION("plain: normal contents") { + SECTION("plain: single line contents") { fkyaml::detail::lexical_token_t lex_type {fkyaml::detail::lexical_token_t::PLAIN_SCALAR}; auto token = GENERATE( @@ -249,13 +249,31 @@ TEST_CASE("ScalarParser_FlowPlainScalar_string") { fkyaml::detail::str_view("-.INF_VALUE"), fkyaml::detail::str_view(".nanValue"), fkyaml::detail::str_view(".NaNValue"), - fkyaml::detail::str_view(".NAN_VALUE")); + fkyaml::detail::str_view(".NAN_VALUE"), + // fkyaml::node::integer_type(=int64_t) cannot express this value. + fkyaml::detail::str_view("0xFFFFFFFFFFFFFFFF0"), + // fkyaml::node::float_number_type(=double) cannot express this value. + fkyaml::detail::str_view("6E-578")); REQUIRE_NOTHROW(node = scalar_parser.parse_flow(lex_type, tag_type, token)); REQUIRE(node.is_string()); REQUIRE(node.get_value_ref() == token); } + SECTION("plain: multiline contents") { + fkyaml::detail::lexical_token_t lex_type {fkyaml::detail::lexical_token_t::PLAIN_SCALAR}; + using test_data_t = std::pair; + auto test_data = GENERATE( + test_data_t("foo\nbar", "foo bar"), + test_data_t("foo\n \tbar", "foo bar"), + test_data_t("foo\n\n \t\n bar", "foo\n\nbar"), + test_data_t("foo\n \t\t\t\n bar", "foo\nbar")); + + REQUIRE_NOTHROW(node = scalar_parser.parse_flow(lex_type, tag_type, test_data.first)); + REQUIRE(node.is_string()); + REQUIRE(node.get_value_ref() == test_data.second); + } + SECTION("single quoted: single line contents") { fkyaml::detail::lexical_token_t lex_type {fkyaml::detail::lexical_token_t::SINGLE_QUOTED_SCALAR}; using test_data_t = std::pair; @@ -399,7 +417,7 @@ TEST_CASE("ScalarParser_BlockLiteralScalar") { SECTION("empty literal string scalar with strip chomping") { fkyaml::detail::str_view token = " \n"; header.chomp = fkyaml::detail::chomping_indicator_t::STRIP; - header.indent = 3; + header.indent = 2; REQUIRE_NOTHROW(node = scalar_parser.parse_block(lex_type, tag_type, token, header)); REQUIRE(node.is_string()); @@ -409,7 +427,7 @@ TEST_CASE("ScalarParser_BlockLiteralScalar") { SECTION("empty literal string scalar with clip chomping") { fkyaml::detail::str_view token = " \n"; header.chomp = fkyaml::detail::chomping_indicator_t::CLIP; - header.indent = 3; + header.indent = 2; REQUIRE_NOTHROW(node = scalar_parser.parse_block(lex_type, tag_type, token, header)); REQUIRE(node.is_string()); @@ -419,13 +437,24 @@ TEST_CASE("ScalarParser_BlockLiteralScalar") { SECTION("empty literal string scalar with keep chomping") { fkyaml::detail::str_view token = " \n"; header.chomp = fkyaml::detail::chomping_indicator_t::KEEP; - header.indent = 3; + header.indent = 2; REQUIRE_NOTHROW(node = scalar_parser.parse_block(lex_type, tag_type, token, header)); REQUIRE(node.is_string()); REQUIRE(node.get_value_ref() == "\n"); } + SECTION("a leading empty line contains a tab") { + fkyaml::detail::str_view token = " \t \n" + " foo"; + header.chomp = fkyaml::detail::chomping_indicator_t::CLIP; + header.indent = 2; + + REQUIRE_NOTHROW(node = scalar_parser.parse_block(lex_type, tag_type, token, header)); + REQUIRE(node.is_string()); + REQUIRE(node.get_value_ref() == "\t \nfoo"); + } + SECTION("literal scalar with the first line being more indented than the indicated level") { fkyaml::detail::str_view token = " foo\n" " bar\n"; @@ -601,6 +630,17 @@ TEST_CASE("ScalarParser_BlockFoldedScalar") { REQUIRE(node.get_value_ref() == "\n"); } + SECTION("a leading empty line contains a tab") { + fkyaml::detail::str_view token = " \t \n" + " foo"; + header.chomp = fkyaml::detail::chomping_indicator_t::CLIP; + header.indent = 2; + + REQUIRE_NOTHROW(node = scalar_parser.parse_block(lex_type, tag_type, token, header)); + REQUIRE(node.is_string()); + REQUIRE(node.get_value_ref() == "\n\t \nfoo"); + } + SECTION("folded string scalar with the first line being more indented than the indicated level") { fkyaml::detail::str_view token = " foo\n" " bar\n"; diff --git a/test/unit_test/test_scalar_scanner_class.cpp b/test/unit_test/test_scalar_scanner_class.cpp index ed5a4a38..1a8a4386 100644 --- a/test/unit_test/test_scalar_scanner_class.cpp +++ b/test/unit_test/test_scalar_scanner_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_serializer_class.cpp b/test/unit_test/test_serializer_class.cpp index 53ce323f..b2cf8d5b 100644 --- a/test/unit_test/test_serializer_class.cpp +++ b/test/unit_test/test_serializer_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -60,6 +60,8 @@ TEST_CASE("SerializeClassTest_FloatNode", "[SerializeClassTest]") { node_str_pair_t(2.10, "2.1"), node_str_pair_t(3.14, "3.14"), node_str_pair_t(-53.97, "-53.97"), + node_str_pair_t(23000000.0, "2.3e+07"), + node_str_pair_t(-23000000.0, "-2.3e+07"), node_str_pair_t(std::numeric_limits::infinity(), ".inf"), node_str_pair_t(-1 * std::numeric_limits::infinity(), "-.inf"), node_str_pair_t(std::nan(""), ".nan")); diff --git a/test/unit_test/test_str_view_class.cpp b/test/unit_test/test_str_view_class.cpp index 31344b59..54c53115 100644 --- a/test/unit_test/test_str_view_class.cpp +++ b/test/unit_test/test_str_view_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_string_formatter.cpp b/test/unit_test/test_string_formatter.cpp index 6abe0bd2..93ca5c41 100644 --- a/test/unit_test/test_string_formatter.cpp +++ b/test/unit_test/test_string_formatter.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_tag_resolver_class.cpp b/test/unit_test/test_tag_resolver_class.cpp index e1412e3e..357ce8b3 100644 --- a/test/unit_test/test_tag_resolver_class.cpp +++ b/test/unit_test/test_tag_resolver_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_uri_encoding_class.cpp b/test/unit_test/test_uri_encoding_class.cpp index 9ff364a0..80c93839 100644 --- a/test/unit_test/test_uri_encoding_class.cpp +++ b/test/unit_test/test_uri_encoding_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_utf_encode_detector.cpp b/test/unit_test/test_utf_encode_detector.cpp index 760ebccd..bffbc6bf 100644 --- a/test/unit_test/test_utf_encode_detector.cpp +++ b/test/unit_test/test_utf_encode_detector.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -23,19 +23,19 @@ #define ENABLE_C4996 #endif -TEST_CASE("UTFEncodeDetector_DetectEncodingType") { - struct test_data_t { - test_data_t(std::array input_, fkyaml::detail::utf_encode_t encode_type_, bool has_bom_) - : input(input_), - encode_type(encode_type_), - has_bom(has_bom_) { - } - - std::array input {}; - fkyaml::detail::utf_encode_t encode_type {fkyaml::detail::utf_encode_t::UTF_8}; - bool has_bom {false}; - }; +struct test_data_t { + test_data_t(std::array input_, fkyaml::detail::utf_encode_t encode_type_, bool has_bom_) + : input(input_), + encode_type(encode_type_), + has_bom(has_bom_) { + } + std::array input {{}}; + fkyaml::detail::utf_encode_t encode_type {fkyaml::detail::utf_encode_t::UTF_8}; + bool has_bom {false}; +}; + +TEST_CASE("UTFEncodeDetector_DetectEncodingType") { auto d = GENERATE( test_data_t {{{0xEFu, 0xBBu, 0xBFu, 0x80u}}, fkyaml::detail::utf_encode_t::UTF_8, true}, test_data_t {{{0xEFu, 0, 0xBFu, 0x80u}}, fkyaml::detail::utf_encode_t::UTF_8, false}, diff --git a/test/unit_test/test_utf_encodings.cpp b/test/unit_test/test_utf_encodings.cpp index a339f794..7a920a75 100644 --- a/test/unit_test/test_utf_encodings.cpp +++ b/test/unit_test/test_utf_encodings.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -238,55 +238,56 @@ TEST_CASE("UTF8_Validate") { } } +struct utf16_test_params { + std::array utf16; + std::array utf8_bytes; + std::size_t consumed_size; + std::size_t encoded_size; +}; + TEST_CASE("UTF8_FromUTF16") { SECTION("valid UTF-16 character(s)") { - struct test_params { - std::array utf16; - std::array utf8_bytes; - std::size_t consumed_size; - std::size_t encoded_size; - }; auto params = GENERATE( - test_params {{{char16_t(0x00u)}}, {{uint8_t(0x00u)}}, 1, 1}, - test_params {{{char16_t(0x01u)}}, {{uint8_t(0x01u)}}, 1, 1}, - test_params {{{char16_t(0x7Eu)}}, {{uint8_t(0x7Eu)}}, 1, 1}, - test_params {{{char16_t(0x7Fu)}}, {{uint8_t(0x7Fu)}}, 1, 1}, - test_params {{{char16_t(0x0080u)}}, {{uint8_t(0xC2u), uint8_t(0x80u)}}, 1, 2}, - test_params {{{char16_t(0x0081u)}}, {{uint8_t(0xC2u), uint8_t(0x81u)}}, 1, 2}, - test_params {{{char16_t(0x07FEu)}}, {{uint8_t(0xDFu), uint8_t(0xBEu)}}, 1, 2}, - test_params {{{char16_t(0x07FFu)}}, {{uint8_t(0xDFu), uint8_t(0xBFu)}}, 1, 2}, - test_params {{{char16_t(0x0800u)}}, {{uint8_t(0xE0u), uint8_t(0xA0u), uint8_t(0x80u)}}, 1, 3}, - test_params {{{char16_t(0x0801u)}}, {{uint8_t(0xE0u), uint8_t(0xA0u), uint8_t(0x81u)}}, 1, 3}, - test_params {{{char16_t(0xD7FEu)}}, {{uint8_t(0xEDu), uint8_t(0x9Fu), uint8_t(0xBEu)}}, 1, 3}, - test_params {{{char16_t(0xD7FFu)}}, {{uint8_t(0xEDu), uint8_t(0x9Fu), uint8_t(0xBFu)}}, 1, 3}, - test_params {{{char16_t(0xE000u)}}, {{uint8_t(0xEEu), uint8_t(0x80u), uint8_t(0x80u)}}, 1, 3}, - test_params {{{char16_t(0xE001u)}}, {{uint8_t(0xEEu), uint8_t(0x80u), uint8_t(0x81u)}}, 1, 3}, - test_params { + utf16_test_params {{{char16_t(0x00u)}}, {{uint8_t(0x00u)}}, 1, 1}, + utf16_test_params {{{char16_t(0x01u)}}, {{uint8_t(0x01u)}}, 1, 1}, + utf16_test_params {{{char16_t(0x7Eu)}}, {{uint8_t(0x7Eu)}}, 1, 1}, + utf16_test_params {{{char16_t(0x7Fu)}}, {{uint8_t(0x7Fu)}}, 1, 1}, + utf16_test_params {{{char16_t(0x0080u)}}, {{uint8_t(0xC2u), uint8_t(0x80u)}}, 1, 2}, + utf16_test_params {{{char16_t(0x0081u)}}, {{uint8_t(0xC2u), uint8_t(0x81u)}}, 1, 2}, + utf16_test_params {{{char16_t(0x07FEu)}}, {{uint8_t(0xDFu), uint8_t(0xBEu)}}, 1, 2}, + utf16_test_params {{{char16_t(0x07FFu)}}, {{uint8_t(0xDFu), uint8_t(0xBFu)}}, 1, 2}, + utf16_test_params {{{char16_t(0x0800u)}}, {{uint8_t(0xE0u), uint8_t(0xA0u), uint8_t(0x80u)}}, 1, 3}, + utf16_test_params {{{char16_t(0x0801u)}}, {{uint8_t(0xE0u), uint8_t(0xA0u), uint8_t(0x81u)}}, 1, 3}, + utf16_test_params {{{char16_t(0xD7FEu)}}, {{uint8_t(0xEDu), uint8_t(0x9Fu), uint8_t(0xBEu)}}, 1, 3}, + utf16_test_params {{{char16_t(0xD7FFu)}}, {{uint8_t(0xEDu), uint8_t(0x9Fu), uint8_t(0xBFu)}}, 1, 3}, + utf16_test_params {{{char16_t(0xE000u)}}, {{uint8_t(0xEEu), uint8_t(0x80u), uint8_t(0x80u)}}, 1, 3}, + utf16_test_params {{{char16_t(0xE001u)}}, {{uint8_t(0xEEu), uint8_t(0x80u), uint8_t(0x81u)}}, 1, 3}, + utf16_test_params { {{char16_t(0xD800u), char16_t(0xDC00u)}}, {{uint8_t(0xF0u), uint8_t(0x90u), uint8_t(0x80u), uint8_t(0x80u)}}, 2, 4}, - test_params { + utf16_test_params { {{char16_t(0xD801u), char16_t(0xDC00u)}}, {{uint8_t(0xF0u), uint8_t(0x90u), uint8_t(0x90u), uint8_t(0x80u)}}, 2, 4}, - test_params { + utf16_test_params { {{char16_t(0xD800u), char16_t(0xDC01u)}}, {{uint8_t(0xF0u), uint8_t(0x90u), uint8_t(0x80u), uint8_t(0x81u)}}, 2, 4}, - test_params { + utf16_test_params { {{char16_t(0xDBFEu), char16_t(0xDFFFu)}}, {{uint8_t(0xF4u), uint8_t(0x8Fu), uint8_t(0xAFu), uint8_t(0xBFu)}}, 2, 4}, - test_params { + utf16_test_params { {{char16_t(0xDBFFu), char16_t(0xDFFEu)}}, {{uint8_t(0xF4u), uint8_t(0x8Fu), uint8_t(0xBFu), uint8_t(0xBEu)}}, 2, 4}, - test_params { + utf16_test_params { {{char16_t(0xDBFFu), char16_t(0xDFFFu)}}, {{uint8_t(0xF4u), uint8_t(0x8Fu), uint8_t(0xBFu), uint8_t(0xBFu)}}, 2, @@ -319,29 +320,30 @@ TEST_CASE("UTF8_FromUTF16") { } } +struct utf32_test_params { + char32_t utf32; + std::array utf8_bytes; + uint32_t size; +}; + TEST_CASE("UTF8_FromUTF32") { SECTION("valid UTF-32 character") { - struct test_params { - char32_t utf32; - std::array utf8_bytes; - uint32_t size; - }; auto params = GENERATE( - test_params {0x00u, {{uint8_t(0x00u)}}, 1}, - test_params {0x01u, {{uint8_t(0x01u)}}, 1}, - test_params {0x7Eu, {{uint8_t(0x7Eu)}}, 1}, - test_params {0x7Fu, {{uint8_t(0x7Fu)}}, 1}, - test_params {0x0080u, {{uint8_t(0xC2u), uint8_t(0x80u)}}, 2}, - test_params {0x0081u, {{uint8_t(0xC2u), uint8_t(0x81u)}}, 2}, - test_params {0x07FEu, {{uint8_t(0xDFu), uint8_t(0xBEu)}}, 2}, - test_params {0x07FFu, {{uint8_t(0xDFu), uint8_t(0xBFu)}}, 2}, - test_params {0x0800u, {{uint8_t(0xE0u), uint8_t(0xA0u), uint8_t(0x80u)}}, 3}, - test_params {0x0801u, {{uint8_t(0xE0u), uint8_t(0xA0u), uint8_t(0x81u)}}, 3}, - test_params {0xFFFFu, {{uint8_t(0xEFu), uint8_t(0xBFu), uint8_t(0xBFu)}}, 3}, - test_params {0x010000u, {{uint8_t(0xF0u), uint8_t(0x90u), uint8_t(0x80u), uint8_t(0x80u)}}, 4}, - test_params {0x010001u, {{uint8_t(0xF0u), uint8_t(0x90u), uint8_t(0x80u), uint8_t(0x81u)}}, 4}, - test_params {0x10FFFEu, {{uint8_t(0xF4u), uint8_t(0x8Fu), uint8_t(0xBFu), uint8_t(0xBEu)}}, 4}, - test_params {0x10FFFFu, {{uint8_t(0xF4u), uint8_t(0x8Fu), uint8_t(0xBFu), uint8_t(0xBFu)}}, 4}); + utf32_test_params {0x00u, {{uint8_t(0x00u)}}, 1}, + utf32_test_params {0x01u, {{uint8_t(0x01u)}}, 1}, + utf32_test_params {0x7Eu, {{uint8_t(0x7Eu)}}, 1}, + utf32_test_params {0x7Fu, {{uint8_t(0x7Fu)}}, 1}, + utf32_test_params {0x0080u, {{uint8_t(0xC2u), uint8_t(0x80u)}}, 2}, + utf32_test_params {0x0081u, {{uint8_t(0xC2u), uint8_t(0x81u)}}, 2}, + utf32_test_params {0x07FEu, {{uint8_t(0xDFu), uint8_t(0xBEu)}}, 2}, + utf32_test_params {0x07FFu, {{uint8_t(0xDFu), uint8_t(0xBFu)}}, 2}, + utf32_test_params {0x0800u, {{uint8_t(0xE0u), uint8_t(0xA0u), uint8_t(0x80u)}}, 3}, + utf32_test_params {0x0801u, {{uint8_t(0xE0u), uint8_t(0xA0u), uint8_t(0x81u)}}, 3}, + utf32_test_params {0xFFFFu, {{uint8_t(0xEFu), uint8_t(0xBFu), uint8_t(0xBFu)}}, 3}, + utf32_test_params {0x010000u, {{uint8_t(0xF0u), uint8_t(0x90u), uint8_t(0x80u), uint8_t(0x80u)}}, 4}, + utf32_test_params {0x010001u, {{uint8_t(0xF0u), uint8_t(0x90u), uint8_t(0x80u), uint8_t(0x81u)}}, 4}, + utf32_test_params {0x10FFFEu, {{uint8_t(0xF4u), uint8_t(0x8Fu), uint8_t(0xBFu), uint8_t(0xBEu)}}, 4}, + utf32_test_params {0x10FFFFu, {{uint8_t(0xF4u), uint8_t(0x8Fu), uint8_t(0xBFu), uint8_t(0xBFu)}}, 4}); std::array utf8_bytes; utf8_bytes.fill(0); diff --git a/test/unit_test/test_yaml_escaper_class.cpp b/test/unit_test/test_yaml_escaper_class.cpp index 68d1abe8..a0772229 100644 --- a/test/unit_test/test_yaml_escaper_class.cpp +++ b/test/unit_test/test_yaml_escaper_class.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_yaml_version_type.cpp b/test/unit_test/test_yaml_version_type.cpp index 779c9794..cb706712 100644 --- a/test/unit_test/test_yaml_version_type.cpp +++ b/test/unit_test/test_yaml_version_type.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/tool/benchmark/main.cpp b/tool/benchmark/main.cpp index e6e46a02..de2fb29f 100644 --- a/tool/benchmark/main.cpp +++ b/tool/benchmark/main.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 +// | __| _ < \_ _/| ___ | _ | |___ version 0.4.0 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/tool/natvis_generator/params.json b/tool/natvis_generator/params.json index dd993f55..30704b00 100644 --- a/tool/natvis_generator/params.json +++ b/tool/natvis_generator/params.json @@ -1 +1 @@ -{ "version": "0.3.14" } +{ "version": "0.4.0" }