From 31d375699beb0a354f96edf0f5b1fb69ba3916ba Mon Sep 17 00:00:00 2001 From: fktn Date: Sun, 20 Oct 2024 14:00:48 +0900 Subject: [PATCH 01/13] Fix wrong scalar value type detection from floating point value token (#414) * fixed false error on floating point value with the exponent * fixed wrong scalar value type detections from some other floating point number formats --- .../fkYAML/detail/input/scalar_scanner.hpp | 97 +++++++++++-------- single_include/fkYAML/node.hpp | 97 +++++++++++-------- test/unit_test/test_scalar_parser_class.cpp | 9 +- test/unit_test/test_scalar_scanner_class.cpp | 20 ++++ 4 files changed, 142 insertions(+), 81 deletions(-) diff --git a/include/fkYAML/detail/input/scalar_scanner.hpp b/include/fkYAML/detail/input/scalar_scanner.hpp index 4064b80f..b5739a91 100644 --- a/include/fkYAML/detail/input/scalar_scanner.hpp +++ b/include/fkYAML/detail/input/scalar_scanner.hpp @@ -137,7 +137,10 @@ class scalar_scanner { case '-': return (len > 1) ? scan_negative_number(++itr, --len) : node_type::STRING; case '+': - return (len > 1) ? scan_decimal_number(++itr, --len, false) : node_type::STRING; + return (len > 1) ? scan_decimal_number(++itr, --len) : node_type::STRING; + case '.': + // some integer(s) required after the decimal point as a floating point value. + return (len > 1) ? scan_after_decimal_point(++itr, --len) : node_type::STRING; case '0': return (len > 1) ? scan_after_zero_at_first(++itr, --len) : node_type::INTEGER; case '1': @@ -149,7 +152,7 @@ class scalar_scanner { case '7': case '8': case '9': - return (len > 1) ? scan_decimal_number(++itr, --len, false) : node_type::INTEGER; + return (len > 1) ? scan_decimal_number(++itr, --len) : node_type::INTEGER; default: return node_type::STRING; } @@ -163,7 +166,12 @@ class scalar_scanner { FK_YAML_ASSERT(len > 0); if (is_digit(*itr)) { - return (len > 1) ? scan_decimal_number(++itr, --len, false) : node_type::INTEGER; + return (len > 1) ? scan_decimal_number(++itr, --len) : node_type::INTEGER; + } + + if (*itr == '.') { + // some integer(s) required after "-." as a floating point value. + return (len > 1) ? scan_after_decimal_point(++itr, --len) : node_type::STRING; } return node_type::STRING; @@ -183,14 +191,13 @@ class scalar_scanner { } switch (*itr) { - case '.': { - if (len == 1) { - // 0 is omitted after `0.`. - return node_type::FLOAT; - } - node_type ret = scan_after_decimal_point(++itr, --len, true); - return (ret == node_type::STRING) ? node_type::STRING : node_type::FLOAT; - } + case '.': + // 0 can be omitted after `0.`. + return (len > 1) ? scan_after_decimal_point(++itr, --len) : node_type::FLOAT; + case 'e': + case 'E': + // some integer(s) required after the exponent sign as a floating point value. + return (len > 1) ? scan_after_exponent(++itr, --len) : node_type::STRING; case 'o': return (len > 1) ? scan_octal_number(++itr, --len) : node_type::STRING; case 'x': @@ -203,31 +210,23 @@ class scalar_scanner { /// @brief Detects a scalar value type by scanning the contents part starting with a decimal. /// @param itr The iterator to the beginning decimal element of the scalar. /// @param len The length of the scalar left unscanned. - /// @param has_decimal_point Whether a decimal point has already been found in the previous part. /// @return A detected scalar value type. - static node_type scan_decimal_number(const char* itr, uint32_t len, bool has_decimal_point) noexcept { + static node_type scan_decimal_number(const char* itr, uint32_t len) noexcept { FK_YAML_ASSERT(len > 0); if (is_digit(*itr)) { - return (len > 1) ? scan_decimal_number(++itr, --len, has_decimal_point) : node_type::INTEGER; + return (len > 1) ? scan_decimal_number(++itr, --len) : node_type::INTEGER; } switch (*itr) { case '.': { - if (has_decimal_point) { - // the token has more than one period, e.g., a semantic version `1.2.3`. - return node_type::STRING; - } - if (len == 1) { - // 0 is omitted after the decimal point - return node_type::FLOAT; - } - node_type ret = scan_after_decimal_point(++itr, --len, true); - return (ret == node_type::STRING) ? node_type::STRING : node_type::FLOAT; + // 0 can be omitted after the decimal point + return (len > 1) ? scan_after_decimal_point(++itr, --len) : node_type::FLOAT; } case 'e': case 'E': - return (len > 1) ? scan_after_exponent(++itr, --len, has_decimal_point) : node_type::STRING; + // some integer(s) required after the exponent + return (len > 1) ? scan_after_exponent(++itr, --len) : node_type::STRING; default: return node_type::STRING; } @@ -236,37 +235,55 @@ class scalar_scanner { /// @brief Detects a scalar value type by scanning the contents right after a decimal point. /// @param itr The iterator to the past-the-decimal-point element of the scalar. /// @param len The length of the scalar left unscanned. - /// @param has_decimal_point Whether the decimal point has already been found in the previous part. /// @return A detected scalar value type. - static node_type scan_after_decimal_point(const char* itr, uint32_t len, bool has_decimal_point) noexcept { + static node_type scan_after_decimal_point(const char* itr, uint32_t len) noexcept { FK_YAML_ASSERT(len > 0); - if (is_digit(*itr)) { - return (len > 1) ? scan_decimal_number(++itr, --len, has_decimal_point) : node_type::FLOAT; + for (uint32_t i = 0; i < len; i++) { + char c = *itr++; + + if (is_digit(c)) { + continue; + } + + if (c == 'e' || c == 'E') { + if (i == len - 1) { + // some integer(s) required after the exponent + return node_type::STRING; + } + return scan_after_exponent(itr, len - i - 1); + } + + return node_type::STRING; } - return node_type::STRING; + return node_type::FLOAT; } /// @brief Detects a scalar value type by scanning the contents right after the exponent prefix ("e" or "E"). /// @param itr The iterator to the past-the-exponent-prefix element of the scalar. /// @param len The length of the scalar left unscanned. - /// @param has_decimal_point Whether the decimal point has already been found in the previous part. /// @return A detected scalar value type. - static node_type scan_after_exponent(const char* itr, uint32_t len, bool has_decimal_point) noexcept { + static node_type scan_after_exponent(const char* itr, uint32_t len) noexcept { FK_YAML_ASSERT(len > 0); - if (is_digit(*itr)) { - return (len > 1) ? scan_decimal_number(++itr, --len, has_decimal_point) : node_type::FLOAT; + char c = *itr; + if (c == '+' || c == '-') { + if (len == 1) { + // some integer(s) required after the sign. + return node_type::STRING; + } + ++itr; + --len; } - switch (*itr) { - case '+': - case '-': - return (len > 1) ? scan_decimal_number(++itr, --len, has_decimal_point) : node_type::STRING; - default: - return node_type::STRING; + for (uint32_t i = 0; i < len; i++) { + if (!is_digit(*itr++)) { + return node_type::STRING; + } } + + return node_type::FLOAT; } /// @brief Detects a scalar value type by scanning the contents assuming octal numbers. diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index c8fe012d..81be9820 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -5336,7 +5336,10 @@ class scalar_scanner { case '-': return (len > 1) ? scan_negative_number(++itr, --len) : node_type::STRING; case '+': - return (len > 1) ? scan_decimal_number(++itr, --len, false) : node_type::STRING; + return (len > 1) ? scan_decimal_number(++itr, --len) : node_type::STRING; + case '.': + // some integer(s) required after the decimal point as a floating point value. + return (len > 1) ? scan_after_decimal_point(++itr, --len) : node_type::STRING; case '0': return (len > 1) ? scan_after_zero_at_first(++itr, --len) : node_type::INTEGER; case '1': @@ -5348,7 +5351,7 @@ class scalar_scanner { case '7': case '8': case '9': - return (len > 1) ? scan_decimal_number(++itr, --len, false) : node_type::INTEGER; + return (len > 1) ? scan_decimal_number(++itr, --len) : node_type::INTEGER; default: return node_type::STRING; } @@ -5362,7 +5365,12 @@ class scalar_scanner { FK_YAML_ASSERT(len > 0); if (is_digit(*itr)) { - return (len > 1) ? scan_decimal_number(++itr, --len, false) : node_type::INTEGER; + return (len > 1) ? scan_decimal_number(++itr, --len) : node_type::INTEGER; + } + + if (*itr == '.') { + // some integer(s) required after "-." as a floating point value. + return (len > 1) ? scan_after_decimal_point(++itr, --len) : node_type::STRING; } return node_type::STRING; @@ -5382,14 +5390,13 @@ class scalar_scanner { } switch (*itr) { - case '.': { - if (len == 1) { - // 0 is omitted after `0.`. - return node_type::FLOAT; - } - node_type ret = scan_after_decimal_point(++itr, --len, true); - return (ret == node_type::STRING) ? node_type::STRING : node_type::FLOAT; - } + case '.': + // 0 can be omitted after `0.`. + return (len > 1) ? scan_after_decimal_point(++itr, --len) : node_type::FLOAT; + case 'e': + case 'E': + // some integer(s) required after the exponent sign as a floating point value. + return (len > 1) ? scan_after_exponent(++itr, --len) : node_type::STRING; case 'o': return (len > 1) ? scan_octal_number(++itr, --len) : node_type::STRING; case 'x': @@ -5402,31 +5409,23 @@ class scalar_scanner { /// @brief Detects a scalar value type by scanning the contents part starting with a decimal. /// @param itr The iterator to the beginning decimal element of the scalar. /// @param len The length of the scalar left unscanned. - /// @param has_decimal_point Whether a decimal point has already been found in the previous part. /// @return A detected scalar value type. - static node_type scan_decimal_number(const char* itr, uint32_t len, bool has_decimal_point) noexcept { + static node_type scan_decimal_number(const char* itr, uint32_t len) noexcept { FK_YAML_ASSERT(len > 0); if (is_digit(*itr)) { - return (len > 1) ? scan_decimal_number(++itr, --len, has_decimal_point) : node_type::INTEGER; + return (len > 1) ? scan_decimal_number(++itr, --len) : node_type::INTEGER; } switch (*itr) { case '.': { - if (has_decimal_point) { - // the token has more than one period, e.g., a semantic version `1.2.3`. - return node_type::STRING; - } - if (len == 1) { - // 0 is omitted after the decimal point - return node_type::FLOAT; - } - node_type ret = scan_after_decimal_point(++itr, --len, true); - return (ret == node_type::STRING) ? node_type::STRING : node_type::FLOAT; + // 0 can be omitted after the decimal point + return (len > 1) ? scan_after_decimal_point(++itr, --len) : node_type::FLOAT; } case 'e': case 'E': - return (len > 1) ? scan_after_exponent(++itr, --len, has_decimal_point) : node_type::STRING; + // some integer(s) required after the exponent + return (len > 1) ? scan_after_exponent(++itr, --len) : node_type::STRING; default: return node_type::STRING; } @@ -5435,37 +5434,55 @@ class scalar_scanner { /// @brief Detects a scalar value type by scanning the contents right after a decimal point. /// @param itr The iterator to the past-the-decimal-point element of the scalar. /// @param len The length of the scalar left unscanned. - /// @param has_decimal_point Whether the decimal point has already been found in the previous part. /// @return A detected scalar value type. - static node_type scan_after_decimal_point(const char* itr, uint32_t len, bool has_decimal_point) noexcept { + static node_type scan_after_decimal_point(const char* itr, uint32_t len) noexcept { FK_YAML_ASSERT(len > 0); - if (is_digit(*itr)) { - return (len > 1) ? scan_decimal_number(++itr, --len, has_decimal_point) : node_type::FLOAT; + for (uint32_t i = 0; i < len; i++) { + char c = *itr++; + + if (is_digit(c)) { + continue; + } + + if (c == 'e' || c == 'E') { + if (i == len - 1) { + // some integer(s) required after the exponent + return node_type::STRING; + } + return scan_after_exponent(itr, len - i - 1); + } + + return node_type::STRING; } - return node_type::STRING; + return node_type::FLOAT; } /// @brief Detects a scalar value type by scanning the contents right after the exponent prefix ("e" or "E"). /// @param itr The iterator to the past-the-exponent-prefix element of the scalar. /// @param len The length of the scalar left unscanned. - /// @param has_decimal_point Whether the decimal point has already been found in the previous part. /// @return A detected scalar value type. - static node_type scan_after_exponent(const char* itr, uint32_t len, bool has_decimal_point) noexcept { + static node_type scan_after_exponent(const char* itr, uint32_t len) noexcept { FK_YAML_ASSERT(len > 0); - if (is_digit(*itr)) { - return (len > 1) ? scan_decimal_number(++itr, --len, has_decimal_point) : node_type::FLOAT; + char c = *itr; + if (c == '+' || c == '-') { + if (len == 1) { + // some integer(s) required after the sign. + return node_type::STRING; + } + ++itr; + --len; } - switch (*itr) { - case '+': - case '-': - return (len > 1) ? scan_decimal_number(++itr, --len, has_decimal_point) : node_type::STRING; - default: - return node_type::STRING; + for (uint32_t i = 0; i < len; i++) { + if (!is_digit(*itr++)) { + return node_type::STRING; + } } + + return node_type::FLOAT; } /// @brief Detects a scalar value type by scanning the contents assuming octal numbers. diff --git a/test/unit_test/test_scalar_parser_class.cpp b/test/unit_test/test_scalar_parser_class.cpp index 94061c56..4d1d76e9 100644 --- a/test/unit_test/test_scalar_parser_class.cpp +++ b/test/unit_test/test_scalar_parser_class.cpp @@ -135,7 +135,14 @@ TEST_CASE("ScalarParser_FlowPlainScalar_float") { test_data_t("4.5E3", 4.5e3f), test_data_t("+4.5E3", 4.5e3f), test_data_t("-4.5E3", -4.5e3f), - test_data_t("-4.5E-3", -4.5e-3f)); + test_data_t("-4.5E-3", -4.5e-3f), + test_data_t("1e-1", 1e-1f), + test_data_t("2E+2", 2e+2f), + test_data_t("3e3", 3e3f), + test_data_t("1.e3", 1.e3f), + test_data_t(".1e-3", .1e-3f), + test_data_t("-.1e-3", -.1e-3f), + test_data_t("+.1e-3", .1e-3f)); REQUIRE_NOTHROW(node = scalar_parser.parse_flow(lex_type, tag_type, test_data.first)); REQUIRE(node.is_float_number()); diff --git a/test/unit_test/test_scalar_scanner_class.cpp b/test/unit_test/test_scalar_scanner_class.cpp index 6c764083..5e57bc8b 100644 --- a/test/unit_test/test_scalar_scanner_class.cpp +++ b/test/unit_test/test_scalar_scanner_class.cpp @@ -69,10 +69,23 @@ TEST_CASE("ScalarScanner_FloatNumberValue") { fkyaml::detail::str_view("+.INF"), fkyaml::detail::str_view("-1.234"), fkyaml::detail::str_view("-21."), + fkyaml::detail::str_view("-.123"), + fkyaml::detail::str_view("+.123"), + fkyaml::detail::str_view(".123"), fkyaml::detail::str_view("567.8"), fkyaml::detail::str_view("123."), fkyaml::detail::str_view("0.24"), fkyaml::detail::str_view("0."), + fkyaml::detail::str_view("0e1"), + fkyaml::detail::str_view("0E+1"), + fkyaml::detail::str_view("0e-1"), + fkyaml::detail::str_view("1e-1"), + fkyaml::detail::str_view("2e+2"), + fkyaml::detail::str_view("3e3"), + fkyaml::detail::str_view("1.e3"), + fkyaml::detail::str_view(".1e-3"), + fkyaml::detail::str_view("-.1e-3"), + fkyaml::detail::str_view("+.1e-3"), fkyaml::detail::str_view("9.8e-3"), fkyaml::detail::str_view("3.95E3"), fkyaml::detail::str_view("1.863e+3")); @@ -105,9 +118,16 @@ TEST_CASE("ScalarScanner_StringValue") { fkyaml::detail::str_view(".foo"), fkyaml::detail::str_view("abc"), fkyaml::detail::str_view("0th"), + fkyaml::detail::str_view("1st"), + fkyaml::detail::str_view("0e"), + fkyaml::detail::str_view("0e+"), + fkyaml::detail::str_view("0e-"), + fkyaml::detail::str_view("0E"), fkyaml::detail::str_view("0123"), fkyaml::detail::str_view("1.2.3"), fkyaml::detail::str_view("1.23e"), + fkyaml::detail::str_view("1.23eE"), + fkyaml::detail::str_view("1.23E-e"), fkyaml::detail::str_view("1.2e-z"), fkyaml::detail::str_view("1.non-digit"), fkyaml::detail::str_view("-.foo"), From f2c442547dcaccc3313c2858dd5b67387b39706b Mon Sep 17 00:00:00 2001 From: fktn Date: Sat, 26 Oct 2024 18:21:05 +0900 Subject: [PATCH 02/13] Update GA workflow jobs for ubuntu24.04 (#415) * use clang-tidy installed in ubuntu-24.04 runner image * updated clang-format version to 18.1.3 (same as ubuntu-24.04) * updated runner image tags for CI jobs in workflows/ubuntu.yml * updated CONTRIBUTING.md regarding clang-format tool version * fixed undefined reference link error and coverage loss * [bot] run clang-format & amalgamation * fixed coverage loss again --- .clang-format | 103 +- .clang-tidy | 18 +- .github/workflows/coverage.yml | 2 +- .github/workflows/ubuntu.yml | 4 +- CONTRIBUTING.md | 4 +- .../fkYAML/detail/conversions/from_node.hpp | 6 +- .../fkYAML/detail/conversions/scalar_conv.hpp | 73 +- include/fkYAML/detail/conversions/to_node.hpp | 4 +- .../fkYAML/detail/conversions/to_string.hpp | 22 +- include/fkYAML/detail/document_metainfo.hpp | 6 +- .../fkYAML/detail/encodings/uri_encoding.hpp | 8 +- .../detail/encodings/utf_encode_detector.hpp | 74 +- .../fkYAML/detail/encodings/utf_encode_t.hpp | 4 +- .../fkYAML/detail/encodings/utf_encodings.hpp | 147 +-- .../fkYAML/detail/encodings/yaml_escaper.hpp | 24 +- .../detail/input/block_scalar_header.hpp | 2 +- include/fkYAML/detail/input/deserializer.hpp | 112 +- include/fkYAML/detail/input/input_adapter.hpp | 188 +-- .../fkYAML/detail/input/lexical_analyzer.hpp | 98 +- .../fkYAML/detail/input/position_tracker.hpp | 4 +- include/fkYAML/detail/input/scalar_parser.hpp | 44 +- .../fkYAML/detail/input/scalar_scanner.hpp | 60 +- include/fkYAML/detail/input/tag_resolver.hpp | 32 +- include/fkYAML/detail/input/tag_t.hpp | 4 +- include/fkYAML/detail/iterator.hpp | 5 +- include/fkYAML/detail/node_attrs.hpp | 34 +- include/fkYAML/detail/node_property.hpp | 4 +- include/fkYAML/detail/node_ref_storage.hpp | 18 +- include/fkYAML/detail/output/serializer.hpp | 31 +- include/fkYAML/detail/str_view.hpp | 31 +- include/fkYAML/detail/string_formatter.hpp | 7 +- .../fkYAML/detail/types/lexical_token_t.hpp | 4 +- include/fkYAML/detail/types/node_t.hpp | 3 +- .../fkYAML/detail/types/yaml_version_t.hpp | 8 +- include/fkYAML/exception.hpp | 30 +- include/fkYAML/node.hpp | 25 +- include/fkYAML/node_type.hpp | 2 +- include/fkYAML/node_value_converter.hpp | 5 +- include/fkYAML/ordered_map.hpp | 10 +- include/fkYAML/yaml_version_type.hpp | 2 +- scripts/run_clang_format.bat | 2 +- scripts/run_clang_format.sh | 2 +- single_include/fkYAML/node.hpp | 1134 +++++++++-------- test/unit_test/test_input_adapter.cpp | 52 +- tool/clang_tidy/CMakeLists.txt | 5 +- 45 files changed, 1254 insertions(+), 1203 deletions(-) diff --git a/.clang-format b/.clang-format index 228a7913..5a49a16e 100644 --- a/.clang-format +++ b/.clang-format @@ -1,6 +1,5 @@ --- -Language: Cpp -# BasedOnStyle: Microsoft +Language: Cpp AccessModifierOffset: -4 AlignAfterOpenBracket: AlwaysBreak AlignArrayOfStructures: None @@ -9,11 +8,12 @@ AlignConsecutiveBitFields: false AlignConsecutiveDeclarations: false AlignConsecutiveMacros: false AlignEscapedNewlines: Right -AlignOperands: Align +AlignOperands: Align AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: Never +AllowBreakBeforeNoexceptSpecifier: Never AllowShortCaseLabelsOnASingleLine: false AllowShortEnumsOnASingleLine: false AllowShortFunctionsOnASingleLine: None @@ -30,45 +30,43 @@ BinPackArguments: false BinPackParameters: true BitFieldColonSpacing: Both BraceWrapping: - AfterCaseLabel: false - AfterClass: false + AfterCaseLabel: false + AfterClass: false AfterControlStatement: Never - AfterEnum: false + AfterEnum: false AfterExternBlock: false - AfterFunction: false - AfterNamespace: false + AfterFunction: false + AfterNamespace: false AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - BeforeCatch: true - BeforeElse: true + AfterStruct: false + AfterUnion: false + BeforeCatch: true + BeforeElse: true BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false + BeforeWhile: false + IndentBraces: false SplitEmptyFunction: false SplitEmptyRecord: false SplitEmptyNamespace: false -# BreakAfterAttributes: Never # since clang-format 16 +BreakAfterAttributes: Never BreakAfterJavaFieldAnnotations: false -# BreakArrays: true # since clang-format 16 +BreakArrays: true BreakBeforeBinaryOperators: None BreakBeforeConceptDeclarations: true BreakBeforeBraces: Custom -# BreakBeforeInlineASMColon: OnlyMultiline # since clang-format 16 BreakBeforeTernaryOperators: true BreakConstructorInitializers: BeforeColon BreakInheritanceList: BeforeColon BreakStringLiterals: true -ColumnLimit: 120 -CommentPragmas: '^ IWYU pragma:' +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DerivePointerAlignment: false -DeriveLineEnding: true -DisableFormat: false +DisableFormat: false EmptyLineAfterAccessModifier: Never EmptyLineBeforeAccessModifier: LogicalBlock ExperimentalAutoDetectBinPacking: false @@ -79,20 +77,20 @@ ForEachMacros: - BOOST_FOREACH IfMacros: - KJ_IF_MAYBE -IncludeBlocks: Preserve +IncludeBlocks: Preserve IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - SortPriority: 0 - CaseSensitive: false - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - SortPriority: 0 - CaseSensitive: false - - Regex: '.*' - Priority: 1 - SortPriority: 0 - CaseSensitive: false + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false IncludeIsMainRegex: '(Test)?$' IncludeIsMainSourceRegex: '' IndentAccessModifiers: false @@ -101,23 +99,19 @@ IndentCaseLabels: false IndentExternBlock: AfterExternBlock IndentGotoLabels: true IndentPPDirectives: None -# IndentRequiresClause: true # since clang-format 15 -IndentWidth: 4 +IndentRequiresClause: true +IndentWidth: 4 IndentWrappedFunctionNames: false -# InsertBraces: false # since clang-format 15 -# InsertNewlineAtEOF: false # since clang-format 16 +InsertBraces: false +InsertNewlineAtEOF: true InsertTrailingCommas: None -# IntegerLiteralSeparator: # since clang-format 16 -# Binary: 0 -# Decimal: 0 -# Hex: 0 JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: true LambdaBodyIndentation: Signature -# LineEnding: DeriveLF # since clang-format 16 +LineEnding: DeriveLF MacroBlockBegin: '' -MacroBlockEnd: '' +MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCBinPackProtocolList: Auto @@ -137,14 +131,13 @@ PenaltyExcessCharacter: 1000000 PenaltyIndentedWhitespace: 0 PenaltyReturnTypeOnItsOwnLine: 1000 PointerAlignment: Left -PPIndentWidth: -1 +PPIndentWidth: -1 QualifierAlignment: Leave ReferenceAlignment: Pointer ReflowComments: true RemoveBracesLLVM: false -# RemoveSemicolon: false # since clang-format 16 -# RequiresClausePosition: OwnLine # since clang-format 15 -# RequiresExpressionIndentation: OuterScope # since clang-format 16 +RemoveSemicolon: false +RequiresExpressionIndentation: OuterScope SeparateDefinitionBlocks: Leave ShortNamespaceLines: 1 SortIncludes: Never @@ -165,10 +158,8 @@ SpaceBeforeParensOptions: AfterForeachMacros: true AfterFunctionDefinitionName: false AfterFunctionDeclarationName: false - AfterIfMacros: true + AfterIfMacros: true AfterOverloadedOperator: false - # AfterRequiresInClause: false - # AfterRequiresInExpression: false BeforeNonEmptyParentheses: false SpaceBeforeRangeBasedForLoopColon: true SpaceBeforeSquareBrackets: false @@ -180,18 +171,18 @@ SpacesInConditionalStatement: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInLineCommentPrefix: - Minimum: 1 - Maximum: -1 + Minimum: 1 + Maximum: -1 SpacesInParentheses: false SpacesInSquareBrackets: false -Standard: Latest +Standard: Latest StatementAttributeLikeMacros: - Q_EMIT StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION -TabWidth: 4 -UseTab: Never +TabWidth: 4 +UseTab: Never UseCRLF: false WhitespaceSensitiveMacros: - BOOST_PP_STRINGIZE diff --git a/.clang-tidy b/.clang-tidy index 0c5d835a..085b78f2 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -3,28 +3,42 @@ Checks: '*, -altera-id-dependent-backward-branch, -altera-struct-pack-align, -altera-unroll-loops, + -cert-dcl21-cpp, -cppcoreguidelines-avoid-c-arrays, + -cppcoreguidelines-avoid-do-while, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-macro-usage, + -cppcoreguidelines-owning-memory, -cppcoreguidelines-pro-bounds-pointer-arithmetic, -cppcoreguidelines-pro-type-reinterpret-cast, -cppcoreguidelines-pro-type-union-access, + -cppcoreguidelines-pro-type-vararg, -fuchsia-default-arguments-calls, + -fuchsia-default-arguments-declarations, -fuchsia-overloaded-operator, + -google-explicit-constructor, -google-readability-todo, -hicpp-avoid-c-arrays, + -hicpp-explicit-conversions, -hicpp-signed-bitwise, + -hicpp-uppercase-literal-suffix, + -hicpp-vararg, -llvm-header-guard, -llvm-include-order, -llvmlibc-*, -misc-no-recursion, + -misc-non-private-member-variables-in-classes, -modernize-avoid-c-arrays, + -modernize-use-nodiscard, + -modernize-type-traits, -modernize-use-trailing-return-type, -readability-function-cognitive-complexity, -readability-identifier-length, -readability-implicit-bool-conversion, -readability-magic-numbers, - -readability-redundant-access-specifiers' + -readability-redundant-access-specifiers, + -readability-simplify-boolean-expr, + -readability-uppercase-literal-suffix' WarningsAsErrors: '*' HeaderFilterRegex: '' CheckOptions: @@ -39,13 +53,13 @@ CheckOptions: - { key: readability-identifier-naming.ClassMemberCase, value: lower_case } - { key: readability-identifier-naming.ClassMemberPrefix, value: s_ } - { key: readability-identifier-naming.PrivateMemberCase, value: lower_case } - - { key: readability-identifier-naming.PrivateMemberPrefix, value: m_ } - { key: readability-identifier-naming.VariableCase, value: lower_case } - { key: readability-identifier-naming.ParameterCase, value: lower_case } - { key: readability-identifier-naming.ConstantParameterCase, value: lower_case } - { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE } - { key: readability-identifier-naming.LocalConstantCase, value: lower_case } - { key: readability-identifier-naming.ConstantCase, value: UPPER_CASE } + - { key: readability-identifier-naming.ConstexprVariableCase, value: lower_case } - { key: readability-identifier-naming.FunctionCase, value: lower_case } - { key: readability-identifier-naming.TemplateParameter, value: CamelCase } - { key: readability-identifier-naming.Namespace, value: lower_case } diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index c7591428..8054217a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -26,7 +26,7 @@ on: jobs: coverage: timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 permissions: pull-requests: write diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 0702a9d7..903f5972 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -61,7 +61,7 @@ jobs: ci_test_clang_tidy: timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 @@ -73,7 +73,7 @@ jobs: ci_test_iwyu: timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 050817da..0df94cef 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -105,10 +105,10 @@ The commands above will automatically install all the dependencies using [Python ### 4. Format source files -[GitHub Actions](https://github.com/fktn-k/fkYAML/actions) will test the updated project with the [Clang-Format](https://releases.llvm.org/14.0.0/tools/clang/docs/ClangFormat.html) tool (14.0.0) once you open a PR or push commits afterwards which include changes in the source files under either [`include`](https://github.com/fktn-k/fkYAML/tree/develop/include) or [`test`](https://github.com/fktn-k/fkYAML/tree/develop/test) directories. +[GitHub Actions](https://github.com/fktn-k/fkYAML/actions) will test the updated project with the [Clang-Format](https://github.com/llvm/llvm-project/releases/tag/llvmorg-18.1.3) tool (18.1.3) once you open a PR or push commits afterwards which include changes in the source files under either [`include`](https://github.com/fktn-k/fkYAML/tree/develop/include) or [`test`](https://github.com/fktn-k/fkYAML/tree/develop/test) directories. Although code formatting is automatically executed in the GitHub Actions workflows, you can run the script files ([`run_clang_format.bat`](https://github.com/fktn-k/fkYAML/scripts/run_clang_format.bat) for Windows, [`run_clang_format.sh`](https://github.com/fktn-k/fkYAML/scripts/run_clang_format.sh) otherwise) to check if your changes follow the rules defined in the [`.clang-format`](https://github.com/fktn-k/fkYAML/tree/develop/.clang-format) file on your local environment in advance. Note that, since the Clang-Format tool does not gurantee backward compatibility especially in its edge cases and its behaviors might therefore vary from version to version, it's highly recommended that you use the above script files to avoid unnecessary confusion for that kind of reason. -The scripts uses [the Clang-Format Python distribution](https://pypi.org/project/clang-format/14.0.0/) and installs it using [the Python venv module](https://docs.python.org/3/library/venv.html) if it's not been installed yet. +The scripts uses [the Clang-Format Python distribution](https://pypi.org/project/clang-format/18.1.3/) and installs it using [the Python venv module](https://docs.python.org/3/library/venv.html) if it's not been installed yet. You can run the scripts with the following commands: **Windows (Command Prompt)** diff --git a/include/fkYAML/detail/conversions/from_node.hpp b/include/fkYAML/detail/conversions/from_node.hpp index 4ccdc87c..9a9f5484 100644 --- a/include/fkYAML/detail/conversions/from_node.hpp +++ b/include/fkYAML/detail/conversions/from_node.hpp @@ -156,7 +156,7 @@ inline void from_node(const BasicNodeType& n, IntegerType& i) { // under/overflow check. using node_int_type = typename BasicNodeType::integer_type; - node_int_type tmp_int = n.template get_value_ref(); + const node_int_type tmp_int = n.template get_value_ref(); if FK_YAML_UNLIKELY (tmp_int < static_cast(std::numeric_limits::min())) { throw exception("Integer value underflow detected."); } @@ -271,8 +271,8 @@ struct from_node_fn { /// @param val A target object assigned from the basic_node object. /// @return decltype(from_node(n, std::forward(val))) void by default. User can set it to some other type. template - auto operator()(const BasicNodeType& n, T&& val) const noexcept(noexcept(from_node(n, std::forward(val)))) - -> decltype(from_node(n, std::forward(val))) { + auto operator()(const BasicNodeType& n, T&& val) const + noexcept(noexcept(from_node(n, std::forward(val)))) -> decltype(from_node(n, std::forward(val))) { return from_node(n, std::forward(val)); } }; diff --git a/include/fkYAML/detail/conversions/scalar_conv.hpp b/include/fkYAML/detail/conversions/scalar_conv.hpp index 4c40ad9a..7a3599f0 100644 --- a/include/fkYAML/detail/conversions/scalar_conv.hpp +++ b/include/fkYAML/detail/conversions/scalar_conv.hpp @@ -15,6 +15,7 @@ #define FK_YAML_CONVERSIONS_SCALAR_CONV_HPP #include +#include #include #include @@ -351,7 +352,7 @@ inline bool aton(CharItr begin, CharItr end, std::nullptr_t& /*unused*/) noexcep return false; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); // This path is the most probable case, so check it first. if FK_YAML_LIKELY (len == 4) { @@ -386,27 +387,27 @@ inline bool atob(CharItr begin, CharItr end, BoolType& boolean) noexcept { return false; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); const char* p_begin = &*begin; if (len == 4) { - bool is_true_scalar = (std::strncmp(p_begin, "true", 4) == 0) || (std::strncmp(p_begin, "True", 4) == 0) || - (std::strncmp(p_begin, "TRUE", 4) == 0); + const bool is_true = (std::strncmp(p_begin, "true", 4) == 0) || (std::strncmp(p_begin, "True", 4) == 0) || + (std::strncmp(p_begin, "TRUE", 4) == 0); - if FK_YAML_LIKELY (is_true_scalar) { + if FK_YAML_LIKELY (is_true) { boolean = static_cast(true); } - return is_true_scalar; + return is_true; } if (len == 5) { - bool is_false_scalar = (std::strncmp(p_begin, "false", 5) == 0) || (std::strncmp(p_begin, "False", 5) == 0) || - (std::strncmp(p_begin, "FALSE", 5) == 0); + const bool is_false = (std::strncmp(p_begin, "false", 5) == 0) || (std::strncmp(p_begin, "False", 5) == 0) || + (std::strncmp(p_begin, "FALSE", 5) == 0); - if FK_YAML_LIKELY (is_false_scalar) { + if FK_YAML_LIKELY (is_false) { boolean = static_cast(false); } - return is_false_scalar; + return is_false; } return false; @@ -438,7 +439,7 @@ inline bool atoi_dec_unchecked(const char* p_begin, const char* p_end, IntType& i = 0; do { - char c = *p_begin; + const char c = *p_begin; if FK_YAML_UNLIKELY (c < '0' || '9' < c) { return false; } @@ -467,7 +468,7 @@ inline bool atoi_dec_pos(const char* p_begin, const char* p_end, IntType& i) noe using conv_limits_type = conv_limits::value>; - std::size_t len = static_cast(p_end - p_begin); + const auto len = static_cast(p_end - p_begin); if FK_YAML_UNLIKELY (len > conv_limits_type::max_chars_dec) { // Overflow will happen. return false; @@ -510,7 +511,7 @@ inline bool atoi_dec_neg(const char* p_begin, const char* p_end, IntType& i) noe using conv_limits_type = conv_limits::value>; - std::size_t len = static_cast(p_end - p_begin); + const auto len = static_cast(p_end - p_begin); if FK_YAML_UNLIKELY (len > conv_limits_type::max_chars_dec) { // Underflow will happen. return false; @@ -557,14 +558,14 @@ inline bool atoi_oct(const char* p_begin, const char* p_end, IntType& i) noexcep using conv_limits_type = conv_limits::value>; - std::size_t len = static_cast(p_end - p_begin); + const auto len = static_cast(p_end - p_begin); if FK_YAML_UNLIKELY (!conv_limits_type::check_if_octs_safe(p_begin, len)) { return false; } i = 0; do { - char c = *p_begin; + const char c = *p_begin; if FK_YAML_UNLIKELY (c < '0' || '7' < c) { return false; } @@ -596,14 +597,15 @@ inline bool atoi_hex(const char* p_begin, const char* p_end, IntType& i) noexcep using conv_limits_type = conv_limits::value>; - std::size_t len = static_cast(p_end - p_begin); + const auto len = static_cast(p_end - p_begin); if FK_YAML_UNLIKELY (!conv_limits_type::check_if_hexs_safe(p_begin, len)) { return false; } i = 0; do { - char c = *p_begin; + // NOLINTBEGIN(bugprone-misplaced-widening-cast) + const char c = *p_begin; IntType ci = 0; if ('0' <= c && c <= '9') { ci = IntType(c - '0'); @@ -618,6 +620,7 @@ inline bool atoi_hex(const char* p_begin, const char* p_end, IntType& i) noexcep return false; } i = i * IntType(16) + ci; + // NOLINTEND(bugprone-misplaced-widening-cast) } while (++p_begin != p_end); return true; @@ -643,11 +646,11 @@ inline bool atoi(CharItr begin, CharItr end, IntType& i) noexcept { return false; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); const char* p_begin = &*begin; const char* p_end = p_begin + len; - char first = *begin; + const char first = *begin; if (first == '+') { return atoi_dec_pos(p_begin + 1, p_end, i); } @@ -657,7 +660,7 @@ inline bool atoi(CharItr begin, CharItr end, IntType& i) noexcept { return false; } - bool success = atoi_dec_neg(p_begin + 1, p_end, i); + const bool success = atoi_dec_neg(p_begin + 1, p_end, i); if (success) { i *= IntType(-1); } @@ -668,7 +671,8 @@ inline bool atoi(CharItr begin, CharItr end, IntType& i) noexcept { if (first != '0') { return atoi_dec_pos(p_begin, p_end, i); } - else if (p_begin + 1 != p_end) { + + if (p_begin + 1 != p_end) { switch (*(p_begin + 1)) { case 'o': return atoi_oct(p_begin + 2, p_end, i); @@ -775,18 +779,17 @@ inline bool atof(CharItr begin, CharItr end, FloatType& f) noexcept(noexcept(ato return false; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); const char* p_begin = &*begin; const char* p_end = p_begin + len; if (*p_begin == '-' || *p_begin == '+') { if (len == 5) { const char* p_from_second = p_begin + 1; - bool is_inf_scalar = (std::strncmp(p_from_second, ".inf", 4) == 0) || - (std::strncmp(p_from_second, ".Inf", 4) == 0) || - (std::strncmp(p_from_second, ".INF", 4) == 0); - - if (is_inf_scalar) { + const bool is_inf = (std::strncmp(p_from_second, ".inf", 4) == 0) || + (std::strncmp(p_from_second, ".Inf", 4) == 0) || + (std::strncmp(p_from_second, ".INF", 4) == 0); + if (is_inf) { set_infinity(f, *p_begin == '-' ? FloatType(-1.) : FloatType(1.)); return true; } @@ -798,20 +801,16 @@ inline bool atof(CharItr begin, CharItr end, FloatType& f) noexcept(noexcept(ato } } else if (len == 4) { - bool is_inf_scalar = (std::strncmp(p_begin, ".inf", 4) == 0) || (std::strncmp(p_begin, ".Inf", 4) == 0) || - (std::strncmp(p_begin, ".INF", 4) == 0); - bool is_nan_scalar = false; - if (!is_inf_scalar) { - is_nan_scalar = (std::strncmp(p_begin, ".nan", 4) == 0) || (std::strncmp(p_begin, ".NaN", 4) == 0) || - (std::strncmp(p_begin, ".NAN", 4) == 0); - } - - if (is_inf_scalar) { + const bool is_inf = (std::strncmp(p_begin, ".inf", 4) == 0) || (std::strncmp(p_begin, ".Inf", 4) == 0) || + (std::strncmp(p_begin, ".INF", 4) == 0); + if (is_inf) { set_infinity(f, FloatType(1.)); return true; } - if (is_nan_scalar) { + const bool is_nan = (std::strncmp(p_begin, ".nan", 4) == 0) || (std::strncmp(p_begin, ".NaN", 4) == 0) || + (std::strncmp(p_begin, ".NAN", 4) == 0); + if (is_nan) { set_nan(f); return true; } diff --git a/include/fkYAML/detail/conversions/to_node.hpp b/include/fkYAML/detail/conversions/to_node.hpp index 66232d5d..4ce2a708 100644 --- a/include/fkYAML/detail/conversions/to_node.hpp +++ b/include/fkYAML/detail/conversions/to_node.hpp @@ -310,8 +310,8 @@ struct to_node_fn { /// @param val A target object assigned to the basic_node object. /// @return decltype(to_node(n, std::forward(val))) void by default. User can set it to some other type. template - auto operator()(BasicNodeType& n, T&& val) const noexcept(noexcept(to_node(n, std::forward(val)))) - -> decltype(to_node(n, std::forward(val))) { + auto operator()(BasicNodeType& n, T&& val) const + noexcept(noexcept(to_node(n, std::forward(val)))) -> decltype(to_node(n, std::forward(val))) { return to_node(n, std::forward(val)); } }; diff --git a/include/fkYAML/detail/conversions/to_string.hpp b/include/fkYAML/detail/conversions/to_string.hpp index 7032ea3c..3c169913 100644 --- a/include/fkYAML/detail/conversions/to_string.hpp +++ b/include/fkYAML/detail/conversions/to_string.hpp @@ -39,10 +39,10 @@ inline void to_string(std::nullptr_t /*unused*/, std::string& s) noexcept { /// @brief Specialization of to_string() for booleans. /// @param s A resulting string YAML token. -/// @param b A boolean source value. +/// @param v A boolean source value. template <> -inline void to_string(bool b, std::string& s) noexcept { - s = b ? "true" : "false"; +inline void to_string(bool v, std::string& s) noexcept { + s = v ? "true" : "false"; } /// @brief Specialization of to_string() for integers. @@ -50,8 +50,8 @@ inline void to_string(bool b, std::string& s) noexcept { /// @param s A resulting string YAML token. /// @param i An integer source value. template -inline enable_if_t::value> to_string(IntegerType i, std::string& s) noexcept { - s = std::to_string(i); +inline enable_if_t::value> to_string(IntegerType v, std::string& s) noexcept { + s = std::to_string(v); } /// @brief Specialization of to_string() for floating point numbers. @@ -59,14 +59,14 @@ inline enable_if_t::value> to_string(IntegerTy /// @param s A resulting string YAML token. /// @param f A floating point number source value. template -inline enable_if_t::value> to_string(FloatType f, std::string& s) noexcept { - if (std::isnan(f)) { +inline enable_if_t::value> to_string(FloatType v, std::string& s) noexcept { + if (std::isnan(v)) { s = ".nan"; return; } - if (std::isinf(f)) { - if (f == std::numeric_limits::infinity()) { + if (std::isinf(v)) { + if (v == std::numeric_limits::infinity()) { s = ".inf"; } else { @@ -76,12 +76,12 @@ inline enable_if_t::value> to_string(FloatType } std::ostringstream oss; - oss << f; + 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 - FloatType diff = f - std::floor(f); + const FloatType diff = v - std::floor(v); if (diff < std::numeric_limits::min()) { s += ".0"; } diff --git a/include/fkYAML/detail/document_metainfo.hpp b/include/fkYAML/detail/document_metainfo.hpp index 0247df9a..f07c5364 100644 --- a/include/fkYAML/detail/document_metainfo.hpp +++ b/include/fkYAML/detail/document_metainfo.hpp @@ -26,11 +26,11 @@ struct document_metainfo { /// Whether the YAML version has been specified. bool is_version_specified {false}; /// The prefix of the primary handle. - std::string primary_handle_prefix {}; + std::string primary_handle_prefix; /// The prefix of the secondary handle. - std::string secondary_handle_prefix {}; + std::string secondary_handle_prefix; /// The map of handle-prefix pairs. - std::map named_handle_map {}; + std::map named_handle_map; /// The map of anchor node which allows for key duplication. std::multimap anchor_table {}; }; diff --git a/include/fkYAML/detail/encodings/uri_encoding.hpp b/include/fkYAML/detail/encodings/uri_encoding.hpp index 2daeac6a..40159001 100644 --- a/include/fkYAML/detail/encodings/uri_encoding.hpp +++ b/include/fkYAML/detail/encodings/uri_encoding.hpp @@ -32,7 +32,7 @@ class uri_encoding { for (; current != end; ++current) { if (*current == '%') { - bool are_valid_octets = validate_octets(++current, end); + const bool are_valid_octets = validate_octets(++current, end); if (!are_valid_octets) { return false; } @@ -40,7 +40,7 @@ class uri_encoding { continue; } - bool is_allowed_character = validate_character(*current); + const bool is_allowed_character = validate_character(*current); if (!is_allowed_character) { return false; } @@ -61,7 +61,7 @@ class uri_encoding { } // Normalize a character for a-f/A-F comparison - int octet = std::tolower(*begin); + const int octet = std::tolower(*begin); if ('0' <= octet && octet <= '9') { continue; @@ -80,7 +80,7 @@ class uri_encoding { /// @brief Verify if the given character is allowed as a URI character. /// @param c The target character. /// @return true if the given character is allowed as a URI character, false otherwise. - static bool validate_character(char c) { + static bool validate_character(const char c) { // Check if the current character is one of reserved/unreserved characters which are allowed for // use. See the following links for details: // * reserved characters: https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 diff --git a/include/fkYAML/detail/encodings/utf_encode_detector.hpp b/include/fkYAML/detail/encodings/utf_encode_detector.hpp index 25dab63e..08e6780b 100644 --- a/include/fkYAML/detail/encodings/utf_encode_detector.hpp +++ b/include/fkYAML/detail/encodings/utf_encode_detector.hpp @@ -28,53 +28,54 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN inline utf_encode_t detect_encoding_type(const std::array& bytes, bool& has_bom) noexcept { has_bom = false; - uint8_t byte0 = bytes[0]; - uint8_t byte1 = bytes[1]; - uint8_t byte2 = bytes[2]; - uint8_t byte3 = bytes[3]; + const uint8_t byte0 = bytes[0]; + const uint8_t byte1 = bytes[1]; + const uint8_t byte2 = bytes[2]; + const uint8_t byte3 = bytes[3]; // Check if a BOM exists. - if (byte0 == uint8_t(0xEFu) && byte1 == uint8_t(0xBBu) && byte2 == uint8_t(0xBFu)) { + if (byte0 == static_cast(0xEFu) && byte1 == static_cast(0xBBu) && + byte2 == static_cast(0xBFu)) { has_bom = true; return utf_encode_t::UTF_8; } - if (byte0 == 0 && byte1 == 0 && byte2 == uint8_t(0xFEu) && byte3 == uint8_t(0xFFu)) { + if (byte0 == 0 && byte1 == 0 && byte2 == static_cast(0xFEu) && byte3 == static_cast(0xFFu)) { has_bom = true; return utf_encode_t::UTF_32BE; } - if (byte0 == uint8_t(0xFFu) && byte1 == uint8_t(0xFEu) && byte2 == 0 && byte3 == 0) { + if (byte0 == static_cast(0xFFu) && byte1 == static_cast(0xFEu) && byte2 == 0 && byte3 == 0) { has_bom = true; return utf_encode_t::UTF_32LE; } - if (byte0 == uint8_t(0xFEu) && byte1 == uint8_t(0xFFu)) { + if (byte0 == static_cast(0xFEu) && byte1 == static_cast(0xFFu)) { has_bom = true; return utf_encode_t::UTF_16BE; } - if (byte0 == uint8_t(0xFFu) && byte1 == uint8_t(0xFEu)) { + if (byte0 == static_cast(0xFFu) && byte1 == static_cast(0xFEu)) { has_bom = true; return utf_encode_t::UTF_16LE; } // Test the first character assuming it's an ASCII character. - if (byte0 == 0 && byte1 == 0 && byte2 == 0 && 0 < byte3 && byte3 < uint8_t(0x80u)) { + if (byte0 == 0 && byte1 == 0 && byte2 == 0 && 0 < byte3 && byte3 < static_cast(0x80u)) { return utf_encode_t::UTF_32BE; } - if (0 < byte0 && byte0 < uint8_t(0x80u) && byte1 == 0 && byte2 == 0 && byte3 == 0) { + if (0 < byte0 && byte0 < static_cast(0x80u) && byte1 == 0 && byte2 == 0 && byte3 == 0) { return utf_encode_t::UTF_32LE; } - if (byte0 == 0 && 0 < byte1 && byte1 < uint8_t(0x80u)) { + if (byte0 == 0 && 0 < byte1 && byte1 < static_cast(0x80u)) { return utf_encode_t::UTF_16BE; } - if (0 < byte0 && byte0 < uint8_t(0x80u) && byte1 == 0) { + if (0 < byte0 && byte0 < static_cast(0x80u) && byte1 == 0) { return utf_encode_t::UTF_16LE; } @@ -102,11 +103,11 @@ struct utf_encode_detector::v std::array bytes {}; bytes.fill(0xFFu); for (int i = 0; i < 4 && begin + i != end; i++) { - bytes[i] = uint8_t(begin[i]); + bytes[i] = uint8_t(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); if (has_bom) { // skip reading the BOM. @@ -147,11 +148,11 @@ struct utf_encode_detector std::array bytes {}; bytes.fill(0xFFu); for (int i = 0; i < 4 && begin + i != end; i++) { - bytes[i] = uint8_t(begin[i]); + bytes[i] = uint8_t(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); if FK_YAML_UNLIKELY (encode_type != utf_encode_t::UTF_8) { throw exception("char8_t characters must be encoded in the UTF-8 format."); @@ -184,13 +185,16 @@ struct utf_encode_detector bytes {}; bytes.fill(0xFFu); for (int i = 0; i < 2 && begin + i != end; i++) { - char16_t elem = begin[i]; - bytes[i * 2] = uint8_t((elem & 0xFF00u) >> 8); - bytes[i * 2 + 1] = uint8_t(elem & 0xFFu); + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-constant-array-index) + const char16_t elem = begin[i]; + const int idx_base = i * 2; + bytes[idx_base] = static_cast((elem & 0xFF00u) >> 8); + bytes[idx_base + 1] = static_cast(elem & 0xFFu); + // NOLINTEND(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); if FK_YAML_UNLIKELY (encode_type != utf_encode_t::UTF_16BE && encode_type != utf_encode_t::UTF_16LE) { throw exception("char16_t characters must be encoded in the UTF-16 format."); @@ -219,14 +223,14 @@ struct utf_encode_detector bytes {}; - char32_t elem = *begin; - bytes[0] = uint8_t((elem & 0xFF000000u) >> 24); - bytes[1] = uint8_t((elem & 0x00FF0000u) >> 16); - bytes[2] = uint8_t((elem & 0x0000FF00u) >> 8); - bytes[3] = uint8_t(elem & 0x000000FFu); + const char32_t elem = *begin; + bytes[0] = static_cast((elem & 0xFF000000u) >> 24); + bytes[1] = static_cast((elem & 0x00FF0000u) >> 16); + bytes[2] = static_cast((elem & 0x0000FF00u) >> 8); + bytes[3] = static_cast(elem & 0x000000FFu); bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); if FK_YAML_UNLIKELY (encode_type != utf_encode_t::UTF_32BE && encode_type != utf_encode_t::UTF_32LE) { throw exception("char32_t characters must be encoded in the UTF-32 format."); @@ -251,18 +255,18 @@ struct file_utf_encode_detector { bytes.fill(0xFFu); for (int i = 0; i < 4; i++) { char byte = 0; - std::size_t size = std::fread(&byte, sizeof(char), 1, p_file); + const std::size_t size = std::fread(&byte, sizeof(char), 1, p_file); if (size != sizeof(char)) { break; } - bytes[i] = uint8_t(byte & 0xFF); + bytes[i] = static_cast(byte & 0xFF); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); // move back to the beginning if a BOM doesn't exist. - long offset = 0; + long offset = 0; // NOLINT(google-runtime-int) if (has_bom) { switch (encode_type) { case utf_encode_t::UTF_8: @@ -278,7 +282,7 @@ struct file_utf_encode_detector { break; } } - std::fseek(p_file, offset, SEEK_SET); + std::fseek(p_file, offset, SEEK_SET); // NOLINT(cert-err33-c) return encode_type; } @@ -295,17 +299,17 @@ struct stream_utf_encode_detector { for (int i = 0; i < 4; i++) { char ch = 0; is.read(&ch, 1); - std::streamsize size = is.gcount(); + const std::streamsize size = is.gcount(); if (size != 1) { // without this, seekg() will fail. is.clear(); break; } - bytes[i] = uint8_t(ch & 0xFF); + bytes[i] = static_cast(ch & 0xFF); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); // move back to the beginning if a BOM doesn't exist. std::streamoff offset = 0; diff --git a/include/fkYAML/detail/encodings/utf_encode_t.hpp b/include/fkYAML/detail/encodings/utf_encode_t.hpp index a860ac6c..88f4c207 100644 --- a/include/fkYAML/detail/encodings/utf_encode_t.hpp +++ b/include/fkYAML/detail/encodings/utf_encode_t.hpp @@ -9,13 +9,15 @@ #ifndef FK_YAML_DETAIL_ENCODINGS_UTF_ENCODE_T_HPP #define FK_YAML_DETAIL_ENCODINGS_UTF_ENCODE_T_HPP +#include + #include FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of Unicode encoding types /// @note Since fkYAML doesn't treat UTF-16/UTF-32 encoded characters per byte, endians do not matter. -enum class utf_encode_t { +enum class utf_encode_t : std::uint8_t { UTF_8, //!< UTF-8 UTF_16BE, //!< UTF-16 Big Endian UTF_16LE, //!< UTF-16 Little Endian diff --git a/include/fkYAML/detail/encodings/utf_encodings.hpp b/include/fkYAML/detail/encodings/utf_encodings.hpp index d56273d6..7855d548 100644 --- a/include/fkYAML/detail/encodings/utf_encodings.hpp +++ b/include/fkYAML/detail/encodings/utf_encodings.hpp @@ -33,15 +33,15 @@ inline uint32_t get_num_bytes(uint8_t first_byte) { return 1; } // The first byte starts with 0b110X'XXXX -> 2-byte character - else if ((first_byte & 0xE0) == 0xC0) { + if ((first_byte & 0xE0) == 0xC0) { return 2; } // The first byte starts with 0b1110'XXXX -> 3-byte character - else if ((first_byte & 0xF0) == 0xE0) { + if ((first_byte & 0xF0) == 0xE0) { return 3; } // The first byte starts with 0b1111'0XXX -> 4-byte character - else if ((first_byte & 0xF8) == 0xF0) { + if ((first_byte & 0xF8) == 0xF0) { return 4; } @@ -56,17 +56,17 @@ inline bool validate(const std::initializer_list& byte_array) noexcept switch (byte_array.size()) { case 1: // U+0000..U+007F - return uint8_t(*(byte_array.begin())) <= uint8_t(0x7Fu); + return *byte_array.begin() <= 0x7Fu; case 2: { - auto itr = byte_array.begin(); - uint8_t first = *itr++; - uint8_t second = *itr; + const auto* itr = byte_array.begin(); + const uint8_t first = *itr++; + const uint8_t second = *itr; // U+0080..U+07FF // 1st Byte: 0xC2..0xDF // 2nd Byte: 0x80..0xBF - if (uint8_t(0xC2u) <= first && first <= uint8_t(0xDFu)) { - if (0x80 <= second && second <= 0xBF) { + if (0xC2u <= first && first <= 0xDFu) { + if (0x80u <= second && second <= 0xBFu) { return true; } } @@ -75,18 +75,18 @@ inline bool validate(const std::initializer_list& byte_array) noexcept return false; } case 3: { - auto itr = byte_array.begin(); - uint8_t first = *itr++; - uint8_t second = *itr++; - uint8_t third = *itr; + const auto* itr = byte_array.begin(); + const uint8_t first = *itr++; + const uint8_t second = *itr++; + const uint8_t third = *itr; // U+1000..U+CFFF: // 1st Byte: 0xE0..0xEC // 2nd Byte: 0x80..0xBF // 3rd Byte: 0x80..0xBF - if (0xE0 <= first && first <= 0xEC) { - if (0x80 <= second && second <= 0xBF) { - if (0x80 <= third && third <= 0xBF) { + if (0xE0u <= first && first <= 0xECu) { + if (0x80u <= second && second <= 0xBFu) { + if (0x80u <= third && third <= 0xBFu) { return true; } } @@ -97,9 +97,9 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // 1st Byte: 0xED // 2nd Byte: 0x80..0x9F // 3rd Byte: 0x80..0xBF - if (first == 0xED) { - if (0x80 <= second && second <= 0x9F) { - if (0x80 <= third && third <= 0xBF) { + if (first == 0xEDu) { + if (0x80u <= second && second <= 0x9Fu) { + if (0x80u <= third && third <= 0xBFu) { return true; } } @@ -110,9 +110,9 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // 1st Byte: 0xEE..0xEF // 2nd Byte: 0x80..0xBF // 3rd Byte: 0x80..0xBF - if (first == 0xEE || first == 0xEF) { - if (0x80 <= second && second <= 0xBF) { - if (0x80 <= third && third <= 0xBF) { + if (first == 0xEEu || first == 0xEFu) { + if (0x80u <= second && second <= 0xBFu) { + if (0x80u <= third && third <= 0xBFu) { return true; } } @@ -123,21 +123,21 @@ inline bool validate(const std::initializer_list& byte_array) noexcept return false; } case 4: { - auto itr = byte_array.begin(); - uint8_t first = *itr++; - uint8_t second = *itr++; - uint8_t third = *itr++; - uint8_t fourth = *itr; + const auto* itr = byte_array.begin(); + const uint8_t first = *itr++; + const uint8_t second = *itr++; + const uint8_t third = *itr++; + const uint8_t fourth = *itr; // U+10000..U+3FFFF: // 1st Byte: 0xF0 // 2nd Byte: 0x90..0xBF // 3rd Byte: 0x80..0xBF // 4th Byte: 0x80..0xBF - if (first == 0xF0) { - if (0x90 <= second && second <= 0xBF) { - if (0x80 <= third && third <= 0xBF) { - if (0x80 <= fourth && fourth <= 0xBF) { + if (first == 0xF0u) { + if (0x90u <= second && second <= 0xBFu) { + if (0x80u <= third && third <= 0xBFu) { + if (0x80u <= fourth && fourth <= 0xBFu) { return true; } } @@ -150,10 +150,10 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // 2nd Byte: 0x80..0xBF // 3rd Byte: 0x80..0xBF // 4th Byte: 0x80..0xBF - if (0xF1 <= first && first <= 0xF3) { - if (0x80 <= second && second <= 0xBF) { - if (0x80 <= third && third <= 0xBF) { - if (0x80 <= fourth && fourth <= 0xBF) { + if (0xF1u <= first && first <= 0xF3u) { + if (0x80u <= second && second <= 0xBFu) { + if (0x80u <= third && third <= 0xBFu) { + if (0x80u <= fourth && fourth <= 0xBFu) { return true; } } @@ -166,10 +166,10 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // 2nd Byte: 0x80..0x8F // 3rd Byte: 0x80..0xBF // 4th Byte: 0x80..0xBF - if (first == 0xF4) { - if (0x80 <= second && second <= 0x8F) { - if (0x80 <= third && third <= 0xBF) { - if (0x80 <= fourth && fourth <= 0xBF) { + if (first == 0xF4u) { + if (0x80u <= second && second <= 0x8Fu) { + if (0x80u <= third && third <= 0xBFu) { + if (0x80u <= fourth && fourth <= 0xBFu) { return true; } } @@ -190,51 +190,45 @@ inline bool validate(const std::initializer_list& byte_array) noexcept /// @param[out] utf8 UTF-8 encoded bytes. /// @param[out] consumed_size The number of UTF-16 encoded characters used for the conversion. /// @param[out] encoded_size The size of UTF-encoded bytes. -inline void from_utf16( +inline void from_utf16( // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) std::array utf16, std::array& utf8, uint32_t& consumed_size, uint32_t& encoded_size) { - if (utf16[0] < char16_t(0x80u)) { + if (utf16[0] < 0x80u) { utf8[0] = static_cast(utf16[0] & 0x7Fu); consumed_size = 1; encoded_size = 1; - return; } - else if (utf16[0] <= char16_t(0x7FFu)) { - uint16_t utf8_chunk = static_cast(0xC080u) | static_cast((utf16[0] & 0x07C0u) << 2) | - static_cast(utf16[0] & 0x003Fu); + else if (utf16[0] <= 0x7FFu) { + const auto utf8_chunk = static_cast(0xC080u | ((utf16[0] & 0x07C0u) << 2) | (utf16[0] & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF00u) >> 8); utf8[1] = static_cast(utf8_chunk & 0x00FFu); consumed_size = 1; encoded_size = 2; - return; } - else if (utf16[0] < char16_t(0xD800u) || char16_t(0xE000u) <= utf16[0]) { - uint32_t utf8_chunk = static_cast(0xE08080u) | static_cast((utf16[0] & 0xF000u) << 4) | - static_cast((utf16[0] & 0x0FC0u) << 2) | - static_cast(utf16[0] & 0x003Fu); + else if (utf16[0] < 0xD800u || 0xE000u <= utf16[0]) { + const auto utf8_chunk = static_cast( + 0xE08080u | ((utf16[0] & 0xF000u) << 4) | ((utf16[0] & 0x0FC0u) << 2) | (utf16[0] & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF0000u) >> 16); utf8[1] = static_cast((utf8_chunk & 0x00FF00u) >> 8); utf8[2] = static_cast(utf8_chunk & 0x0000FFu); consumed_size = 1; encoded_size = 3; - return; } - else if (utf16[0] <= char16_t(0xDBFFu) && char16_t(0xDC00u) <= utf16[1] && utf16[1] <= char16_t(0xDFFFu)) { - // for surrogate pairs - uint32_t code_point = 0x10000u + ((utf16[0] & 0x03FFu) << 10) + (utf16[1] & 0x03FFu); - uint32_t utf8_chunk = - static_cast(0xF0808080u) | static_cast((code_point & 0x1C0000u) << 6) | - static_cast((code_point & 0x03F000u) << 4) | - static_cast((code_point & 0x000FC0u) << 2) | static_cast(code_point & 0x00003Fu); + else if (utf16[0] <= 0xDBFFu && 0xDC00u <= utf16[1] && utf16[1] <= 0xDFFFu) { + // surrogate pair + const uint32_t code_point = 0x10000u + ((utf16[0] & 0x03FFu) << 10) + (utf16[1] & 0x03FFu); + const auto utf8_chunk = static_cast( + 0xF0808080u | ((code_point & 0x1C0000u) << 6) | ((code_point & 0x03F000u) << 4) | + ((code_point & 0x0FC0u) << 2) | (code_point & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF000000u) >> 24); utf8[1] = static_cast((utf8_chunk & 0x00FF0000u) >> 16); utf8[2] = static_cast((utf8_chunk & 0x0000FF00u) >> 8); utf8[3] = static_cast(utf8_chunk & 0x000000FFu); consumed_size = 2; encoded_size = 4; - return; } - - throw invalid_encoding("Invalid UTF-16 encoding detected.", utf16); + else { + throw invalid_encoding("Invalid UTF-16 encoding detected.", utf16); + } } /// @brief Converts a UTF-32 encoded character to UTF-8 encoded bytes. @@ -242,42 +236,37 @@ inline void from_utf16( /// @param[out] utf8 UTF-8 encoded bytes. /// @param[in] encoded_size The size of UTF-encoded bytes. inline void from_utf32(const char32_t utf32, std::array& utf8, uint32_t& encoded_size) { - if (utf32 < char32_t(0x80u)) { + if (utf32 < 0x80u) { utf8[0] = static_cast(utf32 & 0x007F); encoded_size = 1; - return; } - else if (utf32 <= char32_t(0x7FFu)) { - uint16_t utf8_chunk = static_cast(0xC080u) | static_cast((utf32 & 0x07C0u) << 2) | - static_cast(utf32 & 0x003Fu); + else if (utf32 <= 0x7FFu) { + const auto utf8_chunk = static_cast(0xC080u | ((utf32 & 0x07C0u) << 2) | (utf32 & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF00u) >> 8); utf8[1] = static_cast(utf8_chunk & 0x00FFu); encoded_size = 2; - return; } - else if (utf32 <= char32_t(0xFFFFu)) { - uint32_t utf8_chunk = static_cast(0xE08080u) | static_cast((utf32 & 0xF000u) << 4) | - static_cast((utf32 & 0x0FC0u) << 2) | static_cast(utf32 & 0x003F); + else if (utf32 <= 0xFFFFu) { + const auto utf8_chunk = + static_cast(0xE08080u | ((utf32 & 0xF000u) << 4) | ((utf32 & 0x0FC0u) << 2) | (utf32 & 0x3F)); utf8[0] = static_cast((utf8_chunk & 0xFF0000u) >> 16); utf8[1] = static_cast((utf8_chunk & 0x00FF00u) >> 8); utf8[2] = static_cast(utf8_chunk & 0x0000FFu); encoded_size = 3; - return; } - else if (utf32 <= char32_t(0x10FFFFu)) { - uint32_t utf8_chunk = static_cast(0xF0808080u) | static_cast((utf32 & 0x1C0000u) << 6) | - static_cast((utf32 & 0x03F000u) << 4) | - static_cast((utf32 & 0x000FC0u) << 2) | - static_cast(utf32 & 0x00003Fu); + else if (utf32 <= 0x10FFFFu) { + const auto utf8_chunk = static_cast( + 0xF0808080u | ((utf32 & 0x1C0000u) << 6) | ((utf32 & 0x03F000u) << 4) | ((utf32 & 0x0FC0u) << 2) | + (utf32 & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF000000u) >> 24); utf8[1] = static_cast((utf8_chunk & 0x00FF0000u) >> 16); utf8[2] = static_cast((utf8_chunk & 0x0000FF00u) >> 8); utf8[3] = static_cast(utf8_chunk & 0x000000FFu); encoded_size = 4; - return; } - - throw invalid_encoding("Invalid UTF-32 encoding detected.", utf32); + else { + throw invalid_encoding("Invalid UTF-32 encoding detected.", utf32); + } } } // namespace utf8 diff --git a/include/fkYAML/detail/encodings/yaml_escaper.hpp b/include/fkYAML/detail/encodings/yaml_escaper.hpp index ba9b621f..20f6ab46 100644 --- a/include/fkYAML/detail/encodings/yaml_escaper.hpp +++ b/include/fkYAML/detail/encodings/yaml_escaper.hpp @@ -34,7 +34,7 @@ class yaml_escaper { buff.push_back('\b'); break; case 't': - case char(0x09): + case '\t': buff.push_back('\t'); break; case 'n': @@ -50,7 +50,7 @@ class yaml_escaper { buff.push_back('\r'); break; case 'e': - buff.push_back(char(0x1B)); + buff.push_back(static_cast(0x1B)); break; case ' ': buff.push_back(' '); @@ -247,15 +247,15 @@ class yaml_escaper { is_escaped = true; break; default: - int diff = static_cast(std::distance(begin, end)); + const std::ptrdiff_t diff = static_cast(std::distance(begin, end)); if (diff > 1) { - if (*begin == char(0xC2u) && *(begin + 1) == char(0x85u)) { + if (*begin == static_cast(0xC2u) && *(begin + 1) == static_cast(0x85u)) { escaped += "\\N"; std::advance(begin, 1); is_escaped = true; break; } - else if (*begin == char(0xC2u) && *(begin + 1) == char(0xA0u)) { + if (*begin == static_cast(0xC2u) && *(begin + 1) == static_cast(0xA0u)) { escaped += "\\_"; std::advance(begin, 1); is_escaped = true; @@ -263,13 +263,15 @@ class yaml_escaper { } if (diff > 2) { - if (*begin == char(0xE2u) && *(begin + 1) == char(0x80u) && *(begin + 2) == char(0xA8u)) { + if (*begin == static_cast(0xE2u) && *(begin + 1) == static_cast(0x80u) && + *(begin + 2) == static_cast(0xA8u)) { escaped += "\\L"; std::advance(begin, 2); is_escaped = true; break; } - if (*begin == char(0xE2u) && *(begin + 1) == char(0x80u) && *(begin + 2) == char(0xA9u)) { + if (*begin == static_cast(0xE2u) && *(begin + 1) == static_cast(0x80u) && + *(begin + 2) == static_cast(0xA9u)) { escaped += "\\P"; std::advance(begin, 2); is_escaped = true; @@ -288,7 +290,7 @@ class yaml_escaper { static bool convert_hexchar_to_byte(char source, uint8_t& byte) { if ('0' <= source && source <= '9') { // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) - byte = static_cast(source - char('0')); + byte = static_cast(source - '0'); return true; } @@ -309,17 +311,17 @@ class yaml_escaper { } static bool extract_codepoint(const char*& begin, const char* end, int bytes_to_read, char32_t& codepoint) { - bool has_enough_room = static_cast(std::distance(begin, end)) >= (bytes_to_read - 1); + const bool has_enough_room = static_cast(std::distance(begin, end)) >= (bytes_to_read - 1); if (!has_enough_room) { return false; } - int read_size = bytes_to_read * 2; + const int read_size = bytes_to_read * 2; uint8_t byte {0}; codepoint = 0; for (int i = read_size - 1; i >= 0; i--) { - bool is_valid = convert_hexchar_to_byte(*++begin, byte); + const bool is_valid = convert_hexchar_to_byte(*++begin, byte); if (!is_valid) { return false; } diff --git a/include/fkYAML/detail/input/block_scalar_header.hpp b/include/fkYAML/detail/input/block_scalar_header.hpp index f9704440..f336a33c 100644 --- a/include/fkYAML/detail/input/block_scalar_header.hpp +++ b/include/fkYAML/detail/input/block_scalar_header.hpp @@ -16,7 +16,7 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of chomping indicator types. -enum class chomping_indicator_t { +enum class chomping_indicator_t : std::uint8_t { STRIP, //!< excludes final line breaks and trailing empty lines indicated by `-`. CLIP, //!< preserves final line breaks but excludes trailing empty lines. no indicator means this type. KEEP, //!< preserves final line breaks and trailing empty lines indicated by `+`. diff --git a/include/fkYAML/detail/input/deserializer.hpp b/include/fkYAML/detail/input/deserializer.hpp index e327b5ea..408642a7 100644 --- a/include/fkYAML/detail/input/deserializer.hpp +++ b/include/fkYAML/detail/input/deserializer.hpp @@ -50,7 +50,7 @@ class basic_deserializer { using mapping_type = typename basic_node_type::mapping_type; /// @brief Definition of state types of parse contexts. - enum class context_state_t { + enum class context_state_t : std::uint8_t { BLOCK_MAPPING, //!< The underlying node is a block mapping. BLOCK_MAPPING_EXPLICIT_KEY, //!< The underlying node is an explicit block mapping key. BLOCK_MAPPING_EXPLICIT_VALUE, //!< The underlying node is an explicit block mapping value. @@ -68,17 +68,23 @@ class basic_deserializer { parse_context() = default; /// @brief Construct a new parse_context object with non-default values for each parameter. - /// @param _line The current line. (count from zero) - /// @param _indent The indentation width in the current line. (count from zero) - /// @param _state The parse context type. - /// @param _p_node The underlying node associated to this context. - parse_context(uint32_t _line, uint32_t _indent, context_state_t _state, basic_node_type* _p_node) - : line(_line), - indent(_indent), - state(_state), - p_node(_p_node) { + /// @param line The current line. (count from zero) + /// @param indent The indentation width in the current line. (count from zero) + /// @param state The parse context type. + /// @param p_node The underlying node associated to this context. + // // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + parse_context(uint32_t line, uint32_t indent, context_state_t state, basic_node_type* p_node) noexcept + : line(line), + indent(indent), + state(state), + p_node(p_node) { } + parse_context(const parse_context&) noexcept = default; + parse_context& operator=(const parse_context&) noexcept = default; + parse_context(parse_context&&) noexcept = default; + parse_context& operator=(parse_context&&) noexcept = default; + ~parse_context() { switch (state) { case context_state_t::BLOCK_MAPPING_EXPLICIT_KEY: @@ -103,7 +109,7 @@ class basic_deserializer { }; /// @brief Definitions of state types for expected flow token hints. - enum class flow_token_state_t { + enum class flow_token_state_t : std::uint8_t { NEEDS_VALUE_OR_SUFFIX, //!< Either value or flow suffix (`]` or `}`) NEEDS_SEPARATOR_OR_SUFFIX, //!< Either separator (`,`) or flow suffix (`]` or `}`) }; @@ -122,8 +128,8 @@ class basic_deserializer { /// @param input_adapter An input adapter object for the input source buffer. /// @return basic_node_type A root YAML node deserialized from the source string. template ::value, int> = 0> - basic_node_type deserialize(InputAdapterType&& input_adapter) { - str_view input_view = input_adapter.get_buffer_view(); + basic_node_type deserialize(InputAdapterType&& input_adapter) { // NOLINT(cppcoreguidelines-missing-std-forward) + const str_view input_view = input_adapter.get_buffer_view(); lexer_type lexer(input_view); lexical_token_t type {lexical_token_t::END_OF_BUFFER}; @@ -135,8 +141,9 @@ class basic_deserializer { /// @param input_adapter An input adapter object for the input source buffer. /// @return std::vector Root YAML nodes for deserialized YAML documents. template ::value, int> = 0> + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) std::vector deserialize_docs(InputAdapterType&& input_adapter) { - str_view input_view = input_adapter.get_buffer_view(); + const str_view input_view = input_adapter.get_buffer_view(); lexer_type lexer(input_view); std::vector nodes {}; @@ -166,7 +173,7 @@ class basic_deserializer { // parse node properties for root node if any uint32_t line = lexer.get_lines_processed(); uint32_t indent = lexer.get_last_token_begin_pos(); - bool found_props = deserialize_node_properties(lexer, token, line, indent); + const bool found_props = deserialize_node_properties(lexer, token, line, indent); switch (token.type) { case lexical_token_t::SEQUENCE_BLOCK_PREFIX: { @@ -275,7 +282,7 @@ class basic_deserializer { lexer.set_document_state(true); for (;;) { - lexical_token token = lexer.get_next_token(); + const lexical_token token = lexer.get_next_token(); switch (token.type) { case lexical_token_t::YAML_VER_DIRECTIVE: @@ -291,39 +298,39 @@ class basic_deserializer { lacks_end_of_directives_marker = true; break; case lexical_token_t::TAG_DIRECTIVE: { - str_view tag_handle_view = lexer.get_tag_handle(); + const str_view tag_handle_view = lexer.get_tag_handle(); switch (tag_handle_view.size()) { case 1 /* ! */: { - bool is_already_specified = !mp_meta->primary_handle_prefix.empty(); + const bool is_already_specified = !mp_meta->primary_handle_prefix.empty(); if FK_YAML_UNLIKELY (is_already_specified) { throw parse_error( "Primary handle cannot be specified more than once.", lexer.get_lines_processed(), lexer.get_last_token_begin_pos()); } - str_view tag_prefix = lexer.get_tag_prefix(); + const str_view tag_prefix = lexer.get_tag_prefix(); mp_meta->primary_handle_prefix.assign(tag_prefix.begin(), tag_prefix.end()); lacks_end_of_directives_marker = true; break; } case 2 /* !! */: { - bool is_already_specified = !mp_meta->secondary_handle_prefix.empty(); + const bool is_already_specified = !mp_meta->secondary_handle_prefix.empty(); if FK_YAML_UNLIKELY (is_already_specified) { throw parse_error( "Secondary handle cannot be specified more than once.", lexer.get_lines_processed(), lexer.get_last_token_begin_pos()); } - str_view tag_prefix = lexer.get_tag_prefix(); + const str_view tag_prefix = lexer.get_tag_prefix(); mp_meta->secondary_handle_prefix.assign(tag_prefix.begin(), tag_prefix.end()); lacks_end_of_directives_marker = true; break; } default /* !! */: { std::string tag_handle(tag_handle_view.begin(), tag_handle_view.end()); - str_view tag_prefix_view = lexer.get_tag_prefix(); + const str_view tag_prefix_view = lexer.get_tag_prefix(); std::string tag_prefix(tag_prefix_view.begin(), tag_prefix_view.end()); - bool is_already_specified = + const bool is_already_specified = !(mp_meta->named_handle_map.emplace(std::move(tag_handle), std::move(tag_prefix)).second); if FK_YAML_UNLIKELY (is_already_specified) { throw parse_error( @@ -375,7 +382,7 @@ class basic_deserializer { pop_num = static_cast(m_context_stack.size() - 1); } else { - bool needs_to_move_back = indent < m_context_stack.back().indent; + const bool needs_to_move_back = indent < m_context_stack.back().indent; if (needs_to_move_back) { auto target_itr = std::find_if( // LCOV_EXCL_LINE m_context_stack.rbegin(), @@ -405,7 +412,7 @@ class basic_deserializer { } if (m_context_stack.back().state == context_state_t::BLOCK_SEQUENCE) { - sequence_type& seq = mp_current_node->template get_value_ref(); + auto& seq = mp_current_node->template get_value_ref(); seq.emplace_back(basic_node_type::mapping()); m_context_stack.emplace_back(line, indent, context_state_t::BLOCK_MAPPING, &(seq.back())); } @@ -413,7 +420,7 @@ class basic_deserializer { token = lexer.get_next_token(); if (token.type == lexical_token_t::SEQUENCE_BLOCK_PREFIX) { // heap-allocated node will be freed in handling the corresponding KEY_SEPARATOR event - basic_node_type* p_node = new basic_node_type(node_type::SEQUENCE); + auto* p_node = new basic_node_type(node_type::SEQUENCE); m_context_stack.emplace_back(line, indent, context_state_t::BLOCK_MAPPING_EXPLICIT_KEY, p_node); mp_current_node = m_context_stack.back().p_node; apply_directive_set(*mp_current_node); @@ -437,20 +444,20 @@ class basic_deserializer { continue; } case lexical_token_t::KEY_SEPARATOR: { - bool is_empty_seq = mp_current_node->is_sequence() && mp_current_node->empty(); + const bool is_empty_seq = mp_current_node->is_sequence() && mp_current_node->empty(); if FK_YAML_UNLIKELY (is_empty_seq) { throw parse_error("sequence key should not be empty.", line, indent); } // hold the line count of the key separator for later use. - uint32_t old_indent = indent; - uint32_t old_line = line; + const uint32_t old_indent = indent; + const uint32_t old_line = line; token = lexer.get_next_token(); line = lexer.get_lines_processed(); indent = lexer.get_last_token_begin_pos(); - bool found_props = deserialize_node_properties(lexer, token, line, indent); + const bool found_props = deserialize_node_properties(lexer, token, line, indent); if (found_props && line == lexer.get_lines_processed()) { // defer applying node properties for the subsequent node on the same line. continue; @@ -463,7 +470,7 @@ class basic_deserializer { continue; } - bool is_implicit_same_line = + const bool is_implicit_same_line = (line == old_line) && (m_context_stack.empty() || old_indent > m_context_stack.back().indent); if (is_implicit_same_line) { // a key separator for an implicit key with its value on the same line. @@ -472,7 +479,7 @@ class basic_deserializer { if (line > old_line) { if (m_needs_tag_impl) { - tag_t tag_type = tag_resolver_type::resolve_tag(m_tag_name, mp_meta); + const tag_t tag_type = tag_resolver_type::resolve_tag(m_tag_name, mp_meta); if (tag_type == tag_t::MAPPING || tag_type == tag_t::CUSTOM_TAG) { // set YAML node properties here to distinguish them from those for the first key node // as shown in the following snippet: @@ -505,9 +512,9 @@ class basic_deserializer { line = lexer.get_lines_processed(); indent = lexer.get_last_token_begin_pos(); - bool has_props = deserialize_node_properties(lexer, token, line, indent); + const bool has_props = deserialize_node_properties(lexer, token, line, indent); if (has_props) { - uint32_t line_after_props = lexer.get_lines_processed(); + const uint32_t line_after_props = lexer.get_lines_processed(); if (line == line_after_props) { // Skip updating the current indent to avoid stacking a wrong indentation. // @@ -579,7 +586,7 @@ class basic_deserializer { // ``` continue; case lexical_token_t::SEQUENCE_BLOCK_PREFIX: { - bool is_further_nested = m_context_stack.back().indent < indent; + const bool is_further_nested = m_context_stack.back().indent < indent; if (is_further_nested) { mp_current_node->template get_value_ref().emplace_back(basic_node_type::sequence()); mp_current_node = &(mp_current_node->template get_value_ref().back()); @@ -622,7 +629,7 @@ class basic_deserializer { return false; } }); - bool is_indent_valid = (target_itr != m_context_stack.rend()); + const bool is_indent_valid = (target_itr != m_context_stack.rend()); if FK_YAML_UNLIKELY (!is_indent_valid) { throw parse_error("Detected invalid indentation.", line, indent); } @@ -695,7 +702,7 @@ class basic_deserializer { } }); - bool is_valid = itr != m_context_stack.rend(); + const bool is_valid = itr != m_context_stack.rend(); if FK_YAML_UNLIKELY (!is_valid) { throw parse_error("No corresponding flow sequence beginning is found.", line, indent); } @@ -705,7 +712,7 @@ class basic_deserializer { mp_current_node = last_context.p_node; last_context.p_node = nullptr; indent = last_context.indent; - context_state_t state = last_context.state; + const context_state_t state = last_context.state; m_context_stack.pop_back(); // handle cases where the flow sequence is a mapping key node. @@ -769,7 +776,7 @@ class basic_deserializer { return false; } }); - bool is_indent_valid = (target_itr != m_context_stack.rend()); + const bool is_indent_valid = (target_itr != m_context_stack.rend()); if FK_YAML_UNLIKELY (!is_indent_valid) { throw parse_error("Detected invalid indentation.", line, indent); } @@ -845,7 +852,7 @@ class basic_deserializer { } }); - bool is_valid = itr != m_context_stack.rend(); + const bool is_valid = itr != m_context_stack.rend(); if FK_YAML_UNLIKELY (!is_valid) { throw parse_error("No corresponding flow mapping beginning is found.", line, indent); } @@ -855,7 +862,7 @@ class basic_deserializer { mp_current_node = last_context.p_node; last_context.p_node = nullptr; indent = last_context.indent; - context_state_t state = last_context.state; + const context_state_t state = last_context.state; m_context_stack.pop_back(); // handle cases where the flow mapping is a mapping key node. @@ -906,9 +913,9 @@ class basic_deserializer { throw parse_error("Tag cannot be specified to an alias node", line, indent); } - const std::string token_str = std::string(token.str.begin(), token.str.end()); + std::string token_str = std::string(token.str.begin(), token.str.end()); - uint32_t anchor_counts = static_cast(mp_meta->anchor_table.count(token_str)); + const auto anchor_counts = static_cast(mp_meta->anchor_table.count(token_str)); if FK_YAML_UNLIKELY (anchor_counts == 0) { throw parse_error("The given anchor name must appear prior to the alias node.", line, indent); } @@ -921,7 +928,7 @@ class basic_deserializer { apply_directive_set(node); apply_node_properties(node); - bool should_continue = deserialize_scalar(lexer, std::move(node), indent, line, token); + const bool should_continue = deserialize_scalar(lexer, std::move(node), indent, line, token); if (should_continue) { continue; } @@ -939,7 +946,7 @@ class basic_deserializer { apply_directive_set(node); apply_node_properties(node); - bool do_continue = deserialize_scalar(lexer, std::move(node), indent, line, token); + const bool do_continue = deserialize_scalar(lexer, std::move(node), indent, line, token); if (do_continue) { continue; } @@ -988,6 +995,7 @@ class basic_deserializer { /// @param line The variable to store the line of either the first property or the last non-property token. /// @param indent The variable to store the indent of either the first property or the last non-property token. /// @return true if any property is found, false otherwise. + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) bool deserialize_node_properties(lexer_type& lexer, lexical_token& last_token, uint32_t& line, uint32_t& indent) { m_needs_anchor_impl = m_needs_tag_impl = false; @@ -1043,7 +1051,7 @@ class basic_deserializer { } while (!ends_loop); last_token = token; - bool prop_specified = m_needs_anchor_impl || m_needs_tag_impl; + const bool prop_specified = m_needs_anchor_impl || m_needs_tag_impl; if (!prop_specified) { line = lexer.get_lines_processed(); indent = lexer.get_last_token_begin_pos(); @@ -1068,7 +1076,7 @@ class basic_deserializer { // the target node is a block mapping key node with the same indentation. return (indent == c.indent) && (c.state == context_state_t::BLOCK_MAPPING); }); - bool is_indent_valid = (target_itr != m_context_stack.rend()); + const bool is_indent_valid = (target_itr != m_context_stack.rend()); if FK_YAML_UNLIKELY (!is_indent_valid) { throw parse_error("Detected invalid indentation.", line, indent); } @@ -1099,7 +1107,7 @@ class basic_deserializer { } mp_current_node = &(itr.first->second); - parse_context& key_context = m_context_stack.back(); + const parse_context& key_context = m_context_stack.back(); m_context_stack.emplace_back( key_context.line, key_context.indent, context_state_t::MAPPING_VALUE, mp_current_node); } @@ -1265,13 +1273,13 @@ class basic_deserializer { /// A flag to determine the need for a value separator or a flow suffix to follow. flow_token_state_t m_flow_token_state {flow_token_state_t::NEEDS_VALUE_OR_SUFFIX}; /// The last YAML anchor name. - std::string m_anchor_name {}; + std::string m_anchor_name; /// The last tag name. - std::string m_tag_name {}; + std::string m_tag_name; /// The root YAML anchor name. (maybe empty and unused) - std::string m_root_anchor_name {}; + std::string m_root_anchor_name; /// The root tag name. (maybe empty and unused) - std::string m_root_tag_name {}; + std::string m_root_tag_name; }; FK_YAML_DETAIL_NAMESPACE_END diff --git a/include/fkYAML/detail/input/input_adapter.hpp b/include/fkYAML/detail/input/input_adapter.hpp index 675fd094..b55933ba 100644 --- a/include/fkYAML/detail/input/input_adapter.hpp +++ b/include/fkYAML/detail/input/input_adapter.hpp @@ -89,30 +89,30 @@ class iterator_input_adapter(*current++); + const uint32_t num_bytes = utf8::get_num_bytes(first); switch (num_bytes) { case 2: { - std::initializer_list bytes {first, uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, uint8_t(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 3: { - std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 4: { - std::initializer_list bytes { + const std::initializer_list bytes { first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } @@ -125,7 +125,8 @@ class iterator_input_adapter(uint8_t(*current++) << shift_bits[0]); + auto utf16 = static_cast(uint8_t(*current++) << shift_bits[0]); utf16 |= static_cast(uint8_t(*current++) << shift_bits[1]); // skip appending CRs. if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) encoded_buffer[encoded_buf_size++] = utf16; } } @@ -221,7 +223,7 @@ class iterator_input_adapter(*current++ << shift_bits[0]); + auto utf32 = static_cast(*current++ << shift_bits[0]); utf32 |= static_cast(*current++ << shift_bits[1]); utf32 |= static_cast(*current++ << shift_bits[2]); utf32 |= static_cast(*current++ << shift_bits[3]); @@ -243,7 +245,7 @@ class iterator_input_adapter(*current++); - uint32_t num_bytes = utf8::get_num_bytes(first); + const auto first = static_cast(*current++); + const uint32_t num_bytes = utf8::get_num_bytes(first); switch (num_bytes) { case 2: { - std::initializer_list bytes {first, uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, uint8_t(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 3: { - std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 4: { - std::initializer_list bytes { + const std::initializer_list bytes { first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } @@ -324,7 +326,7 @@ class iterator_input_adapter(*current++); if FK_YAML_LIKELY (c != '\r') { m_buffer.push_back(c); } @@ -341,7 +343,7 @@ class iterator_input_adapter encoded_buffer {{0, 0}}; uint32_t encoded_buf_size {0}; @@ -394,11 +396,10 @@ class iterator_input_adapter((utf16 & 0x00FFu) << shift_bits) | - static_cast((utf16 & 0xFF00u) >> shift_bits)); + utf16 = static_cast(((utf16 & 0x00FFu) << shift_bits) | ((utf16 & 0xFF00u) >> shift_bits)); if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) encoded_buffer[encoded_buf_size++] = utf16; } } @@ -426,7 +427,7 @@ class iterator_input_adapter((tmp & 0xFF000000u) >> shift_bits[0]) | - static_cast((tmp & 0x00FF0000u) >> shift_bits[1]) | - static_cast((tmp & 0x0000FF00u) << shift_bits[2]) | - static_cast((tmp & 0x000000FFu) << shift_bits[3])); - - if FK_YAML_UNLIKELY (utf32 != char32_t(0x0000000Du)) { + const char32_t tmp = *current++; + const auto utf32 = static_cast( + ((tmp & 0xFF000000u) >> shift_bits[0]) | ((tmp & 0x00FF0000u) >> shift_bits[1]) | + ((tmp & 0x0000FF00u) << shift_bits[2]) | ((tmp & 0x000000FFu) << shift_bits[3])); + + if FK_YAML_UNLIKELY (utf32 != static_cast(0x0000000Du)) { utf8::from_utf32(utf32, utf8_buffer, utf8_buf_size); m_buffer.append(reinterpret_cast(utf8_buffer.data()), utf8_buf_size); } @@ -503,7 +502,7 @@ class iterator_input_adapter 0) { char* p_current = &tmp_buf[0]; @@ -579,30 +578,34 @@ class file_input_adapter { auto current = m_buffer.begin(); auto end = m_buffer.end(); while (current != end) { - uint8_t first = static_cast(*current++); - uint32_t num_bytes = utf8::get_num_bytes(first); + const auto first = static_cast(*current++); + const uint32_t num_bytes = utf8::get_num_bytes(first); switch (num_bytes) { case 2: { - std::initializer_list bytes {first, uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 3: { - std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes { + first, static_cast(*current++), static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 4: { - std::initializer_list bytes { - first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes { + first, + static_cast(*current++), + static_cast(*current++), + static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } @@ -638,10 +641,11 @@ class file_input_adapter { while (std::feof(m_file) == 0) { while (encoded_buf_size < 2 && std::fread(&chars[0], sizeof(char), 2, m_file) == 2) { - char16_t utf16 = char16_t( - static_cast(uint8_t(chars[0]) << shift_bits[0]) | - static_cast(uint8_t(chars[1]) << shift_bits[1])); - if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { + const auto utf16 = static_cast( + (static_cast(chars[0]) << shift_bits[0]) | + (static_cast(chars[1]) << shift_bits[1])); + if FK_YAML_LIKELY (utf16 != static_cast(0x000Du)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) encoded_buffer[encoded_buf_size++] = utf16; } } @@ -682,16 +686,14 @@ class file_input_adapter { uint32_t utf8_buf_size {0}; while (std::feof(m_file) == 0) { - std::size_t size = std::fread(&chars[0], sizeof(char), 4, m_file); + const std::size_t size = std::fread(&chars[0], sizeof(char), 4, m_file); if (size != 4) { break; } - char32_t utf32 = char32_t( - static_cast(uint8_t(chars[0]) << shift_bits[0]) | - static_cast(uint8_t(chars[1]) << shift_bits[1]) | - static_cast(uint8_t(chars[2]) << shift_bits[2]) | - static_cast(uint8_t(chars[3]) << shift_bits[3])); + const auto utf32 = static_cast( + (static_cast(chars[0]) << shift_bits[0]) | (static_cast(chars[1]) << shift_bits[1]) | + (static_cast(chars[2]) << shift_bits[2]) | (static_cast(chars[3]) << shift_bits[3])); if FK_YAML_LIKELY (utf32 != char32_t(0x0000000Du)) { utf8::from_utf32(utf32, utf8_buffer, utf8_buf_size); @@ -708,7 +710,7 @@ class file_input_adapter { /// The encoding type for this input adapter. utf_encode_t m_encode_type {utf_encode_t::UTF_8}; /// The normalized owned buffer. - std::string m_buffer {}; + std::string m_buffer; }; /// @brief An input adapter for streams @@ -758,7 +760,7 @@ class stream_input_adapter { char tmp_buf[256] {}; do { m_istream->read(&tmp_buf[0], 256); - std::size_t read_size = static_cast(m_istream->gcount()); + const auto read_size = static_cast(m_istream->gcount()); char* p_current = &tmp_buf[0]; char* p_end = p_current + read_size; @@ -780,30 +782,34 @@ class stream_input_adapter { auto current = m_buffer.begin(); auto end = m_buffer.end(); while (current != end) { - uint8_t first = static_cast(*current++); - uint32_t num_bytes = utf8::get_num_bytes(first); + const auto first = static_cast(*current++); + const uint32_t num_bytes = utf8::get_num_bytes(first); switch (num_bytes) { case 2: { - std::initializer_list bytes {first, uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 3: { - std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes { + first, static_cast(*current++), static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 4: { - std::initializer_list bytes { - first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes { + first, + static_cast(*current++), + static_cast(*current++), + static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } @@ -840,16 +846,17 @@ class stream_input_adapter { do { while (encoded_buf_size < 2) { m_istream->read(&chars[0], 2); - std::streamsize size = m_istream->gcount(); + const std::streamsize size = m_istream->gcount(); if (size != 2) { break; } - char16_t utf16 = char16_t( - static_cast(uint8_t(chars[0]) << shift_bits[0]) | - static_cast(uint8_t(chars[1]) << shift_bits[1])); + const auto utf16 = static_cast( + (static_cast(chars[0]) << shift_bits[0]) | + (static_cast(chars[1]) << shift_bits[1])); - if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { + if FK_YAML_LIKELY (utf16 != static_cast(0x000Du)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) encoded_buffer[encoded_buf_size++] = utf16; } } @@ -891,16 +898,14 @@ class stream_input_adapter { do { m_istream->read(&chars[0], 4); - std::streamsize size = m_istream->gcount(); + const std::streamsize size = m_istream->gcount(); if (size != 4) { break; } - char32_t utf32 = char32_t( - static_cast(uint8_t(chars[0]) << shift_bits[0]) | - static_cast(uint8_t(chars[1]) << shift_bits[1]) | - static_cast(uint8_t(chars[2]) << shift_bits[2]) | - static_cast(uint8_t(chars[3]) << shift_bits[3])); + const auto utf32 = static_cast( + (static_cast(chars[0]) << shift_bits[0]) | (static_cast(chars[1]) << shift_bits[1]) | + (static_cast(chars[2]) << shift_bits[2]) | (static_cast(chars[3]) << shift_bits[3])); if FK_YAML_LIKELY (utf32 != char32_t(0x0000000Du)) { utf8::from_utf32(utf32, utf8_buffer, utf8_buf_size); @@ -917,24 +922,25 @@ class stream_input_adapter { /// The encoding type for this input adapter. utf_encode_t m_encode_type {utf_encode_t::UTF_8}; /// The normalized owned buffer. - std::string m_buffer {}; + std::string m_buffer; }; ///////////////////////////////// // input_adapter providers // ///////////////////////////////// -namespace { - +/// @brief A concrete factory method for iterator_input_adapter objects with iterators. +/// @tparam ItrType An iterator type. +/// @param begin The beginning of iterators. +/// @param end The end of iterators. +/// @param is_contiguous Whether iterators refer to a contiguous byte array. +/// @return An iterator_input_adapter object for the target iterator type. template -inline iterator_input_adapter create_iterator_input_adapter( - ItrType begin, ItrType end, bool is_contiguous) noexcept { - utf_encode_t encode_type = utf_encode_detector::detect(begin, end); +inline iterator_input_adapter create_iterator_input_adapter(ItrType begin, ItrType end, bool is_contiguous) { + const utf_encode_t encode_type = utf_encode_detector::detect(begin, end); return iterator_input_adapter(begin, end, encode_type, is_contiguous); } -} // anonymous namespace - /// @brief A factory method for iterator_input_adapter objects with iterator values. /// @tparam ItrType An iterator type. /// @param begin The beginning of iterators. @@ -949,7 +955,7 @@ inline iterator_input_adapter input_adapter(ItrType begin, ItrType end) // Getting distance between begin and (end - 1) avoids dereferencing an invalid sentinel. bool is_contiguous = false; if (is_random_access_itr) { - ptrdiff_t size = static_cast(std::distance(begin, end - 1)); + const auto size = static_cast(std::distance(begin, end - 1)); using CharPtr = remove_cvref_t::pointer>; CharPtr p_begin = &*begin; @@ -1008,7 +1014,7 @@ struct container_input_adapter_factory< /// @return input_adapter_factory::container_input_adapter_factory::adapter_type template inline typename input_adapter_factory::container_input_adapter_factory::adapter_type input_adapter( - ContainerType&& container) { + const ContainerType& container) { return input_adapter_factory::container_input_adapter_factory::create(container); } @@ -1019,7 +1025,8 @@ inline file_input_adapter input_adapter(std::FILE* file) { if FK_YAML_UNLIKELY (!file) { throw fkyaml::exception("Invalid FILE object pointer."); } - utf_encode_t encode_type = file_utf_encode_detector::detect(file); + + const utf_encode_t encode_type = file_utf_encode_detector::detect(file); return file_input_adapter(file, encode_type); } @@ -1030,7 +1037,8 @@ inline stream_input_adapter input_adapter(std::istream& stream) { if FK_YAML_UNLIKELY (!stream.good()) { throw fkyaml::exception("Invalid stream."); } - utf_encode_t encode_type = stream_utf_encode_detector::detect(stream); + + const utf_encode_t encode_type = stream_utf_encode_detector::detect(stream); return stream_input_adapter(stream, encode_type); } diff --git a/include/fkYAML/detail/input/lexical_analyzer.hpp b/include/fkYAML/detail/input/lexical_analyzer.hpp index 2b80e942..127b6170 100644 --- a/include/fkYAML/detail/input/lexical_analyzer.hpp +++ b/include/fkYAML/detail/input/lexical_analyzer.hpp @@ -31,20 +31,16 @@ struct lexical_token { /// Lexical token type. lexical_token_t type {lexical_token_t::END_OF_BUFFER}; /// Lexical token contents. - str_view str {}; + str_view str; }; -namespace { - -// whether the current context is flow(1) or block(0) -const uint32_t flow_context_bit = 1u << 0u; -// whether the current document part is directive(1) or content(0) -const uint32_t document_directive_bit = 1u << 1u; - -} // anonymous namespace - /// @brief A class which lexically analyzes YAML formatted inputs. class lexical_analyzer { + // whether the current context is flow(1) or block(0) + static constexpr uint32_t flow_context_bit = 1u << 0u; + // whether the current document part is directive(1) or content(0) + static constexpr uint32_t document_directive_bit = 1u << 1u; + public: /// @brief Construct a new lexical_analyzer object. /// @param input_buffer An input buffer. @@ -118,7 +114,7 @@ class lexical_analyzer { return token; case '&': { // anchor prefix extract_anchor_name(token); - bool is_empty = token.str.empty(); + const bool is_empty = token.str.empty(); if FK_YAML_UNLIKELY (is_empty) { emit_error("anchor name must not be empty."); } @@ -128,7 +124,7 @@ class lexical_analyzer { } case '*': { // alias prefix extract_anchor_name(token); - bool is_empty = token.str.empty(); + const bool is_empty = token.str.empty(); if FK_YAML_UNLIKELY (is_empty) { emit_error("anchor name must not be empty."); } @@ -152,7 +148,7 @@ class lexical_analyzer { // See https://yaml.org/spec/1.2.2/#912-document-markers for more details. break; case '-': { - char next = *(m_cur_itr + 1); + const char next = *(m_cur_itr + 1); switch (next) { case ' ': case '\t': @@ -165,9 +161,9 @@ class lexical_analyzer { break; } - bool is_available = ((m_end_itr - m_cur_itr) > 2); + const bool is_available = ((m_end_itr - m_cur_itr) > 2); if (is_available) { - bool is_dir_end = std::equal(m_token_begin_itr, m_cur_itr + 3, "---"); + const bool is_dir_end = std::equal(m_token_begin_itr, m_cur_itr + 3, "---"); if (is_dir_end) { m_cur_itr += 3; token.type = lexical_token_t::END_OF_DIRECTIVES; @@ -210,9 +206,9 @@ class lexical_analyzer { check_scalar_content(token.str); return token; case '.': { - bool is_available = ((m_end_itr - m_cur_itr) > 2); + const bool is_available = ((m_end_itr - m_cur_itr) > 2); if (is_available) { - bool is_doc_end = std::equal(m_cur_itr, m_cur_itr + 3, "..."); + const bool is_doc_end = std::equal(m_cur_itr, m_cur_itr + 3, "..."); if (is_doc_end) { m_cur_itr += 3; token.type = lexical_token_t::END_OF_DOCUMENT; @@ -223,14 +219,14 @@ class lexical_analyzer { } case '|': case '>': { - str_view sv {m_token_begin_itr, m_end_itr}; - std::size_t header_end_pos = sv.find('\n'); + const str_view sv {m_token_begin_itr, m_end_itr}; + const std::size_t header_end_pos = sv.find('\n'); FK_YAML_ASSERT(!sv.empty()); token.type = (sv[0] == '|') ? lexical_token_t::BLOCK_LITERAL_SCALAR : lexical_token_t::BLOCK_FOLDED_SCALAR; FK_YAML_ASSERT(header_end_pos != str_view::npos); - str_view header_line = sv.substr(1, header_end_pos - 1); + 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); @@ -333,7 +329,7 @@ class lexical_analyzer { } } - str_view dir_name(m_token_begin_itr, m_cur_itr); + const str_view dir_name(m_token_begin_itr, m_cur_itr); if (dir_name == "TAG") { if FK_YAML_UNLIKELY (!ends_loop) { @@ -397,7 +393,7 @@ class lexical_analyzer { ends_loop = true; break; } - char next = *(m_cur_itr + 1); + const char next = *(m_cur_itr + 1); if FK_YAML_UNLIKELY (next != ' ' && next != '\t') { emit_error("invalid tag handle is found."); } @@ -441,6 +437,8 @@ class lexical_analyzer { case '{': case '}': emit_error("tag prefix must not start with flow indicators (\',\', [], {})."); + default: + break; } // extract the rest of a tag prefix. @@ -452,10 +450,12 @@ class lexical_analyzer { case '\n': ends_loop = true; break; + default: + break; } } while (!ends_loop && ++m_cur_itr != m_end_itr); - bool is_valid = uri_encoding::validate(p_tag_prefix_begin, m_cur_itr); + const bool is_valid = uri_encoding::validate(p_tag_prefix_begin, m_cur_itr); if FK_YAML_UNLIKELY (!is_valid) { emit_error("invalid URI character is found in a tag prefix."); } @@ -593,18 +593,18 @@ class lexical_analyzer { token.str = str_view {m_token_begin_itr, m_cur_itr}; if (is_verbatim) { - char last = token.str.back(); + const char last = token.str.back(); if FK_YAML_UNLIKELY (last != '>') { emit_error("verbatim tag (!) must be ended with \'>\'."); } // only the `TAG` part of the `!` for URI validation. - str_view tag_body = token.str.substr(2, token.str.size() - 3); + const str_view tag_body = token.str.substr(2, token.str.size() - 3); if FK_YAML_UNLIKELY (tag_body.empty()) { emit_error("verbatim tag(!) must not be empty."); } - bool is_valid_uri = uri_encoding::validate(tag_body.begin(), tag_body.end()); + const bool is_valid_uri = uri_encoding::validate(tag_body.begin(), tag_body.end()); if FK_YAML_UNLIKELY (!is_valid_uri) { emit_error("invalid URI character is found in a verbatim tag."); } @@ -613,7 +613,7 @@ class lexical_analyzer { } if (is_named_handle) { - char last = token.str.back(); + const char last = token.str.back(); if FK_YAML_UNLIKELY (last == '!') { // Tag shorthand must be followed by a non-empty suffix. // See the "Tag Shorthands" section in https://yaml.org/spec/1.2.2/#691-node-tags. @@ -623,18 +623,18 @@ class lexical_analyzer { // get the position of last tag prefix character (!) to extract body of tag shorthands. // tag shorthand is either primary(!tag), secondary(!!tag) or named(!handle!tag). - std::size_t last_tag_prefix_pos = token.str.find_last_of('!'); + const std::size_t last_tag_prefix_pos = token.str.find_last_of('!'); FK_YAML_ASSERT(last_tag_prefix_pos != str_view::npos); - str_view tag_uri = token.str.substr(last_tag_prefix_pos + 1); - bool is_valid_uri = uri_encoding::validate(tag_uri.begin(), tag_uri.end()); + const str_view tag_uri = token.str.substr(last_tag_prefix_pos + 1); + const bool is_valid_uri = uri_encoding::validate(tag_uri.begin(), tag_uri.end()); if FK_YAML_UNLIKELY (!is_valid_uri) { emit_error("Invalid URI character is found in a named tag handle."); } // Tag shorthands cannot contain flow indicators({}[],). // See the "Tag Shorthands" section in https://yaml.org/spec/1.2.2/#691-node-tags. - std::size_t invalid_char_pos = tag_uri.find_first_of("{}[],"); + const std::size_t invalid_char_pos = tag_uri.find_first_of("{}[],"); if (invalid_char_pos != str_view::npos) { emit_error("Tag shorthand cannot contain flow indicators({}[],)."); } @@ -643,7 +643,7 @@ class lexical_analyzer { /// @brief Determines the range of single quoted scalar by scanning remaining input buffer contents. /// @param token Storage for the range of single quoted scalar. void determine_single_quoted_scalar_range(str_view& token) { - str_view sv {m_token_begin_itr, m_end_itr}; + const str_view sv {m_token_begin_itr, m_end_itr}; std::size_t pos = sv.find('\''); while (pos != str_view::npos) { @@ -668,7 +668,7 @@ class lexical_analyzer { /// @brief Determines the range of double quoted scalar by scanning remaining input buffer contents. /// @param token Storage for the range of double quoted scalar. void determine_double_quoted_scalar_range(str_view& token) { - str_view sv {m_token_begin_itr, m_end_itr}; + const str_view sv {m_token_begin_itr, m_end_itr}; std::size_t pos = sv.find('\"'); while (pos != str_view::npos) { @@ -709,7 +709,7 @@ class lexical_analyzer { /// @brief Determines the range of plain scalar by scanning remaining input buffer contents. /// @param token Storage for the range of plain scalar. void determine_plain_scalar_range(str_view& token) { - str_view sv {m_token_begin_itr, m_end_itr}; + const str_view sv {m_token_begin_itr, m_end_itr}; constexpr str_view filter = "\n :{}[],"; std::size_t pos = sv.find_first_of(filter); @@ -800,11 +800,11 @@ class lexical_analyzer { /// @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) { - str_view sv {m_token_begin_itr, m_end_itr}; + const str_view sv {m_token_begin_itr, m_end_itr}; // Handle leading all-space lines. constexpr str_view space_filter = " \t\n"; - std::size_t first_non_space_pos = sv.find_first_not_of(space_filter); + 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()); @@ -820,19 +820,17 @@ class lexical_analyzer { 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. - uint32_t cur_indent = static_cast(first_non_space_pos); + 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."); } - - last_newline_pos = 0; } else { FK_YAML_ASSERT(last_newline_pos < first_non_space_pos); - uint32_t cur_indent = static_cast(first_non_space_pos - last_newline_pos - 1); + 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) { @@ -854,14 +852,14 @@ class lexical_analyzer { cur_line_end_pos = sv.size(); } - std::size_t cur_line_content_begin_pos = sv.find_first_not_of(' ', last_newline_pos + 1); + const std::size_t cur_line_content_begin_pos = sv.find_first_not_of(' ', last_newline_pos + 1); if (cur_line_content_begin_pos == str_view::npos) { last_newline_pos = cur_line_end_pos; continue; } FK_YAML_ASSERT(last_newline_pos < cur_line_content_begin_pos); - uint32_t cur_indent = static_cast(cur_line_content_begin_pos - last_newline_pos - 1); + 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') { // Interpret less indented non-space characters as the start of the next token. break; @@ -947,6 +945,8 @@ class lexical_analyzer { emit_error("Control character U+001E (RS) must be escaped to \\u001E."); case 0x1F: emit_error("Control character U+001F (US) must be escaped to \\u001F."); + default: + break; } } @@ -964,9 +964,9 @@ class lexical_analyzer { /// @param chomp_type A variable to store the retrieved chomping style type. /// @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) { + block_scalar_header convert_to_block_scalar_header(str_view line) { constexpr str_view comment_prefix = " #"; - std::size_t comment_begin_pos = line.find(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); } @@ -1004,7 +1004,7 @@ class lexical_analyzer { if FK_YAML_UNLIKELY (header.indent > 0) { emit_error("Invalid indentation level for a block scalar. It must be between 1 and 9."); } - header.indent = static_cast(c - '0'); + header.indent = static_cast(c - '0'); break; case ' ': case '\t': @@ -1061,7 +1061,7 @@ class lexical_analyzer { private: /// An input buffer adapter to be analyzed. - str_view m_input_buffer {}; + str_view m_input_buffer; /// The iterator to the current character in the input buffer. const char* m_cur_itr {}; /// The iterator to the beginning of the current token. @@ -1071,11 +1071,11 @@ class lexical_analyzer { /// The current position tracker of the input buffer. mutable position_tracker m_pos_tracker {}; /// The last yaml version. - str_view m_yaml_version {}; + str_view m_yaml_version; /// The last tag handle. - str_view m_tag_handle {}; + str_view m_tag_handle; /// The last tag prefix. - str_view m_tag_prefix {}; + str_view m_tag_prefix; /// The last block scalar header. block_scalar_header m_block_scalar_header {}; /// The beginning position of the last lexical token. (zero origin) diff --git a/include/fkYAML/detail/input/position_tracker.hpp b/include/fkYAML/detail/input/position_tracker.hpp index 11fcbb07..bca52e0d 100644 --- a/include/fkYAML/detail/input/position_tracker.hpp +++ b/include/fkYAML/detail/input/position_tracker.hpp @@ -28,13 +28,13 @@ class position_tracker { /// @note This function doesn't support cases where cur_pos has moved backward from the last call. /// @param cur_pos The iterator to the current element of the buffer. void update_position(const char* p_current) { - uint32_t diff = static_cast(p_current - m_last); + const auto diff = static_cast(p_current - m_last); if (diff == 0) { return; } m_cur_pos += diff; - uint32_t prev_lines_read = m_lines_read; + const uint32_t prev_lines_read = m_lines_read; m_lines_read += static_cast(std::count(m_last, p_current, '\n')); m_last = p_current; diff --git a/include/fkYAML/detail/input/scalar_parser.hpp b/include/fkYAML/detail/input/scalar_parser.hpp index 99d7c01c..b3bf4f1d 100644 --- a/include/fkYAML/detail/input/scalar_parser.hpp +++ b/include/fkYAML/detail/input/scalar_parser.hpp @@ -47,7 +47,7 @@ class scalar_parser { /// @brief Constructs a new scalar_parser object. /// @param line Current line. /// @param indent Current indentation. - scalar_parser(uint32_t line, uint32_t indent) noexcept + scalar_parser(uint32_t line, uint32_t indent) noexcept // NOLINT(bugprone-easily-swappable-parameters) : m_line(line), m_indent(indent) { } @@ -74,7 +74,7 @@ class scalar_parser { FK_YAML_ASSERT(tag_type != tag_t::SEQUENCE && tag_type != tag_t::MAPPING); token = parse_flow_scalar_token(lex_type, token); - node_type value_type = decide_value_type(lex_type, tag_type, token); + const node_type value_type = decide_value_type(lex_type, tag_type, token); return create_scalar_node(value_type, token); } @@ -97,7 +97,7 @@ class scalar_parser { token = parse_block_folded_scalar(token, header); } - node_type value_type = decide_value_type(lex_type, tag_type, token); + const node_type value_type = decide_value_type(lex_type, tag_type, token); return create_scalar_node(value_type, token); } @@ -197,7 +197,7 @@ class scalar_parser { if (token[pos + 1] != '\n') { token.remove_prefix(pos); const char* p_escape_begin = token.begin(); - bool is_valid_escaping = yaml_escaper::unescape(p_escape_begin, token.end(), m_buffer); + const bool is_valid_escaping = yaml_escaper::unescape(p_escape_begin, token.end(), m_buffer); if FK_YAML_UNLIKELY (!is_valid_escaping) { throw parse_error( "Unsupported escape sequence is found in a double quoted scalar.", m_line, m_indent); @@ -249,8 +249,8 @@ class scalar_parser { cur_line_end_pos = token.size(); } - std::size_t line_size = cur_line_end_pos - cur_line_begin_pos; - str_view line = token.substr(cur_line_begin_pos, line_size); + 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); if (line.size() > header.indent) { m_buffer.append(line.begin() + header.indent, line.end()); @@ -291,8 +291,8 @@ class scalar_parser { cur_line_end_pos = token.size(); } - std::size_t line_size = cur_line_end_pos - cur_line_begin_pos; - str_view line = token.substr(cur_line_begin_pos, line_size); + 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); if (line.size() <= header.indent) { // empty or less-indented lines are turned into a newline @@ -300,8 +300,8 @@ class scalar_parser { can_be_folded = false; } else { - std::size_t non_space_pos = line.find_first_not_of(' '); - bool is_more_indented = (non_space_pos != str_view::npos) && (non_space_pos > header.indent); + const std::size_t non_space_pos = line.find_first_not_of(' '); + const bool is_more_indented = (non_space_pos != str_view::npos) && (non_space_pos > header.indent); if (can_be_folded) { if (is_more_indented) { @@ -348,7 +348,7 @@ class scalar_parser { void process_chomping(chomping_indicator_t chomp) { switch (chomp) { case chomping_indicator_t::STRIP: { - std::size_t content_end_pos = m_buffer.find_last_not_of('\n'); + const std::size_t content_end_pos = m_buffer.find_last_not_of('\n'); if (content_end_pos == std::string::npos) { // if the scalar has no content line, all lines are considered as trailing empty lines. m_buffer.clear(); @@ -366,7 +366,7 @@ class scalar_parser { break; } case chomping_indicator_t::CLIP: { - std::size_t content_end_pos = m_buffer.find_last_not_of('\n'); + const std::size_t content_end_pos = m_buffer.find_last_not_of('\n'); if (content_end_pos == std::string::npos) { // if the scalar has no content line, all lines are considered as trailing empty lines. m_buffer.clear(); @@ -393,7 +393,7 @@ class scalar_parser { /// @param newline_pos Position of the target newline code. void process_line_folding(str_view& token, std::size_t newline_pos) noexcept { // discard trailing white spaces which precedes the line break in the current line. - std::size_t last_non_space_pos = token.substr(0, newline_pos + 1).find_last_not_of(" \t"); + const std::size_t last_non_space_pos = token.substr(0, newline_pos + 1).find_last_not_of(" \t"); if (last_non_space_pos == str_view::npos) { m_buffer.append(token.begin(), newline_pos); } @@ -404,13 +404,13 @@ class scalar_parser { uint32_t empty_line_counts = 0; do { - std::size_t non_space_pos = token.find_first_not_of(" \t"); + const std::size_t non_space_pos = token.find_first_not_of(" \t"); if (non_space_pos == str_view::npos) { // Line folding ignores trailing spaces. token.remove_prefix(token.size()); break; } - else if (token[non_space_pos] != '\n') { + if (token[non_space_pos] != '\n') { token.remove_prefix(non_space_pos); break; } @@ -452,8 +452,6 @@ class scalar_parser { value_type = node_type::FLOAT; break; case tag_t::STRING: - value_type = node_type::STRING; - break; case tag_t::NON_SPECIFIC: // scalars with the non-specific tag is resolved to a string tag. // See the "Non-Specific Tags" section in https://yaml.org/spec/1.2.2/#691-node-tags. @@ -478,7 +476,7 @@ class scalar_parser { switch (type) { case node_type::NULL_OBJECT: { std::nullptr_t null = nullptr; - bool converted = detail::aton(token.begin(), token.end(), null); + 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); } @@ -486,8 +484,8 @@ class scalar_parser { break; } case node_type::BOOLEAN: { - boolean_type boolean = static_cast(false); - bool converted = detail::atob(token.begin(), token.end(), boolean); + auto boolean = static_cast(false); + const bool converted = detail::atob(token.begin(), token.end(), boolean); if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to a boolean.", m_line, m_indent); } @@ -496,7 +494,7 @@ class scalar_parser { } case node_type::INTEGER: { integer_type integer = 0; - bool converted = detail::atoi(token.begin(), token.end(), integer); + const bool converted = detail::atoi(token.begin(), token.end(), integer); if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to an integer.", m_line, m_indent); } @@ -505,7 +503,7 @@ class scalar_parser { } case node_type::FLOAT: { float_number_type float_val = 0; - bool converted = detail::atof(token.begin(), token.end(), float_val); + const bool converted = detail::atof(token.begin(), token.end(), float_val); if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to a floating point value", m_line, m_indent); } @@ -535,7 +533,7 @@ class scalar_parser { /// Whether the parsed contents are stored in an owned buffer. bool m_use_owned_buffer {false}; /// Owned buffer storage for parsing. This buffer is used when scalar contents need mutation. - std::string m_buffer {}; + std::string m_buffer; }; FK_YAML_DETAIL_NAMESPACE_END diff --git a/include/fkYAML/detail/input/scalar_scanner.hpp b/include/fkYAML/detail/input/scalar_scanner.hpp index b5739a91..895dfec5 100644 --- a/include/fkYAML/detail/input/scalar_scanner.hpp +++ b/include/fkYAML/detail/input/scalar_scanner.hpp @@ -18,26 +18,6 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN -namespace { - -/// @brief Check if the given character is a digit. -/// @note This function is needed to avoid assertion failures in `std::isdigit()` especially when compiled with MSVC. -/// @param c A character to be checked. -/// @return true if the given character is a digit, false otherwise. -inline bool is_digit(char c) { - return ('0' <= c && c <= '9'); -} - -/// @brief Check if the given character is a hex-digit. -/// @note This function is needed to avoid assertion failures in `std::isxdigit()` especially when compiled with MSVC. -/// @param c A character to be checked. -/// @return true if the given character is a hex-digit, false otherwise. -inline bool is_xdigit(char c) { - return (('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')); -} - -} // namespace - /// @brief The class which detects a scalar value type by scanning contents. class scalar_scanner { public: @@ -50,7 +30,7 @@ class scalar_scanner { return node_type::STRING; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); if (len > 5) { return scan_possible_number_token(begin, len); } @@ -83,7 +63,7 @@ class scalar_scanner { : node_type::STRING; case '.': { const char* p_from_second = p_begin + 1; - bool is_inf_or_nan_scalar = + const bool is_inf_or_nan_scalar = (std::strncmp(p_from_second, "inf", 3) == 0) || (std::strncmp(p_from_second, "Inf", 3) == 0) || (std::strncmp(p_from_second, "INF", 3) == 0) || (std::strncmp(p_from_second, "nan", 3) == 0) || (std::strncmp(p_from_second, "NaN", 3) == 0) || (std::strncmp(p_from_second, "NAN", 3) == 0); @@ -93,6 +73,8 @@ class scalar_scanner { // maybe a number. break; } + default: + break; } break; case 5: @@ -109,17 +91,21 @@ class scalar_scanner { case '-': if (*(p_begin + 1) == '.') { const char* p_from_third = p_begin + 2; - bool is_min_inf_scalar = (std::strncmp(p_from_third, "inf", 3) == 0) || - (std::strncmp(p_from_third, "Inf", 3) == 0) || - (std::strncmp(p_from_third, "INF", 3) == 0); - if (is_min_inf_scalar) { + const bool is_min_inf = (std::strncmp(p_from_third, "inf", 3) == 0) || + (std::strncmp(p_from_third, "Inf", 3) == 0) || + (std::strncmp(p_from_third, "INF", 3) == 0); + if (is_min_inf) { return node_type::FLOAT; } } // maybe a number. break; + default: + break; } break; + default: + break; } return scan_possible_number_token(begin, len); @@ -240,7 +226,7 @@ class scalar_scanner { FK_YAML_ASSERT(len > 0); for (uint32_t i = 0; i < len; i++) { - char c = *itr++; + const char c = *itr++; if (is_digit(c)) { continue; @@ -267,7 +253,7 @@ class scalar_scanner { static node_type scan_after_exponent(const char* itr, uint32_t len) noexcept { FK_YAML_ASSERT(len > 0); - char c = *itr; + const char c = *itr; if (c == '+' || c == '-') { if (len == 1) { // some integer(s) required after the sign. @@ -320,6 +306,24 @@ class scalar_scanner { } return node_type::STRING; } + + /// @brief Check if the given character is a digit. + /// @note This function is needed to avoid assertion failures in `std::isdigit()` especially when compiled with + /// MSVC. + /// @param c A character to be checked. + /// @return true if the given character is a digit, false otherwise. + static bool is_digit(char c) { + return ('0' <= c && c <= '9'); + } + + /// @brief Check if the given character is a hex-digit. + /// @note This function is needed to avoid assertion failures in `std::isxdigit()` especially when compiled with + /// MSVC. + /// @param c A character to be checked. + /// @return true if the given character is a hex-digit, false otherwise. + static bool is_xdigit(char c) { + return (('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')); + } }; FK_YAML_DETAIL_NAMESPACE_END diff --git a/include/fkYAML/detail/input/tag_resolver.hpp b/include/fkYAML/detail/input/tag_resolver.hpp index 389e914e..682d682f 100644 --- a/include/fkYAML/detail/input/tag_resolver.hpp +++ b/include/fkYAML/detail/input/tag_resolver.hpp @@ -11,24 +11,19 @@ #include #include -#include #include #include #include #include #include +#include #include FK_YAML_DETAIL_NAMESPACE_BEGIN -namespace /*default prefixes*/ -{ - -const std::string default_primary_handle_prefix = "!"; -const std::string default_secondary_handle_prefix = "tag:yaml.org,2002:"; - -} // namespace +static constexpr str_view default_primary_handle_prefix = "!"; +static constexpr str_view default_secondary_handle_prefix = "tag:yaml.org,2002:"; template class tag_resolver { @@ -40,7 +35,7 @@ class tag_resolver { /// @param tag The input tag name. /// @return The type of a node deduced from the given tag name. static tag_t resolve_tag(const std::string& tag, const std::shared_ptr& directives) { - std::string normalized = normalize_tag_name(tag, directives); + const std::string normalized = normalize_tag_name(tag, directives); return convert_to_tag_type(normalized); } @@ -68,9 +63,10 @@ class tag_resolver { switch (tag[1]) { case '!': { // handle a secondary tag handle (!!suffix -> !<[secondary][suffix]>) - bool is_null_or_empty = !directives || directives->secondary_handle_prefix.empty(); + const bool is_null_or_empty = !directives || directives->secondary_handle_prefix.empty(); if (is_null_or_empty) { - normalized += default_secondary_handle_prefix + tag.substr(2); + normalized.append(default_secondary_handle_prefix.begin(), default_secondary_handle_prefix.end()); + normalized += tag.substr(2); } else { normalized += directives->secondary_handle_prefix + tag.substr(2); @@ -79,9 +75,10 @@ class tag_resolver { } case '<': if (tag[2] == '!') { - bool is_null_or_empty = !directives || directives->primary_handle_prefix.empty(); + const bool is_null_or_empty = !directives || directives->primary_handle_prefix.empty(); if (is_null_or_empty) { - return normalized + default_primary_handle_prefix + tag.substr(3); + normalized.append(default_primary_handle_prefix.begin(), default_primary_handle_prefix.end()); + return normalized + tag.substr(3); } return normalized + directives->primary_handle_prefix + tag.substr(3); } @@ -97,7 +94,7 @@ class tag_resolver { // there must be a non-empty suffix. (already checked by the lexer.) FK_YAML_ASSERT(tag_end_pos < tag.size() - 1); - bool is_null_or_empty = !directives || directives->named_handle_map.empty(); + const bool is_null_or_empty = !directives || directives->named_handle_map.empty(); if FK_YAML_UNLIKELY (is_null_or_empty) { throw invalid_tag("named handle has not been registered.", tag.c_str()); } @@ -114,14 +111,15 @@ class tag_resolver { // See https://yaml.org/spec/1.2.2/#56-miscellaneous-characters for more details. normalized += named_handle_itr->second; - normalized.append(tag.begin() + (tag_end_pos + 1), tag.end()); + normalized.append(tag.begin() + (static_cast(tag_end_pos) + 1), tag.end()); break; } // handle a primary tag handle (!suffix -> !<[primary][suffix]>) - bool is_null_or_empty = !directives || directives->primary_handle_prefix.empty(); + const bool is_null_or_empty = !directives || directives->primary_handle_prefix.empty(); if (is_null_or_empty) { - normalized += default_primary_handle_prefix + tag.substr(1); + normalized.append(default_primary_handle_prefix.begin(), default_primary_handle_prefix.end()); + normalized += tag.substr(1); } else { normalized += directives->primary_handle_prefix + tag.substr(1); diff --git a/include/fkYAML/detail/input/tag_t.hpp b/include/fkYAML/detail/input/tag_t.hpp index 227a92f7..fa709442 100644 --- a/include/fkYAML/detail/input/tag_t.hpp +++ b/include/fkYAML/detail/input/tag_t.hpp @@ -9,12 +9,14 @@ #ifndef FK_YAML_DETAIL_INPUT_TAG_T_HPP #define FK_YAML_DETAIL_INPUT_TAG_T_HPP +#include + #include FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of YAML tag types. -enum class tag_t { +enum class tag_t : std::uint8_t { NONE, //!< Represents a non-specific tag "?". NON_SPECIFIC, //!< Represents a non-specific tag "!". CUSTOM_TAG, //!< Represents a custom tag diff --git a/include/fkYAML/detail/iterator.hpp b/include/fkYAML/detail/iterator.hpp index 2395ffac..595861f9 100644 --- a/include/fkYAML/detail/iterator.hpp +++ b/include/fkYAML/detail/iterator.hpp @@ -57,7 +57,7 @@ struct iterator_traits { }; /// @brief Definitions of iterator types for iterators internally held. -enum class iterator_t { +enum class iterator_t : std::uint8_t { SEQUENCE, //!< sequence iterator type. MAPPING, //!< mapping iterator type. }; @@ -100,8 +100,7 @@ class 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 - : m_inner_iterator_type(iterator_t::SEQUENCE) { + iterator(sequence_iterator_tag /* unused */, const typename ValueType::sequence_type::iterator& itr) noexcept { m_iterator_holder.sequence_iterator = itr; } diff --git a/include/fkYAML/detail/node_attrs.hpp b/include/fkYAML/detail/node_attrs.hpp index c70e6256..ad7fa0ac 100644 --- a/include/fkYAML/detail/node_attrs.hpp +++ b/include/fkYAML/detail/node_attrs.hpp @@ -24,17 +24,17 @@ using node_attr_t = uint32_t; namespace node_attr_mask { /// The bit mask for node value type bits. -const node_attr_t value = 0x0000FFFFu; +constexpr node_attr_t value = 0x0000FFFFu; /// The bit mask for node style type bits. (bits are not yet defined.) -const node_attr_t style = 0x00FF0000u; +constexpr node_attr_t style = 0x00FF0000u; /// The bit mask for node property related bits. -const node_attr_t props = 0xFF000000u; +constexpr node_attr_t props = 0xFF000000u; /// The bit mask for anchor/alias node type bits. -const node_attr_t anchoring = 0x03000000u; +constexpr node_attr_t anchoring = 0x03000000u; /// The bit mask for anchor offset value bits. -const node_attr_t anchor_offset = 0xFC000000u; +constexpr node_attr_t anchor_offset = 0xFC000000u; /// The bit mask for all the bits for node attributes. -const node_attr_t all = std::numeric_limits::max(); +constexpr node_attr_t all = std::numeric_limits::max(); } // namespace node_attr_mask @@ -42,30 +42,30 @@ const node_attr_t all = std::numeric_limits::max(); namespace node_attr_bits { /// The sequence node bit. -const node_attr_t seq_bit = 1u << 0; +constexpr node_attr_t seq_bit = 1u << 0; /// The mapping node bit. -const node_attr_t map_bit = 1u << 1; +constexpr node_attr_t map_bit = 1u << 1; /// The null scalar node bit. -const node_attr_t null_bit = 1u << 2; +constexpr node_attr_t null_bit = 1u << 2; /// The boolean scalar node bit. -const node_attr_t bool_bit = 1u << 3; +constexpr node_attr_t bool_bit = 1u << 3; /// The integer scalar node bit. -const node_attr_t int_bit = 1u << 4; +constexpr node_attr_t int_bit = 1u << 4; /// The floating point scalar node bit. -const node_attr_t float_bit = 1u << 5; +constexpr node_attr_t float_bit = 1u << 5; /// The string scalar node bit. -const node_attr_t string_bit = 1u << 6; +constexpr node_attr_t string_bit = 1u << 6; /// A utility bit set to filter scalar node bits. -const node_attr_t scalar_bits = null_bit | bool_bit | int_bit | float_bit | string_bit; +constexpr node_attr_t scalar_bits = null_bit | bool_bit | int_bit | float_bit | string_bit; /// The anchor node bit. -const node_attr_t anchor_bit = 0x01000000u; +constexpr node_attr_t anchor_bit = 0x01000000u; /// The alias node bit. -const node_attr_t alias_bit = 0x02000000u; +constexpr node_attr_t alias_bit = 0x02000000u; /// A utility bit set for initialization. -const node_attr_t default_bits = null_bit; +constexpr node_attr_t default_bits = null_bit; /// @brief Converts a node_type value to a node_attr_t value. /// @param t A type of node value. diff --git a/include/fkYAML/detail/node_property.hpp b/include/fkYAML/detail/node_property.hpp index 797be52d..a9eb65cd 100644 --- a/include/fkYAML/detail/node_property.hpp +++ b/include/fkYAML/detail/node_property.hpp @@ -17,9 +17,9 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN struct node_property { /// The tag name property. - std::string tag {}; + std::string tag; /// The anchor name property. - std::string anchor {}; + std::string anchor; }; FK_YAML_DETAIL_NAMESPACE_END diff --git a/include/fkYAML/detail/node_ref_storage.hpp b/include/fkYAML/detail/node_ref_storage.hpp index 958d8f98..28076862 100644 --- a/include/fkYAML/detail/node_ref_storage.hpp +++ b/include/fkYAML/detail/node_ref_storage.hpp @@ -32,19 +32,19 @@ class node_ref_storage { /// @brief Construct a new node ref storage object with an rvalue basic_node object. /// @param n An rvalue basic_node object. explicit node_ref_storage(node_type&& n) noexcept(std::is_nothrow_move_constructible::value) - : owned_value(std::move(n)) { + : m_owned_value(std::move(n)) { } /// @brief Construct a new node ref storage object with an lvalue basic_node object. /// @param n An lvalue basic_node object. explicit node_ref_storage(const node_type& n) noexcept - : value_ref(&n) { + : m_value_ref(&n) { } /// @brief Construct a new node ref storage object with a std::initializer_list object. /// @param init A std::initializer_list object. node_ref_storage(std::initializer_list init) - : owned_value(init) { + : m_owned_value(init) { } /// @brief Construct a new node ref storage object with variadic template arguments @@ -52,7 +52,7 @@ class node_ref_storage { /// @param args Arguments to construct a basic_node object. template ::value, int> = 0> node_ref_storage(Args&&... args) - : owned_value(std::forward(args)...) { + : m_owned_value(std::forward(args)...) { } // allow only move construct/assignment @@ -61,24 +61,26 @@ class node_ref_storage { node_ref_storage& operator=(const node_ref_storage&) = delete; node_ref_storage& operator=(node_ref_storage&&) = default; + ~node_ref_storage() = default; + public: /// @brief An arrow operator for node_ref_storage objects. /// @return const node_type* A constant pointer to a basic_node object. const node_type* operator->() const noexcept { - return value_ref ? value_ref : &owned_value; + return m_value_ref ? m_value_ref : &m_owned_value; } /// @brief Releases a basic_node object internally held. /// @return node_type A basic_node object internally held. node_type release() const noexcept { - return value_ref ? *value_ref : std::move(owned_value); + return m_value_ref ? *m_value_ref : std::move(m_owned_value); } private: /// A storage for a basic_node object given with rvalue reference. - mutable node_type owned_value = nullptr; + mutable node_type m_owned_value = nullptr; /// A pointer to a basic_node object given with lvalue reference. - const node_type* value_ref = nullptr; + const node_type* m_value_ref = nullptr; }; FK_YAML_DETAIL_NAMESPACE_END diff --git a/include/fkYAML/detail/output/serializer.hpp b/include/fkYAML/detail/output/serializer.hpp index 92b4880c..142e5eef 100644 --- a/include/fkYAML/detail/output/serializer.hpp +++ b/include/fkYAML/detail/output/serializer.hpp @@ -47,7 +47,7 @@ class basic_serializer { std::string serialize_docs(const std::vector& docs) { std::string str {}; - uint32_t size = static_cast(docs.size()); + const auto size = static_cast(docs.size()); for (uint32_t i = 0; i < size; i++) { serialize_document(docs[i], str); if (i + 1 < size) { @@ -61,10 +61,10 @@ class basic_serializer { private: void serialize_document(const BasicNodeType& node, std::string& str) { - bool dirs_serialized = serialize_directives(node, str); + const bool dirs_serialized = serialize_directives(node, str); // the root node cannot be an alias node. - bool root_has_props = node.is_anchor() || node.has_tag_name(); + const bool root_has_props = node.is_anchor() || node.has_tag_name(); if (root_has_props) { if (dirs_serialized) { @@ -141,7 +141,7 @@ class basic_serializer { insert_indentation(cur_indent, str); str += "-"; - bool is_appended = try_append_alias(seq_item, true, str); + const bool is_appended = try_append_alias(seq_item, true, str); if (is_appended) { str += "\n"; continue; @@ -150,7 +150,7 @@ class basic_serializer { try_append_anchor(seq_item, true, str); try_append_tag(seq_item, true, str); - bool is_scalar = seq_item.is_scalar(); + const bool is_scalar = seq_item.is_scalar(); if (is_scalar) { str += " "; serialize_node(seq_item, cur_indent, str); @@ -172,17 +172,17 @@ class basic_serializer { str += " "; } else { - bool is_anchor_appended = try_append_anchor(itr.key(), false, str); - bool is_tag_appended = try_append_tag(itr.key(), is_anchor_appended, str); + const bool is_anchor_appended = try_append_anchor(itr.key(), false, str); + const bool is_tag_appended = try_append_tag(itr.key(), is_anchor_appended, str); if (is_anchor_appended || is_tag_appended) { str += " "; } - bool is_container = !itr.key().is_scalar(); + const bool is_container = !itr.key().is_scalar(); if (is_container) { str += "? "; } - uint32_t indent = static_cast(get_cur_indent(str)); + const auto indent = static_cast(get_cur_indent(str)); serialize_node(itr.key(), indent, str); if (is_container) { // a newline code is already inserted in the above serialize_node() call. @@ -201,7 +201,7 @@ class basic_serializer { try_append_anchor(*itr, true, str); try_append_tag(*itr, true, str); - bool is_scalar = itr->is_scalar(); + const bool is_scalar = itr->is_scalar(); if (is_scalar) { str += " "; serialize_node(*itr, cur_indent, str); @@ -231,7 +231,7 @@ class basic_serializer { break; case node_type::STRING: { bool is_escaped = false; - typename BasicNodeType::string_type str_val = get_string_node_value(node, is_escaped); + auto str_val = get_string_node_value(node, is_escaped); if (is_escaped) { // There's no other token type with escapes than strings. @@ -245,7 +245,7 @@ class basic_serializer { // The next line is intentionally excluded from the LCOV coverage target since the next line is somehow // misrecognized as it has a binary branch. Possibly begin() or end() has some conditional branch(es) // internally. Confirmed with LCOV 1.14 on Ubuntu22.04. - node_type type_if_plain = + const node_type type_if_plain = scalar_scanner::scan(str_val.c_str(), str_val.c_str() + str_val.size()); // LCOV_EXCL_LINE if (type_if_plain != node_type::STRING) { @@ -267,12 +267,12 @@ class basic_serializer { /// @param s The target string object. /// @return The current indentation width. std::size_t get_cur_indent(const std::string& s) const noexcept { - bool is_empty = s.empty(); + const bool is_empty = s.empty(); if (is_empty) { return 0; } - std::size_t last_lf_pos = s.rfind('\n'); + const std::size_t last_lf_pos = s.rfind('\n'); return (last_lf_pos != std::string::npos) ? s.size() - last_lf_pos - 1 : s.size(); } @@ -341,8 +341,7 @@ class basic_serializer { typename BasicNodeType::string_type get_string_node_value(const BasicNodeType& node, bool& is_escaped) { FK_YAML_ASSERT(node.is_string()); - using string_type = typename BasicNodeType::string_type; - const string_type& s = node.template get_value_ref(); + const auto& s = node.template get_value_ref(); return yaml_escaper::escape(s.c_str(), s.c_str() + s.size(), is_escaped); } // LCOV_EXCL_LINE diff --git a/include/fkYAML/detail/str_view.hpp b/include/fkYAML/detail/str_view.hpp index ff65d90f..2314c562 100644 --- a/include/fkYAML/detail/str_view.hpp +++ b/include/fkYAML/detail/str_view.hpp @@ -318,8 +318,9 @@ class basic_str_view { if (ret == 0) { using int_limits = std::numeric_limits; - difference_type diff = - m_len > sv.m_len ? m_len - sv.m_len : difference_type(-1) * difference_type(sv.m_len - m_len); + const difference_type diff = + m_len > sv.m_len ? m_len - sv.m_len + : static_cast(-1) * static_cast(sv.m_len - m_len); if (diff > int_limits::max()) { ret = int_limits::max(); @@ -386,7 +387,7 @@ class basic_str_view { /// @brief Checks if this character sequence starts with `sv` characters. /// @param sv The character sequence to compare with. /// @return true if the character sequence starts with `sv` characters, false otherwise. - bool starts_with(basic_str_view sv) const noexcept { + bool starts_with(basic_str_view sv) const { return substr(0, sv.size()) == sv; } @@ -400,7 +401,7 @@ class basic_str_view { /// @brief Checks if this character sequence starts with `s` characters. /// @param s The character sequence to compare with. /// @return true if the character sequence starts with `s` characters, false otherwise. - bool starts_with(const CharT* s) const noexcept { + bool starts_with(const CharT* s) const { return starts_with(basic_str_view(s)); } @@ -448,6 +449,8 @@ class basic_str_view { return find(s) != npos; } + // NOLINTBEGIN(bugprone-easily-swappable-parameters) + /// @brief Finds the beginning position of `sv` characters in this referenced character sequence. /// @param sv The character sequence to compare with. /// @param pos The offset of the search beginning position in this referenced character sequence. @@ -520,6 +523,8 @@ class basic_str_view { return find(basic_str_view(s), pos); } + // NOLINTEND(bugprone-easily-swappable-parameters) + /// @brief Retrospectively finds the beginning position of `sv` characters in this referenced character sequence. /// @param sv The character sequence to compare with. /// @param pos The offset of the search beginning position in this referenced character sequence. @@ -537,16 +542,13 @@ class basic_str_view { return npos; } - size_type idx = pos; - if (pos >= m_len) { - idx = m_len - 1; - } + const size_type idx = std::min(m_len - 1, pos); - do { - if (traits_type::eq(mp_str[idx], c)) { - return idx; + for (size_type i = 0; i <= idx; i++) { + if (traits_type::eq(mp_str[idx - i], c)) { + return idx - i; } - } while (idx > 0 && --idx < m_len); + } return npos; } @@ -602,6 +604,7 @@ class basic_str_view { /// @param pos The offset of the search beginning position in this referenced character sequence. /// @param n The length of `s` character sequence used for comparison. /// @return The beginning position of `s` characters, `npos` otherwise. + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) size_type find_first_of(const CharT* s, size_type pos, size_type n) const noexcept { if FK_YAML_UNLIKELY (n == 0) { return npos; @@ -829,7 +832,7 @@ inline bool operator==(const std::basic_string& lhs, basic_str_vi template inline bool operator==(basic_str_view lhs, const CharT (&rhs)[N]) noexcept { // assume `rhs` is null terminated - return lhs == basic_str_view(rhs, N - 1); + return lhs == basic_str_view(rhs); } /// @brief An equal-to operator of the basic_str_view class. @@ -842,7 +845,7 @@ inline bool operator==(basic_str_view lhs, const CharT (&rhs)[N]) template inline bool operator==(const CharT (&lhs)[N], basic_str_view rhs) noexcept { // assume `lhs` is null terminated - return basic_str_view(lhs, N - 1) == rhs; + return basic_str_view(lhs) == rhs; } /// @brief An not-equal-to operator of the basic_str_view class. diff --git a/include/fkYAML/detail/string_formatter.hpp b/include/fkYAML/detail/string_formatter.hpp index c9456ad5..fbe95fbc 100644 --- a/include/fkYAML/detail/string_formatter.hpp +++ b/include/fkYAML/detail/string_formatter.hpp @@ -18,7 +18,9 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN +// NOLINTNEXTLINE(cert-dcl50-cpp) inline std::string format(const char* fmt, ...) { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-array-to-pointer-decay,hicpp-no-array-decay) va_list vl; va_start(vl, fmt); int size = std::vsnprintf(nullptr, 0, fmt, vl); @@ -30,13 +32,14 @@ inline std::string format(const char* fmt, ...) { } // LCOV_EXCL_STOP - std::unique_ptr buffer {new char[size + 1] {}}; + const std::unique_ptr buffer {new char[size + 1] {}}; va_start(vl, fmt); size = std::vsnprintf(buffer.get(), size + 1, fmt, vl); va_end(vl); + // NOLINTEND(cppcoreguidelines-pro-bounds-array-to-pointer-decay,hicpp-no-array-decay) - return std::string(buffer.get(), size); + return {buffer.get(), static_cast(size)}; } FK_YAML_DETAIL_NAMESPACE_END diff --git a/include/fkYAML/detail/types/lexical_token_t.hpp b/include/fkYAML/detail/types/lexical_token_t.hpp index 9ffa463a..1999e48f 100644 --- a/include/fkYAML/detail/types/lexical_token_t.hpp +++ b/include/fkYAML/detail/types/lexical_token_t.hpp @@ -9,12 +9,14 @@ #ifndef FK_YAML_DETAIL_TYPES_LEXICAL_TOKEN_T_HPP #define FK_YAML_DETAIL_TYPES_LEXICAL_TOKEN_T_HPP +#include + #include FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of lexical token types. -enum class lexical_token_t { +enum class lexical_token_t : std::uint8_t { END_OF_BUFFER, //!< the end of input buffer. EXPLICIT_KEY_PREFIX, //!< the character for explicit mapping key prefix `?`. KEY_SEPARATOR, //!< the key separator `:` diff --git a/include/fkYAML/detail/types/node_t.hpp b/include/fkYAML/detail/types/node_t.hpp index 5fbad207..cd52c1d2 100644 --- a/include/fkYAML/detail/types/node_t.hpp +++ b/include/fkYAML/detail/types/node_t.hpp @@ -10,7 +10,6 @@ #define FK_YAML_DETAIL_TYPES_NODE_T_HPP #include -#include #include #include @@ -18,7 +17,7 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of node value types. -enum class node_t : std::uint32_t { +enum class node_t : std::uint8_t { SEQUENCE, //!< sequence value type MAPPING, //!< mapping value type NULL_OBJECT, //!< null value type diff --git a/include/fkYAML/detail/types/yaml_version_t.hpp b/include/fkYAML/detail/types/yaml_version_t.hpp index ebf14ae2..961a0fd1 100644 --- a/include/fkYAML/detail/types/yaml_version_t.hpp +++ b/include/fkYAML/detail/types/yaml_version_t.hpp @@ -17,7 +17,7 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of YAML version types. -enum class yaml_version_t : std::uint32_t { +enum class yaml_version_t : std::uint8_t { VER_1_1, //!< YAML version 1.1 VER_1_2, //!< YAML version 1.2 }; @@ -27,9 +27,8 @@ inline yaml_version_t convert_from_yaml_version_type(yaml_version_type t) noexce case yaml_version_type::VERSION_1_1: return yaml_version_t::VER_1_1; case yaml_version_type::VERSION_1_2: + default: return yaml_version_t::VER_1_2; - default: // LCOV_EXCL_LINE - return yaml_version_t::VER_1_2; // LCOV_EXCL_LINE } } @@ -38,9 +37,8 @@ inline yaml_version_type convert_to_yaml_version_type(yaml_version_t t) noexcept case yaml_version_t::VER_1_1: return yaml_version_type::VERSION_1_1; case yaml_version_t::VER_1_2: + default: return yaml_version_type::VERSION_1_2; - default: // LCOV_EXCL_LINE - return yaml_version_type::VERSION_1_2; // LCOV_EXCL_LINE } } diff --git a/include/fkYAML/exception.hpp b/include/fkYAML/exception.hpp index 23a91f1d..e83a6dba 100644 --- a/include/fkYAML/exception.hpp +++ b/include/fkYAML/exception.hpp @@ -47,7 +47,7 @@ class exception : public std::exception { private: /// An error message holder. - std::string m_error_msg {}; + std::string m_error_msg; }; /// @brief An exception class indicating an encoding error. @@ -77,9 +77,9 @@ class invalid_encoding : public exception { } private: - std::string generate_error_message(const char* msg, const std::initializer_list& u8) const noexcept { - auto itr = u8.begin(); - auto end_itr = u8.end(); + static std::string generate_error_message(const char* msg, const std::initializer_list& u8) noexcept { + const auto* itr = u8.begin(); + const auto* end_itr = u8.end(); std::string formatted = detail::format("invalid_encoding: %s in=[ 0x%02x", msg, *itr++); while (itr != end_itr) { formatted += detail::format(", 0x%02x", *itr++); @@ -93,18 +93,22 @@ class invalid_encoding : public exception { /// @param h The first UTF-16 encoded element used for the UTF-8 encoding. /// @param l The second UTF-16 encoded element used for the UTF-8 encoding. /// @return A generated error message. - std::string generate_error_message(const char* msg, std::array u16) const noexcept { + static std::string generate_error_message(const char* msg, std::array u16) noexcept { // uint16_t is large enough for UTF-16 encoded elements. - return detail::format("invalid_encoding: %s in=[ 0x%04x, 0x%04x ]", msg, uint16_t(u16[0]), uint16_t(u16[1])); + return detail::format( + "invalid_encoding: %s in=[ 0x%04x, 0x%04x ]", + msg, + static_cast(u16[0]), + static_cast(u16[1])); } /// @brief Generate an error message from the given parameters for the UTF-32 encoding. /// @param msg An error message. /// @param u32 The UTF-32 encoded element used for the UTF-8 encoding. /// @return A genereated error message. - std::string generate_error_message(const char* msg, char32_t u32) const noexcept { + static std::string generate_error_message(const char* msg, char32_t u32) noexcept { // uint32_t is large enough for UTF-32 encoded elements. - return detail::format("invalid_encoding: %s in=0x%08x", msg, uint32_t(u32)); + return detail::format("invalid_encoding: %s in=0x%08x", msg, static_cast(u32)); } }; @@ -116,7 +120,7 @@ class parse_error : public exception { } private: - std::string generate_error_message(const char* msg, uint32_t lines, uint32_t cols_in_line) const noexcept { + static std::string generate_error_message(const char* msg, uint32_t lines, uint32_t cols_in_line) noexcept { return detail::format("parse_error: %s (at line %u, column %u)", msg, lines, cols_in_line); } }; @@ -146,7 +150,7 @@ class type_error : public exception { /// @param msg An error message. /// @param type The type of a source node value. /// @return A generated error message. - std::string generate_error_message(const char* msg, node_type type) const noexcept { + static std::string generate_error_message(const char* msg, node_type type) noexcept { return detail::format("type_error: %s type=%s", msg, to_string(type)); } }; @@ -162,11 +166,11 @@ class out_of_range : public exception { } private: - std::string generate_error_message(int index) { + static std::string generate_error_message(int index) noexcept { return detail::format("out_of_range: index %d is out of range", index); } - std::string generate_error_message(const char* key) { + static std::string generate_error_message(const char* key) noexcept { return detail::format("out_of_range: key \'%s\' is not found.", key); } }; @@ -178,7 +182,7 @@ class invalid_tag : public exception { } private: - std::string generate_error_message(const char* msg, const char* tag) { + static std::string generate_error_message(const char* msg, const char* tag) noexcept { return detail::format("invalid_tag: %s tag=%s", msg, tag); } }; diff --git a/include/fkYAML/node.hpp b/include/fkYAML/node.hpp index 05285f09..79d706e4 100644 --- a/include/fkYAML/node.hpp +++ b/include/fkYAML/node.hpp @@ -427,7 +427,7 @@ class basic_node { /// @return The resulting basic_node object deserialized from the pair of iterators. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/deserialize/ template - static basic_node deserialize(ItrType&& begin, ItrType&& end) { + static basic_node deserialize(ItrType begin, ItrType end) { return deserializer_type().deserialize( detail::input_adapter(std::forward(begin), std::forward(end))); } @@ -540,7 +540,7 @@ class basic_node { /// @return An alias YAML node created from the given anchor node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/alias_of/ static basic_node alias_of(const basic_node& anchor_node) { - using namespace detail::node_attr_bits; + constexpr detail::node_attr_t anchor_bit = detail::node_attr_bits::anchor_bit; if FK_YAML_UNLIKELY (!anchor_node.has_anchor_name() || !(anchor_node.m_attrs & anchor_bit)) { throw fkyaml::exception("Cannot create an alias without anchor name."); @@ -548,7 +548,7 @@ class basic_node { basic_node node = anchor_node; node.m_attrs &= ~detail::node_attr_mask::anchoring; - node.m_attrs |= alias_bit; + node.m_attrs |= detail::node_attr_bits::alias_bit; return node; } // LCOV_EXCL_LINE @@ -694,7 +694,7 @@ class basic_node { /// @return true if both types and values are equal, false otherwise. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/operator_eq/ bool operator==(const basic_node& rhs) const noexcept { - detail::node_attr_t this_val_bit = get_node_attrs() & detail::node_attr_mask::value; + const detail::node_attr_t this_val_bit = get_node_attrs() & detail::node_attr_mask::value; if (this_val_bit != (rhs.get_node_attrs() & detail::node_attr_mask::value)) { return false; } @@ -752,8 +752,8 @@ class basic_node { return false; } - detail::node_attr_t this_val_bit = get_node_attrs() & detail::node_attr_mask::value; - detail::node_attr_t other_val_bit = rhs.get_node_attrs() & detail::node_attr_mask::value; + const detail::node_attr_t this_val_bit = get_node_attrs() & detail::node_attr_mask::value; + const detail::node_attr_t other_val_bit = rhs.get_node_attrs() & detail::node_attr_mask::value; if (this_val_bit < other_val_bit) { return true; @@ -826,7 +826,7 @@ class basic_node { /// @return The type of the YAML node value. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/get_type/ node_type get_type() const noexcept { - detail::node_attr_t attrs = get_node_attrs(); + const detail::node_attr_t attrs = get_node_attrs(); return detail::node_attr_bits::to_node_type(attrs); } @@ -1236,7 +1236,7 @@ class basic_node { m_attrs &= ~detail::node_attr_mask::anchoring; m_attrs |= detail::node_attr_bits::anchor_bit; mp_meta = p_meta; - uint32_t offset = static_cast(mp_meta->anchor_table.count(anchor_name) - 1); + auto offset = static_cast(mp_meta->anchor_table.count(anchor_name) - 1); detail::node_attr_bits::set_anchor_offset(offset, m_attrs); m_prop.anchor = anchor_name; } @@ -1264,7 +1264,7 @@ class basic_node { m_attrs &= ~detail::node_attr_mask::anchoring; m_attrs |= detail::node_attr_bits::anchor_bit; mp_meta = p_meta; - uint32_t offset = static_cast(mp_meta->anchor_table.count(anchor_name) - 1); + auto offset = static_cast(mp_meta->anchor_table.count(anchor_name) - 1); detail::node_attr_bits::set_anchor_offset(offset, m_attrs); m_prop.anchor = std::move(anchor_name); } @@ -1609,6 +1609,7 @@ class basic_node { detail::node_attr_t m_attrs {detail::node_attr_bits::default_bits}; /// The shared set of YAML directives applied to this node. mutable std::shared_ptr> mp_meta { + // NOLINTNEXTLINE(bugprone-unhandled-exception-at-new) std::shared_ptr>(new detail::document_metainfo())}; /// The current node value. node_value m_node_value {}; @@ -1682,7 +1683,7 @@ inline namespace yaml_literals { /// @return The resulting `node` object deserialized from `s`. /// @sa https://fktn-k.github.io/fkYAML/api/operator_literal_yaml/ inline fkyaml::node operator"" _yaml(const char* s, std::size_t n) { - return fkyaml::node::deserialize(std::move(s), std::move(s + n)); + return fkyaml::node::deserialize(s, s + n); } /// @brief The user-defined string literal which deserializes a `char16_t` array into a `node` object. @@ -1691,7 +1692,7 @@ inline fkyaml::node operator"" _yaml(const char* s, std::size_t n) { /// @return The resulting `node` object deserialized from `s`. /// @sa https://fktn-k.github.io/fkYAML/api/operator_literal_yaml/ inline fkyaml::node operator"" _yaml(const char16_t* s, std::size_t n) { - return fkyaml::node::deserialize(std::move(s), std::move(s + n)); + return fkyaml::node::deserialize(s, s + n); } /// @brief The user-defined string literal which deserializes a `char32_t` array into a `node` object. @@ -1700,7 +1701,7 @@ inline fkyaml::node operator"" _yaml(const char16_t* s, std::size_t n) { /// @return The resulting `node` object deserialized from `s`. /// @sa https://fktn-k.github.io/fkYAML/api/operator_literal_yaml/ inline fkyaml::node operator"" _yaml(const char32_t* s, std::size_t n) { - return fkyaml::node::deserialize(std::move(s), std::move(s + n)); + return fkyaml::node::deserialize(s, s + n); } #if FK_YAML_HAS_CHAR8_T diff --git a/include/fkYAML/node_type.hpp b/include/fkYAML/node_type.hpp index 16f99065..9b0fe445 100644 --- a/include/fkYAML/node_type.hpp +++ b/include/fkYAML/node_type.hpp @@ -15,7 +15,7 @@ FK_YAML_NAMESPACE_BEGIN -enum class node_type : std::uint32_t { +enum class node_type : std::uint8_t { SEQUENCE, //!< sequence value type MAPPING, //!< mapping value type NULL_OBJECT, //!< null value type diff --git a/include/fkYAML/node_value_converter.hpp b/include/fkYAML/node_value_converter.hpp index 0d538784..4d872c9b 100644 --- a/include/fkYAML/node_value_converter.hpp +++ b/include/fkYAML/node_value_converter.hpp @@ -43,9 +43,8 @@ class node_value_converter { /// @param val A native data object. /// @sa https://fktn-k.github.io/fkYAML/api/node_value_converter/to_node/ template - static auto to_node(BasicNodeType& n, TargetType&& val) noexcept( - noexcept(::fkyaml::to_node(n, std::forward(val)))) - -> decltype(::fkyaml::to_node(n, std::forward(val))) { + static auto to_node(BasicNodeType& n, TargetType&& val) noexcept(noexcept(::fkyaml::to_node( + n, std::forward(val)))) -> decltype(::fkyaml::to_node(n, std::forward(val))) { ::fkyaml::to_node(n, std::forward(val)); } }; diff --git a/include/fkYAML/ordered_map.hpp b/include/fkYAML/ordered_map.hpp index 3a51a5af..c9843d24 100644 --- a/include/fkYAML/ordered_map.hpp +++ b/include/fkYAML/ordered_map.hpp @@ -92,7 +92,7 @@ class ordered_map : public std::vector, Allocator> { return {itr, false}; } } - this->emplace_back(key, value); + this->emplace_back(std::forward(key), value); return {std::prev(this->end()), true}; } @@ -104,7 +104,7 @@ class ordered_map : public std::vector, Allocator> { template < typename KeyType, detail::enable_if_t::value, int> = 0> - mapped_type& at(KeyType&& key) { + mapped_type& at(KeyType&& key) { // NOLINT(cppcoreguidelines-missing-std-forward) for (auto itr = this->begin(); itr != this->end(); ++itr) { if (m_compare(itr->first, key)) { return itr->second; @@ -121,7 +121,7 @@ class ordered_map : public std::vector, Allocator> { template < typename KeyType, detail::enable_if_t::value, int> = 0> - const mapped_type& at(KeyType&& key) const { + const mapped_type& at(KeyType&& key) const { // NOLINT(cppcoreguidelines-missing-std-forward) for (auto itr = this->begin(); itr != this->end(); ++itr) { if (m_compare(itr->first, key)) { return itr->second; @@ -138,7 +138,7 @@ class ordered_map : public std::vector, Allocator> { template < typename KeyType, detail::enable_if_t::value, int> = 0> - iterator find(KeyType&& key) noexcept { + iterator find(KeyType&& key) noexcept { // NOLINT(cppcoreguidelines-missing-std-forward) for (auto itr = this->begin(); itr != this->end(); ++itr) { if (m_compare(itr->first, key)) { return itr; @@ -155,7 +155,7 @@ class ordered_map : public std::vector, Allocator> { template < typename KeyType, detail::enable_if_t::value, int> = 0> - const_iterator find(KeyType&& key) const noexcept { + const_iterator find(KeyType&& key) const noexcept { // NOLINT(cppcoreguidelines-missing-std-forward) for (auto itr = this->begin(); itr != this->end(); ++itr) { if (m_compare(itr->first, key)) { return itr; diff --git a/include/fkYAML/yaml_version_type.hpp b/include/fkYAML/yaml_version_type.hpp index 903e7115..1a06c8ee 100644 --- a/include/fkYAML/yaml_version_type.hpp +++ b/include/fkYAML/yaml_version_type.hpp @@ -15,7 +15,7 @@ FK_YAML_NAMESPACE_BEGIN -enum class yaml_version_type : std::uint32_t { +enum class yaml_version_type : std::uint8_t { VERSION_1_1, //!< YAML version 1.1 VERSION_1_2, //!< YAML version 1.2 }; diff --git a/scripts/run_clang_format.bat b/scripts/run_clang_format.bat index da267b05..02544c0f 100644 --- a/scripts/run_clang_format.bat +++ b/scripts/run_clang_format.bat @@ -10,7 +10,7 @@ set ROOT_PATH=%SCRIPT_PATH%\.. if not exist .\venv_clang_format\Scripts\clang-format.exe ( python -m venv .\venv_clang_format - .\venv_clang_format\Scripts\pip.exe install clang-format==14.0.0 + .\venv_clang_format\Scripts\pip.exe install clang-format==18.1.3 ) for /r %ROOT_PATH%\include %%f in (*.hpp) do ( diff --git a/scripts/run_clang_format.sh b/scripts/run_clang_format.sh index e24c5593..0969fa98 100755 --- a/scripts/run_clang_format.sh +++ b/scripts/run_clang_format.sh @@ -20,7 +20,7 @@ fi # install the clang-format package if not installed yet. if [ ! -e "$SCRIPT_DIR"/venv_clang_format/"$VENV_BINARY_DIR"/clang-format ]; then "$PYTHON_EXE" -m venv "$SCRIPT_DIR/venv_clang_format" - "$SCRIPT_DIR"/venv_clang_format/"$VENV_BINARY_DIR"/pip install clang-format==14.0.0 + "$SCRIPT_DIR"/venv_clang_format/"$VENV_BINARY_DIR"/pip install clang-format==18.1.3 fi for f in $(find "$ROOT_DIR/include" "$ROOT_DIR/test" "$ROOT_DIR/docs/examples" "$ROOT_DIR/tool/benchmark" -type f -name "*.hpp" -o -name "*.cpp" | sort); do diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index 81be9820..5cde849e 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -861,7 +861,7 @@ FK_YAML_DETAIL_NAMESPACE_END FK_YAML_NAMESPACE_BEGIN -enum class yaml_version_type : std::uint32_t { +enum class yaml_version_type : std::uint8_t { VERSION_1_1, //!< YAML version 1.1 VERSION_1_2, //!< YAML version 1.2 }; @@ -892,11 +892,11 @@ struct document_metainfo { /// Whether the YAML version has been specified. bool is_version_specified {false}; /// The prefix of the primary handle. - std::string primary_handle_prefix {}; + std::string primary_handle_prefix; /// The prefix of the secondary handle. - std::string secondary_handle_prefix {}; + std::string secondary_handle_prefix; /// The map of handle-prefix pairs. - std::map named_handle_map {}; + std::map named_handle_map; /// The map of anchor node which allows for key duplication. std::multimap anchor_table {}; }; @@ -981,7 +981,7 @@ class uri_encoding { for (; current != end; ++current) { if (*current == '%') { - bool are_valid_octets = validate_octets(++current, end); + const bool are_valid_octets = validate_octets(++current, end); if (!are_valid_octets) { return false; } @@ -989,7 +989,7 @@ class uri_encoding { continue; } - bool is_allowed_character = validate_character(*current); + const bool is_allowed_character = validate_character(*current); if (!is_allowed_character) { return false; } @@ -1010,7 +1010,7 @@ class uri_encoding { } // Normalize a character for a-f/A-F comparison - int octet = std::tolower(*begin); + const int octet = std::tolower(*begin); if ('0' <= octet && octet <= '9') { continue; @@ -1029,7 +1029,7 @@ class uri_encoding { /// @brief Verify if the given character is allowed as a URI character. /// @param c The target character. /// @return true if the given character is allowed as a URI character, false otherwise. - static bool validate_character(char c) { + static bool validate_character(const char c) { // Check if the current character is one of reserved/unreserved characters which are allowed for // use. See the following links for details: // * reserved characters: https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 @@ -1131,7 +1131,9 @@ FK_YAML_DETAIL_NAMESPACE_END FK_YAML_DETAIL_NAMESPACE_BEGIN +// NOLINTNEXTLINE(cert-dcl50-cpp) inline std::string format(const char* fmt, ...) { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-array-to-pointer-decay,hicpp-no-array-decay) va_list vl; va_start(vl, fmt); int size = std::vsnprintf(nullptr, 0, fmt, vl); @@ -1143,13 +1145,14 @@ inline std::string format(const char* fmt, ...) { } // LCOV_EXCL_STOP - std::unique_ptr buffer {new char[size + 1] {}}; + const std::unique_ptr buffer {new char[size + 1] {}}; va_start(vl, fmt); size = std::vsnprintf(buffer.get(), size + 1, fmt, vl); va_end(vl); + // NOLINTEND(cppcoreguidelines-pro-bounds-array-to-pointer-decay,hicpp-no-array-decay) - return std::string(buffer.get(), size); + return {buffer.get(), static_cast(size)}; } FK_YAML_DETAIL_NAMESPACE_END @@ -1169,7 +1172,6 @@ FK_YAML_DETAIL_NAMESPACE_END #define FK_YAML_DETAIL_TYPES_NODE_T_HPP #include -#include // #include @@ -1192,7 +1194,7 @@ FK_YAML_DETAIL_NAMESPACE_END FK_YAML_NAMESPACE_BEGIN -enum class node_type : std::uint32_t { +enum class node_type : std::uint8_t { SEQUENCE, //!< sequence value type MAPPING, //!< mapping value type NULL_OBJECT, //!< null value type @@ -1231,7 +1233,7 @@ FK_YAML_NAMESPACE_END FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of node value types. -enum class node_t : std::uint32_t { +enum class node_t : std::uint8_t { SEQUENCE, //!< sequence value type MAPPING, //!< mapping value type NULL_OBJECT, //!< null value type @@ -1338,7 +1340,7 @@ class exception : public std::exception { private: /// An error message holder. - std::string m_error_msg {}; + std::string m_error_msg; }; /// @brief An exception class indicating an encoding error. @@ -1368,9 +1370,9 @@ class invalid_encoding : public exception { } private: - std::string generate_error_message(const char* msg, const std::initializer_list& u8) const noexcept { - auto itr = u8.begin(); - auto end_itr = u8.end(); + static std::string generate_error_message(const char* msg, const std::initializer_list& u8) noexcept { + const auto* itr = u8.begin(); + const auto* end_itr = u8.end(); std::string formatted = detail::format("invalid_encoding: %s in=[ 0x%02x", msg, *itr++); while (itr != end_itr) { formatted += detail::format(", 0x%02x", *itr++); @@ -1384,18 +1386,22 @@ class invalid_encoding : public exception { /// @param h The first UTF-16 encoded element used for the UTF-8 encoding. /// @param l The second UTF-16 encoded element used for the UTF-8 encoding. /// @return A generated error message. - std::string generate_error_message(const char* msg, std::array u16) const noexcept { + static std::string generate_error_message(const char* msg, std::array u16) noexcept { // uint16_t is large enough for UTF-16 encoded elements. - return detail::format("invalid_encoding: %s in=[ 0x%04x, 0x%04x ]", msg, uint16_t(u16[0]), uint16_t(u16[1])); + return detail::format( + "invalid_encoding: %s in=[ 0x%04x, 0x%04x ]", + msg, + static_cast(u16[0]), + static_cast(u16[1])); } /// @brief Generate an error message from the given parameters for the UTF-32 encoding. /// @param msg An error message. /// @param u32 The UTF-32 encoded element used for the UTF-8 encoding. /// @return A genereated error message. - std::string generate_error_message(const char* msg, char32_t u32) const noexcept { + static std::string generate_error_message(const char* msg, char32_t u32) noexcept { // uint32_t is large enough for UTF-32 encoded elements. - return detail::format("invalid_encoding: %s in=0x%08x", msg, uint32_t(u32)); + return detail::format("invalid_encoding: %s in=0x%08x", msg, static_cast(u32)); } }; @@ -1407,7 +1413,7 @@ class parse_error : public exception { } private: - std::string generate_error_message(const char* msg, uint32_t lines, uint32_t cols_in_line) const noexcept { + static std::string generate_error_message(const char* msg, uint32_t lines, uint32_t cols_in_line) noexcept { return detail::format("parse_error: %s (at line %u, column %u)", msg, lines, cols_in_line); } }; @@ -1437,7 +1443,7 @@ class type_error : public exception { /// @param msg An error message. /// @param type The type of a source node value. /// @return A generated error message. - std::string generate_error_message(const char* msg, node_type type) const noexcept { + static std::string generate_error_message(const char* msg, node_type type) noexcept { return detail::format("type_error: %s type=%s", msg, to_string(type)); } }; @@ -1453,11 +1459,11 @@ class out_of_range : public exception { } private: - std::string generate_error_message(int index) { + static std::string generate_error_message(int index) noexcept { return detail::format("out_of_range: index %d is out of range", index); } - std::string generate_error_message(const char* key) { + static std::string generate_error_message(const char* key) noexcept { return detail::format("out_of_range: key \'%s\' is not found.", key); } }; @@ -1469,7 +1475,7 @@ class invalid_tag : public exception { } private: - std::string generate_error_message(const char* msg, const char* tag) { + static std::string generate_error_message(const char* msg, const char* tag) noexcept { return detail::format("invalid_tag: %s tag=%s", msg, tag); } }; @@ -1497,15 +1503,15 @@ inline uint32_t get_num_bytes(uint8_t first_byte) { return 1; } // The first byte starts with 0b110X'XXXX -> 2-byte character - else if ((first_byte & 0xE0) == 0xC0) { + if ((first_byte & 0xE0) == 0xC0) { return 2; } // The first byte starts with 0b1110'XXXX -> 3-byte character - else if ((first_byte & 0xF0) == 0xE0) { + if ((first_byte & 0xF0) == 0xE0) { return 3; } // The first byte starts with 0b1111'0XXX -> 4-byte character - else if ((first_byte & 0xF8) == 0xF0) { + if ((first_byte & 0xF8) == 0xF0) { return 4; } @@ -1520,17 +1526,17 @@ inline bool validate(const std::initializer_list& byte_array) noexcept switch (byte_array.size()) { case 1: // U+0000..U+007F - return uint8_t(*(byte_array.begin())) <= uint8_t(0x7Fu); + return *byte_array.begin() <= 0x7Fu; case 2: { - auto itr = byte_array.begin(); - uint8_t first = *itr++; - uint8_t second = *itr; + const auto* itr = byte_array.begin(); + const uint8_t first = *itr++; + const uint8_t second = *itr; // U+0080..U+07FF // 1st Byte: 0xC2..0xDF // 2nd Byte: 0x80..0xBF - if (uint8_t(0xC2u) <= first && first <= uint8_t(0xDFu)) { - if (0x80 <= second && second <= 0xBF) { + if (0xC2u <= first && first <= 0xDFu) { + if (0x80u <= second && second <= 0xBFu) { return true; } } @@ -1539,18 +1545,18 @@ inline bool validate(const std::initializer_list& byte_array) noexcept return false; } case 3: { - auto itr = byte_array.begin(); - uint8_t first = *itr++; - uint8_t second = *itr++; - uint8_t third = *itr; + const auto* itr = byte_array.begin(); + const uint8_t first = *itr++; + const uint8_t second = *itr++; + const uint8_t third = *itr; // U+1000..U+CFFF: // 1st Byte: 0xE0..0xEC // 2nd Byte: 0x80..0xBF // 3rd Byte: 0x80..0xBF - if (0xE0 <= first && first <= 0xEC) { - if (0x80 <= second && second <= 0xBF) { - if (0x80 <= third && third <= 0xBF) { + if (0xE0u <= first && first <= 0xECu) { + if (0x80u <= second && second <= 0xBFu) { + if (0x80u <= third && third <= 0xBFu) { return true; } } @@ -1561,9 +1567,9 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // 1st Byte: 0xED // 2nd Byte: 0x80..0x9F // 3rd Byte: 0x80..0xBF - if (first == 0xED) { - if (0x80 <= second && second <= 0x9F) { - if (0x80 <= third && third <= 0xBF) { + if (first == 0xEDu) { + if (0x80u <= second && second <= 0x9Fu) { + if (0x80u <= third && third <= 0xBFu) { return true; } } @@ -1574,9 +1580,9 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // 1st Byte: 0xEE..0xEF // 2nd Byte: 0x80..0xBF // 3rd Byte: 0x80..0xBF - if (first == 0xEE || first == 0xEF) { - if (0x80 <= second && second <= 0xBF) { - if (0x80 <= third && third <= 0xBF) { + if (first == 0xEEu || first == 0xEFu) { + if (0x80u <= second && second <= 0xBFu) { + if (0x80u <= third && third <= 0xBFu) { return true; } } @@ -1587,21 +1593,21 @@ inline bool validate(const std::initializer_list& byte_array) noexcept return false; } case 4: { - auto itr = byte_array.begin(); - uint8_t first = *itr++; - uint8_t second = *itr++; - uint8_t third = *itr++; - uint8_t fourth = *itr; + const auto* itr = byte_array.begin(); + const uint8_t first = *itr++; + const uint8_t second = *itr++; + const uint8_t third = *itr++; + const uint8_t fourth = *itr; // U+10000..U+3FFFF: // 1st Byte: 0xF0 // 2nd Byte: 0x90..0xBF // 3rd Byte: 0x80..0xBF // 4th Byte: 0x80..0xBF - if (first == 0xF0) { - if (0x90 <= second && second <= 0xBF) { - if (0x80 <= third && third <= 0xBF) { - if (0x80 <= fourth && fourth <= 0xBF) { + if (first == 0xF0u) { + if (0x90u <= second && second <= 0xBFu) { + if (0x80u <= third && third <= 0xBFu) { + if (0x80u <= fourth && fourth <= 0xBFu) { return true; } } @@ -1614,10 +1620,10 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // 2nd Byte: 0x80..0xBF // 3rd Byte: 0x80..0xBF // 4th Byte: 0x80..0xBF - if (0xF1 <= first && first <= 0xF3) { - if (0x80 <= second && second <= 0xBF) { - if (0x80 <= third && third <= 0xBF) { - if (0x80 <= fourth && fourth <= 0xBF) { + if (0xF1u <= first && first <= 0xF3u) { + if (0x80u <= second && second <= 0xBFu) { + if (0x80u <= third && third <= 0xBFu) { + if (0x80u <= fourth && fourth <= 0xBFu) { return true; } } @@ -1630,10 +1636,10 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // 2nd Byte: 0x80..0x8F // 3rd Byte: 0x80..0xBF // 4th Byte: 0x80..0xBF - if (first == 0xF4) { - if (0x80 <= second && second <= 0x8F) { - if (0x80 <= third && third <= 0xBF) { - if (0x80 <= fourth && fourth <= 0xBF) { + if (first == 0xF4u) { + if (0x80u <= second && second <= 0x8Fu) { + if (0x80u <= third && third <= 0xBFu) { + if (0x80u <= fourth && fourth <= 0xBFu) { return true; } } @@ -1654,51 +1660,45 @@ inline bool validate(const std::initializer_list& byte_array) noexcept /// @param[out] utf8 UTF-8 encoded bytes. /// @param[out] consumed_size The number of UTF-16 encoded characters used for the conversion. /// @param[out] encoded_size The size of UTF-encoded bytes. -inline void from_utf16( +inline void from_utf16( // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) std::array utf16, std::array& utf8, uint32_t& consumed_size, uint32_t& encoded_size) { - if (utf16[0] < char16_t(0x80u)) { + if (utf16[0] < 0x80u) { utf8[0] = static_cast(utf16[0] & 0x7Fu); consumed_size = 1; encoded_size = 1; - return; } - else if (utf16[0] <= char16_t(0x7FFu)) { - uint16_t utf8_chunk = static_cast(0xC080u) | static_cast((utf16[0] & 0x07C0u) << 2) | - static_cast(utf16[0] & 0x003Fu); + else if (utf16[0] <= 0x7FFu) { + const auto utf8_chunk = static_cast(0xC080u | ((utf16[0] & 0x07C0u) << 2) | (utf16[0] & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF00u) >> 8); utf8[1] = static_cast(utf8_chunk & 0x00FFu); consumed_size = 1; encoded_size = 2; - return; } - else if (utf16[0] < char16_t(0xD800u) || char16_t(0xE000u) <= utf16[0]) { - uint32_t utf8_chunk = static_cast(0xE08080u) | static_cast((utf16[0] & 0xF000u) << 4) | - static_cast((utf16[0] & 0x0FC0u) << 2) | - static_cast(utf16[0] & 0x003Fu); + else if (utf16[0] < 0xD800u || 0xE000u <= utf16[0]) { + const auto utf8_chunk = static_cast( + 0xE08080u | ((utf16[0] & 0xF000u) << 4) | ((utf16[0] & 0x0FC0u) << 2) | (utf16[0] & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF0000u) >> 16); utf8[1] = static_cast((utf8_chunk & 0x00FF00u) >> 8); utf8[2] = static_cast(utf8_chunk & 0x0000FFu); consumed_size = 1; encoded_size = 3; - return; } - else if (utf16[0] <= char16_t(0xDBFFu) && char16_t(0xDC00u) <= utf16[1] && utf16[1] <= char16_t(0xDFFFu)) { - // for surrogate pairs - uint32_t code_point = 0x10000u + ((utf16[0] & 0x03FFu) << 10) + (utf16[1] & 0x03FFu); - uint32_t utf8_chunk = - static_cast(0xF0808080u) | static_cast((code_point & 0x1C0000u) << 6) | - static_cast((code_point & 0x03F000u) << 4) | - static_cast((code_point & 0x000FC0u) << 2) | static_cast(code_point & 0x00003Fu); + else if (utf16[0] <= 0xDBFFu && 0xDC00u <= utf16[1] && utf16[1] <= 0xDFFFu) { + // surrogate pair + const uint32_t code_point = 0x10000u + ((utf16[0] & 0x03FFu) << 10) + (utf16[1] & 0x03FFu); + const auto utf8_chunk = static_cast( + 0xF0808080u | ((code_point & 0x1C0000u) << 6) | ((code_point & 0x03F000u) << 4) | + ((code_point & 0x0FC0u) << 2) | (code_point & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF000000u) >> 24); utf8[1] = static_cast((utf8_chunk & 0x00FF0000u) >> 16); utf8[2] = static_cast((utf8_chunk & 0x0000FF00u) >> 8); utf8[3] = static_cast(utf8_chunk & 0x000000FFu); consumed_size = 2; encoded_size = 4; - return; } - - throw invalid_encoding("Invalid UTF-16 encoding detected.", utf16); + else { + throw invalid_encoding("Invalid UTF-16 encoding detected.", utf16); + } } /// @brief Converts a UTF-32 encoded character to UTF-8 encoded bytes. @@ -1706,42 +1706,37 @@ inline void from_utf16( /// @param[out] utf8 UTF-8 encoded bytes. /// @param[in] encoded_size The size of UTF-encoded bytes. inline void from_utf32(const char32_t utf32, std::array& utf8, uint32_t& encoded_size) { - if (utf32 < char32_t(0x80u)) { + if (utf32 < 0x80u) { utf8[0] = static_cast(utf32 & 0x007F); encoded_size = 1; - return; } - else if (utf32 <= char32_t(0x7FFu)) { - uint16_t utf8_chunk = static_cast(0xC080u) | static_cast((utf32 & 0x07C0u) << 2) | - static_cast(utf32 & 0x003Fu); + else if (utf32 <= 0x7FFu) { + const auto utf8_chunk = static_cast(0xC080u | ((utf32 & 0x07C0u) << 2) | (utf32 & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF00u) >> 8); utf8[1] = static_cast(utf8_chunk & 0x00FFu); encoded_size = 2; - return; } - else if (utf32 <= char32_t(0xFFFFu)) { - uint32_t utf8_chunk = static_cast(0xE08080u) | static_cast((utf32 & 0xF000u) << 4) | - static_cast((utf32 & 0x0FC0u) << 2) | static_cast(utf32 & 0x003F); + else if (utf32 <= 0xFFFFu) { + const auto utf8_chunk = + static_cast(0xE08080u | ((utf32 & 0xF000u) << 4) | ((utf32 & 0x0FC0u) << 2) | (utf32 & 0x3F)); utf8[0] = static_cast((utf8_chunk & 0xFF0000u) >> 16); utf8[1] = static_cast((utf8_chunk & 0x00FF00u) >> 8); utf8[2] = static_cast(utf8_chunk & 0x0000FFu); encoded_size = 3; - return; } - else if (utf32 <= char32_t(0x10FFFFu)) { - uint32_t utf8_chunk = static_cast(0xF0808080u) | static_cast((utf32 & 0x1C0000u) << 6) | - static_cast((utf32 & 0x03F000u) << 4) | - static_cast((utf32 & 0x000FC0u) << 2) | - static_cast(utf32 & 0x00003Fu); + else if (utf32 <= 0x10FFFFu) { + const auto utf8_chunk = static_cast( + 0xF0808080u | ((utf32 & 0x1C0000u) << 6) | ((utf32 & 0x03F000u) << 4) | ((utf32 & 0x0FC0u) << 2) | + (utf32 & 0x3Fu)); utf8[0] = static_cast((utf8_chunk & 0xFF000000u) >> 24); utf8[1] = static_cast((utf8_chunk & 0x00FF0000u) >> 16); utf8[2] = static_cast((utf8_chunk & 0x0000FF00u) >> 8); utf8[3] = static_cast(utf8_chunk & 0x000000FFu); encoded_size = 4; - return; } - - throw invalid_encoding("Invalid UTF-32 encoding detected.", utf32); + else { + throw invalid_encoding("Invalid UTF-32 encoding detected.", utf32); + } } } // namespace utf8 @@ -1770,7 +1765,7 @@ FK_YAML_DETAIL_NAMESPACE_END FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of chomping indicator types. -enum class chomping_indicator_t { +enum class chomping_indicator_t : std::uint8_t { STRIP, //!< excludes final line breaks and trailing empty lines indicated by `-`. CLIP, //!< preserves final line breaks but excludes trailing empty lines. no indicator means this type. KEEP, //!< preserves final line breaks and trailing empty lines indicated by `+`. @@ -2129,8 +2124,9 @@ class basic_str_view { if (ret == 0) { using int_limits = std::numeric_limits; - difference_type diff = - m_len > sv.m_len ? m_len - sv.m_len : difference_type(-1) * difference_type(sv.m_len - m_len); + const difference_type diff = + m_len > sv.m_len ? m_len - sv.m_len + : static_cast(-1) * static_cast(sv.m_len - m_len); if (diff > int_limits::max()) { ret = int_limits::max(); @@ -2197,7 +2193,7 @@ class basic_str_view { /// @brief Checks if this character sequence starts with `sv` characters. /// @param sv The character sequence to compare with. /// @return true if the character sequence starts with `sv` characters, false otherwise. - bool starts_with(basic_str_view sv) const noexcept { + bool starts_with(basic_str_view sv) const { return substr(0, sv.size()) == sv; } @@ -2211,7 +2207,7 @@ class basic_str_view { /// @brief Checks if this character sequence starts with `s` characters. /// @param s The character sequence to compare with. /// @return true if the character sequence starts with `s` characters, false otherwise. - bool starts_with(const CharT* s) const noexcept { + bool starts_with(const CharT* s) const { return starts_with(basic_str_view(s)); } @@ -2259,6 +2255,8 @@ class basic_str_view { return find(s) != npos; } + // NOLINTBEGIN(bugprone-easily-swappable-parameters) + /// @brief Finds the beginning position of `sv` characters in this referenced character sequence. /// @param sv The character sequence to compare with. /// @param pos The offset of the search beginning position in this referenced character sequence. @@ -2331,6 +2329,8 @@ class basic_str_view { return find(basic_str_view(s), pos); } + // NOLINTEND(bugprone-easily-swappable-parameters) + /// @brief Retrospectively finds the beginning position of `sv` characters in this referenced character sequence. /// @param sv The character sequence to compare with. /// @param pos The offset of the search beginning position in this referenced character sequence. @@ -2348,16 +2348,13 @@ class basic_str_view { return npos; } - size_type idx = pos; - if (pos >= m_len) { - idx = m_len - 1; - } + const size_type idx = std::min(m_len - 1, pos); - do { - if (traits_type::eq(mp_str[idx], c)) { - return idx; + for (size_type i = 0; i <= idx; i++) { + if (traits_type::eq(mp_str[idx - i], c)) { + return idx - i; } - } while (idx > 0 && --idx < m_len); + } return npos; } @@ -2413,6 +2410,7 @@ class basic_str_view { /// @param pos The offset of the search beginning position in this referenced character sequence. /// @param n The length of `s` character sequence used for comparison. /// @return The beginning position of `s` characters, `npos` otherwise. + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) size_type find_first_of(const CharT* s, size_type pos, size_type n) const noexcept { if FK_YAML_UNLIKELY (n == 0) { return npos; @@ -2640,7 +2638,7 @@ inline bool operator==(const std::basic_string& lhs, basic_str_vi template inline bool operator==(basic_str_view lhs, const CharT (&rhs)[N]) noexcept { // assume `rhs` is null terminated - return lhs == basic_str_view(rhs, N - 1); + return lhs == basic_str_view(rhs); } /// @brief An equal-to operator of the basic_str_view class. @@ -2653,7 +2651,7 @@ inline bool operator==(basic_str_view lhs, const CharT (&rhs)[N]) template inline bool operator==(const CharT (&lhs)[N], basic_str_view rhs) noexcept { // assume `lhs` is null terminated - return basic_str_view(lhs, N - 1) == rhs; + return basic_str_view(lhs) == rhs; } /// @brief An not-equal-to operator of the basic_str_view class. @@ -2804,13 +2802,13 @@ class position_tracker { /// @note This function doesn't support cases where cur_pos has moved backward from the last call. /// @param cur_pos The iterator to the current element of the buffer. void update_position(const char* p_current) { - uint32_t diff = static_cast(p_current - m_last); + const auto diff = static_cast(p_current - m_last); if (diff == 0) { return; } m_cur_pos += diff; - uint32_t prev_lines_read = m_lines_read; + const uint32_t prev_lines_read = m_lines_read; m_lines_read += static_cast(std::count(m_last, p_current, '\n')); m_last = p_current; @@ -2881,13 +2879,15 @@ FK_YAML_DETAIL_NAMESPACE_END #ifndef FK_YAML_DETAIL_TYPES_LEXICAL_TOKEN_T_HPP #define FK_YAML_DETAIL_TYPES_LEXICAL_TOKEN_T_HPP +#include + // #include FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of lexical token types. -enum class lexical_token_t { +enum class lexical_token_t : std::uint8_t { END_OF_BUFFER, //!< the end of input buffer. EXPLICIT_KEY_PREFIX, //!< the character for explicit mapping key prefix `?`. KEY_SEPARATOR, //!< the key separator `:` @@ -2926,20 +2926,16 @@ struct lexical_token { /// Lexical token type. lexical_token_t type {lexical_token_t::END_OF_BUFFER}; /// Lexical token contents. - str_view str {}; + str_view str; }; -namespace { - -// whether the current context is flow(1) or block(0) -const uint32_t flow_context_bit = 1u << 0u; -// whether the current document part is directive(1) or content(0) -const uint32_t document_directive_bit = 1u << 1u; - -} // anonymous namespace - /// @brief A class which lexically analyzes YAML formatted inputs. class lexical_analyzer { + // whether the current context is flow(1) or block(0) + static constexpr uint32_t flow_context_bit = 1u << 0u; + // whether the current document part is directive(1) or content(0) + static constexpr uint32_t document_directive_bit = 1u << 1u; + public: /// @brief Construct a new lexical_analyzer object. /// @param input_buffer An input buffer. @@ -3013,7 +3009,7 @@ class lexical_analyzer { return token; case '&': { // anchor prefix extract_anchor_name(token); - bool is_empty = token.str.empty(); + const bool is_empty = token.str.empty(); if FK_YAML_UNLIKELY (is_empty) { emit_error("anchor name must not be empty."); } @@ -3023,7 +3019,7 @@ class lexical_analyzer { } case '*': { // alias prefix extract_anchor_name(token); - bool is_empty = token.str.empty(); + const bool is_empty = token.str.empty(); if FK_YAML_UNLIKELY (is_empty) { emit_error("anchor name must not be empty."); } @@ -3047,7 +3043,7 @@ class lexical_analyzer { // See https://yaml.org/spec/1.2.2/#912-document-markers for more details. break; case '-': { - char next = *(m_cur_itr + 1); + const char next = *(m_cur_itr + 1); switch (next) { case ' ': case '\t': @@ -3060,9 +3056,9 @@ class lexical_analyzer { break; } - bool is_available = ((m_end_itr - m_cur_itr) > 2); + const bool is_available = ((m_end_itr - m_cur_itr) > 2); if (is_available) { - bool is_dir_end = std::equal(m_token_begin_itr, m_cur_itr + 3, "---"); + const bool is_dir_end = std::equal(m_token_begin_itr, m_cur_itr + 3, "---"); if (is_dir_end) { m_cur_itr += 3; token.type = lexical_token_t::END_OF_DIRECTIVES; @@ -3105,9 +3101,9 @@ class lexical_analyzer { check_scalar_content(token.str); return token; case '.': { - bool is_available = ((m_end_itr - m_cur_itr) > 2); + const bool is_available = ((m_end_itr - m_cur_itr) > 2); if (is_available) { - bool is_doc_end = std::equal(m_cur_itr, m_cur_itr + 3, "..."); + const bool is_doc_end = std::equal(m_cur_itr, m_cur_itr + 3, "..."); if (is_doc_end) { m_cur_itr += 3; token.type = lexical_token_t::END_OF_DOCUMENT; @@ -3118,14 +3114,14 @@ class lexical_analyzer { } case '|': case '>': { - str_view sv {m_token_begin_itr, m_end_itr}; - std::size_t header_end_pos = sv.find('\n'); + const str_view sv {m_token_begin_itr, m_end_itr}; + const std::size_t header_end_pos = sv.find('\n'); FK_YAML_ASSERT(!sv.empty()); token.type = (sv[0] == '|') ? lexical_token_t::BLOCK_LITERAL_SCALAR : lexical_token_t::BLOCK_FOLDED_SCALAR; FK_YAML_ASSERT(header_end_pos != str_view::npos); - str_view header_line = sv.substr(1, header_end_pos - 1); + 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); @@ -3228,7 +3224,7 @@ class lexical_analyzer { } } - str_view dir_name(m_token_begin_itr, m_cur_itr); + const str_view dir_name(m_token_begin_itr, m_cur_itr); if (dir_name == "TAG") { if FK_YAML_UNLIKELY (!ends_loop) { @@ -3292,7 +3288,7 @@ class lexical_analyzer { ends_loop = true; break; } - char next = *(m_cur_itr + 1); + const char next = *(m_cur_itr + 1); if FK_YAML_UNLIKELY (next != ' ' && next != '\t') { emit_error("invalid tag handle is found."); } @@ -3336,6 +3332,8 @@ class lexical_analyzer { case '{': case '}': emit_error("tag prefix must not start with flow indicators (\',\', [], {})."); + default: + break; } // extract the rest of a tag prefix. @@ -3347,10 +3345,12 @@ class lexical_analyzer { case '\n': ends_loop = true; break; + default: + break; } } while (!ends_loop && ++m_cur_itr != m_end_itr); - bool is_valid = uri_encoding::validate(p_tag_prefix_begin, m_cur_itr); + const bool is_valid = uri_encoding::validate(p_tag_prefix_begin, m_cur_itr); if FK_YAML_UNLIKELY (!is_valid) { emit_error("invalid URI character is found in a tag prefix."); } @@ -3488,18 +3488,18 @@ class lexical_analyzer { token.str = str_view {m_token_begin_itr, m_cur_itr}; if (is_verbatim) { - char last = token.str.back(); + const char last = token.str.back(); if FK_YAML_UNLIKELY (last != '>') { emit_error("verbatim tag (!) must be ended with \'>\'."); } // only the `TAG` part of the `!` for URI validation. - str_view tag_body = token.str.substr(2, token.str.size() - 3); + const str_view tag_body = token.str.substr(2, token.str.size() - 3); if FK_YAML_UNLIKELY (tag_body.empty()) { emit_error("verbatim tag(!) must not be empty."); } - bool is_valid_uri = uri_encoding::validate(tag_body.begin(), tag_body.end()); + const bool is_valid_uri = uri_encoding::validate(tag_body.begin(), tag_body.end()); if FK_YAML_UNLIKELY (!is_valid_uri) { emit_error("invalid URI character is found in a verbatim tag."); } @@ -3508,7 +3508,7 @@ class lexical_analyzer { } if (is_named_handle) { - char last = token.str.back(); + const char last = token.str.back(); if FK_YAML_UNLIKELY (last == '!') { // Tag shorthand must be followed by a non-empty suffix. // See the "Tag Shorthands" section in https://yaml.org/spec/1.2.2/#691-node-tags. @@ -3518,18 +3518,18 @@ class lexical_analyzer { // get the position of last tag prefix character (!) to extract body of tag shorthands. // tag shorthand is either primary(!tag), secondary(!!tag) or named(!handle!tag). - std::size_t last_tag_prefix_pos = token.str.find_last_of('!'); + const std::size_t last_tag_prefix_pos = token.str.find_last_of('!'); FK_YAML_ASSERT(last_tag_prefix_pos != str_view::npos); - str_view tag_uri = token.str.substr(last_tag_prefix_pos + 1); - bool is_valid_uri = uri_encoding::validate(tag_uri.begin(), tag_uri.end()); + const str_view tag_uri = token.str.substr(last_tag_prefix_pos + 1); + const bool is_valid_uri = uri_encoding::validate(tag_uri.begin(), tag_uri.end()); if FK_YAML_UNLIKELY (!is_valid_uri) { emit_error("Invalid URI character is found in a named tag handle."); } // Tag shorthands cannot contain flow indicators({}[],). // See the "Tag Shorthands" section in https://yaml.org/spec/1.2.2/#691-node-tags. - std::size_t invalid_char_pos = tag_uri.find_first_of("{}[],"); + const std::size_t invalid_char_pos = tag_uri.find_first_of("{}[],"); if (invalid_char_pos != str_view::npos) { emit_error("Tag shorthand cannot contain flow indicators({}[],)."); } @@ -3538,7 +3538,7 @@ class lexical_analyzer { /// @brief Determines the range of single quoted scalar by scanning remaining input buffer contents. /// @param token Storage for the range of single quoted scalar. void determine_single_quoted_scalar_range(str_view& token) { - str_view sv {m_token_begin_itr, m_end_itr}; + const str_view sv {m_token_begin_itr, m_end_itr}; std::size_t pos = sv.find('\''); while (pos != str_view::npos) { @@ -3563,7 +3563,7 @@ class lexical_analyzer { /// @brief Determines the range of double quoted scalar by scanning remaining input buffer contents. /// @param token Storage for the range of double quoted scalar. void determine_double_quoted_scalar_range(str_view& token) { - str_view sv {m_token_begin_itr, m_end_itr}; + const str_view sv {m_token_begin_itr, m_end_itr}; std::size_t pos = sv.find('\"'); while (pos != str_view::npos) { @@ -3604,7 +3604,7 @@ class lexical_analyzer { /// @brief Determines the range of plain scalar by scanning remaining input buffer contents. /// @param token Storage for the range of plain scalar. void determine_plain_scalar_range(str_view& token) { - str_view sv {m_token_begin_itr, m_end_itr}; + const str_view sv {m_token_begin_itr, m_end_itr}; constexpr str_view filter = "\n :{}[],"; std::size_t pos = sv.find_first_of(filter); @@ -3695,11 +3695,11 @@ class lexical_analyzer { /// @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) { - str_view sv {m_token_begin_itr, m_end_itr}; + const str_view sv {m_token_begin_itr, m_end_itr}; // Handle leading all-space lines. constexpr str_view space_filter = " \t\n"; - std::size_t first_non_space_pos = sv.find_first_not_of(space_filter); + 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()); @@ -3715,19 +3715,17 @@ class lexical_analyzer { 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. - uint32_t cur_indent = static_cast(first_non_space_pos); + 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."); } - - last_newline_pos = 0; } else { FK_YAML_ASSERT(last_newline_pos < first_non_space_pos); - uint32_t cur_indent = static_cast(first_non_space_pos - last_newline_pos - 1); + 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) { @@ -3749,14 +3747,14 @@ class lexical_analyzer { cur_line_end_pos = sv.size(); } - std::size_t cur_line_content_begin_pos = sv.find_first_not_of(' ', last_newline_pos + 1); + const std::size_t cur_line_content_begin_pos = sv.find_first_not_of(' ', last_newline_pos + 1); if (cur_line_content_begin_pos == str_view::npos) { last_newline_pos = cur_line_end_pos; continue; } FK_YAML_ASSERT(last_newline_pos < cur_line_content_begin_pos); - uint32_t cur_indent = static_cast(cur_line_content_begin_pos - last_newline_pos - 1); + 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') { // Interpret less indented non-space characters as the start of the next token. break; @@ -3842,6 +3840,8 @@ class lexical_analyzer { emit_error("Control character U+001E (RS) must be escaped to \\u001E."); case 0x1F: emit_error("Control character U+001F (US) must be escaped to \\u001F."); + default: + break; } } @@ -3859,9 +3859,9 @@ class lexical_analyzer { /// @param chomp_type A variable to store the retrieved chomping style type. /// @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) { + block_scalar_header convert_to_block_scalar_header(str_view line) { constexpr str_view comment_prefix = " #"; - std::size_t comment_begin_pos = line.find(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); } @@ -3899,7 +3899,7 @@ class lexical_analyzer { if FK_YAML_UNLIKELY (header.indent > 0) { emit_error("Invalid indentation level for a block scalar. It must be between 1 and 9."); } - header.indent = static_cast(c - '0'); + header.indent = static_cast(c - '0'); break; case ' ': case '\t': @@ -3956,7 +3956,7 @@ class lexical_analyzer { private: /// An input buffer adapter to be analyzed. - str_view m_input_buffer {}; + str_view m_input_buffer; /// The iterator to the current character in the input buffer. const char* m_cur_itr {}; /// The iterator to the beginning of the current token. @@ -3966,11 +3966,11 @@ class lexical_analyzer { /// The current position tracker of the input buffer. mutable position_tracker m_pos_tracker {}; /// The last yaml version. - str_view m_yaml_version {}; + str_view m_yaml_version; /// The last tag handle. - str_view m_tag_handle {}; + str_view m_tag_handle; /// The last tag prefix. - str_view m_tag_prefix {}; + str_view m_tag_prefix; /// The last block scalar header. block_scalar_header m_block_scalar_header {}; /// The beginning position of the last lexical token. (zero origin) @@ -4019,6 +4019,7 @@ FK_YAML_DETAIL_NAMESPACE_END #define FK_YAML_CONVERSIONS_SCALAR_CONV_HPP #include +#include #include #include @@ -4357,7 +4358,7 @@ inline bool aton(CharItr begin, CharItr end, std::nullptr_t& /*unused*/) noexcep return false; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); // This path is the most probable case, so check it first. if FK_YAML_LIKELY (len == 4) { @@ -4392,27 +4393,27 @@ inline bool atob(CharItr begin, CharItr end, BoolType& boolean) noexcept { return false; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); const char* p_begin = &*begin; if (len == 4) { - bool is_true_scalar = (std::strncmp(p_begin, "true", 4) == 0) || (std::strncmp(p_begin, "True", 4) == 0) || - (std::strncmp(p_begin, "TRUE", 4) == 0); + const bool is_true = (std::strncmp(p_begin, "true", 4) == 0) || (std::strncmp(p_begin, "True", 4) == 0) || + (std::strncmp(p_begin, "TRUE", 4) == 0); - if FK_YAML_LIKELY (is_true_scalar) { + if FK_YAML_LIKELY (is_true) { boolean = static_cast(true); } - return is_true_scalar; + return is_true; } if (len == 5) { - bool is_false_scalar = (std::strncmp(p_begin, "false", 5) == 0) || (std::strncmp(p_begin, "False", 5) == 0) || - (std::strncmp(p_begin, "FALSE", 5) == 0); + const bool is_false = (std::strncmp(p_begin, "false", 5) == 0) || (std::strncmp(p_begin, "False", 5) == 0) || + (std::strncmp(p_begin, "FALSE", 5) == 0); - if FK_YAML_LIKELY (is_false_scalar) { + if FK_YAML_LIKELY (is_false) { boolean = static_cast(false); } - return is_false_scalar; + return is_false; } return false; @@ -4444,7 +4445,7 @@ inline bool atoi_dec_unchecked(const char* p_begin, const char* p_end, IntType& i = 0; do { - char c = *p_begin; + const char c = *p_begin; if FK_YAML_UNLIKELY (c < '0' || '9' < c) { return false; } @@ -4473,7 +4474,7 @@ inline bool atoi_dec_pos(const char* p_begin, const char* p_end, IntType& i) noe using conv_limits_type = conv_limits::value>; - std::size_t len = static_cast(p_end - p_begin); + const auto len = static_cast(p_end - p_begin); if FK_YAML_UNLIKELY (len > conv_limits_type::max_chars_dec) { // Overflow will happen. return false; @@ -4516,7 +4517,7 @@ inline bool atoi_dec_neg(const char* p_begin, const char* p_end, IntType& i) noe using conv_limits_type = conv_limits::value>; - std::size_t len = static_cast(p_end - p_begin); + const auto len = static_cast(p_end - p_begin); if FK_YAML_UNLIKELY (len > conv_limits_type::max_chars_dec) { // Underflow will happen. return false; @@ -4563,14 +4564,14 @@ inline bool atoi_oct(const char* p_begin, const char* p_end, IntType& i) noexcep using conv_limits_type = conv_limits::value>; - std::size_t len = static_cast(p_end - p_begin); + const auto len = static_cast(p_end - p_begin); if FK_YAML_UNLIKELY (!conv_limits_type::check_if_octs_safe(p_begin, len)) { return false; } i = 0; do { - char c = *p_begin; + const char c = *p_begin; if FK_YAML_UNLIKELY (c < '0' || '7' < c) { return false; } @@ -4602,14 +4603,15 @@ inline bool atoi_hex(const char* p_begin, const char* p_end, IntType& i) noexcep using conv_limits_type = conv_limits::value>; - std::size_t len = static_cast(p_end - p_begin); + const auto len = static_cast(p_end - p_begin); if FK_YAML_UNLIKELY (!conv_limits_type::check_if_hexs_safe(p_begin, len)) { return false; } i = 0; do { - char c = *p_begin; + // NOLINTBEGIN(bugprone-misplaced-widening-cast) + const char c = *p_begin; IntType ci = 0; if ('0' <= c && c <= '9') { ci = IntType(c - '0'); @@ -4624,6 +4626,7 @@ inline bool atoi_hex(const char* p_begin, const char* p_end, IntType& i) noexcep return false; } i = i * IntType(16) + ci; + // NOLINTEND(bugprone-misplaced-widening-cast) } while (++p_begin != p_end); return true; @@ -4649,11 +4652,11 @@ inline bool atoi(CharItr begin, CharItr end, IntType& i) noexcept { return false; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); const char* p_begin = &*begin; const char* p_end = p_begin + len; - char first = *begin; + const char first = *begin; if (first == '+') { return atoi_dec_pos(p_begin + 1, p_end, i); } @@ -4663,7 +4666,7 @@ inline bool atoi(CharItr begin, CharItr end, IntType& i) noexcept { return false; } - bool success = atoi_dec_neg(p_begin + 1, p_end, i); + const bool success = atoi_dec_neg(p_begin + 1, p_end, i); if (success) { i *= IntType(-1); } @@ -4674,7 +4677,8 @@ inline bool atoi(CharItr begin, CharItr end, IntType& i) noexcept { if (first != '0') { return atoi_dec_pos(p_begin, p_end, i); } - else if (p_begin + 1 != p_end) { + + if (p_begin + 1 != p_end) { switch (*(p_begin + 1)) { case 'o': return atoi_oct(p_begin + 2, p_end, i); @@ -4781,18 +4785,17 @@ inline bool atof(CharItr begin, CharItr end, FloatType& f) noexcept(noexcept(ato return false; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); const char* p_begin = &*begin; const char* p_end = p_begin + len; if (*p_begin == '-' || *p_begin == '+') { if (len == 5) { const char* p_from_second = p_begin + 1; - bool is_inf_scalar = (std::strncmp(p_from_second, ".inf", 4) == 0) || - (std::strncmp(p_from_second, ".Inf", 4) == 0) || - (std::strncmp(p_from_second, ".INF", 4) == 0); - - if (is_inf_scalar) { + const bool is_inf = (std::strncmp(p_from_second, ".inf", 4) == 0) || + (std::strncmp(p_from_second, ".Inf", 4) == 0) || + (std::strncmp(p_from_second, ".INF", 4) == 0); + if (is_inf) { set_infinity(f, *p_begin == '-' ? FloatType(-1.) : FloatType(1.)); return true; } @@ -4804,20 +4807,16 @@ inline bool atof(CharItr begin, CharItr end, FloatType& f) noexcept(noexcept(ato } } else if (len == 4) { - bool is_inf_scalar = (std::strncmp(p_begin, ".inf", 4) == 0) || (std::strncmp(p_begin, ".Inf", 4) == 0) || - (std::strncmp(p_begin, ".INF", 4) == 0); - bool is_nan_scalar = false; - if (!is_inf_scalar) { - is_nan_scalar = (std::strncmp(p_begin, ".nan", 4) == 0) || (std::strncmp(p_begin, ".NaN", 4) == 0) || - (std::strncmp(p_begin, ".NAN", 4) == 0); - } - - if (is_inf_scalar) { + const bool is_inf = (std::strncmp(p_begin, ".inf", 4) == 0) || (std::strncmp(p_begin, ".Inf", 4) == 0) || + (std::strncmp(p_begin, ".INF", 4) == 0); + if (is_inf) { set_infinity(f, FloatType(1.)); return true; } - if (is_nan_scalar) { + const bool is_nan = (std::strncmp(p_begin, ".nan", 4) == 0) || (std::strncmp(p_begin, ".NaN", 4) == 0) || + (std::strncmp(p_begin, ".NAN", 4) == 0); + if (is_nan) { set_nan(f); return true; } @@ -4883,7 +4882,7 @@ class yaml_escaper { buff.push_back('\b'); break; case 't': - case char(0x09): + case '\t': buff.push_back('\t'); break; case 'n': @@ -4899,7 +4898,7 @@ class yaml_escaper { buff.push_back('\r'); break; case 'e': - buff.push_back(char(0x1B)); + buff.push_back(static_cast(0x1B)); break; case ' ': buff.push_back(' '); @@ -5096,15 +5095,15 @@ class yaml_escaper { is_escaped = true; break; default: - int diff = static_cast(std::distance(begin, end)); + const std::ptrdiff_t diff = static_cast(std::distance(begin, end)); if (diff > 1) { - if (*begin == char(0xC2u) && *(begin + 1) == char(0x85u)) { + if (*begin == static_cast(0xC2u) && *(begin + 1) == static_cast(0x85u)) { escaped += "\\N"; std::advance(begin, 1); is_escaped = true; break; } - else if (*begin == char(0xC2u) && *(begin + 1) == char(0xA0u)) { + if (*begin == static_cast(0xC2u) && *(begin + 1) == static_cast(0xA0u)) { escaped += "\\_"; std::advance(begin, 1); is_escaped = true; @@ -5112,13 +5111,15 @@ class yaml_escaper { } if (diff > 2) { - if (*begin == char(0xE2u) && *(begin + 1) == char(0x80u) && *(begin + 2) == char(0xA8u)) { + if (*begin == static_cast(0xE2u) && *(begin + 1) == static_cast(0x80u) && + *(begin + 2) == static_cast(0xA8u)) { escaped += "\\L"; std::advance(begin, 2); is_escaped = true; break; } - if (*begin == char(0xE2u) && *(begin + 1) == char(0x80u) && *(begin + 2) == char(0xA9u)) { + if (*begin == static_cast(0xE2u) && *(begin + 1) == static_cast(0x80u) && + *(begin + 2) == static_cast(0xA9u)) { escaped += "\\P"; std::advance(begin, 2); is_escaped = true; @@ -5137,7 +5138,7 @@ class yaml_escaper { static bool convert_hexchar_to_byte(char source, uint8_t& byte) { if ('0' <= source && source <= '9') { // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) - byte = static_cast(source - char('0')); + byte = static_cast(source - '0'); return true; } @@ -5158,17 +5159,17 @@ class yaml_escaper { } static bool extract_codepoint(const char*& begin, const char* end, int bytes_to_read, char32_t& codepoint) { - bool has_enough_room = static_cast(std::distance(begin, end)) >= (bytes_to_read - 1); + const bool has_enough_room = static_cast(std::distance(begin, end)) >= (bytes_to_read - 1); if (!has_enough_room) { return false; } - int read_size = bytes_to_read * 2; + const int read_size = bytes_to_read * 2; uint8_t byte {0}; codepoint = 0; for (int i = read_size - 1; i >= 0; i--) { - bool is_valid = convert_hexchar_to_byte(*++begin, byte); + const bool is_valid = convert_hexchar_to_byte(*++begin, byte); if (!is_valid) { return false; } @@ -5217,26 +5218,6 @@ FK_YAML_DETAIL_NAMESPACE_END FK_YAML_DETAIL_NAMESPACE_BEGIN -namespace { - -/// @brief Check if the given character is a digit. -/// @note This function is needed to avoid assertion failures in `std::isdigit()` especially when compiled with MSVC. -/// @param c A character to be checked. -/// @return true if the given character is a digit, false otherwise. -inline bool is_digit(char c) { - return ('0' <= c && c <= '9'); -} - -/// @brief Check if the given character is a hex-digit. -/// @note This function is needed to avoid assertion failures in `std::isxdigit()` especially when compiled with MSVC. -/// @param c A character to be checked. -/// @return true if the given character is a hex-digit, false otherwise. -inline bool is_xdigit(char c) { - return (('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')); -} - -} // namespace - /// @brief The class which detects a scalar value type by scanning contents. class scalar_scanner { public: @@ -5249,7 +5230,7 @@ class scalar_scanner { return node_type::STRING; } - uint32_t len = static_cast(std::distance(begin, end)); + const auto len = static_cast(std::distance(begin, end)); if (len > 5) { return scan_possible_number_token(begin, len); } @@ -5282,7 +5263,7 @@ class scalar_scanner { : node_type::STRING; case '.': { const char* p_from_second = p_begin + 1; - bool is_inf_or_nan_scalar = + const bool is_inf_or_nan_scalar = (std::strncmp(p_from_second, "inf", 3) == 0) || (std::strncmp(p_from_second, "Inf", 3) == 0) || (std::strncmp(p_from_second, "INF", 3) == 0) || (std::strncmp(p_from_second, "nan", 3) == 0) || (std::strncmp(p_from_second, "NaN", 3) == 0) || (std::strncmp(p_from_second, "NAN", 3) == 0); @@ -5292,6 +5273,8 @@ class scalar_scanner { // maybe a number. break; } + default: + break; } break; case 5: @@ -5308,17 +5291,21 @@ class scalar_scanner { case '-': if (*(p_begin + 1) == '.') { const char* p_from_third = p_begin + 2; - bool is_min_inf_scalar = (std::strncmp(p_from_third, "inf", 3) == 0) || - (std::strncmp(p_from_third, "Inf", 3) == 0) || - (std::strncmp(p_from_third, "INF", 3) == 0); - if (is_min_inf_scalar) { + const bool is_min_inf = (std::strncmp(p_from_third, "inf", 3) == 0) || + (std::strncmp(p_from_third, "Inf", 3) == 0) || + (std::strncmp(p_from_third, "INF", 3) == 0); + if (is_min_inf) { return node_type::FLOAT; } } // maybe a number. break; + default: + break; } break; + default: + break; } return scan_possible_number_token(begin, len); @@ -5439,7 +5426,7 @@ class scalar_scanner { FK_YAML_ASSERT(len > 0); for (uint32_t i = 0; i < len; i++) { - char c = *itr++; + const char c = *itr++; if (is_digit(c)) { continue; @@ -5466,7 +5453,7 @@ class scalar_scanner { static node_type scan_after_exponent(const char* itr, uint32_t len) noexcept { FK_YAML_ASSERT(len > 0); - char c = *itr; + const char c = *itr; if (c == '+' || c == '-') { if (len == 1) { // some integer(s) required after the sign. @@ -5519,6 +5506,24 @@ class scalar_scanner { } return node_type::STRING; } + + /// @brief Check if the given character is a digit. + /// @note This function is needed to avoid assertion failures in `std::isdigit()` especially when compiled with + /// MSVC. + /// @param c A character to be checked. + /// @return true if the given character is a digit, false otherwise. + static bool is_digit(char c) { + return ('0' <= c && c <= '9'); + } + + /// @brief Check if the given character is a hex-digit. + /// @note This function is needed to avoid assertion failures in `std::isxdigit()` especially when compiled with + /// MSVC. + /// @param c A character to be checked. + /// @return true if the given character is a hex-digit, false otherwise. + static bool is_xdigit(char c) { + return (('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')); + } }; FK_YAML_DETAIL_NAMESPACE_END @@ -5537,13 +5542,15 @@ FK_YAML_DETAIL_NAMESPACE_END #ifndef FK_YAML_DETAIL_INPUT_TAG_T_HPP #define FK_YAML_DETAIL_INPUT_TAG_T_HPP +#include + // #include FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of YAML tag types. -enum class tag_t { +enum class tag_t : std::uint8_t { NONE, //!< Represents a non-specific tag "?". NON_SPECIFIC, //!< Represents a non-specific tag "!". CUSTOM_TAG, //!< Represents a custom tag @@ -5596,7 +5603,7 @@ class scalar_parser { /// @brief Constructs a new scalar_parser object. /// @param line Current line. /// @param indent Current indentation. - scalar_parser(uint32_t line, uint32_t indent) noexcept + scalar_parser(uint32_t line, uint32_t indent) noexcept // NOLINT(bugprone-easily-swappable-parameters) : m_line(line), m_indent(indent) { } @@ -5623,7 +5630,7 @@ class scalar_parser { FK_YAML_ASSERT(tag_type != tag_t::SEQUENCE && tag_type != tag_t::MAPPING); token = parse_flow_scalar_token(lex_type, token); - node_type value_type = decide_value_type(lex_type, tag_type, token); + const node_type value_type = decide_value_type(lex_type, tag_type, token); return create_scalar_node(value_type, token); } @@ -5646,7 +5653,7 @@ class scalar_parser { token = parse_block_folded_scalar(token, header); } - node_type value_type = decide_value_type(lex_type, tag_type, token); + const node_type value_type = decide_value_type(lex_type, tag_type, token); return create_scalar_node(value_type, token); } @@ -5746,7 +5753,7 @@ class scalar_parser { if (token[pos + 1] != '\n') { token.remove_prefix(pos); const char* p_escape_begin = token.begin(); - bool is_valid_escaping = yaml_escaper::unescape(p_escape_begin, token.end(), m_buffer); + const bool is_valid_escaping = yaml_escaper::unescape(p_escape_begin, token.end(), m_buffer); if FK_YAML_UNLIKELY (!is_valid_escaping) { throw parse_error( "Unsupported escape sequence is found in a double quoted scalar.", m_line, m_indent); @@ -5798,8 +5805,8 @@ class scalar_parser { cur_line_end_pos = token.size(); } - std::size_t line_size = cur_line_end_pos - cur_line_begin_pos; - str_view line = token.substr(cur_line_begin_pos, line_size); + 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); if (line.size() > header.indent) { m_buffer.append(line.begin() + header.indent, line.end()); @@ -5840,8 +5847,8 @@ class scalar_parser { cur_line_end_pos = token.size(); } - std::size_t line_size = cur_line_end_pos - cur_line_begin_pos; - str_view line = token.substr(cur_line_begin_pos, line_size); + 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); if (line.size() <= header.indent) { // empty or less-indented lines are turned into a newline @@ -5849,8 +5856,8 @@ class scalar_parser { can_be_folded = false; } else { - std::size_t non_space_pos = line.find_first_not_of(' '); - bool is_more_indented = (non_space_pos != str_view::npos) && (non_space_pos > header.indent); + const std::size_t non_space_pos = line.find_first_not_of(' '); + const bool is_more_indented = (non_space_pos != str_view::npos) && (non_space_pos > header.indent); if (can_be_folded) { if (is_more_indented) { @@ -5897,7 +5904,7 @@ class scalar_parser { void process_chomping(chomping_indicator_t chomp) { switch (chomp) { case chomping_indicator_t::STRIP: { - std::size_t content_end_pos = m_buffer.find_last_not_of('\n'); + const std::size_t content_end_pos = m_buffer.find_last_not_of('\n'); if (content_end_pos == std::string::npos) { // if the scalar has no content line, all lines are considered as trailing empty lines. m_buffer.clear(); @@ -5915,7 +5922,7 @@ class scalar_parser { break; } case chomping_indicator_t::CLIP: { - std::size_t content_end_pos = m_buffer.find_last_not_of('\n'); + const std::size_t content_end_pos = m_buffer.find_last_not_of('\n'); if (content_end_pos == std::string::npos) { // if the scalar has no content line, all lines are considered as trailing empty lines. m_buffer.clear(); @@ -5942,7 +5949,7 @@ class scalar_parser { /// @param newline_pos Position of the target newline code. void process_line_folding(str_view& token, std::size_t newline_pos) noexcept { // discard trailing white spaces which precedes the line break in the current line. - std::size_t last_non_space_pos = token.substr(0, newline_pos + 1).find_last_not_of(" \t"); + const std::size_t last_non_space_pos = token.substr(0, newline_pos + 1).find_last_not_of(" \t"); if (last_non_space_pos == str_view::npos) { m_buffer.append(token.begin(), newline_pos); } @@ -5953,13 +5960,13 @@ class scalar_parser { uint32_t empty_line_counts = 0; do { - std::size_t non_space_pos = token.find_first_not_of(" \t"); + const std::size_t non_space_pos = token.find_first_not_of(" \t"); if (non_space_pos == str_view::npos) { // Line folding ignores trailing spaces. token.remove_prefix(token.size()); break; } - else if (token[non_space_pos] != '\n') { + if (token[non_space_pos] != '\n') { token.remove_prefix(non_space_pos); break; } @@ -6001,8 +6008,6 @@ class scalar_parser { value_type = node_type::FLOAT; break; case tag_t::STRING: - value_type = node_type::STRING; - break; case tag_t::NON_SPECIFIC: // scalars with the non-specific tag is resolved to a string tag. // See the "Non-Specific Tags" section in https://yaml.org/spec/1.2.2/#691-node-tags. @@ -6027,7 +6032,7 @@ class scalar_parser { switch (type) { case node_type::NULL_OBJECT: { std::nullptr_t null = nullptr; - bool converted = detail::aton(token.begin(), token.end(), null); + 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); } @@ -6035,8 +6040,8 @@ class scalar_parser { break; } case node_type::BOOLEAN: { - boolean_type boolean = static_cast(false); - bool converted = detail::atob(token.begin(), token.end(), boolean); + auto boolean = static_cast(false); + const bool converted = detail::atob(token.begin(), token.end(), boolean); if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to a boolean.", m_line, m_indent); } @@ -6045,7 +6050,7 @@ class scalar_parser { } case node_type::INTEGER: { integer_type integer = 0; - bool converted = detail::atoi(token.begin(), token.end(), integer); + const bool converted = detail::atoi(token.begin(), token.end(), integer); if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to an integer.", m_line, m_indent); } @@ -6054,7 +6059,7 @@ class scalar_parser { } case node_type::FLOAT: { float_number_type float_val = 0; - bool converted = detail::atof(token.begin(), token.end(), float_val); + const bool converted = detail::atof(token.begin(), token.end(), float_val); if FK_YAML_UNLIKELY (!converted) { throw parse_error("Failed to convert a scalar to a floating point value", m_line, m_indent); } @@ -6084,7 +6089,7 @@ class scalar_parser { /// Whether the parsed contents are stored in an owned buffer. bool m_use_owned_buffer {false}; /// Owned buffer storage for parsing. This buffer is used when scalar contents need mutation. - std::string m_buffer {}; + std::string m_buffer; }; FK_YAML_DETAIL_NAMESPACE_END @@ -6105,7 +6110,6 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -#include // #include @@ -6117,18 +6121,15 @@ FK_YAML_DETAIL_NAMESPACE_END // #include +// #include + // #include FK_YAML_DETAIL_NAMESPACE_BEGIN -namespace /*default prefixes*/ -{ - -const std::string default_primary_handle_prefix = "!"; -const std::string default_secondary_handle_prefix = "tag:yaml.org,2002:"; - -} // namespace +static constexpr str_view default_primary_handle_prefix = "!"; +static constexpr str_view default_secondary_handle_prefix = "tag:yaml.org,2002:"; template class tag_resolver { @@ -6140,7 +6141,7 @@ class tag_resolver { /// @param tag The input tag name. /// @return The type of a node deduced from the given tag name. static tag_t resolve_tag(const std::string& tag, const std::shared_ptr& directives) { - std::string normalized = normalize_tag_name(tag, directives); + const std::string normalized = normalize_tag_name(tag, directives); return convert_to_tag_type(normalized); } @@ -6168,9 +6169,10 @@ class tag_resolver { switch (tag[1]) { case '!': { // handle a secondary tag handle (!!suffix -> !<[secondary][suffix]>) - bool is_null_or_empty = !directives || directives->secondary_handle_prefix.empty(); + const bool is_null_or_empty = !directives || directives->secondary_handle_prefix.empty(); if (is_null_or_empty) { - normalized += default_secondary_handle_prefix + tag.substr(2); + normalized.append(default_secondary_handle_prefix.begin(), default_secondary_handle_prefix.end()); + normalized += tag.substr(2); } else { normalized += directives->secondary_handle_prefix + tag.substr(2); @@ -6179,9 +6181,10 @@ class tag_resolver { } case '<': if (tag[2] == '!') { - bool is_null_or_empty = !directives || directives->primary_handle_prefix.empty(); + const bool is_null_or_empty = !directives || directives->primary_handle_prefix.empty(); if (is_null_or_empty) { - return normalized + default_primary_handle_prefix + tag.substr(3); + normalized.append(default_primary_handle_prefix.begin(), default_primary_handle_prefix.end()); + return normalized + tag.substr(3); } return normalized + directives->primary_handle_prefix + tag.substr(3); } @@ -6197,7 +6200,7 @@ class tag_resolver { // there must be a non-empty suffix. (already checked by the lexer.) FK_YAML_ASSERT(tag_end_pos < tag.size() - 1); - bool is_null_or_empty = !directives || directives->named_handle_map.empty(); + const bool is_null_or_empty = !directives || directives->named_handle_map.empty(); if FK_YAML_UNLIKELY (is_null_or_empty) { throw invalid_tag("named handle has not been registered.", tag.c_str()); } @@ -6214,14 +6217,15 @@ class tag_resolver { // See https://yaml.org/spec/1.2.2/#56-miscellaneous-characters for more details. normalized += named_handle_itr->second; - normalized.append(tag.begin() + (tag_end_pos + 1), tag.end()); + normalized.append(tag.begin() + (static_cast(tag_end_pos) + 1), tag.end()); break; } // handle a primary tag handle (!suffix -> !<[primary][suffix]>) - bool is_null_or_empty = !directives || directives->primary_handle_prefix.empty(); + const bool is_null_or_empty = !directives || directives->primary_handle_prefix.empty(); if (is_null_or_empty) { - normalized += default_primary_handle_prefix + tag.substr(1); + normalized.append(default_primary_handle_prefix.begin(), default_primary_handle_prefix.end()); + normalized += tag.substr(1); } else { normalized += directives->primary_handle_prefix + tag.substr(1); @@ -6419,17 +6423,17 @@ using node_attr_t = uint32_t; namespace node_attr_mask { /// The bit mask for node value type bits. -const node_attr_t value = 0x0000FFFFu; +constexpr node_attr_t value = 0x0000FFFFu; /// The bit mask for node style type bits. (bits are not yet defined.) -const node_attr_t style = 0x00FF0000u; +constexpr node_attr_t style = 0x00FF0000u; /// The bit mask for node property related bits. -const node_attr_t props = 0xFF000000u; +constexpr node_attr_t props = 0xFF000000u; /// The bit mask for anchor/alias node type bits. -const node_attr_t anchoring = 0x03000000u; +constexpr node_attr_t anchoring = 0x03000000u; /// The bit mask for anchor offset value bits. -const node_attr_t anchor_offset = 0xFC000000u; +constexpr node_attr_t anchor_offset = 0xFC000000u; /// The bit mask for all the bits for node attributes. -const node_attr_t all = std::numeric_limits::max(); +constexpr node_attr_t all = std::numeric_limits::max(); } // namespace node_attr_mask @@ -6437,30 +6441,30 @@ const node_attr_t all = std::numeric_limits::max(); namespace node_attr_bits { /// The sequence node bit. -const node_attr_t seq_bit = 1u << 0; +constexpr node_attr_t seq_bit = 1u << 0; /// The mapping node bit. -const node_attr_t map_bit = 1u << 1; +constexpr node_attr_t map_bit = 1u << 1; /// The null scalar node bit. -const node_attr_t null_bit = 1u << 2; +constexpr node_attr_t null_bit = 1u << 2; /// The boolean scalar node bit. -const node_attr_t bool_bit = 1u << 3; +constexpr node_attr_t bool_bit = 1u << 3; /// The integer scalar node bit. -const node_attr_t int_bit = 1u << 4; +constexpr node_attr_t int_bit = 1u << 4; /// The floating point scalar node bit. -const node_attr_t float_bit = 1u << 5; +constexpr node_attr_t float_bit = 1u << 5; /// The string scalar node bit. -const node_attr_t string_bit = 1u << 6; +constexpr node_attr_t string_bit = 1u << 6; /// A utility bit set to filter scalar node bits. -const node_attr_t scalar_bits = null_bit | bool_bit | int_bit | float_bit | string_bit; +constexpr node_attr_t scalar_bits = null_bit | bool_bit | int_bit | float_bit | string_bit; /// The anchor node bit. -const node_attr_t anchor_bit = 0x01000000u; +constexpr node_attr_t anchor_bit = 0x01000000u; /// The alias node bit. -const node_attr_t alias_bit = 0x02000000u; +constexpr node_attr_t alias_bit = 0x02000000u; /// A utility bit set for initialization. -const node_attr_t default_bits = null_bit; +constexpr node_attr_t default_bits = null_bit; /// @brief Converts a node_type value to a node_attr_t value. /// @param t A type of node value. @@ -6552,9 +6556,9 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN struct node_property { /// The tag name property. - std::string tag {}; + std::string tag; /// The anchor name property. - std::string anchor {}; + std::string anchor; }; FK_YAML_DETAIL_NAMESPACE_END @@ -6590,7 +6594,7 @@ class basic_deserializer { using mapping_type = typename basic_node_type::mapping_type; /// @brief Definition of state types of parse contexts. - enum class context_state_t { + enum class context_state_t : std::uint8_t { BLOCK_MAPPING, //!< The underlying node is a block mapping. BLOCK_MAPPING_EXPLICIT_KEY, //!< The underlying node is an explicit block mapping key. BLOCK_MAPPING_EXPLICIT_VALUE, //!< The underlying node is an explicit block mapping value. @@ -6608,16 +6612,22 @@ class basic_deserializer { parse_context() = default; /// @brief Construct a new parse_context object with non-default values for each parameter. - /// @param _line The current line. (count from zero) - /// @param _indent The indentation width in the current line. (count from zero) - /// @param _state The parse context type. - /// @param _p_node The underlying node associated to this context. - parse_context(uint32_t _line, uint32_t _indent, context_state_t _state, basic_node_type* _p_node) - : line(_line), - indent(_indent), - state(_state), - p_node(_p_node) { - } + /// @param line The current line. (count from zero) + /// @param indent The indentation width in the current line. (count from zero) + /// @param state The parse context type. + /// @param p_node The underlying node associated to this context. + // // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + parse_context(uint32_t line, uint32_t indent, context_state_t state, basic_node_type* p_node) noexcept + : line(line), + indent(indent), + state(state), + p_node(p_node) { + } + + parse_context(const parse_context&) noexcept = default; + parse_context& operator=(const parse_context&) noexcept = default; + parse_context(parse_context&&) noexcept = default; + parse_context& operator=(parse_context&&) noexcept = default; ~parse_context() { switch (state) { @@ -6643,7 +6653,7 @@ class basic_deserializer { }; /// @brief Definitions of state types for expected flow token hints. - enum class flow_token_state_t { + enum class flow_token_state_t : std::uint8_t { NEEDS_VALUE_OR_SUFFIX, //!< Either value or flow suffix (`]` or `}`) NEEDS_SEPARATOR_OR_SUFFIX, //!< Either separator (`,`) or flow suffix (`]` or `}`) }; @@ -6662,8 +6672,8 @@ class basic_deserializer { /// @param input_adapter An input adapter object for the input source buffer. /// @return basic_node_type A root YAML node deserialized from the source string. template ::value, int> = 0> - basic_node_type deserialize(InputAdapterType&& input_adapter) { - str_view input_view = input_adapter.get_buffer_view(); + basic_node_type deserialize(InputAdapterType&& input_adapter) { // NOLINT(cppcoreguidelines-missing-std-forward) + const str_view input_view = input_adapter.get_buffer_view(); lexer_type lexer(input_view); lexical_token_t type {lexical_token_t::END_OF_BUFFER}; @@ -6675,8 +6685,9 @@ class basic_deserializer { /// @param input_adapter An input adapter object for the input source buffer. /// @return std::vector Root YAML nodes for deserialized YAML documents. template ::value, int> = 0> + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) std::vector deserialize_docs(InputAdapterType&& input_adapter) { - str_view input_view = input_adapter.get_buffer_view(); + const str_view input_view = input_adapter.get_buffer_view(); lexer_type lexer(input_view); std::vector nodes {}; @@ -6706,7 +6717,7 @@ class basic_deserializer { // parse node properties for root node if any uint32_t line = lexer.get_lines_processed(); uint32_t indent = lexer.get_last_token_begin_pos(); - bool found_props = deserialize_node_properties(lexer, token, line, indent); + const bool found_props = deserialize_node_properties(lexer, token, line, indent); switch (token.type) { case lexical_token_t::SEQUENCE_BLOCK_PREFIX: { @@ -6815,7 +6826,7 @@ class basic_deserializer { lexer.set_document_state(true); for (;;) { - lexical_token token = lexer.get_next_token(); + const lexical_token token = lexer.get_next_token(); switch (token.type) { case lexical_token_t::YAML_VER_DIRECTIVE: @@ -6831,39 +6842,39 @@ class basic_deserializer { lacks_end_of_directives_marker = true; break; case lexical_token_t::TAG_DIRECTIVE: { - str_view tag_handle_view = lexer.get_tag_handle(); + const str_view tag_handle_view = lexer.get_tag_handle(); switch (tag_handle_view.size()) { case 1 /* ! */: { - bool is_already_specified = !mp_meta->primary_handle_prefix.empty(); + const bool is_already_specified = !mp_meta->primary_handle_prefix.empty(); if FK_YAML_UNLIKELY (is_already_specified) { throw parse_error( "Primary handle cannot be specified more than once.", lexer.get_lines_processed(), lexer.get_last_token_begin_pos()); } - str_view tag_prefix = lexer.get_tag_prefix(); + const str_view tag_prefix = lexer.get_tag_prefix(); mp_meta->primary_handle_prefix.assign(tag_prefix.begin(), tag_prefix.end()); lacks_end_of_directives_marker = true; break; } case 2 /* !! */: { - bool is_already_specified = !mp_meta->secondary_handle_prefix.empty(); + const bool is_already_specified = !mp_meta->secondary_handle_prefix.empty(); if FK_YAML_UNLIKELY (is_already_specified) { throw parse_error( "Secondary handle cannot be specified more than once.", lexer.get_lines_processed(), lexer.get_last_token_begin_pos()); } - str_view tag_prefix = lexer.get_tag_prefix(); + const str_view tag_prefix = lexer.get_tag_prefix(); mp_meta->secondary_handle_prefix.assign(tag_prefix.begin(), tag_prefix.end()); lacks_end_of_directives_marker = true; break; } default /* !! */: { std::string tag_handle(tag_handle_view.begin(), tag_handle_view.end()); - str_view tag_prefix_view = lexer.get_tag_prefix(); + const str_view tag_prefix_view = lexer.get_tag_prefix(); std::string tag_prefix(tag_prefix_view.begin(), tag_prefix_view.end()); - bool is_already_specified = + const bool is_already_specified = !(mp_meta->named_handle_map.emplace(std::move(tag_handle), std::move(tag_prefix)).second); if FK_YAML_UNLIKELY (is_already_specified) { throw parse_error( @@ -6915,7 +6926,7 @@ class basic_deserializer { pop_num = static_cast(m_context_stack.size() - 1); } else { - bool needs_to_move_back = indent < m_context_stack.back().indent; + const bool needs_to_move_back = indent < m_context_stack.back().indent; if (needs_to_move_back) { auto target_itr = std::find_if( // LCOV_EXCL_LINE m_context_stack.rbegin(), @@ -6945,7 +6956,7 @@ class basic_deserializer { } if (m_context_stack.back().state == context_state_t::BLOCK_SEQUENCE) { - sequence_type& seq = mp_current_node->template get_value_ref(); + auto& seq = mp_current_node->template get_value_ref(); seq.emplace_back(basic_node_type::mapping()); m_context_stack.emplace_back(line, indent, context_state_t::BLOCK_MAPPING, &(seq.back())); } @@ -6953,7 +6964,7 @@ class basic_deserializer { token = lexer.get_next_token(); if (token.type == lexical_token_t::SEQUENCE_BLOCK_PREFIX) { // heap-allocated node will be freed in handling the corresponding KEY_SEPARATOR event - basic_node_type* p_node = new basic_node_type(node_type::SEQUENCE); + auto* p_node = new basic_node_type(node_type::SEQUENCE); m_context_stack.emplace_back(line, indent, context_state_t::BLOCK_MAPPING_EXPLICIT_KEY, p_node); mp_current_node = m_context_stack.back().p_node; apply_directive_set(*mp_current_node); @@ -6977,20 +6988,20 @@ class basic_deserializer { continue; } case lexical_token_t::KEY_SEPARATOR: { - bool is_empty_seq = mp_current_node->is_sequence() && mp_current_node->empty(); + const bool is_empty_seq = mp_current_node->is_sequence() && mp_current_node->empty(); if FK_YAML_UNLIKELY (is_empty_seq) { throw parse_error("sequence key should not be empty.", line, indent); } // hold the line count of the key separator for later use. - uint32_t old_indent = indent; - uint32_t old_line = line; + const uint32_t old_indent = indent; + const uint32_t old_line = line; token = lexer.get_next_token(); line = lexer.get_lines_processed(); indent = lexer.get_last_token_begin_pos(); - bool found_props = deserialize_node_properties(lexer, token, line, indent); + const bool found_props = deserialize_node_properties(lexer, token, line, indent); if (found_props && line == lexer.get_lines_processed()) { // defer applying node properties for the subsequent node on the same line. continue; @@ -7003,7 +7014,7 @@ class basic_deserializer { continue; } - bool is_implicit_same_line = + const bool is_implicit_same_line = (line == old_line) && (m_context_stack.empty() || old_indent > m_context_stack.back().indent); if (is_implicit_same_line) { // a key separator for an implicit key with its value on the same line. @@ -7012,7 +7023,7 @@ class basic_deserializer { if (line > old_line) { if (m_needs_tag_impl) { - tag_t tag_type = tag_resolver_type::resolve_tag(m_tag_name, mp_meta); + const tag_t tag_type = tag_resolver_type::resolve_tag(m_tag_name, mp_meta); if (tag_type == tag_t::MAPPING || tag_type == tag_t::CUSTOM_TAG) { // set YAML node properties here to distinguish them from those for the first key node // as shown in the following snippet: @@ -7045,9 +7056,9 @@ class basic_deserializer { line = lexer.get_lines_processed(); indent = lexer.get_last_token_begin_pos(); - bool has_props = deserialize_node_properties(lexer, token, line, indent); + const bool has_props = deserialize_node_properties(lexer, token, line, indent); if (has_props) { - uint32_t line_after_props = lexer.get_lines_processed(); + const uint32_t line_after_props = lexer.get_lines_processed(); if (line == line_after_props) { // Skip updating the current indent to avoid stacking a wrong indentation. // @@ -7119,7 +7130,7 @@ class basic_deserializer { // ``` continue; case lexical_token_t::SEQUENCE_BLOCK_PREFIX: { - bool is_further_nested = m_context_stack.back().indent < indent; + const bool is_further_nested = m_context_stack.back().indent < indent; if (is_further_nested) { mp_current_node->template get_value_ref().emplace_back(basic_node_type::sequence()); mp_current_node = &(mp_current_node->template get_value_ref().back()); @@ -7162,7 +7173,7 @@ class basic_deserializer { return false; } }); - bool is_indent_valid = (target_itr != m_context_stack.rend()); + const bool is_indent_valid = (target_itr != m_context_stack.rend()); if FK_YAML_UNLIKELY (!is_indent_valid) { throw parse_error("Detected invalid indentation.", line, indent); } @@ -7235,7 +7246,7 @@ class basic_deserializer { } }); - bool is_valid = itr != m_context_stack.rend(); + const bool is_valid = itr != m_context_stack.rend(); if FK_YAML_UNLIKELY (!is_valid) { throw parse_error("No corresponding flow sequence beginning is found.", line, indent); } @@ -7245,7 +7256,7 @@ class basic_deserializer { mp_current_node = last_context.p_node; last_context.p_node = nullptr; indent = last_context.indent; - context_state_t state = last_context.state; + const context_state_t state = last_context.state; m_context_stack.pop_back(); // handle cases where the flow sequence is a mapping key node. @@ -7309,7 +7320,7 @@ class basic_deserializer { return false; } }); - bool is_indent_valid = (target_itr != m_context_stack.rend()); + const bool is_indent_valid = (target_itr != m_context_stack.rend()); if FK_YAML_UNLIKELY (!is_indent_valid) { throw parse_error("Detected invalid indentation.", line, indent); } @@ -7385,7 +7396,7 @@ class basic_deserializer { } }); - bool is_valid = itr != m_context_stack.rend(); + const bool is_valid = itr != m_context_stack.rend(); if FK_YAML_UNLIKELY (!is_valid) { throw parse_error("No corresponding flow mapping beginning is found.", line, indent); } @@ -7395,7 +7406,7 @@ class basic_deserializer { mp_current_node = last_context.p_node; last_context.p_node = nullptr; indent = last_context.indent; - context_state_t state = last_context.state; + const context_state_t state = last_context.state; m_context_stack.pop_back(); // handle cases where the flow mapping is a mapping key node. @@ -7446,9 +7457,9 @@ class basic_deserializer { throw parse_error("Tag cannot be specified to an alias node", line, indent); } - const std::string token_str = std::string(token.str.begin(), token.str.end()); + std::string token_str = std::string(token.str.begin(), token.str.end()); - uint32_t anchor_counts = static_cast(mp_meta->anchor_table.count(token_str)); + const auto anchor_counts = static_cast(mp_meta->anchor_table.count(token_str)); if FK_YAML_UNLIKELY (anchor_counts == 0) { throw parse_error("The given anchor name must appear prior to the alias node.", line, indent); } @@ -7461,7 +7472,7 @@ class basic_deserializer { apply_directive_set(node); apply_node_properties(node); - bool should_continue = deserialize_scalar(lexer, std::move(node), indent, line, token); + const bool should_continue = deserialize_scalar(lexer, std::move(node), indent, line, token); if (should_continue) { continue; } @@ -7479,7 +7490,7 @@ class basic_deserializer { apply_directive_set(node); apply_node_properties(node); - bool do_continue = deserialize_scalar(lexer, std::move(node), indent, line, token); + const bool do_continue = deserialize_scalar(lexer, std::move(node), indent, line, token); if (do_continue) { continue; } @@ -7528,6 +7539,7 @@ class basic_deserializer { /// @param line The variable to store the line of either the first property or the last non-property token. /// @param indent The variable to store the indent of either the first property or the last non-property token. /// @return true if any property is found, false otherwise. + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) bool deserialize_node_properties(lexer_type& lexer, lexical_token& last_token, uint32_t& line, uint32_t& indent) { m_needs_anchor_impl = m_needs_tag_impl = false; @@ -7583,7 +7595,7 @@ class basic_deserializer { } while (!ends_loop); last_token = token; - bool prop_specified = m_needs_anchor_impl || m_needs_tag_impl; + const bool prop_specified = m_needs_anchor_impl || m_needs_tag_impl; if (!prop_specified) { line = lexer.get_lines_processed(); indent = lexer.get_last_token_begin_pos(); @@ -7608,7 +7620,7 @@ class basic_deserializer { // the target node is a block mapping key node with the same indentation. return (indent == c.indent) && (c.state == context_state_t::BLOCK_MAPPING); }); - bool is_indent_valid = (target_itr != m_context_stack.rend()); + const bool is_indent_valid = (target_itr != m_context_stack.rend()); if FK_YAML_UNLIKELY (!is_indent_valid) { throw parse_error("Detected invalid indentation.", line, indent); } @@ -7639,7 +7651,7 @@ class basic_deserializer { } mp_current_node = &(itr.first->second); - parse_context& key_context = m_context_stack.back(); + const parse_context& key_context = m_context_stack.back(); m_context_stack.emplace_back( key_context.line, key_context.indent, context_state_t::MAPPING_VALUE, mp_current_node); } @@ -7805,13 +7817,13 @@ class basic_deserializer { /// A flag to determine the need for a value separator or a flow suffix to follow. flow_token_state_t m_flow_token_state {flow_token_state_t::NEEDS_VALUE_OR_SUFFIX}; /// The last YAML anchor name. - std::string m_anchor_name {}; + std::string m_anchor_name; /// The last tag name. - std::string m_tag_name {}; + std::string m_tag_name; /// The root YAML anchor name. (maybe empty and unused) - std::string m_root_anchor_name {}; + std::string m_root_anchor_name; /// The root tag name. (maybe empty and unused) - std::string m_root_tag_name {}; + std::string m_root_tag_name; }; FK_YAML_DETAIL_NAMESPACE_END @@ -7870,6 +7882,8 @@ FK_YAML_DETAIL_NAMESPACE_END #ifndef FK_YAML_DETAIL_ENCODINGS_UTF_ENCODE_T_HPP #define FK_YAML_DETAIL_ENCODINGS_UTF_ENCODE_T_HPP +#include + // #include @@ -7877,7 +7891,7 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of Unicode encoding types /// @note Since fkYAML doesn't treat UTF-16/UTF-32 encoded characters per byte, endians do not matter. -enum class utf_encode_t { +enum class utf_encode_t : std::uint8_t { UTF_8, //!< UTF-8 UTF_16BE, //!< UTF-16 Big Endian UTF_16LE, //!< UTF-16 Little Endian @@ -7906,53 +7920,54 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN inline utf_encode_t detect_encoding_type(const std::array& bytes, bool& has_bom) noexcept { has_bom = false; - uint8_t byte0 = bytes[0]; - uint8_t byte1 = bytes[1]; - uint8_t byte2 = bytes[2]; - uint8_t byte3 = bytes[3]; + const uint8_t byte0 = bytes[0]; + const uint8_t byte1 = bytes[1]; + const uint8_t byte2 = bytes[2]; + const uint8_t byte3 = bytes[3]; // Check if a BOM exists. - if (byte0 == uint8_t(0xEFu) && byte1 == uint8_t(0xBBu) && byte2 == uint8_t(0xBFu)) { + if (byte0 == static_cast(0xEFu) && byte1 == static_cast(0xBBu) && + byte2 == static_cast(0xBFu)) { has_bom = true; return utf_encode_t::UTF_8; } - if (byte0 == 0 && byte1 == 0 && byte2 == uint8_t(0xFEu) && byte3 == uint8_t(0xFFu)) { + if (byte0 == 0 && byte1 == 0 && byte2 == static_cast(0xFEu) && byte3 == static_cast(0xFFu)) { has_bom = true; return utf_encode_t::UTF_32BE; } - if (byte0 == uint8_t(0xFFu) && byte1 == uint8_t(0xFEu) && byte2 == 0 && byte3 == 0) { + if (byte0 == static_cast(0xFFu) && byte1 == static_cast(0xFEu) && byte2 == 0 && byte3 == 0) { has_bom = true; return utf_encode_t::UTF_32LE; } - if (byte0 == uint8_t(0xFEu) && byte1 == uint8_t(0xFFu)) { + if (byte0 == static_cast(0xFEu) && byte1 == static_cast(0xFFu)) { has_bom = true; return utf_encode_t::UTF_16BE; } - if (byte0 == uint8_t(0xFFu) && byte1 == uint8_t(0xFEu)) { + if (byte0 == static_cast(0xFFu) && byte1 == static_cast(0xFEu)) { has_bom = true; return utf_encode_t::UTF_16LE; } // Test the first character assuming it's an ASCII character. - if (byte0 == 0 && byte1 == 0 && byte2 == 0 && 0 < byte3 && byte3 < uint8_t(0x80u)) { + if (byte0 == 0 && byte1 == 0 && byte2 == 0 && 0 < byte3 && byte3 < static_cast(0x80u)) { return utf_encode_t::UTF_32BE; } - if (0 < byte0 && byte0 < uint8_t(0x80u) && byte1 == 0 && byte2 == 0 && byte3 == 0) { + if (0 < byte0 && byte0 < static_cast(0x80u) && byte1 == 0 && byte2 == 0 && byte3 == 0) { return utf_encode_t::UTF_32LE; } - if (byte0 == 0 && 0 < byte1 && byte1 < uint8_t(0x80u)) { + if (byte0 == 0 && 0 < byte1 && byte1 < static_cast(0x80u)) { return utf_encode_t::UTF_16BE; } - if (0 < byte0 && byte0 < uint8_t(0x80u) && byte1 == 0) { + if (0 < byte0 && byte0 < static_cast(0x80u) && byte1 == 0) { return utf_encode_t::UTF_16LE; } @@ -7980,11 +7995,11 @@ struct utf_encode_detector::v std::array bytes {}; bytes.fill(0xFFu); for (int i = 0; i < 4 && begin + i != end; i++) { - bytes[i] = uint8_t(begin[i]); + bytes[i] = uint8_t(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); if (has_bom) { // skip reading the BOM. @@ -8025,11 +8040,11 @@ struct utf_encode_detector std::array bytes {}; bytes.fill(0xFFu); for (int i = 0; i < 4 && begin + i != end; i++) { - bytes[i] = uint8_t(begin[i]); + bytes[i] = uint8_t(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); if FK_YAML_UNLIKELY (encode_type != utf_encode_t::UTF_8) { throw exception("char8_t characters must be encoded in the UTF-8 format."); @@ -8062,13 +8077,16 @@ struct utf_encode_detector bytes {}; bytes.fill(0xFFu); for (int i = 0; i < 2 && begin + i != end; i++) { - char16_t elem = begin[i]; - bytes[i * 2] = uint8_t((elem & 0xFF00u) >> 8); - bytes[i * 2 + 1] = uint8_t(elem & 0xFFu); + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-constant-array-index) + const char16_t elem = begin[i]; + const int idx_base = i * 2; + bytes[idx_base] = static_cast((elem & 0xFF00u) >> 8); + bytes[idx_base + 1] = static_cast(elem & 0xFFu); + // NOLINTEND(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); if FK_YAML_UNLIKELY (encode_type != utf_encode_t::UTF_16BE && encode_type != utf_encode_t::UTF_16LE) { throw exception("char16_t characters must be encoded in the UTF-16 format."); @@ -8097,14 +8115,14 @@ struct utf_encode_detector bytes {}; - char32_t elem = *begin; - bytes[0] = uint8_t((elem & 0xFF000000u) >> 24); - bytes[1] = uint8_t((elem & 0x00FF0000u) >> 16); - bytes[2] = uint8_t((elem & 0x0000FF00u) >> 8); - bytes[3] = uint8_t(elem & 0x000000FFu); + const char32_t elem = *begin; + bytes[0] = static_cast((elem & 0xFF000000u) >> 24); + bytes[1] = static_cast((elem & 0x00FF0000u) >> 16); + bytes[2] = static_cast((elem & 0x0000FF00u) >> 8); + bytes[3] = static_cast(elem & 0x000000FFu); bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); if FK_YAML_UNLIKELY (encode_type != utf_encode_t::UTF_32BE && encode_type != utf_encode_t::UTF_32LE) { throw exception("char32_t characters must be encoded in the UTF-32 format."); @@ -8129,18 +8147,18 @@ struct file_utf_encode_detector { bytes.fill(0xFFu); for (int i = 0; i < 4; i++) { char byte = 0; - std::size_t size = std::fread(&byte, sizeof(char), 1, p_file); + const std::size_t size = std::fread(&byte, sizeof(char), 1, p_file); if (size != sizeof(char)) { break; } - bytes[i] = uint8_t(byte & 0xFF); + bytes[i] = static_cast(byte & 0xFF); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); // move back to the beginning if a BOM doesn't exist. - long offset = 0; + long offset = 0; // NOLINT(google-runtime-int) if (has_bom) { switch (encode_type) { case utf_encode_t::UTF_8: @@ -8156,7 +8174,7 @@ struct file_utf_encode_detector { break; } } - std::fseek(p_file, offset, SEEK_SET); + std::fseek(p_file, offset, SEEK_SET); // NOLINT(cert-err33-c) return encode_type; } @@ -8173,17 +8191,17 @@ struct stream_utf_encode_detector { for (int i = 0; i < 4; i++) { char ch = 0; is.read(&ch, 1); - std::streamsize size = is.gcount(); + const std::streamsize size = is.gcount(); if (size != 1) { // without this, seekg() will fail. is.clear(); break; } - bytes[i] = uint8_t(ch & 0xFF); + bytes[i] = static_cast(ch & 0xFF); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; - utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); + const utf_encode_t encode_type = detect_encoding_type(bytes, has_bom); // move back to the beginning if a BOM doesn't exist. std::streamoff offset = 0; @@ -8288,30 +8306,30 @@ class iterator_input_adapter(*current++); + const uint32_t num_bytes = utf8::get_num_bytes(first); switch (num_bytes) { case 2: { - std::initializer_list bytes {first, uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, uint8_t(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 3: { - std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 4: { - std::initializer_list bytes { + const std::initializer_list bytes { first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } @@ -8324,7 +8342,8 @@ class iterator_input_adapter(uint8_t(*current++) << shift_bits[0]); + auto utf16 = static_cast(uint8_t(*current++) << shift_bits[0]); utf16 |= static_cast(uint8_t(*current++) << shift_bits[1]); // skip appending CRs. if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) encoded_buffer[encoded_buf_size++] = utf16; } } @@ -8420,7 +8440,7 @@ class iterator_input_adapter(*current++ << shift_bits[0]); + auto utf32 = static_cast(*current++ << shift_bits[0]); utf32 |= static_cast(*current++ << shift_bits[1]); utf32 |= static_cast(*current++ << shift_bits[2]); utf32 |= static_cast(*current++ << shift_bits[3]); @@ -8442,7 +8462,7 @@ class iterator_input_adapter(*current++); - uint32_t num_bytes = utf8::get_num_bytes(first); + const auto first = static_cast(*current++); + const uint32_t num_bytes = utf8::get_num_bytes(first); switch (num_bytes) { case 2: { - std::initializer_list bytes {first, uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, uint8_t(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 3: { - std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 4: { - std::initializer_list bytes { + const std::initializer_list bytes { first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } @@ -8523,7 +8543,7 @@ class iterator_input_adapter(*current++); if FK_YAML_LIKELY (c != '\r') { m_buffer.push_back(c); } @@ -8540,7 +8560,7 @@ class iterator_input_adapter encoded_buffer {{0, 0}}; uint32_t encoded_buf_size {0}; @@ -8593,11 +8613,10 @@ class iterator_input_adapter((utf16 & 0x00FFu) << shift_bits) | - static_cast((utf16 & 0xFF00u) >> shift_bits)); + utf16 = static_cast(((utf16 & 0x00FFu) << shift_bits) | ((utf16 & 0xFF00u) >> shift_bits)); if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) encoded_buffer[encoded_buf_size++] = utf16; } } @@ -8625,7 +8644,7 @@ class iterator_input_adapter((tmp & 0xFF000000u) >> shift_bits[0]) | - static_cast((tmp & 0x00FF0000u) >> shift_bits[1]) | - static_cast((tmp & 0x0000FF00u) << shift_bits[2]) | - static_cast((tmp & 0x000000FFu) << shift_bits[3])); - - if FK_YAML_UNLIKELY (utf32 != char32_t(0x0000000Du)) { + const char32_t tmp = *current++; + const auto utf32 = static_cast( + ((tmp & 0xFF000000u) >> shift_bits[0]) | ((tmp & 0x00FF0000u) >> shift_bits[1]) | + ((tmp & 0x0000FF00u) << shift_bits[2]) | ((tmp & 0x000000FFu) << shift_bits[3])); + + if FK_YAML_UNLIKELY (utf32 != static_cast(0x0000000Du)) { utf8::from_utf32(utf32, utf8_buffer, utf8_buf_size); m_buffer.append(reinterpret_cast(utf8_buffer.data()), utf8_buf_size); } @@ -8702,7 +8719,7 @@ class iterator_input_adapter 0) { char* p_current = &tmp_buf[0]; @@ -8778,30 +8795,34 @@ class file_input_adapter { auto current = m_buffer.begin(); auto end = m_buffer.end(); while (current != end) { - uint8_t first = static_cast(*current++); - uint32_t num_bytes = utf8::get_num_bytes(first); + const auto first = static_cast(*current++); + const uint32_t num_bytes = utf8::get_num_bytes(first); switch (num_bytes) { case 2: { - std::initializer_list bytes {first, uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 3: { - std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes { + first, static_cast(*current++), static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 4: { - std::initializer_list bytes { - first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes { + first, + static_cast(*current++), + static_cast(*current++), + static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } @@ -8837,10 +8858,11 @@ class file_input_adapter { while (std::feof(m_file) == 0) { while (encoded_buf_size < 2 && std::fread(&chars[0], sizeof(char), 2, m_file) == 2) { - char16_t utf16 = char16_t( - static_cast(uint8_t(chars[0]) << shift_bits[0]) | - static_cast(uint8_t(chars[1]) << shift_bits[1])); - if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { + const auto utf16 = static_cast( + (static_cast(chars[0]) << shift_bits[0]) | + (static_cast(chars[1]) << shift_bits[1])); + if FK_YAML_LIKELY (utf16 != static_cast(0x000Du)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) encoded_buffer[encoded_buf_size++] = utf16; } } @@ -8881,16 +8903,14 @@ class file_input_adapter { uint32_t utf8_buf_size {0}; while (std::feof(m_file) == 0) { - std::size_t size = std::fread(&chars[0], sizeof(char), 4, m_file); + const std::size_t size = std::fread(&chars[0], sizeof(char), 4, m_file); if (size != 4) { break; } - char32_t utf32 = char32_t( - static_cast(uint8_t(chars[0]) << shift_bits[0]) | - static_cast(uint8_t(chars[1]) << shift_bits[1]) | - static_cast(uint8_t(chars[2]) << shift_bits[2]) | - static_cast(uint8_t(chars[3]) << shift_bits[3])); + const auto utf32 = static_cast( + (static_cast(chars[0]) << shift_bits[0]) | (static_cast(chars[1]) << shift_bits[1]) | + (static_cast(chars[2]) << shift_bits[2]) | (static_cast(chars[3]) << shift_bits[3])); if FK_YAML_LIKELY (utf32 != char32_t(0x0000000Du)) { utf8::from_utf32(utf32, utf8_buffer, utf8_buf_size); @@ -8907,7 +8927,7 @@ class file_input_adapter { /// The encoding type for this input adapter. utf_encode_t m_encode_type {utf_encode_t::UTF_8}; /// The normalized owned buffer. - std::string m_buffer {}; + std::string m_buffer; }; /// @brief An input adapter for streams @@ -8957,7 +8977,7 @@ class stream_input_adapter { char tmp_buf[256] {}; do { m_istream->read(&tmp_buf[0], 256); - std::size_t read_size = static_cast(m_istream->gcount()); + const auto read_size = static_cast(m_istream->gcount()); char* p_current = &tmp_buf[0]; char* p_end = p_current + read_size; @@ -8979,30 +8999,34 @@ class stream_input_adapter { auto current = m_buffer.begin(); auto end = m_buffer.end(); while (current != end) { - uint8_t first = static_cast(*current++); - uint32_t num_bytes = utf8::get_num_bytes(first); + const auto first = static_cast(*current++); + const uint32_t num_bytes = utf8::get_num_bytes(first); switch (num_bytes) { case 2: { - std::initializer_list bytes {first, uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes {first, static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 3: { - std::initializer_list bytes {first, uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes { + first, static_cast(*current++), static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } break; } case 4: { - std::initializer_list bytes { - first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; - bool is_valid = utf8::validate(bytes); + const std::initializer_list bytes { + first, + static_cast(*current++), + static_cast(*current++), + static_cast(*current++)}; + const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); } @@ -9039,16 +9063,17 @@ class stream_input_adapter { do { while (encoded_buf_size < 2) { m_istream->read(&chars[0], 2); - std::streamsize size = m_istream->gcount(); + const std::streamsize size = m_istream->gcount(); if (size != 2) { break; } - char16_t utf16 = char16_t( - static_cast(uint8_t(chars[0]) << shift_bits[0]) | - static_cast(uint8_t(chars[1]) << shift_bits[1])); + const auto utf16 = static_cast( + (static_cast(chars[0]) << shift_bits[0]) | + (static_cast(chars[1]) << shift_bits[1])); - if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { + if FK_YAML_LIKELY (utf16 != static_cast(0x000Du)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) encoded_buffer[encoded_buf_size++] = utf16; } } @@ -9090,16 +9115,14 @@ class stream_input_adapter { do { m_istream->read(&chars[0], 4); - std::streamsize size = m_istream->gcount(); + const std::streamsize size = m_istream->gcount(); if (size != 4) { break; } - char32_t utf32 = char32_t( - static_cast(uint8_t(chars[0]) << shift_bits[0]) | - static_cast(uint8_t(chars[1]) << shift_bits[1]) | - static_cast(uint8_t(chars[2]) << shift_bits[2]) | - static_cast(uint8_t(chars[3]) << shift_bits[3])); + const auto utf32 = static_cast( + (static_cast(chars[0]) << shift_bits[0]) | (static_cast(chars[1]) << shift_bits[1]) | + (static_cast(chars[2]) << shift_bits[2]) | (static_cast(chars[3]) << shift_bits[3])); if FK_YAML_LIKELY (utf32 != char32_t(0x0000000Du)) { utf8::from_utf32(utf32, utf8_buffer, utf8_buf_size); @@ -9116,24 +9139,25 @@ class stream_input_adapter { /// The encoding type for this input adapter. utf_encode_t m_encode_type {utf_encode_t::UTF_8}; /// The normalized owned buffer. - std::string m_buffer {}; + std::string m_buffer; }; ///////////////////////////////// // input_adapter providers // ///////////////////////////////// -namespace { - +/// @brief A concrete factory method for iterator_input_adapter objects with iterators. +/// @tparam ItrType An iterator type. +/// @param begin The beginning of iterators. +/// @param end The end of iterators. +/// @param is_contiguous Whether iterators refer to a contiguous byte array. +/// @return An iterator_input_adapter object for the target iterator type. template -inline iterator_input_adapter create_iterator_input_adapter( - ItrType begin, ItrType end, bool is_contiguous) noexcept { - utf_encode_t encode_type = utf_encode_detector::detect(begin, end); +inline iterator_input_adapter create_iterator_input_adapter(ItrType begin, ItrType end, bool is_contiguous) { + const utf_encode_t encode_type = utf_encode_detector::detect(begin, end); return iterator_input_adapter(begin, end, encode_type, is_contiguous); } -} // anonymous namespace - /// @brief A factory method for iterator_input_adapter objects with iterator values. /// @tparam ItrType An iterator type. /// @param begin The beginning of iterators. @@ -9148,7 +9172,7 @@ inline iterator_input_adapter input_adapter(ItrType begin, ItrType end) // Getting distance between begin and (end - 1) avoids dereferencing an invalid sentinel. bool is_contiguous = false; if (is_random_access_itr) { - ptrdiff_t size = static_cast(std::distance(begin, end - 1)); + const auto size = static_cast(std::distance(begin, end - 1)); using CharPtr = remove_cvref_t::pointer>; CharPtr p_begin = &*begin; @@ -9207,7 +9231,7 @@ struct container_input_adapter_factory< /// @return input_adapter_factory::container_input_adapter_factory::adapter_type template inline typename input_adapter_factory::container_input_adapter_factory::adapter_type input_adapter( - ContainerType&& container) { + const ContainerType& container) { return input_adapter_factory::container_input_adapter_factory::create(container); } @@ -9218,7 +9242,8 @@ inline file_input_adapter input_adapter(std::FILE* file) { if FK_YAML_UNLIKELY (!file) { throw fkyaml::exception("Invalid FILE object pointer."); } - utf_encode_t encode_type = file_utf_encode_detector::detect(file); + + const utf_encode_t encode_type = file_utf_encode_detector::detect(file); return file_input_adapter(file, encode_type); } @@ -9229,7 +9254,8 @@ inline stream_input_adapter input_adapter(std::istream& stream) { if FK_YAML_UNLIKELY (!stream.good()) { throw fkyaml::exception("Invalid stream."); } - utf_encode_t encode_type = stream_utf_encode_detector::detect(stream); + + const utf_encode_t encode_type = stream_utf_encode_detector::detect(stream); return stream_input_adapter(stream, encode_type); } @@ -9300,7 +9326,7 @@ struct iterator_traits { }; /// @brief Definitions of iterator types for iterators internally held. -enum class iterator_t { +enum class iterator_t : std::uint8_t { SEQUENCE, //!< sequence iterator type. MAPPING, //!< mapping iterator type. }; @@ -9343,8 +9369,7 @@ class 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 - : m_inner_iterator_type(iterator_t::SEQUENCE) { + iterator(sequence_iterator_tag /* unused */, const typename ValueType::sequence_type::iterator& itr) noexcept { m_iterator_holder.sequence_iterator = itr; } @@ -9682,19 +9707,19 @@ class node_ref_storage { /// @brief Construct a new node ref storage object with an rvalue basic_node object. /// @param n An rvalue basic_node object. explicit node_ref_storage(node_type&& n) noexcept(std::is_nothrow_move_constructible::value) - : owned_value(std::move(n)) { + : m_owned_value(std::move(n)) { } /// @brief Construct a new node ref storage object with an lvalue basic_node object. /// @param n An lvalue basic_node object. explicit node_ref_storage(const node_type& n) noexcept - : value_ref(&n) { + : m_value_ref(&n) { } /// @brief Construct a new node ref storage object with a std::initializer_list object. /// @param init A std::initializer_list object. node_ref_storage(std::initializer_list init) - : owned_value(init) { + : m_owned_value(init) { } /// @brief Construct a new node ref storage object with variadic template arguments @@ -9702,7 +9727,7 @@ class node_ref_storage { /// @param args Arguments to construct a basic_node object. template ::value, int> = 0> node_ref_storage(Args&&... args) - : owned_value(std::forward(args)...) { + : m_owned_value(std::forward(args)...) { } // allow only move construct/assignment @@ -9711,24 +9736,26 @@ class node_ref_storage { node_ref_storage& operator=(const node_ref_storage&) = delete; node_ref_storage& operator=(node_ref_storage&&) = default; + ~node_ref_storage() = default; + public: /// @brief An arrow operator for node_ref_storage objects. /// @return const node_type* A constant pointer to a basic_node object. const node_type* operator->() const noexcept { - return value_ref ? value_ref : &owned_value; + return m_value_ref ? m_value_ref : &m_owned_value; } /// @brief Releases a basic_node object internally held. /// @return node_type A basic_node object internally held. node_type release() const noexcept { - return value_ref ? *value_ref : std::move(owned_value); + return m_value_ref ? *m_value_ref : std::move(m_owned_value); } private: /// A storage for a basic_node object given with rvalue reference. - mutable node_type owned_value = nullptr; + mutable node_type m_owned_value = nullptr; /// A pointer to a basic_node object given with lvalue reference. - const node_type* value_ref = nullptr; + const node_type* m_value_ref = nullptr; }; FK_YAML_DETAIL_NAMESPACE_END @@ -9799,10 +9826,10 @@ inline void to_string(std::nullptr_t /*unused*/, std::string& s) noexcept { /// @brief Specialization of to_string() for booleans. /// @param s A resulting string YAML token. -/// @param b A boolean source value. +/// @param v A boolean source value. template <> -inline void to_string(bool b, std::string& s) noexcept { - s = b ? "true" : "false"; +inline void to_string(bool v, std::string& s) noexcept { + s = v ? "true" : "false"; } /// @brief Specialization of to_string() for integers. @@ -9810,8 +9837,8 @@ inline void to_string(bool b, std::string& s) noexcept { /// @param s A resulting string YAML token. /// @param i An integer source value. template -inline enable_if_t::value> to_string(IntegerType i, std::string& s) noexcept { - s = std::to_string(i); +inline enable_if_t::value> to_string(IntegerType v, std::string& s) noexcept { + s = std::to_string(v); } /// @brief Specialization of to_string() for floating point numbers. @@ -9819,14 +9846,14 @@ inline enable_if_t::value> to_string(IntegerTy /// @param s A resulting string YAML token. /// @param f A floating point number source value. template -inline enable_if_t::value> to_string(FloatType f, std::string& s) noexcept { - if (std::isnan(f)) { +inline enable_if_t::value> to_string(FloatType v, std::string& s) noexcept { + if (std::isnan(v)) { s = ".nan"; return; } - if (std::isinf(f)) { - if (f == std::numeric_limits::infinity()) { + if (std::isinf(v)) { + if (v == std::numeric_limits::infinity()) { s = ".inf"; } else { @@ -9836,12 +9863,12 @@ inline enable_if_t::value> to_string(FloatType } std::ostringstream oss; - oss << f; + 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 - FloatType diff = f - std::floor(f); + const FloatType diff = v - std::floor(v); if (diff < std::numeric_limits::min()) { s += ".0"; } @@ -9888,7 +9915,7 @@ class basic_serializer { std::string serialize_docs(const std::vector& docs) { std::string str {}; - uint32_t size = static_cast(docs.size()); + const auto size = static_cast(docs.size()); for (uint32_t i = 0; i < size; i++) { serialize_document(docs[i], str); if (i + 1 < size) { @@ -9902,10 +9929,10 @@ class basic_serializer { private: void serialize_document(const BasicNodeType& node, std::string& str) { - bool dirs_serialized = serialize_directives(node, str); + const bool dirs_serialized = serialize_directives(node, str); // the root node cannot be an alias node. - bool root_has_props = node.is_anchor() || node.has_tag_name(); + const bool root_has_props = node.is_anchor() || node.has_tag_name(); if (root_has_props) { if (dirs_serialized) { @@ -9982,7 +10009,7 @@ class basic_serializer { insert_indentation(cur_indent, str); str += "-"; - bool is_appended = try_append_alias(seq_item, true, str); + const bool is_appended = try_append_alias(seq_item, true, str); if (is_appended) { str += "\n"; continue; @@ -9991,7 +10018,7 @@ class basic_serializer { try_append_anchor(seq_item, true, str); try_append_tag(seq_item, true, str); - bool is_scalar = seq_item.is_scalar(); + const bool is_scalar = seq_item.is_scalar(); if (is_scalar) { str += " "; serialize_node(seq_item, cur_indent, str); @@ -10013,17 +10040,17 @@ class basic_serializer { str += " "; } else { - bool is_anchor_appended = try_append_anchor(itr.key(), false, str); - bool is_tag_appended = try_append_tag(itr.key(), is_anchor_appended, str); + const bool is_anchor_appended = try_append_anchor(itr.key(), false, str); + const bool is_tag_appended = try_append_tag(itr.key(), is_anchor_appended, str); if (is_anchor_appended || is_tag_appended) { str += " "; } - bool is_container = !itr.key().is_scalar(); + const bool is_container = !itr.key().is_scalar(); if (is_container) { str += "? "; } - uint32_t indent = static_cast(get_cur_indent(str)); + const auto indent = static_cast(get_cur_indent(str)); serialize_node(itr.key(), indent, str); if (is_container) { // a newline code is already inserted in the above serialize_node() call. @@ -10042,7 +10069,7 @@ class basic_serializer { try_append_anchor(*itr, true, str); try_append_tag(*itr, true, str); - bool is_scalar = itr->is_scalar(); + const bool is_scalar = itr->is_scalar(); if (is_scalar) { str += " "; serialize_node(*itr, cur_indent, str); @@ -10072,7 +10099,7 @@ class basic_serializer { break; case node_type::STRING: { bool is_escaped = false; - typename BasicNodeType::string_type str_val = get_string_node_value(node, is_escaped); + auto str_val = get_string_node_value(node, is_escaped); if (is_escaped) { // There's no other token type with escapes than strings. @@ -10086,7 +10113,7 @@ class basic_serializer { // The next line is intentionally excluded from the LCOV coverage target since the next line is somehow // misrecognized as it has a binary branch. Possibly begin() or end() has some conditional branch(es) // internally. Confirmed with LCOV 1.14 on Ubuntu22.04. - node_type type_if_plain = + const node_type type_if_plain = scalar_scanner::scan(str_val.c_str(), str_val.c_str() + str_val.size()); // LCOV_EXCL_LINE if (type_if_plain != node_type::STRING) { @@ -10108,12 +10135,12 @@ class basic_serializer { /// @param s The target string object. /// @return The current indentation width. std::size_t get_cur_indent(const std::string& s) const noexcept { - bool is_empty = s.empty(); + const bool is_empty = s.empty(); if (is_empty) { return 0; } - std::size_t last_lf_pos = s.rfind('\n'); + const std::size_t last_lf_pos = s.rfind('\n'); return (last_lf_pos != std::string::npos) ? s.size() - last_lf_pos - 1 : s.size(); } @@ -10182,8 +10209,7 @@ class basic_serializer { typename BasicNodeType::string_type get_string_node_value(const BasicNodeType& node, bool& is_escaped) { FK_YAML_ASSERT(node.is_string()); - using string_type = typename BasicNodeType::string_type; - const string_type& s = node.template get_value_ref(); + const auto& s = node.template get_value_ref(); return yaml_escaper::escape(s.c_str(), s.c_str() + s.size(), is_escaped); } // LCOV_EXCL_LINE @@ -10220,7 +10246,7 @@ FK_YAML_DETAIL_NAMESPACE_END FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief Definition of YAML version types. -enum class yaml_version_t : std::uint32_t { +enum class yaml_version_t : std::uint8_t { VER_1_1, //!< YAML version 1.1 VER_1_2, //!< YAML version 1.2 }; @@ -10230,9 +10256,8 @@ inline yaml_version_t convert_from_yaml_version_type(yaml_version_type t) noexce case yaml_version_type::VERSION_1_1: return yaml_version_t::VER_1_1; case yaml_version_type::VERSION_1_2: + default: return yaml_version_t::VER_1_2; - default: // LCOV_EXCL_LINE - return yaml_version_t::VER_1_2; // LCOV_EXCL_LINE } } @@ -10241,9 +10266,8 @@ inline yaml_version_type convert_to_yaml_version_type(yaml_version_t t) noexcept case yaml_version_t::VER_1_1: return yaml_version_type::VERSION_1_1; case yaml_version_t::VER_1_2: + default: return yaml_version_type::VERSION_1_2; - default: // LCOV_EXCL_LINE - return yaml_version_type::VERSION_1_2; // LCOV_EXCL_LINE } } @@ -10436,7 +10460,7 @@ inline void from_node(const BasicNodeType& n, IntegerType& i) { // under/overflow check. using node_int_type = typename BasicNodeType::integer_type; - node_int_type tmp_int = n.template get_value_ref(); + const node_int_type tmp_int = n.template get_value_ref(); if FK_YAML_UNLIKELY (tmp_int < static_cast(std::numeric_limits::min())) { throw exception("Integer value underflow detected."); } @@ -10551,8 +10575,8 @@ struct from_node_fn { /// @param val A target object assigned from the basic_node object. /// @return decltype(from_node(n, std::forward(val))) void by default. User can set it to some other type. template - auto operator()(const BasicNodeType& n, T&& val) const noexcept(noexcept(from_node(n, std::forward(val)))) - -> decltype(from_node(n, std::forward(val))) { + auto operator()(const BasicNodeType& n, T&& val) const + noexcept(noexcept(from_node(n, std::forward(val)))) -> decltype(from_node(n, std::forward(val))) { return from_node(n, std::forward(val)); } }; @@ -10899,8 +10923,8 @@ struct to_node_fn { /// @param val A target object assigned to the basic_node object. /// @return decltype(to_node(n, std::forward(val))) void by default. User can set it to some other type. template - auto operator()(BasicNodeType& n, T&& val) const noexcept(noexcept(to_node(n, std::forward(val)))) - -> decltype(to_node(n, std::forward(val))) { + auto operator()(BasicNodeType& n, T&& val) const + noexcept(noexcept(to_node(n, std::forward(val)))) -> decltype(to_node(n, std::forward(val))) { return to_node(n, std::forward(val)); } }; @@ -10957,9 +10981,8 @@ class node_value_converter { /// @param val A native data object. /// @sa https://fktn-k.github.io/fkYAML/api/node_value_converter/to_node/ template - static auto to_node(BasicNodeType& n, TargetType&& val) noexcept( - noexcept(::fkyaml::to_node(n, std::forward(val)))) - -> decltype(::fkyaml::to_node(n, std::forward(val))) { + static auto to_node(BasicNodeType& n, TargetType&& val) noexcept(noexcept(::fkyaml::to_node( + n, std::forward(val)))) -> decltype(::fkyaml::to_node(n, std::forward(val))) { ::fkyaml::to_node(n, std::forward(val)); } }; @@ -11066,7 +11089,7 @@ class ordered_map : public std::vector, Allocator> { return {itr, false}; } } - this->emplace_back(key, value); + this->emplace_back(std::forward(key), value); return {std::prev(this->end()), true}; } @@ -11078,7 +11101,7 @@ class ordered_map : public std::vector, Allocator> { template < typename KeyType, detail::enable_if_t::value, int> = 0> - mapped_type& at(KeyType&& key) { + mapped_type& at(KeyType&& key) { // NOLINT(cppcoreguidelines-missing-std-forward) for (auto itr = this->begin(); itr != this->end(); ++itr) { if (m_compare(itr->first, key)) { return itr->second; @@ -11095,7 +11118,7 @@ class ordered_map : public std::vector, Allocator> { template < typename KeyType, detail::enable_if_t::value, int> = 0> - const mapped_type& at(KeyType&& key) const { + const mapped_type& at(KeyType&& key) const { // NOLINT(cppcoreguidelines-missing-std-forward) for (auto itr = this->begin(); itr != this->end(); ++itr) { if (m_compare(itr->first, key)) { return itr->second; @@ -11112,7 +11135,7 @@ class ordered_map : public std::vector, Allocator> { template < typename KeyType, detail::enable_if_t::value, int> = 0> - iterator find(KeyType&& key) noexcept { + iterator find(KeyType&& key) noexcept { // NOLINT(cppcoreguidelines-missing-std-forward) for (auto itr = this->begin(); itr != this->end(); ++itr) { if (m_compare(itr->first, key)) { return itr; @@ -11129,7 +11152,7 @@ class ordered_map : public std::vector, Allocator> { template < typename KeyType, detail::enable_if_t::value, int> = 0> - const_iterator find(KeyType&& key) const noexcept { + const_iterator find(KeyType&& key) const noexcept { // NOLINT(cppcoreguidelines-missing-std-forward) for (auto itr = this->begin(); itr != this->end(); ++itr) { if (m_compare(itr->first, key)) { return itr; @@ -11536,7 +11559,7 @@ class basic_node { /// @return The resulting basic_node object deserialized from the pair of iterators. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/deserialize/ template - static basic_node deserialize(ItrType&& begin, ItrType&& end) { + static basic_node deserialize(ItrType begin, ItrType end) { return deserializer_type().deserialize( detail::input_adapter(std::forward(begin), std::forward(end))); } @@ -11649,7 +11672,7 @@ class basic_node { /// @return An alias YAML node created from the given anchor node. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/alias_of/ static basic_node alias_of(const basic_node& anchor_node) { - using namespace detail::node_attr_bits; + constexpr detail::node_attr_t anchor_bit = detail::node_attr_bits::anchor_bit; if FK_YAML_UNLIKELY (!anchor_node.has_anchor_name() || !(anchor_node.m_attrs & anchor_bit)) { throw fkyaml::exception("Cannot create an alias without anchor name."); @@ -11657,7 +11680,7 @@ class basic_node { basic_node node = anchor_node; node.m_attrs &= ~detail::node_attr_mask::anchoring; - node.m_attrs |= alias_bit; + node.m_attrs |= detail::node_attr_bits::alias_bit; return node; } // LCOV_EXCL_LINE @@ -11803,7 +11826,7 @@ class basic_node { /// @return true if both types and values are equal, false otherwise. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/operator_eq/ bool operator==(const basic_node& rhs) const noexcept { - detail::node_attr_t this_val_bit = get_node_attrs() & detail::node_attr_mask::value; + const detail::node_attr_t this_val_bit = get_node_attrs() & detail::node_attr_mask::value; if (this_val_bit != (rhs.get_node_attrs() & detail::node_attr_mask::value)) { return false; } @@ -11861,8 +11884,8 @@ class basic_node { return false; } - detail::node_attr_t this_val_bit = get_node_attrs() & detail::node_attr_mask::value; - detail::node_attr_t other_val_bit = rhs.get_node_attrs() & detail::node_attr_mask::value; + const detail::node_attr_t this_val_bit = get_node_attrs() & detail::node_attr_mask::value; + const detail::node_attr_t other_val_bit = rhs.get_node_attrs() & detail::node_attr_mask::value; if (this_val_bit < other_val_bit) { return true; @@ -11935,7 +11958,7 @@ class basic_node { /// @return The type of the YAML node value. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/get_type/ node_type get_type() const noexcept { - detail::node_attr_t attrs = get_node_attrs(); + const detail::node_attr_t attrs = get_node_attrs(); return detail::node_attr_bits::to_node_type(attrs); } @@ -12345,7 +12368,7 @@ class basic_node { m_attrs &= ~detail::node_attr_mask::anchoring; m_attrs |= detail::node_attr_bits::anchor_bit; mp_meta = p_meta; - uint32_t offset = static_cast(mp_meta->anchor_table.count(anchor_name) - 1); + auto offset = static_cast(mp_meta->anchor_table.count(anchor_name) - 1); detail::node_attr_bits::set_anchor_offset(offset, m_attrs); m_prop.anchor = anchor_name; } @@ -12373,7 +12396,7 @@ class basic_node { m_attrs &= ~detail::node_attr_mask::anchoring; m_attrs |= detail::node_attr_bits::anchor_bit; mp_meta = p_meta; - uint32_t offset = static_cast(mp_meta->anchor_table.count(anchor_name) - 1); + auto offset = static_cast(mp_meta->anchor_table.count(anchor_name) - 1); detail::node_attr_bits::set_anchor_offset(offset, m_attrs); m_prop.anchor = std::move(anchor_name); } @@ -12718,6 +12741,7 @@ class basic_node { detail::node_attr_t m_attrs {detail::node_attr_bits::default_bits}; /// The shared set of YAML directives applied to this node. mutable std::shared_ptr> mp_meta { + // NOLINTNEXTLINE(bugprone-unhandled-exception-at-new) std::shared_ptr>(new detail::document_metainfo())}; /// The current node value. node_value m_node_value {}; @@ -12791,7 +12815,7 @@ inline namespace yaml_literals { /// @return The resulting `node` object deserialized from `s`. /// @sa https://fktn-k.github.io/fkYAML/api/operator_literal_yaml/ inline fkyaml::node operator"" _yaml(const char* s, std::size_t n) { - return fkyaml::node::deserialize(std::move(s), std::move(s + n)); + return fkyaml::node::deserialize(s, s + n); } /// @brief The user-defined string literal which deserializes a `char16_t` array into a `node` object. @@ -12800,7 +12824,7 @@ inline fkyaml::node operator"" _yaml(const char* s, std::size_t n) { /// @return The resulting `node` object deserialized from `s`. /// @sa https://fktn-k.github.io/fkYAML/api/operator_literal_yaml/ inline fkyaml::node operator"" _yaml(const char16_t* s, std::size_t n) { - return fkyaml::node::deserialize(std::move(s), std::move(s + n)); + return fkyaml::node::deserialize(s, s + n); } /// @brief The user-defined string literal which deserializes a `char32_t` array into a `node` object. @@ -12809,7 +12833,7 @@ inline fkyaml::node operator"" _yaml(const char16_t* s, std::size_t n) { /// @return The resulting `node` object deserialized from `s`. /// @sa https://fktn-k.github.io/fkYAML/api/operator_literal_yaml/ inline fkyaml::node operator"" _yaml(const char32_t* s, std::size_t n) { - return fkyaml::node::deserialize(std::move(s), std::move(s + n)); + return fkyaml::node::deserialize(s, s + n); } #if FK_YAML_HAS_CHAR8_T diff --git a/test/unit_test/test_input_adapter.cpp b/test/unit_test/test_input_adapter.cpp index 63b09992..fc0a24e3 100644 --- a/test/unit_test/test_input_adapter.cpp +++ b/test/unit_test/test_input_adapter.cpp @@ -72,21 +72,21 @@ TEST_CASE("InputAdapter_IteratorInputAdapterProvider") { SECTION("std::string") { std::string input_str(input); auto input_adapter = fkyaml::detail::input_adapter(input_str); - using iterator_type = typename std::string::iterator; + using iterator_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); } SECTION("std::u16string") { std::u16string input_str(u"test"); auto input_adapter = fkyaml::detail::input_adapter(input_str); - using iterator_type = typename std::u16string::iterator; + using iterator_type = typename std::u16string::const_iterator; REQUIRE(std::is_same>::value); } SECTION("std::u32string") { std::u32string input_str(U"test"); auto input_adapter = fkyaml::detail::input_adapter(input_str); - using iterator_type = typename std::u32string::iterator; + using iterator_type = typename std::u32string::const_iterator; REQUIRE(std::is_same>::value); } @@ -94,7 +94,7 @@ TEST_CASE("InputAdapter_IteratorInputAdapterProvider") { SECTION("std::string_view") { std::string_view input_str_view(input); auto input_adapter = fkyaml::detail::input_adapter(input_str_view); - using iterator_type = typename std::string_view::iterator; + using iterator_type = typename std::string_view::const_iterator; REQUIRE(std::is_same>::value); } @@ -102,7 +102,7 @@ TEST_CASE("InputAdapter_IteratorInputAdapterProvider") { using namespace std::string_view_literals; std::u16string_view input_str_view = u"test"sv; auto input_adapter = fkyaml::detail::input_adapter(input_str_view); - using iterator_type = typename std::u16string_view::iterator; + using iterator_type = typename std::u16string_view::const_iterator; REQUIRE(std::is_same>::value); } @@ -110,7 +110,7 @@ TEST_CASE("InputAdapter_IteratorInputAdapterProvider") { using namespace std::string_view_literals; std::u32string_view input_str_view = U"test"sv; auto input_adapter = fkyaml::detail::input_adapter(input_str_view); - using iterator_type = typename std::u32string_view::iterator; + using iterator_type = typename std::u32string_view::const_iterator; REQUIRE(std::is_same>::value); } #endif @@ -119,7 +119,7 @@ TEST_CASE("InputAdapter_IteratorInputAdapterProvider") { SECTION("std::u8string") { std::u8string input_str(u8"test"); auto input_adapter = fkyaml::detail::input_adapter(input_str); - using iterator_type = typename std::u8string::iterator; + using iterator_type = typename std::u8string::const_iterator; REQUIRE(std::is_same>::value); } @@ -127,7 +127,7 @@ TEST_CASE("InputAdapter_IteratorInputAdapterProvider") { using namespace std::string_view_literals; std::u8string_view input_str_view = u8"test"sv; auto input_adapter = fkyaml::detail::input_adapter(input_str_view); - using iterator_type = typename std::u8string_view::iterator; + using iterator_type = typename std::u8string_view::const_iterator; REQUIRE(std::is_same>::value); } #endif @@ -192,7 +192,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF8N") { SECTION("iterator_input_adapter with std::string") { std::string input = "test source."; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -283,7 +283,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF8BOM") { char(0xEFu), char(0xBBu), char(0xBFu), 't', 'e', 's', 't', ' ', 's', 'o', 'u', 'r', 'c', 'e', '.', 0}; std::string input = raw_input; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -368,7 +368,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF16BEN") { SECTION("iterator_input_adapter with std::string") { std::string input {0, 0x61, 0x30, 0x42, char(0xD8u), 0x40, char(0xDCu), 0x0B, 0, 0x52, 0, 0x5A}; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -409,7 +409,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF16BEN") { char16_t raw_input[] = {0x0061u, 0x3042u, 0xD840u, 0xDC0Bu, 0x0052u, 0x005Au, 0}; std::u16string input = raw_input; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::u16string::iterator; + using itr_type = typename std::u16string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -496,7 +496,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF16BEBOM") { std::string input { char(0xFEu), char(0xFFu), 0, 0x61, 0x30, 0x42, char(0xD8u), 0x40, char(0xDCu), 0x0B, 0, 0x52}; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -536,7 +536,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF16BEBOM") { char16_t raw_input[] = {0xFEFFu, 0x0061u, 0x3042u, 0xD840u, 0xDC0Bu, 0x0052u, 0}; std::u16string input = raw_input; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::u16string::iterator; + using itr_type = typename std::u16string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -619,7 +619,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF16LEN") { SECTION("iterator_input_adapter with std::string") { std::string input {0x61, 0, 0x42, 0x30, 0x40, char(0xD8u), 0x0B, char(0xDCu), 0x52, 0}; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -659,7 +659,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF16LEN") { char16_t raw_input[] = {0x6100u, 0x4230u, 0x40D8u, 0x0BDCu, 0x5200u, 0}; std::u16string input = raw_input; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::u16string::iterator; + using itr_type = typename std::u16string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -745,7 +745,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF16LEBOM") { std::string input { char(0xFFu), char(0xFEu), 0x61, 0, 0x42, 0x30, 0x40, char(0xD8u), 0x0B, char(0xDCu), 0x52, 0}; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -785,7 +785,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF16LEBOM") { char16_t raw_input[] = {0xFFFEu, 0x6100u, 0x4230u, 0x40D8u, 0x0BDCu, 0x5200u, 0}; std::u16string input = raw_input; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::u16string::iterator; + using itr_type = typename std::u16string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -868,7 +868,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF32BEN") { SECTION("iterator_input_adapter with std::string") { std::string input {0, 0, 0, 0x61, 0, 0, 0x30, 0x42, 0, 0x02, 0, 0x0B}; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -906,7 +906,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF32BEN") { char32_t raw_input[] = {0x00000061u, 0x00003042u, 0x0002000Bu, 0x00000000}; std::u32string input = raw_input; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::u32string::iterator; + using itr_type = typename std::u32string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -986,7 +986,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF32BEBOM") { SECTION("iterator_input_adapter with std::string") { std::string input {0, 0, char(0xFEu), char(0xFFu), 0, 0, 0, 0x61, 0, 0, 0x30, 0x42, 0, 0x02, 0, 0x0B}; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -1024,7 +1024,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF32BEBOM") { char32_t raw_input[] = {0x0000FEFFu, 0x00000061u, 0x00003042u, 0x0002000Bu, 0x00000000}; std::u32string input = raw_input; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::u32string::iterator; + using itr_type = typename std::u32string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -1104,7 +1104,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF32LEN") { SECTION("iterator_input_adapter with std::string") { std::string input {0x61, 0, 0, 0, 0x42, 0x30, 0, 0, 0x0B, 0, 0x02, 0}; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -1142,7 +1142,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF32LEN") { char32_t raw_input[] = {0x61000000u, 0x42300000u, 0x0B000200u, 0x00000000}; std::u32string input = raw_input; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::u32string::iterator; + using itr_type = typename std::u32string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -1222,7 +1222,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF32LEBOM") { SECTION("iterator_input_adapter with std::string") { std::string input {char(0xFFu), char(0xFEu), 0, 0, 0x61, 0, 0, 0, 0x42, 0x30, 0, 0, 0x0B, 0, 0x02, 0}; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::string::iterator; + using itr_type = typename std::string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); @@ -1260,7 +1260,7 @@ TEST_CASE("InputAdapter_FillBuffer_UTF32LEBOM") { char32_t raw_input[] = {0xFFFE0000u, 0x61000000u, 0x42300000u, 0x0B000200u, 0x00000000}; std::u32string input = raw_input; auto input_adapter = fkyaml::detail::input_adapter(input); - using itr_type = typename std::u32string::iterator; + using itr_type = typename std::u32string::const_iterator; REQUIRE(std::is_same>::value); fkyaml::detail::str_view buffer = input_adapter.get_buffer_view(); diff --git a/tool/clang_tidy/CMakeLists.txt b/tool/clang_tidy/CMakeLists.txt index 52b8fd57..50575239 100644 --- a/tool/clang_tidy/CMakeLists.txt +++ b/tool/clang_tidy/CMakeLists.txt @@ -17,11 +17,10 @@ message(STATUS "Found clang-tidy. version: ${CLANG_TIDY_VERSION} path: ${CLANG_T #################################### set(HELPER_FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/clang_tidy_helper.cpp") -file(WRITE ${HELPER_FILE_PATH} "") file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/fkYAML/*.hpp) foreach(SRC_FILE ${SRC_FILES}) file(RELATIVE_PATH REL_SRC_FILE "${PROJECT_SOURCE_DIR}/include" ${SRC_FILE}) - file(APPEND ${HELPER_FILE_PATH} "#include <${REL_SRC_FILE}>\n") + file(APPEND ${HELPER_FILE_PATH} "#include <${REL_SRC_FILE}> // NOLINT(misc-include-cleaner)\n") endforeach() file(APPEND ${HELPER_FILE_PATH} "\nint main() { return 0; }\n") @@ -29,7 +28,7 @@ file(APPEND ${HELPER_FILE_PATH} "\nint main() { return 0; }\n") # set options for the clang-tidy tool # ########################################### -set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE}") +set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE};--header-filter=include/") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) #################################### From 5f4f4ddb316d7ede43ed5e5c7b253bba20c7fe27 Mon Sep 17 00:00:00 2001 From: fktn Date: Sun, 27 Oct 2024 01:53:55 +0900 Subject: [PATCH 03/13] Disable -Wdeprecated-literal-operator warnings (#417) * added -Wdeprecated compile option to unit test app builds * disable -Wdeprecated-literal-operator if clang compiler is detected --- include/fkYAML/node.hpp | 12 ++++++++++++ single_include/fkYAML/node.hpp | 12 ++++++++++++ test/unit_test/CMakeLists.txt | 6 +++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/fkYAML/node.hpp b/include/fkYAML/node.hpp index 79d706e4..01945941 100644 --- a/include/fkYAML/node.hpp +++ b/include/fkYAML/node.hpp @@ -1677,6 +1677,13 @@ inline namespace literals { /// @brief namespace for user-defined literals for YAML node objects. inline namespace yaml_literals { +// Whitespace before the literal operator identifier is deprecated in C++23 or better but required in C++11. +// Ignore the warning as a workaround. https://github.com/fktn-k/fkYAML/pull/417 +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" +#endif + /// @brief The user-defined string literal which deserializes a `char` array into a `node` object. /// @param s An input `char` array. /// @param n The size of `s`. @@ -1712,6 +1719,11 @@ inline fkyaml::node operator"" _yaml(const char32_t* s, std::size_t n) { inline fkyaml::node operator"" _yaml(const char8_t* s, std::size_t n) { return fkyaml::node::deserialize((const char8_t*)s, (const char8_t*)s + n); } + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + #endif } // namespace yaml_literals diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index 5cde849e..aaad0593 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -12809,6 +12809,13 @@ inline namespace literals { /// @brief namespace for user-defined literals for YAML node objects. inline namespace yaml_literals { +// Whitespace before the literal operator identifier is deprecated in C++23 or better but required in C++11. +// Ignore the warning as a workaround. https://github.com/fktn-k/fkYAML/pull/417 +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" +#endif + /// @brief The user-defined string literal which deserializes a `char` array into a `node` object. /// @param s An input `char` array. /// @param n The size of `s`. @@ -12844,6 +12851,11 @@ inline fkyaml::node operator"" _yaml(const char32_t* s, std::size_t n) { inline fkyaml::node operator"" _yaml(const char8_t* s, std::size_t n) { return fkyaml::node::deserialize((const char8_t*)s, (const char8_t*)s + n); } + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + #endif } // namespace yaml_literals diff --git a/test/unit_test/CMakeLists.txt b/test/unit_test/CMakeLists.txt index a887ae5a..3649052e 100644 --- a/test/unit_test/CMakeLists.txt +++ b/test/unit_test/CMakeLists.txt @@ -116,18 +116,18 @@ target_compile_options( > # GNU $<$: - -Wall -Wextra -Werror -pedantic -Wpedantic --all-warnings --extra-warnings + -Wall -Wextra -Werror -pedantic -Wpedantic -Wdeprecated --all-warnings --extra-warnings -Wno-deprecated-declarations # for testing deprecated functions -Wno-self-move # necessary to build the detail::iterator class test > # Clang $<$: - -Wall -Wextra -Werror -pedantic + -Wall -Wextra -Werror -pedantic -Wdeprecated -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-deprecated-declarations # for testing deprecated functions > $<$: - -Wall -Wextra -Werror -pedantic + -Wall -Wextra -Werror -pedantic -Wdeprecated -Wno-deprecated-declarations # for testing deprecated functions > # IntelLLVM From b18b27af29473b7248059b717322b1d68fb054aa Mon Sep 17 00:00:00 2001 From: fktn Date: Sun, 27 Oct 2024 04:17:34 +0900 Subject: [PATCH 04/13] GA workflow jobs with more AppleClang versions on macOS (#416) * added newly added Xcode versions for macos-14 & macos-15 in macos.yml * updated supported compilers list --- .github/workflows/macos.yml | 28 +++++++++++++++++++- README.md | 2 ++ docs/mkdocs/docs/home/supported_compilers.md | 2 ++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index fd69d8c3..c31141e8 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -109,7 +109,33 @@ jobs: runs-on: macos-14 strategy: matrix: - xcode: [ '14.3.1', '15.0.1', '15.1', '15.2', '15.3' ] + xcode: [ '14.3.1', '15.0.1', '15.1', '15.2', '15.3', '15.4', '16' ] + 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_macos15: + timeout-minutes: 10 + runs-on: macos-15 + strategy: + matrix: + xcode: [ '16' ] build_type: [ Debug, Release ] env: DEVELOPER_DIR: /Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer diff --git a/README.md b/README.md index 5ca47033..1fe2df19 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,8 @@ Currently, the following compilers are known to work and used in GitHub Actions | 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.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) | diff --git a/docs/mkdocs/docs/home/supported_compilers.md b/docs/mkdocs/docs/home/supported_compilers.md index 7a873635..ada073a0 100644 --- a/docs/mkdocs/docs/home/supported_compilers.md +++ b/docs/mkdocs/docs/home/supported_compilers.md @@ -15,6 +15,8 @@ Currently, the following compilers are known to work and used in GitHub Actions | 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.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) | From 9f704b08801f2a9a50603ebcee5a70b31cadbee4 Mon Sep 17 00:00:00 2001 From: fktn Date: Sun, 27 Oct 2024 13:56:53 +0900 Subject: [PATCH 05/13] Fix somehow shadowed clang-tidy warnings (#418) * fixed clang-tidy(14.0.0) warnings somehow shadowed in using 18.1.3 * [bot] run clang-format & amalgamation --- .clang-tidy | 2 ++ .../fkYAML/detail/conversions/scalar_conv.hpp | 18 +++++----- .../detail/encodings/utf_encode_detector.hpp | 2 +- include/fkYAML/detail/input/input_adapter.hpp | 14 +++++--- single_include/fkYAML/node.hpp | 34 +++++++++++-------- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 085b78f2..aa9f337e 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -20,6 +20,7 @@ Checks: '*, -google-readability-todo, -hicpp-avoid-c-arrays, -hicpp-explicit-conversions, + -hicpp-noexcept-move, -hicpp-signed-bitwise, -hicpp-uppercase-literal-suffix, -hicpp-vararg, @@ -32,6 +33,7 @@ Checks: '*, -modernize-use-nodiscard, -modernize-type-traits, -modernize-use-trailing-return-type, + -performance-noexcept-move-constructor, -readability-function-cognitive-complexity, -readability-identifier-length, -readability-implicit-bool-conversion, diff --git a/include/fkYAML/detail/conversions/scalar_conv.hpp b/include/fkYAML/detail/conversions/scalar_conv.hpp index 7a3599f0..678dfef7 100644 --- a/include/fkYAML/detail/conversions/scalar_conv.hpp +++ b/include/fkYAML/detail/conversions/scalar_conv.hpp @@ -444,7 +444,7 @@ inline bool atoi_dec_unchecked(const char* p_begin, const char* p_end, IntType& return false; } // Overflow is intentional when the IntType is signed. - i = i * IntType(10) + IntType(c - '0'); + i = i * static_cast(10) + static_cast(c - '0'); } while (++p_begin != p_end); return true; @@ -569,7 +569,7 @@ inline bool atoi_oct(const char* p_begin, const char* p_end, IntType& i) noexcep if FK_YAML_UNLIKELY (c < '0' || '7' < c) { return false; } - i = i * IntType(8) + IntType(c - '0'); + i = i * static_cast(8) + static_cast(c - '0'); } while (++p_begin != p_end); return true; @@ -608,18 +608,18 @@ inline bool atoi_hex(const char* p_begin, const char* p_end, IntType& i) noexcep const char c = *p_begin; IntType ci = 0; if ('0' <= c && c <= '9') { - ci = IntType(c - '0'); + ci = static_cast(c - '0'); } else if ('A' <= c && c <= 'F') { - ci = IntType(c - 'A' + 10); + ci = static_cast(c - 'A' + 10); } else if ('a' <= c && c <= 'f') { - ci = IntType(c - 'a' + 10); + ci = static_cast(c - 'a' + 10); } else { return false; } - i = i * IntType(16) + ci; + i = i * static_cast(16) + ci; // NOLINTEND(bugprone-misplaced-widening-cast) } while (++p_begin != p_end); @@ -662,7 +662,7 @@ inline bool atoi(CharItr begin, CharItr end, IntType& i) noexcept { const bool success = atoi_dec_neg(p_begin + 1, p_end, i); if (success) { - i *= IntType(-1); + i *= static_cast(-1); } return success; @@ -790,7 +790,7 @@ inline bool atof(CharItr begin, CharItr end, FloatType& f) noexcept(noexcept(ato (std::strncmp(p_from_second, ".Inf", 4) == 0) || (std::strncmp(p_from_second, ".INF", 4) == 0); if (is_inf) { - set_infinity(f, *p_begin == '-' ? FloatType(-1.) : FloatType(1.)); + set_infinity(f, *p_begin == '-' ? static_cast(-1.) : static_cast(1.)); return true; } } @@ -804,7 +804,7 @@ inline bool atof(CharItr begin, CharItr end, FloatType& f) noexcept(noexcept(ato const bool is_inf = (std::strncmp(p_begin, ".inf", 4) == 0) || (std::strncmp(p_begin, ".Inf", 4) == 0) || (std::strncmp(p_begin, ".INF", 4) == 0); if (is_inf) { - set_infinity(f, FloatType(1.)); + set_infinity(f, static_cast(1.)); return true; } diff --git a/include/fkYAML/detail/encodings/utf_encode_detector.hpp b/include/fkYAML/detail/encodings/utf_encode_detector.hpp index 08e6780b..09d6326a 100644 --- a/include/fkYAML/detail/encodings/utf_encode_detector.hpp +++ b/include/fkYAML/detail/encodings/utf_encode_detector.hpp @@ -103,7 +103,7 @@ struct utf_encode_detector::v std::array bytes {}; bytes.fill(0xFFu); for (int i = 0; i < 4 && begin + i != end; i++) { - bytes[i] = uint8_t(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) + bytes[i] = static_cast(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; diff --git a/include/fkYAML/detail/input/input_adapter.hpp b/include/fkYAML/detail/input/input_adapter.hpp index b55933ba..e8510df0 100644 --- a/include/fkYAML/detail/input/input_adapter.hpp +++ b/include/fkYAML/detail/input/input_adapter.hpp @@ -94,7 +94,7 @@ class iterator_input_adapter bytes {first, uint8_t(*current++)}; + const std::initializer_list bytes {first, static_cast(*current++)}; const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); @@ -102,7 +102,8 @@ class iterator_input_adapter bytes {first, uint8_t(*current++), uint8_t(*current++)}; + const std::initializer_list bytes { + first, static_cast(*current++), static_cast(*current++)}; const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); @@ -111,7 +112,10 @@ class iterator_input_adapter bytes { - first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; + first, + static_cast(*current++), + static_cast(*current++), + static_cast(*current++)}; const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); @@ -172,8 +176,8 @@ class iterator_input_adapter(uint8_t(*current++) << shift_bits[0]); - utf16 |= static_cast(uint8_t(*current++) << shift_bits[1]); + auto utf16 = static_cast(static_cast(*current++) << shift_bits[0]); + utf16 |= static_cast(static_cast(*current++) << shift_bits[1]); // skip appending CRs. if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index aaad0593..9a719c55 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -4450,7 +4450,7 @@ inline bool atoi_dec_unchecked(const char* p_begin, const char* p_end, IntType& return false; } // Overflow is intentional when the IntType is signed. - i = i * IntType(10) + IntType(c - '0'); + i = i * static_cast(10) + static_cast(c - '0'); } while (++p_begin != p_end); return true; @@ -4575,7 +4575,7 @@ inline bool atoi_oct(const char* p_begin, const char* p_end, IntType& i) noexcep if FK_YAML_UNLIKELY (c < '0' || '7' < c) { return false; } - i = i * IntType(8) + IntType(c - '0'); + i = i * static_cast(8) + static_cast(c - '0'); } while (++p_begin != p_end); return true; @@ -4614,18 +4614,18 @@ inline bool atoi_hex(const char* p_begin, const char* p_end, IntType& i) noexcep const char c = *p_begin; IntType ci = 0; if ('0' <= c && c <= '9') { - ci = IntType(c - '0'); + ci = static_cast(c - '0'); } else if ('A' <= c && c <= 'F') { - ci = IntType(c - 'A' + 10); + ci = static_cast(c - 'A' + 10); } else if ('a' <= c && c <= 'f') { - ci = IntType(c - 'a' + 10); + ci = static_cast(c - 'a' + 10); } else { return false; } - i = i * IntType(16) + ci; + i = i * static_cast(16) + ci; // NOLINTEND(bugprone-misplaced-widening-cast) } while (++p_begin != p_end); @@ -4668,7 +4668,7 @@ inline bool atoi(CharItr begin, CharItr end, IntType& i) noexcept { const bool success = atoi_dec_neg(p_begin + 1, p_end, i); if (success) { - i *= IntType(-1); + i *= static_cast(-1); } return success; @@ -4796,7 +4796,7 @@ inline bool atof(CharItr begin, CharItr end, FloatType& f) noexcept(noexcept(ato (std::strncmp(p_from_second, ".Inf", 4) == 0) || (std::strncmp(p_from_second, ".INF", 4) == 0); if (is_inf) { - set_infinity(f, *p_begin == '-' ? FloatType(-1.) : FloatType(1.)); + set_infinity(f, *p_begin == '-' ? static_cast(-1.) : static_cast(1.)); return true; } } @@ -4810,7 +4810,7 @@ inline bool atof(CharItr begin, CharItr end, FloatType& f) noexcept(noexcept(ato const bool is_inf = (std::strncmp(p_begin, ".inf", 4) == 0) || (std::strncmp(p_begin, ".Inf", 4) == 0) || (std::strncmp(p_begin, ".INF", 4) == 0); if (is_inf) { - set_infinity(f, FloatType(1.)); + set_infinity(f, static_cast(1.)); return true; } @@ -7995,7 +7995,7 @@ struct utf_encode_detector::v std::array bytes {}; bytes.fill(0xFFu); for (int i = 0; i < 4 && begin + i != end; i++) { - bytes[i] = uint8_t(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) + bytes[i] = static_cast(begin[i]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) } bool has_bom = false; @@ -8311,7 +8311,7 @@ class iterator_input_adapter bytes {first, uint8_t(*current++)}; + const std::initializer_list bytes {first, static_cast(*current++)}; const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); @@ -8319,7 +8319,8 @@ class iterator_input_adapter bytes {first, uint8_t(*current++), uint8_t(*current++)}; + const std::initializer_list bytes { + first, static_cast(*current++), static_cast(*current++)}; const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); @@ -8328,7 +8329,10 @@ class iterator_input_adapter bytes { - first, uint8_t(*current++), uint8_t(*current++), uint8_t(*current++)}; + first, + static_cast(*current++), + static_cast(*current++), + static_cast(*current++)}; const bool is_valid = utf8::validate(bytes); if FK_YAML_UNLIKELY (!is_valid) { throw fkyaml::invalid_encoding("Invalid UTF-8 encoding.", bytes); @@ -8389,8 +8393,8 @@ class iterator_input_adapter(uint8_t(*current++) << shift_bits[0]); - utf16 |= static_cast(uint8_t(*current++) << shift_bits[1]); + auto utf16 = static_cast(static_cast(*current++) << shift_bits[0]); + utf16 |= static_cast(static_cast(*current++) << shift_bits[1]); // skip appending CRs. if FK_YAML_LIKELY (utf16 != char16_t(0x000Du)) { From 4b2490c9cde2c67075aca2aa58d3ee7d9d426ac3 Mon Sep 17 00:00:00 2001 From: fktn Date: Mon, 28 Oct 2024 05:29:52 +0900 Subject: [PATCH 06/13] Numeric scalar conversions inside basic_node::get_value API (#419) * added internal numeric scalar conversions in from_node() functions * updated document/example for the basic_node::get_value() API * added node to uint64_t conversions --- docs/examples/ex_basic_node_get_value.cpp | 16 +- docs/examples/ex_basic_node_get_value.output | 6 +- docs/examples/ex_macros_versions.output | 2 +- docs/mkdocs/docs/api/basic_node/get_value.md | 19 +- .../fkYAML/detail/conversions/from_node.hpp | 281 ++++++++++++------ single_include/fkYAML/node.hpp | 281 ++++++++++++------ test/unit_test/test_node_class.cpp | 163 +++++++--- 7 files changed, 549 insertions(+), 219 deletions(-) diff --git a/docs/examples/ex_basic_node_get_value.cpp b/docs/examples/ex_basic_node_get_value.cpp index 418d3fae..4325b266 100644 --- a/docs/examples/ex_basic_node_get_value.cpp +++ b/docs/examples/ex_basic_node_get_value.cpp @@ -11,17 +11,23 @@ int main() { // create a YAML node. - fkyaml::node n = 123; + fkyaml::node n = 1.23; fkyaml::node n2 = "foo"; - // get references to the value. - auto int_val = n.get_value(); + // get the node value (value gets copied). + auto float_val = n.get_value(); auto str_val = n2.get_value(); - // print the values - std::cout << int_val << std::endl; + std::cout << float_val << std::endl; std::cout << str_val << std::endl; + // Numeric scalar value can be converted to other numeric types inside get_value(). + auto bool_val = n.get_value(); + auto int_val = n.get_value(); + + std::cout << std::boolalpha << bool_val << std::endl; + std::cout << int_val << std::endl; + // specifying incompatible type throws an exception try { auto float_val = n2.get_value(); diff --git a/docs/examples/ex_basic_node_get_value.output b/docs/examples/ex_basic_node_get_value.output index 1f00b91f..a1eec460 100644 --- a/docs/examples/ex_basic_node_get_value.output +++ b/docs/examples/ex_basic_node_get_value.output @@ -1,3 +1,5 @@ -123 +1.23 foo -type_error: The target node value type is not float number type. type=STRING +true +1 +type_error: The target node value type is not compatible with float number type. type=STRING diff --git a/docs/examples/ex_macros_versions.output b/docs/examples/ex_macros_versions.output index 09fd8435..7466728c 100644 --- a/docs/examples/ex_macros_versions.output +++ b/docs/examples/ex_macros_versions.output @@ -1 +1 @@ -fkYAML version 0.3.11 +fkYAML version 0.3.13 diff --git a/docs/mkdocs/docs/api/basic_node/get_value.md b/docs/mkdocs/docs/api/basic_node/get_value.md index d968eed4..e5e64491 100644 --- a/docs/mkdocs/docs/api/basic_node/get_value.md +++ b/docs/mkdocs/docs/api/basic_node/get_value.md @@ -16,7 +16,24 @@ T get_value() const noexcept( Explicit type conversion between the internally stored YAML node value and a compatible value which is [copy-constructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and [default-constructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). The conversion relies on the [`node_value_converter`](../node_value_converter/index.md)::[`from_node`](../node_value_converter/from_node.md). This API makes a copy of the value. -If the copying costs a lot, or if you need an address of the original value, then it is more suitable to call [`get_value_ref`](get_value_ref.md) instead. +If the copying costs a lot, or if you need an address of the original value, then you should call [`get_value_ref`](get_value_ref.md) instead. + +If the YAML node value is a null, boolean, integer or floating point, this function internally executes type conversion according to the following rules which all depend on the template paramter type `T`: +* If the YAML node value is a **null** (node_type::NULL_OBJECT), the value can be converted to: + * `false` (boolean) + * `0` (integer) + * `0.0` (floating point) +* If the YAML node value is a **boolean** (node_type::BOOLEAN), the value can be converted to: + * `1 /*true*/` or `0 /*false*/` (integer) + * `1.0 /*true*/` or `0.0 /*false*/` (floating point) +* If the YAML node value is a **integer** (node_type::INTEGER), the value can be converted to: + * `true /*non-0*/` or `false /*0*/` (boolean) + * `static_cast`ed floating point value (floating point) +* If the YAML node value is a **floating point** (node_type::FLOAT), the value can be converted to: + * `true /*non-0*/` or `false /*0*/` (boolean) + * `static_cast`ed integer value (integer) + +Note that those scalar type cannot be converted to a sequence, mapping, string scalar and throws a [`type_error`](../exception/type_error.md). ## **Template Parameters** diff --git a/include/fkYAML/detail/conversions/from_node.hpp b/include/fkYAML/detail/conversions/from_node.hpp index 9a9f5484..c5126c57 100644 --- a/include/fkYAML/detail/conversions/from_node.hpp +++ b/include/fkYAML/detail/conversions/from_node.hpp @@ -80,6 +80,14 @@ inline void from_node(const BasicNodeType& n, typename BasicNodeType::mapping_ty } } +/// @brief from node function for mappings whose key and value are of both compatible types. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam CompatibleKeyType Mapping key type compatible with BasicNodeType. +/// @tparam CompatibleValueType Mapping value type compatible with BasicNodeType. +/// @tparam Compare Comparator type for mapping keys. +/// @tparam Allocator Allocator type for destination mapping object. +/// @param n A node object. +/// @param m Mapping container object to store converted key/value objects. template < typename BasicNodeType, typename CompatibleKeyType, typename CompatibleValueType, typename Compare, typename Allocator, @@ -100,10 +108,10 @@ inline void from_node(const BasicNodeType& n, std::map::value, int> = 0> inline void from_node(const BasicNodeType& n, std::nullptr_t& null) { // to ensure the target node value type is null. @@ -113,118 +121,221 @@ inline void from_node(const BasicNodeType& n, std::nullptr_t& null) { null = nullptr; } -/// @brief from_node function for BasicNodeType::boolean_type objects. +/// @brief from_node function for booleans. /// @tparam BasicNodeType A basic_node template instance type. -/// @param n A basic_node object. -/// @param b A boolean node value object. +/// @param n A node object. +/// @param b Storage for a boolean value. template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::boolean_type& b) { - if FK_YAML_UNLIKELY (!n.is_boolean()) { - throw type_error("The target node value type is not boolean type.", n.get_type()); +inline void from_node(const BasicNodeType& n, bool& b) { + switch (n.get_type()) { + case node_type::NULL_OBJECT: + // nullptr is converted to false just as C++ implicitly does. + b = false; + break; + case node_type::BOOLEAN: + b = static_cast(n.template get_value_ref()); + break; + case node_type::INTEGER: + // true: non-zero, false: zero + b = (n.template get_value_ref() != 0); + break; + case node_type::FLOAT: + // true: non-zero, false: zero + using float_type = typename BasicNodeType::float_number_type; + b = (n.template get_value_ref() != static_cast(0.)); + break; + case node_type::SEQUENCE: + case node_type::MAPPING: + case node_type::STRING: + default: + throw type_error("The target node value type is not compatible with boolean type.", n.get_type()); } - b = n.template get_value_ref(); } -/// @brief from_node function for BasicNodeType::integer_type objects. +/// @brief Helper struct for node-to-int conversion. /// @tparam BasicNodeType A basic_node template instance type. -/// @param n A basic_node object. -/// @param i An integer node value object. -template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::integer_type& i) { - if FK_YAML_UNLIKELY (!n.is_integer()) { - throw type_error("The target node value type is not integer type.", n.get_type()); +/// @tparam IntType Target integer value type (same as BasicNodeType::integer_type) +template < + typename BasicNodeType, typename IntType, bool = std::is_same::value> +struct from_node_int_helper { + /// @brief Convert node's integer value to the target integer type. + /// @param n A node object. + /// @return An integer value converted from the node's integer value. + static IntType convert(const BasicNodeType& n) { + return n.template get_value_ref(); } - i = n.template get_value_ref(); -} +}; + +/// @brief Helper struct for node-to-int conversion if IntType is not the node's integer value type. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam IntType Target integer value type (different from BasicNodeType::integer_type) +template +struct from_node_int_helper { + /// @brief Convert node's integer value to non-uint64_t integer types. + /// @param n A node object. + /// @return An integer value converted from the node's integer value. + static IntType convert(const BasicNodeType& n) { + using node_int_type = typename BasicNodeType::integer_type; + const node_int_type tmp_int = n.template get_value_ref(); + + // under/overflow check. + if (std::is_same::value) { + if FK_YAML_UNLIKELY (tmp_int < 0) { + throw exception("Integer value underflow detected."); + } + } + else { + if FK_YAML_UNLIKELY (tmp_int < static_cast(std::numeric_limits::min())) { + throw exception("Integer value underflow detected."); + } + if FK_YAML_UNLIKELY (static_cast(std::numeric_limits::max()) < tmp_int) { + throw exception("Integer value overflow detected."); + } + } -/// @brief from_node function for other integer objects. (i.e., not BasicNodeType::integer_type) + return static_cast(tmp_int); + } +}; + +/// @brief from_node function for integers. +/// @note If node's value is null, boolean, or float, such a value is converted into an integer internally. /// @tparam BasicNodeType A basic_node template instance type. /// @tparam IntegerType An integer value type. -/// @param n A basic_node object. -/// @param i An integer node value object. +/// @param n A node object. +/// @param i Storage for an integer value. template < typename BasicNodeType, typename IntegerType, - enable_if_t< - conjunction< - is_non_bool_integral, - negation>>::value, - int> = 0> + enable_if_t, is_non_bool_integral>::value, int> = 0> inline void from_node(const BasicNodeType& n, IntegerType& i) { - if FK_YAML_UNLIKELY (!n.is_integer()) { - throw type_error("The target node value type is not integer type.", n.get_type()); - } + switch (n.get_type()) { + case node_type::NULL_OBJECT: + // nullptr is interpreted as 0 + i = static_cast(0); + break; + case node_type::BOOLEAN: + i = static_cast(n.template get_value_ref()) + ? static_cast(1) + : static_cast(0); + break; + case node_type::INTEGER: + i = from_node_int_helper::convert(n); + break; + case node_type::FLOAT: { + // int64_t should be safe to express integer part values of possible floating point types. + const auto tmp_int = + static_cast(n.template get_value_ref()); + + // under/overflow check. + if (std::is_same::value) { + if FK_YAML_UNLIKELY (tmp_int < 0) { + throw exception("Integer value underflow detected."); + } + } + else { + if FK_YAML_UNLIKELY (tmp_int < static_cast(std::numeric_limits::min())) { + throw exception("Integer value underflow detected."); + } + if FK_YAML_UNLIKELY (static_cast(std::numeric_limits::max()) < tmp_int) { + throw exception("Integer value overflow detected."); + } + } - // under/overflow check. - using node_int_type = typename BasicNodeType::integer_type; - const node_int_type tmp_int = n.template get_value_ref(); - if FK_YAML_UNLIKELY (tmp_int < static_cast(std::numeric_limits::min())) { - throw exception("Integer value underflow detected."); + i = static_cast(tmp_int); + break; } - if FK_YAML_UNLIKELY (static_cast(std::numeric_limits::max()) < tmp_int) { - throw exception("Integer value overflow detected."); + case node_type::SEQUENCE: + case node_type::MAPPING: + case node_type::STRING: + default: + throw type_error("The target node value type is not compatible with integer type.", n.get_type()); } - - i = static_cast(tmp_int); } -/// @brief from_node function for BasicNodeType::float_number_type objects. +/// @brief Helper struct for node-to-float conversion if FloatType is the node's floating point value type. /// @tparam BasicNodeType A basic_node template instance type. -/// @param n A basic_node object. -/// @param f A float number node value object. -template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::float_number_type& f) { - if FK_YAML_UNLIKELY (!n.is_float_number()) { - throw type_error("The target node value type is not float number type.", n.get_type()); - } - f = n.template get_value_ref(); -} - -/// @brief from_node function for other float number objects. (i.e., not BasicNodeType::float_number_type) -/// @tparam BasicNodeType A basic_node template instance type. -/// @tparam FloatType A float number value type. -/// @param n A basic_node object. -/// @param f A float number node value object. +/// @tparam FloatType Target floating point value type (same as the BasicNodeType::float_number_type) template < typename BasicNodeType, typename FloatType, - enable_if_t< - conjunction< - std::is_floating_point, - negation>>::value, - int> = 0> -inline void from_node(const BasicNodeType& n, FloatType& f) { - if FK_YAML_UNLIKELY (!n.is_float_number()) { - throw type_error("The target node value type is not float number type.", n.get_type()); + bool = std::is_same::value> +struct from_node_float_helper { + /// @brief Convert node's floating point value to the target floating point type. + /// @param n A node object. + /// @return A floating point value converted from the node's floating point value. + static FloatType convert(const BasicNodeType& n) { + return n.template get_value_ref(); } +}; - using node_float_type = typename BasicNodeType::float_number_type; - auto tmp_float = n.template get_value_ref(); +/// @brief Helper struct for node-to-float conversion if IntType is not the node's floating point value type. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam FloatType Target floating point value type (different from BasicNodeType::float_number_type) +template +struct from_node_float_helper { + /// @brief Convert node's floating point value to the target floating point type. + /// @param n A node object. + /// @return A floating point value converted from the node's floating point value. + static FloatType convert(const BasicNodeType& n) { + using node_float_type = typename BasicNodeType::float_number_type; + auto tmp_float = n.template get_value_ref(); + + // check if the value is an infinite number (either positive or negative) + if (std::isinf(tmp_float)) { + if (tmp_float == std::numeric_limits::infinity()) { + return std::numeric_limits::infinity(); + } + + return static_cast(-1.) * std::numeric_limits::infinity(); + } - // check if the value is an infinite number (either positive or negative) - if (std::isinf(tmp_float)) { - if (tmp_float == std::numeric_limits::infinity()) { - f = std::numeric_limits::infinity(); - return; + // check if the value is not a number + if (std::isnan(tmp_float)) { + return std::numeric_limits::quiet_NaN(); } - f = -1 * std::numeric_limits::infinity(); - return; - } + // check if the value is expressible as FloatType. + if FK_YAML_UNLIKELY (tmp_float < std::numeric_limits::lowest()) { + throw exception("Floating point value underflow detected."); + } + if FK_YAML_UNLIKELY (std::numeric_limits::max() < tmp_float) { + throw exception("Floating point value overflow detected."); + } - // check if the value is not a number - if (std::isnan(tmp_float)) { - f = std::numeric_limits::quiet_NaN(); - return; + return static_cast(tmp_float); } +}; - // check if the value is expressible as FloatType. - if FK_YAML_UNLIKELY (tmp_float < std::numeric_limits::lowest()) { - throw exception("Floating point value underflow detected."); - } - if FK_YAML_UNLIKELY (std::numeric_limits::max() < tmp_float) { - throw exception("Floating point value overflow detected."); +/// @brief from_node function for floating point values. +/// @note If node's value is null, boolean, or integer, such a value is converted into a floating point internally. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam FloatType A floating point value type. +/// @param n A node object. +/// @param f Storage for a float point value. +template < + typename BasicNodeType, typename FloatType, + enable_if_t, std::is_floating_point>::value, int> = 0> +inline void from_node(const BasicNodeType& n, FloatType& f) { + switch (n.get_type()) { + case node_type::NULL_OBJECT: + // nullptr is interpreted as 0.0 + f = static_cast(0.); + break; + case node_type::BOOLEAN: + f = static_cast(n.template get_value_ref()) + ? static_cast(1.) + : static_cast(0.); + break; + case node_type::INTEGER: + f = static_cast(n.template get_value_ref()); + break; + case node_type::FLOAT: + f = from_node_float_helper::convert(n); + break; + case node_type::SEQUENCE: + case node_type::MAPPING: + case node_type::STRING: + default: + throw type_error("The target node value type is not compatible with float number type.", n.get_type()); } - - f = static_cast(tmp_float); } /// @brief from_node function for BasicNodeType::string_type objects. diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index 9a719c55..d465ce4c 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -10388,6 +10388,14 @@ inline void from_node(const BasicNodeType& n, typename BasicNodeType::mapping_ty } } +/// @brief from node function for mappings whose key and value are of both compatible types. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam CompatibleKeyType Mapping key type compatible with BasicNodeType. +/// @tparam CompatibleValueType Mapping value type compatible with BasicNodeType. +/// @tparam Compare Comparator type for mapping keys. +/// @tparam Allocator Allocator type for destination mapping object. +/// @param n A node object. +/// @param m Mapping container object to store converted key/value objects. template < typename BasicNodeType, typename CompatibleKeyType, typename CompatibleValueType, typename Compare, typename Allocator, @@ -10408,10 +10416,10 @@ inline void from_node(const BasicNodeType& n, std::map::value, int> = 0> inline void from_node(const BasicNodeType& n, std::nullptr_t& null) { // to ensure the target node value type is null. @@ -10421,118 +10429,221 @@ inline void from_node(const BasicNodeType& n, std::nullptr_t& null) { null = nullptr; } -/// @brief from_node function for BasicNodeType::boolean_type objects. +/// @brief from_node function for booleans. /// @tparam BasicNodeType A basic_node template instance type. -/// @param n A basic_node object. -/// @param b A boolean node value object. +/// @param n A node object. +/// @param b Storage for a boolean value. template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::boolean_type& b) { - if FK_YAML_UNLIKELY (!n.is_boolean()) { - throw type_error("The target node value type is not boolean type.", n.get_type()); +inline void from_node(const BasicNodeType& n, bool& b) { + switch (n.get_type()) { + case node_type::NULL_OBJECT: + // nullptr is converted to false just as C++ implicitly does. + b = false; + break; + case node_type::BOOLEAN: + b = static_cast(n.template get_value_ref()); + break; + case node_type::INTEGER: + // true: non-zero, false: zero + b = (n.template get_value_ref() != 0); + break; + case node_type::FLOAT: + // true: non-zero, false: zero + using float_type = typename BasicNodeType::float_number_type; + b = (n.template get_value_ref() != static_cast(0.)); + break; + case node_type::SEQUENCE: + case node_type::MAPPING: + case node_type::STRING: + default: + throw type_error("The target node value type is not compatible with boolean type.", n.get_type()); } - b = n.template get_value_ref(); } -/// @brief from_node function for BasicNodeType::integer_type objects. +/// @brief Helper struct for node-to-int conversion. /// @tparam BasicNodeType A basic_node template instance type. -/// @param n A basic_node object. -/// @param i An integer node value object. -template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::integer_type& i) { - if FK_YAML_UNLIKELY (!n.is_integer()) { - throw type_error("The target node value type is not integer type.", n.get_type()); +/// @tparam IntType Target integer value type (same as BasicNodeType::integer_type) +template < + typename BasicNodeType, typename IntType, bool = std::is_same::value> +struct from_node_int_helper { + /// @brief Convert node's integer value to the target integer type. + /// @param n A node object. + /// @return An integer value converted from the node's integer value. + static IntType convert(const BasicNodeType& n) { + return n.template get_value_ref(); } - i = n.template get_value_ref(); -} +}; -/// @brief from_node function for other integer objects. (i.e., not BasicNodeType::integer_type) +/// @brief Helper struct for node-to-int conversion if IntType is not the node's integer value type. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam IntType Target integer value type (different from BasicNodeType::integer_type) +template +struct from_node_int_helper { + /// @brief Convert node's integer value to non-uint64_t integer types. + /// @param n A node object. + /// @return An integer value converted from the node's integer value. + static IntType convert(const BasicNodeType& n) { + using node_int_type = typename BasicNodeType::integer_type; + const node_int_type tmp_int = n.template get_value_ref(); + + // under/overflow check. + if (std::is_same::value) { + if FK_YAML_UNLIKELY (tmp_int < 0) { + throw exception("Integer value underflow detected."); + } + } + else { + if FK_YAML_UNLIKELY (tmp_int < static_cast(std::numeric_limits::min())) { + throw exception("Integer value underflow detected."); + } + if FK_YAML_UNLIKELY (static_cast(std::numeric_limits::max()) < tmp_int) { + throw exception("Integer value overflow detected."); + } + } + + return static_cast(tmp_int); + } +}; + +/// @brief from_node function for integers. +/// @note If node's value is null, boolean, or float, such a value is converted into an integer internally. /// @tparam BasicNodeType A basic_node template instance type. /// @tparam IntegerType An integer value type. -/// @param n A basic_node object. -/// @param i An integer node value object. +/// @param n A node object. +/// @param i Storage for an integer value. template < typename BasicNodeType, typename IntegerType, - enable_if_t< - conjunction< - is_non_bool_integral, - negation>>::value, - int> = 0> + enable_if_t, is_non_bool_integral>::value, int> = 0> inline void from_node(const BasicNodeType& n, IntegerType& i) { - if FK_YAML_UNLIKELY (!n.is_integer()) { - throw type_error("The target node value type is not integer type.", n.get_type()); - } - - // under/overflow check. - using node_int_type = typename BasicNodeType::integer_type; - const node_int_type tmp_int = n.template get_value_ref(); - if FK_YAML_UNLIKELY (tmp_int < static_cast(std::numeric_limits::min())) { - throw exception("Integer value underflow detected."); - } - if FK_YAML_UNLIKELY (static_cast(std::numeric_limits::max()) < tmp_int) { - throw exception("Integer value overflow detected."); - } + switch (n.get_type()) { + case node_type::NULL_OBJECT: + // nullptr is interpreted as 0 + i = static_cast(0); + break; + case node_type::BOOLEAN: + i = static_cast(n.template get_value_ref()) + ? static_cast(1) + : static_cast(0); + break; + case node_type::INTEGER: + i = from_node_int_helper::convert(n); + break; + case node_type::FLOAT: { + // int64_t should be safe to express integer part values of possible floating point types. + const auto tmp_int = + static_cast(n.template get_value_ref()); - i = static_cast(tmp_int); -} + // under/overflow check. + if (std::is_same::value) { + if FK_YAML_UNLIKELY (tmp_int < 0) { + throw exception("Integer value underflow detected."); + } + } + else { + if FK_YAML_UNLIKELY (tmp_int < static_cast(std::numeric_limits::min())) { + throw exception("Integer value underflow detected."); + } + if FK_YAML_UNLIKELY (static_cast(std::numeric_limits::max()) < tmp_int) { + throw exception("Integer value overflow detected."); + } + } -/// @brief from_node function for BasicNodeType::float_number_type objects. -/// @tparam BasicNodeType A basic_node template instance type. -/// @param n A basic_node object. -/// @param f A float number node value object. -template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::float_number_type& f) { - if FK_YAML_UNLIKELY (!n.is_float_number()) { - throw type_error("The target node value type is not float number type.", n.get_type()); + i = static_cast(tmp_int); + break; + } + case node_type::SEQUENCE: + case node_type::MAPPING: + case node_type::STRING: + default: + throw type_error("The target node value type is not compatible with integer type.", n.get_type()); } - f = n.template get_value_ref(); } -/// @brief from_node function for other float number objects. (i.e., not BasicNodeType::float_number_type) +/// @brief Helper struct for node-to-float conversion if FloatType is the node's floating point value type. /// @tparam BasicNodeType A basic_node template instance type. -/// @tparam FloatType A float number value type. -/// @param n A basic_node object. -/// @param f A float number node value object. +/// @tparam FloatType Target floating point value type (same as the BasicNodeType::float_number_type) template < typename BasicNodeType, typename FloatType, - enable_if_t< - conjunction< - std::is_floating_point, - negation>>::value, - int> = 0> -inline void from_node(const BasicNodeType& n, FloatType& f) { - if FK_YAML_UNLIKELY (!n.is_float_number()) { - throw type_error("The target node value type is not float number type.", n.get_type()); + bool = std::is_same::value> +struct from_node_float_helper { + /// @brief Convert node's floating point value to the target floating point type. + /// @param n A node object. + /// @return A floating point value converted from the node's floating point value. + static FloatType convert(const BasicNodeType& n) { + return n.template get_value_ref(); } +}; - using node_float_type = typename BasicNodeType::float_number_type; - auto tmp_float = n.template get_value_ref(); +/// @brief Helper struct for node-to-float conversion if IntType is not the node's floating point value type. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam FloatType Target floating point value type (different from BasicNodeType::float_number_type) +template +struct from_node_float_helper { + /// @brief Convert node's floating point value to the target floating point type. + /// @param n A node object. + /// @return A floating point value converted from the node's floating point value. + static FloatType convert(const BasicNodeType& n) { + using node_float_type = typename BasicNodeType::float_number_type; + auto tmp_float = n.template get_value_ref(); - // check if the value is an infinite number (either positive or negative) - if (std::isinf(tmp_float)) { - if (tmp_float == std::numeric_limits::infinity()) { - f = std::numeric_limits::infinity(); - return; + // check if the value is an infinite number (either positive or negative) + if (std::isinf(tmp_float)) { + if (tmp_float == std::numeric_limits::infinity()) { + return std::numeric_limits::infinity(); + } + + return static_cast(-1.) * std::numeric_limits::infinity(); } - f = -1 * std::numeric_limits::infinity(); - return; - } + // check if the value is not a number + if (std::isnan(tmp_float)) { + return std::numeric_limits::quiet_NaN(); + } - // check if the value is not a number - if (std::isnan(tmp_float)) { - f = std::numeric_limits::quiet_NaN(); - return; - } + // check if the value is expressible as FloatType. + if FK_YAML_UNLIKELY (tmp_float < std::numeric_limits::lowest()) { + throw exception("Floating point value underflow detected."); + } + if FK_YAML_UNLIKELY (std::numeric_limits::max() < tmp_float) { + throw exception("Floating point value overflow detected."); + } - // check if the value is expressible as FloatType. - if FK_YAML_UNLIKELY (tmp_float < std::numeric_limits::lowest()) { - throw exception("Floating point value underflow detected."); - } - if FK_YAML_UNLIKELY (std::numeric_limits::max() < tmp_float) { - throw exception("Floating point value overflow detected."); + return static_cast(tmp_float); } +}; - f = static_cast(tmp_float); +/// @brief from_node function for floating point values. +/// @note If node's value is null, boolean, or integer, such a value is converted into a floating point internally. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam FloatType A floating point value type. +/// @param n A node object. +/// @param f Storage for a float point value. +template < + typename BasicNodeType, typename FloatType, + enable_if_t, std::is_floating_point>::value, int> = 0> +inline void from_node(const BasicNodeType& n, FloatType& f) { + switch (n.get_type()) { + case node_type::NULL_OBJECT: + // nullptr is interpreted as 0.0 + f = static_cast(0.); + break; + case node_type::BOOLEAN: + f = static_cast(n.template get_value_ref()) + ? static_cast(1.) + : static_cast(0.); + break; + case node_type::INTEGER: + f = static_cast(n.template get_value_ref()); + break; + case node_type::FLOAT: + f = from_node_float_helper::convert(n); + break; + case node_type::SEQUENCE: + case node_type::MAPPING: + case node_type::STRING: + default: + throw type_error("The target node value type is not compatible with float number type.", n.get_type()); + } } /// @brief from_node function for BasicNodeType::string_type objects. diff --git a/test/unit_test/test_node_class.cpp b/test/unit_test/test_node_class.cpp index 15538692..abb9456f 100644 --- a/test/unit_test/test_node_class.cpp +++ b/test/unit_test/test_node_class.cpp @@ -2419,44 +2419,82 @@ TEST_CASE("Node_GetValue") { SECTION("null node value") { fkyaml::node node(nullptr); - SECTION("null value") { + SECTION("null type") { auto null = node.get_value(); REQUIRE(null == nullptr); } - SECTION("non-null values") { + SECTION("non-null compatible types") { + REQUIRE(node.get_value() == false); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0.f); + REQUIRE(node.get_value() == 0.); + REQUIRE(node.get_value() == 0.l); + } + + SECTION("non-null incompatible types") { REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); } } SECTION("boolean node value") { - fkyaml::node node(true); - - SECTION("boolean value") { - REQUIRE(node.get_value() == true); - } - - SECTION("non-boolean values") { - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); + fkyaml::node true_node(true); + fkyaml::node false_node(false); + + SECTION("boolean type") { + REQUIRE(true_node.get_value() == true); + REQUIRE(false_node.get_value() == false); + } + + SECTION("non-boolean compatible types") { + REQUIRE(true_node.get_value() == 1); + REQUIRE(true_node.get_value() == 1); + REQUIRE(true_node.get_value() == 1); + REQUIRE(true_node.get_value() == 1); + REQUIRE(true_node.get_value() == 1); + REQUIRE(true_node.get_value() == 1); + REQUIRE(true_node.get_value() == 1); + REQUIRE(true_node.get_value() == 1); + REQUIRE(true_node.get_value() == 1.f); + REQUIRE(true_node.get_value() == 1.); + REQUIRE(true_node.get_value() == 1.l); + + REQUIRE(false_node.get_value() == 0); + REQUIRE(false_node.get_value() == 0); + REQUIRE(false_node.get_value() == 0); + REQUIRE(false_node.get_value() == 0); + REQUIRE(false_node.get_value() == 0); + REQUIRE(false_node.get_value() == 0); + REQUIRE(false_node.get_value() == 0); + REQUIRE(false_node.get_value() == 0); + REQUIRE(false_node.get_value() == 0.f); + REQUIRE(false_node.get_value() == 0.); + REQUIRE(false_node.get_value() == 0.l); + } + + SECTION("non-boolean incompatible types") { + REQUIRE_THROWS_AS(true_node.get_value(), fkyaml::type_error); + REQUIRE_THROWS_AS(true_node.get_value(), fkyaml::type_error); + REQUIRE_THROWS_AS(true_node.get_value(), fkyaml::type_error); + REQUIRE_THROWS_AS(true_node.get_value(), fkyaml::type_error); + REQUIRE_THROWS_AS(true_node.get_value(), fkyaml::type_error); } } SECTION("integer node value") { fkyaml::node node(123); - SECTION("integer values") { + SECTION("integer types") { REQUIRE(node.get_value() == 123); REQUIRE(node.get_value() == 123); REQUIRE(node.get_value() == 123); @@ -2464,27 +2502,40 @@ TEST_CASE("Node_GetValue") { REQUIRE(node.get_value() == 123); REQUIRE(node.get_value() == 123); REQUIRE(node.get_value() == 123); - // TODO: REQUIRE(node.get_value() == 123); + REQUIRE(node.get_value() == 123); + } + + SECTION("non-integer compatible types") { + REQUIRE(node.get_value() == true); + REQUIRE(node.get_value() == 123.f); + REQUIRE(node.get_value() == 123.); + REQUIRE(node.get_value() == 123.l); + + node = -123; + REQUIRE(node.get_value() == true); + REQUIRE(node.get_value() == -123.f); + REQUIRE(node.get_value() == -123.); + REQUIRE(node.get_value() == -123.l); + + node = 0; + REQUIRE(node.get_value() == false); + REQUIRE(node.get_value() == 0.f); + REQUIRE(node.get_value() == 0.); + REQUIRE(node.get_value() == 0.l); } - SECTION("non-integer values") { + SECTION("non-integer incompatible types") { REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); } - SECTION("non-integer node value") { - fkyaml::node non_int_node(true); - REQUIRE_THROWS_AS(non_int_node.get_value(), fkyaml::type_error); - } - SECTION("underflowable integer type") { fkyaml::node negative_int_node(std::numeric_limits::min()); REQUIRE_THROWS_AS(negative_int_node.get_value(), fkyaml::exception); + REQUIRE_THROWS_AS(negative_int_node.get_value(), fkyaml::exception); } SECTION("overflowable integer type") { @@ -2496,41 +2547,64 @@ TEST_CASE("Node_GetValue") { SECTION("float number node value") { fkyaml::node node(3.14); - SECTION("positive float number values") { + SECTION("positive float values") { REQUIRE(std::abs(node.get_value() - 3.14) < std::numeric_limits::epsilon()); REQUIRE(std::abs(node.get_value() - 3.14) < std::numeric_limits::epsilon()); REQUIRE(std::abs(node.get_value() - 3.14) < std::numeric_limits::epsilon()); } - SECTION("zero float number values") { + SECTION("zero float values") { node = 0.0; REQUIRE(std::abs(node.get_value() - 0.0) < std::numeric_limits::epsilon()); REQUIRE(std::abs(node.get_value() - 0.0) < std::numeric_limits::epsilon()); REQUIRE(std::abs(node.get_value() - 0.0) < std::numeric_limits::epsilon()); } - SECTION("negative float number values") { + SECTION("negative float values") { node = -3.14; REQUIRE(std::abs(node.get_value() - (-3.14)) < std::numeric_limits::epsilon()); REQUIRE(std::abs(node.get_value() - (-3.14)) < std::numeric_limits::epsilon()); REQUIRE(std::abs(node.get_value() - (-3.14)) < std::numeric_limits::epsilon()); } - SECTION("non-float-number values") { + SECTION("non-float compatible types") { + REQUIRE(node.get_value() == true); + REQUIRE(node.get_value() == 3); + REQUIRE(node.get_value() == 3); + REQUIRE(node.get_value() == 3); + REQUIRE(node.get_value() == 3); + REQUIRE(node.get_value() == 3); + REQUIRE(node.get_value() == 3); + REQUIRE(node.get_value() == 3); + REQUIRE(node.get_value() == 3); + + node = -3.14; + REQUIRE(node.get_value() == true); + REQUIRE(node.get_value() == -3); + REQUIRE(node.get_value() == -3); + REQUIRE(node.get_value() == -3); + REQUIRE(node.get_value() == -3); + + node = 0.0; + REQUIRE(node.get_value() == false); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + REQUIRE(node.get_value() == 0); + } + + SECTION("non-float incompatible types") { REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); - REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); } - SECTION("non-float-number node value") { - fkyaml::node non_float_num_node(true); - REQUIRE_THROWS_AS(non_float_num_node.get_value(), fkyaml::type_error); - } - SECTION("underflowable float number type") { fkyaml::node negative_float_node(std::numeric_limits::lowest()); REQUIRE_THROWS_AS(negative_float_node.get_value(), fkyaml::exception); @@ -2540,6 +2614,15 @@ TEST_CASE("Node_GetValue") { fkyaml::node large_float_node(std::numeric_limits::max()); REQUIRE_THROWS_AS(large_float_node.get_value(), fkyaml::exception); } + + SECTION("invalid float-to-int conversion") { + node = -3.14; + REQUIRE_THROWS_AS(node.get_value(), fkyaml::exception); + REQUIRE_THROWS_AS(node.get_value(), fkyaml::exception); + + node = 256.0; + REQUIRE_THROWS_AS(node.get_value(), fkyaml::exception); + } } SECTION("string node value") { From aaaff43fc06bbf71054cc810982d837ae1aa591a Mon Sep 17 00:00:00 2001 From: fktn Date: Tue, 12 Nov 2024 04:55:12 +0900 Subject: [PATCH 07/13] Support more STL types in from_node (#421) * support more STL container types in from_node functions * updated document page and example for get_value API * added tests for missing lines/branches * fixed compile & usan errors --- docs/examples/ex_basic_node_get_value.cpp | 33 +- docs/examples/ex_basic_node_get_value.output | 8 + docs/mkdocs/docs/api/basic_node/get_value.md | 106 +++- .../fkYAML/detail/conversions/from_node.hpp | 243 ++++++-- .../detail/macros/cpp_config_macros.hpp | 13 + include/fkYAML/detail/meta/detect.hpp | 117 ++++ include/fkYAML/detail/meta/stl_supplement.hpp | 78 ++- include/fkYAML/node.hpp | 94 ++- single_include/fkYAML/node.hpp | 545 ++++++++++++++++-- test/unit_test/test_custom_from_node.cpp | 33 +- test/unit_test/test_node_class.cpp | 359 +++++++++++- 11 files changed, 1469 insertions(+), 160 deletions(-) diff --git a/docs/examples/ex_basic_node_get_value.cpp b/docs/examples/ex_basic_node_get_value.cpp index 4325b266..0732993c 100644 --- a/docs/examples/ex_basic_node_get_value.cpp +++ b/docs/examples/ex_basic_node_get_value.cpp @@ -10,7 +10,38 @@ #include int main() { - // create a YAML node. + // create sequence nodes. + fkyaml::node seq = {true, false}; + fkyaml::node seq2 = {123, 3.14, "foo"}; + + // get the node values + // to std::vector + auto bool_vec = seq.get_value>(); + for (auto b : bool_vec) { + std::cout << std::boolalpha << b << " "; + } + std::cout << "\n\n"; + // to std::tuple + auto tpl = seq2.get_value>(); + std::cout << std::get<0>(tpl) << " "; + std::cout << std::get<1>(tpl) << " "; + std::cout << std::get<2>(tpl) << "\n\n"; + + // create a mapping node. + fkyaml::node map = { + {0, "foo"}, + {1, "bar"}, + {2, "baz"}, + }; + // get the node values + // to std::unordered_map + auto umap = map.get_value>(); + for (auto& p : umap) { + std::cout << p.first << " : " << p.second << std::endl; + } + std::cout << std::endl; + + // create scalar nodes. fkyaml::node n = 1.23; fkyaml::node n2 = "foo"; diff --git a/docs/examples/ex_basic_node_get_value.output b/docs/examples/ex_basic_node_get_value.output index a1eec460..2b00855e 100644 --- a/docs/examples/ex_basic_node_get_value.output +++ b/docs/examples/ex_basic_node_get_value.output @@ -1,3 +1,11 @@ +true false + +123 3.14 foo + +2 : baz +1 : bar +0 : foo + 1.23 foo true diff --git a/docs/mkdocs/docs/api/basic_node/get_value.md b/docs/mkdocs/docs/api/basic_node/get_value.md index e5e64491..c210a52e 100644 --- a/docs/mkdocs/docs/api/basic_node/get_value.md +++ b/docs/mkdocs/docs/api/basic_node/get_value.md @@ -3,37 +3,82 @@ # fkyaml::basic_node::get_value ```cpp -template < - typename T, typename ValueType = detail::remove_cvref_t, - detail::enable_if_t< - detail::conjunction< - std::is_default_constructible, detail::has_from_node>::value, - int> = 0> +template > T get_value() const noexcept( - noexcept(ConverterType::from_node(std::declval(), std::declval()))); + noexcept(ConverterType::from_node(std::declval(), std::declval()))); // (1) + +template +BasicNodeType get_value() const; // (2) ``` -Explicit type conversion between the internally stored YAML node value and a compatible value which is [copy-constructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and [default-constructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). -The conversion relies on the [`node_value_converter`](../node_value_converter/index.md)::[`from_node`](../node_value_converter/from_node.md). -This API makes a copy of the value. -If the copying costs a lot, or if you need an address of the original value, then you should call [`get_value_ref`](get_value_ref.md) instead. - -If the YAML node value is a null, boolean, integer or floating point, this function internally executes type conversion according to the following rules which all depend on the template paramter type `T`: -* If the YAML node value is a **null** (node_type::NULL_OBJECT), the value can be converted to: - * `false` (boolean) - * `0` (integer) - * `0.0` (floating point) -* If the YAML node value is a **boolean** (node_type::BOOLEAN), the value can be converted to: - * `1 /*true*/` or `0 /*false*/` (integer) - * `1.0 /*true*/` or `0.0 /*false*/` (floating point) -* If the YAML node value is a **integer** (node_type::INTEGER), the value can be converted to: - * `true /*non-0*/` or `false /*0*/` (boolean) - * `static_cast`ed floating point value (floating point) -* If the YAML node value is a **floating point** (node_type::FLOAT), the value can be converted to: - * `true /*non-0*/` or `false /*0*/` (boolean) - * `static_cast`ed integer value (integer) - -Note that those scalar type cannot be converted to a sequence, mapping, string scalar and throws a [`type_error`](../exception/type_error.md). +This function converts a [fkyaml::basic_node](./index.md) to either + +1. a compatible value ([copy-constructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and [default-constructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible)) + The function is equivalent to executing + ```cpp + ValueType ret; + ConverterType::from_node(*this, ret); + return ret; + ``` + This library implements conversions from a node to a number of STL container types and scalar types. (see the notes down below) +2. a [fkyaml::basic_node](./index.md) object + The function is equivalent to executing + ```cpp + return *this; // Copy-constructs a new basic_node object. + ``` + +Actual conversions rely on the [`node_value_converter`](../node_value_converter/index.md)::[`from_node`](../node_value_converter/from_node.md) function. +This API makes a copy of the value, and if the copying costs too much, or if you need an address of the original value, then you should call [`get_value_ref`](get_value_ref.md) instead. + +???+ Note "Convert from a Sequence Node" + + This library implements conversions from a sequence node to a number of STL container types whose element type is not a key-value pair. The implementation can be used for custom container types, but they need to have both `iterator` member type and `insert()` member function. The test suite confirms successful conversions to the following types. + + * std::vector, std::deque, std::list *(sequence containers)* + * std::set, std::multiset *(associative containers for keys)* + * std::unordered_set, std::unordered_multiset *(unordered associative containers for keys)* + + And you can also convert to these types which do not have `insert()` member function though. + + * std::array, std::valarray *(sequence containers)* + * std::stack, std::queue, std::priority_queue *(sequence container adapters)* + * std::pair, std::tuple + + Note that the above types cannot be converted from a non-sequence node, which results in throwing a [type_error](../exception/type_error.md). + +???+ Note "Convert from a Mapping Node" + + This library implements conversions from a mapping node to STL container types whose element type is a key-value pair. The implementation can be used for custom container types, but they need to have `key_type`, `mapped_type` and `value_type` member types and `emplace()` member function. The test suite confirms successful conversions to the following types. + + * std::map, std::multimap *(associative containers for key-value pairs)* + * std::unordered_map, std::unordered_multi_map *(unordered associative containers for key-value pairs)* + +???+ Note "Convert from a Null or Numeric Scalar Node" + + If the YAML node value is a null, boolean, integer or floating point, this function internally executes type conversion according to the following rules which all depend on the template paramter type `T`: + + * If the YAML node value is a **null** (node_type::NULL_OBJECT), the value can be converted to: + * `false` (boolean) + * `0` (integer) + * `0.0` (floating point) + * If the YAML node value is a **boolean** (node_type::BOOLEAN), the value can be converted to: + * `1 /*true*/` or `0 /*false*/` (integer) + * `1.0 /*true*/` or `0.0 /*false*/` (floating point) + * If the YAML node value is a **integer** (node_type::INTEGER), the value can be converted to: + * `true /*non-0*/` or `false /*0*/` (boolean) + * `static_cast`ed floating point value (floating point) + * If the YAML node value is a **floating point** (node_type::FLOAT), the value can be converted to: + * `true /*non-0*/` or `false /*0*/` (boolean) + * `static_cast`ed integer value (integer) + + Note that those scalar type cannot be converted to a sequence, mapping, string scalar, which results in throwing a [`type_error`](../exception/type_error.md). + +???+ Note "Convert from a String Scalar Node" + + String scalar nodes can be converted to STL container types which can be constructible from `const fkyaml::basic_node::string_type&` (`const std::string&` by default). The test suite confirms successful conversions to the following types. + + * std::string + * std::string_view (from C++17) ## **Template Parameters** @@ -45,9 +90,12 @@ Note that those scalar type cannot be converted to a sequence, mapping, string s This is, by default, a type of [std::remove_cvref_t](https://en.cppreference.com/w/cpp/types/remove_cvref). If fkYAML is compiled with C++11, C++14 or C++17, fkYAML uses its own implementation. +***BasicNodeType*** +: A basic_node template instance type. + ## **Return Value** -A compatible native data value converted from the basic_node object. +A compatible native data value converted from the [basic_node](./index.md) object. ???+ Example diff --git a/include/fkYAML/detail/conversions/from_node.hpp b/include/fkYAML/detail/conversions/from_node.hpp index c5126c57..8f5e391f 100644 --- a/include/fkYAML/detail/conversions/from_node.hpp +++ b/include/fkYAML/detail/conversions/from_node.hpp @@ -9,11 +9,11 @@ #ifndef FK_YAML_DETAIL_CONVERSIONS_FROM_NODE_HPP #define FK_YAML_DETAIL_CONVERSIONS_FROM_NODE_HPP +#include #include #include -#include #include -#include +#include #include #include @@ -22,65 +22,158 @@ #include #include +#ifdef FK_YAML_HAS_CXX_17 +#include +#endif + FK_YAML_DETAIL_NAMESPACE_BEGIN /////////////////// // from_node // /////////////////// -/// @brief from_node function for BasicNodeType::sequence_type objects. +// utility type traits and functors + +/// @brief Utility traits type alias to detect constructible associative container types from a mapping node, e.g., +/// std::map or std::unordered_map. +/// @tparam T A target type for detection. +template +using is_constructible_mapping_type = + conjunction, detect::has_mapped_type, detect::has_value_type>; + +/// @brief Utility traits type alias to detect constructible container types from a sequence node, e.g., std::vector or +/// std::list. /// @tparam BasicNodeType A basic_node template instance type. +/// @tparam T A target type for detection. +template +using is_constructible_sequence_type = conjunction< + negation>, detect::has_iterator, detect::is_iterator_traits, + detect::has_begin_end, negation>, + negation>>; + +/// @brief Utility traits type alias to detect a sequence container adapter type, e.g., std::stack or std::queue. +/// @tparam T A target type for detection. +template +using is_sequence_container_adapter = conjunction< + negation>, detect::has_container_type, detect::has_value_type, + negation>>; + +/// @brief Helper struct for reserve() member function call switch for types which do not have reserve function. +/// @tparam ContainerType A container type. +template +struct call_reserve_if_available { + /// @brief Do nothing since ContainerType does not have reserve function. + /// @param + /// @param + static void call(ContainerType& /*unused*/, typename ContainerType::size_type /*unused*/) { + } +}; + +/// @brief Helper struct for reserve() member function call switch for types which have reserve function. +/// @tparam ContainerType A container type. +template +struct call_reserve_if_available::value>> { + /// @brief Call reserve function on the ContainerType object with a given size. + /// @param c A container object. + /// @param n A size to reserve. + static void call(ContainerType& c, typename ContainerType::size_type n) { + c.reserve(n); + } +}; + +// from_node() implementations + +/// @brief from_node function for std::array objects whose element type must be a basic_node template instance type or a +/// compatible type. This function is necessary since insert function is not implemented for std::array. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam T Element type of std::array. +/// @tparam N Size of std::array. /// @param n A basic_node object. -/// @param s A sequence node value object. -template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::sequence_type& s) { +/// @param arr A std::array object. +template +inline auto from_node(const BasicNodeType& n, std::array& arr) -> decltype(n.template get_value(), void()) { + if FK_YAML_UNLIKELY (!n.is_sequence()) { + throw type_error("The target node value type is not sequence type.", n.get_type()); + } + + std::size_t count = std::min(n.size(), N); + for (std::size_t i = 0; i < count; i++) { + arr.at(i) = n.at(i).template get_value(); + } +} + +/// @brief from_node function for std::valarray objects whose element type must be a basic_node template instance type +/// or a compatible type. This function is necessary since insert function is not implemented for std::valarray. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam T Element type of std::valarray. +/// @param n A basic_node object. +/// @param va A std::valarray object. +template +inline auto from_node(const BasicNodeType& n, std::valarray& va) -> decltype(n.template get_value(), void()) { if FK_YAML_UNLIKELY (!n.is_sequence()) { throw type_error("The target node value type is not sequence type.", n.get_type()); } - s = n.template get_value_ref(); + + std::size_t count = n.size(); + va.resize(count); + for (std::size_t i = 0; i < count; i++) { + va[i] = n.at(i).template get_value(); + } } -/// @brief from_node function for objects of the std::vector of compatible types. +/// @brief from_node function for container objects of only keys or values, e.g., std::vector or std::set, whose element +/// type must be a basic_node template instance type or a compatible type. /// @tparam BasicNodeType A basic_node template instance type. -/// @tparam CompatibleValueType A compatible type for BasicNodeType. +/// @tparam CompatSeqType A container type. /// @param n A basic_node object. -/// @param s A vector of compatible type objects. +/// @param s A container object. template < - typename BasicNodeType, typename CompatibleValueType, + typename BasicNodeType, typename CompatSeqType, enable_if_t< conjunction< - is_basic_node, negation>, - has_from_node, - negation, typename BasicNodeType::sequence_type>>>::value, + is_basic_node, is_constructible_sequence_type, + negation>>::value, int> = 0> -inline void from_node(const BasicNodeType& n, std::vector& s) { +inline auto from_node(const BasicNodeType& n, CompatSeqType& s) + -> decltype(n.template get_value(), void()) { if FK_YAML_UNLIKELY (!n.is_sequence()) { throw type_error("The target node value is not sequence type.", n.get_type()); } - s.reserve(n.size()); + // call reserve function first if it's available (like std::vector). + call_reserve_if_available::call(s, n.size()); - for (const auto& elem : n) { - s.emplace_back(elem.template get_value()); - } + // transform a sequence node into a destination type object by calling insert function. + using std::end; + std::transform(n.begin(), n.end(), std::inserter(s, end(s)), [](const BasicNodeType& elem) { + return elem.template get_value(); + }); } -/// @brief from_node function for BasicNodeType::mapping_type objects. +/// @brief from_node function for sequence container adapter objects, e.g., std::stack or std::queue, whose element type +/// must be either a basic_node template instance type or a compatible type. /// @tparam BasicNodeType A basic_node template instance type. -/// @param n A basic_node object. -/// @param m A mapping node value object. -template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::mapping_type& m) { - if FK_YAML_UNLIKELY (!n.is_mapping()) { - throw type_error("The target node value type is not mapping type.", n.get_type()); +/// @tparam SeqContainerAdapter A sequence container adapter type. +/// @param n A node object. +/// @param ca A sequence container adapter object. +template < + typename BasicNodeType, typename SeqContainerAdapter, + enable_if_t< + conjunction, is_sequence_container_adapter>::value, int> = 0> +inline auto from_node(const BasicNodeType& n, SeqContainerAdapter& ca) + -> decltype(n.template get_value(), ca.emplace(std::declval()), void()) { + if FK_YAML_UNLIKELY (!n.is_sequence()) { + throw type_error("The target node value is not sequence type.", n.get_type()); } - for (auto pair : n.template get_value_ref()) { - m.emplace(pair.first, pair.second); + for (const auto& elem : n) { + // container adapter classes commonly have push function. + // emplace function cannot be used in case SeqContainerAdapter::container_type is std::vector in C++11. + ca.push(elem.template get_value()); } } -/// @brief from node function for mappings whose key and value are of both compatible types. +/// @brief from_node function for mappings whose key and value are of both compatible types. /// @tparam BasicNodeType A basic_node template instance type. /// @tparam CompatibleKeyType Mapping key type compatible with BasicNodeType. /// @tparam CompatibleValueType Mapping value type compatible with BasicNodeType. @@ -88,23 +181,23 @@ inline void from_node(const BasicNodeType& n, typename BasicNodeType::mapping_ty /// @tparam Allocator Allocator type for destination mapping object. /// @param n A node object. /// @param m Mapping container object to store converted key/value objects. -template < - typename BasicNodeType, typename CompatibleKeyType, typename CompatibleValueType, typename Compare, - typename Allocator, - enable_if_t< - conjunction< - is_basic_node, negation>, - negation>, has_from_node, - has_from_node>::value, - int> = 0> -inline void from_node(const BasicNodeType& n, std::map& m) { +template ::value, int> = 0> +inline auto from_node(const BasicNodeType& n, CompatMapType& m) + -> decltype( + std::declval().template get_value(), + std::declval().template get_value(), + m.emplace(std::declval(), std::declval()), + void()) { if FK_YAML_UNLIKELY (!n.is_mapping()) { throw type_error("The target node value type is not mapping type.", n.get_type()); } - for (auto pair : n.template get_value_ref()) { + call_reserve_if_available::call(m, n.size()); + + for (const auto& pair : n.template get_value_ref()) { m.emplace( - pair.first.template get_value(), pair.second.template get_value()); + pair.first.template get_value(), + pair.second.template get_value()); } } @@ -372,6 +465,74 @@ inline void from_node(const BasicNodeType& n, CompatibleStringType& s) { s = n.template get_value_ref(); } +/// @brief from_node function for std::pair objects whose element types must be either a basic_node template instance +/// type or a compatible type. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam T The first type of the std::pair. +/// @tparam U The second type of the std::pair. +/// @param n A basic_node object. +/// @param p A std::pair object. +template ::value, int> = 0> +inline auto from_node(const BasicNodeType& n, std::pair& p) + -> decltype(std::declval().template get_value(), std::declval().template get_value(), void()) { + if FK_YAML_UNLIKELY (!n.is_sequence()) { + throw type_error("The target node value type is not sequence type.", n.get_type()); + } + + p = {n.at(0).template get_value(), n.at(1).template get_value()}; +} + +/// @brief concrete implementation of from_node function for std::tuple objects. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam ...Types The value types of std::tuple. +/// @tparam ...Idx Index sequence values for std::tuples value types. +/// @param n A basic_node object +/// @param _ Index sequence values (unused). +/// @return A std::tuple object converted from the sequence node values. +template +inline std::tuple from_node_tuple_impl(const BasicNodeType& n, index_sequence /*unused*/) { + return std::make_tuple(n.at(Idx).template get_value()...); +} + +/// @brief from_node function for std::tuple objects whose value types must all be either a basic_node template instance +/// type or a compatible type +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam ...Types Value types of std::tuple. +/// @param n A basic_node object. +/// @param t A std::tuple object. +template ::value, int> = 0> +inline void from_node(const BasicNodeType& n, std::tuple& t) { + if FK_YAML_UNLIKELY (!n.is_sequence()) { + throw type_error("The target node value type is not sequence type.", n.get_type()); + } + + // Types... must be explicitly specified; the retun type would otherwise be std::tuple with no value types. + t = from_node_tuple_impl(n, index_sequence_for {}); +} + +#ifdef FK_YAML_HAS_CXX_17 + +/// @brief from_node function for std::optional objects whose value type must be either a basic_node template instance +/// type or a compatible type. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam T A value type of the std::optional. +/// @param n A basic_node object. +/// @param o A std::optional object. +template ::value, int> = 0> +inline auto from_node(const BasicNodeType& n, std::optional& o) -> decltype(n.template get_value(), void()) { + try { + o.emplace(n.template get_value()); + } + catch (const std::exception& /*unused*/) { + // Any exception derived from std::exception is interpreted as a conversion failure in some way + // since user-defined from_node function may throw a different object from a fkyaml::type_error. + // and std::exception is usually the base class of user-defined exception types. + o = std::nullopt; + } +} + +#endif // defined(FK_YAML_HAS_CXX_17) + /// @brief A function object to call from_node functions. /// @note User-defined specialization is available by providing implementation **OUTSIDE** fkyaml namespace. struct from_node_fn { diff --git a/include/fkYAML/detail/macros/cpp_config_macros.hpp b/include/fkYAML/detail/macros/cpp_config_macros.hpp index fdb62402..ad5036b9 100644 --- a/include/fkYAML/detail/macros/cpp_config_macros.hpp +++ b/include/fkYAML/detail/macros/cpp_config_macros.hpp @@ -88,6 +88,19 @@ #define FK_YAML_HAS_CPP_ATTRIBUTE(attr) (0) #endif +#ifdef __has_feature +#define FK_YAML_HAS_FEATURE(feat) __has_feature(feat) +#else +#define FK_YAML_HAS_FEATURE(feat) (0) +#endif + +// switch usage of the no_sanitize attribute only when Clang sanitizer is active. +#if defined(__clang__) && FK_YAML_HAS_FEATURE(address_sanitizer) +#define FK_YAML_NO_SANITIZE(...) __attribute__((no_sanitize(__VA_ARGS__))) +#else +#define FK_YAML_NO_SANITIZE(...) +#endif + #if FK_YAML_HAS_INCLUDE() // is available since C++20 #include diff --git a/include/fkYAML/detail/meta/detect.hpp b/include/fkYAML/detail/meta/detect.hpp index 062a87c3..31e79559 100644 --- a/include/fkYAML/detail/meta/detect.hpp +++ b/include/fkYAML/detail/meta/detect.hpp @@ -9,6 +9,7 @@ #ifndef FK_YAML_DETAIL_META_DETECT_HPP #define FK_YAML_DETAIL_META_DETECT_HPP +#include #include #include @@ -71,6 +72,122 @@ using detected_t = typename detector_impl::detector template class Op, typename... Args> using is_detected_exact = std::is_same>; +/// @brief namespace for member type detections of aliases and functions. +namespace detect { + +/// @brief The type which represents `iterator` member type. +/// @tparam T A target type. +template +using iterator_t = typename T::iterator; + +/// @brief The type which represents `key_type` member type. +/// @tparam T A target type. +template +using key_type_t = typename T::key_type; + +/// @brief The type which represents `mapped_type` member type. +/// @tparam T A target type. +template +using mapped_type_t = typename T::mapped_type; + +/// @brief The type which represents `value_type` member type. +/// @tparam T A target type. +template +using value_type_t = typename T::value_type; + +/// @brief The type which represents `difference_type` member type. +/// @tparam T A target type. +template +using difference_type_t = typename T::difference_type; + +/// @brief The type which represents `pointer` member type. +/// @tparam T A target type. +template +using pointer_t = typename T::pointer; + +/// @brief The type which represents `reference` member type. +/// @tparam T A target type. +template +using reference_t = typename T::reference; + +/// @brief The type which represents `iterator_category` member type. +/// @tparam T A target type. +template +using iterator_category_t = typename T::iterator_category; + +/// @brief The type which represents `container_type` member type. +/// @tparam T A target type. +template +using container_type_t = typename T::container_type; + +/// @brief The type which represents emplace member function. +/// @tparam T A target type. +template +using emplace_fn_t = decltype(std::declval().emplace(std::declval()...)); + +/// @brief The type which represents reserve member function. +/// @tparam T A target type. +template +using reserve_fn_t = decltype(std::declval().reserve(std::declval())); + +/// @brief Type traits to check if T has `iterator` member type. +/// @tparam T A target type. +template +using has_iterator = is_detected; + +/// @brief Type traits to check if T has `key_type` member type. +/// @tparam T A target type. +template +using has_key_type = is_detected; + +/// @brief Type traits to check if T has `mapped_type` member type. +/// @tparam T A target type. +template +using has_mapped_type = is_detected; + +/// @brief Type traits to check if T has `value_type` member type. +/// @tparam T A target type. +template +using has_value_type = is_detected; + +/// @brief Type traits to check if T is a std::iterator_traits like type. +/// @tparam T A target type. +template +struct is_iterator_traits : conjunction< + is_detected, has_value_type, is_detected, + is_detected, is_detected> {}; + +/// @brief Type traits to check if T has `container_type` member type. +/// @tparam T A target type. +template +using has_container_type = is_detected; + +/// @brief Type traits to check if T has emplace member function. +/// @tparam T A target type. +template +using has_emplace = is_detected; + +/// @brief Type traits to check if T has reserve member function. +/// @tparam T A target type. +template +using has_reserve = is_detected; + +// fallback to these STL functions. +using std::begin; +using std::end; + +/// @brief Type traits to check if begin/end functions can be called on a T object. +/// @tparam T A target type. +template +struct has_begin_end : std::false_type {}; + +/// @brief Type traits to check if begin/end functions can be called on a T object. +/// @tparam T A target type. +template +struct has_begin_end()), end(std::declval()))>> : std::true_type {}; + +} // namespace detect + FK_YAML_DETAIL_NAMESPACE_END #endif /* FK_YAML_DETAIL_META_DETECT_HPP */ diff --git a/include/fkYAML/detail/meta/stl_supplement.hpp b/include/fkYAML/detail/meta/stl_supplement.hpp index c79b24d5..950e8575 100644 --- a/include/fkYAML/detail/meta/stl_supplement.hpp +++ b/include/fkYAML/detail/meta/stl_supplement.hpp @@ -14,6 +14,10 @@ #include +#ifdef FK_YAML_HAS_CXX_14 +#include +#endif + FK_YAML_DETAIL_NAMESPACE_BEGIN ///////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -70,16 +74,84 @@ using remove_pointer_t = typename std::remove_pointer::type; template using remove_reference_t = typename std::remove_reference::type; +template +struct integer_sequence { + using value_type = T; + static constexpr std::size_t size() noexcept { + return sizeof...(I); + } +}; + +#if !FK_YAML_HAS_BUILTIN(__make_integer_seq) && !FK_YAML_HAS_BUILTIN(__integer_pack) + +namespace make_int_seq_impl { + +template +struct merger; + +template +struct merger, integer_sequence> { + using type = integer_sequence; +}; + +template +struct generator { + using type = + typename merger::type, typename generator::type>::type; +}; + +template +struct generator { + using type = integer_sequence; +}; + +template +struct generator { + using type = integer_sequence; +}; + +} // namespace make_int_seq_impl + +#endif + +template +using make_integer_sequence +#if FK_YAML_HAS_BUILTIN(__make_integer_seq) + // clang defines built-in __make_integer_seq to generate an integer sequence. + = __make_integer_seq; +#elif FK_YAML_HAS_BUILTIN(__integer_pack) + // GCC or other compilers may implement built-in __integer_pack to generate an + // integer sequence. + = integer_sequence; #else + // fallback to the library implementation of make_integer_sequence. + = typename make_int_seq_impl::generator::type; +#endif + +template +using index_sequence = integer_sequence; + +template +using make_index_sequence = make_integer_sequence; + +template +using index_sequence_for = make_index_sequence; + +#else // !defined(FK_YAML_HAS_CXX_14) using std::add_pointer_t; using std::enable_if_t; +using std::index_sequence; +using std::index_sequence_for; +using std::integer_sequence; using std::is_null_pointer; +using std::make_index_sequence; +using std::make_integer_sequence; using std::remove_cv_t; using std::remove_pointer_t; using std::remove_reference_t; -#endif +#endif // !defined(FK_YAML_HAS_CXX_14) #ifndef FK_YAML_HAS_CXX_17 @@ -149,7 +221,7 @@ struct make_void { template using void_t = typename make_void::type; -#else +#else // !defined(FK_YAML_HAS_CXX_17) using std::bool_constant; using std::conjunction; @@ -157,7 +229,7 @@ using std::disjunction; using std::negation; using std::void_t; -#endif +#endif // !defined(FK_YAML_HAS_CXX_17) #ifndef FK_YAML_HAS_CXX_20 diff --git a/include/fkYAML/node.hpp b/include/fkYAML/node.hpp index 01945941..3cb58883 100644 --- a/include/fkYAML/node.hpp +++ b/include/fkYAML/node.hpp @@ -1312,20 +1312,17 @@ class basic_node { /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/get_value/ template < typename T, typename ValueType = detail::remove_cvref_t, - detail::enable_if_t< - detail::conjunction< - std::is_default_constructible, detail::has_from_node>::value, - int> = 0> - T get_value() const noexcept(noexcept( - ConverterType::from_node(std::declval(), std::declval()))) { + detail::enable_if_t::value, int> = 0> + T get_value() const noexcept( + noexcept(std::declval().template get_value_impl(std::declval()))) { auto ret = ValueType(); if (has_anchor_name()) { auto itr = mp_meta->anchor_table.equal_range(m_prop.anchor).first; std::advance(itr, detail::node_attr_bits::get_anchor_offset(m_attrs)); - ConverterType::from_node(itr->second, ret); + itr->second.get_value_impl(ret); } else { - ConverterType::from_node(*this, ret); + get_value_impl(ret); } return ret; } @@ -1485,6 +1482,18 @@ class basic_node { return m_attrs; } + template < + typename ValueType, detail::enable_if_t>::value, int> = 0> + void get_value_impl(ValueType& v) const + noexcept(noexcept(ConverterType::from_node(std::declval(), v))) { + ConverterType::from_node(*this, v); + } + + template ::value, int> = 0> + void get_value_impl(ValueType& v) const { + v = *this; + } + /// @brief Returns reference to the sequence node value. /// @throw fkyaml::exception The node value is not a sequence. /// @return Reference to the sequence node value. @@ -1731,4 +1740,73 @@ inline fkyaml::node operator"" _yaml(const char8_t* s, std::size_t n) { FK_YAML_NAMESPACE_END +namespace std { + +template < + template class SequenceType, template class MappingType, + typename BooleanType, typename IntegerType, typename FloatNumberType, typename StringType, + template class ConverterType> +// NOLINTNEXTLINE(cert-dcl58-cpp) +struct hash> { + using node_t = fkyaml::basic_node< + SequenceType, MappingType, BooleanType, IntegerType, FloatNumberType, StringType, ConverterType>; + + std::size_t operator()(const node_t& n) const { + using boolean_type = typename node_t::boolean_type; + using integer_type = typename node_t::integer_type; + using float_number_type = typename node_t::float_number_type; + using string_type = typename node_t::string_type; + + const auto type = n.get_type(); + + std::size_t seed = 0; + hash_combine(seed, std::hash()(static_cast(type))); + + switch (type) { + case fkyaml::node_type::SEQUENCE: + hash_combine(seed, n.size()); + for (const auto& elem : n) { + hash_combine(seed, operator()(elem)); + } + return seed; + + case fkyaml::node_type::MAPPING: + hash_combine(seed, n.size()); + for (auto itr = n.begin(), end_itr = n.end(); itr != end_itr; ++itr) { + hash_combine(seed, operator()(itr.key())); + hash_combine(seed, operator()(itr.value())); + } + return seed; + + case fkyaml::node_type::NULL_OBJECT: + hash_combine(seed, 0); + return seed; + case fkyaml::node_type::BOOLEAN: + hash_combine(seed, std::hash()(n.template get_value())); + return seed; + case fkyaml::node_type::INTEGER: + hash_combine(seed, std::hash()(n.template get_value())); + return seed; + case fkyaml::node_type::FLOAT: + hash_combine(seed, std::hash()(n.template get_value())); + return seed; + case fkyaml::node_type::STRING: + hash_combine(seed, std::hash()(n.template get_value())); + return seed; + default: // LCOV_EXCL_LINE + return 0; // LCOV_EXCL_LINE + } + } + +private: + // taken from boost::hash_combine + FK_YAML_NO_SANITIZE("unsigned-shift-base", "unsigned-integer-overflow") + static void hash_combine(std::size_t& seed, std::size_t v) { + seed ^= v + 0x9e3779b9 + (seed << 6u) + (seed >> 2u); + } +}; + +} // namespace std + #endif /* FK_YAML_NODE_HPP */ diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index d465ce4c..b0a6bbfa 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -158,6 +158,19 @@ #define FK_YAML_HAS_CPP_ATTRIBUTE(attr) (0) #endif +#ifdef __has_feature +#define FK_YAML_HAS_FEATURE(feat) __has_feature(feat) +#else +#define FK_YAML_HAS_FEATURE(feat) (0) +#endif + +// switch usage of the no_sanitize attribute only when Clang sanitizer is active. +#if defined(__clang__) && FK_YAML_HAS_FEATURE(address_sanitizer) +#define FK_YAML_NO_SANITIZE(...) __attribute__((no_sanitize(__VA_ARGS__))) +#else +#define FK_YAML_NO_SANITIZE(...) +#endif + #if FK_YAML_HAS_INCLUDE() // is available since C++20 #include @@ -275,6 +288,7 @@ #ifndef FK_YAML_DETAIL_META_DETECT_HPP #define FK_YAML_DETAIL_META_DETECT_HPP +#include #include // #include @@ -297,6 +311,10 @@ // #include +#ifdef FK_YAML_HAS_CXX_14 +#include +#endif + FK_YAML_DETAIL_NAMESPACE_BEGIN ///////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -353,16 +371,84 @@ using remove_pointer_t = typename std::remove_pointer::type; template using remove_reference_t = typename std::remove_reference::type; +template +struct integer_sequence { + using value_type = T; + static constexpr std::size_t size() noexcept { + return sizeof...(I); + } +}; + +#if !FK_YAML_HAS_BUILTIN(__make_integer_seq) && !FK_YAML_HAS_BUILTIN(__integer_pack) + +namespace make_int_seq_impl { + +template +struct merger; + +template +struct merger, integer_sequence> { + using type = integer_sequence; +}; + +template +struct generator { + using type = + typename merger::type, typename generator::type>::type; +}; + +template +struct generator { + using type = integer_sequence; +}; + +template +struct generator { + using type = integer_sequence; +}; + +} // namespace make_int_seq_impl + +#endif + +template +using make_integer_sequence +#if FK_YAML_HAS_BUILTIN(__make_integer_seq) + // clang defines built-in __make_integer_seq to generate an integer sequence. + = __make_integer_seq; +#elif FK_YAML_HAS_BUILTIN(__integer_pack) + // GCC or other compilers may implement built-in __integer_pack to generate an + // integer sequence. + = integer_sequence; #else + // fallback to the library implementation of make_integer_sequence. + = typename make_int_seq_impl::generator::type; +#endif + +template +using index_sequence = integer_sequence; + +template +using make_index_sequence = make_integer_sequence; + +template +using index_sequence_for = make_index_sequence; + +#else // !defined(FK_YAML_HAS_CXX_14) using std::add_pointer_t; using std::enable_if_t; +using std::index_sequence; +using std::index_sequence_for; +using std::integer_sequence; using std::is_null_pointer; +using std::make_index_sequence; +using std::make_integer_sequence; using std::remove_cv_t; using std::remove_pointer_t; using std::remove_reference_t; -#endif +#endif // !defined(FK_YAML_HAS_CXX_14) #ifndef FK_YAML_HAS_CXX_17 @@ -432,7 +518,7 @@ struct make_void { template using void_t = typename make_void::type; -#else +#else // !defined(FK_YAML_HAS_CXX_17) using std::bool_constant; using std::conjunction; @@ -440,7 +526,7 @@ using std::disjunction; using std::negation; using std::void_t; -#endif +#endif // !defined(FK_YAML_HAS_CXX_17) #ifndef FK_YAML_HAS_CXX_20 @@ -519,6 +605,122 @@ using detected_t = typename detector_impl::detector template class Op, typename... Args> using is_detected_exact = std::is_same>; +/// @brief namespace for member type detections of aliases and functions. +namespace detect { + +/// @brief The type which represents `iterator` member type. +/// @tparam T A target type. +template +using iterator_t = typename T::iterator; + +/// @brief The type which represents `key_type` member type. +/// @tparam T A target type. +template +using key_type_t = typename T::key_type; + +/// @brief The type which represents `mapped_type` member type. +/// @tparam T A target type. +template +using mapped_type_t = typename T::mapped_type; + +/// @brief The type which represents `value_type` member type. +/// @tparam T A target type. +template +using value_type_t = typename T::value_type; + +/// @brief The type which represents `difference_type` member type. +/// @tparam T A target type. +template +using difference_type_t = typename T::difference_type; + +/// @brief The type which represents `pointer` member type. +/// @tparam T A target type. +template +using pointer_t = typename T::pointer; + +/// @brief The type which represents `reference` member type. +/// @tparam T A target type. +template +using reference_t = typename T::reference; + +/// @brief The type which represents `iterator_category` member type. +/// @tparam T A target type. +template +using iterator_category_t = typename T::iterator_category; + +/// @brief The type which represents `container_type` member type. +/// @tparam T A target type. +template +using container_type_t = typename T::container_type; + +/// @brief The type which represents emplace member function. +/// @tparam T A target type. +template +using emplace_fn_t = decltype(std::declval().emplace(std::declval()...)); + +/// @brief The type which represents reserve member function. +/// @tparam T A target type. +template +using reserve_fn_t = decltype(std::declval().reserve(std::declval())); + +/// @brief Type traits to check if T has `iterator` member type. +/// @tparam T A target type. +template +using has_iterator = is_detected; + +/// @brief Type traits to check if T has `key_type` member type. +/// @tparam T A target type. +template +using has_key_type = is_detected; + +/// @brief Type traits to check if T has `mapped_type` member type. +/// @tparam T A target type. +template +using has_mapped_type = is_detected; + +/// @brief Type traits to check if T has `value_type` member type. +/// @tparam T A target type. +template +using has_value_type = is_detected; + +/// @brief Type traits to check if T is a std::iterator_traits like type. +/// @tparam T A target type. +template +struct is_iterator_traits : conjunction< + is_detected, has_value_type, is_detected, + is_detected, is_detected> {}; + +/// @brief Type traits to check if T has `container_type` member type. +/// @tparam T A target type. +template +using has_container_type = is_detected; + +/// @brief Type traits to check if T has emplace member function. +/// @tparam T A target type. +template +using has_emplace = is_detected; + +/// @brief Type traits to check if T has reserve member function. +/// @tparam T A target type. +template +using has_reserve = is_detected; + +// fallback to these STL functions. +using std::begin; +using std::end; + +/// @brief Type traits to check if begin/end functions can be called on a T object. +/// @tparam T A target type. +template +struct has_begin_end : std::false_type {}; + +/// @brief Type traits to check if begin/end functions can be called on a T object. +/// @tparam T A target type. +template +struct has_begin_end()), end(std::declval()))>> : std::true_type {}; + +} // namespace detect + FK_YAML_DETAIL_NAMESPACE_END #endif /* FK_YAML_DETAIL_META_DETECT_HPP */ @@ -10311,11 +10513,11 @@ FK_YAML_DETAIL_NAMESPACE_END #ifndef FK_YAML_DETAIL_CONVERSIONS_FROM_NODE_HPP #define FK_YAML_DETAIL_CONVERSIONS_FROM_NODE_HPP +#include #include #include -#include #include -#include +#include // #include @@ -10330,65 +10532,158 @@ FK_YAML_DETAIL_NAMESPACE_END // #include +#ifdef FK_YAML_HAS_CXX_17 +#include +#endif + FK_YAML_DETAIL_NAMESPACE_BEGIN /////////////////// // from_node // /////////////////// -/// @brief from_node function for BasicNodeType::sequence_type objects. +// utility type traits and functors + +/// @brief Utility traits type alias to detect constructible associative container types from a mapping node, e.g., +/// std::map or std::unordered_map. +/// @tparam T A target type for detection. +template +using is_constructible_mapping_type = + conjunction, detect::has_mapped_type, detect::has_value_type>; + +/// @brief Utility traits type alias to detect constructible container types from a sequence node, e.g., std::vector or +/// std::list. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam T A target type for detection. +template +using is_constructible_sequence_type = conjunction< + negation>, detect::has_iterator, detect::is_iterator_traits, + detect::has_begin_end, negation>, + negation>>; + +/// @brief Utility traits type alias to detect a sequence container adapter type, e.g., std::stack or std::queue. +/// @tparam T A target type for detection. +template +using is_sequence_container_adapter = conjunction< + negation>, detect::has_container_type, detect::has_value_type, + negation>>; + +/// @brief Helper struct for reserve() member function call switch for types which do not have reserve function. +/// @tparam ContainerType A container type. +template +struct call_reserve_if_available { + /// @brief Do nothing since ContainerType does not have reserve function. + /// @param + /// @param + static void call(ContainerType& /*unused*/, typename ContainerType::size_type /*unused*/) { + } +}; + +/// @brief Helper struct for reserve() member function call switch for types which have reserve function. +/// @tparam ContainerType A container type. +template +struct call_reserve_if_available::value>> { + /// @brief Call reserve function on the ContainerType object with a given size. + /// @param c A container object. + /// @param n A size to reserve. + static void call(ContainerType& c, typename ContainerType::size_type n) { + c.reserve(n); + } +}; + +// from_node() implementations + +/// @brief from_node function for std::array objects whose element type must be a basic_node template instance type or a +/// compatible type. This function is necessary since insert function is not implemented for std::array. /// @tparam BasicNodeType A basic_node template instance type. +/// @tparam T Element type of std::array. +/// @tparam N Size of std::array. /// @param n A basic_node object. -/// @param s A sequence node value object. -template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::sequence_type& s) { +/// @param arr A std::array object. +template +inline auto from_node(const BasicNodeType& n, std::array& arr) -> decltype(n.template get_value(), void()) { if FK_YAML_UNLIKELY (!n.is_sequence()) { throw type_error("The target node value type is not sequence type.", n.get_type()); } - s = n.template get_value_ref(); + + std::size_t count = std::min(n.size(), N); + for (std::size_t i = 0; i < count; i++) { + arr.at(i) = n.at(i).template get_value(); + } } -/// @brief from_node function for objects of the std::vector of compatible types. +/// @brief from_node function for std::valarray objects whose element type must be a basic_node template instance type +/// or a compatible type. This function is necessary since insert function is not implemented for std::valarray. /// @tparam BasicNodeType A basic_node template instance type. -/// @tparam CompatibleValueType A compatible type for BasicNodeType. +/// @tparam T Element type of std::valarray. /// @param n A basic_node object. -/// @param s A vector of compatible type objects. +/// @param va A std::valarray object. +template +inline auto from_node(const BasicNodeType& n, std::valarray& va) -> decltype(n.template get_value(), void()) { + if FK_YAML_UNLIKELY (!n.is_sequence()) { + throw type_error("The target node value type is not sequence type.", n.get_type()); + } + + std::size_t count = n.size(); + va.resize(count); + for (std::size_t i = 0; i < count; i++) { + va[i] = n.at(i).template get_value(); + } +} + +/// @brief from_node function for container objects of only keys or values, e.g., std::vector or std::set, whose element +/// type must be a basic_node template instance type or a compatible type. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam CompatSeqType A container type. +/// @param n A basic_node object. +/// @param s A container object. template < - typename BasicNodeType, typename CompatibleValueType, + typename BasicNodeType, typename CompatSeqType, enable_if_t< conjunction< - is_basic_node, negation>, - has_from_node, - negation, typename BasicNodeType::sequence_type>>>::value, + is_basic_node, is_constructible_sequence_type, + negation>>::value, int> = 0> -inline void from_node(const BasicNodeType& n, std::vector& s) { +inline auto from_node(const BasicNodeType& n, CompatSeqType& s) + -> decltype(n.template get_value(), void()) { if FK_YAML_UNLIKELY (!n.is_sequence()) { throw type_error("The target node value is not sequence type.", n.get_type()); } - s.reserve(n.size()); + // call reserve function first if it's available (like std::vector). + call_reserve_if_available::call(s, n.size()); - for (const auto& elem : n) { - s.emplace_back(elem.template get_value()); - } + // transform a sequence node into a destination type object by calling insert function. + using std::end; + std::transform(n.begin(), n.end(), std::inserter(s, end(s)), [](const BasicNodeType& elem) { + return elem.template get_value(); + }); } -/// @brief from_node function for BasicNodeType::mapping_type objects. +/// @brief from_node function for sequence container adapter objects, e.g., std::stack or std::queue, whose element type +/// must be either a basic_node template instance type or a compatible type. /// @tparam BasicNodeType A basic_node template instance type. -/// @param n A basic_node object. -/// @param m A mapping node value object. -template ::value, int> = 0> -inline void from_node(const BasicNodeType& n, typename BasicNodeType::mapping_type& m) { - if FK_YAML_UNLIKELY (!n.is_mapping()) { - throw type_error("The target node value type is not mapping type.", n.get_type()); +/// @tparam SeqContainerAdapter A sequence container adapter type. +/// @param n A node object. +/// @param ca A sequence container adapter object. +template < + typename BasicNodeType, typename SeqContainerAdapter, + enable_if_t< + conjunction, is_sequence_container_adapter>::value, int> = 0> +inline auto from_node(const BasicNodeType& n, SeqContainerAdapter& ca) + -> decltype(n.template get_value(), ca.emplace(std::declval()), void()) { + if FK_YAML_UNLIKELY (!n.is_sequence()) { + throw type_error("The target node value is not sequence type.", n.get_type()); } - for (auto pair : n.template get_value_ref()) { - m.emplace(pair.first, pair.second); + for (const auto& elem : n) { + // container adapter classes commonly have push function. + // emplace function cannot be used in case SeqContainerAdapter::container_type is std::vector in C++11. + ca.push(elem.template get_value()); } } -/// @brief from node function for mappings whose key and value are of both compatible types. +/// @brief from_node function for mappings whose key and value are of both compatible types. /// @tparam BasicNodeType A basic_node template instance type. /// @tparam CompatibleKeyType Mapping key type compatible with BasicNodeType. /// @tparam CompatibleValueType Mapping value type compatible with BasicNodeType. @@ -10396,23 +10691,23 @@ inline void from_node(const BasicNodeType& n, typename BasicNodeType::mapping_ty /// @tparam Allocator Allocator type for destination mapping object. /// @param n A node object. /// @param m Mapping container object to store converted key/value objects. -template < - typename BasicNodeType, typename CompatibleKeyType, typename CompatibleValueType, typename Compare, - typename Allocator, - enable_if_t< - conjunction< - is_basic_node, negation>, - negation>, has_from_node, - has_from_node>::value, - int> = 0> -inline void from_node(const BasicNodeType& n, std::map& m) { +template ::value, int> = 0> +inline auto from_node(const BasicNodeType& n, CompatMapType& m) + -> decltype( + std::declval().template get_value(), + std::declval().template get_value(), + m.emplace(std::declval(), std::declval()), + void()) { if FK_YAML_UNLIKELY (!n.is_mapping()) { throw type_error("The target node value type is not mapping type.", n.get_type()); } - for (auto pair : n.template get_value_ref()) { + call_reserve_if_available::call(m, n.size()); + + for (const auto& pair : n.template get_value_ref()) { m.emplace( - pair.first.template get_value(), pair.second.template get_value()); + pair.first.template get_value(), + pair.second.template get_value()); } } @@ -10680,6 +10975,74 @@ inline void from_node(const BasicNodeType& n, CompatibleStringType& s) { s = n.template get_value_ref(); } +/// @brief from_node function for std::pair objects whose element types must be either a basic_node template instance +/// type or a compatible type. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam T The first type of the std::pair. +/// @tparam U The second type of the std::pair. +/// @param n A basic_node object. +/// @param p A std::pair object. +template ::value, int> = 0> +inline auto from_node(const BasicNodeType& n, std::pair& p) + -> decltype(std::declval().template get_value(), std::declval().template get_value(), void()) { + if FK_YAML_UNLIKELY (!n.is_sequence()) { + throw type_error("The target node value type is not sequence type.", n.get_type()); + } + + p = {n.at(0).template get_value(), n.at(1).template get_value()}; +} + +/// @brief concrete implementation of from_node function for std::tuple objects. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam ...Types The value types of std::tuple. +/// @tparam ...Idx Index sequence values for std::tuples value types. +/// @param n A basic_node object +/// @param _ Index sequence values (unused). +/// @return A std::tuple object converted from the sequence node values. +template +inline std::tuple from_node_tuple_impl(const BasicNodeType& n, index_sequence /*unused*/) { + return std::make_tuple(n.at(Idx).template get_value()...); +} + +/// @brief from_node function for std::tuple objects whose value types must all be either a basic_node template instance +/// type or a compatible type +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam ...Types Value types of std::tuple. +/// @param n A basic_node object. +/// @param t A std::tuple object. +template ::value, int> = 0> +inline void from_node(const BasicNodeType& n, std::tuple& t) { + if FK_YAML_UNLIKELY (!n.is_sequence()) { + throw type_error("The target node value type is not sequence type.", n.get_type()); + } + + // Types... must be explicitly specified; the retun type would otherwise be std::tuple with no value types. + t = from_node_tuple_impl(n, index_sequence_for {}); +} + +#ifdef FK_YAML_HAS_CXX_17 + +/// @brief from_node function for std::optional objects whose value type must be either a basic_node template instance +/// type or a compatible type. +/// @tparam BasicNodeType A basic_node template instance type. +/// @tparam T A value type of the std::optional. +/// @param n A basic_node object. +/// @param o A std::optional object. +template ::value, int> = 0> +inline auto from_node(const BasicNodeType& n, std::optional& o) -> decltype(n.template get_value(), void()) { + try { + o.emplace(n.template get_value()); + } + catch (const std::exception& /*unused*/) { + // Any exception derived from std::exception is interpreted as a conversion failure in some way + // since user-defined from_node function may throw a different object from a fkyaml::type_error. + // and std::exception is usually the base class of user-defined exception types. + o = std::nullopt; + } +} + +#endif // defined(FK_YAML_HAS_CXX_17) + /// @brief A function object to call from_node functions. /// @note User-defined specialization is available by providing implementation **OUTSIDE** fkyaml namespace. struct from_node_fn { @@ -12559,20 +12922,17 @@ class basic_node { /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/get_value/ template < typename T, typename ValueType = detail::remove_cvref_t, - detail::enable_if_t< - detail::conjunction< - std::is_default_constructible, detail::has_from_node>::value, - int> = 0> - T get_value() const noexcept(noexcept( - ConverterType::from_node(std::declval(), std::declval()))) { + detail::enable_if_t::value, int> = 0> + T get_value() const noexcept( + noexcept(std::declval().template get_value_impl(std::declval()))) { auto ret = ValueType(); if (has_anchor_name()) { auto itr = mp_meta->anchor_table.equal_range(m_prop.anchor).first; std::advance(itr, detail::node_attr_bits::get_anchor_offset(m_attrs)); - ConverterType::from_node(itr->second, ret); + itr->second.get_value_impl(ret); } else { - ConverterType::from_node(*this, ret); + get_value_impl(ret); } return ret; } @@ -12732,6 +13092,18 @@ class basic_node { return m_attrs; } + template < + typename ValueType, detail::enable_if_t>::value, int> = 0> + void get_value_impl(ValueType& v) const + noexcept(noexcept(ConverterType::from_node(std::declval(), v))) { + ConverterType::from_node(*this, v); + } + + template ::value, int> = 0> + void get_value_impl(ValueType& v) const { + v = *this; + } + /// @brief Returns reference to the sequence node value. /// @throw fkyaml::exception The node value is not a sequence. /// @return Reference to the sequence node value. @@ -12978,4 +13350,73 @@ inline fkyaml::node operator"" _yaml(const char8_t* s, std::size_t n) { FK_YAML_NAMESPACE_END +namespace std { + +template < + template class SequenceType, template class MappingType, + typename BooleanType, typename IntegerType, typename FloatNumberType, typename StringType, + template class ConverterType> +// NOLINTNEXTLINE(cert-dcl58-cpp) +struct hash> { + using node_t = fkyaml::basic_node< + SequenceType, MappingType, BooleanType, IntegerType, FloatNumberType, StringType, ConverterType>; + + std::size_t operator()(const node_t& n) const { + using boolean_type = typename node_t::boolean_type; + using integer_type = typename node_t::integer_type; + using float_number_type = typename node_t::float_number_type; + using string_type = typename node_t::string_type; + + const auto type = n.get_type(); + + std::size_t seed = 0; + hash_combine(seed, std::hash()(static_cast(type))); + + switch (type) { + case fkyaml::node_type::SEQUENCE: + hash_combine(seed, n.size()); + for (const auto& elem : n) { + hash_combine(seed, operator()(elem)); + } + return seed; + + case fkyaml::node_type::MAPPING: + hash_combine(seed, n.size()); + for (auto itr = n.begin(), end_itr = n.end(); itr != end_itr; ++itr) { + hash_combine(seed, operator()(itr.key())); + hash_combine(seed, operator()(itr.value())); + } + return seed; + + case fkyaml::node_type::NULL_OBJECT: + hash_combine(seed, 0); + return seed; + case fkyaml::node_type::BOOLEAN: + hash_combine(seed, std::hash()(n.template get_value())); + return seed; + case fkyaml::node_type::INTEGER: + hash_combine(seed, std::hash()(n.template get_value())); + return seed; + case fkyaml::node_type::FLOAT: + hash_combine(seed, std::hash()(n.template get_value())); + return seed; + case fkyaml::node_type::STRING: + hash_combine(seed, std::hash()(n.template get_value())); + return seed; + default: // LCOV_EXCL_LINE + return 0; // LCOV_EXCL_LINE + } + } + +private: + // taken from boost::hash_combine + FK_YAML_NO_SANITIZE("unsigned-shift-base", "unsigned-integer-overflow") + static void hash_combine(std::size_t& seed, std::size_t v) { + seed ^= v + 0x9e3779b9 + (seed << 6u) + (seed >> 2u); + } +}; + +} // namespace std + #endif /* FK_YAML_NODE_HPP */ diff --git a/test/unit_test/test_custom_from_node.cpp b/test/unit_test/test_custom_from_node.cpp index fed40fcd..635b224c 100644 --- a/test/unit_test/test_custom_from_node.cpp +++ b/test/unit_test/test_custom_from_node.cpp @@ -6,7 +6,9 @@ // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani // SPDX-License-Identifier: MIT +#include #include +#include #include #include @@ -30,10 +32,14 @@ struct color { int value; }; -bool operator<(const color& lhs, const color& rhs) { +bool operator<(const color& lhs, const color& rhs) noexcept { return lhs.value < rhs.value; } +bool operator==(const color& lhs, const color& rhs) noexcept { + return lhs.value == rhs.value; +} + void from_node(const fkyaml::node& node, color& color) { color.value = node["color"].get_value(); } @@ -44,6 +50,10 @@ struct rgb { int b; }; +bool operator==(const rgb& lhs, const rgb& rhs) noexcept { + return (lhs.r == rhs.r) && (lhs.g == rhs.g) && (lhs.b == rhs.b); +} + void from_node(const fkyaml::node& node, rgb& rgb) { rgb.r = node["r"].get_value(); rgb.g = node["g"].get_value(); @@ -52,6 +62,25 @@ void from_node(const fkyaml::node& node, rgb& rgb) { } // namespace test +// std::hash specialization for std::unordered_map +namespace std { + +template <> +struct hash { + std::size_t operator()(const test::color& c) const noexcept { + return std::hash()(c.value); + } +}; + +template <> +struct hash { + std::size_t operator()(const test::rgb& rgb) const noexcept { + return hash()(rgb.r) ^ (hash()(rgb.g) << 1) ^ (hash()(rgb.b) << 2); + } +}; + +} // namespace std + TEST_CASE("FromNode_UserDefinedType") { std::string input = "title: Robinson Crusoe\n" "author: Daniel Defoe\n" @@ -125,6 +154,8 @@ TEST_CASE("FromNode_UserDefinedTypeMap") { REQUIRE(colors.at(test::color {0x586776}).r == 0x58); REQUIRE(colors.at(test::color {0x586776}).g == 0x67); REQUIRE(colors.at(test::color {0x586776}).b == 0x76); + + auto colors_umap = node["colors"].get_value>(); } TEST_CASE("FromNode_UserDefinedTypeMapError") { diff --git a/test/unit_test/test_node_class.cpp b/test/unit_test/test_node_class.cpp index abb9456f..7874c47f 100644 --- a/test/unit_test/test_node_class.cpp +++ b/test/unit_test/test_node_class.cpp @@ -8,9 +8,16 @@ #include #include +#include #include -#include +#include #include +#include +#include +#include +#include +#include +#include #include @@ -2369,15 +2376,170 @@ struct string_wrap { TEST_CASE("Node_GetValue") { SECTION("sequence") { - fkyaml::node node(fkyaml::node::sequence_type {fkyaml::node(true), fkyaml::node(false)}); - - SECTION("sequence value") { - auto seq = node.get_value(); - REQUIRE(seq.size() == 2); - REQUIRE(seq[0].is_boolean()); - REQUIRE(seq[0].get_value() == true); - REQUIRE(seq[1].is_boolean()); - REQUIRE(seq[1].get_value() == false); + fkyaml::node node {true, false}; + + SECTION("sequence value (std::vector)") { + auto vector_node = node.get_value>(); + REQUIRE(vector_node.size() == 2); + REQUIRE(vector_node[0].is_boolean()); + REQUIRE(vector_node[0].get_value() == true); + REQUIRE(vector_node[1].is_boolean()); + REQUIRE(vector_node[1].get_value() == false); + + auto vector_bool = node.get_value>(); + REQUIRE(vector_bool.size() == 2); + REQUIRE(vector_bool[0] == true); + REQUIRE(vector_bool[1] == false); + } + + SECTION("sequence value (std::array)") { + auto array_node = node.get_value>(); + REQUIRE(array_node[0].is_boolean()); + REQUIRE(array_node[0].get_value() == true); + REQUIRE(array_node[1].is_boolean()); + REQUIRE(array_node[1].get_value() == false); + + auto array_bool = node.get_value>(); + REQUIRE(array_bool[0] == true); + REQUIRE(array_bool[1] == false); + } + + SECTION("sequence value (std::valarray)") { + auto valarray_node = node.get_value>(); + REQUIRE(valarray_node[0].is_boolean()); + REQUIRE(valarray_node[0].get_value() == true); + REQUIRE(valarray_node[1].is_boolean()); + REQUIRE(valarray_node[1].get_value() == false); + + auto valarray_bool = node.get_value>(); + REQUIRE(valarray_bool[0] == true); + REQUIRE(valarray_bool[1] == false); + } + + SECTION("sequence value (std::deque)") { + auto deque_node = node.get_value>(); + REQUIRE(deque_node.size() == 2); + REQUIRE(deque_node[0].is_boolean()); + REQUIRE(deque_node[0].get_value() == true); + REQUIRE(deque_node[1].is_boolean()); + REQUIRE(deque_node[1].get_value() == false); + + auto deque_bool = node.get_value>(); + REQUIRE(deque_bool.size() == 2); + REQUIRE(deque_bool[0] == true); + REQUIRE(deque_bool[1] == false); + } + + SECTION("sequence value (std::list)") { + auto list_node = node.get_value>(); + REQUIRE(list_node.size() == 2); + auto list_node_itr = list_node.begin(); + REQUIRE(list_node_itr->is_boolean()); + REQUIRE(list_node_itr->get_value() == true); + list_node_itr++; + REQUIRE(list_node_itr->is_boolean()); + REQUIRE(list_node_itr->get_value() == false); + + auto list_bool = node.get_value>(); + REQUIRE(list_bool.size() == 2); + REQUIRE(*list_bool.begin() == true); + REQUIRE(*(std::next(list_bool.begin())) == false); + } + + SECTION("sequence value (std::set)") { + auto set_node = node.get_value>(); + REQUIRE(set_node.size() == 2); + REQUIRE(set_node.find(fkyaml::node(true)) != set_node.end()); + REQUIRE(set_node.find(fkyaml::node(false)) != set_node.end()); + + auto set_bool = node.get_value>(); + REQUIRE(set_bool.size() == 2); + REQUIRE(set_bool.find(true) != set_bool.end()); + REQUIRE(set_bool.find(false) != set_bool.end()); + } + + SECTION("sequence value (std::multiset)") { + auto mset_node = node.get_value>(); + REQUIRE(mset_node.size() == 2); + REQUIRE(mset_node.find(fkyaml::node(true)) != mset_node.end()); + REQUIRE(mset_node.find(fkyaml::node(false)) != mset_node.end()); + + auto mset_bool = node.get_value>(); + REQUIRE(mset_bool.size() == 2); + REQUIRE(mset_bool.find(true) != mset_bool.end()); + REQUIRE(mset_bool.find(false) != mset_bool.end()); + } + + SECTION("sequence value (std::unordered_set)") { + auto uset_node = node.get_value>(); + REQUIRE(uset_node.size() == 2); + REQUIRE(uset_node.find(fkyaml::node(true)) != uset_node.end()); + REQUIRE(uset_node.find(fkyaml::node(false)) != uset_node.end()); + + auto uset_bool = node.get_value>(); + REQUIRE(uset_bool.size() == 2); + REQUIRE(uset_bool.find(true) != uset_bool.end()); + REQUIRE(uset_bool.find(false) != uset_bool.end()); + } + + SECTION("sequence value (std::unordered_set)") { + auto umset_node = node.get_value>(); + REQUIRE(umset_node.size() == 2); + REQUIRE(umset_node.find(fkyaml::node(true)) != umset_node.end()); + REQUIRE(umset_node.find(fkyaml::node(false)) != umset_node.end()); + + auto umset_bool = node.get_value>(); + REQUIRE(umset_bool.size() == 2); + REQUIRE(umset_bool.find(true) != umset_bool.end()); + REQUIRE(umset_bool.find(false) != umset_bool.end()); + } + + SECTION("sequence value (std::stack)") { + auto stack_node = node.get_value>(); + REQUIRE(stack_node.size() == 2); + REQUIRE(stack_node.top().is_boolean()); + REQUIRE(stack_node.top().get_value() == false); + stack_node.pop(); + REQUIRE(stack_node.top().is_boolean()); + REQUIRE(stack_node.top().get_value() == true); + + auto stack_bool = node.get_value>(); + REQUIRE(stack_bool.size() == 2); + REQUIRE(stack_bool.top() == false); + stack_bool.pop(); + REQUIRE(stack_bool.top() == true); + } + + SECTION("sequence value (std::queue)") { + auto queue_node = node.get_value>(); + REQUIRE(queue_node.size() == 2); + REQUIRE(queue_node.front().is_boolean()); + REQUIRE(queue_node.front().get_value() == true); + queue_node.pop(); + REQUIRE(queue_node.front().is_boolean()); + REQUIRE(queue_node.front().get_value() == false); + + auto queue_bool = node.get_value>(); + REQUIRE(queue_bool.size() == 2); + REQUIRE(queue_bool.front() == true); + queue_bool.pop(); + REQUIRE(queue_bool.front() == false); + } + + SECTION("sequence value (std::queue)") { + auto pqueue_node = node.get_value>(); + REQUIRE(pqueue_node.size() == 2); + REQUIRE(pqueue_node.top().is_boolean()); + REQUIRE(pqueue_node.top().get_value() == true); + pqueue_node.pop(); + REQUIRE(pqueue_node.top().is_boolean()); + REQUIRE(pqueue_node.top().get_value() == false); + + auto pqueue_bool = node.get_value>(); + REQUIRE(pqueue_bool.size() == 2); + REQUIRE(pqueue_bool.top() == true); + pqueue_bool.pop(); + REQUIRE(pqueue_bool.top() == false); } SECTION("non-sequence value") { @@ -2392,21 +2554,117 @@ TEST_CASE("Node_GetValue") { } SECTION("mapping") { - fkyaml::node node(fkyaml::node::mapping_type {{"test", fkyaml::node(3.14)}, {"foo", fkyaml::node("bar")}}); - - SECTION("mapping value") { - auto map = node.get_value(); - REQUIRE(map.size() == 2); - REQUIRE(map.find("test") != map.end()); - REQUIRE(map.at("test").is_float_number()); - REQUIRE(map.at("test").get_value() == 3.14); - REQUIRE(map.find("foo") != map.end()); - REQUIRE(map.at("foo").is_string()); - REQUIRE(map.at("foo").get_value_ref() == "bar"); + fkyaml::node node {{"test", 123}, {"foo", -456}}; + + SECTION("mapping value (std::map)") { + auto map_node = node.get_value>(); + REQUIRE(map_node.size() == 2); + REQUIRE(map_node.find("test") != map_node.end()); + REQUIRE(map_node.at("test").is_integer()); + REQUIRE(map_node.at("test").get_value() == 123); + REQUIRE(map_node.find("foo") != map_node.end()); + REQUIRE(map_node.at("foo").is_integer()); + REQUIRE(map_node.at("foo").get_value() == -456); + + auto map_compat = node.get_value>(); + REQUIRE(map_compat.size() == 2); + REQUIRE(map_compat.find("test") != map_compat.end()); + REQUIRE(map_compat.at("test") == 123); + REQUIRE(map_compat.find("foo") != map_compat.end()); + REQUIRE(map_compat.at("foo") == -456); + } + + SECTION("mapping value (std::multimap)") { + auto mmap_node = node.get_value>(); + REQUIRE(mmap_node.size() == 2); + REQUIRE(mmap_node.find("test") != mmap_node.end()); + auto mmap_node_test_range = mmap_node.equal_range("test"); + REQUIRE(std::distance(mmap_node_test_range.first, mmap_node_test_range.second) == 1); + REQUIRE(mmap_node_test_range.first->second.is_integer()); + REQUIRE(mmap_node_test_range.first->second.get_value() == 123); + REQUIRE(mmap_node.find("foo") != mmap_node.end()); + auto mmap_node_foo_range = mmap_node.equal_range("foo"); + REQUIRE(std::distance(mmap_node_test_range.first, mmap_node_test_range.second) == 1); + REQUIRE(mmap_node_foo_range.first->second.is_integer()); + REQUIRE(mmap_node_foo_range.first->second.get_value() == -456); + + auto mmap_compat = node.get_value>(); + REQUIRE(mmap_compat.size() == 2); + REQUIRE(mmap_compat.find("test") != mmap_compat.end()); + auto mmap_compat_test_range = mmap_compat.equal_range("test"); + REQUIRE(std::distance(mmap_compat_test_range.first, mmap_compat_test_range.second) == 1); + REQUIRE(mmap_compat_test_range.first->second == 123); + REQUIRE(mmap_compat.find("foo") != mmap_compat.end()); + auto mmap_compat_foo_range = mmap_compat.equal_range("foo"); + REQUIRE(std::distance(mmap_compat_test_range.first, mmap_compat_test_range.second) == 1); + REQUIRE(mmap_compat_foo_range.first->second == -456); + } + + SECTION("mapping value (std::unordered_map)") { + auto umap_node = node.get_value>(); + REQUIRE(umap_node.size() == 2); + REQUIRE(umap_node.find("test") != umap_node.end()); + REQUIRE(umap_node.at("test").is_integer()); + REQUIRE(umap_node.at("test").get_value() == 123); + REQUIRE(umap_node.find("foo") != umap_node.end()); + REQUIRE(umap_node.at("foo").is_integer()); + REQUIRE(umap_node.at("foo").get_value() == -456); + + auto umap_compat = node.get_value>(); + REQUIRE(umap_compat.size() == 2); + REQUIRE(umap_compat.find("test") != umap_compat.end()); + REQUIRE(umap_compat.at("test") == 123); + REQUIRE(umap_compat.find("foo") != umap_compat.end()); + REQUIRE(umap_compat.at("foo") == -456); + + fkyaml::node various_type_nodes = { + {nullptr, nullptr}, + {true, nullptr}, + {123, nullptr}, + {3.14, nullptr}, + {"foo", nullptr}, + {{{"foo", "bar"}}, nullptr}, + {{"foo", "bar"}, nullptr}, + }; + auto umap = various_type_nodes.get_value>(); + } + + SECTION("mapping value (std::unordered_multimap)") { + auto ummap_node = node.get_value>(); + REQUIRE(ummap_node.size() == 2); + REQUIRE(ummap_node.find("test") != ummap_node.end()); + auto ummap_node_test_range = ummap_node.equal_range("test"); + REQUIRE(std::distance(ummap_node_test_range.first, ummap_node_test_range.second) == 1); + REQUIRE(ummap_node_test_range.first->second.is_integer()); + REQUIRE(ummap_node_test_range.first->second.get_value() == 123); + REQUIRE(ummap_node.find("foo") != ummap_node.end()); + auto ummap_node_foo_range = ummap_node.equal_range("foo"); + REQUIRE(std::distance(ummap_node_test_range.first, ummap_node_test_range.second) == 1); + REQUIRE(ummap_node_foo_range.first->second.is_integer()); + REQUIRE(ummap_node_foo_range.first->second.get_value() == -456); + + auto ummap_compat = node.get_value>(); + REQUIRE(ummap_compat.size() == 2); + REQUIRE(ummap_compat.find("test") != ummap_compat.end()); + auto ummap_compat_test_range = ummap_compat.equal_range("test"); + REQUIRE(std::distance(ummap_compat_test_range.first, ummap_compat_test_range.second) == 1); + REQUIRE(ummap_compat_test_range.first->second == 123); + REQUIRE(ummap_compat.find("foo") != ummap_compat.end()); + auto ummap_compat_foo_range = ummap_compat.equal_range("foo"); + REQUIRE(std::distance(ummap_compat_test_range.first, ummap_compat_test_range.second) == 1); + REQUIRE(ummap_compat_foo_range.first->second == -456); } SECTION("non-mapping values") { REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); + using array_t = std::array; + REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); + REQUIRE_THROWS_AS(node.get_value>(), fkyaml::type_error); + REQUIRE_THROWS_AS(node.get_value>(), fkyaml::type_error); + using pair_t = std::pair; + REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); + using tuple_t = std::tuple; + REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); @@ -2628,20 +2886,26 @@ TEST_CASE("Node_GetValue") { SECTION("string node value") { fkyaml::node node("test"); - SECTION("string value") { - auto str = node.get_value(); + SECTION("string value (std::string)") { + auto str = node.get_value(); REQUIRE(str.size() == 4); REQUIRE(str == "test"); } - SECTION("compatible string value") { + SECTION("string value (string_wrap)") { auto str_wrap = node.get_value(); REQUIRE(str_wrap.str.size() == 4); REQUIRE(str_wrap.str == "test"); } + SECTION("string value (fkyaml::detail::str_view)") { + auto str_view = node.get_value(); + REQUIRE(str_view.size() == 4); + REQUIRE(str_view == "test"); + } + #ifdef FK_YAML_HAS_CXX_17 - SECTION("string view") { + SECTION("string value (std::string_view)") { auto str_view = node.get_value(); REQUIRE(str_view.size() == 4); REQUIRE(str_view == "test"); @@ -2657,6 +2921,51 @@ TEST_CASE("Node_GetValue") { REQUIRE_THROWS_AS(node.get_value(), fkyaml::type_error); } } + + SECTION("std::pair") { + fkyaml::node n {123, "test"}; + + auto pair_node = n.get_value>(); + REQUIRE(pair_node.first.is_integer()); + REQUIRE(pair_node.first.get_value() == 123); + REQUIRE(pair_node.second.is_string()); + REQUIRE(pair_node.second.get_value() == "test"); + + auto pair_val = n.get_value>(); + REQUIRE(pair_val.first == 123); + REQUIRE(pair_val.second == "test"); + } + + SECTION("std::tuple") { + fkyaml::node n {123, "test", true}; + + auto tuple_node = n.get_value>(); + REQUIRE(std::get<0>(tuple_node).is_integer()); + REQUIRE(std::get<0>(tuple_node).get_value() == 123); + REQUIRE(std::get<1>(tuple_node).is_string()); + REQUIRE(std::get<1>(tuple_node).get_value() == "test"); + REQUIRE(std::get<2>(tuple_node).is_boolean()); + REQUIRE(std::get<2>(tuple_node).get_value() == true); + + auto tuple_val = n.get_value>(); + REQUIRE(std::get<0>(tuple_val) == 123); + REQUIRE(std::get<1>(tuple_val) == "test"); + REQUIRE(std::get<2>(tuple_val) == true); + } + +#ifdef FK_YAML_HAS_CXX_17 + SECTION("std::optional") { + fkyaml::node n {true, false}; + auto opt_vec = n.get_value>>(); + REQUIRE(opt_vec.has_value()); + REQUIRE(opt_vec.value().size() == 2); + REQUIRE(opt_vec.value().at(0) == true); + REQUIRE(opt_vec.value().at(1) == false); + + auto opt_bool = n.get_value>(); + REQUIRE_FALSE(opt_bool.has_value()); + } +#endif } // From 5f59b1371bae9a708727c5c93114c3f97be03b61 Mon Sep 17 00:00:00 2001 From: fktn Date: Tue, 12 Nov 2024 22:14:48 +0900 Subject: [PATCH 08/13] Add forward declaration header (#422) * added fkyaml_fwd.hpp to provide forward declarations * no include of cpp_config_macros.hpp in version_macros.hpp & added define_macros.hpp * updated amalgamation scripts and CONTRIBUTING.md * added descriptions about the header file for forward declarations --- CONTRIBUTING.md | 8 +- README.md | 4 +- docs/mkdocs/docs/index.md | 4 +- docs/mkdocs/docs/tutorials/index.md | 6 +- .../fkYAML/detail/conversions/from_node.hpp | 2 +- .../fkYAML/detail/conversions/scalar_conv.hpp | 2 +- include/fkYAML/detail/conversions/to_node.hpp | 2 +- .../fkYAML/detail/conversions/to_string.hpp | 2 +- include/fkYAML/detail/document_metainfo.hpp | 2 +- .../fkYAML/detail/encodings/uri_encoding.hpp | 2 +- .../detail/encodings/utf_encode_detector.hpp | 2 +- .../fkYAML/detail/encodings/utf_encode_t.hpp | 2 +- .../fkYAML/detail/encodings/utf_encodings.hpp | 2 +- .../fkYAML/detail/encodings/yaml_escaper.hpp | 2 +- .../detail/input/block_scalar_header.hpp | 2 +- include/fkYAML/detail/input/deserializer.hpp | 2 +- include/fkYAML/detail/input/input_adapter.hpp | 2 +- .../fkYAML/detail/input/lexical_analyzer.hpp | 2 +- .../fkYAML/detail/input/position_tracker.hpp | 2 +- include/fkYAML/detail/input/scalar_parser.hpp | 2 +- .../fkYAML/detail/input/scalar_scanner.hpp | 2 +- include/fkYAML/detail/input/tag_resolver.hpp | 2 +- include/fkYAML/detail/input/tag_t.hpp | 2 +- include/fkYAML/detail/iterator.hpp | 2 +- .../fkYAML/detail/macros/define_macros.hpp | 15 ++ .../fkYAML/detail/macros/version_macros.hpp | 2 - include/fkYAML/detail/meta/detect.hpp | 2 +- .../detail/meta/input_adapter_traits.hpp | 2 +- include/fkYAML/detail/meta/node_traits.hpp | 14 +- include/fkYAML/detail/meta/stl_supplement.hpp | 2 +- include/fkYAML/detail/meta/type_traits.hpp | 2 +- include/fkYAML/detail/node_attrs.hpp | 2 +- include/fkYAML/detail/node_property.hpp | 2 +- include/fkYAML/detail/node_ref_storage.hpp | 2 +- include/fkYAML/detail/output/serializer.hpp | 2 +- include/fkYAML/detail/str_view.hpp | 2 +- include/fkYAML/detail/string_formatter.hpp | 2 +- .../fkYAML/detail/types/lexical_token_t.hpp | 2 +- include/fkYAML/detail/types/node_t.hpp | 2 +- .../fkYAML/detail/types/yaml_version_t.hpp | 2 +- include/fkYAML/exception.hpp | 2 +- include/fkYAML/fkyaml_fwd.hpp | 51 ++++++ include/fkYAML/node.hpp | 13 +- include/fkYAML/node_type.hpp | 2 +- include/fkYAML/node_value_converter.hpp | 2 +- include/fkYAML/ordered_map.hpp | 2 +- include/fkYAML/yaml_version_type.hpp | 2 +- scripts/check_amalgamation.bat | 23 ++- scripts/check_amalgamation.sh | 24 ++- scripts/run_amalgamation.bat | 3 +- scripts/run_amalgamation.sh | 3 +- single_include/fkYAML/fkyaml_fwd.hpp | 100 +++++++++++ single_include/fkYAML/node.hpp | 156 ++++++++++++------ tool/amalgamation/fkyaml_fwd_hpp.json | 10 ++ .../{fkYAML.json => node_hpp.json} | 0 55 files changed, 374 insertions(+), 138 deletions(-) create mode 100644 include/fkYAML/detail/macros/define_macros.hpp create mode 100644 include/fkYAML/fkyaml_fwd.hpp create mode 100644 single_include/fkYAML/fkyaml_fwd.hpp create mode 100644 tool/amalgamation/fkyaml_fwd_hpp.json rename tool/amalgamation/{fkYAML.json => node_hpp.json} (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0df94cef..1f1be360 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,7 @@ To make changes to the fkYAML project, you need to edit the following files: ### 1. [`include/fkYAML/**.hpp`](https://github.com/fktn-k/fkYAML/tree/develop/include/fkYAML) -These files are the sources of the fkYAML library and **DO NOT** directly change the single header version under the [`single_include`](https://github.com/fktn-k/fkYAML/tree/develop/single_include/) directory. Alghough amalgamation is automatically executed in the GitHub Actions workflows, you can run the script ([`run_amalgamation.bat`](https://github.com/fktn-k/fkYAML/scripts/run_amalgamation.bat) for Windows, [`run_amalgamation.sh`](https://github.com/fktn-k/fkYAML/scripts/run_amalgamation.sh) otherwise) to regenerate [`single_include/fkYAML/node.hpp`](https://github.com/fktn-k/fkYAML/tree/develop/single_include/fkYAML/node.hpp) locally, which will save you from waiting unnecessarily long for the workflow results. +These files are the sources of the fkYAML library and **DO NOT** directly change the files under the [`single_include`](https://github.com/fktn-k/fkYAML/tree/develop/single_include/) directory. Alghough amalgamation is automatically executed in the GitHub Actions workflows, you can run the script ([`run_amalgamation.bat`](https://github.com/fktn-k/fkYAML/scripts/run_amalgamation.bat) for Windows, [`run_amalgamation.sh`](https://github.com/fktn-k/fkYAML/scripts/run_amalgamation.sh) otherwise) to regenerate [`single_include/fkYAML/node.hpp`](https://github.com/fktn-k/fkYAML/blob/develop/single_include/fkYAML/node.hpp) and [`single_include/fkYAML/fkyaml_fwd.hpp`](https://github.com/fktn-k/fkYAML/blob/develop/single_include/fkYAML/fkyaml_fwd.hpp) locally, which will save us from waiting unnecessarily long for the workflow results. **Windows (Command Prompt)** ```batch @@ -41,7 +41,7 @@ cd path/to/fkYAML scripts/run_amalgamation.sh ``` -If you just want to check if amalgamation is needed locally, run the script ([`run_amalgamation.bat`](https://github.com/fktn-k/fkYAML/scripts/run_amalgamation.bat) for Windows, [`run_amalgamation.sh`](https://github.com/fktn-k/fkYAML/scripts/run_amalgamation.sh) otherwise) with the following commands: +If you just want to check if amalgamation is needed locally, run the script ([`check_amalgamation.bat`](https://github.com/fktn-k/fkYAML/blob/develop/scripts/check_amalgamation.bat) for Windows, [`check_amalgamation.sh`](https://github.com/fktn-k/fkYAML/blob/develop/scripts/check_amalgamation.sh) otherwise) with the following commands: **Windows (Command Prompt)** ```batch @@ -106,7 +106,7 @@ The commands above will automatically install all the dependencies using [Python ### 4. Format source files [GitHub Actions](https://github.com/fktn-k/fkYAML/actions) will test the updated project with the [Clang-Format](https://github.com/llvm/llvm-project/releases/tag/llvmorg-18.1.3) tool (18.1.3) once you open a PR or push commits afterwards which include changes in the source files under either [`include`](https://github.com/fktn-k/fkYAML/tree/develop/include) or [`test`](https://github.com/fktn-k/fkYAML/tree/develop/test) directories. -Although code formatting is automatically executed in the GitHub Actions workflows, you can run the script files ([`run_clang_format.bat`](https://github.com/fktn-k/fkYAML/scripts/run_clang_format.bat) for Windows, [`run_clang_format.sh`](https://github.com/fktn-k/fkYAML/scripts/run_clang_format.sh) otherwise) to check if your changes follow the rules defined in the [`.clang-format`](https://github.com/fktn-k/fkYAML/tree/develop/.clang-format) file on your local environment in advance. +Although code formatting is automatically executed in the GitHub Actions workflows, you can run the script files ([`run_clang_format.bat`](https://github.com/fktn-k/fkYAML/blob/develop/scripts/run_clang_format.bat) for Windows, [`run_clang_format.sh`](https://github.com/fktn-k/fkYAML/blob/develop/scripts/run_clang_format.sh) otherwise) to check if your changes follow the rules defined in the [`.clang-format`](https://github.com/fktn-k/fkYAML/blob/develop/.clang-format) file on your local environment in advance. Note that, since the Clang-Format tool does not gurantee backward compatibility especially in its edge cases and its behaviors might therefore vary from version to version, it's highly recommended that you use the above script files to avoid unnecessary confusion for that kind of reason. The scripts uses [the Clang-Format Python distribution](https://pypi.org/project/clang-format/18.1.3/) and installs it using [the Python venv module](https://docs.python.org/3/library/venv.html) if it's not been installed yet. You can run the scripts with the following commands: @@ -128,7 +128,7 @@ scripts/run_clang_format.sh When you open a pull request, fkYAML will automatically be built/tested with (1) various combinations of compilers and operating systems and (2) analyzers such as [Valgrind](https://valgrind.org/) and [Clang Sanitizers](https://clang.llvm.org/docs/index.html) to detect runtime issues (e.g., memory leaks), on [GitHub Actions](https://github.com/fktn-k/fkYAML/actions) once you open a pull request. These can result in failing builds and/or unit tests which run successfully on your local environment. As a policy of this project, however, all the workflow checks must be passed before merging. -You can run tests with those tools with the following commands: +You can run tests with those tools locally by executing the following commands: **Valgrind** (assuming Valgrind is already installed.) ```bash diff --git a/README.md b/README.md index 1fe2df19..36a4d02b 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,9 @@ There are a lot of YAML libraries out there, and each may have its reason to exi fkYAML has been developed with these design goals: ### :briefcase: **Portable** -The whole code depends only on C++ standards, and is carefully designed to work on many platforms so that fkYAML can be imported into existing C++ projects written in C++11 or better. +The library depends only on C++ standards, and is carefully designed to work on many platforms so that fkYAML can be imported into existing C++ projects written in C++11 or better. No external dependencies, no sub-project, or no additional compiler flags are required. -Although fkYAML is a library with multiple header files by default, you can use the single-header version located in the [single_include](https://github.com/fktn-k/tree/develop/single_include) directory. +Although fkYAML is a library with multiple header files by default, you can use the single-header version ([single_include/fkYAML/node.hpp](https://github.com/fktn-k/fkYAML/blob/develop/single_include/fkYAML/node.hpp)) located in the [single_include](https://github.com/fktn-k/tree/develop/single_include) directory. You can further use [single_include/fkYAML/fkyaml_fwd.hpp](https://github.com/fktn-k/fkYAML/blob/develop/single_include/fkYAML/fkyaml_fwd.hpp) for forward declarations. Furthermore, the project supports [CMake](https://cmake.org/) and provides [the documentation exclusively for CMake integration](https://fktn-k.github.io/fkYAML/tutorials/cmake_integration). Those characteristics allow existing C++ project using CMake for builds to quickly incorporate YAML support with just a little effort. diff --git a/docs/mkdocs/docs/index.md b/docs/mkdocs/docs/index.md index d89e3cf9..bf39d9d5 100644 --- a/docs/mkdocs/docs/index.md +++ b/docs/mkdocs/docs/index.md @@ -9,9 +9,9 @@ There are a lot of YAML libraries out there, and each may have its reason to exi fkYAML has been developed with these design goals: ### :briefcase: **Portable** -: The whole code depends only on C++ standards, and is carefully designed to work on many platforms so that fkYAML can be imported into existing C++ projects written in C++11 or better. +: The library depends only on C++ standards, and is carefully designed to work on many platforms so that fkYAML can be imported into existing C++ projects written in C++11 or better. No external dependencies, no sub-project, or no additional compiler flags are required. - Although fkYAML is a library with multiple header files by default, you can use the single-header version located in the [single_include](https://github.com/fktn-k/tree/develop/single_include) directory. + Although fkYAML is a library with multiple header files by default, you can use the single-header version ([single_include/fkYAML/node.hpp](https://github.com/fktn-k/fkYAML/blob/develop/single_include/fkYAML/node.hpp)) located in the [single_include](https://github.com/fktn-k/tree/develop/single_include) directory. You can further use [single_include/fkYAML/fkyaml_fwd.hpp](https://github.com/fktn-k/fkYAML/blob/develop/single_include/fkYAML/fkyaml_fwd.hpp) for forward declarations. Furthermore, the project supports [CMake](https://cmake.org/) and provides [the documentation exclusively for CMake integration](https://fktn-k.github.io/fkYAML/tutorials/cmake_integration). Those characteristics allow existing C++ project using CMake for builds to quickly incorporate YAML support with just a little effort. diff --git a/docs/mkdocs/docs/tutorials/index.md b/docs/mkdocs/docs/tutorials/index.md index 012e1602..8518c79f 100644 --- a/docs/mkdocs/docs/tutorials/index.md +++ b/docs/mkdocs/docs/tutorials/index.md @@ -12,8 +12,8 @@ Although you can just copy, paste and include the header files in your C++ proje The followings are possible ways of preparing for the use of fkYAML: ### :file_folder: Download a release package -You can [download the latest package (fkYAML.tgz for UNIX or fkYAML.zip for Windows) from here](https://github.com/fktn-k/fkYAML/releases/latest). -The single-header version of the fkYAML package can also be downloaded since v0.3.1 with the name of fkYAML_single_header.{tgz|zip}. +You can [download the latest package (fkYAML.tgz or fkYAML.zip) from here](https://github.com/fktn-k/fkYAML/releases/latest). +The single-header versions can also be downloaded since v0.3.1 with the name of fkYAML_single_header.{tgz|zip}. After the download gets completed, unzip and put the package in some directory on your machine. The destination path can be whatever you want, and you're all set! @@ -58,7 +58,7 @@ Note that you must execute the CMake `add_subdirectory()` command for the submod Let's start with a really simple example. Say you have an example.yaml file and now you want to load the contents. Note that the following example files assumes that you have installed the fkYAML library somewhere on your machine. -See [the CMake Integration section]() for the other ways and modify the implementation if necessary. +See [the CMake Integration section](./cmake_integration.md) for the other ways and modify the implementation if necessary. Also, make sure the example.yaml file is encoded in either the UTF-8, UTF-16BE/LE or UTF-32BE/LE format. ```title="Project Structure" diff --git a/include/fkYAML/detail/conversions/from_node.hpp b/include/fkYAML/detail/conversions/from_node.hpp index 8f5e391f..4c8c9178 100644 --- a/include/fkYAML/detail/conversions/from_node.hpp +++ b/include/fkYAML/detail/conversions/from_node.hpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/conversions/scalar_conv.hpp b/include/fkYAML/detail/conversions/scalar_conv.hpp index 678dfef7..4b583b8f 100644 --- a/include/fkYAML/detail/conversions/scalar_conv.hpp +++ b/include/fkYAML/detail/conversions/scalar_conv.hpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #if FK_YAML_HAS_TO_CHARS diff --git a/include/fkYAML/detail/conversions/to_node.hpp b/include/fkYAML/detail/conversions/to_node.hpp index 4ce2a708..e0cbe5d3 100644 --- a/include/fkYAML/detail/conversions/to_node.hpp +++ b/include/fkYAML/detail/conversions/to_node.hpp @@ -11,7 +11,7 @@ #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/conversions/to_string.hpp b/include/fkYAML/detail/conversions/to_string.hpp index 3c169913..32bd24a0 100644 --- a/include/fkYAML/detail/conversions/to_string.hpp +++ b/include/fkYAML/detail/conversions/to_string.hpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include diff --git a/include/fkYAML/detail/document_metainfo.hpp b/include/fkYAML/detail/document_metainfo.hpp index f07c5364..c078b8b6 100644 --- a/include/fkYAML/detail/document_metainfo.hpp +++ b/include/fkYAML/detail/document_metainfo.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/include/fkYAML/detail/encodings/uri_encoding.hpp b/include/fkYAML/detail/encodings/uri_encoding.hpp index 40159001..fb99a59e 100644 --- a/include/fkYAML/detail/encodings/uri_encoding.hpp +++ b/include/fkYAML/detail/encodings/uri_encoding.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/encodings/utf_encode_detector.hpp b/include/fkYAML/detail/encodings/utf_encode_detector.hpp index 09d6326a..3bcaa5f6 100644 --- a/include/fkYAML/detail/encodings/utf_encode_detector.hpp +++ b/include/fkYAML/detail/encodings/utf_encode_detector.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/encodings/utf_encode_t.hpp b/include/fkYAML/detail/encodings/utf_encode_t.hpp index 88f4c207..1def9d3f 100644 --- a/include/fkYAML/detail/encodings/utf_encode_t.hpp +++ b/include/fkYAML/detail/encodings/utf_encode_t.hpp @@ -11,7 +11,7 @@ #include -#include +#include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/encodings/utf_encodings.hpp b/include/fkYAML/detail/encodings/utf_encodings.hpp index 7855d548..0a6efb59 100644 --- a/include/fkYAML/detail/encodings/utf_encodings.hpp +++ b/include/fkYAML/detail/encodings/utf_encodings.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/encodings/yaml_escaper.hpp b/include/fkYAML/detail/encodings/yaml_escaper.hpp index 20f6ab46..13faa4c6 100644 --- a/include/fkYAML/detail/encodings/yaml_escaper.hpp +++ b/include/fkYAML/detail/encodings/yaml_escaper.hpp @@ -11,7 +11,7 @@ #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/input/block_scalar_header.hpp b/include/fkYAML/detail/input/block_scalar_header.hpp index f336a33c..d9bc2aa1 100644 --- a/include/fkYAML/detail/input/block_scalar_header.hpp +++ b/include/fkYAML/detail/input/block_scalar_header.hpp @@ -11,7 +11,7 @@ #include -#include +#include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/input/deserializer.hpp b/include/fkYAML/detail/input/deserializer.hpp index 408642a7..a3311125 100644 --- a/include/fkYAML/detail/input/deserializer.hpp +++ b/include/fkYAML/detail/input/deserializer.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/input/input_adapter.hpp b/include/fkYAML/detail/input/input_adapter.hpp index e8510df0..0907d715 100644 --- a/include/fkYAML/detail/input/input_adapter.hpp +++ b/include/fkYAML/detail/input/input_adapter.hpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/input/lexical_analyzer.hpp b/include/fkYAML/detail/input/lexical_analyzer.hpp index 127b6170..94796bf4 100644 --- a/include/fkYAML/detail/input/lexical_analyzer.hpp +++ b/include/fkYAML/detail/input/lexical_analyzer.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/input/position_tracker.hpp b/include/fkYAML/detail/input/position_tracker.hpp index bca52e0d..1ecbffad 100644 --- a/include/fkYAML/detail/input/position_tracker.hpp +++ b/include/fkYAML/detail/input/position_tracker.hpp @@ -11,7 +11,7 @@ #include -#include +#include #include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/input/scalar_parser.hpp b/include/fkYAML/detail/input/scalar_parser.hpp index b3bf4f1d..b5062eea 100644 --- a/include/fkYAML/detail/input/scalar_parser.hpp +++ b/include/fkYAML/detail/input/scalar_parser.hpp @@ -9,7 +9,7 @@ #ifndef FK_YAML_DETAIL_INPUT_SCALAR_PARSER_HPP #define FK_YAML_DETAIL_INPUT_SCALAR_PARSER_HPP -#include +#include #include #include #include diff --git a/include/fkYAML/detail/input/scalar_scanner.hpp b/include/fkYAML/detail/input/scalar_scanner.hpp index 895dfec5..4b86e444 100644 --- a/include/fkYAML/detail/input/scalar_scanner.hpp +++ b/include/fkYAML/detail/input/scalar_scanner.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/include/fkYAML/detail/input/tag_resolver.hpp b/include/fkYAML/detail/input/tag_resolver.hpp index 682d682f..dc001ff9 100644 --- a/include/fkYAML/detail/input/tag_resolver.hpp +++ b/include/fkYAML/detail/input/tag_resolver.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/input/tag_t.hpp b/include/fkYAML/detail/input/tag_t.hpp index fa709442..62ae847f 100644 --- a/include/fkYAML/detail/input/tag_t.hpp +++ b/include/fkYAML/detail/input/tag_t.hpp @@ -11,7 +11,7 @@ #include -#include +#include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/iterator.hpp b/include/fkYAML/detail/iterator.hpp index 595861f9..f0d638f4 100644 --- a/include/fkYAML/detail/iterator.hpp +++ b/include/fkYAML/detail/iterator.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/include/fkYAML/detail/macros/define_macros.hpp b/include/fkYAML/detail/macros/define_macros.hpp new file mode 100644 index 00000000..5325fce6 --- /dev/null +++ b/include/fkYAML/detail/macros/define_macros.hpp @@ -0,0 +1,15 @@ +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#ifndef FK_YAML_DETAIL_MACROS_DEFINE_MACROS_HPP +#define FK_YAML_DETAIL_MACROS_DEFINE_MACROS_HPP + +#include +#include + +#endif /* FK_YAML_DETAIL_MACROS_DEFINE_MACROS_HPP */ diff --git a/include/fkYAML/detail/macros/version_macros.hpp b/include/fkYAML/detail/macros/version_macros.hpp index 044468a6..ea5e740c 100644 --- a/include/fkYAML/detail/macros/version_macros.hpp +++ b/include/fkYAML/detail/macros/version_macros.hpp @@ -45,6 +45,4 @@ } /* namespace detail */ \ FK_YAML_NAMESPACE_END -#include - #endif // !defined(FK_YAML_VERCHECK_SUCCEEDED) diff --git a/include/fkYAML/detail/meta/detect.hpp b/include/fkYAML/detail/meta/detect.hpp index 31e79559..36b85030 100644 --- a/include/fkYAML/detail/meta/detect.hpp +++ b/include/fkYAML/detail/meta/detect.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/meta/input_adapter_traits.hpp b/include/fkYAML/detail/meta/input_adapter_traits.hpp index 734f30b9..8442fb18 100644 --- a/include/fkYAML/detail/meta/input_adapter_traits.hpp +++ b/include/fkYAML/detail/meta/input_adapter_traits.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/include/fkYAML/detail/meta/node_traits.hpp b/include/fkYAML/detail/meta/node_traits.hpp index e94e6409..b6050afc 100644 --- a/include/fkYAML/detail/meta/node_traits.hpp +++ b/include/fkYAML/detail/meta/node_traits.hpp @@ -9,21 +9,11 @@ #ifndef FK_YAML_DETAIL_META_NODE_TRAITS_HPP #define FK_YAML_DETAIL_META_NODE_TRAITS_HPP -#include +#include #include #include #include - -FK_YAML_NAMESPACE_BEGIN - -// forward declaration for basic_node<...> -template < - template class SequenceType, template class MappingType, - typename BooleanType, typename IntegerType, typename FloatNumberType, typename StringType, - template class ConverterType> -class basic_node; - -FK_YAML_NAMESPACE_END +#include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/meta/stl_supplement.hpp b/include/fkYAML/detail/meta/stl_supplement.hpp index 950e8575..9d2e0028 100644 --- a/include/fkYAML/detail/meta/stl_supplement.hpp +++ b/include/fkYAML/detail/meta/stl_supplement.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #ifdef FK_YAML_HAS_CXX_14 #include diff --git a/include/fkYAML/detail/meta/type_traits.hpp b/include/fkYAML/detail/meta/type_traits.hpp index 06a3d663..4e9ec4ae 100644 --- a/include/fkYAML/detail/meta/type_traits.hpp +++ b/include/fkYAML/detail/meta/type_traits.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include diff --git a/include/fkYAML/detail/node_attrs.hpp b/include/fkYAML/detail/node_attrs.hpp index ad7fa0ac..6c1f4c9c 100644 --- a/include/fkYAML/detail/node_attrs.hpp +++ b/include/fkYAML/detail/node_attrs.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/node_property.hpp b/include/fkYAML/detail/node_property.hpp index a9eb65cd..7fd0c92d 100644 --- a/include/fkYAML/detail/node_property.hpp +++ b/include/fkYAML/detail/node_property.hpp @@ -11,7 +11,7 @@ #include -#include +#include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/node_ref_storage.hpp b/include/fkYAML/detail/node_ref_storage.hpp index 28076862..2c0abbcb 100644 --- a/include/fkYAML/detail/node_ref_storage.hpp +++ b/include/fkYAML/detail/node_ref_storage.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include diff --git a/include/fkYAML/detail/output/serializer.hpp b/include/fkYAML/detail/output/serializer.hpp index 142e5eef..db9d3e4f 100644 --- a/include/fkYAML/detail/output/serializer.hpp +++ b/include/fkYAML/detail/output/serializer.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/str_view.hpp b/include/fkYAML/detail/str_view.hpp index 2314c562..e4b88bdc 100644 --- a/include/fkYAML/detail/str_view.hpp +++ b/include/fkYAML/detail/str_view.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/fkYAML/detail/string_formatter.hpp b/include/fkYAML/detail/string_formatter.hpp index fbe95fbc..80b7f5fc 100644 --- a/include/fkYAML/detail/string_formatter.hpp +++ b/include/fkYAML/detail/string_formatter.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/types/lexical_token_t.hpp b/include/fkYAML/detail/types/lexical_token_t.hpp index 1999e48f..65267b37 100644 --- a/include/fkYAML/detail/types/lexical_token_t.hpp +++ b/include/fkYAML/detail/types/lexical_token_t.hpp @@ -11,7 +11,7 @@ #include -#include +#include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/types/node_t.hpp b/include/fkYAML/detail/types/node_t.hpp index cd52c1d2..be60b4a0 100644 --- a/include/fkYAML/detail/types/node_t.hpp +++ b/include/fkYAML/detail/types/node_t.hpp @@ -11,7 +11,7 @@ #include -#include +#include #include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/detail/types/yaml_version_t.hpp b/include/fkYAML/detail/types/yaml_version_t.hpp index 961a0fd1..cf0dea48 100644 --- a/include/fkYAML/detail/types/yaml_version_t.hpp +++ b/include/fkYAML/detail/types/yaml_version_t.hpp @@ -11,7 +11,7 @@ #include -#include +#include #include FK_YAML_DETAIL_NAMESPACE_BEGIN diff --git a/include/fkYAML/exception.hpp b/include/fkYAML/exception.hpp index e83a6dba..5eccea0f 100644 --- a/include/fkYAML/exception.hpp +++ b/include/fkYAML/exception.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/include/fkYAML/fkyaml_fwd.hpp b/include/fkYAML/fkyaml_fwd.hpp new file mode 100644 index 00000000..db3bb99d --- /dev/null +++ b/include/fkYAML/fkyaml_fwd.hpp @@ -0,0 +1,51 @@ +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#ifndef FK_YAML_FKYAML_FWD_HPP +#define FK_YAML_FKYAML_FWD_HPP + +#include +#include +#include +#include + +#include + +FK_YAML_NAMESPACE_BEGIN + +/// @brief An ADL friendly converter between basic_node objects and native data objects. +/// @tparam ValueType A target data type. +/// @sa https://fktn-k.github.io/fkYAML/api/node_value_converter/ +template +class node_value_converter; + +/// @brief A class to store value of YAML nodes. +/// @sa https://fktn-k.github.io/fkYAML/api/basic_node/ +template < + template class SequenceType = std::vector, + template class MappingType = std::map, typename BooleanType = bool, + typename IntegerType = std::int64_t, typename FloatNumberType = double, typename StringType = std::string, + template class ConverterType = node_value_converter> +class basic_node; + +/// @brief default YAML node value container. +/// @sa https://fktn-k.github.io/fkYAML/api/basic_node/node/ +using node = basic_node<>; + +/// @brief A minimal map-like container which preserves insertion order. +/// @tparam Key A type for keys. +/// @tparam Value A type for values. +/// @tparam IgnoredCompare A placeholder for key comparison. This will be ignored. +/// @tparam Allocator A class for allocators. +/// @sa https://fktn-k.github.io/fkYAML/api/ordered_map/ +template +class ordered_map; + +FK_YAML_NAMESPACE_END + +#endif /* FK_YAML_FKYAML_FWD_HPP */ diff --git a/include/fkYAML/node.hpp b/include/fkYAML/node.hpp index 3cb58883..bbdeca3a 100644 --- a/include/fkYAML/node.hpp +++ b/include/fkYAML/node.hpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include @@ -44,10 +44,9 @@ FK_YAML_NAMESPACE_BEGIN /// @brief A class to store value of YAML nodes. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/ template < - template class SequenceType = std::vector, - template class MappingType = std::map, typename BooleanType = bool, - typename IntegerType = std::int64_t, typename FloatNumberType = double, typename StringType = std::string, - template class ConverterType = node_value_converter> + template class SequenceType, template class MappingType, + typename BooleanType, typename IntegerType, typename FloatNumberType, typename StringType, + template class ConverterType> class basic_node { public: /// @brief A type for iterators of basic_node containers. @@ -1677,10 +1676,6 @@ inline std::istream& operator>>( return is; } -/// @brief default YAML node value container. -/// @sa https://fktn-k.github.io/fkYAML/api/basic_node/node/ -using node = basic_node<>; - /// @brief namespace for user-defined literals for the fkYAML library. inline namespace literals { /// @brief namespace for user-defined literals for YAML node objects. diff --git a/include/fkYAML/node_type.hpp b/include/fkYAML/node_type.hpp index 9b0fe445..247fe322 100644 --- a/include/fkYAML/node_type.hpp +++ b/include/fkYAML/node_type.hpp @@ -11,7 +11,7 @@ #include -#include +#include FK_YAML_NAMESPACE_BEGIN diff --git a/include/fkYAML/node_value_converter.hpp b/include/fkYAML/node_value_converter.hpp index 4d872c9b..2a84526f 100644 --- a/include/fkYAML/node_value_converter.hpp +++ b/include/fkYAML/node_value_converter.hpp @@ -11,7 +11,7 @@ #include -#include +#include #include #include diff --git a/include/fkYAML/ordered_map.hpp b/include/fkYAML/ordered_map.hpp index c9843d24..d05cccde 100644 --- a/include/fkYAML/ordered_map.hpp +++ b/include/fkYAML/ordered_map.hpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include diff --git a/include/fkYAML/yaml_version_type.hpp b/include/fkYAML/yaml_version_type.hpp index 1a06c8ee..ecb608a3 100644 --- a/include/fkYAML/yaml_version_type.hpp +++ b/include/fkYAML/yaml_version_type.hpp @@ -11,7 +11,7 @@ #include -#include +#include FK_YAML_NAMESPACE_BEGIN diff --git a/scripts/check_amalgamation.bat b/scripts/check_amalgamation.bat index 8a382525..34748010 100644 --- a/scripts/check_amalgamation.bat +++ b/scripts/check_amalgamation.bat @@ -6,19 +6,30 @@ set CALLER_DIR=%cd% set SCRIPT_DIR=%~dp0 cd $SCRIPT_DIR%\.. -set SINGLE_HEADER_PATH=%SCRIPT_DIR%\..\single_include\fkYAML\node.hpp +set NODE_HPP_PATH=%SCRIPT_DIR%\..\single_include\fkYAML\node.hpp +set FKYAML_FWD_HPP_PATH=%SCRIPT_DIR%\..\single_include\fkYAML\fkyaml_fwd.hpp + +move %NODE_HPP_PATH% %NODE_HPP_PATH%~ > nul +move %FKYAML_FWD_HPP_PATH% %FKYAML_FWD_HPP_PATH%~ > nul -move %SINGLE_HEADER_PATH% %SINGLE_HEADER_PATH%~ > nul call %SCRIPT_DIR%\run_amalgamation.bat > nul -fc %SINGLE_HEADER_PATH% %SINGLE_HEADER_PATH%~ > nul +fc %NODE_HPP_PATH% %NODE_HPP_PATH%~ > nul if %errorlevel% == 0 ( - echo Amalgamation check passed! + echo Amalgamation check passed for node.hpp file! ) else ( - echo Amalgamation required! + echo Amalgamation required for node.hpp file! echo Please follow the guideline in the CONTRIBUTING.md file. ) +move %NODE_HPP_PATH%~ %NODE_HPP_PATH% > nul -move %SINGLE_HEADER_PATH%~ %SINGLE_HEADER_PATH% > nul +fc %FKYAML_FWD_HPP_PATH% %FKYAML_FWD_HPP_PATH%~ > nul +if %errorlevel% == 0 ( + echo Amalgamation check passed for fkyaml_fwd.hpp file! +) else ( + echo Amalgamation required for fkyaml_fwd.hpp file! + echo Please follow the guideline in the CONTRIBUTING.md file. +) +move %FKYAML_FWD_HPP_PATH%~ %FKYAML_FWD_HPP_PATH% > nul cd %CALLER_DIR% diff --git a/scripts/check_amalgamation.sh b/scripts/check_amalgamation.sh index d82ad311..84636c53 100755 --- a/scripts/check_amalgamation.sh +++ b/scripts/check_amalgamation.sh @@ -4,15 +4,27 @@ set -eu ROOT_DIR="$(dirname "$0")/.." -SINGLE_HEADER_PATH="$ROOT_DIR/single_include/fkYAML/node.hpp" -mv "$SINGLE_HEADER_PATH" "$SINGLE_HEADER_PATH~" +NODE_HPP_PATH="$ROOT_DIR/single_include/fkYAML/node.hpp" +FKYAML_FWD_HPP_PATH="$ROOT_DIR/single_include/fkYAML/fkyaml_fwd.hpp" + +mv "$NODE_HPP_PATH" "$NODE_HPP_PATH~" +mv "$FKYAML_FWD_HPP_PATH" "$FKYAML_FWD_HPP_PATH~" + "$ROOT_DIR"/scripts/run_amalgamation.sh >/dev/null -if cmp -s "$SINGLE_HEADER_PATH" "$SINGLE_HEADER_PATH~" ; then - echo Amalgamation check passed! +if cmp -s "$NODE_HPP_PATH" "$NODE_HPP_PATH~" ; then + echo Amalgamation check passed for node.hpp file! +else + echo Amalgamation required for node.hpp file. + echo Please follow the guideline in the CONTRIBUTING.md file. +fi +mv "$NODE_HPP_PATH~" "$NODE_HPP_PATH" + +if cmp -s "$FKYAML_FWD_HPP_PATH" "$FKYAML_FWD_HPP_PATH~" ; then + echo Amalgamation check passed for fkyaml_fwd.hpp file! else - echo Amalgamation required. + echo Amalgamation required for fkyaml_fwd.hpp file. echo Please follow the guideline in the CONTRIBUTING.md file. fi +mv "$FKYAML_FWD_HPP_PATH~" "$FKYAML_FWD_HPP_PATH" -mv "$SINGLE_HEADER_PATH~" "$SINGLE_HEADER_PATH" diff --git a/scripts/run_amalgamation.bat b/scripts/run_amalgamation.bat index 52ed9652..26752a15 100644 --- a/scripts/run_amalgamation.bat +++ b/scripts/run_amalgamation.bat @@ -7,7 +7,8 @@ set SCRIPT_PATH=%~dp0 set AMALGAMATION_TOOL_DIR=%SCRIPT_PATH%\..\tool\amalgamation cd %SCRIPT_PATH%\.. -python %AMALGAMATION_TOOL_DIR%\amalgamate.py -c %AMALGAMATION_TOOL_DIR%\fkYAML.json -s . --verbose=yes +python %AMALGAMATION_TOOL_DIR%\amalgamate.py -c %AMALGAMATION_TOOL_DIR%\node_hpp.json -s . --verbose=yes +python %AMALGAMATION_TOOL_DIR%\amalgamate.py -c %AMALGAMATION_TOOL_DIR%\fkyaml_fwd_hpp.json -s . --verbose=yes if %errorlevel% == 0 ( echo Amalgamation succeeded! diff --git a/scripts/run_amalgamation.sh b/scripts/run_amalgamation.sh index 1ca9be6c..85a9395b 100755 --- a/scripts/run_amalgamation.sh +++ b/scripts/run_amalgamation.sh @@ -14,4 +14,5 @@ fi ROOT_DIR="$(dirname "$0")"/.. AMALGAMATION_TOOL_DIR="$ROOT_DIR/tool/amalgamation" -"$PYTHON_EXE" "$AMALGAMATION_TOOL_DIR"/amalgamate.py -c "$AMALGAMATION_TOOL_DIR"/fkYAML.json -s . --verbose=yes +"$PYTHON_EXE" "$AMALGAMATION_TOOL_DIR"/amalgamate.py -c "$AMALGAMATION_TOOL_DIR"/node_hpp.json -s . --verbose=yes +"$PYTHON_EXE" "$AMALGAMATION_TOOL_DIR"/amalgamate.py -c "$AMALGAMATION_TOOL_DIR"/fkyaml_fwd_hpp.json -s . --verbose=yes diff --git a/single_include/fkYAML/fkyaml_fwd.hpp b/single_include/fkYAML/fkyaml_fwd.hpp new file mode 100644 index 00000000..165c4ffb --- /dev/null +++ b/single_include/fkYAML/fkyaml_fwd.hpp @@ -0,0 +1,100 @@ +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#ifndef FK_YAML_FKYAML_FWD_HPP +#define FK_YAML_FKYAML_FWD_HPP + +#include +#include +#include +#include + +// #include +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +// 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 != 13 +#warning Already included a different version of the fkYAML library! +#else +// define macros to skip defining macros down below. +#define FK_YAML_VERCHECK_SUCCEEDED +#endif +#endif + +#ifndef FK_YAML_VERCHECK_SUCCEEDED + +#define FK_YAML_MAJOR_VERSION 0 +#define FK_YAML_MINOR_VERSION 3 +#define FK_YAML_PATCH_VERSION 13 + +#define FK_YAML_NAMESPACE_VERSION_CONCAT_IMPL(major, minor, patch) v##major##_##minor##_##patch + +#define FK_YAML_NAMESPACE_VERSION_CONCAT(major, minor, patch) FK_YAML_NAMESPACE_VERSION_CONCAT_IMPL(major, minor, patch) + +#define FK_YAML_NAMESPACE_VERSION \ + FK_YAML_NAMESPACE_VERSION_CONCAT(FK_YAML_MAJOR_VERSION, FK_YAML_MINOR_VERSION, FK_YAML_PATCH_VERSION) + +#define FK_YAML_NAMESPACE_BEGIN \ + namespace fkyaml { \ + inline namespace FK_YAML_NAMESPACE_VERSION { + +#define FK_YAML_NAMESPACE_END \ + } /* inline namespace FK_YAML_NAMESPACE_VERSION */ \ + } // namespace fkyaml + +#define FK_YAML_DETAIL_NAMESPACE_BEGIN \ + FK_YAML_NAMESPACE_BEGIN \ + namespace detail { + +#define FK_YAML_DETAIL_NAMESPACE_END \ + } /* namespace detail */ \ + FK_YAML_NAMESPACE_END + +#endif // !defined(FK_YAML_VERCHECK_SUCCEEDED) + + +FK_YAML_NAMESPACE_BEGIN + +/// @brief An ADL friendly converter between basic_node objects and native data objects. +/// @tparam ValueType A target data type. +/// @sa https://fktn-k.github.io/fkYAML/api/node_value_converter/ +template +class node_value_converter; + +/// @brief A class to store value of YAML nodes. +/// @sa https://fktn-k.github.io/fkYAML/api/basic_node/ +template < + template class SequenceType = std::vector, + template class MappingType = std::map, typename BooleanType = bool, + typename IntegerType = std::int64_t, typename FloatNumberType = double, typename StringType = std::string, + template class ConverterType = node_value_converter> +class basic_node; + +/// @brief default YAML node value container. +/// @sa https://fktn-k.github.io/fkYAML/api/basic_node/node/ +using node = basic_node<>; + +/// @brief A minimal map-like container which preserves insertion order. +/// @tparam Key A type for keys. +/// @tparam Value A type for values. +/// @tparam IgnoredCompare A placeholder for key comparison. This will be ignored. +/// @tparam Allocator A class for allocators. +/// @sa https://fktn-k.github.io/fkYAML/api/ordered_map/ +template +class ordered_map; + +FK_YAML_NAMESPACE_END + +#endif /* FK_YAML_FKYAML_FWD_HPP */ diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index b0a6bbfa..fd422e7a 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -19,6 +19,18 @@ #include #include +// #include +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#ifndef FK_YAML_DETAIL_MACROS_DEFINE_MACROS_HPP +#define FK_YAML_DETAIL_MACROS_DEFINE_MACROS_HPP + // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library @@ -67,6 +79,8 @@ } /* namespace detail */ \ FK_YAML_NAMESPACE_END +#endif // !defined(FK_YAML_VERCHECK_SUCCEEDED) + // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library @@ -219,7 +233,7 @@ #endif /* FK_YAML_DETAIL_MACROS_CPP_CONFIG_MACROS_HPP */ -#endif // !defined(FK_YAML_VERCHECK_SUCCEEDED) +#endif /* FK_YAML_DETAIL_MACROS_DEFINE_MACROS_HPP */ // #include // _______ __ __ __ _____ __ __ __ @@ -260,7 +274,7 @@ #include #include -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -274,7 +288,7 @@ #ifndef FK_YAML_DETAIL_META_NODE_TRAITS_HPP #define FK_YAML_DETAIL_META_NODE_TRAITS_HPP -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -291,7 +305,7 @@ #include #include -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -308,7 +322,7 @@ #include #include -// #include +// #include #ifdef FK_YAML_HAS_CXX_14 @@ -743,7 +757,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -897,18 +911,61 @@ FK_YAML_DETAIL_NAMESPACE_END #endif /* FK_YAML_DETAIL_META_TYPE_TRAITS_HPP */ +// #include +// _______ __ __ __ _____ __ __ __ +// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML +// +// SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani +// SPDX-License-Identifier: MIT + +#ifndef FK_YAML_FKYAML_FWD_HPP +#define FK_YAML_FKYAML_FWD_HPP + +#include +#include +#include +#include + +// #include + FK_YAML_NAMESPACE_BEGIN -// forward declaration for basic_node<...> +/// @brief An ADL friendly converter between basic_node objects and native data objects. +/// @tparam ValueType A target data type. +/// @sa https://fktn-k.github.io/fkYAML/api/node_value_converter/ +template +class node_value_converter; + +/// @brief A class to store value of YAML nodes. +/// @sa https://fktn-k.github.io/fkYAML/api/basic_node/ template < - template class SequenceType, template class MappingType, - typename BooleanType, typename IntegerType, typename FloatNumberType, typename StringType, - template class ConverterType> + template class SequenceType = std::vector, + template class MappingType = std::map, typename BooleanType = bool, + typename IntegerType = std::int64_t, typename FloatNumberType = double, typename StringType = std::string, + template class ConverterType = node_value_converter> class basic_node; +/// @brief default YAML node value container. +/// @sa https://fktn-k.github.io/fkYAML/api/basic_node/node/ +using node = basic_node<>; + +/// @brief A minimal map-like container which preserves insertion order. +/// @tparam Key A type for keys. +/// @tparam Value A type for values. +/// @tparam IgnoredCompare A placeholder for key comparison. This will be ignored. +/// @tparam Allocator A class for allocators. +/// @sa https://fktn-k.github.io/fkYAML/api/ordered_map/ +template +class ordered_map; + FK_YAML_NAMESPACE_END +#endif /* FK_YAML_FKYAML_FWD_HPP */ + + FK_YAML_DETAIL_NAMESPACE_BEGIN ///////////////////////////// @@ -1058,7 +1115,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include FK_YAML_NAMESPACE_BEGIN @@ -1123,7 +1180,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -1143,7 +1200,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -1162,7 +1219,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include FK_YAML_DETAIL_NAMESPACE_BEGIN @@ -1290,7 +1347,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -1309,7 +1366,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -1328,7 +1385,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include FK_YAML_DETAIL_NAMESPACE_BEGIN @@ -1375,7 +1432,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -1391,7 +1448,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include FK_YAML_NAMESPACE_BEGIN @@ -1961,7 +2018,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include FK_YAML_DETAIL_NAMESPACE_BEGIN @@ -1999,7 +2056,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -2016,7 +2073,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -3083,7 +3140,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include FK_YAML_DETAIL_NAMESPACE_BEGIN @@ -4199,7 +4256,7 @@ FK_YAML_DETAIL_NAMESPACE_END #ifndef FK_YAML_DETAIL_INPUT_SCALAR_PARSER_HPP #define FK_YAML_DETAIL_INPUT_SCALAR_PARSER_HPP -// #include +// #include // #include @@ -4225,7 +4282,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -5057,7 +5114,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include // #include @@ -5411,7 +5468,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -5746,7 +5803,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include FK_YAML_DETAIL_NAMESPACE_BEGIN @@ -6313,7 +6370,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -6500,7 +6557,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -6611,7 +6668,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -6751,7 +6808,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include FK_YAML_DETAIL_NAMESPACE_BEGIN @@ -8051,7 +8108,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -8070,7 +8127,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -8086,7 +8143,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include FK_YAML_DETAIL_NAMESPACE_BEGIN @@ -9484,7 +9541,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -9891,7 +9948,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -9985,7 +10042,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -10005,7 +10062,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -10444,7 +10501,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include // #include @@ -10499,7 +10556,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include -// #include +// #include // #include // _______ __ __ __ _____ __ __ __ @@ -10519,7 +10576,7 @@ FK_YAML_DETAIL_NAMESPACE_END #include #include -// #include +// #include // #include @@ -11096,7 +11153,7 @@ FK_YAML_NAMESPACE_END #include -// #include +// #include // #include @@ -11487,7 +11544,7 @@ FK_YAML_NAMESPACE_END #include #include -// #include +// #include // #include @@ -11654,10 +11711,9 @@ FK_YAML_NAMESPACE_BEGIN /// @brief A class to store value of YAML nodes. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/ template < - template class SequenceType = std::vector, - template class MappingType = std::map, typename BooleanType = bool, - typename IntegerType = std::int64_t, typename FloatNumberType = double, typename StringType = std::string, - template class ConverterType = node_value_converter> + template class SequenceType, template class MappingType, + typename BooleanType, typename IntegerType, typename FloatNumberType, typename StringType, + template class ConverterType> class basic_node { public: /// @brief A type for iterators of basic_node containers. @@ -13287,10 +13343,6 @@ inline std::istream& operator>>( return is; } -/// @brief default YAML node value container. -/// @sa https://fktn-k.github.io/fkYAML/api/basic_node/node/ -using node = basic_node<>; - /// @brief namespace for user-defined literals for the fkYAML library. inline namespace literals { /// @brief namespace for user-defined literals for YAML node objects. diff --git a/tool/amalgamation/fkyaml_fwd_hpp.json b/tool/amalgamation/fkyaml_fwd_hpp.json new file mode 100644 index 00000000..9954a915 --- /dev/null +++ b/tool/amalgamation/fkyaml_fwd_hpp.json @@ -0,0 +1,10 @@ +{ + "project": "fkYAML", + "target": "single_include/fkYAML/fkyaml_fwd.hpp", + "sources": [ + "include/fkYAML/fkyaml_fwd.hpp" + ], + "include_paths": [ + "include" + ] +} diff --git a/tool/amalgamation/fkYAML.json b/tool/amalgamation/node_hpp.json similarity index 100% rename from tool/amalgamation/fkYAML.json rename to tool/amalgamation/node_hpp.json From f121341fb92c643919ca9d51bb28a006cf375872 Mon Sep 17 00:00:00 2001 From: fktn Date: Wed, 13 Nov 2024 21:46:55 +0900 Subject: [PATCH 09/13] Fix duplicate include error if clang-tidy helper file already exists (#423) --- tool/clang_tidy/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tool/clang_tidy/CMakeLists.txt b/tool/clang_tidy/CMakeLists.txt index 50575239..5f671112 100644 --- a/tool/clang_tidy/CMakeLists.txt +++ b/tool/clang_tidy/CMakeLists.txt @@ -17,6 +17,9 @@ message(STATUS "Found clang-tidy. version: ${CLANG_TIDY_VERSION} path: ${CLANG_T #################################### set(HELPER_FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/clang_tidy_helper.cpp") +# clear the contents written previously to the file. +file(WRITE ${HELPER_FILE_PATH} "") + file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/fkYAML/*.hpp) foreach(SRC_FILE ${SRC_FILES}) file(RELATIVE_PATH REL_SRC_FILE "${PROJECT_SOURCE_DIR}/include" ${SRC_FILE}) From cf79a865871fc843b7bbbce17df6c1e6247fee8e Mon Sep 17 00:00:00 2001 From: fktn Date: Sat, 16 Nov 2024 13:44:44 +0900 Subject: [PATCH 10/13] Clarify type restrictions of get_value() & get_value_ref() APIs (#424) * emit static_assertion errors on get_value() calls with reference, pointer and C-style array types * clarify type restrictions of get_value() and get_value_ref() APIs * run amalgamation --- docs/mkdocs/docs/api/basic_node/get_value.md | 3 ++- docs/mkdocs/docs/api/basic_node/get_value_ref.md | 3 +-- include/fkYAML/node.hpp | 13 ++++++++++--- single_include/fkYAML/node.hpp | 13 ++++++++++--- test/unit_test/test_node_class.cpp | 9 +++++++++ 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/docs/mkdocs/docs/api/basic_node/get_value.md b/docs/mkdocs/docs/api/basic_node/get_value.md index c210a52e..c9d88f0d 100644 --- a/docs/mkdocs/docs/api/basic_node/get_value.md +++ b/docs/mkdocs/docs/api/basic_node/get_value.md @@ -20,7 +20,8 @@ This function converts a [fkyaml::basic_node](./index.md) to either ConverterType::from_node(*this, ret); return ret; ``` - This library implements conversions from a node to a number of STL container types and scalar types. (see the notes down below) + This library implements conversions from a node to a number of STL container types and scalar types. (see the notes down below) + Note that ValueType cannot be either a reference, pointer or C-style array type except `std::nullptr_t`. 2. a [fkyaml::basic_node](./index.md) object The function is equivalent to executing ```cpp diff --git a/docs/mkdocs/docs/api/basic_node/get_value_ref.md b/docs/mkdocs/docs/api/basic_node/get_value_ref.md index 67701fb4..9a8142e1 100644 --- a/docs/mkdocs/docs/api/basic_node/get_value_ref.md +++ b/docs/mkdocs/docs/api/basic_node/get_value_ref.md @@ -23,8 +23,7 @@ This API makes no copies. ***ReferenceType*** : reference type to the target YAML node value. - This must be a reference to [`sequence_type`](sequence_type.md), [`mapping_type`](mapping_type.md), [`boolean_type`](boolean_type.md), [`integer_type`](integer_type.md), [`float_number_type`](float_number_type.md) or [`string_type`](string_type.md). - The above restriction is enforced by a static assertion. + This must be a (const) reference type to [`sequence_type`](sequence_type.md), [`mapping_type`](mapping_type.md), [`boolean_type`](boolean_type.md), [`integer_type`](integer_type.md), [`float_number_type`](float_number_type.md) or [`string_type`](string_type.md). ## **Return Value** diff --git a/include/fkYAML/node.hpp b/include/fkYAML/node.hpp index bbdeca3a..10b9d5ee 100644 --- a/include/fkYAML/node.hpp +++ b/include/fkYAML/node.hpp @@ -1305,15 +1305,22 @@ class basic_node { /// @brief Get the node value object converted into a given type. /// @note This function requires T objects to be default constructible. - /// @tparam T A compatible value type which might be cv-qualified or a reference type. - /// @tparam ValueType A compatible value type, without cv-qualifiers and reference by default. + /// @tparam T A compatible value type which might be cv-qualified. + /// @tparam ValueType A compatible value type with cv-qualifiers removed by default. /// @return A compatible native data value converted from the basic_node object. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/get_value/ template < - typename T, typename ValueType = detail::remove_cvref_t, + typename T, typename ValueType = detail::remove_cv_t, detail::enable_if_t::value, int> = 0> T get_value() const noexcept( noexcept(std::declval().template get_value_impl(std::declval()))) { + // emit a compile error if T is either a reference, pointer or C-style array type. + static_assert( + !std::is_reference::value, + "get_value() cannot be called with reference types. you might want to call get_value_ref()."); + static_assert(!std::is_pointer::value, "get_value() cannot be called with pointer types."); + static_assert(!std::is_array::value, "get_value() cannot be called with C-style array types."); + auto ret = ValueType(); if (has_anchor_name()) { auto itr = mp_meta->anchor_table.equal_range(m_prop.anchor).first; diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index fd422e7a..195fb28a 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -12972,15 +12972,22 @@ class basic_node { /// @brief Get the node value object converted into a given type. /// @note This function requires T objects to be default constructible. - /// @tparam T A compatible value type which might be cv-qualified or a reference type. - /// @tparam ValueType A compatible value type, without cv-qualifiers and reference by default. + /// @tparam T A compatible value type which might be cv-qualified. + /// @tparam ValueType A compatible value type with cv-qualifiers removed by default. /// @return A compatible native data value converted from the basic_node object. /// @sa https://fktn-k.github.io/fkYAML/api/basic_node/get_value/ template < - typename T, typename ValueType = detail::remove_cvref_t, + typename T, typename ValueType = detail::remove_cv_t, detail::enable_if_t::value, int> = 0> T get_value() const noexcept( noexcept(std::declval().template get_value_impl(std::declval()))) { + // emit a compile error if T is either a reference, pointer or C-style array type. + static_assert( + !std::is_reference::value, + "get_value() cannot be called with reference types. you might want to call get_value_ref()."); + static_assert(!std::is_pointer::value, "get_value() cannot be called with pointer types."); + static_assert(!std::is_array::value, "get_value() cannot be called with C-style array types."); + auto ret = ValueType(); if (has_anchor_name()) { auto itr = mp_meta->anchor_table.equal_range(m_prop.anchor).first; diff --git a/test/unit_test/test_node_class.cpp b/test/unit_test/test_node_class.cpp index 7874c47f..27799b37 100644 --- a/test/unit_test/test_node_class.cpp +++ b/test/unit_test/test_node_class.cpp @@ -2373,6 +2373,9 @@ struct string_wrap { std::string str; }; +template +using get_fn_t = decltype(std::declval().template get()); + TEST_CASE("Node_GetValue") { SECTION("sequence") { @@ -2966,6 +2969,12 @@ TEST_CASE("Node_GetValue") { REQUIRE_FALSE(opt_bool.has_value()); } #endif + + SECTION("unsupported types") { + STATIC_REQUIRE_FALSE(fkyaml::detail::is_detected::value); + STATIC_REQUIRE_FALSE(fkyaml::detail::is_detected::value); + STATIC_REQUIRE_FALSE(fkyaml::detail::is_detected::value); + } } // From 248dcba5354d0b9ddf58e3ba033898b07f0cff1e Mon Sep 17 00:00:00 2001 From: fktn Date: Sat, 16 Nov 2024 17:51:35 +0900 Subject: [PATCH 11/13] Use std::unreachable or similar compiler specific extensions for dead but necessary code (#425) * use std::unreachable() or the likes for dead but necessary codes like default case --- docs/mkdocs/docs/api/macros.md | 5 +- .../fkYAML/detail/encodings/utf_encodings.hpp | 4 +- include/fkYAML/detail/input/deserializer.hpp | 2 +- include/fkYAML/detail/input/input_adapter.hpp | 12 +- .../fkYAML/detail/input/lexical_analyzer.hpp | 4 +- include/fkYAML/detail/input/scalar_parser.hpp | 4 +- .../detail/macros/cpp_config_macros.hpp | 15 ++- include/fkYAML/detail/meta/stl_supplement.hpp | 14 +++ include/fkYAML/detail/node_attrs.hpp | 4 +- include/fkYAML/detail/types/node_t.hpp | 12 +- include/fkYAML/node.hpp | 26 ++--- include/fkYAML/node_type.hpp | 5 +- include/fkYAML/yaml_version_type.hpp | 5 +- single_include/fkYAML/node.hpp | 109 +++++++++++------- 14 files changed, 133 insertions(+), 88 deletions(-) diff --git a/docs/mkdocs/docs/api/macros.md b/docs/mkdocs/docs/api/macros.md index 90baf253..263bc8a6 100644 --- a/docs/mkdocs/docs/api/macros.md +++ b/docs/mkdocs/docs/api/macros.md @@ -66,8 +66,8 @@ You can also override the implementation by defining the following preprocessor ## Language Supports The fkYAML library targets C++11, but also supports some features introduced in later C++ standards. -For those new features, the library implements some preprocessor checks to determine the C++ standard based on preprocessor macros such as `__cplusplus`, `_HAS_CXX14` or `_MSVC_LANG`. -By defining any of the following symbols, the internal check is overridden and the provided C++ standard is unconditionally assumed. +For those new features, the library implements some preprocessor checks to determine the active C++ standard based on preprocessor macros `__cplusplus` and `_MSVC_LANG`. +By defining any of the following macros, the internal check is overridden and the provided C++ standard is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and the standard would be detected incorrectly. | Name | Description | @@ -76,6 +76,7 @@ This can be helpful for compilers that only implement parts of the standard and | FK_YAML_HAS_CXX_14 | supports C++14 features. | | FK_YAML_HAS_CXX_17 | supports C++17 features. | | FK_YAML_HAS_CXX_20 | supports C++20 features. | +| FK_YAML_HAS_CXX_23 | supports C++23 features. | ??? Example annotate "Example: force the fkYAML library to use a specific C++ standard" diff --git a/include/fkYAML/detail/encodings/utf_encodings.hpp b/include/fkYAML/detail/encodings/utf_encodings.hpp index 0a6efb59..d8d974a7 100644 --- a/include/fkYAML/detail/encodings/utf_encodings.hpp +++ b/include/fkYAML/detail/encodings/utf_encodings.hpp @@ -180,8 +180,8 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // The rest of byte combinations are invalid. return false; } - default: // LCOV_EXCL_LINE - return false; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } diff --git a/include/fkYAML/detail/input/deserializer.hpp b/include/fkYAML/detail/input/deserializer.hpp index a3311125..7907d50a 100644 --- a/include/fkYAML/detail/input/deserializer.hpp +++ b/include/fkYAML/detail/input/deserializer.hpp @@ -978,7 +978,7 @@ class basic_deserializer { case lexical_token_t::YAML_VER_DIRECTIVE: // LCOV_EXCL_LINE case lexical_token_t::TAG_DIRECTIVE: // LCOV_EXCL_LINE case lexical_token_t::INVALID_DIRECTIVE: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } token = lexer.get_next_token(); diff --git a/include/fkYAML/detail/input/input_adapter.hpp b/include/fkYAML/detail/input/input_adapter.hpp index 0907d715..2808ed4e 100644 --- a/include/fkYAML/detail/input/input_adapter.hpp +++ b/include/fkYAML/detail/input/input_adapter.hpp @@ -76,8 +76,8 @@ class iterator_input_adapter= 202002L +#if !defined(FK_YAML_HAS_CXX_23) && !defined(FK_YAML_HAS_CXX_20) && !defined(FK_YAML_HAS_CXX_17) && \ + !defined(FK_YAML_HAS_CXX_14) && !defined(FK_YAML_CXX_11) +#if FK_YAML_CPLUSPLUS >= 202302L +#define FK_YAML_HAS_CXX_23 +#define FK_YAML_HAS_CXX_20 +#define FK_YAML_HAS_CXX_17 +#define FK_YAML_HAS_CXX_14 +#elif FK_YAML_CPLUSPLUS >= 202002L #define FK_YAML_HAS_CXX_20 #define FK_YAML_HAS_CXX_17 #define FK_YAML_HAS_CXX_14 @@ -125,7 +130,7 @@ #endif // -// C++ attribute detections +// utility macros // // switch usage of [[likely]] C++ attribute which has been available since C++20. diff --git a/include/fkYAML/detail/meta/stl_supplement.hpp b/include/fkYAML/detail/meta/stl_supplement.hpp index 9d2e0028..13abb119 100644 --- a/include/fkYAML/detail/meta/stl_supplement.hpp +++ b/include/fkYAML/detail/meta/stl_supplement.hpp @@ -246,6 +246,20 @@ using std::remove_cvref_t; #endif +/// @brief A wrapper function to call std::unreachable() (since C++23) or similar compiler specific extensions. +[[noreturn]] inline void unreachable() { + // use compiler specific extensions if possible. + // undefined behavior should be raised by an empty function with noreturn attribute. + +#if defined(FK_YAML_HAS_CXX_23) || (defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L) + std::unreachable(); +#elif defined(_MSC_VER) && !defined(__clang__) // MSVC + __assume(false); +#else + __builtin_unreachable(); +#endif +} + FK_YAML_DETAIL_NAMESPACE_END #endif /* FK_YAML_DETAIL_META_STL_SUPPLEMENT_HPP */ diff --git a/include/fkYAML/detail/node_attrs.hpp b/include/fkYAML/detail/node_attrs.hpp index 6c1f4c9c..1e94954e 100644 --- a/include/fkYAML/detail/node_attrs.hpp +++ b/include/fkYAML/detail/node_attrs.hpp @@ -110,8 +110,8 @@ inline node_type to_node_type(node_attr_t bits) noexcept { return node_type::FLOAT; case string_bit: return node_type::STRING; - default: // LCOV_EXCL_LINE - return node_type::NULL_OBJECT; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } diff --git a/include/fkYAML/detail/types/node_t.hpp b/include/fkYAML/detail/types/node_t.hpp index be60b4a0..ebc94c61 100644 --- a/include/fkYAML/detail/types/node_t.hpp +++ b/include/fkYAML/detail/types/node_t.hpp @@ -43,8 +43,8 @@ inline const char* to_string(node_t t) noexcept { return "float"; case node_t::STRING: return "string"; - default: // LCOV_EXCL_LINE - return ""; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -64,8 +64,8 @@ inline node_t convert_from_node_type(node_type t) { return node_t::FLOAT_NUMBER; case node_type::STRING: return node_t::STRING; - default: // LCOV_EXCL_LINE - return node_t::NULL_OBJECT; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -85,8 +85,8 @@ inline node_type convert_to_node_type(node_t t) { return node_type::FLOAT; case node_t::STRING: return node_type::STRING; - default: // LCOV_EXCL_LINE - return node_type::NULL_OBJECT; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } diff --git a/include/fkYAML/node.hpp b/include/fkYAML/node.hpp index 10b9d5ee..86ca8215 100644 --- a/include/fkYAML/node.hpp +++ b/include/fkYAML/node.hpp @@ -148,8 +148,8 @@ class basic_node { case detail::node_attr_bits::string_bit: p_string = create_object(); break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -275,8 +275,8 @@ class basic_node { case detail::node_attr_bits::string_bit: m_node_value.p_string = create_object(*(rhs.m_node_value.p_string)); break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } } @@ -321,8 +321,8 @@ class basic_node { m_node_value.p_string = rhs.m_node_value.p_string; rhs.m_node_value.p_string = nullptr; break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -727,8 +727,8 @@ class basic_node { case detail::node_attr_bits::string_bit: ret = (*(this_node_value_ptr->p_string) == *(other_node_value_ptr->p_string)); break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } return ret; @@ -775,7 +775,7 @@ class basic_node { break; case detail::node_attr_bits::null_bit: // LCOV_EXCL_LINE // Will not come here since null nodes are always the same. - break; // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE case detail::node_attr_bits::bool_bit: // false < true ret = (!p_this_value->boolean && p_other_value->boolean); @@ -789,8 +789,8 @@ class basic_node { case detail::node_attr_bits::string_bit: ret = (*(p_this_value->p_string) < *(p_other_value->p_string)); break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } return ret; @@ -1796,8 +1796,8 @@ struct hash()(n.template get_value())); return seed; - default: // LCOV_EXCL_LINE - return 0; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + fkyaml::detail::unreachable(); // LCOV_EXCL_LINE } } diff --git a/include/fkYAML/node_type.hpp b/include/fkYAML/node_type.hpp index 247fe322..78b7481e 100644 --- a/include/fkYAML/node_type.hpp +++ b/include/fkYAML/node_type.hpp @@ -12,6 +12,7 @@ #include #include +#include FK_YAML_NAMESPACE_BEGIN @@ -41,8 +42,8 @@ inline const char* to_string(node_type t) noexcept { return "FLOAT"; case node_type::STRING: return "STRING"; - default: // LCOV_EXCL_LINE - return ""; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } diff --git a/include/fkYAML/yaml_version_type.hpp b/include/fkYAML/yaml_version_type.hpp index ecb608a3..c715c0e7 100644 --- a/include/fkYAML/yaml_version_type.hpp +++ b/include/fkYAML/yaml_version_type.hpp @@ -12,6 +12,7 @@ #include #include +#include FK_YAML_NAMESPACE_BEGIN @@ -26,8 +27,8 @@ inline const char* to_string(yaml_version_type t) noexcept { return "VERSION_1_1"; case yaml_version_type::VERSION_1_2: return "VERSION_1_2"; - default: // LCOV_EXCL_LINE - return ""; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index 195fb28a..e265f38c 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -105,11 +105,16 @@ #define FK_YAML_CPLUSPLUS __cplusplus #endif -// C++ language standard detection (__cplusplus is not yet defined for C++23) +// C++ language standard detection // Skip detection if the definitions listed below already exist. -#if !defined(FK_YAML_HAS_CXX_20) && !defined(FK_YAML_HAS_CXX_17) && !defined(FK_YAML_HAS_CXX_14) && \ - !defined(FK_YAML_CXX_11) -#if FK_YAML_CPLUSPLUS >= 202002L +#if !defined(FK_YAML_HAS_CXX_23) && !defined(FK_YAML_HAS_CXX_20) && !defined(FK_YAML_HAS_CXX_17) && \ + !defined(FK_YAML_HAS_CXX_14) && !defined(FK_YAML_CXX_11) +#if FK_YAML_CPLUSPLUS >= 202302L +#define FK_YAML_HAS_CXX_23 +#define FK_YAML_HAS_CXX_20 +#define FK_YAML_HAS_CXX_17 +#define FK_YAML_HAS_CXX_14 +#elif FK_YAML_CPLUSPLUS >= 202002L #define FK_YAML_HAS_CXX_20 #define FK_YAML_HAS_CXX_17 #define FK_YAML_HAS_CXX_14 @@ -209,7 +214,7 @@ #endif // -// C++ attribute detections +// utility macros // // switch usage of [[likely]] C++ attribute which has been available since C++20. @@ -557,6 +562,20 @@ using std::remove_cvref_t; #endif +/// @brief A wrapper function to call std::unreachable() (since C++23) or similar compiler specific extensions. +[[noreturn]] inline void unreachable() { + // use compiler specific extensions if possible. + // undefined behavior should be raised by an empty function with noreturn attribute. + +#if defined(FK_YAML_HAS_CXX_23) || (defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L) + std::unreachable(); +#elif defined(_MSC_VER) && !defined(__clang__) // MSVC + __assume(false); +#else + __builtin_unreachable(); +#endif +} + FK_YAML_DETAIL_NAMESPACE_END #endif /* FK_YAML_DETAIL_META_STL_SUPPLEMENT_HPP */ @@ -1117,6 +1136,8 @@ FK_YAML_DETAIL_NAMESPACE_END // #include +// #include + FK_YAML_NAMESPACE_BEGIN @@ -1131,8 +1152,8 @@ inline const char* to_string(yaml_version_type t) noexcept { return "VERSION_1_1"; case yaml_version_type::VERSION_1_2: return "VERSION_1_2"; - default: // LCOV_EXCL_LINE - return ""; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -1450,6 +1471,8 @@ FK_YAML_DETAIL_NAMESPACE_END // #include +// #include + FK_YAML_NAMESPACE_BEGIN @@ -1479,8 +1502,8 @@ inline const char* to_string(node_type t) noexcept { return "FLOAT"; case node_type::STRING: return "STRING"; - default: // LCOV_EXCL_LINE - return ""; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -1518,8 +1541,8 @@ inline const char* to_string(node_t t) noexcept { return "float"; case node_t::STRING: return "string"; - default: // LCOV_EXCL_LINE - return ""; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -1539,8 +1562,8 @@ inline node_t convert_from_node_type(node_type t) { return node_t::FLOAT_NUMBER; case node_type::STRING: return node_t::STRING; - default: // LCOV_EXCL_LINE - return node_t::NULL_OBJECT; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -1560,8 +1583,8 @@ inline node_type convert_to_node_type(node_t t) { return node_type::FLOAT; case node_t::STRING: return node_type::STRING; - default: // LCOV_EXCL_LINE - return node_type::NULL_OBJECT; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -1909,8 +1932,8 @@ inline bool validate(const std::initializer_list& byte_array) noexcept // The rest of byte combinations are invalid. return false; } - default: // LCOV_EXCL_LINE - return false; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -3934,8 +3957,8 @@ class lexical_analyzer { // This check is enabled only in a flow context. ends_loop = (m_state & flow_context_bit); break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } if (ends_loop) { @@ -6334,8 +6357,8 @@ class scalar_parser { node = basic_node_type(std::string(token.begin(), token.end())); } break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } return node; @@ -6768,8 +6791,8 @@ inline node_type to_node_type(node_attr_t bits) noexcept { return node_type::FLOAT; case string_bit: return node_type::STRING; - default: // LCOV_EXCL_LINE - return node_type::NULL_OBJECT; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -7781,7 +7804,7 @@ class basic_deserializer { case lexical_token_t::YAML_VER_DIRECTIVE: // LCOV_EXCL_LINE case lexical_token_t::TAG_DIRECTIVE: // LCOV_EXCL_LINE case lexical_token_t::INVALID_DIRECTIVE: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } token = lexer.get_next_token(); @@ -8552,8 +8575,8 @@ class iterator_input_adapter(); break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -11942,8 +11965,8 @@ class basic_node { case detail::node_attr_bits::string_bit: m_node_value.p_string = create_object(*(rhs.m_node_value.p_string)); break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } } @@ -11988,8 +12011,8 @@ class basic_node { m_node_value.p_string = rhs.m_node_value.p_string; rhs.m_node_value.p_string = nullptr; break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } } @@ -12394,8 +12417,8 @@ class basic_node { case detail::node_attr_bits::string_bit: ret = (*(this_node_value_ptr->p_string) == *(other_node_value_ptr->p_string)); break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } return ret; @@ -12442,7 +12465,7 @@ class basic_node { break; case detail::node_attr_bits::null_bit: // LCOV_EXCL_LINE // Will not come here since null nodes are always the same. - break; // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE case detail::node_attr_bits::bool_bit: // false < true ret = (!p_this_value->boolean && p_other_value->boolean); @@ -12456,8 +12479,8 @@ class basic_node { case detail::node_attr_bits::string_bit: ret = (*(p_this_value->p_string) < *(p_other_value->p_string)); break; - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + detail::unreachable(); // LCOV_EXCL_LINE } return ret; @@ -13463,8 +13486,8 @@ struct hash()(n.template get_value())); return seed; - default: // LCOV_EXCL_LINE - return 0; // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + fkyaml::detail::unreachable(); // LCOV_EXCL_LINE } } From bd052ac5def74a4cdfd70494a8282dcd0c1e897c Mon Sep 17 00:00:00 2001 From: fktn Date: Sat, 16 Nov 2024 18:36:00 +0900 Subject: [PATCH 12/13] Exclude detail::unreachable() from coverage target (#426) --- include/fkYAML/detail/meta/stl_supplement.hpp | 4 ++++ single_include/fkYAML/node.hpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/include/fkYAML/detail/meta/stl_supplement.hpp b/include/fkYAML/detail/meta/stl_supplement.hpp index 13abb119..6b5e28bb 100644 --- a/include/fkYAML/detail/meta/stl_supplement.hpp +++ b/include/fkYAML/detail/meta/stl_supplement.hpp @@ -247,6 +247,9 @@ using std::remove_cvref_t; #endif /// @brief A wrapper function to call std::unreachable() (since C++23) or similar compiler specific extensions. +/// @note This function is implemented only for better code optimization against dead code and thus excluded from +/// coverage report. +// LCOV_EXCL_START [[noreturn]] inline void unreachable() { // use compiler specific extensions if possible. // undefined behavior should be raised by an empty function with noreturn attribute. @@ -259,6 +262,7 @@ using std::remove_cvref_t; __builtin_unreachable(); #endif } +// LCOV_EXCL_STOP FK_YAML_DETAIL_NAMESPACE_END diff --git a/single_include/fkYAML/node.hpp b/single_include/fkYAML/node.hpp index e265f38c..5a75832c 100644 --- a/single_include/fkYAML/node.hpp +++ b/single_include/fkYAML/node.hpp @@ -563,6 +563,9 @@ using std::remove_cvref_t; #endif /// @brief A wrapper function to call std::unreachable() (since C++23) or similar compiler specific extensions. +/// @note This function is implemented only for better code optimization against dead code and thus excluded from +/// coverage report. +// LCOV_EXCL_START [[noreturn]] inline void unreachable() { // use compiler specific extensions if possible. // undefined behavior should be raised by an empty function with noreturn attribute. @@ -575,6 +578,7 @@ using std::remove_cvref_t; __builtin_unreachable(); #endif } +// LCOV_EXCL_STOP FK_YAML_DETAIL_NAMESPACE_END From e34b19f6b250391157e985bacc7a19525687c90f Mon Sep 17 00:00:00 2001 From: fktn Date: Sat, 16 Nov 2024 23:51:53 +0900 Subject: [PATCH 13/13] set version to 0.3.14 --- .reuse/templates/fkYAML.jinja2 | 2 +- .reuse/templates/fkYAML_support.jinja2 | 2 +- CHANGELOG.md | 18 ++++ CMakeLists.txt | 2 +- Makefile | 2 +- .../ex_basic_node_add_anchor_name.cpp | 2 +- docs/examples/ex_basic_node_add_tag_name.cpp | 2 +- docs/examples/ex_basic_node_alias_of.cpp | 2 +- docs/examples/ex_basic_node_at_basic_node.cpp | 2 +- .../ex_basic_node_at_compatible_type.cpp | 2 +- docs/examples/ex_basic_node_begin.cpp | 2 +- docs/examples/ex_basic_node_boolean_type.cpp | 2 +- .../examples/ex_basic_node_const_iterator.cpp | 2 +- docs/examples/ex_basic_node_constructor_1.cpp | 2 +- docs/examples/ex_basic_node_constructor_2.cpp | 2 +- docs/examples/ex_basic_node_constructor_3.cpp | 2 +- docs/examples/ex_basic_node_constructor_4.cpp | 2 +- docs/examples/ex_basic_node_constructor_5.cpp | 2 +- docs/examples/ex_basic_node_constructor_6.cpp | 2 +- docs/examples/ex_basic_node_constructor_7.cpp | 2 +- docs/examples/ex_basic_node_constructor_8.cpp | 2 +- docs/examples/ex_basic_node_contains.cpp | 2 +- ...ex_basic_node_copy_assignment_operator.cpp | 2 +- .../ex_basic_node_deserialize_char_array.cpp | 2 +- ...basic_node_deserialize_docs_char_array.cpp | 2 +- ...sic_node_deserialize_docs_file_pointer.cpp | 2 +- ..._basic_node_deserialize_docs_iterators.cpp | 2 +- .../ex_basic_node_deserialize_docs_string.cpp | 2 +- ...ex_basic_node_deserialize_file_pointer.cpp | 2 +- .../ex_basic_node_deserialize_iterators.cpp | 2 +- .../ex_basic_node_deserialize_string.cpp | 2 +- docs/examples/ex_basic_node_empty.cpp | 2 +- docs/examples/ex_basic_node_end.cpp | 2 +- .../ex_basic_node_extraction_operator.cpp | 2 +- .../ex_basic_node_float_number_type.cpp | 2 +- .../ex_basic_node_get_anchor_name.cpp | 2 +- docs/examples/ex_basic_node_get_tag_name.cpp | 2 +- docs/examples/ex_basic_node_get_type.cpp | 2 +- docs/examples/ex_basic_node_get_value.cpp | 2 +- docs/examples/ex_basic_node_get_value_ref.cpp | 2 +- .../ex_basic_node_get_yaml_version.cpp | 2 +- .../ex_basic_node_get_yaml_version_type.cpp | 2 +- .../ex_basic_node_has_anchor_name.cpp | 2 +- docs/examples/ex_basic_node_has_tag_name.cpp | 2 +- .../ex_basic_node_insertion_operator.cpp | 2 +- docs/examples/ex_basic_node_integer_type.cpp | 2 +- docs/examples/ex_basic_node_is_alias.cpp | 2 +- docs/examples/ex_basic_node_is_anchor.cpp | 2 +- docs/examples/ex_basic_node_is_boolean.cpp | 2 +- .../ex_basic_node_is_float_number.cpp | 2 +- docs/examples/ex_basic_node_is_integer.cpp | 2 +- docs/examples/ex_basic_node_is_mapping.cpp | 2 +- docs/examples/ex_basic_node_is_null.cpp | 2 +- docs/examples/ex_basic_node_is_scalar.cpp | 2 +- docs/examples/ex_basic_node_is_sequence.cpp | 2 +- docs/examples/ex_basic_node_is_string.cpp | 2 +- docs/examples/ex_basic_node_iterator.cpp | 2 +- docs/examples/ex_basic_node_mapping.cpp | 2 +- docs/examples/ex_basic_node_mapping_type.cpp | 2 +- docs/examples/ex_basic_node_node.cpp | 2 +- docs/examples/ex_basic_node_node_t.cpp | 2 +- docs/examples/ex_basic_node_operator_eq.cpp | 2 +- docs/examples/ex_basic_node_operator_ge.cpp | 2 +- docs/examples/ex_basic_node_operator_gt.cpp | 2 +- docs/examples/ex_basic_node_operator_le.cpp | 2 +- docs/examples/ex_basic_node_operator_lt.cpp | 2 +- docs/examples/ex_basic_node_operator_ne.cpp | 2 +- docs/examples/ex_basic_node_sequence.cpp | 2 +- docs/examples/ex_basic_node_sequence_type.cpp | 2 +- docs/examples/ex_basic_node_serialize.cpp | 2 +- .../examples/ex_basic_node_serialize_docs.cpp | 2 +- .../ex_basic_node_set_yaml_version.cpp | 2 +- .../ex_basic_node_set_yaml_version_type.cpp | 2 +- docs/examples/ex_basic_node_size.cpp | 2 +- docs/examples/ex_basic_node_string_type.cpp | 2 +- ...sic_node_subscript_operator_basic_node.cpp | 2 +- ...ode_subscript_operator_compatible_type.cpp | 2 +- docs/examples/ex_basic_node_swap_member.cpp | 2 +- docs/examples/ex_basic_node_swap_std.cpp | 2 +- docs/examples/ex_basic_node_type.cpp | 2 +- .../ex_basic_node_value_converter_type.cpp | 2 +- .../examples/ex_basic_node_yaml_version_t.cpp | 2 +- .../examples/ex_exception_constructor_msg.cpp | 2 +- .../ex_exception_constructor_noarg.cpp | 2 +- docs/examples/ex_exception_what.cpp | 2 +- docs/examples/ex_macros_versions.cpp | 2 +- docs/examples/ex_macros_versions.output | 2 +- docs/examples/ex_node_type.cpp | 2 +- .../ex_node_value_converter_from_node.cpp | 2 +- .../ex_node_value_converter_to_node.cpp | 2 +- docs/examples/ex_operator_literal_yaml.cpp | 2 +- docs/examples/ex_ordered_map_at.cpp | 2 +- ...dered_map_constructor_initializer_list.cpp | 2 +- .../ex_ordered_map_constructor_noarg.cpp | 2 +- docs/examples/ex_ordered_map_emplace.cpp | 2 +- docs/examples/ex_ordered_map_find.cpp | 2 +- .../ex_ordered_map_subscript_operator.cpp | 2 +- docs/examples/ex_yaml_version_type.cpp | 2 +- docs/examples/tutorial_1.cpp | 2 +- docs/examples/tutorial_2.cpp | 2 +- docs/examples/tutorial_3.cpp | 2 +- docs/examples/tutorial_4.cpp | 2 +- docs/mkdocs/docs/home/releases.md | 53 +++++++++++ .../docs/tutorials/cmake_integration.md | 2 +- fkYAML.natvis | 24 ++--- include/fkYAML/detail/assert.hpp | 2 +- .../fkYAML/detail/conversions/from_node.hpp | 2 +- .../fkYAML/detail/conversions/scalar_conv.hpp | 2 +- include/fkYAML/detail/conversions/to_node.hpp | 2 +- .../fkYAML/detail/conversions/to_string.hpp | 2 +- include/fkYAML/detail/document_metainfo.hpp | 2 +- .../fkYAML/detail/encodings/uri_encoding.hpp | 2 +- .../detail/encodings/utf_encode_detector.hpp | 2 +- .../fkYAML/detail/encodings/utf_encode_t.hpp | 2 +- .../fkYAML/detail/encodings/utf_encodings.hpp | 2 +- .../fkYAML/detail/encodings/yaml_escaper.hpp | 2 +- .../detail/input/block_scalar_header.hpp | 2 +- include/fkYAML/detail/input/deserializer.hpp | 2 +- include/fkYAML/detail/input/input_adapter.hpp | 2 +- .../fkYAML/detail/input/lexical_analyzer.hpp | 2 +- .../fkYAML/detail/input/position_tracker.hpp | 2 +- include/fkYAML/detail/input/scalar_parser.hpp | 2 +- .../fkYAML/detail/input/scalar_scanner.hpp | 2 +- include/fkYAML/detail/input/tag_resolver.hpp | 2 +- include/fkYAML/detail/input/tag_t.hpp | 2 +- include/fkYAML/detail/iterator.hpp | 2 +- .../detail/macros/cpp_config_macros.hpp | 2 +- .../fkYAML/detail/macros/define_macros.hpp | 2 +- .../fkYAML/detail/macros/version_macros.hpp | 6 +- include/fkYAML/detail/meta/detect.hpp | 2 +- .../detail/meta/input_adapter_traits.hpp | 2 +- include/fkYAML/detail/meta/node_traits.hpp | 2 +- include/fkYAML/detail/meta/stl_supplement.hpp | 2 +- include/fkYAML/detail/meta/type_traits.hpp | 2 +- include/fkYAML/detail/node_attrs.hpp | 2 +- include/fkYAML/detail/node_property.hpp | 2 +- include/fkYAML/detail/node_ref_storage.hpp | 2 +- include/fkYAML/detail/output/serializer.hpp | 2 +- include/fkYAML/detail/str_view.hpp | 2 +- include/fkYAML/detail/string_formatter.hpp | 2 +- .../fkYAML/detail/types/lexical_token_t.hpp | 2 +- include/fkYAML/detail/types/node_t.hpp | 2 +- .../fkYAML/detail/types/yaml_version_t.hpp | 2 +- include/fkYAML/exception.hpp | 2 +- include/fkYAML/fkyaml_fwd.hpp | 2 +- include/fkYAML/node.hpp | 2 +- include/fkYAML/node_type.hpp | 2 +- include/fkYAML/node_value_converter.hpp | 2 +- include/fkYAML/ordered_map.hpp | 2 +- include/fkYAML/yaml_version_type.hpp | 2 +- single_include/fkYAML/fkyaml_fwd.hpp | 8 +- single_include/fkYAML/node.hpp | 94 +++++++++---------- .../project/main.cpp | 2 +- .../project/CMakeLists.txt | 2 +- .../cmake_fetch_content_test/project/main.cpp | 2 +- test/cmake_find_package_test/project/main.cpp | 2 +- .../project/main.cpp | 2 +- test/unit_test/main.cpp | 2 +- test/unit_test/test_custom_from_node.cpp | 2 +- test/unit_test/test_deserializer_class.cpp | 2 +- test/unit_test/test_exception_class.cpp | 2 +- test/unit_test/test_input_adapter.cpp | 2 +- test/unit_test/test_iterator_class.cpp | 2 +- .../unit_test/test_lexical_analyzer_class.cpp | 2 +- test/unit_test/test_node_attrs.cpp | 2 +- test/unit_test/test_node_class.cpp | 2 +- .../unit_test/test_node_ref_storage_class.cpp | 2 +- test/unit_test/test_node_type.cpp | 2 +- test/unit_test/test_ordered_map_class.cpp | 2 +- .../unit_test/test_position_tracker_class.cpp | 2 +- test/unit_test/test_scalar_conv.cpp | 2 +- test/unit_test/test_scalar_parser_class.cpp | 2 +- test/unit_test/test_scalar_scanner_class.cpp | 2 +- test/unit_test/test_serializer_class.cpp | 2 +- test/unit_test/test_str_view_class.cpp | 2 +- test/unit_test/test_string_formatter.cpp | 2 +- test/unit_test/test_tag_resolver_class.cpp | 2 +- test/unit_test/test_uri_encoding_class.cpp | 2 +- test/unit_test/test_utf_encode_detector.cpp | 2 +- test/unit_test/test_utf_encodings.cpp | 2 +- test/unit_test/test_yaml_escaper_class.cpp | 2 +- test/unit_test/test_yaml_version_type.cpp | 2 +- tool/benchmark/main.cpp | 2 +- tool/natvis_generator/params.json | 2 +- 184 files changed, 315 insertions(+), 244 deletions(-) diff --git a/.reuse/templates/fkYAML.jinja2 b/.reuse/templates/fkYAML.jinja2 index 1b222e37..16e0d107 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.13 +| __| _ < \_ _/| ___ | _ | |___ version 0.3.14 |__| |_| \__| |_| |_| |_|___||___|______| 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 a72410b9..10b1bd93 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.13 +| __| _ < \_ _/| ___ | _ | |___ version 0.3.14 |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML {% for copyright_line in copyright_lines %} diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a63a235..0b604439 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## [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) + +- Disable -Wdeprecated-literal-operator warnings [\#417](https://github.com/fktn-k/fkYAML/pull/417) ([fktn-k](https://github.com/fktn-k)) +- Fix wrong scalar value type detection from floating point value token [\#414](https://github.com/fktn-k/fkYAML/pull/414) ([fktn-k](https://github.com/fktn-k)) + +- Exclude detail::unreachable\(\) from coverage target [\#426](https://github.com/fktn-k/fkYAML/pull/426) ([fktn-k](https://github.com/fktn-k)) +- Use std::unreachable\(\) or similar compiler specific extensions for dead but necessary code [\#425](https://github.com/fktn-k/fkYAML/pull/425) ([fktn-k](https://github.com/fktn-k)) +- Clarify type restrictions of get\_value\(\) & get\_value\_ref\(\) APIs [\#424](https://github.com/fktn-k/fkYAML/pull/424) ([fktn-k](https://github.com/fktn-k)) +- Fix duplicate include error if clang-tidy helper file already exists [\#423](https://github.com/fktn-k/fkYAML/pull/423) ([fktn-k](https://github.com/fktn-k)) +- Add forward declaration header [\#422](https://github.com/fktn-k/fkYAML/pull/422) ([fktn-k](https://github.com/fktn-k)) +- Support more STL types in from\_node [\#421](https://github.com/fktn-k/fkYAML/pull/421) ([fktn-k](https://github.com/fktn-k)) +- Numeric scalar conversions inside basic\_node::get\_value API [\#419](https://github.com/fktn-k/fkYAML/pull/419) ([fktn-k](https://github.com/fktn-k)) +- Fix somehow shadowed clang-tidy warnings [\#418](https://github.com/fktn-k/fkYAML/pull/418) ([fktn-k](https://github.com/fktn-k)) +- GA workflow jobs with more AppleClang versions on macOS [\#416](https://github.com/fktn-k/fkYAML/pull/416) ([fktn-k](https://github.com/fktn-k)) +- Update GA workflow jobs for ubuntu24.04 [\#415](https://github.com/fktn-k/fkYAML/pull/415) ([fktn-k](https://github.com/fktn-k)) + ## [v0.3.13](https://github.com/fktn-k/fkYAML/releases/tag/v0.3.13) (2024-10-14) [Full Changelog](https://github.com/fktn-k/fkYAML/compare/v0.3.12...v0.3.13) diff --git a/CMakeLists.txt b/CMakeLists.txt index d3147f74..e655e0b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.8) project( fkYAML - VERSION 0.3.13 + VERSION 0.3.14 LANGUAGES CXX) ############################################################# diff --git a/Makefile b/Makefile index 75b51224..ca615282 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ TOOL_SRCS = $(shell find tool -type f -name '*.cpp' | sort) # target version definition TARGET_MAJOR_VERSION := 0 TARGET_MINOR_VERSION := 3 -TARGET_PATCH_VERSION := 13 +TARGET_PATCH_VERSION := 14 TARGET_VERSION_FULL := $(TARGET_MAJOR_VERSION).$(TARGET_MINOR_VERSION).$(TARGET_PATCH_VERSION) VERSION_MACRO_FILE := include/fkYAML/detail/macros/version_macros.hpp diff --git a/docs/examples/ex_basic_node_add_anchor_name.cpp b/docs/examples/ex_basic_node_add_anchor_name.cpp index 07ec70da..578ee6bb 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 b2e79c3c..83fcc2f6 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 7659f701..7f3786cc 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 6ec9b6f0..38185ba8 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 a059a85a..7dce0749 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 7f9f0b31..10c7ef8a 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 1dcfa0f3..ba4bdd5b 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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_const_iterator.cpp index 8440f4ce..2d06a046 100644 --- a/docs/examples/ex_basic_node_const_iterator.cpp +++ b/docs/examples/ex_basic_node_const_iterator.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_constructor_1.cpp b/docs/examples/ex_basic_node_constructor_1.cpp index e0cbdbe1..159c1864 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 0ba84c5c..8722c362 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 c67f2747..79ff6bc2 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 57147d9a..b9c8c915 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d3ec490e..1e103244 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 c6bb05c6..28102d96 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d05a47d8..cf3d32a2 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 289bc219..9d777cc2 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 eabe7c33..32989914 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 df303e47..09f448c0 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 fb1a3744..be74a955 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d2e4631a..9714cc3e 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 c7414423..fc307c99 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 34ec6366..8ef4ecd7 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 67f6b400..2fd5028d 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 76145c43..9fdb1bf4 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d48d4b5d..8b850945 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 65b5757b..18c99589 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 5c71eae0..a955d86a 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_end.cpp b/docs/examples/ex_basic_node_end.cpp index 4c39ee19..a1ca0b4a 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 90960e10..9b072bdc 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 7cd97580..c1c54b8b 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 754c030f..e7e83f9a 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 9bdd8f65..b280c7d9 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 0d3fefb1..5eb15b00 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 0732993c..7a7d9c78 100644 --- a/docs/examples/ex_basic_node_get_value.cpp +++ b/docs/examples/ex_basic_node_get_value.cpp @@ -1,6 +1,6 @@ // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code) -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_get_value_ref.cpp b/docs/examples/ex_basic_node_get_value_ref.cpp index f010e9c3..2cb53bed 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d682602d..9f8b26cf 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 dfa4a082..bcb6abca 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d0191859..fc716a6d 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 78fbcb13..f6ae5acf 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 34186f92..21b527f2 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 7fa003f3..99c3bebf 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d456b37f..88b565b6 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 2316f4e3..bab7630e 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 9d143d93..d0c4ebb4 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 1faea26e..c48790d9 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d3a9df0a..2080b6e8 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 f7839192..3320e514 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 96d14139..872fa2f9 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 e8ef1597..9f8630f6 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 4cb20ae9..2951499e 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 8f6eff21..b278107b 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 f52cad6b..e3162885 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_mapping.cpp b/docs/examples/ex_basic_node_mapping.cpp index 76a290da..4614822f 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 3fef6e40..e5e19cd5 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 b65e2cfa..d2581845 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 59f0f422..e9fc9cdc 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 fd1103d6..2d19b663 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 ecc8cf7e..a90f30d1 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 0daeef46..a704a422 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 ba9822eb..d73cbfc7 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 a061cdc9..48c9c3a0 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 2850319b..0609c882 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_sequence.cpp b/docs/examples/ex_basic_node_sequence.cpp index 23d3eb54..e79479af 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 71f6e7a6..9228ca8f 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 0f3da2e3..119fafb3 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 cbf23a7c..fa25aa37 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 719aed9c..c671dd95 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 99d3ee95..672b2e3c 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 62d6dbb7..7f96014b 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/examples/ex_basic_node_string_type.cpp b/docs/examples/ex_basic_node_string_type.cpp index 412d7113..759c9d39 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d4036c0e..002d98a9 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 dce34be8..a36f97d7 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 c81dd5aa..061ea98e 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 96732b7f..247a2e69 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 59f0f422..e9fc9cdc 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 aa889e50..22989b1f 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 cee6f828..a3efec50 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 7274048e..2050a0cc 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 b8f4ae04..34fd0a1e 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 77a2dab7..7057783b 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 2f2adaca..67b53866 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 7466728c..25ca8acb 100644 --- a/docs/examples/ex_macros_versions.output +++ b/docs/examples/ex_macros_versions.output @@ -1 +1 @@ -fkYAML version 0.3.13 +fkYAML version 0.3.14 diff --git a/docs/examples/ex_node_type.cpp b/docs/examples/ex_node_type.cpp index 044fac8c..fd5aa2d2 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 ff5c8cc8..7b445bd9 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 9cac304e..6622df56 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 258b694c..715fb038 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 85427cb2..446b6e65 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 0ff9167f..d08c1bcd 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 7faad6ac..12f68ebb 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 a1c33b27..2540b469 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 e802bf62..858a2241 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 14a86c03..a22f212b 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 17f4c355..41938cfe 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 e94df280..97969cd2 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 fe579ff0..2c1ccddf 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 6e84daea..38fe6643 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 75105d69..60c06486 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/docs/mkdocs/docs/home/releases.md b/docs/mkdocs/docs/home/releases.md index 81dbd3ef..4c56836b 100644 --- a/docs/mkdocs/docs/home/releases.md +++ b/docs/mkdocs/docs/home/releases.md @@ -1,5 +1,58 @@ # Releases +## **fkYAML version 0.3.14** + +!!! abstract "Release Packages" + + * [fkYAML.zip](https://github.com/fktn-k/fkYAML/releases/download/v0.3.14/fkYAML.zip) + * [fkYAML.tgz](https://github.com/fktn-k/fkYAML/releases/download/v0.3.14/fkYAML.tgz) + * [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) + +### 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. +Furthermore, conversions of YAML nodes into arbitrary types have been much improved and a lot more STL container and scalar types have been supported for that purpose. See [the API documentation page](https://fktn-k.github.io/fkYAML/api/basic_node/get_value/) for more details. +Other changes are related to minor bug fixes in YAML scalar parsing and maintenance fixes for CI. + +### What's Changed + +#### :sparkles: New Features +- Numeric scalar conversions inside basic\_node::get\_value API ([\#419](https://github.com/fktn-k/fkYAML/pull/419), [fktn-k](https://github.com/fktn-k)) + - Suggested by [ARessegetesStery](https://github.com/ARessegetesStery) in the issue [\#366](https://github.com/fktn-k/fkYAML/issues/366) + - Automatic value conversions among null, boolean, integer and floating-point scalar values inside [fkyaml::basic_node::get_value()](../api/basic_node/get_value.md) API calls +- Add forward declaration header ([\#422](https://github.com/fktn-k/fkYAML/pull/422), [fktn-k](https://github.com/fktn-k)) + - Suggested by [abcminiuser](https://github.com/abcminiuser) in the duscussion [\#420](https://github.com/fktn-k/fkYAML/discussions/420) + - This new header provides the fkYAML namespace macros and forward declarations of fkYAML API classes. + - This file is available both in the [include](https://github.com/fktn-k/fkYAML/tree/v0.3.14/include) and [single_include](https://github.com/fktn-k/fkYAML/tree/v0.3.14/single_include) directories. + +#### :zap: Improvements +- Support more STL types in from\_node ([\#421](https://github.com/fktn-k/fkYAML/pull/421), [fktn-k](https://github.com/fktn-k)) + - YAML node objects can now be converted into a lot more STL container types. + - See [the API documentation page](https://fktn-k.github.io/fkYAML/api/basic_node/get_value/) for more details. +- Clarify type restrictions of get\_value\(\) & get\_value\_ref\(\) APIs ([\#424](https://github.com/fktn-k/fkYAML/pull/424), [fktn-k](https://github.com/fktn-k)) + - get_value calls with unsupported types (reference, pointer and C-style array types) now emits an explicit error message. +- Use std::unreachable\(\) or similar compiler specific extensions for dead but necessary code ([\#425](https://github.com/fktn-k/fkYAML/pull/425), [fktn-k](https://github.com/fktn-k)) + - Exclude detail::unreachable\(\) from coverage target ([\#426](https://github.com/fktn-k/fkYAML/pull/426), [fktn-k](https://github.com/fktn-k)) + +#### :bug: Bug Fixes +- Fix wrong scalar value type detection from floating point value token ([\#414](https://github.com/fktn-k/fkYAML/pull/414), [fktn-k](https://github.com/fktn-k)) + - reported by [ebertolazzi](https://github.com/ebertolazzi) in the issue [\#413](https://github.com/fktn-k/fkYAML/issues/413) +- Disable -Wdeprecated-literal-operator warnings ([\#417](https://github.com/fktn-k/fkYAML/pull/417), [fktn-k](https://github.com/fktn-k)) + - reported by [ebertolazzi](https://github.com/ebertolazzi) in the issue [\#413](https://github.com/fktn-k/fkYAML/issues/413) + +#### :robot: CI +- Update GA workflow jobs for ubuntu24.04 ([\#415](https://github.com/fktn-k/fkYAML/pull/415), [fktn-k](https://github.com/fktn-k)) +- GA workflow jobs with more AppleClang versions on macOS ([\#416](https://github.com/fktn-k/fkYAML/pull/416), [fktn-k](https://github.com/fktn-k)) +- Fix somehow shadowed clang-tidy warnings ([\#418](https://github.com/fktn-k/fkYAML/pull/418), [fktn-k](https://github.com/fktn-k)) +- Fix duplicate include error if clang-tidy helper file already exists ([\#423](https://github.com/fktn-k/fkYAML/pull/423), [fktn-k](https://github.com/fktn-k)) + +### Full Changelog +https://github.com/fktn-k/fkYAML/compare/v0.3.13...v0.3.14 + +--- + ## **fkYAML version 0.3.13** !!! abstract "Release Packages" diff --git a/docs/mkdocs/docs/tutorials/cmake_integration.md b/docs/mkdocs/docs/tutorials/cmake_integration.md index 9ee52af2..47510025 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.13 + GIT_TAG v0.3.14 ) FetchContent_MakeAvailable(fkYAML) diff --git a/fkYAML.natvis b/fkYAML.natvis index 7c8975ad..8a59861b 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 e881f075..c4e1ec18 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 4c8c9178..55333be7 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 4b583b8f..70918217 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 e0cbe5d3..a2d01059 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 32bd24a0..9c06a61e 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/document_metainfo.hpp b/include/fkYAML/detail/document_metainfo.hpp index c078b8b6..df9ec7e4 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 fb99a59e..f70f8740 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/encodings/utf_encode_detector.hpp b/include/fkYAML/detail/encodings/utf_encode_detector.hpp index 3bcaa5f6..80e72045 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/encodings/utf_encode_t.hpp b/include/fkYAML/detail/encodings/utf_encode_t.hpp index 1def9d3f..446271a3 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d8d974a7..dc5cdaf2 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 13faa4c6..5a7f5a41 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/input/block_scalar_header.hpp b/include/fkYAML/detail/input/block_scalar_header.hpp index d9bc2aa1..cb50aa9a 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/input/deserializer.hpp b/include/fkYAML/detail/input/deserializer.hpp index 7907d50a..bb79e155 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/input/input_adapter.hpp b/include/fkYAML/detail/input/input_adapter.hpp index 2808ed4e..044ca4fc 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 20dc0428..29e0acf1 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/input/position_tracker.hpp b/include/fkYAML/detail/input/position_tracker.hpp index 1ecbffad..dd3ff025 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 f56158e4..cc3c92e6 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/input/scalar_scanner.hpp b/include/fkYAML/detail/input/scalar_scanner.hpp index 4b86e444..46e00d42 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 dc001ff9..1d56460d 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/input/tag_t.hpp b/include/fkYAML/detail/input/tag_t.hpp index 62ae847f..607e8ba6 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 f0d638f4..43fcda9b 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/macros/cpp_config_macros.hpp b/include/fkYAML/detail/macros/cpp_config_macros.hpp index 2393b265..c829c8c4 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 5325fce6..a202ab4d 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 ea5e740c..9d05c6fa 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 != 13 +#if FK_YAML_MAJOR_VERSION != 0 || FK_YAML_MINOR_VERSION != 3 || FK_YAML_PATCH_VERSION != 14 #warning Already included a different version of the fkYAML library! #else // define macros to skip defining macros down below. @@ -20,7 +20,7 @@ #define FK_YAML_MAJOR_VERSION 0 #define FK_YAML_MINOR_VERSION 3 -#define FK_YAML_PATCH_VERSION 13 +#define FK_YAML_PATCH_VERSION 14 #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 36b85030..a9b90524 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 8442fb18..b1b5fa6a 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 b6050afc..ff1f963d 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 6b5e28bb..5b25d68f 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 4e9ec4ae..649b7a78 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 1e94954e..08c95caf 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 7fd0c92d..cfe72f92 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/node_ref_storage.hpp b/include/fkYAML/detail/node_ref_storage.hpp index 2c0abbcb..38a8fa0e 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 db9d3e4f..9029c6f4 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/str_view.hpp b/include/fkYAML/detail/str_view.hpp index e4b88bdc..1be1f5cd 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/detail/string_formatter.hpp b/include/fkYAML/detail/string_formatter.hpp index 80b7f5fc..90edc50b 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 65267b37..372ff159 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 ebc94c61..75149a03 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 cf0dea48..fbeb9413 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 5eccea0f..f88ea281 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 db3bb99d..fc9d2175 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 86ca8215..032c7b39 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/include/fkYAML/node_type.hpp b/include/fkYAML/node_type.hpp index 78b7481e..50d5868d 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 2a84526f..04ee8303 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 d05cccde..3c086e94 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 c715c0e7..9e938f44 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 165c4ffb..23ce75d6 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 != 13 +#if FK_YAML_MAJOR_VERSION != 0 || FK_YAML_MINOR_VERSION != 3 || FK_YAML_PATCH_VERSION != 14 #warning Already included a different version of the fkYAML library! #else // define macros to skip defining macros down below. @@ -37,7 +37,7 @@ #define FK_YAML_MAJOR_VERSION 0 #define FK_YAML_MINOR_VERSION 3 -#define FK_YAML_PATCH_VERSION 13 +#define FK_YAML_PATCH_VERSION 14 #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 5a75832c..749a9bbb 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 != 13 +#if FK_YAML_MAJOR_VERSION != 0 || FK_YAML_MINOR_VERSION != 3 || FK_YAML_PATCH_VERSION != 14 #warning Already included a different version of the fkYAML library! #else // define macros to skip defining macros down below. @@ -54,7 +54,7 @@ #define FK_YAML_MAJOR_VERSION 0 #define FK_YAML_MINOR_VERSION 3 -#define FK_YAML_PATCH_VERSION 13 +#define FK_YAML_PATCH_VERSION 14 #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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -1360,7 +1360,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -2072,7 +2072,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -3156,7 +3156,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -4274,7 +4274,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -4290,7 +4290,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -5130,7 +5130,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -5483,7 +5483,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -5819,7 +5819,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -6385,7 +6385,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -6570,7 +6570,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -6683,7 +6683,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -6824,7 +6824,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -8119,7 +8119,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -8142,7 +8142,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -8159,7 +8159,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -9556,7 +9556,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -9962,7 +9962,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10055,7 +10055,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10074,7 +10074,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10517,7 +10517,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10572,7 +10572,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -10588,7 +10588,7 @@ FK_YAML_DETAIL_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -11169,7 +11169,7 @@ FK_YAML_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani @@ -11556,7 +11556,7 @@ FK_YAML_NAMESPACE_END // #include // _______ __ __ __ _____ __ __ __ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library -// | __| _ < \_ _/| ___ | _ | |___ version 0.3.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/cmake_add_subdirectory_test/project/main.cpp b/test/cmake_add_subdirectory_test/project/main.cpp index 9a8fa4ef..052c3ca7 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 86eecd8d..1a9875f3 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.13) + GIT_TAG v0.3.14) 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 9a8fa4ef..052c3ca7 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 9a8fa4ef..052c3ca7 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 9a8fa4ef..052c3ca7 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/main.cpp b/test/unit_test/main.cpp index 2f113837..7ef2e622 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 635b224c..2efdc087 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 feae3b4a..2180bfdd 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_exception_class.cpp b/test/unit_test/test_exception_class.cpp index dc19b49c..03a5a2e0 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 fc0a24e3..bb1d385b 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 b9e8705d..7b5c1205 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_lexical_analyzer_class.cpp b/test/unit_test/test_lexical_analyzer_class.cpp index e75fcf9d..072e5e00 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_node_attrs.cpp b/test/unit_test/test_node_attrs.cpp index 57b1b7fb..5dace365 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 27799b37..b9b5be46 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_node_ref_storage_class.cpp b/test/unit_test/test_node_ref_storage_class.cpp index d0e89628..e0c46ed7 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 a7f62f06..eb4fe5c9 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 8d032263..76aae24f 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 5dab8774..d17bdf08 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_scalar_conv.cpp b/test/unit_test/test_scalar_conv.cpp index 179100c1..a35e113f 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 4d1d76e9..8a0ef795 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_scalar_scanner_class.cpp b/test/unit_test/test_scalar_scanner_class.cpp index 5e57bc8b..ed5a4a38 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 7d69c7c5..53ce323f 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_str_view_class.cpp b/test/unit_test/test_str_view_class.cpp index 01c05384..31344b59 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 9dd02570..6abe0bd2 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 0349dcb6..e1412e3e 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 4dfbf3a9..9ff364a0 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 0b7fdd29..760ebccd 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_utf_encodings.cpp b/test/unit_test/test_utf_encodings.cpp index 0ff1e298..a339f794 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML // // SPDX-FileCopyrightText: 2023-2024 Kensuke Fukutani diff --git a/test/unit_test/test_yaml_escaper_class.cpp b/test/unit_test/test_yaml_escaper_class.cpp index 849f3a27..68d1abe8 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 06f1e32a..779c9794 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 701d818c..e6e46a02 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.13 +// | __| _ < \_ _/| ___ | _ | |___ version 0.3.14 // |__| |_| \__| |_| |_| |_|___||___|______| 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 48616f95..dd993f55 100644 --- a/tool/natvis_generator/params.json +++ b/tool/natvis_generator/params.json @@ -1 +1 @@ -{ "version": "0.3.13" } +{ "version": "0.3.14" }