[libcxx-commits] [libcxx] [libc++] Added segmented iterator for std::fill (PR #104680)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Sep 8 08:47:38 PDT 2024


https://github.com/NoumanAmir657 updated https://github.com/llvm/llvm-project/pull/104680

>From 17ff23114939701d7b666c9c809ecc3c4a350759 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Sat, 17 Aug 2024 23:18:52 +0500
Subject: [PATCH 01/24] [libcxx] Added segment iterator for fill

---
 libcxx/include/__algorithm/fill.h | 53 +++++++++++++++++++++++++++----
 1 file changed, 47 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 1ce3eadb013d05..3ba37e7260a4a2 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -21,25 +21,66 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 // fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
 
-template <class _ForwardIterator, class _Tp>
+template <
+    class _ForwardIterator,
+    class _Tp,
+    __enable_if_t<
+        is_same<typename iterator_traits<_ForwardIterator>::iterator_category, forward_iterator_tag>::value ||
+            is_same<typename iterator_traits<_ForwardIterator>::iterator_category, bidirectional_iterator_tag>::value,
+        int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) {
+__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
   for (; __first != __last; ++__first)
     *__first = __value;
 }
 
-template <class _RandomAccessIterator, class _Tp>
+template <class _RandomAccessIterator,
+          class _Tp,
+          __enable_if_t<(is_same<typename iterator_traits<_RandomAccessIterator>::iterator_category,
+                                 random_access_iterator_tag>::value ||
+                         is_same<typename iterator_traits<_RandomAccessIterator>::iterator_category,
+                                 contiguous_iterator_tag>::value) &&
+                            !__is_segmented_iterator<_RandomAccessIterator>::value,
+                        int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) {
+__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value) {
   std::fill_n(__first, __last - __first, __value);
 }
 
+template <class _SegmentedIterator,
+          class _Tp,
+          __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
+__fill(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value) {
+  using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
+
+  auto __sfirst = _Traits::__segment(__first);
+  auto __slast  = _Traits::__segment(__last);
+
+  // We are in a single segment, so we might not be at the beginning or end
+  if (__sfirst == __slast) {
+    __fill(_Traits::__local(__first), _Traits::__local(__last), __value);
+    return;
+  }
+
+  // We have more than one segment. Iterate over the first segment, since we might not start at the beginning
+  __fill(_Traits::__local(__first), _Traits::__end(__sfirst), __value);
+  ++__sfirst;
+  // iterate over the segments which are guaranteed to be completely in the range
+  while (__sfirst != __slast) {
+    __fill(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), __value);
+    ++__sfirst;
+  }
+  // iterate over the last segment
+  __fill(_Traits::__begin(__sfirst), _Traits::__local(__last), __value);
+}
+
 template <class _ForwardIterator, class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
-  std::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category());
+  std::__fill(__first, __last, __value);
 }
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP___ALGORITHM_FILL_H
+#endif // _LIBCPP___ALGORITHM_FILL_H
\ No newline at end of file

>From 8f32f1571ac198275ab483fa844f4b47ce4ab73b Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Sat, 17 Aug 2024 23:37:14 +0500
Subject: [PATCH 02/24] Fixed newline

---
 libcxx/include/__algorithm/fill.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 3ba37e7260a4a2..da2bda4713c373 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -83,4 +83,4 @@ fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP___ALGORITHM_FILL_H
\ No newline at end of file
+#endif // _LIBCPP___ALGORITHM_FILL_H

>From 58c23b8d4da14e522cf401adaa6005a285890025 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Sun, 18 Aug 2024 00:57:05 +0500
Subject: [PATCH 03/24] Fixed the logic of templates

---
 libcxx/include/__algorithm/fill.h | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index da2bda4713c373..b8d893e2ee7339 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -12,6 +12,7 @@
 #include <__algorithm/fill_n.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
+#include <__iterator/segmented_iterator.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -24,10 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <
     class _ForwardIterator,
     class _Tp,
-    __enable_if_t<
-        is_same<typename iterator_traits<_ForwardIterator>::iterator_category, forward_iterator_tag>::value ||
-            is_same<typename iterator_traits<_ForwardIterator>::iterator_category, bidirectional_iterator_tag>::value,
-        int> = 0>
+    __enable_if_t<!__has_random_access_iterator_category<_ForwardIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
   for (; __first != __last; ++__first)
@@ -36,12 +34,8 @@ __fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
 
 template <class _RandomAccessIterator,
           class _Tp,
-          __enable_if_t<(is_same<typename iterator_traits<_RandomAccessIterator>::iterator_category,
-                                 random_access_iterator_tag>::value ||
-                         is_same<typename iterator_traits<_RandomAccessIterator>::iterator_category,
-                                 contiguous_iterator_tag>::value) &&
-                            !__is_segmented_iterator<_RandomAccessIterator>::value,
-                        int> = 0>
+          __enable_if_t<__has_random_access_iterator_category<_RandomAccessIterator>::value &&
+                        !__is_segmented_iterator<_RandomAccessIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value) {
   std::fill_n(__first, __last - __first, __value);

>From eaf5ccbcaaa61a2593160500deb3bb060d142d83 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Sun, 18 Aug 2024 01:42:46 +0500
Subject: [PATCH 04/24] Used std::for_each to remove redundant code

---
 libcxx/include/__algorithm/fill.h | 49 ++++++++++++++++---------------
 1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index b8d893e2ee7339..32439f03dc9cff 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -10,6 +10,7 @@
 #define _LIBCPP___ALGORITHM_FILL_H
 
 #include <__algorithm/fill_n.h>
+#include <__algorithm/for_each.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/segmented_iterator.h>
@@ -22,10 +23,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 // fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
 
-template <
-    class _ForwardIterator,
-    class _Tp,
-    __enable_if_t<!__has_random_access_iterator_category<_ForwardIterator>::value, int> = 0>
+template < class _ForwardIterator,
+           class _Tp,
+           __enable_if_t<!__has_random_access_iterator_category<_ForwardIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
   for (; __first != __last; ++__first)
@@ -35,7 +35,8 @@ __fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
 template <class _RandomAccessIterator,
           class _Tp,
           __enable_if_t<__has_random_access_iterator_category<_RandomAccessIterator>::value &&
-                        !__is_segmented_iterator<_RandomAccessIterator>::value, int> = 0>
+                            !__is_segmented_iterator<_RandomAccessIterator>::value,
+                        int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value) {
   std::fill_n(__first, __last - __first, __value);
@@ -46,27 +47,29 @@ template <class _SegmentedIterator,
           __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value) {
-  using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
+  // using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
 
-  auto __sfirst = _Traits::__segment(__first);
-  auto __slast  = _Traits::__segment(__last);
+  // auto __sfirst = _Traits::__segment(__first);
+  // auto __slast  = _Traits::__segment(__last);
 
-  // We are in a single segment, so we might not be at the beginning or end
-  if (__sfirst == __slast) {
-    __fill(_Traits::__local(__first), _Traits::__local(__last), __value);
-    return;
-  }
+  // // We are in a single segment, so we might not be at the beginning or end
+  // if (__sfirst == __slast) {
+  //   __fill(_Traits::__local(__first), _Traits::__local(__last), __value);
+  //   return;
+  // }
 
-  // We have more than one segment. Iterate over the first segment, since we might not start at the beginning
-  __fill(_Traits::__local(__first), _Traits::__end(__sfirst), __value);
-  ++__sfirst;
-  // iterate over the segments which are guaranteed to be completely in the range
-  while (__sfirst != __slast) {
-    __fill(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), __value);
-    ++__sfirst;
-  }
-  // iterate over the last segment
-  __fill(_Traits::__begin(__sfirst), _Traits::__local(__last), __value);
+  // // We have more than one segment. Iterate over the first segment, since we might not start at the beginning
+  // __fill(_Traits::__local(__first), _Traits::__end(__sfirst), __value);
+  // ++__sfirst;
+  // // iterate over the segments which are guaranteed to be completely in the range
+  // while (__sfirst != __slast) {
+  //   __fill(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), __value);
+  //   ++__sfirst;
+  // }
+  // // iterate over the last segment
+  // __fill(_Traits::__begin(__sfirst), _Traits::__local(__last), __value);
+
+  std::for_each(__first, __last, [__value](_Tp& val) { val = __value; });
 }
 
 template <class _ForwardIterator, class _Tp>

>From 8cf639de652a1170b698e4bfe538c284327e9b80 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Sun, 18 Aug 2024 01:53:47 +0500
Subject: [PATCH 05/24] Fixed case

---
 libcxx/include/__algorithm/fill.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 32439f03dc9cff..df9eb6ed16aa23 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -69,7 +69,7 @@ __fill(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value
   // // iterate over the last segment
   // __fill(_Traits::__begin(__sfirst), _Traits::__local(__last), __value);
 
-  std::for_each(__first, __last, [__value](_Tp& val) { val = __value; });
+  std::for_each(__first, __last, [__value](_Tp& __val) { __val = __value; });
 }
 
 template <class _ForwardIterator, class _Tp>

>From 4659ba3c398f655496719c8bb247ecbcbf907ad2 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Thu, 22 Aug 2024 16:26:51 +0500
Subject: [PATCH 06/24] Added benchmark

---
 libcxx/include/__algorithm/fill.h             | 22 -------------------
 .../test/benchmarks/algorithms/fill.bench.cpp | 10 +++++++++
 2 files changed, 10 insertions(+), 22 deletions(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index df9eb6ed16aa23..41f37c46fe471d 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -47,28 +47,6 @@ template <class _SegmentedIterator,
           __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value) {
-  // using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
-
-  // auto __sfirst = _Traits::__segment(__first);
-  // auto __slast  = _Traits::__segment(__last);
-
-  // // We are in a single segment, so we might not be at the beginning or end
-  // if (__sfirst == __slast) {
-  //   __fill(_Traits::__local(__first), _Traits::__local(__last), __value);
-  //   return;
-  // }
-
-  // // We have more than one segment. Iterate over the first segment, since we might not start at the beginning
-  // __fill(_Traits::__local(__first), _Traits::__end(__sfirst), __value);
-  // ++__sfirst;
-  // // iterate over the segments which are guaranteed to be completely in the range
-  // while (__sfirst != __slast) {
-  //   __fill(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), __value);
-  //   ++__sfirst;
-  // }
-  // // iterate over the last segment
-  // __fill(_Traits::__begin(__sfirst), _Traits::__local(__last), __value);
-
   std::for_each(__first, __last, [__value](_Tp& __val) { __val = __value; });
 }
 
diff --git a/libcxx/test/benchmarks/algorithms/fill.bench.cpp b/libcxx/test/benchmarks/algorithms/fill.bench.cpp
index 40f37425c394cf..313fc7f849cbe5 100644
--- a/libcxx/test/benchmarks/algorithms/fill.bench.cpp
+++ b/libcxx/test/benchmarks/algorithms/fill.bench.cpp
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <benchmark/benchmark.h>
 #include <vector>
+#include <deque>
 
 static void bm_fill_n(benchmark::State& state) {
   std::vector<bool> vec1(state.range());
@@ -37,6 +38,15 @@ static void bm_fill(benchmark::State& state) {
 }
 BENCHMARK(bm_fill)->DenseRange(1, 8)->Range(16, 1 << 20);
 
+static void bm_deque_fill(benchmark::State& state) {
+  std::deque<bool> vec1(state.range());
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(vec1);
+    std::fill(vec1.begin(), vec1.end(), false);
+  }
+}
+BENCHMARK(bm_fill)->DenseRange(1, 8)->Range(16, 1 << 20);
+
 static void bm_ranges_fill(benchmark::State& state) {
   std::vector<bool> vec1(state.range());
   for (auto _ : state) {

>From cebfcdfd31f6676e2ede5ca4bcd0eeb6fb88b12c Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Sat, 24 Aug 2024 12:00:13 +0500
Subject: [PATCH 07/24] Added call to benchmark

---
 libcxx/include/__algorithm/fill.h                | 1 +
 libcxx/test/benchmarks/algorithms/fill.bench.cpp | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 41f37c46fe471d..954814ff4c00d1 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -59,3 +59,4 @@ fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___ALGORITHM_FILL_H
+
diff --git a/libcxx/test/benchmarks/algorithms/fill.bench.cpp b/libcxx/test/benchmarks/algorithms/fill.bench.cpp
index 313fc7f849cbe5..ccfb866c147b12 100644
--- a/libcxx/test/benchmarks/algorithms/fill.bench.cpp
+++ b/libcxx/test/benchmarks/algorithms/fill.bench.cpp
@@ -45,7 +45,7 @@ static void bm_deque_fill(benchmark::State& state) {
     std::fill(vec1.begin(), vec1.end(), false);
   }
 }
-BENCHMARK(bm_fill)->DenseRange(1, 8)->Range(16, 1 << 20);
+BENCHMARK(bm_deque_fill)->DenseRange(1, 8)->Range(16, 1 << 20);
 
 static void bm_ranges_fill(benchmark::State& state) {
   std::vector<bool> vec1(state.range());

>From a47ec99b6bbb59ef13d5e8c099204dec0e0af2c5 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Sat, 24 Aug 2024 12:24:48 +0500
Subject: [PATCH 08/24] Added release note

---
 libcxx/docs/ReleaseNotes/20.rst   | 3 +++
 libcxx/include/__algorithm/fill.h | 1 -
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index 93d6027291ad95..96c350a73e1c6e 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -48,6 +48,9 @@ Improvements and New Features
 
 - The ``lexicographical_compare`` and ``ranges::lexicographical_compare`` algorithms have been optimized for trivially
   equality comparable types, resulting in a performance improvement of up to 40x.
+  
+- ``std::fill`` has been optimized for segmented iterators like ``std::deque::iterator`` in C++23 and
+  later, which can lead up to 40x performance improvements.
 
 - The ``_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION`` macro has been added to make ``std::uncaught_exception`` available in C++20 and later modes.
 
diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 954814ff4c00d1..41f37c46fe471d 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -59,4 +59,3 @@ fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___ALGORITHM_FILL_H
-

>From 198fd74dc851251701e2a31f21cf0c0d3c88ca02 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Mon, 26 Aug 2024 09:57:13 +0500
Subject: [PATCH 09/24] Added tests

---
 .../alg.modifying.operations/alg.fill/fill.pass.cpp    | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp
index 481d565961b2b5..86cc7d46d15f65 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp
@@ -17,6 +17,7 @@
 #include <array>
 #include <cassert>
 #include <vector>
+#include <deque>
 
 #include "test_macros.h"
 #include "test_iterators.h"
@@ -101,5 +102,14 @@ int main(int, char**) {
   static_assert(test());
 #endif
 
+  // check that segmented iterators work properly
+  int sizes[] = {0, 1, 2, 1023, 1024, 1025, 2047, 2048, 2049};
+  for (const int size : sizes) {
+    std::deque<bool> in(size, false);
+    std::deque<bool> expected(size, true);
+    std::fill(in.begin(), in.end(), true);
+    assert(in == expected);
+  }
+
   return 0;
 }

>From 90c6b552eb681b2f6cc12958807e323cb3d00f5b Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Mon, 26 Aug 2024 11:08:05 +0500
Subject: [PATCH 10/24] Updated transitive includes

---
 libcxx/include/__algorithm/fill.h             |  1 +
 .../test/libcxx/transitive_includes/cxx03.csv | 21 ++-----------------
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 41f37c46fe471d..93aa980d8f12dc 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -14,6 +14,7 @@
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/segmented_iterator.h>
+#include <__type_traits/enable_if.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index fd2cd7f1c2d961..f4c88f7a3bf7ad 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -86,7 +86,6 @@ bit version
 bitset climits
 bitset concepts
 bitset cstddef
-bitset cstdint
 bitset cstdlib
 bitset cstring
 bitset cwchar
@@ -94,6 +93,7 @@ bitset initializer_list
 bitset iosfwd
 bitset limits
 bitset new
+bitset optional
 bitset stdexcept
 bitset string
 bitset string_view
@@ -250,21 +250,11 @@ experimental/simd limits
 experimental/utility utility
 filesystem compare
 filesystem concepts
-filesystem cstddef
-filesystem cstdint
 filesystem cstdlib
 filesystem cstring
-filesystem ctime
-filesystem iomanip
 filesystem iosfwd
-filesystem limits
-filesystem locale
 filesystem new
-filesystem ratio
-filesystem string
-filesystem string_view
 filesystem system_error
-filesystem type_traits
 filesystem version
 format array
 format cctype
@@ -798,15 +788,7 @@ stack version
 stdexcept cstdlib
 stdexcept exception
 stdexcept iosfwd
-stop_token atomic
-stop_token cstddef
-stop_token cstdint
-stop_token cstring
-stop_token ctime
 stop_token iosfwd
-stop_token limits
-stop_token ratio
-stop_token type_traits
 stop_token version
 streambuf cctype
 streambuf climits
@@ -988,6 +970,7 @@ valarray functional
 valarray initializer_list
 valarray limits
 valarray new
+valarray optional
 valarray stdexcept
 valarray type_traits
 valarray version

>From 50454f79b36468dae3a33227298d37ada1c5accd Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Mon, 26 Aug 2024 11:31:16 +0500
Subject: [PATCH 11/24] Fixed transitive includes

---
 .../test/libcxx/transitive_includes/cxx11.csv | 21 ++---------
 .../test/libcxx/transitive_includes/cxx14.csv | 36 +++++++------------
 .../test/libcxx/transitive_includes/cxx17.csv | 23 ++++++------
 .../test/libcxx/transitive_includes/cxx20.csv |  3 +-
 .../test/libcxx/transitive_includes/cxx23.csv |  3 +-
 .../test/libcxx/transitive_includes/cxx26.csv |  3 +-
 6 files changed, 33 insertions(+), 56 deletions(-)

diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index 04122fd0f4571a..e75a033838749d 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -86,7 +86,6 @@ bit version
 bitset climits
 bitset concepts
 bitset cstddef
-bitset cstdint
 bitset cstdlib
 bitset cstring
 bitset cwchar
@@ -94,6 +93,7 @@ bitset initializer_list
 bitset iosfwd
 bitset limits
 bitset new
+bitset optional
 bitset stdexcept
 bitset string
 bitset string_view
@@ -251,21 +251,11 @@ experimental/simd limits
 experimental/utility utility
 filesystem compare
 filesystem concepts
-filesystem cstddef
-filesystem cstdint
 filesystem cstdlib
 filesystem cstring
-filesystem ctime
-filesystem iomanip
 filesystem iosfwd
-filesystem limits
-filesystem locale
 filesystem new
-filesystem ratio
-filesystem string
-filesystem string_view
 filesystem system_error
-filesystem type_traits
 filesystem version
 format array
 format cctype
@@ -804,15 +794,7 @@ stack version
 stdexcept cstdlib
 stdexcept exception
 stdexcept iosfwd
-stop_token atomic
-stop_token cstddef
-stop_token cstdint
-stop_token cstring
-stop_token ctime
 stop_token iosfwd
-stop_token limits
-stop_token ratio
-stop_token type_traits
 stop_token version
 streambuf cctype
 streambuf climits
@@ -995,6 +977,7 @@ valarray functional
 valarray initializer_list
 valarray limits
 valarray new
+valarray optional
 valarray stdexcept
 valarray type_traits
 valarray version
diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index 42c742bead0c1f..6991f3ae3238e1 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -7,7 +7,6 @@ algorithm cstdint
 algorithm cstdlib
 algorithm cstring
 algorithm cwchar
-algorithm execution
 algorithm initializer_list
 algorithm iosfwd
 algorithm iterator
@@ -16,11 +15,11 @@ algorithm memory
 algorithm new
 algorithm optional
 algorithm stdexcept
+algorithm tuple
 algorithm type_traits
 algorithm utility
 algorithm version
 any atomic
-any chrono
 any concepts
 any cstddef
 any cstdint
@@ -87,7 +86,6 @@ bit version
 bitset climits
 bitset concepts
 bitset cstddef
-bitset cstdint
 bitset cstdlib
 bitset cstring
 bitset cwchar
@@ -95,6 +93,7 @@ bitset initializer_list
 bitset iosfwd
 bitset limits
 bitset new
+bitset optional
 bitset stdexcept
 bitset string
 bitset string_view
@@ -115,15 +114,21 @@ charconv new
 charconv type_traits
 charconv version
 chrono bit
+chrono charconv
+chrono cmath
 chrono compare
 chrono concepts
 chrono cstddef
 chrono cstdint
 chrono cstring
 chrono ctime
+chrono format
 chrono forward_list
 chrono limits
+chrono locale
+chrono ostream
 chrono ratio
+chrono sstream
 chrono stdexcept
 chrono string
 chrono string_view
@@ -194,6 +199,9 @@ condition_variable type_traits
 condition_variable typeinfo
 condition_variable version
 coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine cstring
 coroutine iosfwd
 coroutine limits
 coroutine type_traits
@@ -359,7 +367,6 @@ functional vector
 functional version
 future atomic
 future cerrno
-future chrono
 future cstddef
 future cstdint
 future cstdlib
@@ -589,6 +596,7 @@ numeric iterator
 numeric limits
 numeric new
 numeric optional
+numeric tuple
 numeric type_traits
 numeric version
 optional atomic
@@ -645,18 +653,11 @@ print stdexcept
 print string
 print string_view
 print version
-queue compare
-queue concepts
 queue cstddef
-queue cstdlib
 queue deque
-queue functional
 queue initializer_list
 queue limits
 queue new
-queue type_traits
-queue vector
-queue version
 random algorithm
 random climits
 random cmath
@@ -754,16 +755,12 @@ set stdexcept
 set tuple
 set type_traits
 set version
-shared_mutex cerrno
 shared_mutex cstddef
 shared_mutex ctime
 shared_mutex limits
 shared_mutex ratio
-shared_mutex stdexcept
 shared_mutex string
-shared_mutex system_error
 shared_mutex type_traits
-shared_mutex version
 source_location cstdint
 source_location version
 span array
@@ -807,15 +804,7 @@ stack version
 stdexcept cstdlib
 stdexcept exception
 stdexcept iosfwd
-stop_token atomic
-stop_token cstddef
-stop_token cstdint
-stop_token cstring
-stop_token ctime
 stop_token iosfwd
-stop_token limits
-stop_token ratio
-stop_token type_traits
 stop_token version
 streambuf cctype
 streambuf climits
@@ -998,6 +987,7 @@ valarray functional
 valarray initializer_list
 valarray limits
 valarray new
+valarray optional
 valarray stdexcept
 valarray type_traits
 valarray version
diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index bc0659127d4bf5..acfec9ec537b74 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -20,7 +20,6 @@ algorithm type_traits
 algorithm utility
 algorithm version
 any atomic
-any chrono
 any concepts
 any cstddef
 any cstdint
@@ -87,7 +86,6 @@ bit version
 bitset climits
 bitset concepts
 bitset cstddef
-bitset cstdint
 bitset cstdlib
 bitset cstring
 bitset cwchar
@@ -95,6 +93,7 @@ bitset initializer_list
 bitset iosfwd
 bitset limits
 bitset new
+bitset optional
 bitset stdexcept
 bitset string
 bitset string_view
@@ -115,15 +114,21 @@ charconv new
 charconv type_traits
 charconv version
 chrono bit
+chrono charconv
+chrono cmath
 chrono compare
 chrono concepts
 chrono cstddef
 chrono cstdint
 chrono cstring
 chrono ctime
+chrono format
 chrono forward_list
 chrono limits
+chrono locale
+chrono ostream
 chrono ratio
+chrono sstream
 chrono stdexcept
 chrono string
 chrono string_view
@@ -194,6 +199,9 @@ condition_variable type_traits
 condition_variable typeinfo
 condition_variable version
 coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine cstring
 coroutine iosfwd
 coroutine limits
 coroutine type_traits
@@ -359,7 +367,6 @@ functional vector
 functional version
 future atomic
 future cerrno
-future chrono
 future cstddef
 future cstdint
 future cstdlib
@@ -684,6 +691,7 @@ ranges optional
 ranges span
 ranges tuple
 ranges type_traits
+ranges variant
 ranges version
 ratio climits
 ratio cstdint
@@ -886,15 +894,7 @@ syncstream shared_mutex
 syncstream streambuf
 syncstream string
 system_error cerrno
-system_error compare
-system_error cstddef
-system_error cstdint
-system_error cstring
-system_error limits
-system_error stdexcept
 system_error string
-system_error type_traits
-system_error version
 thread array
 thread atomic
 thread cctype
@@ -999,6 +999,7 @@ valarray functional
 valarray initializer_list
 valarray limits
 valarray new
+valarray optional
 valarray stdexcept
 valarray type_traits
 valarray version
diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv
index fed0944f0219c4..cfbd3e38cd2553 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -86,7 +86,6 @@ bit version
 bitset climits
 bitset concepts
 bitset cstddef
-bitset cstdint
 bitset cstdlib
 bitset cstring
 bitset cwchar
@@ -94,6 +93,7 @@ bitset initializer_list
 bitset iosfwd
 bitset limits
 bitset new
+bitset optional
 bitset stdexcept
 bitset string
 bitset string_view
@@ -1006,6 +1006,7 @@ valarray functional
 valarray initializer_list
 valarray limits
 valarray new
+valarray optional
 valarray stdexcept
 valarray type_traits
 valarray version
diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv
index 53f99384a7f573..b957bd9b209fd3 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx23.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv
@@ -49,13 +49,13 @@ bit limits
 bit version
 bitset climits
 bitset cstddef
-bitset cstdint
 bitset cstring
 bitset cwchar
 bitset initializer_list
 bitset iosfwd
 bitset limits
 bitset new
+bitset optional
 bitset stdexcept
 bitset string
 bitset string_view
@@ -691,6 +691,7 @@ valarray cstdint
 valarray initializer_list
 valarray limits
 valarray new
+valarray optional
 valarray version
 variant compare
 variant cstddef
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index 53f99384a7f573..b957bd9b209fd3 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -49,13 +49,13 @@ bit limits
 bit version
 bitset climits
 bitset cstddef
-bitset cstdint
 bitset cstring
 bitset cwchar
 bitset initializer_list
 bitset iosfwd
 bitset limits
 bitset new
+bitset optional
 bitset stdexcept
 bitset string
 bitset string_view
@@ -691,6 +691,7 @@ valarray cstdint
 valarray initializer_list
 valarray limits
 valarray new
+valarray optional
 valarray version
 variant compare
 variant cstddef

>From 63b1294ca7efdb23c81c74872c46dd086503bc14 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Mon, 26 Aug 2024 12:37:02 +0500
Subject: [PATCH 12/24] Updated transitive includes

---
 .../test/libcxx/transitive_includes/cxx14.csv | 35 ++++++++-----------
 .../test/libcxx/transitive_includes/cxx17.csv | 28 ++++++---------
 2 files changed, 24 insertions(+), 39 deletions(-)

diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index 6991f3ae3238e1..c87cec73db5b6f 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -7,6 +7,7 @@ algorithm cstdint
 algorithm cstdlib
 algorithm cstring
 algorithm cwchar
+algorithm execution
 algorithm initializer_list
 algorithm iosfwd
 algorithm iterator
@@ -15,11 +16,11 @@ algorithm memory
 algorithm new
 algorithm optional
 algorithm stdexcept
-algorithm tuple
 algorithm type_traits
 algorithm utility
 algorithm version
 any atomic
+any chrono
 any concepts
 any cstddef
 any cstdint
@@ -114,21 +115,15 @@ charconv new
 charconv type_traits
 charconv version
 chrono bit
-chrono charconv
-chrono cmath
 chrono compare
 chrono concepts
 chrono cstddef
 chrono cstdint
 chrono cstring
 chrono ctime
-chrono format
 chrono forward_list
 chrono limits
-chrono locale
-chrono ostream
 chrono ratio
-chrono sstream
 chrono stdexcept
 chrono string
 chrono string_view
@@ -199,9 +194,6 @@ condition_variable type_traits
 condition_variable typeinfo
 condition_variable version
 coroutine compare
-coroutine cstddef
-coroutine cstdint
-coroutine cstring
 coroutine iosfwd
 coroutine limits
 coroutine type_traits
@@ -262,21 +254,11 @@ experimental/type_traits type_traits
 experimental/utility utility
 filesystem compare
 filesystem concepts
-filesystem cstddef
-filesystem cstdint
 filesystem cstdlib
 filesystem cstring
-filesystem ctime
-filesystem iomanip
 filesystem iosfwd
-filesystem limits
-filesystem locale
 filesystem new
-filesystem ratio
-filesystem string
-filesystem string_view
 filesystem system_error
-filesystem type_traits
 filesystem version
 format array
 format cctype
@@ -367,6 +349,7 @@ functional vector
 functional version
 future atomic
 future cerrno
+future chrono
 future cstddef
 future cstdint
 future cstdlib
@@ -596,7 +579,6 @@ numeric iterator
 numeric limits
 numeric new
 numeric optional
-numeric tuple
 numeric type_traits
 numeric version
 optional atomic
@@ -653,11 +635,18 @@ print stdexcept
 print string
 print string_view
 print version
+queue compare
+queue concepts
 queue cstddef
+queue cstdlib
 queue deque
+queue functional
 queue initializer_list
 queue limits
 queue new
+queue type_traits
+queue vector
+queue version
 random algorithm
 random climits
 random cmath
@@ -755,12 +744,16 @@ set stdexcept
 set tuple
 set type_traits
 set version
+shared_mutex cerrno
 shared_mutex cstddef
 shared_mutex ctime
 shared_mutex limits
 shared_mutex ratio
+shared_mutex stdexcept
 shared_mutex string
+shared_mutex system_error
 shared_mutex type_traits
+shared_mutex version
 source_location cstdint
 source_location version
 span array
diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index acfec9ec537b74..840c777bbf7b05 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -20,6 +20,7 @@ algorithm type_traits
 algorithm utility
 algorithm version
 any atomic
+any chrono
 any concepts
 any cstddef
 any cstdint
@@ -114,21 +115,15 @@ charconv new
 charconv type_traits
 charconv version
 chrono bit
-chrono charconv
-chrono cmath
 chrono compare
 chrono concepts
 chrono cstddef
 chrono cstdint
 chrono cstring
 chrono ctime
-chrono format
 chrono forward_list
 chrono limits
-chrono locale
-chrono ostream
 chrono ratio
-chrono sstream
 chrono stdexcept
 chrono string
 chrono string_view
@@ -199,9 +194,6 @@ condition_variable type_traits
 condition_variable typeinfo
 condition_variable version
 coroutine compare
-coroutine cstddef
-coroutine cstdint
-coroutine cstring
 coroutine iosfwd
 coroutine limits
 coroutine type_traits
@@ -367,6 +359,7 @@ functional vector
 functional version
 future atomic
 future cerrno
+future chrono
 future cstddef
 future cstdint
 future cstdlib
@@ -691,7 +684,6 @@ ranges optional
 ranges span
 ranges tuple
 ranges type_traits
-ranges variant
 ranges version
 ratio climits
 ratio cstdint
@@ -816,15 +808,7 @@ stack version
 stdexcept cstdlib
 stdexcept exception
 stdexcept iosfwd
-stop_token atomic
-stop_token cstddef
-stop_token cstdint
-stop_token cstring
-stop_token ctime
 stop_token iosfwd
-stop_token limits
-stop_token ratio
-stop_token type_traits
 stop_token version
 streambuf cctype
 streambuf climits
@@ -894,7 +878,15 @@ syncstream shared_mutex
 syncstream streambuf
 syncstream string
 system_error cerrno
+system_error compare
+system_error cstddef
+system_error cstdint
+system_error cstring
+system_error limits
+system_error stdexcept
 system_error string
+system_error type_traits
+system_error version
 thread array
 thread atomic
 thread cctype

>From 01c2351887e7112235dece96e1744b8f2523629a Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Mon, 26 Aug 2024 16:38:29 +0500
Subject: [PATCH 13/24] Added functor

---
 libcxx/include/__algorithm/fill.h | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 93aa980d8f12dc..52f7bd7b15bae2 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -43,12 +43,21 @@ __fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& _
   std::fill_n(__first, __last - __first, __value);
 }
 
+template <class _Tp>
+struct __fill_segment {
+  const _Tp& __value_;
+
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __fill_segment(const _Tp& __value) : __value_(__value) {}
+
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void operator()(_Tp& __val) const { __val = __value_; }
+};
+
 template <class _SegmentedIterator,
           class _Tp,
           __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value) {
-  std::for_each(__first, __last, [__value](_Tp& __val) { __val = __value; });
+  std::for_each(__first, __last, __fill_segment<_Tp>(__value));
 }
 
 template <class _ForwardIterator, class _Tp>

>From 9e6ca5e04fe9120d9945e8e46c1ea0fcaabc276b Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Mon, 26 Aug 2024 18:04:35 +0500
Subject: [PATCH 14/24] Fixed

---
 libcxx/include/__algorithm/fill.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 52f7bd7b15bae2..405b1dfb419600 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -49,7 +49,7 @@ struct __fill_segment {
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __fill_segment(const _Tp& __value) : __value_(__value) {}
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void operator()(_Tp& __val) const { __val = __value_; }
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(_Tp& __val) const { __val = __value_; }
 };
 
 template <class _SegmentedIterator,

>From b9db25e9c2c4a5214dabc33b30f48a3ea7f63397 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Wed, 28 Aug 2024 18:44:31 +0500
Subject: [PATCH 15/24] Optimized fill_n

---
 libcxx/include/__algorithm/fill.h             | 15 ++++----------
 libcxx/include/__algorithm/fill_n.h           | 20 +++++++++++++++++--
 .../test/benchmarks/algorithms/fill.bench.cpp |  9 +++++++++
 .../alg.fill/fill_n.pass.cpp                  | 13 ++++++++++++
 4 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 405b1dfb419600..fb84c6b78f6d46 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -9,7 +9,6 @@
 #ifndef _LIBCPP___ALGORITHM_FILL_H
 #define _LIBCPP___ALGORITHM_FILL_H
 
-#include <__algorithm/fill_n.h>
 #include <__algorithm/for_each.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
@@ -23,6 +22,9 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
+template <class _OutputIterator, class _Size, class _Tp>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
+fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
 
 template < class _ForwardIterator,
            class _Tp,
@@ -43,21 +45,12 @@ __fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& _
   std::fill_n(__first, __last - __first, __value);
 }
 
-template <class _Tp>
-struct __fill_segment {
-  const _Tp& __value_;
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __fill_segment(const _Tp& __value) : __value_(__value) {}
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(_Tp& __val) const { __val = __value_; }
-};
-
 template <class _SegmentedIterator,
           class _Tp,
           __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value) {
-  std::for_each(__first, __last, __fill_segment<_Tp>(__value));
+  std::for_each(__first, __last, [__value](_Tp& __val) { __val = __value; });
 }
 
 template <class _ForwardIterator, class _Tp>
diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h
index f29633f88087f0..817a5578786246 100644
--- a/libcxx/include/__algorithm/fill_n.h
+++ b/libcxx/include/__algorithm/fill_n.h
@@ -15,6 +15,8 @@
 #include <__iterator/iterator_traits.h>
 #include <__memory/pointer_traits.h>
 #include <__utility/convert_to_integral.h>
+#include <__iterator/segmented_iterator.h>
+#include <__type_traits/enable_if.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -26,8 +28,15 @@ _LIBCPP_PUSH_MACROS
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
+fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
 
-template <class _OutputIterator, class _Size, class _Tp>
+template <class _OutputIterator, class _Size, class _Tp, enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int> = 0>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
+__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
+
+template <class _OutputIterator, class _Size, class _Tp, enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
 
@@ -77,7 +86,7 @@ __fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) {
   return __first + __n;
 }
 
-template <class _OutputIterator, class _Size, class _Tp>
+template <class _OutputIterator, class _Size, class _Tp, enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int>>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
   for (; __n > 0; ++__first, (void)--__n)
@@ -85,6 +94,13 @@ __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
   return __first;
 }
 
+template <class _OutputIterator, class _Size, class _Tp, enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int>>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
+__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
+  std::fill(__first, __first + __n, __value);
+  return __n > 0 ? __first + __n : __first;
+}
+
 template <class _OutputIterator, class _Size, class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
diff --git a/libcxx/test/benchmarks/algorithms/fill.bench.cpp b/libcxx/test/benchmarks/algorithms/fill.bench.cpp
index ccfb866c147b12..6b65755e3ce9cd 100644
--- a/libcxx/test/benchmarks/algorithms/fill.bench.cpp
+++ b/libcxx/test/benchmarks/algorithms/fill.bench.cpp
@@ -20,6 +20,15 @@ static void bm_fill_n(benchmark::State& state) {
 }
 BENCHMARK(bm_fill_n)->DenseRange(1, 8)->Range(16, 1 << 20);
 
+static void bm_deque_fill_n(benchmark::State& state) {
+  std::deque<bool> vec1(state.range());
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(vec1);
+    benchmark::DoNotOptimize(std::fill_n(vec1.begin(), vec1.size(), false));
+  }
+}
+BENCHMARK(bm_deque_fill_n)->DenseRange(1, 8)->Range(16, 1 << 20);
+
 static void bm_ranges_fill_n(benchmark::State& state) {
   std::vector<bool> vec1(state.range());
   for (auto _ : state) {
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
index 7d6770de702bf3..ef4a666834b2e4 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <algorithm>
 #include <cassert>
+#include <deque>
 
 #include "test_macros.h"
 #include "test_iterators.h"
@@ -144,6 +145,16 @@ void test6()
   std::fill_n(&foo[0], UDI(5), Storage());
 }
 
+void test_deque() {
+    std::deque<int> dq(5);
+    std::fill_n(dq.begin(), dq.size(), 4);
+    assert(dq[0] == 4);
+    assert(dq[1] == 4);
+    assert(dq[2] == 4);
+    assert(dq[3] == 4);
+    assert(dq[4] == 4);
+}   
+
 
 int main(int, char**)
 {
@@ -166,6 +177,8 @@ int main(int, char**)
     test5();
     test6();
 
+    test_deque();
+
 #if TEST_STD_VER > 17
     static_assert(test_constexpr());
 #endif

>From 5afafa963e2e64a4a097dcc9cade000d26c7ba02 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Wed, 28 Aug 2024 19:05:08 +0500
Subject: [PATCH 16/24] Formatted

---
 libcxx/include/__algorithm/fill_n.h | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h
index 817a5578786246..efa549481c98fb 100644
--- a/libcxx/include/__algorithm/fill_n.h
+++ b/libcxx/include/__algorithm/fill_n.h
@@ -13,10 +13,10 @@
 #include <__config>
 #include <__fwd/bit_reference.h>
 #include <__iterator/iterator_traits.h>
-#include <__memory/pointer_traits.h>
-#include <__utility/convert_to_integral.h>
 #include <__iterator/segmented_iterator.h>
+#include <__memory/pointer_traits.h>
 #include <__type_traits/enable_if.h>
+#include <__utility/convert_to_integral.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -32,11 +32,17 @@ template <class _ForwardIterator, class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
 
-template <class _OutputIterator, class _Size, class _Tp, enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int> = 0>
+template <class _OutputIterator,
+          class _Size,
+          class _Tp,
+          enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
 
-template <class _OutputIterator, class _Size, class _Tp, enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int> = 0>
+template <class _OutputIterator,
+          class _Size,
+          class _Tp,
+          enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
 
@@ -86,7 +92,10 @@ __fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) {
   return __first + __n;
 }
 
-template <class _OutputIterator, class _Size, class _Tp, enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int>>
+template <class _OutputIterator,
+          class _Size,
+          class _Tp,
+          enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int>>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
   for (; __n > 0; ++__first, (void)--__n)
@@ -94,7 +103,10 @@ __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
   return __first;
 }
 
-template <class _OutputIterator, class _Size, class _Tp, enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int>>
+template <class _OutputIterator,
+          class _Size,
+          class _Tp,
+          enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int>>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
   std::fill(__first, __first + __n, __value);

>From cb29f67d168a74460db9f04d8e3fd928c44abdef Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Wed, 28 Aug 2024 19:13:23 +0500
Subject: [PATCH 17/24] Formatted

---
 .../alg.fill/fill_n.pass.cpp                  | 215 ++++++++----------
 1 file changed, 98 insertions(+), 117 deletions(-)

diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
index ef4a666834b2e4..89c7b854586711 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
@@ -23,164 +23,145 @@
 
 #if TEST_STD_VER > 17
 TEST_CONSTEXPR bool test_constexpr() {
-    const std::size_t N = 5;
-    int ib[] = {0, 0, 0, 0, 0, 0}; // one bigger than N
-
-    auto it = std::fill_n(std::begin(ib), N, 5);
-    return it == (std::begin(ib) + N)
-        && std::all_of(std::begin(ib), it, [](int a) {return a == 5; })
-        && *it == 0 // don't overwrite the last value in the output array
-        ;
-    }
+  const std::size_t N = 5;
+  int ib[]            = {0, 0, 0, 0, 0, 0}; // one bigger than N
+
+  auto it = std::fill_n(std::begin(ib), N, 5);
+  return it == (std::begin(ib) + N) && std::all_of(std::begin(ib), it, [](int a) { return a == 5; }) &&
+       *it == 0 // don't overwrite the last value in the output array
+      ;
+}
 #endif
 
 typedef UserDefinedIntegral<unsigned> UDI;
 
 template <class Iter>
-void
-test_char()
-{
-    char a[4] = {};
-    Iter it = std::fill_n(Iter(a), UDI(4), char(1));
-    assert(base(it) == a + 4);
-    assert(a[0] == 1);
-    assert(a[1] == 1);
-    assert(a[2] == 1);
-    assert(a[3] == 1);
+void test_char() {
+  char a[4] = {};
+  Iter it   = std::fill_n(Iter(a), UDI(4), char(1));
+  assert(base(it) == a + 4);
+  assert(a[0] == 1);
+  assert(a[1] == 1);
+  assert(a[2] == 1);
+  assert(a[3] == 1);
 }
 
 template <class Iter>
-void
-test_int()
-{
-    int a[4] = {};
-    Iter it = std::fill_n(Iter(a), UDI(4), 1);
-    assert(base(it) == a + 4);
-    assert(a[0] == 1);
-    assert(a[1] == 1);
-    assert(a[2] == 1);
-    assert(a[3] == 1);
+void test_int() {
+  int a[4] = {};
+  Iter it  = std::fill_n(Iter(a), UDI(4), 1);
+  assert(base(it) == a + 4);
+  assert(a[0] == 1);
+  assert(a[1] == 1);
+  assert(a[2] == 1);
+  assert(a[3] == 1);
 }
 
-void
-test_int_array()
-{
-    int a[4] = {};
-    assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
-    assert(a[0] == 1);
-    assert(a[1] == 1);
-    assert(a[2] == 1);
-    assert(a[3] == 1);
+void test_int_array() {
+  int a[4] = {};
+  assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
+  assert(a[0] == 1);
+  assert(a[1] == 1);
+  assert(a[2] == 1);
+  assert(a[3] == 1);
 }
 
 struct source {
-    source() : i(0) { }
+  source() : i(0) {}
 
-    operator int() const { return i++; }
-    mutable int i;
+  operator int() const { return i++; }
+  mutable int i;
 };
 
-void
-test_int_array_struct_source()
-{
-    int a[4] = {};
-    assert(std::fill_n(a, UDI(4), source()) == a + 4);
-    assert(a[0] == 0);
-    assert(a[1] == 1);
-    assert(a[2] == 2);
-    assert(a[3] == 3);
+void test_int_array_struct_source() {
+  int a[4] = {};
+  assert(std::fill_n(a, UDI(4), source()) == a + 4);
+  assert(a[0] == 0);
+  assert(a[1] == 1);
+  assert(a[2] == 2);
+  assert(a[3] == 3);
 }
 
 struct test1 {
-    test1() : c(0) { }
-    test1(char xc) : c(xc + 1) { }
-    char c;
+  test1() : c(0) {}
+  test1(char xc) : c(xc + 1) {}
+  char c;
 };
 
-void
-test_struct_array()
-{
-    test1 test1a[4] = {};
-    assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
-    assert(test1a[0].c == 11);
-    assert(test1a[1].c == 11);
-    assert(test1a[2].c == 11);
-    assert(test1a[3].c == 11);
+void test_struct_array() {
+  test1 test1a[4] = {};
+  assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
+  assert(test1a[0].c == 11);
+  assert(test1a[1].c == 11);
+  assert(test1a[2].c == 11);
+  assert(test1a[3].c == 11);
 }
 
-class A
-{
-    char a_;
+class A {
+  char a_;
+
 public:
-    A() {}
-    explicit A(char a) : a_(a) {}
-    operator unsigned char() const {return 'b';}
+  A() {}
+  explicit A(char a) : a_(a) {}
+  operator unsigned char() const { return 'b'; }
 
-    friend bool operator==(const A& x, const A& y)
-        {return x.a_ == y.a_;}
+  friend bool operator==(const A& x, const A& y) { return x.a_ == y.a_; }
 };
 
-void
-test5()
-{
-    A a[3];
-    assert(std::fill_n(&a[0], UDI(3), A('a')) == a+3);
-    assert(a[0] == A('a'));
-    assert(a[1] == A('a'));
-    assert(a[2] == A('a'));
+void test5() {
+  A a[3];
+  assert(std::fill_n(&a[0], UDI(3), A('a')) == a + 3);
+  assert(a[0] == A('a'));
+  assert(a[1] == A('a'));
+  assert(a[2] == A('a'));
 }
 
-struct Storage
-{
-  union
-  {
+struct Storage {
+  union {
     unsigned char a;
     unsigned char b;
   };
 };
 
-void test6()
-{
+void test6() {
   Storage foo[5];
   std::fill_n(&foo[0], UDI(5), Storage());
 }
 
 void test_deque() {
-    std::deque<int> dq(5);
-    std::fill_n(dq.begin(), dq.size(), 4);
-    assert(dq[0] == 4);
-    assert(dq[1] == 4);
-    assert(dq[2] == 4);
-    assert(dq[3] == 4);
-    assert(dq[4] == 4);
-}   
-
-
-int main(int, char**)
-{
-    test_char<cpp17_output_iterator<char*> >();
-    test_char<forward_iterator<char*> >();
-    test_char<bidirectional_iterator<char*> >();
-    test_char<random_access_iterator<char*> >();
-    test_char<char*>();
-
-    test_int<cpp17_output_iterator<int*> >();
-    test_int<forward_iterator<int*> >();
-    test_int<bidirectional_iterator<int*> >();
-    test_int<random_access_iterator<int*> >();
-    test_int<int*>();
-
-    test_int_array();
-    test_int_array_struct_source();
-    test_struct_array();
-
-    test5();
-    test6();
-
-    test_deque();
+  std::deque<int> dq(5);
+  std::fill_n(dq.begin(), dq.size(), 4);
+  assert(dq[0] == 4);
+  assert(dq[1] == 4);
+  assert(dq[2] == 4);
+  assert(dq[3] == 4);
+  assert(dq[4] == 4);
+}
+
+int main(int, char**) {
+  test_char<cpp17_output_iterator<char*> >();
+  test_char<forward_iterator<char*> >();
+  test_char<bidirectional_iterator<char*> >();
+  test_char<random_access_iterator<char*> >();
+  test_char<char*>();
+
+  test_int<cpp17_output_iterator<int*> >();
+  test_int<forward_iterator<int*> >();
+  test_int<bidirectional_iterator<int*> >();
+  test_int<random_access_iterator<int*> >();
+  test_int<int*>();
+
+  test_int_array();
+  test_int_array_struct_source();
+  test_struct_array();
+
+  test5();
+  test6();
+
+  test_deque();
 
 #if TEST_STD_VER > 17
-    static_assert(test_constexpr());
+  static_assert(test_constexpr());
 #endif
 
   return 0;

>From 290ee3094fc38bea085345dac9c30094c564c1fd Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Wed, 28 Aug 2024 19:19:11 +0500
Subject: [PATCH 18/24] Fixed

---
 libcxx/include/__algorithm/fill_n.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h
index efa549481c98fb..f18569748469b0 100644
--- a/libcxx/include/__algorithm/fill_n.h
+++ b/libcxx/include/__algorithm/fill_n.h
@@ -35,14 +35,14 @@ fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
 template <class _OutputIterator,
           class _Size,
           class _Tp,
-          enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int> = 0>
+          __enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
 
 template <class _OutputIterator,
           class _Size,
           class _Tp,
-          enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int> = 0>
+          __enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
 
@@ -95,7 +95,7 @@ __fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) {
 template <class _OutputIterator,
           class _Size,
           class _Tp,
-          enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int>>
+          __enable_if_t<!__is_segmented_iterator<_OutputIterator>::value, int> >
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
   for (; __n > 0; ++__first, (void)--__n)
@@ -106,7 +106,7 @@ __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
 template <class _OutputIterator,
           class _Size,
           class _Tp,
-          enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int>>
+          __enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int> >
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
   std::fill(__first, __first + __n, __value);

>From a6d889dd1a35fa2c186dbf2e38f07b3e822b76ae Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Wed, 28 Aug 2024 20:29:00 +0500
Subject: [PATCH 19/24] using for_each for fill_n

---
 libcxx/include/__algorithm/fill.h                | 4 +---
 libcxx/include/__algorithm/fill_n.h              | 6 ++----
 libcxx/test/libcxx/transitive_includes/cxx03.csv | 6 +++++-
 libcxx/test/libcxx/transitive_includes/cxx11.csv | 6 +++++-
 libcxx/test/libcxx/transitive_includes/cxx14.csv | 6 +++++-
 libcxx/test/libcxx/transitive_includes/cxx17.csv | 7 ++++++-
 libcxx/test/libcxx/transitive_includes/cxx20.csv | 7 ++++++-
 libcxx/test/libcxx/transitive_includes/cxx23.csv | 7 ++++++-
 libcxx/test/libcxx/transitive_includes/cxx26.csv | 7 ++++++-
 9 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index fb84c6b78f6d46..93aa980d8f12dc 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -9,6 +9,7 @@
 #ifndef _LIBCPP___ALGORITHM_FILL_H
 #define _LIBCPP___ALGORITHM_FILL_H
 
+#include <__algorithm/fill_n.h>
 #include <__algorithm/for_each.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
@@ -22,9 +23,6 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
-template <class _OutputIterator, class _Size, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
-fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
 
 template < class _ForwardIterator,
            class _Tp,
diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h
index f18569748469b0..cb5f00dfd2c826 100644
--- a/libcxx/include/__algorithm/fill_n.h
+++ b/libcxx/include/__algorithm/fill_n.h
@@ -9,6 +9,7 @@
 #ifndef _LIBCPP___ALGORITHM_FILL_N_H
 #define _LIBCPP___ALGORITHM_FILL_N_H
 
+#include <__algorithm/for_each.h>
 #include <__algorithm/min.h>
 #include <__config>
 #include <__fwd/bit_reference.h>
@@ -28,9 +29,6 @@ _LIBCPP_PUSH_MACROS
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 // fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
-template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
 
 template <class _OutputIterator,
           class _Size,
@@ -109,7 +107,7 @@ template <class _OutputIterator,
           __enable_if_t<__is_segmented_iterator<_OutputIterator>::value, int> >
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
-  std::fill(__first, __first + __n, __value);
+  std::for_each(__first, __first + __n, [__value](_Tp& __val) { __val = __value; });
   return __n > 0 ? __first + __n : __first;
 }
 
diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index f4c88f7a3bf7ad..d0647456134ca1 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -47,6 +47,7 @@ array initializer_list
 array iterator
 array limits
 array new
+array optional
 array stdexcept
 array type_traits
 array utility
@@ -209,7 +210,6 @@ deque concepts
 deque cstddef
 deque cstdint
 deque cstdlib
-deque cstring
 deque cwchar
 deque functional
 deque initializer_list
@@ -217,6 +217,7 @@ deque iosfwd
 deque iterator
 deque limits
 deque new
+deque optional
 deque stdexcept
 deque tuple
 deque type_traits
@@ -821,6 +822,7 @@ string iosfwd
 string iterator
 string limits
 string new
+string optional
 string stdexcept
 string string_view
 string tuple
@@ -842,6 +844,7 @@ string_view iosfwd
 string_view iterator
 string_view limits
 string_view new
+string_view optional
 string_view stdexcept
 string_view type_traits
 string_view version
@@ -1006,6 +1009,7 @@ vector iosfwd
 vector limits
 vector locale
 vector new
+vector optional
 vector stdexcept
 vector string
 vector string_view
diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index e75a033838749d..f645f147596158 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -47,6 +47,7 @@ array initializer_list
 array iterator
 array limits
 array new
+array optional
 array stdexcept
 array type_traits
 array utility
@@ -210,7 +211,6 @@ deque concepts
 deque cstddef
 deque cstdint
 deque cstdlib
-deque cstring
 deque cwchar
 deque functional
 deque initializer_list
@@ -218,6 +218,7 @@ deque iosfwd
 deque iterator
 deque limits
 deque new
+deque optional
 deque stdexcept
 deque tuple
 deque type_traits
@@ -828,6 +829,7 @@ string iosfwd
 string iterator
 string limits
 string new
+string optional
 string stdexcept
 string string_view
 string tuple
@@ -849,6 +851,7 @@ string_view iosfwd
 string_view iterator
 string_view limits
 string_view new
+string_view optional
 string_view stdexcept
 string_view type_traits
 string_view version
@@ -1013,6 +1016,7 @@ vector iosfwd
 vector limits
 vector locale
 vector new
+vector optional
 vector stdexcept
 vector string
 vector string_view
diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index c87cec73db5b6f..ba9d33b7b8facc 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -48,6 +48,7 @@ array initializer_list
 array iterator
 array limits
 array new
+array optional
 array stdexcept
 array type_traits
 array utility
@@ -211,7 +212,6 @@ deque concepts
 deque cstddef
 deque cstdint
 deque cstdlib
-deque cstring
 deque cwchar
 deque functional
 deque initializer_list
@@ -219,6 +219,7 @@ deque iosfwd
 deque iterator
 deque limits
 deque new
+deque optional
 deque stdexcept
 deque tuple
 deque type_traits
@@ -831,6 +832,7 @@ string iosfwd
 string iterator
 string limits
 string new
+string optional
 string stdexcept
 string string_view
 string tuple
@@ -852,6 +854,7 @@ string_view iosfwd
 string_view iterator
 string_view limits
 string_view new
+string_view optional
 string_view stdexcept
 string_view type_traits
 string_view version
@@ -1016,6 +1019,7 @@ vector iosfwd
 vector limits
 vector locale
 vector new
+vector optional
 vector stdexcept
 vector string
 vector string_view
diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index 840c777bbf7b05..8b35d4e09b442e 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -48,6 +48,7 @@ array initializer_list
 array iterator
 array limits
 array new
+array optional
 array stdexcept
 array type_traits
 array utility
@@ -211,7 +212,6 @@ deque concepts
 deque cstddef
 deque cstdint
 deque cstdlib
-deque cstring
 deque cwchar
 deque functional
 deque initializer_list
@@ -219,6 +219,7 @@ deque iosfwd
 deque iterator
 deque limits
 deque new
+deque optional
 deque stdexcept
 deque tuple
 deque type_traits
@@ -349,6 +350,7 @@ functional iosfwd
 functional limits
 functional memory
 functional new
+functional optional
 functional stdexcept
 functional tuple
 functional type_traits
@@ -842,6 +844,7 @@ string iosfwd
 string iterator
 string limits
 string new
+string optional
 string stdexcept
 string string_view
 string tuple
@@ -863,6 +866,7 @@ string_view iosfwd
 string_view iterator
 string_view limits
 string_view new
+string_view optional
 string_view stdexcept
 string_view type_traits
 string_view version
@@ -1027,6 +1031,7 @@ vector iosfwd
 vector limits
 vector locale
 vector new
+vector optional
 vector stdexcept
 vector string
 vector string_view
diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv
index cfbd3e38cd2553..7d61ed365fb8ea 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -47,6 +47,7 @@ array initializer_list
 array iterator
 array limits
 array new
+array optional
 array stdexcept
 array type_traits
 array utility
@@ -219,7 +220,6 @@ deque concepts
 deque cstddef
 deque cstdint
 deque cstdlib
-deque cstring
 deque cwchar
 deque functional
 deque initializer_list
@@ -227,6 +227,7 @@ deque iosfwd
 deque iterator
 deque limits
 deque new
+deque optional
 deque stdexcept
 deque tuple
 deque type_traits
@@ -357,6 +358,7 @@ functional iosfwd
 functional limits
 functional memory
 functional new
+functional optional
 functional stdexcept
 functional tuple
 functional type_traits
@@ -858,6 +860,7 @@ string iosfwd
 string iterator
 string limits
 string new
+string optional
 string stdexcept
 string string_view
 string tuple
@@ -879,6 +882,7 @@ string_view iosfwd
 string_view iterator
 string_view limits
 string_view new
+string_view optional
 string_view stdexcept
 string_view type_traits
 string_view version
@@ -1042,6 +1046,7 @@ vector iosfwd
 vector limits
 vector locale
 vector new
+vector optional
 vector stdexcept
 vector string
 vector string_view
diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv
index b957bd9b209fd3..43171c13833eb0 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx23.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv
@@ -27,6 +27,7 @@ array cwchar
 array initializer_list
 array limits
 array new
+array optional
 array stdexcept
 array version
 atomic cstddef
@@ -139,11 +140,11 @@ cwctype cctype
 deque compare
 deque cstddef
 deque cstdint
-deque cstring
 deque cwchar
 deque initializer_list
 deque limits
 deque new
+deque optional
 deque stdexcept
 deque tuple
 deque version
@@ -235,6 +236,7 @@ functional cstring
 functional initializer_list
 functional limits
 functional new
+functional optional
 functional tuple
 functional typeinfo
 functional unordered_map
@@ -588,6 +590,7 @@ string initializer_list
 string iosfwd
 string limits
 string new
+string optional
 string stdexcept
 string string_view
 string tuple
@@ -602,6 +605,7 @@ string_view initializer_list
 string_view iosfwd
 string_view limits
 string_view new
+string_view optional
 string_view stdexcept
 string_view version
 strstream istream
@@ -715,6 +719,7 @@ vector cwchar
 vector initializer_list
 vector limits
 vector new
+vector optional
 vector stdexcept
 vector string
 vector string_view
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index b957bd9b209fd3..43171c13833eb0 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -27,6 +27,7 @@ array cwchar
 array initializer_list
 array limits
 array new
+array optional
 array stdexcept
 array version
 atomic cstddef
@@ -139,11 +140,11 @@ cwctype cctype
 deque compare
 deque cstddef
 deque cstdint
-deque cstring
 deque cwchar
 deque initializer_list
 deque limits
 deque new
+deque optional
 deque stdexcept
 deque tuple
 deque version
@@ -235,6 +236,7 @@ functional cstring
 functional initializer_list
 functional limits
 functional new
+functional optional
 functional tuple
 functional typeinfo
 functional unordered_map
@@ -588,6 +590,7 @@ string initializer_list
 string iosfwd
 string limits
 string new
+string optional
 string stdexcept
 string string_view
 string tuple
@@ -602,6 +605,7 @@ string_view initializer_list
 string_view iosfwd
 string_view limits
 string_view new
+string_view optional
 string_view stdexcept
 string_view version
 strstream istream
@@ -715,6 +719,7 @@ vector cwchar
 vector initializer_list
 vector limits
 vector new
+vector optional
 vector stdexcept
 vector string
 vector string_view

>From 186c516f7cd1584c1808eb513d13bc3b92997140 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Wed, 28 Aug 2024 23:11:05 +0500
Subject: [PATCH 20/24] Updated transitive includes

---
 libcxx/test/libcxx/transitive_includes/cxx17.csv | 1 -
 libcxx/test/libcxx/transitive_includes/cxx20.csv | 1 -
 2 files changed, 2 deletions(-)

diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index 8b35d4e09b442e..b6e2e85d6952d5 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -345,7 +345,6 @@ functional cstdint
 functional cstdlib
 functional cstring
 functional exception
-functional initializer_list
 functional iosfwd
 functional limits
 functional memory
diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv
index 7d61ed365fb8ea..663bfc5214571c 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -353,7 +353,6 @@ functional cstdint
 functional cstdlib
 functional cstring
 functional exception
-functional initializer_list
 functional iosfwd
 functional limits
 functional memory

>From e4db365aa9bb52eb6293e79fda0e775c368402cb Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Mon, 2 Sep 2024 09:33:46 +0500
Subject: [PATCH 21/24] Rebased and release note added for fill_n

---
 libcxx/docs/ReleaseNotes/20.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index 96c350a73e1c6e..03d30969d551f0 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -51,6 +51,9 @@ Improvements and New Features
   
 - ``std::fill`` has been optimized for segmented iterators like ``std::deque::iterator`` in C++23 and
   later, which can lead up to 40x performance improvements.
+  
+- ``std::fill_n`` has been optimized for segmented iterators like ``std::deque::iterator`` in C++23 and
+  later, which can lead up to 40x performance improvements.
 
 - The ``_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION`` macro has been added to make ``std::uncaught_exception`` available in C++20 and later modes.
 

>From e3a2dc5f606de4e5ba6056c38dbeb9dd3e82855f Mon Sep 17 00:00:00 2001
From: NoumanAmir-10xe <66777536+NoumanAmir657 at users.noreply.github.com>
Date: Sun, 8 Sep 2024 20:19:54 +0500
Subject: [PATCH 22/24] Delete
 libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp

---
 .../alg.fill/fill_n.pass.cpp                  | 168 ------------------
 1 file changed, 168 deletions(-)
 delete mode 100644 libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp

diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
deleted file mode 100644
index 89c7b854586711..00000000000000
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <algorithm>
-
-// template<class Iter, IntegralLike Size, class T>
-//   requires OutputIterator<Iter, const T&>
-//   constexpr OutputIterator      // constexpr after C++17
-//   fill_n(Iter first, Size n, const T& value);
-
-#include <algorithm>
-#include <cassert>
-#include <deque>
-
-#include "test_macros.h"
-#include "test_iterators.h"
-#include "user_defined_integral.h"
-
-#if TEST_STD_VER > 17
-TEST_CONSTEXPR bool test_constexpr() {
-  const std::size_t N = 5;
-  int ib[]            = {0, 0, 0, 0, 0, 0}; // one bigger than N
-
-  auto it = std::fill_n(std::begin(ib), N, 5);
-  return it == (std::begin(ib) + N) && std::all_of(std::begin(ib), it, [](int a) { return a == 5; }) &&
-       *it == 0 // don't overwrite the last value in the output array
-      ;
-}
-#endif
-
-typedef UserDefinedIntegral<unsigned> UDI;
-
-template <class Iter>
-void test_char() {
-  char a[4] = {};
-  Iter it   = std::fill_n(Iter(a), UDI(4), char(1));
-  assert(base(it) == a + 4);
-  assert(a[0] == 1);
-  assert(a[1] == 1);
-  assert(a[2] == 1);
-  assert(a[3] == 1);
-}
-
-template <class Iter>
-void test_int() {
-  int a[4] = {};
-  Iter it  = std::fill_n(Iter(a), UDI(4), 1);
-  assert(base(it) == a + 4);
-  assert(a[0] == 1);
-  assert(a[1] == 1);
-  assert(a[2] == 1);
-  assert(a[3] == 1);
-}
-
-void test_int_array() {
-  int a[4] = {};
-  assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
-  assert(a[0] == 1);
-  assert(a[1] == 1);
-  assert(a[2] == 1);
-  assert(a[3] == 1);
-}
-
-struct source {
-  source() : i(0) {}
-
-  operator int() const { return i++; }
-  mutable int i;
-};
-
-void test_int_array_struct_source() {
-  int a[4] = {};
-  assert(std::fill_n(a, UDI(4), source()) == a + 4);
-  assert(a[0] == 0);
-  assert(a[1] == 1);
-  assert(a[2] == 2);
-  assert(a[3] == 3);
-}
-
-struct test1 {
-  test1() : c(0) {}
-  test1(char xc) : c(xc + 1) {}
-  char c;
-};
-
-void test_struct_array() {
-  test1 test1a[4] = {};
-  assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
-  assert(test1a[0].c == 11);
-  assert(test1a[1].c == 11);
-  assert(test1a[2].c == 11);
-  assert(test1a[3].c == 11);
-}
-
-class A {
-  char a_;
-
-public:
-  A() {}
-  explicit A(char a) : a_(a) {}
-  operator unsigned char() const { return 'b'; }
-
-  friend bool operator==(const A& x, const A& y) { return x.a_ == y.a_; }
-};
-
-void test5() {
-  A a[3];
-  assert(std::fill_n(&a[0], UDI(3), A('a')) == a + 3);
-  assert(a[0] == A('a'));
-  assert(a[1] == A('a'));
-  assert(a[2] == A('a'));
-}
-
-struct Storage {
-  union {
-    unsigned char a;
-    unsigned char b;
-  };
-};
-
-void test6() {
-  Storage foo[5];
-  std::fill_n(&foo[0], UDI(5), Storage());
-}
-
-void test_deque() {
-  std::deque<int> dq(5);
-  std::fill_n(dq.begin(), dq.size(), 4);
-  assert(dq[0] == 4);
-  assert(dq[1] == 4);
-  assert(dq[2] == 4);
-  assert(dq[3] == 4);
-  assert(dq[4] == 4);
-}
-
-int main(int, char**) {
-  test_char<cpp17_output_iterator<char*> >();
-  test_char<forward_iterator<char*> >();
-  test_char<bidirectional_iterator<char*> >();
-  test_char<random_access_iterator<char*> >();
-  test_char<char*>();
-
-  test_int<cpp17_output_iterator<int*> >();
-  test_int<forward_iterator<int*> >();
-  test_int<bidirectional_iterator<int*> >();
-  test_int<random_access_iterator<int*> >();
-  test_int<int*>();
-
-  test_int_array();
-  test_int_array_struct_source();
-  test_struct_array();
-
-  test5();
-  test6();
-
-  test_deque();
-
-#if TEST_STD_VER > 17
-  static_assert(test_constexpr());
-#endif
-
-  return 0;
-}

>From 64bfc39f67039ba0a7fd50f1bf23241486bc7966 Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Sun, 8 Sep 2024 20:39:31 +0500
Subject: [PATCH 23/24] Remove conditonal check

---
 libcxx/include/__algorithm/fill.h             |   3 +-
 .../alg.fill/fill_n.pass.cpp                  | 174 ++++++++++++++++++
 2 files changed, 175 insertions(+), 2 deletions(-)
 create mode 100644 libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index 93aa980d8f12dc..c64593a6ac95f2 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -44,8 +44,7 @@ __fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& _
 }
 
 template <class _SegmentedIterator,
-          class _Tp,
-          __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
+          class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value) {
   std::for_each(__first, __last, [__value](_Tp& __val) { __val = __value; });
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
new file mode 100644
index 00000000000000..c682e3335a58fc
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
@@ -0,0 +1,174 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template<class Iter, IntegralLike Size, class T>
+//   requires OutputIterator<Iter, const T&>
+//   constexpr OutputIterator      // constexpr after C++17
+//   fill_n(Iter first, Size n, const T& value);
+
+#include <algorithm>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "user_defined_integral.h"
+
+#if TEST_STD_VER > 17
+TEST_CONSTEXPR bool test_constexpr() {
+    const std::size_t N = 5;
+    int ib[] = {0, 0, 0, 0, 0, 0}; // one bigger than N
+
+    auto it = std::fill_n(std::begin(ib), N, 5);
+    return it == (std::begin(ib) + N)
+        && std::all_of(std::begin(ib), it, [](int a) {return a == 5; })
+        && *it == 0 // don't overwrite the last value in the output array
+        ;
+    }
+#endif
+
+typedef UserDefinedIntegral<unsigned> UDI;
+
+template <class Iter>
+void
+test_char()
+{
+    char a[4] = {};
+    Iter it = std::fill_n(Iter(a), UDI(4), char(1));
+    assert(base(it) == a + 4);
+    assert(a[0] == 1);
+    assert(a[1] == 1);
+    assert(a[2] == 1);
+    assert(a[3] == 1);
+}
+
+template <class Iter>
+void
+test_int()
+{
+    int a[4] = {};
+    Iter it = std::fill_n(Iter(a), UDI(4), 1);
+    assert(base(it) == a + 4);
+    assert(a[0] == 1);
+    assert(a[1] == 1);
+    assert(a[2] == 1);
+    assert(a[3] == 1);
+}
+
+void
+test_int_array()
+{
+    int a[4] = {};
+    assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
+    assert(a[0] == 1);
+    assert(a[1] == 1);
+    assert(a[2] == 1);
+    assert(a[3] == 1);
+}
+
+struct source {
+    source() : i(0) { }
+
+    operator int() const { return i++; }
+    mutable int i;
+};
+
+void
+test_int_array_struct_source()
+{
+    int a[4] = {};
+    assert(std::fill_n(a, UDI(4), source()) == a + 4);
+    assert(a[0] == 0);
+    assert(a[1] == 1);
+    assert(a[2] == 2);
+    assert(a[3] == 3);
+}
+
+struct test1 {
+    test1() : c(0) { }
+    test1(char xc) : c(xc + 1) { }
+    char c;
+};
+
+void
+test_struct_array()
+{
+    test1 test1a[4] = {};
+    assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
+    assert(test1a[0].c == 11);
+    assert(test1a[1].c == 11);
+    assert(test1a[2].c == 11);
+    assert(test1a[3].c == 11);
+}
+
+class A
+{
+    char a_;
+public:
+    A() {}
+    explicit A(char a) : a_(a) {}
+    operator unsigned char() const {return 'b';}
+
+    friend bool operator==(const A& x, const A& y)
+        {return x.a_ == y.a_;}
+};
+
+void
+test5()
+{
+    A a[3];
+    assert(std::fill_n(&a[0], UDI(3), A('a')) == a+3);
+    assert(a[0] == A('a'));
+    assert(a[1] == A('a'));
+    assert(a[2] == A('a'));
+}
+
+struct Storage
+{
+  union
+  {
+    unsigned char a;
+    unsigned char b;
+  };
+};
+
+void test6()
+{
+  Storage foo[5];
+  std::fill_n(&foo[0], UDI(5), Storage());
+}
+
+
+int main(int, char**)
+{
+    test_char<cpp17_output_iterator<char*> >();
+    test_char<forward_iterator<char*> >();
+    test_char<bidirectional_iterator<char*> >();
+    test_char<random_access_iterator<char*> >();
+    test_char<char*>();
+
+    test_int<cpp17_output_iterator<int*> >();
+    test_int<forward_iterator<int*> >();
+    test_int<bidirectional_iterator<int*> >();
+    test_int<random_access_iterator<int*> >();
+    test_int<int*>();
+
+    test_int_array();
+    test_int_array_struct_source();
+    test_struct_array();
+
+    test5();
+    test6();
+
+#if TEST_STD_VER > 17
+    static_assert(test_constexpr());
+#endif
+
+  return 0;
+}
\ No newline at end of file

>From 04178dae18561b3640dbf7b9ed639f56527bed5d Mon Sep 17 00:00:00 2001
From: nouman-10x <noumanamir453 at gmail.com>
Date: Sun, 8 Sep 2024 20:46:35 +0500
Subject: [PATCH 24/24] Format

---
 libcxx/include/__algorithm/fill.h                 |  3 +--
 .../alg.fill/fill_n.pass.cpp                      | 15 ++++++++++++++-
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index c64593a6ac95f2..817354f1f2ceed 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -43,8 +43,7 @@ __fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& _
   std::fill_n(__first, __last - __first, __value);
 }
 
-template <class _SegmentedIterator,
-          class _Tp>
+template <class _SegmentedIterator, class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 __fill(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value) {
   std::for_each(__first, __last, [__value](_Tp& __val) { __val = __value; });
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
index c682e3335a58fc..37524ccbed5011 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <algorithm>
 #include <cassert>
+#include <deque>
 
 #include "test_macros.h"
 #include "test_iterators.h"
@@ -144,6 +145,18 @@ void test6()
   std::fill_n(&foo[0], UDI(5), Storage());
 }
 
+void
+test_deque()
+{
+    std::deque<int> dq(5);
+    std::fill_n(dq.begin(), dq.size(), 4);
+    assert(dq[0] == 4);
+    assert(dq[1] == 4);
+    assert(dq[2] == 4);
+    assert(dq[3] == 4);
+    assert(dq[4] == 4);
+}
+
 
 int main(int, char**)
 {
@@ -171,4 +184,4 @@ int main(int, char**)
 #endif
 
   return 0;
-}
\ No newline at end of file
+}



More information about the libcxx-commits mailing list