mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-25 23:06:10 +01:00
Introduced ReusableStringStream and removed all uses of std::ostringstream from the main path
ReusableStringStream holds a std::ostringstream internally, but only exposes the ostream interface. It caches a pool of ostringstreams in a vector which is currently global, but will be made thread-local. Altogether this should enable both runtime and compile-time benefits. although more work is needed to realise the compile time opportunities.
This commit is contained in:
parent
868e125d49
commit
56e1075613
@ -36,9 +36,9 @@ namespace Detail {
|
||||
}
|
||||
|
||||
std::string Approx::toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
|
||||
return oss.str();
|
||||
ReusableStringStream rss;
|
||||
rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
|
||||
return rss.str();
|
||||
}
|
||||
|
||||
bool Approx::equalityComparisonImpl(const double other) const {
|
||||
|
@ -8,10 +8,10 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
|
||||
|
||||
#include "catch_enforce.h"
|
||||
#include "catch_tostring.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
@ -83,9 +83,12 @@ namespace Detail {
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
Approx& epsilon( T const& newEpsilon ) {
|
||||
double epsilonAsDouble = static_cast<double>(newEpsilon);
|
||||
CATCH_ENFORCE(epsilonAsDouble >= 0 && epsilonAsDouble <= 1.0,
|
||||
"Invalid Approx::epsilon: " << epsilonAsDouble
|
||||
<< ", Approx::epsilon has to be between 0 and 1");
|
||||
if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) {
|
||||
throw std::domain_error
|
||||
( "Invalid Approx::epsilon: " +
|
||||
Catch::Detail::stringify( epsilonAsDouble ) +
|
||||
", Approx::epsilon has to be between 0 and 1" );
|
||||
}
|
||||
m_epsilon = epsilonAsDouble;
|
||||
return *this;
|
||||
}
|
||||
@ -93,9 +96,13 @@ namespace Detail {
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
Approx& margin( T const& newMargin ) {
|
||||
double marginAsDouble = static_cast<double>(newMargin);
|
||||
CATCH_ENFORCE(marginAsDouble >= 0,
|
||||
"Invalid Approx::margin: " << marginAsDouble
|
||||
<< ", Approx::Margin has to be non-negative.");
|
||||
if( marginAsDouble < 0 ) {
|
||||
throw std::domain_error
|
||||
( "Invalid Approx::margin: " +
|
||||
Catch::Detail::stringify( marginAsDouble ) +
|
||||
", Approx::Margin has to be non-negative." );
|
||||
|
||||
}
|
||||
m_margin = marginAsDouble;
|
||||
return *this;
|
||||
}
|
||||
|
@ -17,10 +17,9 @@ namespace Catch {
|
||||
|
||||
if( reconstructedExpression.empty() ) {
|
||||
if( lazyExpression ) {
|
||||
// !TBD Use stringstream for now, but rework above to pass stream in
|
||||
std::ostringstream oss;
|
||||
oss << lazyExpression;
|
||||
reconstructedExpression = oss.str();
|
||||
ReusableStringStream rss;
|
||||
rss << lazyExpression;
|
||||
reconstructedExpression = rss.str();
|
||||
}
|
||||
}
|
||||
return reconstructedExpression;
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "catch_debugger.h"
|
||||
#include "catch_windows_h_proxy.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
namespace {
|
||||
|
||||
|
@ -8,12 +8,13 @@
|
||||
#define TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED
|
||||
|
||||
#include "catch_common.h"
|
||||
#include "catch_stream.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <iosfwd>
|
||||
|
||||
#define CATCH_PREPARE_EXCEPTION( type, msg ) \
|
||||
type( static_cast<std::ostringstream&&>( std::ostringstream() << msg ).str() )
|
||||
type( static_cast<std::ostringstream&&>( Catch::ReusableStringStream().get() << msg ).str() )
|
||||
#define CATCH_INTERNAL_ERROR( msg ) \
|
||||
throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
|
||||
#define CATCH_ERROR( msg ) \
|
||||
|
@ -115,13 +115,14 @@ namespace Catch {
|
||||
}
|
||||
|
||||
for( auto const& tagCount : tagCounts ) {
|
||||
std::ostringstream oss;
|
||||
oss << " " << std::setw(2) << tagCount.second.count << " ";
|
||||
ReusableStringStream rss;
|
||||
rss << " " << std::setw(2) << tagCount.second.count << " ";
|
||||
auto str = rss.str();
|
||||
auto wrapper = Column( tagCount.second.all() )
|
||||
.initialIndent( 0 )
|
||||
.indent( oss.str().size() )
|
||||
.indent( str.size() )
|
||||
.width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
|
||||
Catch::cout() << oss.str() << wrapper << '\n';
|
||||
Catch::cout() << str << wrapper << '\n';
|
||||
}
|
||||
Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
|
||||
return tagCounts.size();
|
||||
|
@ -9,9 +9,9 @@
|
||||
#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "catch_result_type.h"
|
||||
#include "catch_common.h"
|
||||
#include "catch_stream.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@ -40,8 +40,7 @@ namespace Catch {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// !TBD reuse a global/ thread-local stream
|
||||
std::ostringstream m_stream;
|
||||
ReusableStringStream m_stream;
|
||||
};
|
||||
|
||||
struct MessageBuilder : MessageStream {
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@ -13,7 +14,7 @@ namespace Catch {
|
||||
: m_stream(stream),
|
||||
m_prevBuf(stream.rdbuf()),
|
||||
m_targetString(targetString) {
|
||||
stream.rdbuf(m_oss.rdbuf());
|
||||
stream.rdbuf(m_oss.get().rdbuf());
|
||||
}
|
||||
|
||||
StreamRedirect::~StreamRedirect() {
|
||||
@ -24,8 +25,8 @@ namespace Catch {
|
||||
StdErrRedirect::StdErrRedirect(std::string & targetString)
|
||||
:m_cerrBuf(cerr().rdbuf()), m_clogBuf(clog().rdbuf()),
|
||||
m_targetString(targetString) {
|
||||
cerr().rdbuf(m_oss.rdbuf());
|
||||
clog().rdbuf(m_oss.rdbuf());
|
||||
cerr().rdbuf(m_oss.get().rdbuf());
|
||||
clog().rdbuf(m_oss.get().rdbuf());
|
||||
}
|
||||
|
||||
StdErrRedirect::~StdErrRedirect() {
|
||||
|
@ -32,13 +32,12 @@ namespace Catch {
|
||||
|
||||
public:
|
||||
StreamRedirect(std::ostream& stream, std::string& targetString);
|
||||
|
||||
~StreamRedirect();
|
||||
|
||||
private:
|
||||
std::ostream& m_stream;
|
||||
std::streambuf* m_prevBuf;
|
||||
std::ostringstream m_oss;
|
||||
ReusableStringStream m_oss;
|
||||
std::string& m_targetString;
|
||||
};
|
||||
|
||||
@ -52,7 +51,7 @@ namespace Catch {
|
||||
private:
|
||||
std::streambuf* m_cerrBuf;
|
||||
std::streambuf* m_clogBuf;
|
||||
std::ostringstream m_oss;
|
||||
ReusableStringStream m_oss;
|
||||
std::string& m_targetString;
|
||||
};
|
||||
|
||||
|
@ -13,10 +13,16 @@
|
||||
#include "catch_debug_console.h"
|
||||
#include "catch_stringref.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wexit-time-destructors"
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@ -132,18 +138,64 @@ namespace Catch {
|
||||
return new detail::FileStream( filename );
|
||||
}
|
||||
|
||||
|
||||
// This class encapsulates the idea of a pool of ostringstreams that can be reused.
|
||||
struct StringStreams {
|
||||
std::vector<std::unique_ptr<std::ostringstream>> m_streams;
|
||||
std::vector<std::size_t> m_unused;
|
||||
std::ostringstream m_referenceStream; // Used for copy state/ flags from
|
||||
|
||||
auto add() -> std::size_t {
|
||||
if( m_unused.empty() ) {
|
||||
m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
|
||||
return m_streams.size()-1;
|
||||
}
|
||||
else {
|
||||
auto index = m_unused.back();
|
||||
m_unused.pop_back();
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
void release( std::size_t index ) {
|
||||
m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
|
||||
m_unused.push_back(index);
|
||||
}
|
||||
|
||||
// !TBD: put in TLS
|
||||
static auto instance() -> StringStreams& {
|
||||
static StringStreams s_stringStreams;
|
||||
return s_stringStreams;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ReusableStringStream::ReusableStringStream()
|
||||
: m_index( StringStreams::instance().add() ),
|
||||
m_oss( StringStreams::instance().m_streams[m_index].get() )
|
||||
{}
|
||||
|
||||
ReusableStringStream::~ReusableStringStream() {
|
||||
static_cast<std::ostringstream*>( m_oss )->str("");
|
||||
m_oss->clear();
|
||||
StringStreams::instance().release( m_index );
|
||||
}
|
||||
|
||||
auto ReusableStringStream::str() const -> std::string {
|
||||
return static_cast<std::ostringstream*>( m_oss )->str();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
|
||||
std::ostream& cout() {
|
||||
return std::cout;
|
||||
}
|
||||
std::ostream& cerr() {
|
||||
return std::cerr;
|
||||
}
|
||||
std::ostream& clog() {
|
||||
return std::clog;
|
||||
}
|
||||
std::ostream& cout() { return std::cout; }
|
||||
std::ostream& cerr() { return std::cerr; }
|
||||
std::ostream& clog() { return std::clog; }
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
@ -10,6 +10,8 @@
|
||||
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
||||
|
||||
#include <iosfwd>
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@ -25,6 +27,23 @@ namespace Catch {
|
||||
};
|
||||
|
||||
auto makeStream( StringRef const &filename ) -> IStream const*;
|
||||
|
||||
class ReusableStringStream {
|
||||
std::size_t m_index;
|
||||
std::ostream* m_oss;
|
||||
public:
|
||||
ReusableStringStream();
|
||||
~ReusableStringStream();
|
||||
|
||||
auto str() const -> std::string;
|
||||
|
||||
template<typename T>
|
||||
auto operator << ( T const& value ) -> ReusableStringStream& {
|
||||
*m_oss << value;
|
||||
return *this;
|
||||
}
|
||||
auto get() -> std::ostream& { return *m_oss; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
||||
|
@ -10,9 +10,10 @@
|
||||
#include "catch_console_colour.h"
|
||||
#include "catch_enforce.h"
|
||||
#include "catch_interfaces_registry_hub.h"
|
||||
#include "catch_stream.h"
|
||||
#include "catch_string_manip.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
TagAliasRegistry::~TagAliasRegistry() {}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <cctype>
|
||||
#include <exception>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
|
@ -66,9 +66,9 @@ namespace Catch {
|
||||
void TestRegistry::registerTest( TestCase const& testCase ) {
|
||||
std::string name = testCase.getTestCaseInfo().name;
|
||||
if( name.empty() ) {
|
||||
std::ostringstream oss;
|
||||
oss << "Anonymous test case " << ++m_unnamedCount;
|
||||
return registerTest( testCase.withName( oss.str() ) );
|
||||
ReusableStringStream rss;
|
||||
rss << "Anonymous test case " << ++m_unnamedCount;
|
||||
return registerTest( testCase.withName( rss.str() ) );
|
||||
}
|
||||
m_functions.push_back( testCase );
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
|
@ -52,22 +52,22 @@ namespace Detail {
|
||||
}
|
||||
|
||||
unsigned char const *bytes = static_cast<unsigned char const *>(object);
|
||||
std::ostringstream os;
|
||||
os << "0x" << std::setfill('0') << std::hex;
|
||||
ReusableStringStream rss;
|
||||
rss << "0x" << std::setfill('0') << std::hex;
|
||||
for( ; i != end; i += inc )
|
||||
os << std::setw(2) << static_cast<unsigned>(bytes[i]);
|
||||
return os.str();
|
||||
rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
|
||||
return rss.str();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
std::string fpToString( T value, int precision ) {
|
||||
std::ostringstream oss;
|
||||
oss << std::setprecision( precision )
|
||||
ReusableStringStream rss;
|
||||
rss << std::setprecision( precision )
|
||||
<< std::fixed
|
||||
<< value;
|
||||
std::string d = oss.str();
|
||||
std::string d = rss.str();
|
||||
std::size_t i = d.find_last_not_of( '0' );
|
||||
if( i != std::string::npos && i != d.size()-1 ) {
|
||||
if( d[i] == '.' )
|
||||
@ -153,12 +153,12 @@ std::string StringMaker<long>::convert(long value) {
|
||||
return ::Catch::Detail::stringify(static_cast<long long>(value));
|
||||
}
|
||||
std::string StringMaker<long long>::convert(long long value) {
|
||||
std::ostringstream oss;
|
||||
oss << value;
|
||||
ReusableStringStream rss;
|
||||
rss << value;
|
||||
if (value > Detail::hexThreshold) {
|
||||
oss << " (0x" << std::hex << value << ')';
|
||||
rss << " (0x" << std::hex << value << ')';
|
||||
}
|
||||
return oss.str();
|
||||
return rss.str();
|
||||
}
|
||||
|
||||
std::string StringMaker<unsigned int>::convert(unsigned int value) {
|
||||
@ -168,12 +168,12 @@ std::string StringMaker<unsigned long>::convert(unsigned long value) {
|
||||
return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
|
||||
}
|
||||
std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
|
||||
std::ostringstream oss;
|
||||
oss << value;
|
||||
ReusableStringStream rss;
|
||||
rss << value;
|
||||
if (value > Detail::hexThreshold) {
|
||||
oss << " (0x" << std::hex << value << ')';
|
||||
rss << " (0x" << std::hex << value << ')';
|
||||
}
|
||||
return oss.str();
|
||||
return rss.str();
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,11 +9,11 @@
|
||||
#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
#include "catch_stream.h"
|
||||
|
||||
#ifdef __OBJC__
|
||||
#include "catch_objc_arc.hpp"
|
||||
@ -66,9 +66,9 @@ namespace Catch {
|
||||
static
|
||||
typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
|
||||
convert(const Fake& t) {
|
||||
std::ostringstream sstr;
|
||||
sstr << t;
|
||||
return sstr.str();
|
||||
ReusableStringStream rss;
|
||||
rss << t;
|
||||
return rss.str();
|
||||
}
|
||||
|
||||
template <typename Fake = T>
|
||||
@ -221,15 +221,15 @@ namespace Catch {
|
||||
namespace Detail {
|
||||
template<typename InputIterator>
|
||||
std::string rangeToString(InputIterator first, InputIterator last) {
|
||||
std::ostringstream oss;
|
||||
oss << "{ ";
|
||||
ReusableStringStream rss;
|
||||
rss << "{ ";
|
||||
if (first != last) {
|
||||
oss << ::Catch::Detail::stringify(*first);
|
||||
rss << ::Catch::Detail::stringify(*first);
|
||||
for (++first; first != last; ++first)
|
||||
oss << ", " << ::Catch::Detail::stringify(*first);
|
||||
rss << ", " << ::Catch::Detail::stringify(*first);
|
||||
}
|
||||
oss << " }";
|
||||
return oss.str();
|
||||
rss << " }";
|
||||
return rss.str();
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,13 +290,13 @@ namespace Catch {
|
||||
template<typename T1, typename T2>
|
||||
struct StringMaker<std::pair<T1, T2> > {
|
||||
static std::string convert(const std::pair<T1, T2>& pair) {
|
||||
std::ostringstream oss;
|
||||
oss << "{ "
|
||||
ReusableStringStream rss;
|
||||
rss << "{ "
|
||||
<< ::Catch::Detail::stringify(pair.first)
|
||||
<< ", "
|
||||
<< ::Catch::Detail::stringify(pair.second)
|
||||
<< " }";
|
||||
return oss.str();
|
||||
return rss.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -334,11 +334,11 @@ namespace Catch {
|
||||
template<typename ...Types>
|
||||
struct StringMaker<std::tuple<Types...>> {
|
||||
static std::string convert(const std::tuple<Types...>& tuple) {
|
||||
std::ostringstream os;
|
||||
os << '{';
|
||||
Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, os);
|
||||
os << " }";
|
||||
return os.str();
|
||||
ReusableStringStream rss;
|
||||
rss << '{';
|
||||
Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
|
||||
rss << " }";
|
||||
return rss.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -358,10 +358,10 @@ struct ratio_string {
|
||||
|
||||
template <class Ratio>
|
||||
std::string ratio_string<Ratio>::symbol() {
|
||||
std::ostringstream oss;
|
||||
oss << '[' << Ratio::num << '/'
|
||||
Catch::ReusableStringStream rss;
|
||||
rss << '[' << Ratio::num << '/'
|
||||
<< Ratio::den << ']';
|
||||
return oss.str();
|
||||
return rss.str();
|
||||
}
|
||||
template <>
|
||||
struct ratio_string<std::atto> {
|
||||
@ -394,33 +394,33 @@ namespace Catch {
|
||||
template<typename Value, typename Ratio>
|
||||
struct StringMaker<std::chrono::duration<Value, Ratio>> {
|
||||
static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
|
||||
std::ostringstream oss;
|
||||
oss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
|
||||
return oss.str();
|
||||
ReusableStringStream rss;
|
||||
rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
|
||||
return rss.str();
|
||||
}
|
||||
};
|
||||
template<typename Value>
|
||||
struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
|
||||
static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
|
||||
std::ostringstream oss;
|
||||
oss << duration.count() << " s";
|
||||
return oss.str();
|
||||
ReusableStringStream rss;
|
||||
rss << duration.count() << " s";
|
||||
return rss.str();
|
||||
}
|
||||
};
|
||||
template<typename Value>
|
||||
struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
|
||||
static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
|
||||
std::ostringstream oss;
|
||||
oss << duration.count() << " m";
|
||||
return oss.str();
|
||||
ReusableStringStream rss;
|
||||
rss << duration.count() << " m";
|
||||
return rss.str();
|
||||
}
|
||||
};
|
||||
template<typename Value>
|
||||
struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
|
||||
static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
|
||||
std::ostringstream oss;
|
||||
oss << duration.count() << " h";
|
||||
return oss.str();
|
||||
ReusableStringStream rss;
|
||||
rss << duration.count() << " h";
|
||||
return rss.str();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "catch_enforce.h"
|
||||
#include "catch_string_manip.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "catch_stream.h"
|
||||
#include "catch_compiler_capabilities.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace Catch {
|
||||
@ -73,10 +72,9 @@ namespace Catch {
|
||||
|
||||
template<typename T>
|
||||
XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
|
||||
m_oss.clear();
|
||||
m_oss.str(std::string());
|
||||
m_oss << attribute;
|
||||
return writeAttribute( name, m_oss.str() );
|
||||
ReusableStringStream rss;
|
||||
rss << attribute;
|
||||
return writeAttribute( name, rss.str() );
|
||||
}
|
||||
|
||||
XmlWriter& writeText( std::string const& text, bool indent = true );
|
||||
@ -100,7 +98,6 @@ namespace Catch {
|
||||
std::vector<std::string> m_tags;
|
||||
std::string m_indent;
|
||||
std::ostream& m_os;
|
||||
std::ostringstream m_oss;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -8,16 +8,15 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
|
||||
|
||||
#include "../internal/catch_enforce.h"
|
||||
#include "../internal/catch_interfaces_reporter.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cfloat>
|
||||
#include <cstdio>
|
||||
#include <assert.h>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
|
||||
namespace Catch {
|
||||
void prepareExpandedExpression(AssertionResult& result);
|
||||
@ -33,7 +32,8 @@ namespace Catch {
|
||||
stream( _config.stream() )
|
||||
{
|
||||
m_reporterPrefs.shouldRedirectStdOut = false;
|
||||
CATCH_ENFORCE( DerivedT::getSupportedVerbosities().count( m_config->verbosity() ), "Verbosity level not supported by this reporter" );
|
||||
if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
|
||||
throw std::domain_error( "Verbosity level not supported by this reporter" );
|
||||
}
|
||||
|
||||
ReporterPreferences getPreferences() const override {
|
||||
@ -147,7 +147,8 @@ namespace Catch {
|
||||
stream( _config.stream() )
|
||||
{
|
||||
m_reporterPrefs.shouldRedirectStdOut = false;
|
||||
CATCH_ENFORCE( DerivedT::getSupportedVerbosities().count( m_config->verbosity() ), "Verbosity level not supported by this reporter" );
|
||||
if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
|
||||
throw std::domain_error( "Verbosity level not supported by this reporter" );
|
||||
}
|
||||
~CumulativeReporterBase() override = default;
|
||||
|
||||
|
@ -543,9 +543,9 @@ namespace Catch {
|
||||
colour( _colour )
|
||||
{}
|
||||
SummaryColumn addRow( std::size_t count ) {
|
||||
std::ostringstream oss;
|
||||
oss << count;
|
||||
std::string row = oss.str();
|
||||
ReusableStringStream rss;
|
||||
rss << count;
|
||||
std::string row = rss.str();
|
||||
for( auto& oldRow : rows ) {
|
||||
while( oldRow.size() < row.size() )
|
||||
oldRow = ' ' + oldRow;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "../internal/catch_timer.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
|
||||
@ -230,15 +230,15 @@ namespace Catch {
|
||||
xml.writeAttribute( "message", result.getExpandedExpression() );
|
||||
xml.writeAttribute( "type", result.getTestMacroName() );
|
||||
|
||||
std::ostringstream oss;
|
||||
ReusableStringStream rss;
|
||||
if( !result.getMessage().empty() )
|
||||
oss << result.getMessage() << '\n';
|
||||
rss << result.getMessage() << '\n';
|
||||
for( auto const& msg : stats.infoMessages )
|
||||
if( msg.type == ResultWas::Info )
|
||||
oss << msg.message << '\n';
|
||||
rss << msg.message << '\n';
|
||||
|
||||
oss << "at " << result.getSourceInfo();
|
||||
xml.writeText( oss.str(), false );
|
||||
rss << "at " << result.getSourceInfo();
|
||||
xml.writeText( rss.str(), false );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
// file can be distributed as a single header that works with the main
|
||||
// Catch single header.
|
||||
|
||||
#include "../internal/catch_enforce.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#ifdef __clang__
|
||||
@ -69,9 +71,9 @@ namespace Catch {
|
||||
AssertionResult const& result = assertionStats.assertionResult;
|
||||
if( !result.isOk() ) {
|
||||
|
||||
std::ostringstream msg;
|
||||
ReusableStringStream msg;
|
||||
if( !m_headerPrintedForThisSection )
|
||||
printSectionHeader( msg );
|
||||
printSectionHeader( msg.get() );
|
||||
m_headerPrintedForThisSection = true;
|
||||
|
||||
msg << result.getSourceInfo() << "\n";
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wweak-vtables"
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <iostream>
|
||||
#include <cerrno>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
TEST_CASE( "random SECTION tests", "[.][sections][failing]" ) {
|
||||
int a = 1;
|
||||
|
@ -15,10 +15,11 @@
|
||||
// that is triggered when compiling as Win32|Release
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
std::string toString( const std::pair<int, int>& value ) {
|
||||
std::ostringstream oss;
|
||||
|
Loading…
Reference in New Issue
Block a user