// 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 #include #include #include #include #include #include namespace Catch { // This class encapsulates the idea of a pool of ostringstreams that can be reused. struct StringStreams { std::vector> m_streams; std::vector m_unused; std::ostringstream m_referenceStream; // Used for copy state/ flags from Detail::Mutex m_mutex; auto add() -> std::size_t { Detail::LockGuard _( m_mutex ); if( m_unused.empty() ) { m_streams.push_back( Detail::make_unique() ); return m_streams.size()-1; } else { auto index = m_unused.back(); m_unused.pop_back(); return index; } } 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() : m_index( Singleton::getMutable().add() ), m_oss( Singleton::getMutable().m_streams[m_index].get() ) {} ReusableStringStream::~ReusableStringStream() { static_cast( m_oss )->str(""); m_oss->clear(); Singleton::getMutable().release( m_index, m_oss ); } std::string ReusableStringStream::str() const { return static_cast( m_oss )->str(); } void ReusableStringStream::str( std::string const& str ) { static_cast( m_oss )->str( str ); } }