diff options
| author | Leitwolf11 | 2026-11-01 00:25:59 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-11-01 00:25:59 +0300 |
| commit | ff1da91edffa9ee887e9fe737fcd87ec540dfa60 (patch) | |
| tree | 25841e888932ebac3a51c4b59f77cea5a87ae5bd | |
| parent | 42c68725c816963ec6529dd635d5aaaac23b1c05 (diff) | |
| download | catch3-chore/cpp17-descriptions.tar.gz | |
Say C++17 everywhere the project describes itselfchore/cpp17-descriptions
The move to C++17 left a trail of older claims. The Runner's own
.clang-format still said c++20; the result is byte for byte the same under
either value. Premake and Xmake still compiled the library as C++20 and
the main library as C++14, which meant their CI jobs were not testing the
language the project promises. Both now use C++17 for every target.
The rest is text: the Meson pkg-config description claimed C++14, comments
in the CMake and Meson files explained requirements that no longer exist,
.clang-tidy gave C++14 as the reason for two exclusions, issue templates
asked for C++20 samples, and the example headers named -std=c++14 and
catch2-with-main. The release notes and the migration guide state the
C++17 minimum. Doxygen's brief called the project "Catch2's test API",
which presents it as Catch2. Meson declared only BSL-1.0; it now names both
licenses of the tree. The amalgamated files are regenerated.
27 files changed, 40 insertions, 50 deletions
diff --git a/.clang-tidy b/.clang-tidy index 8d3a17f2..57acd162 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -28,11 +28,11 @@ Checks: >- -modernize-concat-nested-namespaces, -modernize-use-nodiscard, -modernize-use-default-member-init, - -modernize-type-traits,# we need to support C++14, + -modernize-type-traits,# the engine spells these out, -modernize-deprecated-headers, ,# There's a lot of these and most of them are probably not useful, -modernize-pass-by-value, - -modernize-use-string-view, # We support C++14, + -modernize-use-string-view, # the engine has its own StringRef, performance-*, performance-enum-size, diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 7d640168..81c651c9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -26,7 +26,7 @@ Describe the expected behavior and the contract or documentation that supports i ### Minimal reproduction -Provide a small C++20 test, the command used to build and run it, and the test-runner arguments. For a property failure, include the root seed, replay seed, trial number, and minimized counterexample when available. For a snapshot failure, describe the snapshot mode and file location without pasting private content. +Provide a small C++17 test, the command used to build and run it, and the test-runner arguments. For a property failure, include the root seed, replay seed, trial number, and minimized counterexample when available. For a snapshot failure, describe the snapshot mode and file location without pasting private content. ### Environment diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 180a12dd..dd1ca2b2 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -15,7 +15,7 @@ What testing task is difficult today? Include a concrete example from a real tes ### Proposed behavior -Describe the user-facing API or runner behavior, with a short C++20 example if useful. Explain how failures should be reported and reproduced. +Describe the user-facing API or runner behavior, with a short C++17 example if useful. Explain how failures should be reported and reproduced. ### Ownership and compatibility @@ -54,7 +54,7 @@ PROJECT_NUMBER = # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = "Catch2's test API with a parallel runner, property testing and snapshots" +PROJECT_BRIEF = "A C++ test framework with a parallel runner, property testing and snapshots" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 diff --git a/docs/migrate-v2-to-v3.md b/docs/migrate-v2-to-v3.md index bd030523..9ec1f1c7 100644 --- a/docs/migrate-v2-to-v3.md +++ b/docs/migrate-v2-to-v3.md @@ -7,7 +7,7 @@ v3 is the next major version of Catch2 and brings three significant changes: * Catch2 is now split into multiple headers * Catch2 is now compiled as a static library - * C++14 is the minimum required C++ version + * C++17 is the minimum required C++ version There are many reasons why we decided to go from the old single-header distribution model to a more standard library distribution model. The diff --git a/docs/release-notes.md b/docs/release-notes.md index 870541d4..0e3633de 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -71,8 +71,7 @@ line and reporters with [a runner of its own](progmasoft-runner.md#top): * Catch2's command line, reporters, `CATCH_REGISTER_REPORTER` and listing were removed; see [the command line](command-line.md#top) and [reports](reporters.md#top). Listeners keep working. -* The library is compiled as C++20; code that includes only the engine's - headers still needs C++14. +* C++17 is the minimum, for the library and for the code that uses it. * The results model in `Progmasoft/Catch3/Results.hpp` was rewritten around tests and attempts. * Conan packaging was dropped. diff --git a/examples/010-TestCase.cpp b/examples/010-TestCase.cpp index 5eb982c8..d4c42a48 100644 --- a/examples/010-TestCase.cpp +++ b/examples/010-TestCase.cpp @@ -27,7 +27,7 @@ TEST_CASE( "Factorials of 1 and higher are computed (pass)", "[single-file]" ) { } // Compile & run: -// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 010-TestCase 010-TestCase.cpp && 010-TestCase --success +// - g++ -std=c++17 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 010-TestCase 010-TestCase.cpp && 010-TestCase --success // - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 010-TestCase.cpp && 010-TestCase --success // Expected compact output (all assertions): diff --git a/examples/020-TestCase-1.cpp b/examples/020-TestCase-1.cpp index 86de07a9..1acdc7a0 100644 --- a/examples/020-TestCase-1.cpp +++ b/examples/020-TestCase-1.cpp @@ -18,8 +18,8 @@ TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file: // Here just to show there are two source files via option --list-tests. // Compile & run: -// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -c 020-TestCase-1.cpp -// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 020-TestCase TestCase-1.o 020-TestCase-2.cpp && 020-TestCase --success +// - g++ -std=c++17 -Wall -I$(CATCH_SINGLE_INCLUDE) -c 020-TestCase-1.cpp +// - g++ -std=c++17 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 020-TestCase TestCase-1.o 020-TestCase-2.cpp && 020-TestCase --success // // - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -c 020-TestCase-1.cpp // - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -Fe020-TestCase.exe 020-TestCase-1.obj 020-TestCase-2.cpp && 020-TestCase --success diff --git a/examples/030-Asn-Require-Check.cpp b/examples/030-Asn-Require-Check.cpp index ed6ad752..416db4bc 100644 --- a/examples/030-Asn-Require-Check.cpp +++ b/examples/030-Asn-Require-Check.cpp @@ -61,7 +61,7 @@ TEST_CASE( "Assert that something is false (continue after failure)", "[check-fa } // Compile & run: -// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 030-Asn-Require-Check 030-Asn-Require-Check.cpp && 030-Asn-Require-Check --success +// - g++ -std=c++17 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 030-Asn-Require-Check 030-Asn-Require-Check.cpp && 030-Asn-Require-Check --success // - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 030-Asn-Require-Check.cpp && 030-Asn-Require-Check --success // Expected compact output (all assertions): diff --git a/examples/100-Fix-Section.cpp b/examples/100-Fix-Section.cpp index d1e4cdbc..b095d78b 100644 --- a/examples/100-Fix-Section.cpp +++ b/examples/100-Fix-Section.cpp @@ -53,7 +53,7 @@ TEST_CASE( "vectors can be sized and resized", "[vector]" ) { } // Compile & run: -// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 100-Fix-Section 100-Fix-Section.cpp && 100-Fix-Section --success +// - g++ -std=c++17 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 100-Fix-Section 100-Fix-Section.cpp && 100-Fix-Section --success // - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 100-Fix-Section.cpp && 100-Fix-Section --success // Expected compact output (all assertions): diff --git a/examples/110-Fix-ClassFixture.cpp b/examples/110-Fix-ClassFixture.cpp index 1b3f053f..f988f676 100644 --- a/examples/110-Fix-ClassFixture.cpp +++ b/examples/110-Fix-ClassFixture.cpp @@ -60,11 +60,11 @@ TEST_CASE_METHOD( UniqueTestsFixture, "Create Employee/Normal", "[create]" ) { } // Compile & run: -// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 110-Fix-ClassFixture 110-Fix-ClassFixture.cpp && 110-Fix-ClassFixture --success +// - g++ -std=c++17 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 110-Fix-ClassFixture 110-Fix-ClassFixture.cpp && 110-Fix-ClassFixture --success // - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 110-Fix-ClassFixture.cpp && 110-Fix-ClassFixture --success // // Compile with pkg-config: -// - g++ -std=c++14 -Wall $(pkg-config catch2-with-main --cflags) -o 110-Fix-ClassFixture 110-Fix-ClassFixture.cpp $(pkg-config catch2-with-main --libs) +// - g++ -std=c++17 -Wall $(pkg-config catch3-with-main --cflags) -o 110-Fix-ClassFixture 110-Fix-ClassFixture.cpp $(pkg-config catch3-with-main --libs) // Expected compact output (all assertions): // diff --git a/examples/120-Bdd-ScenarioGivenWhenThen.cpp b/examples/120-Bdd-ScenarioGivenWhenThen.cpp index b3edcd8c..1446393c 100644 --- a/examples/120-Bdd-ScenarioGivenWhenThen.cpp +++ b/examples/120-Bdd-ScenarioGivenWhenThen.cpp @@ -56,7 +56,7 @@ SCENARIO( "vectors can be sized and resized", "[vector]" ) { } // Compile & run: -// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 120-Bdd-ScenarioGivenWhenThen 120-Bdd-ScenarioGivenWhenThen.cpp && 120-Bdd-ScenarioGivenWhenThen --success +// - g++ -std=c++17 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 120-Bdd-ScenarioGivenWhenThen 120-Bdd-ScenarioGivenWhenThen.cpp && 120-Bdd-ScenarioGivenWhenThen --success // - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 120-Bdd-ScenarioGivenWhenThen.cpp && 120-Bdd-ScenarioGivenWhenThen --success // Expected compact output (all assertions): diff --git a/examples/210-Evt-EventListeners.cpp b/examples/210-Evt-EventListeners.cpp index 48ccce20..5c09d283 100644 --- a/examples/210-Evt-EventListeners.cpp +++ b/examples/210-Evt-EventListeners.cpp @@ -419,7 +419,7 @@ TEST_CASE_METHOD( Fixture, "3: Testcase with class-based fixture", "[tag-C][tag- } // Compile & run: -// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 210-Evt-EventListeners 210-Evt-EventListeners.cpp && 210-Evt-EventListeners --success +// - g++ -std=c++17 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 210-Evt-EventListeners 210-Evt-EventListeners.cpp && 210-Evt-EventListeners --success // - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 210-Evt-EventListeners.cpp && 210-Evt-EventListeners --success // Expected compact output (all assertions): diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp index 3151faf3..7556181e 100644 --- a/extras/catch_amalgamated.cpp +++ b/extras/catch_amalgamated.cpp @@ -7,7 +7,7 @@ // SPDX-License-Identifier: BSL-1.0 // Catch3 v0.3.0, on the Catch2 v3.16.1 engine -// Generated: 2026-10-31 20:20:20.891771 +// Generated: 2026-11-01 00:25:29.768099 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp index f26b0811..513c91ae 100644 --- a/extras/catch_amalgamated.hpp +++ b/extras/catch_amalgamated.hpp @@ -7,7 +7,7 @@ // SPDX-License-Identifier: BSL-1.0 // Catch3 v0.3.0, on the Catch2 v3.16.1 engine -// Generated: 2026-10-31 20:20:20.604513 +// Generated: 2026-11-01 00:25:29.668428 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -5942,7 +5942,7 @@ namespace Detail { namespace Catch { namespace Detail { - // This was added in C++20, but we require only C++14 for now. + // This was added in C++20, but we require only C++17. template <typename T> using RemoveCVRef_t = std::remove_cv_t<std::remove_reference_t<T>>; } diff --git a/extras/catch_amalgamated_third_party.hpp b/extras/catch_amalgamated_third_party.hpp index 6a48d4dd..353e0009 100644 --- a/extras/catch_amalgamated_third_party.hpp +++ b/extras/catch_amalgamated_third_party.hpp @@ -1,5 +1,5 @@ // Catch3 v0.3.0: yyjson and pugixml for catch_amalgamated.cpp -// Generated: 2026-10-31 20:20:21.165039 +// Generated: 2026-11-01 00:25:29.854771 // ---------------------------------------------------------- // This file is an amalgamation of src/Progmasoft/Runner/Yyjson.inl, // src/Progmasoft/PugiXml.inl and the libraries they include from diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt index 03e205ce..436642c6 100644 --- a/fuzzing/CMakeLists.txt +++ b/fuzzing/CMakeLists.txt @@ -7,7 +7,7 @@ add_library(fuzzhelper NullOStream.h NullOStream.cpp) target_link_libraries(fuzzhelper PUBLIC Catch3::Catch3) -# The runner fuzzers include its C++20 headers. +# The runner fuzzers include its headers, which need C++17. target_compile_features(fuzzhelper PUBLIC cxx_std_17) # This should be possible to set from the outside to be oss-fuzz compatible, diff --git a/meson.build b/meson.build index 4329a2f9..d63151e0 100644 --- a/meson.build +++ b/meson.build @@ -9,8 +9,8 @@ project( 'catch3', 'cpp', version: '0.3.0', - license: 'BSL-1.0', - # Meson 1.1 added clang-cl support for the C++20 mode used by Progmasoft tests. + license: ['BSL-1.0', 'MPL-2.0 WITH AdditionRef-Progmasoft-Exception-2.0'], + # Meson 1.1 added clang-cl support for the C++ modes used by Progmasoft tests. meson_version: '>=1.1.0', ) diff --git a/premake5.lua b/premake5.lua index d8a005d5..a1427cf3 100644 --- a/premake5.lua +++ b/premake5.lua @@ -33,12 +33,11 @@ workspace "Catch3" filter {} -- The Catch2-compatible engine, the Catch3 runner, property testing and --- snapshots; the library is C++20, the engine's headers need only C++14 in --- the code that includes them. +-- snapshots; the library and the code that includes it need C++17. project "Catch3" kind "StaticLib" language "C++" - cppdialect "C++20" + cppdialect "C++17" targetdir "build/premake/bin/%{cfg.buildcfg}" objdir "build/premake/obj/Catch3/%{cfg.buildcfg}" files { @@ -64,7 +63,7 @@ project "Catch3" project "Catch3WithMain" kind "StaticLib" language "C++" - cppdialect "C++14" + cppdialect "C++17" -- Visual Studio injects UNICODE for Windows projects, which would select -- Catch2's wmain entry point instead of the normal console main. defines { "DO_NOT_USE_WMAIN" } @@ -77,7 +76,7 @@ project "Catch3WithMain" project "ProgmasoftPropertyTests" kind "ConsoleApp" language "C++" - cppdialect "C++20" + cppdialect "C++17" targetdir "build/premake/bin/%{cfg.buildcfg}" objdir "build/premake/obj/ProgmasoftPropertyTests/%{cfg.buildcfg}" files { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 398260fd..aee8c7a3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -396,8 +396,7 @@ set_target_properties(Catch3 PROPERTIES SOVERSION ${PROJECT_VERSION} ) -# Code that includes the engine's headers needs C++14, and the other -# Progmasoft/ headers C++20; the library itself, with the runner, is built as C++20. +# The library, and the code that includes its headers, need C++17. target_compile_features(Catch3 PUBLIC cxx_std_17) configure_file( @@ -489,7 +488,7 @@ if(CATCH3_BUILD_EXAMPLES OR CATCH3_BUILD_EXTRA_TESTS) Catch3Pugixml ) # These targets compile the library's sources themselves, the runner's - # among them, which need C++20. + # among them, which need C++17. target_compile_features(Catch3_buildall_interface INTERFACE cxx_std_17) endif() diff --git a/src/Progmasoft/Catch3/Internal/Decomposer.hpp b/src/Progmasoft/Catch3/Internal/Decomposer.hpp index 77a4a123..4c57d3be 100644 --- a/src/Progmasoft/Catch3/Internal/Decomposer.hpp +++ b/src/Progmasoft/Catch3/Internal/Decomposer.hpp @@ -128,7 +128,7 @@ namespace Catch { namespace Detail { - // This was added in C++20, but we require only C++14 for now. + // This was added in C++20, but we require only C++17. template <typename T> using RemoveCVRef_t = std::remove_cv_t<std::remove_reference_t<T>>; } diff --git a/src/Progmasoft/Catch3/meson.build b/src/Progmasoft/Catch3/meson.build index b8d38908..7b75dc6d 100644 --- a/src/Progmasoft/Catch3/meson.build +++ b/src/Progmasoft/Catch3/meson.build @@ -347,8 +347,7 @@ if ((host_machine.system() == 'android') or catch3_dependencies += log_dep endif -# Code that includes the engine's headers needs C++14, and the other -# Progmasoft/ headers C++20; the library itself, with the runner, is built as C++20. +# The library, and the code that includes its headers, need C++17. catch3 = static_library( 'Catch3', sources, @@ -368,7 +367,7 @@ if get_option('install') pkg.generate( catch3, filebase: 'catch3', - description: 'A C++ test framework with a Catch2-compatible API; headers need C++14 and above', + description: 'A C++ test framework with a Catch2-compatible API; headers need C++17 and above', url: 'https://github.com/Progmasoft/catch3', ) endif diff --git a/src/Progmasoft/Runner/.clang-format b/src/Progmasoft/Runner/.clang-format index 1063b9ea..2cdf8220 100644 --- a/src/Progmasoft/Runner/.clang-format +++ b/src/Progmasoft/Runner/.clang-format @@ -1,7 +1,7 @@ --- Language: Cpp BasedOnStyle: LLVM -Standard: c++20 +Standard: c++17 UseTab: Never IndentWidth: 4 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a5524a38..33bbc4b5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -31,9 +31,8 @@ if(CATCH3_BUILD_SURROGATES) # Extracts all non-helper (e.g. Progmasoft/Catch3/All.hpp) headers from the # Catch3 target, and returns them through the argument. function(ExtractCatch3Headers OutArg) - # The engine's headers are the ones that come from Catch2. The other - # headers need C++20; the surrogates check the engine's headers at the - # language level of the build. + # The engine's headers are the ones that come from Catch2; the surrogates + # check them at the language level of the build. file(STRINGS "${CATCH_DIR}/tools/scripts/upstreamFiles.txt" upstreamFiles REGEX "^src/") get_target_property(targetSources Catch3 SOURCES) foreach(Source ${targetSources}) @@ -153,8 +152,7 @@ add_executable(SelfTest ${TEST_SOURCES} ${TEST_HEADERS}) target_include_directories(SelfTest PRIVATE ${SELF_TEST_DIR}) target_link_libraries(SelfTest PRIVATE Catch3WithMain) -# Exercise the C++20 Progmasoft layer independently so the upstream Catch2 -# SelfTest continues to compile at its supported baseline language level. +# Exercise the Progmasoft layer independently of the upstream Catch2 SelfTest. add_executable(ProgmasoftSelfTest Progmasoft/Generators.tests.cpp Progmasoft/Property.tests.cpp diff --git a/tests/ExtraTests/CMakeLists.txt b/tests/ExtraTests/CMakeLists.txt index e6488650..232b86dc 100644 --- a/tests/ExtraTests/CMakeLists.txt +++ b/tests/ExtraTests/CMakeLists.txt @@ -430,7 +430,7 @@ add_executable(AmalgamatedTestCompilation ${CATCH_DIR}/extras/catch_amalgamated_third_party.hpp ) target_include_directories(AmalgamatedTestCompilation PRIVATE ${CATCH_DIR}/extras) -# The amalgamated files hold the runner, which needs C++20. +# The amalgamated files hold the runner, which needs C++17. target_compile_features(AmalgamatedTestCompilation PRIVATE cxx_std_17) add_test(NAME AmalgamatedFileTest COMMAND AmalgamatedTestCompilation --no-history) diff --git a/tests/meson.build b/tests/meson.build index 95556f06..6ec807d7 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -68,7 +68,7 @@ self_test = executable( test('SelfTest', self_test, args: ['--no-history']) -# The Progmasoft tests need C++20; SelfTest keeps the C++ mode it has upstream. +# The Progmasoft tests need C++17; SelfTest keeps the project's C++ mode. progmasoft_property_tests = executable( 'ProgmasoftPropertyTests', [ @@ -3,7 +3,7 @@ set_project("Catch3") set_version("0.3.0") -set_languages("cxx14") +set_languages("cxx17") set_warnings("all") local repository_root = os.projectdir() @@ -15,11 +15,9 @@ includes("third_party/yyjson", "third_party/pugixml") -- The Catch2-compatible engine, the Catch3 runner, which replaced Catch2's -- session, command line and reporters, property testing and snapshots. The --- library is C++20; the engine's headers still need only C++14 in the code --- that includes them. +-- library and the code that includes it need C++17. target("catch3") set_kind("static") - set_languages("cxx20") on_load(function(target) -- File I/O is restricted to Xmake's script domain, so generate here -- rather than while the declarative project file is being evaluated. @@ -46,14 +44,12 @@ target("catch3") target("catch3_main") set_kind("static") - set_languages("cxx14") add_files("src/Progmasoft/Catch3/Internal/Main.cpp") add_deps("catch3") add_includedirs("src", generated_include, {public = true}) target("ProgmasoftPropertyTests") set_kind("binary") - set_languages("cxx20") add_files( "tests/Progmasoft/Generators.tests.cpp", "tests/Progmasoft/Property.tests.cpp", |