[libc-commits] [libc] [libc][NFC] Remove template arguments from Block (PR #117386)

Daniel Thornburgh via libc-commits libc-commits at lists.llvm.org
Fri Nov 22 13:40:41 PST 2024


https://github.com/mysterymath created https://github.com/llvm/llvm-project/pull/117386

None

>From e20170e04e8587aeb9afb809a491f9d7c202f427 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Fri, 22 Nov 2024 11:53:03 -0800
Subject: [PATCH] [libc][NFC] Remove template arguments from Block

---
 libc/src/__support/block.h                    | 155 +++-----
 libc/src/__support/freelist.cpp               |   2 +-
 libc/src/__support/freelist.h                 |  10 +-
 libc/src/__support/freelist_heap.h            |  24 +-
 libc/src/__support/freestore.h                |  28 +-
 libc/src/__support/freetrie.h                 |   4 +-
 libc/test/src/__support/block_test.cpp        | 344 ++++++++----------
 .../test/src/__support/freelist_heap_test.cpp |  12 +-
 .../src/__support/freelist_malloc_test.cpp    |   8 +-
 libc/test/src/__support/freelist_test.cpp     |   6 +-
 libc/test/src/__support/freestore_test.cpp    |  40 +-
 libc/test/src/__support/freetrie_test.cpp     |  32 +-
 12 files changed, 293 insertions(+), 372 deletions(-)

diff --git a/libc/src/__support/block.h b/libc/src/__support/block.h
index e63801301ac752..9ca3f11530c4ba 100644
--- a/libc/src/__support/block.h
+++ b/libc/src/__support/block.h
@@ -68,13 +68,11 @@ using cpp::optional;
 /// The blocks store their offsets to the previous and next blocks. The latter
 /// is also the block's size.
 ///
-/// The `ALIGNMENT` constant provided by the derived block is typically the
-/// minimum value of `alignof(OffsetType)`. Blocks will always be aligned to a
-/// `ALIGNMENT` boundary. Block sizes will always be rounded up to a multiple of
-/// `ALIGNMENT`.
+/// Blocks will always be aligned to a `ALIGNMENT` boundary. Block sizes will
+/// always be rounded up to a multiple of `ALIGNMENT`.
 ///
-/// As an example, the diagram below represents two contiguous
-/// `Block<uint32_t, 8>`s. The indices indicate byte offsets:
+/// As an example, the diagram below represents two contiguous `Block`s. The
+/// indices indicate byte offsets:
 ///
 /// @code{.unparsed}
 /// Block 1:
@@ -117,17 +115,6 @@ using cpp::optional;
 ///
 /// The next offset of a block matches the previous offset of its next block.
 /// The first block in a list is denoted by having a previous offset of `0`.
-///
-/// @tparam   OffsetType  Unsigned integral type used to encode offsets. Larger
-///                       types can address more memory, but consume greater
-///                       overhead.
-/// @tparam   kAlign      Sets the overall alignment for blocks. Minimum is
-///                       `alignof(OffsetType)`, but the default is max_align_t,
-///                       since the usable space will then already be
-///                       aligned to max_align_t if the size of OffsetType is no
-///                       less than half of max_align_t. Larger values cause
-///                       greater overhead.
-template <typename OffsetType = uintptr_t, size_t kAlign = alignof(max_align_t)>
 class Block {
   // Masks for the contents of the next_ field.
   static constexpr size_t PREV_FREE_MASK = 1 << 0;
@@ -135,12 +122,8 @@ class Block {
   static constexpr size_t SIZE_MASK = ~(PREV_FREE_MASK | LAST_MASK);
 
 public:
-  using offset_type = OffsetType;
-  static_assert(cpp::is_unsigned_v<offset_type>,
-                "offset type must be unsigned");
-  static constexpr size_t ALIGNMENT =
-      cpp::max(cpp::max(kAlign, alignof(offset_type)), size_t{4});
-  static constexpr size_t BLOCK_OVERHEAD = align_up(sizeof(Block), ALIGNMENT);
+  static constexpr size_t ALIGNMENT = cpp::max(alignof(max_align_t), size_t{4});
+  static const size_t BLOCK_OVERHEAD;
 
   // No copy or move.
   Block(const Block &other) = delete;
@@ -157,26 +140,26 @@ class Block {
   ///
   /// @warning  This method does not do any checking; passing a random
   ///           pointer will return a non-null pointer.
-  static Block *from_usable_space(void *usable_space) {
+  LIBC_INLINE static Block *from_usable_space(void *usable_space) {
     auto *bytes = reinterpret_cast<cpp::byte *>(usable_space);
     return reinterpret_cast<Block *>(bytes - BLOCK_OVERHEAD);
   }
-  static const Block *from_usable_space(const void *usable_space) {
+  LIBC_INLINE static const Block *from_usable_space(const void *usable_space) {
     const auto *bytes = reinterpret_cast<const cpp::byte *>(usable_space);
     return reinterpret_cast<const Block *>(bytes - BLOCK_OVERHEAD);
   }
 
   /// @returns The total size of the block in bytes, including the header.
-  size_t outer_size() const { return next_ & SIZE_MASK; }
+  LIBC_INLINE size_t outer_size() const { return next_ & SIZE_MASK; }
 
-  static size_t outer_size(size_t inner_size) {
+  LIBC_INLINE static size_t outer_size(size_t inner_size) {
     // The usable region includes the prev_ field of the next block.
     return inner_size - sizeof(prev_) + BLOCK_OVERHEAD;
   }
 
   /// @returns The number of usable bytes inside the block were it to be
   /// allocated.
-  size_t inner_size() const {
+  LIBC_INLINE size_t inner_size() const {
     if (!next())
       return 0;
     return inner_size(outer_size());
@@ -184,13 +167,13 @@ class Block {
 
   /// @returns The number of usable bytes inside a block with the given outer
   /// size were it to be allocated.
-  static size_t inner_size(size_t outer_size) {
+  LIBC_INLINE static size_t inner_size(size_t outer_size) {
     // The usable region includes the prev_ field of the next block.
     return inner_size_free(outer_size) + sizeof(prev_);
   }
 
   /// @returns The number of usable bytes inside the block if it remains free.
-  size_t inner_size_free() const {
+  LIBC_INLINE size_t inner_size_free() const {
     if (!next())
       return 0;
     return inner_size_free(outer_size());
@@ -198,20 +181,20 @@ class Block {
 
   /// @returns The number of usable bytes inside a block with the given outer
   /// size if it remains free.
-  static size_t inner_size_free(size_t outer_size) {
+  LIBC_INLINE static size_t inner_size_free(size_t outer_size) {
     return outer_size - BLOCK_OVERHEAD;
   }
 
   /// @returns A pointer to the usable space inside this block.
-  cpp::byte *usable_space() {
+  LIBC_INLINE cpp::byte *usable_space() {
     return reinterpret_cast<cpp::byte *>(this) + BLOCK_OVERHEAD;
   }
-  const cpp::byte *usable_space() const {
+  LIBC_INLINE const cpp::byte *usable_space() const {
     return reinterpret_cast<const cpp::byte *>(this) + BLOCK_OVERHEAD;
   }
 
   // @returns The region of memory the block manages, including the header.
-  ByteSpan region() {
+  LIBC_INLINE ByteSpan region() {
     return {reinterpret_cast<cpp::byte *>(this), outer_size()};
   }
 
@@ -229,42 +212,53 @@ class Block {
 
   /// @returns The block immediately after this one, or a null pointer if this
   /// is the last block.
-  Block *next() const;
+  LIBC_INLINE Block *next() const {
+    if (next_ & LAST_MASK)
+      return nullptr;
+    return reinterpret_cast<Block *>(reinterpret_cast<uintptr_t>(this) +
+                                     outer_size());
+  }
 
   /// @returns The free block immediately before this one, otherwise nullptr.
-  Block *prev_free() const;
+  LIBC_INLINE Block *prev_free() const {
+    if (!(next_ & PREV_FREE_MASK))
+      return nullptr;
+    return reinterpret_cast<Block *>(reinterpret_cast<uintptr_t>(this) - prev_);
+  }
 
   /// @returns Whether the block is unavailable for allocation.
-  bool used() const { return !next() || !next()->prev_free(); }
+  LIBC_INLINE bool used() const { return !next() || !next()->prev_free(); }
 
   /// Marks this block as in use.
-  void mark_used() {
+  LIBC_INLINE void mark_used() {
     LIBC_ASSERT(next() && "last block is always considered used");
     next()->next_ &= ~PREV_FREE_MASK;
   }
 
   /// Marks this block as free.
-  void mark_free() {
+  LIBC_INLINE void mark_free() {
     LIBC_ASSERT(next() && "last block is always considered used");
     next()->next_ |= PREV_FREE_MASK;
     // The next block's prev_ field becomes alive, as it is no longer part of
     // this block's used space.
-    *new (&next()->prev_) offset_type = outer_size();
+    *new (&next()->prev_) size_t = outer_size();
   }
 
   /// Marks this block as the last one in the chain. Makes next() return
   /// nullptr.
-  void mark_last() { next_ |= LAST_MASK; }
+  LIBC_INLINE void mark_last() { next_ |= LAST_MASK; }
 
-  constexpr Block(size_t outer_size);
+  LIBC_INLINE constexpr Block(size_t outer_size) : next_(outer_size) {
+    LIBC_ASSERT(outer_size % ALIGNMENT == 0 && "block sizes must be aligned");
+  }
 
-  bool is_usable_space_aligned(size_t alignment) const {
+  LIBC_INLINE bool is_usable_space_aligned(size_t alignment) const {
     return reinterpret_cast<uintptr_t>(usable_space()) % alignment == 0;
   }
 
   /// @returns The new inner size of this block that would give the usable
   /// space of the next block the given alignment.
-  size_t padding_for_alignment(size_t alignment) const {
+  LIBC_INLINE size_t padding_for_alignment(size_t alignment) const {
     if (is_usable_space_aligned(alignment))
       return 0;
 
@@ -322,7 +316,9 @@ class Block {
 private:
   /// Construct a block to represent a span of bytes. Overwrites only enough
   /// memory for the block header; the rest of the span is left alone.
-  static Block *as_block(ByteSpan bytes);
+  LIBC_INLINE static Block *as_block(ByteSpan bytes) {
+    return ::new (bytes.data()) Block(bytes.size());
+  }
 
   /// Like `split`, but assumes the caller has already checked to parameters to
   /// ensure the split will succeed.
@@ -332,11 +328,11 @@ class Block {
   /// block. This field is only alive when the previous block is free;
   /// otherwise, its memory is reused as part of the previous block's usable
   /// space.
-  offset_type prev_ = 0;
+  size_t prev_ = 0;
 
   /// Offset from this block to the next block. Valid even if this is the last
   /// block, since it equals the size of the block.
-  offset_type next_ = 0;
+  size_t next_ = 0;
 
   /// Information about the current state of the block is stored in the two low
   /// order bits of the next_ value. These are guaranteed free by a minimum
@@ -347,9 +343,10 @@ class Block {
   ///   previous block is free.
   /// * If the `last` flag is set, the block is the sentinel last block. It is
   ///   summarily considered used and has no next block.
-} __attribute__((packed, aligned(cpp::max(kAlign, size_t{4}))));
+} __attribute__((packed, aligned(cpp::max(alignof(max_align_t), size_t{4}))));
 
-// Public template method implementations.
+inline constexpr size_t Block::BLOCK_OVERHEAD =
+    align_up(sizeof(Block), ALIGNMENT);
 
 LIBC_INLINE ByteSpan get_aligned_subspan(ByteSpan bytes, size_t alignment) {
   if (bytes.data() == nullptr)
@@ -367,9 +364,8 @@ LIBC_INLINE ByteSpan get_aligned_subspan(ByteSpan bytes, size_t alignment) {
                        aligned_end - aligned_start);
 }
 
-template <typename OffsetType, size_t kAlign>
-optional<Block<OffsetType, kAlign> *>
-Block<OffsetType, kAlign>::init(ByteSpan region) {
+LIBC_INLINE
+optional<Block *> Block::init(ByteSpan region) {
   optional<ByteSpan> result = get_aligned_subspan(region, ALIGNMENT);
   if (!result)
     return {};
@@ -379,7 +375,7 @@ Block<OffsetType, kAlign>::init(ByteSpan region) {
   if (region.size() < 2 * BLOCK_OVERHEAD)
     return {};
 
-  if (cpp::numeric_limits<OffsetType>::max() < region.size())
+  if (cpp::numeric_limits<size_t>::max() < region.size())
     return {};
 
   Block *block = as_block(region.first(region.size() - BLOCK_OVERHEAD));
@@ -389,9 +385,8 @@ Block<OffsetType, kAlign>::init(ByteSpan region) {
   return block;
 }
 
-template <typename OffsetType, size_t kAlign>
-bool Block<OffsetType, kAlign>::can_allocate(size_t alignment,
-                                             size_t size) const {
+LIBC_INLINE
+bool Block::can_allocate(size_t alignment, size_t size) const {
   if (inner_size() < size)
     return false;
   if (is_usable_space_aligned(alignment))
@@ -406,10 +401,8 @@ bool Block<OffsetType, kAlign>::can_allocate(size_t alignment,
   return size <= aligned_inner_size;
 }
 
-template <typename OffsetType, size_t kAlign>
-typename Block<OffsetType, kAlign>::BlockInfo
-Block<OffsetType, kAlign>::allocate(Block *block, size_t alignment,
-                                    size_t size) {
+LIBC_INLINE
+Block::BlockInfo Block::allocate(Block *block, size_t alignment, size_t size) {
   LIBC_ASSERT(
       block->can_allocate(alignment, size) &&
       "Calls to this function for a given alignment and size should only be "
@@ -447,9 +440,8 @@ Block<OffsetType, kAlign>::allocate(Block *block, size_t alignment,
   return info;
 }
 
-template <typename OffsetType, size_t kAlign>
-optional<Block<OffsetType, kAlign> *>
-Block<OffsetType, kAlign>::split(size_t new_inner_size) {
+LIBC_INLINE
+optional<Block *> Block::split(size_t new_inner_size) {
   if (used())
     return {};
   // The prev_ field of the next block is always available, so there is a
@@ -469,9 +461,8 @@ Block<OffsetType, kAlign>::split(size_t new_inner_size) {
   return split_impl(new_inner_size);
 }
 
-template <typename OffsetType, size_t kAlign>
-Block<OffsetType, kAlign> *
-Block<OffsetType, kAlign>::split_impl(size_t new_inner_size) {
+LIBC_INLINE
+Block *Block::split_impl(size_t new_inner_size) {
   size_t outer_size1 = outer_size(new_inner_size);
   LIBC_ASSERT(outer_size1 % ALIGNMENT == 0 && "new size must be aligned");
   ByteSpan new_region = region().subspan(outer_size1);
@@ -484,8 +475,8 @@ Block<OffsetType, kAlign>::split_impl(size_t new_inner_size) {
   return new_block;
 }
 
-template <typename OffsetType, size_t kAlign>
-bool Block<OffsetType, kAlign>::merge_next() {
+LIBC_INLINE
+bool Block::merge_next() {
   if (used() || next()->used())
     return false;
   size_t new_size = outer_size() + next()->outer_size();
@@ -495,34 +486,6 @@ bool Block<OffsetType, kAlign>::merge_next() {
   return true;
 }
 
-template <typename OffsetType, size_t kAlign>
-Block<OffsetType, kAlign> *Block<OffsetType, kAlign>::next() const {
-  if (next_ & LAST_MASK)
-    return nullptr;
-  return reinterpret_cast<Block *>(reinterpret_cast<uintptr_t>(this) +
-                                   outer_size());
-}
-
-template <typename OffsetType, size_t kAlign>
-Block<OffsetType, kAlign> *Block<OffsetType, kAlign>::prev_free() const {
-  if (!(next_ & PREV_FREE_MASK))
-    return nullptr;
-  return reinterpret_cast<Block *>(reinterpret_cast<uintptr_t>(this) - prev_);
-}
-
-// Private template method implementations.
-
-template <typename OffsetType, size_t kAlign>
-constexpr Block<OffsetType, kAlign>::Block(size_t outer_size)
-    : next_(outer_size) {
-  LIBC_ASSERT(outer_size % ALIGNMENT == 0 && "block sizes must be aligned");
-}
-
-template <typename OffsetType, size_t kAlign>
-Block<OffsetType, kAlign> *Block<OffsetType, kAlign>::as_block(ByteSpan bytes) {
-  return ::new (bytes.data()) Block(bytes.size());
-}
-
 } // namespace LIBC_NAMESPACE_DECL
 
 #endif // LLVM_LIBC_SRC___SUPPORT_BLOCK_H
diff --git a/libc/src/__support/freelist.cpp b/libc/src/__support/freelist.cpp
index d3dd44895130cd..bfb90ae1c4db47 100644
--- a/libc/src/__support/freelist.cpp
+++ b/libc/src/__support/freelist.cpp
@@ -12,7 +12,7 @@ namespace LIBC_NAMESPACE_DECL {
 
 void FreeList::push(Node *node) {
   if (begin_) {
-    LIBC_ASSERT(Block<>::from_usable_space(node)->outer_size() ==
+    LIBC_ASSERT(Block::from_usable_space(node)->outer_size() ==
                     begin_->block()->outer_size() &&
                 "freelist entries must have the same size");
     // Since the list is circular, insert the node immediately before begin_.
diff --git a/libc/src/__support/freelist.h b/libc/src/__support/freelist.h
index eaeaeb013eeaec..c51f14fe57ae73 100644
--- a/libc/src/__support/freelist.h
+++ b/libc/src/__support/freelist.h
@@ -26,12 +26,12 @@ class FreeList {
   class Node {
   public:
     /// @returns The block containing this node.
-    LIBC_INLINE const Block<> *block() const {
-      return Block<>::from_usable_space(this);
+    LIBC_INLINE const Block *block() const {
+      return Block::from_usable_space(this);
     }
 
     /// @returns The block containing this node.
-    LIBC_INLINE Block<> *block() { return Block<>::from_usable_space(this); }
+    LIBC_INLINE Block *block() { return Block::from_usable_space(this); }
 
     /// @returns The inner size of blocks in the list containing this node.
     LIBC_INLINE size_t size() const { return block()->inner_size(); }
@@ -58,11 +58,11 @@ class FreeList {
   LIBC_INLINE Node *begin() { return begin_; }
 
   /// @returns The first block in the list.
-  LIBC_INLINE Block<> *front() { return begin_->block(); }
+  LIBC_INLINE Block *front() { return begin_->block(); }
 
   /// Push a block to the back of the list.
   /// The block must be large enough to contain a node.
-  LIBC_INLINE void push(Block<> *block) {
+  LIBC_INLINE void push(Block *block) {
     LIBC_ASSERT(!block->used() &&
                 "only free blocks can be placed on free lists");
     LIBC_ASSERT(block->inner_size_free() >= sizeof(FreeList) &&
diff --git a/libc/src/__support/freelist_heap.h b/libc/src/__support/freelist_heap.h
index cfcf72fc4c9859..8fa36257cb91ae 100644
--- a/libc/src/__support/freelist_heap.h
+++ b/libc/src/__support/freelist_heap.h
@@ -53,7 +53,7 @@ class FreeListHeap {
 
   void *allocate_impl(size_t alignment, size_t size);
 
-  span<cpp::byte> block_to_span(Block<> *block) {
+  span<cpp::byte> block_to_span(Block *block) {
     return span<cpp::byte>(block->usable_space(), block->inner_size());
   }
 
@@ -75,8 +75,8 @@ template <size_t BUFF_SIZE> class FreeListHeapBuffer : public FreeListHeap {
 
 LIBC_INLINE void FreeListHeap::init() {
   LIBC_ASSERT(!is_initialized && "duplicate initialization");
-  auto result = Block<>::init(region());
-  Block<> *block = *result;
+  auto result = Block::init(region());
+  Block *block = *result;
   free_store.set_range({0, cpp::bit_ceil(block->inner_size())});
   free_store.insert(block);
   is_initialized = true;
@@ -93,17 +93,17 @@ LIBC_INLINE void *FreeListHeap::allocate_impl(size_t alignment, size_t size) {
 
   // TODO: usable_space should always be aligned to max_align_t.
   if (alignment > alignof(max_align_t) ||
-      (Block<>::BLOCK_OVERHEAD % alignof(max_align_t) != 0)) {
+      (Block::BLOCK_OVERHEAD % alignof(max_align_t) != 0)) {
     // TODO: This bound isn't precisely calculated yet. It assumes one extra
-    // Block<>::ALIGNMENT to accomodate the possibility for padding block
+    // Block::ALIGNMENT to accomodate the possibility for padding block
     // overhead. (alignment - 1) ensures that there is an aligned point
     // somewhere in usable_space, but this isn't tight either, since
     // usable_space is also already somewhat aligned.
-    if (add_overflow(size, (alignment - 1) + Block<>::ALIGNMENT, request_size))
+    if (add_overflow(size, (alignment - 1) + Block::ALIGNMENT, request_size))
       return nullptr;
   }
 
-  Block<> *block = free_store.remove_best_fit(request_size);
+  Block *block = free_store.remove_best_fit(request_size);
   if (!block)
     return nullptr;
 
@@ -111,7 +111,7 @@ LIBC_INLINE void *FreeListHeap::allocate_impl(size_t alignment, size_t size) {
               "block should always be large enough to allocate at the correct "
               "alignment");
 
-  auto block_info = Block<>::allocate(block, alignment, size);
+  auto block_info = Block::allocate(block, alignment, size);
   if (block_info.next)
     free_store.insert(block_info.next);
   if (block_info.prev)
@@ -143,14 +143,14 @@ LIBC_INLINE void FreeListHeap::free(void *ptr) {
 
   LIBC_ASSERT(is_valid_ptr(bytes) && "Invalid pointer");
 
-  Block<> *block = Block<>::from_usable_space(bytes);
+  Block *block = Block::from_usable_space(bytes);
   LIBC_ASSERT(block->next() && "sentinel last block cannot be freed");
   LIBC_ASSERT(block->used() && "double free");
   block->mark_free();
 
   // Can we combine with the left or right blocks?
-  Block<> *prev_free = block->prev_free();
-  Block<> *next = block->next();
+  Block *prev_free = block->prev_free();
+  Block *next = block->next();
 
   if (prev_free != nullptr) {
     // Remove from free store and merge.
@@ -183,7 +183,7 @@ LIBC_INLINE void *FreeListHeap::realloc(void *ptr, size_t size) {
   if (!is_valid_ptr(bytes))
     return nullptr;
 
-  Block<> *block = Block<>::from_usable_space(bytes);
+  Block *block = Block::from_usable_space(bytes);
   if (!block->used())
     return nullptr;
   size_t old_size = block->inner_size();
diff --git a/libc/src/__support/freestore.h b/libc/src/__support/freestore.h
index f04b561f5d91dc..97197dda4b546b 100644
--- a/libc/src/__support/freestore.h
+++ b/libc/src/__support/freestore.h
@@ -29,40 +29,40 @@ class FreeStore {
 
   /// Insert a free block. If the block is too small to be tracked, nothing
   /// happens.
-  void insert(Block<> *block);
+  void insert(Block *block);
 
   /// Remove a free block. If the block is too small to be tracked, nothing
   /// happens.
-  void remove(Block<> *block);
+  void remove(Block *block);
 
   /// Remove a best-fit free block that can contain the given size when
   /// allocated. Returns nullptr if there is no such block.
-  Block<> *remove_best_fit(size_t size);
+  Block *remove_best_fit(size_t size);
 
 private:
   static constexpr size_t ALIGNMENT = alignof(max_align_t);
   static constexpr size_t MIN_OUTER_SIZE =
-      align_up(Block<>::BLOCK_OVERHEAD + sizeof(FreeList::Node), ALIGNMENT);
+      align_up(Block::BLOCK_OVERHEAD + sizeof(FreeList::Node), ALIGNMENT);
   static constexpr size_t MIN_LARGE_OUTER_SIZE =
-      align_up(Block<>::BLOCK_OVERHEAD + sizeof(FreeTrie::Node), ALIGNMENT);
+      align_up(Block::BLOCK_OVERHEAD + sizeof(FreeTrie::Node), ALIGNMENT);
   static constexpr size_t NUM_SMALL_SIZES =
       (MIN_LARGE_OUTER_SIZE - MIN_OUTER_SIZE) / ALIGNMENT;
 
-  LIBC_INLINE static bool too_small(Block<> *block) {
+  LIBC_INLINE static bool too_small(Block *block) {
     return block->outer_size() < MIN_OUTER_SIZE;
   }
-  LIBC_INLINE static bool is_small(Block<> *block) {
+  LIBC_INLINE static bool is_small(Block *block) {
     return block->outer_size() < MIN_LARGE_OUTER_SIZE;
   }
 
-  FreeList &small_list(Block<> *block);
+  FreeList &small_list(Block *block);
   FreeList *find_best_small_fit(size_t size);
 
   cpp::array<FreeList, NUM_SMALL_SIZES> small_lists;
   FreeTrie large_trie;
 };
 
-LIBC_INLINE void FreeStore::insert(Block<> *block) {
+LIBC_INLINE void FreeStore::insert(Block *block) {
   if (too_small(block))
     return;
   if (is_small(block))
@@ -71,7 +71,7 @@ LIBC_INLINE void FreeStore::insert(Block<> *block) {
     large_trie.push(block);
 }
 
-LIBC_INLINE void FreeStore::remove(Block<> *block) {
+LIBC_INLINE void FreeStore::remove(Block *block) {
   if (too_small(block))
     return;
   if (is_small(block)) {
@@ -83,21 +83,21 @@ LIBC_INLINE void FreeStore::remove(Block<> *block) {
   }
 }
 
-LIBC_INLINE Block<> *FreeStore::remove_best_fit(size_t size) {
+LIBC_INLINE Block *FreeStore::remove_best_fit(size_t size) {
   if (FreeList *list = find_best_small_fit(size)) {
-    Block<> *block = list->front();
+    Block *block = list->front();
     list->pop();
     return block;
   }
   if (FreeTrie::Node *best_fit = large_trie.find_best_fit(size)) {
-    Block<> *block = best_fit->block();
+    Block *block = best_fit->block();
     large_trie.remove(best_fit);
     return block;
   }
   return nullptr;
 }
 
-LIBC_INLINE FreeList &FreeStore::small_list(Block<> *block) {
+LIBC_INLINE FreeList &FreeStore::small_list(Block *block) {
   LIBC_ASSERT(is_small(block) && "only legal for small blocks");
   return small_lists[(block->outer_size() - MIN_OUTER_SIZE) / ALIGNMENT];
 }
diff --git a/libc/src/__support/freetrie.h b/libc/src/__support/freetrie.h
index ff1912ee94f884..42363c2c9e2f4e 100644
--- a/libc/src/__support/freetrie.h
+++ b/libc/src/__support/freetrie.h
@@ -96,7 +96,7 @@ class FreeTrie {
   LIBC_INLINE bool empty() const { return !root; }
 
   /// Push a block to the trie.
-  void push(Block<> *block);
+  void push(Block *block);
 
   /// Remove a node from this trie node's free list.
   void remove(Node *node);
@@ -117,7 +117,7 @@ class FreeTrie {
   SizeRange range;
 };
 
-LIBC_INLINE void FreeTrie::push(Block<> *block) {
+LIBC_INLINE void FreeTrie::push(Block *block) {
   LIBC_ASSERT(block->inner_size_free() >= sizeof(Node) &&
               "block too small to accomodate free trie node");
   size_t size = block->inner_size();
diff --git a/libc/test/src/__support/block_test.cpp b/libc/test/src/__support/block_test.cpp
index 4d23861155502a..5e437db51b6092 100644
--- a/libc/test/src/__support/block_test.cpp
+++ b/libc/test/src/__support/block_test.cpp
@@ -14,96 +14,60 @@
 #include "src/string/memcpy.h"
 #include "test/UnitTest/Test.h"
 
-// Block types.
-using LargeOffsetBlock = LIBC_NAMESPACE::Block<uint64_t>;
-using SmallOffsetBlock = LIBC_NAMESPACE::Block<uint16_t>;
-
-// For each of the block types above, we'd like to run the same tests since
-// they should work independently of the parameter sizes. Rather than re-writing
-// the same test for each case, let's instead create a custom test framework for
-// each test case that invokes the actual testing function for each block type.
-//
-// It's organized this way because the ASSERT/EXPECT macros only work within a
-// `Test` class due to those macros expanding to `test` methods.
-#define TEST_FOR_EACH_BLOCK_TYPE(TestCase)                                     \
-  class LlvmLibcBlockTest##TestCase : public LIBC_NAMESPACE::testing::Test {   \
-  public:                                                                      \
-    template <typename BlockType> void RunTest();                              \
-  };                                                                           \
-  TEST_F(LlvmLibcBlockTest##TestCase, TestCase) {                              \
-    RunTest<LargeOffsetBlock>();                                               \
-    RunTest<SmallOffsetBlock>();                                               \
-  }                                                                            \
-  template <typename BlockType> void LlvmLibcBlockTest##TestCase::RunTest()
-
+using LIBC_NAMESPACE::Block;
 using LIBC_NAMESPACE::cpp::array;
 using LIBC_NAMESPACE::cpp::bit_ceil;
 using LIBC_NAMESPACE::cpp::byte;
 using LIBC_NAMESPACE::cpp::span;
 
-TEST_FOR_EACH_BLOCK_TYPE(CanCreateSingleAlignedBlock) {
+TEST(LlvmLibcBlockTest, CanCreateSingleAlignedBlock) {
   constexpr size_t kN = 1024;
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
 
-  auto result = BlockType::init(bytes);
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
-  BlockType *last = block->next();
-  ASSERT_NE(last, static_cast<BlockType *>(nullptr));
-  constexpr size_t last_outer_size = BlockType::BLOCK_OVERHEAD;
+  Block *last = block->next();
+  ASSERT_NE(last, static_cast<Block *>(nullptr));
+  constexpr size_t last_outer_size = Block::BLOCK_OVERHEAD;
   EXPECT_EQ(last->outer_size(), last_outer_size);
   EXPECT_EQ(last->prev_free(), block);
   EXPECT_TRUE(last->used());
 
   EXPECT_EQ(block->outer_size(), kN - last_outer_size);
-  constexpr size_t last_prev_field_size =
-      sizeof(typename BlockType::offset_type);
-  EXPECT_EQ(block->inner_size(), kN - last_outer_size -
-                                     BlockType::BLOCK_OVERHEAD +
+  constexpr size_t last_prev_field_size = sizeof(size_t);
+  EXPECT_EQ(block->inner_size(), kN - last_outer_size - Block::BLOCK_OVERHEAD +
                                      last_prev_field_size);
-  EXPECT_EQ(block->prev_free(), static_cast<BlockType *>(nullptr));
+  EXPECT_EQ(block->prev_free(), static_cast<Block *>(nullptr));
   EXPECT_FALSE(block->used());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanCreateUnalignedSingleBlock) {
+TEST(LlvmLibcBlockTest, CanCreateUnalignedSingleBlock) {
   constexpr size_t kN = 1024;
 
   // Force alignment, so we can un-force it below
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
   span<byte> aligned(bytes);
 
-  auto result = BlockType::init(aligned.subspan(1));
+  auto result = Block::init(aligned.subspan(1));
   EXPECT_TRUE(result.has_value());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CannotCreateTooSmallBlock) {
+TEST(LlvmLibcBlockTest, CannotCreateTooSmallBlock) {
   array<byte, 2> bytes;
-  auto result = BlockType::init(bytes);
+  auto result = Block::init(bytes);
   EXPECT_FALSE(result.has_value());
 }
 
-// This test specifically checks that we cannot allocate a block with a size
-// larger than what can be held by the offset type, we don't need to test with
-// multiple block types for this particular check, so we use the normal TEST
-// macro and not the custom framework.
-TEST(LlvmLibcBlockTest, CannotCreateTooLargeBlock) {
-  using BlockType = LIBC_NAMESPACE::Block<uint8_t>;
+TEST(LlvmLibcBlockTest, CanSplitBlock) {
   constexpr size_t kN = 1024;
-
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
-  EXPECT_FALSE(result.has_value());
-}
-
-TEST_FOR_EACH_BLOCK_TYPE(CanSplitBlock) {
-  constexpr size_t kN = 1024;
-  constexpr size_t prev_field_size = sizeof(typename BlockType::offset_type);
+  constexpr size_t prev_field_size = sizeof(size_t);
   // Give the split position a large alignment.
   constexpr size_t kSplitN = 512 + prev_field_size;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
   auto *block1 = *result;
   size_t orig_size = block1->outer_size();
@@ -114,7 +78,7 @@ TEST_FOR_EACH_BLOCK_TYPE(CanSplitBlock) {
 
   EXPECT_EQ(block1->inner_size(), kSplitN);
   EXPECT_EQ(block1->outer_size(),
-            kSplitN - prev_field_size + BlockType::BLOCK_OVERHEAD);
+            kSplitN - prev_field_size + Block::BLOCK_OVERHEAD);
 
   EXPECT_EQ(block2->outer_size(), orig_size - block1->outer_size());
   EXPECT_FALSE(block2->used());
@@ -123,26 +87,26 @@ TEST_FOR_EACH_BLOCK_TYPE(CanSplitBlock) {
   EXPECT_EQ(block2->prev_free(), block1);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanSplitBlockUnaligned) {
+TEST(LlvmLibcBlockTest, CanSplitBlockUnaligned) {
   constexpr size_t kN = 1024;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block1 = *result;
+  Block *block1 = *result;
   size_t orig_size = block1->outer_size();
 
   constexpr size_t kSplitN = 513;
-  constexpr size_t prev_field_size = sizeof(typename BlockType::offset_type);
+  constexpr size_t prev_field_size = sizeof(size_t);
   uintptr_t split_addr =
       reinterpret_cast<uintptr_t>(block1) + (kSplitN - prev_field_size);
   // Round split_addr up to a multiple of the alignment.
-  split_addr += alignof(BlockType) - (split_addr % alignof(BlockType));
+  split_addr += alignof(Block) - (split_addr % alignof(Block));
   uintptr_t split_len = split_addr - (uintptr_t)&bytes + prev_field_size;
 
   result = block1->split(kSplitN);
   ASSERT_TRUE(result.has_value());
-  BlockType *block2 = *result;
+  Block *block2 = *result;
 
   EXPECT_EQ(block1->inner_size(), split_len);
 
@@ -153,7 +117,7 @@ TEST_FOR_EACH_BLOCK_TYPE(CanSplitBlockUnaligned) {
   EXPECT_EQ(block2->prev_free(), block1);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanSplitMidBlock) {
+TEST(LlvmLibcBlockTest, CanSplitMidBlock) {
   // split once, then split the original block again to ensure that the
   // pointers get rewired properly.
   // I.e.
@@ -167,18 +131,18 @@ TEST_FOR_EACH_BLOCK_TYPE(CanSplitMidBlock) {
   constexpr size_t kSplit1 = 512;
   constexpr size_t kSplit2 = 256;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block1 = *result;
+  Block *block1 = *result;
 
   result = block1->split(kSplit1);
   ASSERT_TRUE(result.has_value());
-  BlockType *block2 = *result;
+  Block *block2 = *result;
 
   result = block1->split(kSplit2);
   ASSERT_TRUE(result.has_value());
-  BlockType *block3 = *result;
+  Block *block3 = *result;
 
   EXPECT_EQ(block1->next(), block3);
   EXPECT_EQ(block3->prev_free(), block1);
@@ -186,97 +150,97 @@ TEST_FOR_EACH_BLOCK_TYPE(CanSplitMidBlock) {
   EXPECT_EQ(block2->prev_free(), block3);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CannotSplitTooSmallBlock) {
+TEST(LlvmLibcBlockTest, CannotSplitTooSmallBlock) {
   constexpr size_t kN = 64;
   constexpr size_t kSplitN = kN + 1;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   result = block->split(kSplitN);
   ASSERT_FALSE(result.has_value());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CannotSplitBlockWithoutHeaderSpace) {
+TEST(LlvmLibcBlockTest, CannotSplitBlockWithoutHeaderSpace) {
   constexpr size_t kN = 1024;
-  constexpr size_t kSplitN = kN - 2 * BlockType::BLOCK_OVERHEAD - 1;
+  constexpr size_t kSplitN = kN - 2 * Block::BLOCK_OVERHEAD - 1;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   result = block->split(kSplitN);
   ASSERT_FALSE(result.has_value());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CannotMakeBlockLargerInSplit) {
+TEST(LlvmLibcBlockTest, CannotMakeBlockLargerInSplit) {
   // Ensure that we can't ask for more space than the block actually has...
   constexpr size_t kN = 1024;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   result = block->split(block->inner_size() + 1);
   ASSERT_FALSE(result.has_value());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CannotMakeSecondBlockLargerInSplit) {
+TEST(LlvmLibcBlockTest, CannotMakeSecondBlockLargerInSplit) {
   // Ensure that the second block in split is at least of the size of header.
   constexpr size_t kN = 1024;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
-  result = block->split(block->inner_size() - BlockType::BLOCK_OVERHEAD + 1);
+  result = block->split(block->inner_size() - Block::BLOCK_OVERHEAD + 1);
   ASSERT_FALSE(result.has_value());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanMakeMinimalSizeFirstBlock) {
+TEST(LlvmLibcBlockTest, CanMakeMinimalSizeFirstBlock) {
   // This block does support splitting with minimal payload size.
   constexpr size_t kN = 1024;
-  constexpr size_t minimal_size = sizeof(typename BlockType::offset_type);
+  constexpr size_t minimal_size = sizeof(size_t);
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   result = block->split(minimal_size);
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(block->inner_size(), minimal_size);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanMakeMinimalSizeSecondBlock) {
+TEST(LlvmLibcBlockTest, CanMakeMinimalSizeSecondBlock) {
   // Likewise, the split block can be minimal-width.
   constexpr size_t kN = 1024;
-  constexpr size_t minimal_size = sizeof(typename BlockType::offset_type);
+  constexpr size_t minimal_size = sizeof(size_t);
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block1 = *result;
+  Block *block1 = *result;
 
-  result = block1->split(block1->inner_size() - BlockType::BLOCK_OVERHEAD);
+  result = block1->split(block1->inner_size() - Block::BLOCK_OVERHEAD);
   ASSERT_TRUE(result.has_value());
-  BlockType *block2 = *result;
+  Block *block2 = *result;
 
   EXPECT_EQ(block2->inner_size(), minimal_size);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanMarkBlockUsed) {
+TEST(LlvmLibcBlockTest, CanMarkBlockUsed) {
   constexpr size_t kN = 1024;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
   size_t orig_size = block->outer_size();
 
   block->mark_used();
@@ -287,33 +251,33 @@ TEST_FOR_EACH_BLOCK_TYPE(CanMarkBlockUsed) {
   EXPECT_FALSE(block->used());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CannotSplitUsedBlock) {
+TEST(LlvmLibcBlockTest, CannotSplitUsedBlock) {
   constexpr size_t kN = 1024;
   constexpr size_t kSplitN = 512;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   block->mark_used();
   result = block->split(kSplitN);
   ASSERT_FALSE(result.has_value());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanMergeWithNextBlock) {
+TEST(LlvmLibcBlockTest, CanMergeWithNextBlock) {
   // Do the three way merge from "CanSplitMidBlock", and let's
   // merge block 3 and 2
   constexpr size_t kN = 1024;
   // Give the split positions large alignments.
-  constexpr size_t prev_field_size = sizeof(typename BlockType::offset_type);
+  constexpr size_t prev_field_size = sizeof(size_t);
   constexpr size_t kSplit1 = 512 + prev_field_size;
   constexpr size_t kSplit2 = 256 + prev_field_size;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block1 = *result;
+  Block *block1 = *result;
   size_t orig_size = block1->outer_size();
 
   result = block1->split(kSplit1);
@@ -321,7 +285,7 @@ TEST_FOR_EACH_BLOCK_TYPE(CanMergeWithNextBlock) {
 
   result = block1->split(kSplit2);
   ASSERT_TRUE(result.has_value());
-  BlockType *block3 = *result;
+  Block *block3 = *result;
 
   EXPECT_TRUE(block3->merge_next());
 
@@ -331,31 +295,31 @@ TEST_FOR_EACH_BLOCK_TYPE(CanMergeWithNextBlock) {
   EXPECT_EQ(block3->outer_size(), orig_size - block1->outer_size());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CannotMergeWithFirstOrLastBlock) {
+TEST(LlvmLibcBlockTest, CannotMergeWithFirstOrLastBlock) {
   constexpr size_t kN = 1024;
   constexpr size_t kSplitN = 512;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block1 = *result;
+  Block *block1 = *result;
 
   // Do a split, just to check that the checks on next/prev are different...
   result = block1->split(kSplitN);
   ASSERT_TRUE(result.has_value());
-  BlockType *block2 = *result;
+  Block *block2 = *result;
 
   EXPECT_FALSE(block2->merge_next());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CannotMergeUsedBlock) {
+TEST(LlvmLibcBlockTest, CannotMergeUsedBlock) {
   constexpr size_t kN = 1024;
   constexpr size_t kSplitN = 512;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes;
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes;
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   // Do a split, just to check that the checks on next/prev are different...
   result = block->split(kSplitN);
@@ -365,177 +329,176 @@ TEST_FOR_EACH_BLOCK_TYPE(CannotMergeUsedBlock) {
   EXPECT_FALSE(block->merge_next());
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanGetBlockFromUsableSpace) {
+TEST(LlvmLibcBlockTest, CanGetBlockFromUsableSpace) {
   constexpr size_t kN = 1024;
 
   array<byte, kN> bytes{};
-  auto result = BlockType::init(bytes);
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block1 = *result;
+  Block *block1 = *result;
 
   void *ptr = block1->usable_space();
-  BlockType *block2 = BlockType::from_usable_space(ptr);
+  Block *block2 = Block::from_usable_space(ptr);
   EXPECT_EQ(block1, block2);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanGetConstBlockFromUsableSpace) {
+TEST(LlvmLibcBlockTest, CanGetConstBlockFromUsableSpace) {
   constexpr size_t kN = 1024;
 
   array<byte, kN> bytes{};
-  auto result = BlockType::init(bytes);
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  const BlockType *block1 = *result;
+  const Block *block1 = *result;
 
   const void *ptr = block1->usable_space();
-  const BlockType *block2 = BlockType::from_usable_space(ptr);
+  const Block *block2 = Block::from_usable_space(ptr);
   EXPECT_EQ(block1, block2);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanAllocate) {
-  constexpr size_t kN = 1024 + BlockType::BLOCK_OVERHEAD;
+TEST(LlvmLibcBlockTest, CanAllocate) {
+  constexpr size_t kN = 1024 + Block::BLOCK_OVERHEAD;
 
   // Ensure we can allocate everything up to the block size within this block.
-  for (size_t i = 0; i < kN - 2 * BlockType::BLOCK_OVERHEAD; ++i) {
-    alignas(BlockType::ALIGNMENT) array<byte, kN> bytes{};
-    auto result = BlockType::init(bytes);
+  for (size_t i = 0; i < kN - 2 * Block::BLOCK_OVERHEAD; ++i) {
+    alignas(Block::ALIGNMENT) array<byte, kN> bytes{};
+    auto result = Block::init(bytes);
     ASSERT_TRUE(result.has_value());
-    BlockType *block = *result;
+    Block *block = *result;
 
     constexpr size_t ALIGN = 1; // Effectively ignores alignment.
     EXPECT_TRUE(block->can_allocate(ALIGN, i));
 
     // For each can_allocate, we should be able to do a successful call to
     // allocate.
-    auto info = BlockType::allocate(block, ALIGN, i);
-    EXPECT_NE(info.block, static_cast<BlockType *>(nullptr));
+    auto info = Block::allocate(block, ALIGN, i);
+    EXPECT_NE(info.block, static_cast<Block *>(nullptr));
   }
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes{};
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes{};
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   // Given a block of size N (assuming it's also a power of two), we should be
   // able to allocate a block within it that's aligned to N/2. This is
   // because regardless of where the buffer is located, we can always find a
   // starting location within it that meets this alignment.
   EXPECT_TRUE(block->can_allocate(block->outer_size() / 2, 1));
-  auto info = BlockType::allocate(block, block->outer_size() / 2, 1);
-  EXPECT_NE(info.block, static_cast<BlockType *>(nullptr));
+  auto info = Block::allocate(block, block->outer_size() / 2, 1);
+  EXPECT_NE(info.block, static_cast<Block *>(nullptr));
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(AllocateAlreadyAligned) {
+TEST(LlvmLibcBlockTest, AllocateAlreadyAligned) {
   constexpr size_t kN = 1024;
 
-  alignas(BlockType::ALIGNMENT) array<byte, kN> bytes{};
-  auto result = BlockType::init(bytes);
+  alignas(Block::ALIGNMENT) array<byte, kN> bytes{};
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   // This should result in no new blocks.
-  constexpr size_t kAlignment = BlockType::ALIGNMENT;
-  constexpr size_t prev_field_size = sizeof(typename BlockType::offset_type);
-  constexpr size_t kExpectedSize = BlockType::ALIGNMENT + prev_field_size;
+  constexpr size_t kAlignment = Block::ALIGNMENT;
+  constexpr size_t prev_field_size = sizeof(size_t);
+  constexpr size_t kExpectedSize = Block::ALIGNMENT + prev_field_size;
   EXPECT_TRUE(block->can_allocate(kAlignment, kExpectedSize));
 
   auto [aligned_block, prev, next] =
-      BlockType::allocate(block, BlockType::ALIGNMENT, kExpectedSize);
+      Block::allocate(block, Block::ALIGNMENT, kExpectedSize);
 
   // Since this is already aligned, there should be no previous block.
-  EXPECT_EQ(prev, static_cast<BlockType *>(nullptr));
+  EXPECT_EQ(prev, static_cast<Block *>(nullptr));
 
   // Ensure we the block is aligned and the size we expect.
-  EXPECT_NE(aligned_block, static_cast<BlockType *>(nullptr));
-  EXPECT_TRUE(aligned_block->is_usable_space_aligned(BlockType::ALIGNMENT));
+  EXPECT_NE(aligned_block, static_cast<Block *>(nullptr));
+  EXPECT_TRUE(aligned_block->is_usable_space_aligned(Block::ALIGNMENT));
   EXPECT_EQ(aligned_block->inner_size(), kExpectedSize);
 
   // Check the next block.
-  EXPECT_NE(next, static_cast<BlockType *>(nullptr));
+  EXPECT_NE(next, static_cast<Block *>(nullptr));
   EXPECT_EQ(aligned_block->next(), next);
   EXPECT_EQ(reinterpret_cast<byte *>(next) + next->outer_size(),
-            bytes.data() + bytes.size() - BlockType::BLOCK_OVERHEAD);
+            bytes.data() + bytes.size() - Block::BLOCK_OVERHEAD);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(AllocateNeedsAlignment) {
+TEST(LlvmLibcBlockTest, AllocateNeedsAlignment) {
   constexpr size_t kN = 1024;
 
   alignas(kN) array<byte, kN> bytes{};
-  auto result = BlockType::init(bytes);
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   // Ensure first the usable_data is only aligned to the block alignment.
-  ASSERT_EQ(block->usable_space(), bytes.data() + BlockType::BLOCK_OVERHEAD);
-  ASSERT_EQ(block->prev_free(), static_cast<BlockType *>(nullptr));
+  ASSERT_EQ(block->usable_space(), bytes.data() + Block::BLOCK_OVERHEAD);
+  ASSERT_EQ(block->prev_free(), static_cast<Block *>(nullptr));
 
   // Now pick an alignment such that the usable space is not already aligned to
   // it. We want to explicitly test that the block will split into one before
   // it.
-  constexpr size_t kAlignment = bit_ceil(BlockType::BLOCK_OVERHEAD) * 8;
+  constexpr size_t kAlignment = bit_ceil(Block::BLOCK_OVERHEAD) * 8;
   ASSERT_FALSE(block->is_usable_space_aligned(kAlignment));
 
   constexpr size_t kSize = 10;
   EXPECT_TRUE(block->can_allocate(kAlignment, kSize));
 
-  auto [aligned_block, prev, next] =
-      BlockType::allocate(block, kAlignment, kSize);
+  auto [aligned_block, prev, next] = Block::allocate(block, kAlignment, kSize);
 
   // Check the previous block was created appropriately. Since this block is the
   // first block, a new one should be made before this.
-  EXPECT_NE(prev, static_cast<BlockType *>(nullptr));
+  EXPECT_NE(prev, static_cast<Block *>(nullptr));
   EXPECT_EQ(aligned_block->prev_free(), prev);
   EXPECT_EQ(prev->next(), aligned_block);
   EXPECT_EQ(prev->outer_size(), reinterpret_cast<uintptr_t>(aligned_block) -
                                     reinterpret_cast<uintptr_t>(prev));
 
   // Ensure we the block is aligned and the size we expect.
-  EXPECT_NE(next, static_cast<BlockType *>(nullptr));
+  EXPECT_NE(next, static_cast<Block *>(nullptr));
   EXPECT_TRUE(aligned_block->is_usable_space_aligned(kAlignment));
 
   // Check the next block.
-  EXPECT_NE(next, static_cast<BlockType *>(nullptr));
+  EXPECT_NE(next, static_cast<Block *>(nullptr));
   EXPECT_EQ(aligned_block->next(), next);
   EXPECT_EQ(reinterpret_cast<byte *>(next) + next->outer_size(),
-            bytes.data() + bytes.size() - BlockType::BLOCK_OVERHEAD);
+            bytes.data() + bytes.size() - Block::BLOCK_OVERHEAD);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(PreviousBlockMergedIfNotFirst) {
+TEST(LlvmLibcBlockTest, PreviousBlockMergedIfNotFirst) {
   constexpr size_t kN = 1024;
 
   alignas(kN) array<byte, kN> bytes{};
-  auto result = BlockType::init(bytes);
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
+  Block *block = *result;
 
   // Split the block roughly halfway and work on the second half.
   auto result2 = block->split(kN / 2);
   ASSERT_TRUE(result2.has_value());
-  BlockType *newblock = *result2;
+  Block *newblock = *result2;
   ASSERT_EQ(newblock->prev_free(), block);
   size_t old_prev_size = block->outer_size();
 
   // Now pick an alignment such that the usable space is not already aligned to
   // it. We want to explicitly test that the block will split into one before
   // it.
-  constexpr size_t kAlignment = bit_ceil(BlockType::BLOCK_OVERHEAD) * 8;
+  constexpr size_t kAlignment = bit_ceil(Block::BLOCK_OVERHEAD) * 8;
   ASSERT_FALSE(newblock->is_usable_space_aligned(kAlignment));
 
   // Ensure we can allocate in the new block.
-  constexpr size_t kSize = BlockType::ALIGNMENT;
+  constexpr size_t kSize = Block::ALIGNMENT;
   EXPECT_TRUE(newblock->can_allocate(kAlignment, kSize));
 
   auto [aligned_block, prev, next] =
-      BlockType::allocate(newblock, kAlignment, kSize);
+      Block::allocate(newblock, kAlignment, kSize);
 
   // Now there should be no new previous block. Instead, the padding we did
   // create should be merged into the original previous block.
-  EXPECT_EQ(prev, static_cast<BlockType *>(nullptr));
+  EXPECT_EQ(prev, static_cast<Block *>(nullptr));
   EXPECT_EQ(aligned_block->prev_free(), block);
   EXPECT_EQ(block->next(), aligned_block);
   EXPECT_GT(block->outer_size(), old_prev_size);
 }
 
-TEST_FOR_EACH_BLOCK_TYPE(CanRemergeBlockAllocations) {
+TEST(LlvmLibcBlockTest, CanRemergeBlockAllocations) {
   // Finally to ensure we made the split blocks correctly via allocate. We
   // should be able to reconstruct the original block from the blocklets.
   //
@@ -543,31 +506,30 @@ TEST_FOR_EACH_BLOCK_TYPE(CanRemergeBlockAllocations) {
   constexpr size_t kN = 1024;
 
   alignas(kN) array<byte, kN> bytes{};
-  auto result = BlockType::init(bytes);
+  auto result = Block::init(bytes);
   ASSERT_TRUE(result.has_value());
-  BlockType *block = *result;
-  BlockType *last = block->next();
+  Block *block = *result;
+  Block *last = block->next();
 
   // Ensure first the usable_data is only aligned to the block alignment.
-  ASSERT_EQ(block->usable_space(), bytes.data() + BlockType::BLOCK_OVERHEAD);
-  ASSERT_EQ(block->prev_free(), static_cast<BlockType *>(nullptr));
+  ASSERT_EQ(block->usable_space(), bytes.data() + Block::BLOCK_OVERHEAD);
+  ASSERT_EQ(block->prev_free(), static_cast<Block *>(nullptr));
 
   // Now pick an alignment such that the usable space is not already aligned to
   // it. We want to explicitly test that the block will split into one before
   // it.
-  constexpr size_t kAlignment = bit_ceil(BlockType::BLOCK_OVERHEAD) * 8;
+  constexpr size_t kAlignment = bit_ceil(Block::BLOCK_OVERHEAD) * 8;
   ASSERT_FALSE(block->is_usable_space_aligned(kAlignment));
 
-  constexpr size_t kSize = BlockType::ALIGNMENT;
+  constexpr size_t kSize = Block::ALIGNMENT;
   EXPECT_TRUE(block->can_allocate(kAlignment, kSize));
 
-  auto [aligned_block, prev, next] =
-      BlockType::allocate(block, kAlignment, kSize);
+  auto [aligned_block, prev, next] = Block::allocate(block, kAlignment, kSize);
 
   // Check we have the appropriate blocks.
-  ASSERT_NE(prev, static_cast<BlockType *>(nullptr));
+  ASSERT_NE(prev, static_cast<Block *>(nullptr));
   ASSERT_EQ(aligned_block->prev_free(), prev);
-  EXPECT_NE(next, static_cast<BlockType *>(nullptr));
+  EXPECT_NE(next, static_cast<Block *>(nullptr));
   EXPECT_EQ(aligned_block->next(), next);
   EXPECT_EQ(next->next(), last);
 
@@ -579,7 +541,7 @@ TEST_FOR_EACH_BLOCK_TYPE(CanRemergeBlockAllocations) {
 
   // We should have the original buffer.
   EXPECT_EQ(reinterpret_cast<byte *>(prev), &*bytes.begin());
-  EXPECT_EQ(prev->outer_size(), bytes.size() - BlockType::BLOCK_OVERHEAD);
+  EXPECT_EQ(prev->outer_size(), bytes.size() - Block::BLOCK_OVERHEAD);
   EXPECT_EQ(reinterpret_cast<byte *>(prev) + prev->outer_size(),
-            &*bytes.end() - BlockType::BLOCK_OVERHEAD);
+            &*bytes.end() - Block::BLOCK_OVERHEAD);
 }
diff --git a/libc/test/src/__support/freelist_heap_test.cpp b/libc/test/src/__support/freelist_heap_test.cpp
index 59ebf4e50974b7..991c158825a888 100644
--- a/libc/test/src/__support/freelist_heap_test.cpp
+++ b/libc/test/src/__support/freelist_heap_test.cpp
@@ -42,7 +42,7 @@ using LIBC_NAMESPACE::cpp::span;
     void RunTest(FreeListHeap &allocator, [[maybe_unused]] size_t N);          \
   };                                                                           \
   TEST_F(LlvmLibcFreeListHeapTest##TestCase, TestCase) {                       \
-    alignas(Block<>) byte buf[BufferSize] = {byte(0)};                         \
+    alignas(Block) byte buf[BufferSize] = {byte(0)};                           \
     FreeListHeap allocator(buf);                                               \
     RunTest(allocator, BufferSize);                                            \
     RunTest(*freelist_heap, freelist_heap->region().size());                   \
@@ -95,13 +95,13 @@ TEST_FOR_EACH_ALLOCATOR(ReturnsNullWhenAllocationTooLarge, 2048) {
 // is used for other test cases and we don't explicitly free them.
 TEST(LlvmLibcFreeListHeap, ReturnsNullWhenFull) {
   constexpr size_t N = 2048;
-  alignas(Block<>) byte buf[N] = {byte(0)};
+  alignas(Block) byte buf[N] = {byte(0)};
 
   FreeListHeap allocator(buf);
 
   // Use aligned_allocate so we don't need to worry about ensuring the `buf`
   // being aligned to max_align_t.
-  EXPECT_NE(allocator.aligned_allocate(1, N - 2 * Block<>::BLOCK_OVERHEAD),
+  EXPECT_NE(allocator.aligned_allocate(1, N - 2 * Block::BLOCK_OVERHEAD),
             static_cast<void *>(nullptr));
   EXPECT_EQ(allocator.allocate(1), static_cast<void *>(nullptr));
 }
@@ -241,16 +241,16 @@ TEST_FOR_EACH_ALLOCATOR(AlignedAlloc, 2048) {
 
 // This test is not part of the TEST_FOR_EACH_ALLOCATOR since we want to
 // explicitly ensure that the buffer can still return aligned allocations even
-// if the underlying buffer is at most aligned to the Block<> alignment. This
+// if the underlying buffer is at most aligned to the Block alignment. This
 // is so we can check that we can still get aligned allocations even if the
 // underlying buffer is not aligned to the alignments we request.
 TEST(LlvmLibcFreeListHeap, AlignedAllocOnlyBlockAligned) {
   constexpr size_t BUFFER_SIZE = 4096;
-  constexpr size_t BUFFER_ALIGNMENT = alignof(Block<>) * 2;
+  constexpr size_t BUFFER_ALIGNMENT = alignof(Block) * 2;
   alignas(BUFFER_ALIGNMENT) byte buf[BUFFER_SIZE] = {byte(0)};
 
   // Ensure the underlying buffer is at most aligned to the block type.
-  FreeListHeap allocator(span<byte>(buf).subspan(alignof(Block<>)));
+  FreeListHeap allocator(span<byte>(buf).subspan(alignof(Block)));
 
   constexpr size_t ALIGNMENTS[] = {1, 2, 4, 8, 16, 32, 64, 128, 256};
   constexpr size_t SIZE_SCALES[] = {1, 2, 3, 4, 5};
diff --git a/libc/test/src/__support/freelist_malloc_test.cpp b/libc/test/src/__support/freelist_malloc_test.cpp
index 583e40d9478223..793e2498304fb9 100644
--- a/libc/test/src/__support/freelist_malloc_test.cpp
+++ b/libc/test/src/__support/freelist_malloc_test.cpp
@@ -24,12 +24,12 @@ TEST(LlvmLibcFreeListMalloc, Malloc) {
   constexpr size_t kCallocSize = 64;
 
   void *ptr1 = LIBC_NAMESPACE::malloc(kAllocSize);
-  auto *block = Block<>::from_usable_space(ptr1);
+  auto *block = Block::from_usable_space(ptr1);
   EXPECT_GE(block->inner_size(), kAllocSize);
 
   LIBC_NAMESPACE::free(ptr1);
-  ASSERT_NE(block->next(), static_cast<Block<> *>(nullptr));
-  ASSERT_EQ(block->next()->next(), static_cast<Block<> *>(nullptr));
+  ASSERT_NE(block->next(), static_cast<Block *>(nullptr));
+  ASSERT_EQ(block->next()->next(), static_cast<Block *>(nullptr));
   size_t heap_size = block->inner_size();
 
   void *ptr2 = LIBC_NAMESPACE::calloc(kCallocNum, kCallocSize);
@@ -46,7 +46,7 @@ TEST(LlvmLibcFreeListMalloc, Malloc) {
   void *ptr3 = LIBC_NAMESPACE::aligned_alloc(ALIGN, kAllocSize);
   EXPECT_NE(ptr3, static_cast<void *>(nullptr));
   EXPECT_EQ(reinterpret_cast<uintptr_t>(ptr3) % ALIGN, size_t(0));
-  auto *aligned_block = reinterpret_cast<Block<> *>(ptr3);
+  auto *aligned_block = reinterpret_cast<Block *>(ptr3);
   EXPECT_GE(aligned_block->inner_size(), kAllocSize);
 
   LIBC_NAMESPACE::free(ptr3);
diff --git a/libc/test/src/__support/freelist_test.cpp b/libc/test/src/__support/freelist_test.cpp
index 1f310761bee180..bd5ecec45d921b 100644
--- a/libc/test/src/__support/freelist_test.cpp
+++ b/libc/test/src/__support/freelist_test.cpp
@@ -18,13 +18,13 @@ using LIBC_NAMESPACE::cpp::optional;
 
 TEST(LlvmLibcFreeList, FreeList) {
   byte mem[1024];
-  optional<Block<> *> maybeBlock = Block<>::init(mem);
+  optional<Block *> maybeBlock = Block::init(mem);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *block1 = *maybeBlock;
+  Block *block1 = *maybeBlock;
 
   maybeBlock = block1->split(128);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *block2 = *maybeBlock;
+  Block *block2 = *maybeBlock;
 
   maybeBlock = block2->split(128);
   ASSERT_TRUE(maybeBlock.has_value());
diff --git a/libc/test/src/__support/freestore_test.cpp b/libc/test/src/__support/freestore_test.cpp
index 84f2acfab878a1..7960d32c8bbf0f 100644
--- a/libc/test/src/__support/freestore_test.cpp
+++ b/libc/test/src/__support/freestore_test.cpp
@@ -21,12 +21,12 @@ using LIBC_NAMESPACE::cpp::optional;
 // Inserting or removing blocks too small to be tracked does nothing.
 TEST(LlvmLibcFreeStore, TooSmall) {
   byte mem[1024];
-  optional<Block<> *> maybeBlock = Block<>::init(mem);
+  optional<Block *> maybeBlock = Block::init(mem);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *too_small = *maybeBlock;
-  maybeBlock = too_small->split(sizeof(Block<>::offset_type));
+  Block *too_small = *maybeBlock;
+  maybeBlock = too_small->split(sizeof(size_t));
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *remainder = *maybeBlock;
+  Block *remainder = *maybeBlock;
 
   FreeStore store;
   store.set_range({0, 4096});
@@ -39,24 +39,22 @@ TEST(LlvmLibcFreeStore, TooSmall) {
 
 TEST(LlvmLibcFreeStore, RemoveBestFit) {
   byte mem[1024];
-  optional<Block<> *> maybeBlock = Block<>::init(mem);
+  optional<Block *> maybeBlock = Block::init(mem);
   ASSERT_TRUE(maybeBlock.has_value());
 
-  Block<> *smallest = *maybeBlock;
-  maybeBlock =
-      smallest->split(sizeof(FreeList::Node) + sizeof(Block<>::offset_type));
+  Block *smallest = *maybeBlock;
+  maybeBlock = smallest->split(sizeof(FreeList::Node) + sizeof(size_t));
   ASSERT_TRUE(maybeBlock.has_value());
 
-  Block<> *largest_small = *maybeBlock;
-  maybeBlock =
-      largest_small->split(sizeof(FreeTrie::Node) +
-                           sizeof(Block<>::offset_type) - alignof(max_align_t));
+  Block *largest_small = *maybeBlock;
+  maybeBlock = largest_small->split(sizeof(FreeTrie::Node) + sizeof(size_t) -
+                                    alignof(max_align_t));
   ASSERT_TRUE(maybeBlock.has_value());
   if (largest_small->inner_size() == smallest->inner_size())
     largest_small = smallest;
   ASSERT_GE(largest_small->inner_size(), smallest->inner_size());
 
-  Block<> *remainder = *maybeBlock;
+  Block *remainder = *maybeBlock;
 
   FreeStore store;
   store.set_range({0, 4096});
@@ -74,8 +72,7 @@ TEST(LlvmLibcFreeStore, RemoveBestFit) {
   store.insert(largest_small);
 
   // Search small list for best fit.
-  Block<> *next_smallest =
-      largest_small == smallest ? remainder : largest_small;
+  Block *next_smallest = largest_small == smallest ? remainder : largest_small;
   ASSERT_EQ(store.remove_best_fit(smallest->inner_size() + 1), next_smallest);
   store.insert(next_smallest);
 
@@ -85,15 +82,14 @@ TEST(LlvmLibcFreeStore, RemoveBestFit) {
 
 TEST(LlvmLibcFreeStore, Remove) {
   byte mem[1024];
-  optional<Block<> *> maybeBlock = Block<>::init(mem);
+  optional<Block *> maybeBlock = Block::init(mem);
   ASSERT_TRUE(maybeBlock.has_value());
 
-  Block<> *small = *maybeBlock;
-  maybeBlock =
-      small->split(sizeof(FreeList::Node) + sizeof(Block<>::offset_type));
+  Block *small = *maybeBlock;
+  maybeBlock = small->split(sizeof(FreeList::Node) + sizeof(size_t));
   ASSERT_TRUE(maybeBlock.has_value());
 
-  Block<> *remainder = *maybeBlock;
+  Block *remainder = *maybeBlock;
 
   FreeStore store;
   store.set_range({0, 4096});
@@ -102,8 +98,8 @@ TEST(LlvmLibcFreeStore, Remove) {
 
   store.remove(remainder);
   ASSERT_EQ(store.remove_best_fit(remainder->inner_size()),
-            static_cast<Block<> *>(nullptr));
+            static_cast<Block *>(nullptr));
   store.remove(small);
   ASSERT_EQ(store.remove_best_fit(small->inner_size()),
-            static_cast<Block<> *>(nullptr));
+            static_cast<Block *>(nullptr));
 }
diff --git a/libc/test/src/__support/freetrie_test.cpp b/libc/test/src/__support/freetrie_test.cpp
index 1e3caceb7293bb..5663a01687294e 100644
--- a/libc/test/src/__support/freetrie_test.cpp
+++ b/libc/test/src/__support/freetrie_test.cpp
@@ -21,9 +21,9 @@ TEST(LlvmLibcFreeTrie, FindBestFitRoot) {
   EXPECT_EQ(trie.find_best_fit(123), static_cast<FreeTrie::Node *>(nullptr));
 
   byte mem[1024];
-  optional<Block<> *> maybeBlock = Block<>::init(mem);
+  optional<Block *> maybeBlock = Block::init(mem);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *block = *maybeBlock;
+  Block *block = *maybeBlock;
   trie.push(block);
 
   FreeTrie::Node *root = trie.find_best_fit(0);
@@ -37,12 +37,12 @@ TEST(LlvmLibcFreeTrie, FindBestFitRoot) {
 
 TEST(LlvmLibcFreeTrie, FindBestFitLower) {
   byte mem[4096];
-  optional<Block<> *> maybeBlock = Block<>::init(mem);
+  optional<Block *> maybeBlock = Block::init(mem);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *lower = *maybeBlock;
+  Block *lower = *maybeBlock;
   maybeBlock = lower->split(512);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *root = *maybeBlock;
+  Block *root = *maybeBlock;
 
   FreeTrie trie({0, 4096});
   trie.push(root);
@@ -53,12 +53,12 @@ TEST(LlvmLibcFreeTrie, FindBestFitLower) {
 
 TEST(LlvmLibcFreeTrie, FindBestFitUpper) {
   byte mem[4096];
-  optional<Block<> *> maybeBlock = Block<>::init(mem);
+  optional<Block *> maybeBlock = Block::init(mem);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *root = *maybeBlock;
+  Block *root = *maybeBlock;
   maybeBlock = root->split(512);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *upper = *maybeBlock;
+  Block *upper = *maybeBlock;
 
   FreeTrie trie({0, 4096});
   trie.push(root);
@@ -71,15 +71,15 @@ TEST(LlvmLibcFreeTrie, FindBestFitUpper) {
 
 TEST(LlvmLibcFreeTrie, FindBestFitLowerAndUpper) {
   byte mem[4096];
-  optional<Block<> *> maybeBlock = Block<>::init(mem);
+  optional<Block *> maybeBlock = Block::init(mem);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *root = *maybeBlock;
+  Block *root = *maybeBlock;
   maybeBlock = root->split(1024);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *lower = *maybeBlock;
+  Block *lower = *maybeBlock;
   maybeBlock = lower->split(128);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *upper = *maybeBlock;
+  Block *upper = *maybeBlock;
 
   FreeTrie trie({0, 4096});
   trie.push(root);
@@ -95,16 +95,16 @@ TEST(LlvmLibcFreeTrie, FindBestFitLowerAndUpper) {
 
 TEST(LlvmLibcFreeTrie, Remove) {
   byte mem[4096];
-  optional<Block<> *> maybeBlock = Block<>::init(mem);
+  optional<Block *> maybeBlock = Block::init(mem);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *small1 = *maybeBlock;
+  Block *small1 = *maybeBlock;
   maybeBlock = small1->split(512);
   ASSERT_TRUE(maybeBlock.has_value());
-  Block<> *small2 = *maybeBlock;
+  Block *small2 = *maybeBlock;
   maybeBlock = small2->split(512);
   ASSERT_TRUE(maybeBlock.has_value());
   ASSERT_EQ(small1->inner_size(), small2->inner_size());
-  Block<> *large = *maybeBlock;
+  Block *large = *maybeBlock;
 
   // Removing the root empties the trie.
   FreeTrie trie({0, 4096});



More information about the libc-commits mailing list