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

via libc-commits libc-commits at lists.llvm.org
Mon Sep 14 11:47:35 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Alex Strelnikov (strel-12)

<details>
<summary>Changes</summary>

`InlinedAny` is essentially aligned storage with `load` and `store` functions to copy the value in or out of a member array.

The motivation is to use this type in place of `UInt128` for [`printf_core::BasicFormatSection::conv_val_raw`](https://github.com/llvm/llvm-project/blob/main/libc/src/__support/printf_core/core_structs.h#L98). Printf conversion values are currently stored into `conv_val_raw` with a mixture of `bit_cast` and `static_cast`. Signed integer values are often retrieved from `conv_val_raw` via a narrowing `static_cast` to the destination type, which is a bit brittle and not quite up-to-standard in terms of overflow.

Assisted-by: Automated tooling, human reviewed.

---
Full diff: https://github.com/llvm/llvm-project/pull/223490.diff


5 Files Affected:

- (modified) libc/src/__support/CMakeLists.txt (+9) 
- (modified) libc/src/__support/CPP/type_traits/is_trivially_constructible.h (+4) 
- (added) libc/src/__support/inline_any.h (+57) 
- (modified) libc/test/src/__support/CMakeLists.txt (+11) 
- (added) libc/test/src/__support/inline_any_test.cpp (+43) 


``````````diff
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..efc43e5c91538
--- /dev/null
+++ b/libc/src/__support/inline_any.h
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 for the saved value.
+// 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);
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/223490


More information about the libc-commits mailing list