From b07c88563febdb62b82daad0480d7b6131bc54d4 Mon Sep 17 00:00:00 2001 From: Jakub Kuderski Date: Tue, 15 Apr 2025 23:44:33 -0400 Subject: [Support] Add format object for interleaved ranges (#135517) Add two new format functions for printing ranges: `interleaved` and `interleaved_array`. This is meant to improve the ergonomics of printing ranges. Before this patch, we have to either use `llvm::interleave` or write a for loop by hand. For example: Before: ```c++ ArrayRef types = ...; ArrayRef values = ...; LLVM_DEBUG({ llvm::dbgs() << "Types: "; llvm::interleave_comma(llvm::dbgs(), types); llvm::dbgs() << "\n"; llvm::dbgs() << "Values: ["; llvm::interleave_comma(llvm::dbgs(), values); llvm::dbgs() << "]\n"; }): ``` After: ```c++ ArrayRef types = ...; ArrayRef values = ...; LLVM_DEBUG(llvm::dbgs() << "Types: " << interleaved(types) << "\n"); LLVM_DEBUG(llvm::dbgs() << "Values: " << interleaved_array(values) << "\n"); ``` The separator and the prefix/suffix strings are customizable. --- llvm/unittests/Support/InterleavedRangeTest.cpp | 70 +++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 llvm/unittests/Support/InterleavedRangeTest.cpp (limited to 'llvm/unittests/Support/InterleavedRangeTest.cpp') diff --git a/llvm/unittests/Support/InterleavedRangeTest.cpp b/llvm/unittests/Support/InterleavedRangeTest.cpp new file mode 100644 index 0000000..8640b81 --- /dev/null +++ b/llvm/unittests/Support/InterleavedRangeTest.cpp @@ -0,0 +1,70 @@ +//===- InterleavedRangeTest.cpp - Unit tests for interleaved format -------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/InterleavedRange.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/raw_ostream.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +TEST(InterleavedRangeTest, VectorInt) { + SmallVector V = {0, 1, 2, 3}; + + // First, make sure that the raw print API works as expected. + std::string Buff; + raw_string_ostream OS(Buff); + OS << interleaved(V); + EXPECT_EQ("0, 1, 2, 3", Buff); + Buff.clear(); + OS << interleaved_array(V); + EXPECT_EQ("[0, 1, 2, 3]", Buff); + + // In the rest of the tests, use `.str()` for convenience. + EXPECT_EQ("0, 1, 2, 3", interleaved(V).str()); + EXPECT_EQ("{{0,1,2,3}}", interleaved(V, ",", "{{", "}}").str()); + EXPECT_EQ("[0, 1, 2, 3]", interleaved_array(V).str()); + EXPECT_EQ("[0;1;2;3]", interleaved_array(V, ";").str()); + EXPECT_EQ("0;1;2;3", interleaved(V, ";").str()); +} + +TEST(InterleavedRangeTest, VectorIntEmpty) { + SmallVector V = {}; + EXPECT_EQ("", interleaved(V).str()); + EXPECT_EQ("{{}}", interleaved(V, ",", "{{", "}}").str()); + EXPECT_EQ("[]", interleaved_array(V).str()); + EXPECT_EQ("", interleaved(V, ";").str()); +} + +TEST(InterleavedRangeTest, VectorIntOneElem) { + SmallVector V = {42}; + EXPECT_EQ("42", interleaved(V).str()); + EXPECT_EQ("{{42}}", interleaved(V, ",", "{{", "}}").str()); + EXPECT_EQ("[42]", interleaved_array(V).str()); + EXPECT_EQ("42", interleaved(V, ";").str()); +} + +struct CustomPrint { + int N; + friend raw_ostream &operator<<(raw_ostream &OS, const CustomPrint &CP) { + OS << "$$" << CP.N << "##"; + return OS; + } +}; + +TEST(InterleavedRangeTest, CustomPrint) { + CustomPrint V[] = {{3}, {4}, {5}}; + EXPECT_EQ("$$3##, $$4##, $$5##", interleaved(V).str()); + EXPECT_EQ("{{$$3##;$$4##;$$5##}}", interleaved(V, ";", "{{", "}}").str()); + EXPECT_EQ("[$$3##, $$4##, $$5##]", interleaved_array(V).str()); +} + +} // namespace -- cgit v1.1