Compare commits

..
Author SHA1 Message Date
Claude 3c38455c7d BSON writer: drop the SFINAE guard that Visual Studio 2017 cannot deduce
write_bson_document_single_pass() was a member template enabled by
is_detected<sink_written_t, SinkType>. MSVC 19.16 (Visual Studio 2017)
fails to deduce it through the class-scope alias template (C2672, C2783)
when it compiles to_bson() and to_bon8(), so every Visual Studio 2017
job on AppVeyor fails since #5979.

The guard is not needed: as a non-template member of the class template,
the function is only instantiated when called, and its only caller is
the write_bson_document() overload for sinks that have written(), which
already calls oa.written() and oa.rewind() itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>
2026-11-02 10:35:13 +00:00
Claude 4571446da7 CI: give the Valgrind tests a timeout of one hour
Under Valgrind, test-json_view_builder_cpp11 and test-ordered_json_cpp11
took 1435 s and 1390 s on develop (ddc34f5), close to ctest's default
timeout of 1500 s. On the next run (b2674a4) the whole job was about 10 %
slower and both timed out, failing ci_test_valgrind on develop and on
every PR based on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasAgbDGG28MqXjQvLqp
Signed-off-by: Claude <noreply@anthropic.com>
2026-11-02 10:29:38 +00:00
7 changed files with 11 additions and 75 deletions

No files matched your search

+3 -1
View File
@@ -178,8 +178,10 @@ function(_json_test_add_test test_name file main cxx_standard)
COMMAND ${memcheck_command} $<TARGET_FILE:${test_target}> ${DOCTEST_TEST_FILTER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
# under Valgrind the slowest tests take close to 25 minutes, so ctest's
# default timeout of 1500 seconds leaves no headroom
set_tests_properties(${test_target}_valgrind PROPERTIES
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA TIMEOUT 3600
)
endif()
endfunction()
@@ -406,7 +406,6 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
| `#!cpp operator<<(std::ostream&, const json_pointer&)` | streamability to `#!cpp std::ostream` |
| [`to_string`](../../api/basic_json/to_string.md) | conversion of `StringType` to `#!cpp std::string` (the function returns a `#!cpp std::string`) |
| exception messages | `data()` and `size()`, or `begin()` and `end()` |
| [`basic_json_view::dump`](../../api/basic_json_view/dump.md) | `reserve(n)` and `resize(n)` (one argument); `capacity()` is **not** required |
### Compatible types
@@ -2422,7 +2422,6 @@ class binary_writer
nothing large has been written then, and the caller writes the
document in two passes, which reports that error
*/
template<typename SinkType = OutputSinkType, typename std::enable_if<is_detected<sink_written_t, SinkType>::value, int>::type = 0>
bool write_bson_document_single_pass(const BasicJsonType& document)
{
const std::size_t start = oa.written();
+4 -9
View File
@@ -47,7 +47,6 @@ class output_buffer
: m_out(sized(out, estimate))
, m_pos(&m_out[0])
, m_end(m_pos + m_out.size())
, m_reserved((std::max)(estimate, m_out.size()))
{}
void finish()
@@ -117,12 +116,11 @@ class output_buffer
const auto used = static_cast<std::size_t>(m_pos - m_out.data());
// (a step does not go beyond the reserved estimate, so that a good
// estimate is never copied to a larger allocation; not a clamp: the
// lower bound used + n + 256 can exceed m_reserved, and then it must win)
const std::size_t size = (std::max)((std::min)(m_out.size() + step, m_reserved), used + n + 256);
if (size > m_reserved)
// lower bound used + n + 256 can exceed capacity(), and then it must win)
const std::size_t size = (std::max)((std::min)(m_out.size() + step, m_out.capacity()), used + n + 256);
if (size > m_out.capacity())
{
m_reserved = (std::max)(m_reserved * 2, size);
m_out.reserve(m_reserved);
m_out.reserve((std::max)(m_out.capacity() * 2, size));
}
m_out.resize(size);
m_pos = &m_out[0] + used;
@@ -132,9 +130,6 @@ class output_buffer
StringType& m_out;
char* m_pos;
char* m_end;
/// what was last passed to reserve(), a lower bound of the capacity
/// (StringType need not have a capacity() member)
std::size_t m_reserved;
};
/// The length of the run at s that dump() writes unchanged without
-1
View File
@@ -30394,7 +30394,6 @@ class binary_writer
nothing large has been written then, and the caller writes the
document in two passes, which reports that error
*/
template<typename SinkType = OutputSinkType, typename std::enable_if<is_detected<sink_written_t, SinkType>::value, int>::type = 0>
bool write_bson_document_single_pass(const BasicJsonType& document)
{
const std::size_t start = oa.written();
+4 -9
View File
@@ -8511,7 +8511,6 @@ class output_buffer
: m_out(sized(out, estimate))
, m_pos(&m_out[0])
, m_end(m_pos + m_out.size())
, m_reserved((std::max)(estimate, m_out.size()))
{}
void finish()
@@ -8581,12 +8580,11 @@ class output_buffer
const auto used = static_cast<std::size_t>(m_pos - m_out.data());
// (a step does not go beyond the reserved estimate, so that a good
// estimate is never copied to a larger allocation; not a clamp: the
// lower bound used + n + 256 can exceed m_reserved, and then it must win)
const std::size_t size = (std::max)((std::min)(m_out.size() + step, m_reserved), used + n + 256);
if (size > m_reserved)
// lower bound used + n + 256 can exceed capacity(), and then it must win)
const std::size_t size = (std::max)((std::min)(m_out.size() + step, m_out.capacity()), used + n + 256);
if (size > m_out.capacity())
{
m_reserved = (std::max)(m_reserved * 2, size);
m_out.reserve(m_reserved);
m_out.reserve((std::max)(m_out.capacity() * 2, size));
}
m_out.resize(size);
m_pos = &m_out[0] + used;
@@ -8596,9 +8594,6 @@ class output_buffer
StringType& m_out;
char* m_pos;
char* m_end;
/// what was last passed to reserve(), a lower bound of the capacity
/// (StringType need not have a capacity() member)
std::size_t m_reserved;
};
/// The length of the run at s that dump() writes unchanged without
-53
View File
@@ -10,7 +10,6 @@
#include "doctest_compatibility.h"
#include <nlohmann/json.hpp>
#include <nlohmann/json_view.hpp>
#include <cstdint>
#include <string>
@@ -484,56 +483,4 @@ TEST_CASE("alternative string type")
}
}
TEST_CASE("alternative string type with json_view")
{
// regression test for #5994: basic_json_view::dump() called
// StringType::capacity(), which alt_string (and the documented StringType
// requirements) do not provide
using alt_document = nlohmann::basic_json_document<alt_json, nlohmann::view_mode::read_only>;
using alt_editable_document = nlohmann::basic_json_document<alt_json, nlohmann::view_mode::editable>;
const char* text = R"({"a":[1,"x\u00e4"],"b":{"c":true,"d":null},"e":2.5})";
const alt_json j = alt_json::parse(text);
SECTION("read-only document")
{
const alt_document d = alt_document::parse(text);
CHECK(d.root().dump() == j.dump());
CHECK(d.root().dump(2) == j.dump(2));
CHECK(d.root().dump(-1, ' ', true) == j.dump(-1, ' ', true));
CHECK(d.root().materialize() == j);
CHECK(d.root().contains(alt_string("b")));
CHECK(d.root()[alt_string("b")][alt_string("c")].dump() == "true");
}
SECTION("long output")
{
// more than one growth step of the output buffer
alt_json big = alt_json::array();
for (int i = 0; i < 20000; ++i)
{
big.push_back(alt_json::parse(text));
}
const alt_string big_text = big.dump();
const alt_document d = alt_document::parse(big_text);
CHECK(d.root().dump() == big_text);
CHECK(d.root().dump(4) == big.dump(4));
}
SECTION("editable document")
{
alt_editable_document d = alt_editable_document::parse(text);
d.set(d.root(), "f", "new");
d.push_back(d.root()[alt_string("a")], 3);
alt_json expected = j;
expected["f"] = "new";
expected["a"].push_back(3);
CHECK(d.root().materialize() == expected);
CHECK(alt_json::parse(d.root().dump()) == expected);
const alt_editable_document loaded = alt_editable_document::load(d.save());
CHECK(loaded.root().materialize() == expected);
}
}
DOCTEST_CLANG_SUPPRESS_WARNING_POP