[NFC][sanitizer] Iterator adaptors for Leb128 encoding

It's similar to back_insert_iterator

Needed for D114924

Reviewed By: morehouse, kstoimenov

Differential Revision: https://reviews.llvm.org/D114980

GitOrigin-RevId: 5f1d1854eb1450d352663ee732235893c5782237
diff --git a/lib/sanitizer_common/sanitizer_stack_store.cpp b/lib/sanitizer_common/sanitizer_stack_store.cpp
index d371a4f..416e3b8 100644
--- a/lib/sanitizer_common/sanitizer_stack_store.cpp
+++ b/lib/sanitizer_common/sanitizer_stack_store.cpp
@@ -130,26 +130,76 @@
   return Create();
 }
 
+class SLeb128Encoder {
+ public:
+  SLeb128Encoder(u8 *begin, u8 *end) : begin(begin), end(end) {}
+
+  bool operator==(const SLeb128Encoder &other) const {
+    return begin == other.begin;
+  }
+
+  bool operator!=(const SLeb128Encoder &other) const {
+    return begin != other.begin;
+  }
+
+  SLeb128Encoder &operator=(uptr v) {
+    sptr diff = v - previous;
+    begin = EncodeSLEB128(diff, begin, end);
+    previous = v;
+    return *this;
+  }
+  SLeb128Encoder &operator*() { return *this; }
+  SLeb128Encoder &operator++() { return *this; }
+
+  u8 *base() const { return begin; }
+
+ private:
+  u8 *begin;
+  u8 *end;
+  uptr previous = 0;
+};
+
+class SLeb128Decoder {
+ public:
+  SLeb128Decoder(const u8 *begin, const u8 *end) : begin(begin), end(end) {}
+
+  bool operator==(const SLeb128Decoder &other) const {
+    return begin == other.begin;
+  }
+
+  bool operator!=(const SLeb128Decoder &other) const {
+    return begin != other.begin;
+  }
+
+  uptr operator*() {
+    sptr diff;
+    begin = DecodeSLEB128(begin, end, &diff);
+    previous += diff;
+    return previous;
+  }
+  SLeb128Decoder &operator++() { return *this; }
+
+  SLeb128Decoder operator++(int) { return *this; }
+
+ private:
+  const u8 *begin;
+  const u8 *end;
+  uptr previous = 0;
+};
+
 static u8 *CompressDelta(const uptr *from, const uptr *from_end, u8 *to,
                          u8 *to_end) {
-  uptr prev = 0;
-  for (; from < from_end; ++from) {
-    sptr diff = *from - prev;
-    to = EncodeSLEB128(diff, to, to_end);
-    prev += diff;
-  }
-  return to;
+  SLeb128Encoder encoder(to, to_end);
+  for (; from != from_end; ++from, ++encoder) *encoder = *from;
+  return encoder.base();
 }
 
 static uptr *UncompressDelta(const u8 *from, const u8 *from_end, uptr *to,
                              uptr *to_end) {
-  uptr prev = 0;
-  for (; to < to_end; ++to) {
-    sptr diff;
-    from = DecodeSLEB128<sptr>(from, from_end, &diff);
-    prev += diff;
-    *to = prev;
-  }
+  SLeb128Decoder decoder(from, from_end);
+  SLeb128Decoder end(from_end, from_end);
+  for (; decoder != end; ++to, ++decoder) *to = *decoder;
+  CHECK_EQ(to, to_end);
   return to;
 }