[libc-commits] [libc] [libc] Add a small utility type in __support/ called InlineAny. (PR #223490)

Alex Strelnikov via libc-commits libc-commits at lists.llvm.org
Mon Sep 14 11:57:55 PDT 2026


https://github.com/strel-12 updated https://github.com/llvm/llvm-project/pull/223490

>From 5b3033720cee17f63714b7783e9e49b5540a6433 Mon Sep 17 00:00:00 2001
From: Alex Strelnikov <strel at google.com>
Date: Mon, 14 Sep 2026 18:24:07 +0000
Subject: [PATCH 1/4] Add InlineAny utility in __support.

---
 libc/src/__support/CMakeLists.txt             |  9 +++
 .../type_traits/is_trivially_constructible.h  |  4 ++
 libc/src/__support/inline_any.h               | 56 +++++++++++++++++++
 libc/test/src/__support/CMakeLists.txt        | 11 ++++
 libc/test/src/__support/inline_any_test.cpp   | 43 ++++++++++++++
 5 files changed, 123 insertions(+)
 create mode 100644 libc/src/__support/inline_any.h
 create mode 100644 libc/test/src/__support/inline_any_test.cpp

diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index b93c88260cdc9..bef7acdaebb05 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -270,6 +270,15 @@ add_header_library(
     libc.hdr.stdint_proxy
 )
 
+add_header_library(
+  inline_any
+  HDRS
+    inline_any.h
+  DEPENDS
+    libc.src.__support.CPP.bit
+    libc.src.__support.CPP.type_traits
+)
+
 add_header_library(
   str_to_float
   HDRS
diff --git a/libc/src/__support/CPP/type_traits/is_trivially_constructible.h b/libc/src/__support/CPP/type_traits/is_trivially_constructible.h
index b801911038a90..64b974cb275be 100644
--- a/libc/src/__support/CPP/type_traits/is_trivially_constructible.h
+++ b/libc/src/__support/CPP/type_traits/is_trivially_constructible.h
@@ -19,6 +19,10 @@ template <class T, class... Args>
 struct is_trivially_constructible
     : integral_constant<bool, __is_trivially_constructible(T, Args...)> {};
 
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_trivially_constructible_v =
+    is_trivially_constructible<T>::value;
+
 } // namespace cpp
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/__support/inline_any.h b/libc/src/__support/inline_any.h
new file mode 100644
index 0000000000000..cc3c9b4bbdeb1
--- /dev/null
+++ b/libc/src/__support/inline_any.h
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// InlineAny utility template type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_INLINE_ANY_H
+#define LLVM_LIBC_SRC___SUPPORT_INLINE_ANY_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/type_traits.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// A utility providing inline storage for a type-erased value with trivial type.
+//
+// The maximum size and alignment of stored types is controlled by `Size` and
+// `Alignment`. Does not store or check any type information. Example:
+//
+//     InlineAny<20> any;
+//     any.store(5.0);
+//     double value = any.load<double>();
+template <size_t Size, size_t Alignment = alignof(max_align_t)>
+class InlineAny {
+  alignas(Alignment) char buffer[Size];
+
+public:
+  template <typename T> LIBC_INLINE void store(const T &value) {
+    static_assert(cpp::is_trivially_copyable_v<T> &&
+                  cpp::is_trivially_constructible_v<T> &&
+                  cpp::is_trivially_destructible_v<T> && sizeof(T) <= Size &&
+                  alignof(T) <= Alignment);
+    cpp::inline_copy<sizeof(T)>(reinterpret_cast<const char *>(&value), buffer);
+  }
+
+  template <typename T> LIBC_INLINE T load() const {
+    static_assert(cpp::is_trivially_copyable_v<T> &&
+                  cpp::is_trivially_constructible_v<T> &&
+                  cpp::is_trivially_destructible_v<T> && sizeof(T) <= Size &&
+                  alignof(T) <= Alignment);
+    T result;
+    cpp::inline_copy<sizeof(T)>(buffer, reinterpret_cast<char *>(&result));
+    return result;
+  }
+};
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_INLINE_ANY_H
diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt
index 3663b1774e211..5693608c2f67f 100644
--- a/libc/test/src/__support/CMakeLists.txt
+++ b/libc/test/src/__support/CMakeLists.txt
@@ -137,6 +137,17 @@ add_libc_test(
     libc.src.__support.uint128
 )
 
+add_libc_test(
+  inline_any_test
+  SUITE
+    libc-support-tests
+  SRCS
+    inline_any_test.cpp
+  DEPENDS
+    libc.src.__support.inline_any
+    libc.src.__support.uint128
+)
+
 add_libc_test(
   str_to_float_test
   SUITE
diff --git a/libc/test/src/__support/inline_any_test.cpp b/libc/test/src/__support/inline_any_test.cpp
new file mode 100644
index 0000000000000..795dcc733903e
--- /dev/null
+++ b/libc/test/src/__support/inline_any_test.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unit tests for InlineAny.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/inline_any.h"
+#include "src/__support/uint128.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+struct PageAlignedInt {
+  alignas(64) int value;
+};
+
+TEST(LlvmLibcInlineAnyTest, LoadAndStore) {
+  LIBC_NAMESPACE::InlineAny<16> any;
+
+  any.store(27);
+  EXPECT_EQ(any.load<int>(), 27);
+
+  any.store(-5.25);
+  EXPECT_FP_EQ(any.load<double>(), -5.25);
+
+  any.store(UInt128(1) << 75);
+  EXPECT_EQ(any.load<UInt128>(), UInt128(1) << 75);
+
+  LIBC_NAMESPACE::InlineAny<sizeof(PageAlignedInt), alignof(PageAlignedInt)>
+      overaligned_any;
+
+  overaligned_any.store(42);
+  EXPECT_EQ(overaligned_any.load<int>(), 42);
+
+  overaligned_any.store(PageAlignedInt{-17});
+  EXPECT_EQ(overaligned_any.load<PageAlignedInt>().value, -17);
+}

>From 0164cb8927e3510d6d17f3bad937fa5ef5525dde Mon Sep 17 00:00:00 2001
From: Alex Strelnikov <strel at google.com>
Date: Mon, 14 Sep 2026 18:46:02 +0000
Subject: [PATCH 2/4] Clarity comment wording

---
 libc/src/__support/inline_any.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/inline_any.h b/libc/src/__support/inline_any.h
index cc3c9b4bbdeb1..efc43e5c91538 100644
--- a/libc/src/__support/inline_any.h
+++ b/libc/src/__support/inline_any.h
@@ -22,7 +22,8 @@ namespace LIBC_NAMESPACE_DECL {
 // A utility providing inline storage for a type-erased value with trivial type.
 //
 // The maximum size and alignment of stored types is controlled by `Size` and
-// `Alignment`. Does not store or check any type information. Example:
+// `Alignment`. Does not store or check any type information for the saved value.
+// Example:
 //
 //     InlineAny<20> any;
 //     any.store(5.0);

>From 81232f8a54079b3d2bcae28abbbb680549ad420f Mon Sep 17 00:00:00 2001
From: Alex Strelnikov <strel at google.com>
Date: Mon, 14 Sep 2026 18:49:43 +0000
Subject: [PATCH 3/4] Format

---
 libc/src/__support/inline_any.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libc/src/__support/inline_any.h b/libc/src/__support/inline_any.h
index efc43e5c91538..2758a20ec15d2 100644
--- a/libc/src/__support/inline_any.h
+++ b/libc/src/__support/inline_any.h
@@ -22,8 +22,8 @@ namespace LIBC_NAMESPACE_DECL {
 // A utility providing inline storage for a type-erased value with trivial type.
 //
 // The maximum size and alignment of stored types is controlled by `Size` and
-// `Alignment`. Does not store or check any type information for the saved value.
-// Example:
+// `Alignment`. Does not store or check any type information for the saved
+// value. Example:
 //
 //     InlineAny<20> any;
 //     any.store(5.0);

>From a80c63af8e508edc83342ea1ddf1cafa8b56eb24 Mon Sep 17 00:00:00 2001
From: Alex Strelnikov <strel at google.com>
Date: Mon, 14 Sep 2026 18:57:35 +0000
Subject: [PATCH 4/4] Fix for platforms with alignof(max_align_t) = 8.

---
 libc/test/src/__support/inline_any_test.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/test/src/__support/inline_any_test.cpp b/libc/test/src/__support/inline_any_test.cpp
index 795dcc733903e..6feadd37b9c23 100644
--- a/libc/test/src/__support/inline_any_test.cpp
+++ b/libc/test/src/__support/inline_any_test.cpp
@@ -21,7 +21,7 @@ struct PageAlignedInt {
 };
 
 TEST(LlvmLibcInlineAnyTest, LoadAndStore) {
-  LIBC_NAMESPACE::InlineAny<16> any;
+  LIBC_NAMESPACE::InlineAny<sizeof(UInt128), alignof(UInt128)> any;
 
   any.store(27);
   EXPECT_EQ(any.load<int>(), 27);



More information about the libc-commits mailing list