diff options
| author | Leitwolf | 2026-10-25 10:31:36 +0300 |
|---|---|---|
| committer | GitHub | 2026-10-25 10:31:36 +0300 |
| commit | d2e3e074bb2e1b8ffd9fc990d0b87667ea602f58 (patch) | |
| tree | 0bce4462b2e190c39b3e1c5f697e3e4abd1a5e2a /src/Progmasoft/Catch3/Internal/ReusableStringStream.cpp | |
| parent | 13f81a480a93807c14dddb5abdb97355ced4d4c5 (diff) | |
| parent | 126dc333564cb72b5115d9a9242d66694694b6d0 (diff) | |
| download | catch3-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.cpp | 74 |
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 ); + } + + +} |