Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/Progmasoft/Catch3/Internal/ReusableStringStream.cpp
diff options
context:
space:
mode:
authorLeitwolf2026-10-25 10:31:36 +0300
committerGitHub2026-10-25 10:31:36 +0300
commitd2e3e074bb2e1b8ffd9fc990d0b87667ea602f58 (patch)
tree0bce4462b2e190c39b3e1c5f697e3e4abd1a5e2a /src/Progmasoft/Catch3/Internal/ReusableStringStream.cpp
parent13f81a480a93807c14dddb5abdb97355ced4d4c5 (diff)
parent126dc333564cb72b5115d9a9242d66694694b6d0 (diff)
downloadcatch3-d2e3e074bb2e1b8ffd9fc990d0b87667ea602f58.tar.gz
Merge pull request #18 from Progmasoft/build/catch3-identity
Give Catch3 its own build names and headers
Diffstat (limited to 'src/Progmasoft/Catch3/Internal/ReusableStringStream.cpp')
-rw-r--r--src/Progmasoft/Catch3/Internal/ReusableStringStream.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/Progmasoft/Catch3/Internal/ReusableStringStream.cpp b/src/Progmasoft/Catch3/Internal/ReusableStringStream.cpp
new file mode 100644
index 00000000..6713fb0d
--- /dev/null
+++ b/src/Progmasoft/Catch3/Internal/ReusableStringStream.cpp
@@ -0,0 +1,74 @@
+
+// Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+#include <Progmasoft/Catch3/Internal/ReusableStringStream.hpp>
+#include <Progmasoft/Catch3/Internal/Singletons.hpp>
+#include <Progmasoft/Catch3/Internal/ThreadSupport.hpp>
+#include <Progmasoft/Catch3/Internal/UniquePtr.hpp>
+
+#include <cstdio>
+#include <list>
+#include <sstream>
+#include <tuple>
+#include <vector>
+
+namespace Catch {
+
+ // This class encapsulates the idea of a pool of ostringstreams that can be reused.
+ struct StringStreams {
+ std::vector<Detail::unique_ptr<std::ostringstream>> m_streams;
+ // The library can be linked into ASan-instrumented clients without
+ // instrumenting Catch3 itself. A list avoids mixed-mode libc++ vector
+ // container annotations for the reusable-index pool.
+ std::list<std::size_t> m_unused;
+ std::ostringstream m_referenceStream; // Used for copy state/ flags from
+ Detail::Mutex m_mutex;
+
+ auto add() -> std::pair<std::size_t, std::ostringstream*> {
+ Detail::LockGuard _( m_mutex );
+ if( m_unused.empty() ) {
+ m_streams.push_back( Detail::make_unique<std::ostringstream>() );
+ return { m_streams.size()-1, m_streams.back().get() };
+ }
+ else {
+ auto index = m_unused.back();
+ m_unused.pop_back();
+ return { index, m_streams[index].get() };
+ }
+ }
+
+ void release( std::size_t index, std::ostream* originalPtr ) {
+ assert( originalPtr );
+ originalPtr->copyfmt( m_referenceStream ); // Restore initial flags and other state
+
+ Detail::LockGuard _( m_mutex );
+ assert( originalPtr == m_streams[index].get() && "Mismatch between release index and stream ptr" );
+ m_unused.push_back( index );
+ }
+ };
+
+ ReusableStringStream::ReusableStringStream() {
+ std::tie( m_index, m_oss ) =
+ Singleton<StringStreams>::getMutable().add();
+ }
+
+ ReusableStringStream::~ReusableStringStream() {
+ static_cast<std::ostringstream*>( m_oss )->str("");
+ m_oss->clear();
+ Singleton<StringStreams>::getMutable().release( m_index, m_oss );
+ }
+
+ std::string ReusableStringStream::str() const {
+ return static_cast<std::ostringstream*>( m_oss )->str();
+ }
+
+ void ReusableStringStream::str( std::string const& str ) {
+ static_cast<std::ostringstream*>( m_oss )->str( str );
+ }
+
+
+}