diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn index d69b978d16..89eb6eef99 100644 --- a/src/tint/BUILD.gn +++ b/src/tint/BUILD.gn @@ -293,7 +293,10 @@ libtint_source_set("libtint_demangler_src") { "demangler.cc", "demangler.h", ] - deps = [ ":libtint_program_src" ] + deps = [ + ":libtint_base_src", + ":libtint_program_src", + ] } libtint_source_set("libtint_initializer_src") { diff --git a/src/tint/ast/float_literal_expression_test.cc b/src/tint/ast/float_literal_expression_test.cc index 5ec5f0fccd..63745832c6 100644 --- a/src/tint/ast/float_literal_expression_test.cc +++ b/src/tint/ast/float_literal_expression_test.cc @@ -14,6 +14,8 @@ #include "src/tint/ast/test_helper.h" +#include "src/tint/utils/string_stream.h" + namespace tint::ast { namespace { @@ -42,7 +44,7 @@ TEST_F(FloatLiteralExpressionTest, SuffixH) { TEST_F(FloatLiteralExpressionTest, SuffixStringStream) { auto to_str = [](FloatLiteralExpression::Suffix suffix) { - std::stringstream ss; + utils::StringStream ss; ss << suffix; return ss.str(); }; diff --git a/src/tint/ast/int_literal_expression_test.cc b/src/tint/ast/int_literal_expression_test.cc index 969e1b94ea..9481c3046b 100644 --- a/src/tint/ast/int_literal_expression_test.cc +++ b/src/tint/ast/int_literal_expression_test.cc @@ -14,6 +14,8 @@ #include "src/tint/ast/test_helper.h" +#include "src/tint/utils/string_stream.h" + namespace tint::ast { namespace { @@ -42,7 +44,7 @@ TEST_F(IntLiteralExpressionTest, SuffixU) { TEST_F(IntLiteralExpressionTest, SuffixStringStream) { auto to_str = [](IntLiteralExpression::Suffix suffix) { - std::stringstream ss; + utils::StringStream ss; ss << suffix; return ss.str(); }; diff --git a/src/tint/bench/benchmark.cc b/src/tint/bench/benchmark.cc index c00e51f928..6b072db53d 100644 --- a/src/tint/bench/benchmark.cc +++ b/src/tint/bench/benchmark.cc @@ -19,6 +19,8 @@ #include #include +#include "src/tint/utils/string_stream.h" + namespace tint::bench { namespace { @@ -44,7 +46,7 @@ std::variant, Error> ReadFile(const std::string& input_file) { fseek(file, 0, SEEK_END); const auto file_size = static_cast(ftell(file)); if (0 != (file_size % sizeof(T))) { - std::stringstream err; + utils::StringStream err; err << "File " << input_file << " does not contain an integral number of objects: " << file_size << " bytes in the file, require " << sizeof(T) << " bytes per object"; diff --git a/src/tint/cmd/main.cc b/src/tint/cmd/main.cc index cd46885720..12d5b8c068 100644 --- a/src/tint/cmd/main.cc +++ b/src/tint/cmd/main.cc @@ -37,6 +37,7 @@ #include "src/tint/cmd/helper.h" #include "src/tint/utils/io/command.h" #include "src/tint/utils/string.h" +#include "src/tint/utils/string_stream.h" #include "src/tint/utils/transform.h" #include "src/tint/val/val.h" #include "tint/tint.h" @@ -245,7 +246,7 @@ Format infer_format(const std::string& filename) { std::vector split_on_char(std::string list, char c) { std::vector res; - std::stringstream str(list); + std::istringstream str(list); while (str.good()) { std::string substr; getline(str, substr, c); @@ -1034,7 +1035,7 @@ int main(int argc, const char** argv) { }}, }; auto transform_names = [&] { - std::stringstream names; + tint::utils::StringStream names; for (auto& t : transforms) { names << " " << t.name << std::endl; } diff --git a/src/tint/debug.h b/src/tint/debug.h index 43bc052c04..5caeb5dbe4 100644 --- a/src/tint/debug.h +++ b/src/tint/debug.h @@ -21,6 +21,7 @@ #include "src/tint/diagnostic/formatter.h" #include "src/tint/diagnostic/printer.h" #include "src/tint/utils/compiler_macros.h" +#include "src/tint/utils/string_stream.h" namespace tint { @@ -71,7 +72,7 @@ class InternalCompilerError { const size_t line_; diag::System system_; diag::List& diagnostics_; - std::stringstream msg_; + utils::StringStream msg_; }; } // namespace tint diff --git a/src/tint/demangler.cc b/src/tint/demangler.cc index d68a62a825..146a31c518 100644 --- a/src/tint/demangler.cc +++ b/src/tint/demangler.cc @@ -15,6 +15,7 @@ #include "src/tint/demangler.h" #include "src/tint/program.h" +#include "src/tint/utils/string_stream.h" namespace tint { namespace { @@ -29,7 +30,7 @@ Demangler::Demangler() = default; Demangler::~Demangler() = default; std::string Demangler::Demangle(const SymbolTable& symbols, const std::string& str) const { - std::stringstream out; + utils::StringStream out; size_t pos = 0; for (;;) { diff --git a/src/tint/diagnostic/formatter.cc b/src/tint/diagnostic/formatter.cc index db69397b53..18520fc1fe 100644 --- a/src/tint/diagnostic/formatter.cc +++ b/src/tint/diagnostic/formatter.cc @@ -20,6 +20,7 @@ #include "src/tint/diagnostic/diagnostic.h" #include "src/tint/diagnostic/printer.h" +#include "src/tint/utils/string_stream.h" namespace tint::diag { namespace { @@ -41,7 +42,7 @@ const char* to_str(Severity severity) { } std::string to_str(const Source::Location& location) { - std::stringstream ss; + utils::StringStream ss; if (location.line > 0) { ss << location.line; if (location.column > 0) { @@ -75,7 +76,7 @@ struct Formatter::State { auto str = stream.str(); if (str.length() > 0) { printer->write(str, style); - std::stringstream reset; + utils::StringStream reset; stream.swap(reset); } } @@ -95,12 +96,12 @@ struct Formatter::State { /// repeat queues the character c to be written to the printer n times. /// @param c the character to print `n` times /// @param n the number of times to print character `c` - void repeat(char c, size_t n) { std::fill_n(std::ostream_iterator(stream), n, c); } + void repeat(char c, size_t n) { stream.repeat(c, n); } private: Printer* printer; diag::Style style; - std::stringstream stream; + utils::StringStream stream; }; Formatter::Formatter() {} diff --git a/src/tint/diagnostic/printer.h b/src/tint/diagnostic/printer.h index b2ac1051d6..9e4ce7c62c 100644 --- a/src/tint/diagnostic/printer.h +++ b/src/tint/diagnostic/printer.h @@ -19,6 +19,8 @@ #include #include +#include "src/tint/utils/string_stream.h" + namespace tint::diag { class List; @@ -73,7 +75,7 @@ class StringPrinter : public Printer { void write(const std::string& str, const Style&) override; private: - std::stringstream stream; + utils::StringStream stream; }; } // namespace tint::diag diff --git a/src/tint/number_test.cc b/src/tint/number_test.cc index fe036631b2..7ae5e375f5 100644 --- a/src/tint/number_test.cc +++ b/src/tint/number_test.cc @@ -19,6 +19,7 @@ #include "src/tint/program_builder.h" #include "src/tint/utils/compiler_macros.h" +#include "src/tint/utils/string_stream.h" #include "gtest/gtest.h" @@ -254,7 +255,7 @@ TEST_P(NumberF16Test, QuantizeF16) { float input_value = GetParam().input_value; float quantized_value = GetParam().quantized_value; - std::stringstream ss; + utils::StringStream ss; ss << "input value = " << input_value << ", expected quantized value = " << quantized_value; SCOPED_TRACE(ss.str()); @@ -269,7 +270,7 @@ TEST_P(NumberF16Test, BitsRepresentation) { float input_value = GetParam().input_value; uint16_t representation = GetParam().f16_bit_pattern; - std::stringstream ss; + utils::StringStream ss; ss << "input value = " << input_value << ", expected binary16 bits representation = " << std::hex << std::showbase << representation; @@ -282,7 +283,7 @@ TEST_P(NumberF16Test, FromBits) { float input_value = GetParam().quantized_value; uint16_t representation = GetParam().f16_bit_pattern; - std::stringstream ss; + utils::StringStream ss; ss << "binary16 bits representation = " << std::hex << std::showbase << representation << " expected value = " << input_value; SCOPED_TRACE(ss.str()); diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc index 28ecebdddd..0030ca1d64 100644 --- a/src/tint/transform/decompose_memory_access.cc +++ b/src/tint/transform/decompose_memory_access.cc @@ -36,6 +36,7 @@ #include "src/tint/utils/block_allocator.h" #include "src/tint/utils/hash.h" #include "src/tint/utils/map.h" +#include "src/tint/utils/string_stream.h" using namespace tint::number_suffixes; // NOLINT @@ -695,7 +696,7 @@ DecomposeMemoryAccess::Intrinsic::Intrinsic(ProgramID pid, : Base(pid, nid), op(o), type(ty), address_space(as), buffer(buf) {} DecomposeMemoryAccess::Intrinsic::~Intrinsic() = default; std::string DecomposeMemoryAccess::Intrinsic::InternalName() const { - std::stringstream ss; + utils::StringStream ss; switch (op) { case Op::kLoad: ss << "intrinsic_load_"; diff --git a/src/tint/transform/direct_variable_access.cc b/src/tint/transform/direct_variable_access.cc index a6ef9d8f22..00d1e6733f 100644 --- a/src/tint/transform/direct_variable_access.cc +++ b/src/tint/transform/direct_variable_access.cc @@ -32,6 +32,7 @@ #include "src/tint/type/abstract_int.h" #include "src/tint/utils/reverse.h" #include "src/tint/utils/scoped_assignment.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::transform::DirectVariableAccess); TINT_INSTANTIATE_TYPEINFO(tint::transform::DirectVariableAccess::Config); @@ -687,7 +688,7 @@ struct DirectVariableAccess::State { // Build an appropriate variant function name. // This is derived from the original function name and the pointer parameter // chains. - std::stringstream ss; + utils::StringStream ss; ss << ctx.src->Symbols().NameFor(target->Declaration()->name->symbol); for (auto* param : target->Parameters()) { if (auto indices = target_signature.Find(param)) { @@ -1080,7 +1081,7 @@ struct DirectVariableAccess::State { /// @returns a name describing the given shape std::string AccessShapeName(const AccessShape& shape) { - std::stringstream ss; + utils::StringStream ss; if (IsPrivateOrFunction(shape.root.address_space)) { ss << "F"; diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc index ecc75763b2..09a68bb155 100644 --- a/src/tint/transform/vertex_pulling.cc +++ b/src/tint/transform/vertex_pulling.cc @@ -26,6 +26,7 @@ #include "src/tint/utils/compiler_macros.h" #include "src/tint/utils/map.h" #include "src/tint/utils/math.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::transform::VertexPulling); TINT_INSTANTIATE_TYPEINFO(tint::transform::VertexPulling::Config); @@ -59,7 +60,7 @@ enum class VertexDataType { /// @param out the std::ostream to write to /// @param format the VertexFormat to write /// @returns out so calls can be chained -std::ostream& operator<<(std::ostream& out, VertexFormat format) { +utils::StringStream& operator<<(utils::StringStream& out, VertexFormat format) { switch (format) { case VertexFormat::kUint8x2: return out << "uint8x2"; @@ -379,7 +380,7 @@ struct VertexPulling::State { // Base types must match between the vertex stream and the WGSL variable if (!IsTypeCompatible(var_dt, fmt_dt)) { - std::stringstream err; + utils::StringStream err; err << "VertexAttributeDescriptor for location " << std::to_string(attribute_desc.shader_location) << " has format " << attribute_desc.format << " but shader expects " diff --git a/src/tint/type/array.cc b/src/tint/type/array.cc index dedf986aa1..96c745c8cf 100644 --- a/src/tint/type/array.cc +++ b/src/tint/type/array.cc @@ -21,6 +21,7 @@ #include "src/tint/type/manager.h" #include "src/tint/type/texture_dimension.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::Array); @@ -81,7 +82,7 @@ bool Array::Equals(const UniqueNode& other) const { } std::string Array::FriendlyName(const SymbolTable& symbols) const { - std::ostringstream out; + utils::StringStream out; if (!IsStrideImplicit()) { out << "@stride(" << stride_ << ") "; } diff --git a/src/tint/type/atomic.cc b/src/tint/type/atomic.cc index 045939476b..39e2aaee16 100644 --- a/src/tint/type/atomic.cc +++ b/src/tint/type/atomic.cc @@ -19,6 +19,7 @@ #include "src/tint/type/manager.h" #include "src/tint/type/reference.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::Atomic); @@ -42,7 +43,7 @@ bool Atomic::Equals(const type::UniqueNode& other) const { } std::string Atomic::FriendlyName(const SymbolTable& symbols) const { - std::ostringstream out; + utils::StringStream out; out << "atomic<" << subtype_->FriendlyName(symbols) << ">"; return out.str(); } diff --git a/src/tint/type/depth_multisampled_texture.cc b/src/tint/type/depth_multisampled_texture.cc index 84d7c321db..fc3b753de3 100644 --- a/src/tint/type/depth_multisampled_texture.cc +++ b/src/tint/type/depth_multisampled_texture.cc @@ -19,6 +19,7 @@ #include "src/tint/type/manager.h" #include "src/tint/type/texture_dimension.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::DepthMultisampledTexture); @@ -46,7 +47,7 @@ bool DepthMultisampledTexture::Equals(const UniqueNode& other) const { } std::string DepthMultisampledTexture::FriendlyName(const SymbolTable&) const { - std::ostringstream out; + utils::StringStream out; out << "texture_depth_multisampled_" << dim(); return out.str(); } diff --git a/src/tint/type/depth_texture.cc b/src/tint/type/depth_texture.cc index ca216e7389..90a612734c 100644 --- a/src/tint/type/depth_texture.cc +++ b/src/tint/type/depth_texture.cc @@ -19,6 +19,7 @@ #include "src/tint/type/manager.h" #include "src/tint/type/texture_dimension.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::DepthTexture); @@ -47,7 +48,7 @@ bool DepthTexture::Equals(const UniqueNode& other) const { } std::string DepthTexture::FriendlyName(const SymbolTable&) const { - std::ostringstream out; + utils::StringStream out; out << "texture_depth_" << dim(); return out.str(); } diff --git a/src/tint/type/matrix.cc b/src/tint/type/matrix.cc index 76970e6208..195a9e9da0 100644 --- a/src/tint/type/matrix.cc +++ b/src/tint/type/matrix.cc @@ -19,6 +19,7 @@ #include "src/tint/type/manager.h" #include "src/tint/type/vector.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::Matrix); @@ -51,7 +52,7 @@ bool Matrix::Equals(const UniqueNode& other) const { } std::string Matrix::FriendlyName(const SymbolTable& symbols) const { - std::ostringstream out; + utils::StringStream out; out << "mat" << columns_ << "x" << rows_ << "<" << subtype_->FriendlyName(symbols) << ">"; return out.str(); } diff --git a/src/tint/type/multisampled_texture.cc b/src/tint/type/multisampled_texture.cc index 182ae88af1..0b2dfd0b63 100644 --- a/src/tint/type/multisampled_texture.cc +++ b/src/tint/type/multisampled_texture.cc @@ -19,6 +19,7 @@ #include "src/tint/type/manager.h" #include "src/tint/type/texture_dimension.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::MultisampledTexture); @@ -40,7 +41,7 @@ bool MultisampledTexture::Equals(const UniqueNode& other) const { } std::string MultisampledTexture::FriendlyName(const SymbolTable& symbols) const { - std::ostringstream out; + utils::StringStream out; out << "texture_multisampled_" << dim() << "<" << type_->FriendlyName(symbols) << ">"; return out.str(); } diff --git a/src/tint/type/pointer.cc b/src/tint/type/pointer.cc index 17bbe1a33c..aa77816832 100644 --- a/src/tint/type/pointer.cc +++ b/src/tint/type/pointer.cc @@ -19,6 +19,7 @@ #include "src/tint/type/manager.h" #include "src/tint/type/reference.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::Pointer); @@ -43,7 +44,7 @@ bool Pointer::Equals(const UniqueNode& other) const { } std::string Pointer::FriendlyName(const SymbolTable& symbols) const { - std::ostringstream out; + utils::StringStream out; out << "ptr<"; if (address_space_ != builtin::AddressSpace::kUndefined) { out << address_space_ << ", "; diff --git a/src/tint/type/reference.cc b/src/tint/type/reference.cc index 5db6300512..03ed224576 100644 --- a/src/tint/type/reference.cc +++ b/src/tint/type/reference.cc @@ -18,6 +18,7 @@ #include "src/tint/diagnostic/diagnostic.h" #include "src/tint/type/manager.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::Reference); @@ -44,7 +45,7 @@ bool Reference::Equals(const UniqueNode& other) const { } std::string Reference::FriendlyName(const SymbolTable& symbols) const { - std::ostringstream out; + utils::StringStream out; out << "ref<"; if (address_space_ != builtin::AddressSpace::kUndefined) { out << address_space_ << ", "; diff --git a/src/tint/type/sampled_texture.cc b/src/tint/type/sampled_texture.cc index b3e737500f..b3e6e1061f 100644 --- a/src/tint/type/sampled_texture.cc +++ b/src/tint/type/sampled_texture.cc @@ -19,6 +19,7 @@ #include "src/tint/type/manager.h" #include "src/tint/type/texture_dimension.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::SampledTexture); @@ -39,7 +40,7 @@ bool SampledTexture::Equals(const UniqueNode& other) const { } std::string SampledTexture::FriendlyName(const SymbolTable& symbols) const { - std::ostringstream out; + utils::StringStream out; out << "texture_" << dim() << "<" << type_->FriendlyName(symbols) << ">"; return out.str(); } diff --git a/src/tint/type/storage_texture.cc b/src/tint/type/storage_texture.cc index beb5da6a5d..180db4f9f3 100644 --- a/src/tint/type/storage_texture.cc +++ b/src/tint/type/storage_texture.cc @@ -19,6 +19,7 @@ #include "src/tint/type/manager.h" #include "src/tint/type/u32.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::StorageTexture); @@ -43,7 +44,7 @@ bool StorageTexture::Equals(const UniqueNode& other) const { } std::string StorageTexture::FriendlyName(const SymbolTable&) const { - std::ostringstream out; + utils::StringStream out; out << "texture_storage_" << dim() << "<" << texel_format_ << ", " << access_ << ">"; return out.str(); } diff --git a/src/tint/type/struct.cc b/src/tint/type/struct.cc index c39916b605..7649691288 100644 --- a/src/tint/type/struct.cc +++ b/src/tint/type/struct.cc @@ -22,6 +22,7 @@ #include "src/tint/symbol_table.h" #include "src/tint/type/manager.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::Struct); TINT_INSTANTIATE_TYPEINFO(tint::type::StructMember); @@ -96,7 +97,7 @@ std::string Struct::FriendlyName(const SymbolTable& symbols) const { } std::string Struct::Layout(const tint::SymbolTable& symbols) const { - std::stringstream ss; + utils::StringStream ss; auto member_name_of = [&](const StructMember* sm) { return symbols.NameFor(sm->Name()); }; diff --git a/src/tint/type/vector.cc b/src/tint/type/vector.cc index 6db1465811..9f1f415bf2 100644 --- a/src/tint/type/vector.cc +++ b/src/tint/type/vector.cc @@ -18,6 +18,7 @@ #include "src/tint/diagnostic/diagnostic.h" #include "src/tint/type/manager.h" #include "src/tint/utils/hash.h" +#include "src/tint/utils/string_stream.h" TINT_INSTANTIATE_TYPEINFO(tint::type::Vector); @@ -47,7 +48,7 @@ bool Vector::Equals(const UniqueNode& other) const { } std::string Vector::FriendlyName(const SymbolTable& symbols) const { - std::ostringstream out; + utils::StringStream out; if (packed_) { out << "__packed_"; } diff --git a/src/tint/utils/enum_set_test.cc b/src/tint/utils/enum_set_test.cc index 4cdeb63440..a6bb169cf7 100644 --- a/src/tint/utils/enum_set_test.cc +++ b/src/tint/utils/enum_set_test.cc @@ -18,6 +18,7 @@ #include #include "gmock/gmock.h" +#include "src/tint/utils/string_stream.h" namespace tint::utils { namespace { @@ -232,7 +233,7 @@ TEST(EnumSetTest, Loop) { } TEST(EnumSetTest, Ostream) { - std::stringstream ss; + utils::StringStream ss; ss << EnumSet(E::A, E::C); EXPECT_EQ(ss.str(), "{A, C}"); } diff --git a/src/tint/utils/io/command_windows.cc b/src/tint/utils/io/command_windows.cc index abe724291c..31d03085bf 100644 --- a/src/tint/utils/io/command_windows.cc +++ b/src/tint/utils/io/command_windows.cc @@ -21,6 +21,7 @@ #include #include "src/tint/utils/defer.h" +#include "src/tint/utils/string_stream.h" namespace tint::utils { @@ -197,7 +198,7 @@ Command::Output Command::Exec(std::initializer_list arguments) cons si.hStdError = stderr_pipe.write; si.hStdInput = stdin_pipe.read; - std::stringstream args; + utils::StringStream args; args << path_; for (auto& arg : arguments) { if (!arg.empty()) { diff --git a/src/tint/utils/io/tmpfile.h b/src/tint/utils/io/tmpfile.h index 24e72086c2..7949a371d9 100644 --- a/src/tint/utils/io/tmpfile.h +++ b/src/tint/utils/io/tmpfile.h @@ -18,6 +18,8 @@ #include #include +#include "src/tint/utils/string_stream.h" + namespace tint::utils { /// TmpFile constructs a temporary file that can be written to, and is @@ -55,7 +57,7 @@ class TmpFile { /// @return a reference to this TmpFile template inline TmpFile& operator<<(T&& data) { - std::stringstream ss; + utils::StringStream ss; ss << data; std::string str = ss.str(); Append(str.data(), str.size()); diff --git a/src/tint/utils/string.h b/src/tint/utils/string.h index 9bf6e7a5b0..e77e637230 100644 --- a/src/tint/utils/string.h +++ b/src/tint/utils/string.h @@ -43,7 +43,7 @@ namespace tint::utils { /// @returns value printed as a string via the std::ostream `<<` operator template std::string ToString(const T& value) { - std::stringstream s; + utils::StringStream s; s << value; return s.str(); } @@ -52,7 +52,7 @@ std::string ToString(const T& value) { /// @returns value printed as a string via the std::ostream `<<` operator template std::string ToString(const std::variant& value) { - std::stringstream s; + utils::StringStream s; s << std::visit([&](auto& v) { return ToString(v); }, value); return s.str(); } diff --git a/src/tint/utils/string_stream.h b/src/tint/utils/string_stream.h index 6cb6efcd3b..893d2b9cc8 100644 --- a/src/tint/utils/string_stream.h +++ b/src/tint/utils/string_stream.h @@ -16,9 +16,11 @@ #define SRC_TINT_UTILS_STRING_STREAM_H_ #include +#include #include #include #include +#include namespace tint::utils { @@ -89,6 +91,15 @@ class StringStream { return *this; } + /// Swaps streams + /// @param other stream to swap too + void swap(StringStream& other) { sstream_.swap(other.sstream_); } + + /// repeat queues the character c to be written to the printer n times. + /// @param c the character to print `n` times + /// @param n the number of times to print character `c` + void repeat(char c, size_t n) { std::fill_n(std::ostream_iterator(sstream_), n, c); } + /// The callback to emit a `endl` to the stream using StdEndl = std::ostream& (*)(std::ostream&); diff --git a/src/tint/utils/vector_test.cc b/src/tint/utils/vector_test.cc index 6245476053..06047326f4 100644 --- a/src/tint/utils/vector_test.cc +++ b/src/tint/utils/vector_test.cc @@ -20,6 +20,7 @@ #include "gmock/gmock.h" #include "src/tint/utils/bitcast.h" +#include "src/tint/utils/string_stream.h" namespace tint::utils { namespace { @@ -1788,7 +1789,7 @@ TEST(TintVectorTest, Equality) { } TEST(TintVectorTest, ostream) { - std::stringstream ss; + utils::StringStream ss; ss << Vector{1, 2, 3}; EXPECT_EQ(ss.str(), "[1, 2, 3]"); } @@ -2065,7 +2066,7 @@ TEST(TintVectorRefTest, BeginEnd) { } TEST(TintVectorRefTest, ostream) { - std::stringstream ss; + utils::StringStream ss; Vector vec{1, 2, 3}; const VectorRef vec_ref(vec); ss << vec_ref;