|
| 1 | +//===- InterleavedRange.h - Output stream formatting for ranges -----------===// |
| 2 | +// |
| 3 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | +// See https://llvm.org/LICENSE.txt for license information. |
| 5 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | +// |
| 7 | +//===----------------------------------------------------------------------===// |
| 8 | +// |
| 9 | +// Implements format objects for printing ranges to output streams. |
| 10 | +// For example: |
| 11 | +// ```c++ |
| 12 | +// ArrayRef<Type> Types = ...; |
| 13 | +// OS << "Types: " << interleaved(Types); // ==> "Types: i32, f16, i8" |
| 14 | +// ArrayRef<int> Values = ...; |
| 15 | +// OS << "Values: " << interleaved_array(Values); // ==> "Values: [1, 2, 3]" |
| 16 | +// ``` |
| 17 | +// |
| 18 | +//===----------------------------------------------------------------------===// |
| 19 | + |
| 20 | +#ifndef LLVM_SUPPORT_INTERLEAVED_RANGE_H |
| 21 | +#define LLVM_SUPPORT_INTERLEAVED_RANGE_H |
| 22 | + |
| 23 | +#include "llvm/ADT/STLExtras.h" |
| 24 | +#include "llvm/ADT/StringRef.h" |
| 25 | +#include "llvm/Support/raw_ostream.h" |
| 26 | + |
| 27 | +namespace llvm { |
| 28 | + |
| 29 | +/// Format object class for interleaved ranges. Supports specifying the |
| 30 | +/// separator and, optionally, the prefix and suffix to be printed surrounding |
| 31 | +/// the range. |
| 32 | +/// Uses the operator '<<' of the range element type for printing. The range |
| 33 | +/// type itself does not have to have an '<<' operator defined. |
| 34 | +template <typename Range> class InterleavedRange { |
| 35 | + const Range &TheRange; |
| 36 | + StringRef Separator; |
| 37 | + StringRef Prefix; |
| 38 | + StringRef Suffix; |
| 39 | + |
| 40 | +public: |
| 41 | + InterleavedRange(const Range &R, StringRef Separator, StringRef Prefix, |
| 42 | + StringRef Suffix) |
| 43 | + : TheRange(R), Separator(Separator), Prefix(Prefix), Suffix(Suffix) {} |
| 44 | + |
| 45 | + friend raw_ostream &operator<<(raw_ostream &OS, |
| 46 | + const InterleavedRange &Interleaved) { |
| 47 | + if (!Interleaved.Prefix.empty()) |
| 48 | + OS << Interleaved.Prefix; |
| 49 | + llvm::interleave(Interleaved.TheRange, OS, Interleaved.Separator); |
| 50 | + if (!Interleaved.Suffix.empty()) |
| 51 | + OS << Interleaved.Suffix; |
| 52 | + return OS; |
| 53 | + } |
| 54 | + |
| 55 | + std::string str() const { |
| 56 | + std::string Result; |
| 57 | + raw_string_ostream Stream(Result); |
| 58 | + Stream << *this; |
| 59 | + Stream.flush(); |
| 60 | + return Result; |
| 61 | + } |
| 62 | + |
| 63 | + operator std::string() const { return str(); } |
| 64 | +}; |
| 65 | + |
| 66 | +/// Output range `R` as a sequence of interleaved elements. Requires the range |
| 67 | +/// element type to be printable using `raw_ostream& operator<<`. The |
| 68 | +/// `Separator` and `Prefix` / `Suffix` can be customized. Examples: |
| 69 | +/// ```c++ |
| 70 | +/// SmallVector<int> Vals = {1, 2, 3}; |
| 71 | +/// OS << interleaved(Vals); // ==> "1, 2, 3" |
| 72 | +/// OS << interleaved(Vals, ";"); // ==> "1;2;3" |
| 73 | +/// OS << interleaved(Vals, " ", "{", "}"); // ==> "{1 2 3}" |
| 74 | +/// ``` |
| 75 | +template <typename Range> |
| 76 | +InterleavedRange<Range> interleaved(const Range &R, StringRef Separator = ", ", |
| 77 | + StringRef Prefix = "", |
| 78 | + StringRef Suffix = "") { |
| 79 | + return {R, Separator, Prefix, Suffix}; |
| 80 | +} |
| 81 | + |
| 82 | +/// Output range `R` as an array of interleaved elements. Requires the range |
| 83 | +/// element type to be printable using `raw_ostream& operator<<`. The |
| 84 | +/// `Separator` can be customized. Examples: |
| 85 | +/// ```c++ |
| 86 | +/// SmallVector<int> Vals = {1, 2, 3}; |
| 87 | +/// OS << interleaved_array(Vals); // ==> "[1, 2, 3]" |
| 88 | +/// OS << interleaved_array(Vals, ";"); // ==> "[1;2;3]" |
| 89 | +/// OS << interleaved_array(Vals, " "); // ==> "[1 2 3]" |
| 90 | +/// ``` |
| 91 | +template <typename Range> |
| 92 | +InterleavedRange<Range> interleaved_array(const Range &R, |
| 93 | + StringRef Separator = ", ") { |
| 94 | + return {R, Separator, "[", "]"}; |
| 95 | +} |
| 96 | + |
| 97 | +} // end namespace llvm |
| 98 | + |
| 99 | +#endif // LLVM_SUPPORT_INTERLEAVED_RANGE_H |
0 commit comments