File indexing completed on 2026-05-10 08:43:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef DEMANGLE_UTILITY_H
0017 #define DEMANGLE_UTILITY_H
0018
0019 #include "DemangleConfig.h"
0020
0021 #include <array>
0022 #include <cstdint>
0023 #include <cstdlib>
0024 #include <cstring>
0025 #include <limits>
0026 #include <string_view>
0027
0028 DEMANGLE_NAMESPACE_BEGIN
0029
0030
0031
0032 class OutputBuffer {
0033 char *Buffer = nullptr;
0034 size_t CurrentPosition = 0;
0035 size_t BufferCapacity = 0;
0036
0037
0038 void grow(size_t N) {
0039 size_t Need = N + CurrentPosition;
0040 if (Need > BufferCapacity) {
0041
0042
0043
0044 Need += 1024 - 32;
0045 BufferCapacity *= 2;
0046 if (BufferCapacity < Need)
0047 BufferCapacity = Need;
0048 Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
0049 if (Buffer == nullptr)
0050 std::abort();
0051 }
0052 }
0053
0054 OutputBuffer &writeUnsigned(uint64_t N, bool isNeg = false) {
0055 std::array<char, 21> Temp;
0056 char *TempPtr = Temp.data() + Temp.size();
0057
0058
0059 do {
0060 *--TempPtr = char('0' + N % 10);
0061 N /= 10;
0062 } while (N);
0063
0064
0065 if (isNeg)
0066 *--TempPtr = '-';
0067
0068 return operator+=(
0069 std::string_view(TempPtr, Temp.data() + Temp.size() - TempPtr));
0070 }
0071
0072 public:
0073 OutputBuffer(char *StartBuf, size_t Size)
0074 : Buffer(StartBuf), BufferCapacity(Size) {}
0075 OutputBuffer(char *StartBuf, size_t *SizePtr)
0076 : OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {}
0077 OutputBuffer() = default;
0078
0079 OutputBuffer(const OutputBuffer &) = delete;
0080 OutputBuffer &operator=(const OutputBuffer &) = delete;
0081
0082 operator std::string_view() const {
0083 return std::string_view(Buffer, CurrentPosition);
0084 }
0085
0086
0087
0088 unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
0089 unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
0090
0091
0092
0093 unsigned GtIsGt = 1;
0094
0095 bool isGtInsideTemplateArgs() const { return GtIsGt == 0; }
0096
0097 void printOpen(char Open = '(') {
0098 GtIsGt++;
0099 *this += Open;
0100 }
0101 void printClose(char Close = ')') {
0102 GtIsGt--;
0103 *this += Close;
0104 }
0105
0106 OutputBuffer &operator+=(std::string_view R) {
0107 if (size_t Size = R.size()) {
0108 grow(Size);
0109 std::memcpy(Buffer + CurrentPosition, &*R.begin(), Size);
0110 CurrentPosition += Size;
0111 }
0112 return *this;
0113 }
0114
0115 OutputBuffer &operator+=(char C) {
0116 grow(1);
0117 Buffer[CurrentPosition++] = C;
0118 return *this;
0119 }
0120
0121 OutputBuffer &prepend(std::string_view R) {
0122 size_t Size = R.size();
0123
0124 grow(Size);
0125 std::memmove(Buffer + Size, Buffer, CurrentPosition);
0126 std::memcpy(Buffer, &*R.begin(), Size);
0127 CurrentPosition += Size;
0128
0129 return *this;
0130 }
0131
0132 OutputBuffer &operator<<(std::string_view R) { return (*this += R); }
0133
0134 OutputBuffer &operator<<(char C) { return (*this += C); }
0135
0136 OutputBuffer &operator<<(long long N) {
0137 return writeUnsigned(static_cast<unsigned long long>(std::abs(N)), N < 0);
0138 }
0139
0140 OutputBuffer &operator<<(unsigned long long N) {
0141 return writeUnsigned(N, false);
0142 }
0143
0144 OutputBuffer &operator<<(long N) {
0145 return this->operator<<(static_cast<long long>(N));
0146 }
0147
0148 OutputBuffer &operator<<(unsigned long N) {
0149 return this->operator<<(static_cast<unsigned long long>(N));
0150 }
0151
0152 OutputBuffer &operator<<(int N) {
0153 return this->operator<<(static_cast<long long>(N));
0154 }
0155
0156 OutputBuffer &operator<<(unsigned int N) {
0157 return this->operator<<(static_cast<unsigned long long>(N));
0158 }
0159
0160 void insert(size_t Pos, const char *S, size_t N) {
0161 DEMANGLE_ASSERT(Pos <= CurrentPosition, "");
0162 if (N == 0)
0163 return;
0164 grow(N);
0165 std::memmove(Buffer + Pos + N, Buffer + Pos, CurrentPosition - Pos);
0166 std::memcpy(Buffer + Pos, S, N);
0167 CurrentPosition += N;
0168 }
0169
0170 size_t getCurrentPosition() const { return CurrentPosition; }
0171 void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
0172
0173 char back() const {
0174 DEMANGLE_ASSERT(CurrentPosition, "");
0175 return Buffer[CurrentPosition - 1];
0176 }
0177
0178 bool empty() const { return CurrentPosition == 0; }
0179
0180 char *getBuffer() { return Buffer; }
0181 char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
0182 size_t getBufferCapacity() const { return BufferCapacity; }
0183 };
0184
0185 template <class T> class ScopedOverride {
0186 T &Loc;
0187 T Original;
0188
0189 public:
0190 ScopedOverride(T &Loc_) : ScopedOverride(Loc_, Loc_) {}
0191
0192 ScopedOverride(T &Loc_, T NewVal) : Loc(Loc_), Original(Loc_) {
0193 Loc_ = std::move(NewVal);
0194 }
0195 ~ScopedOverride() { Loc = std::move(Original); }
0196
0197 ScopedOverride(const ScopedOverride &) = delete;
0198 ScopedOverride &operator=(const ScopedOverride &) = delete;
0199 };
0200
0201 DEMANGLE_NAMESPACE_END
0202
0203 #endif