[libcxx-commits] [libcxx] [libc++][math] Implement C++23 (parts of) P0533: constexpr `std::div()` (PR #104633)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Aug 17 04:19:45 PDT 2024


https://github.com/PaulXiCao updated https://github.com/llvm/llvm-project/pull/104633

>From 9839eb1fbefbfd3c7519f2db605bd1fc4169b629 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Thu, 15 Aug 2024 21:31:34 +0200
Subject: [PATCH 01/10] group std::div(), std::div_t tests into one test
 function

---
 .../support.runtime/cstdlib.pass.cpp          | 48 +++++++++++--------
 1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
index 823417f8a418eb..4f38fda86b2d3a 100644
--- a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -34,15 +34,6 @@
 #error RAND_MAX not defined
 #endif
 
-template <class TestType, class IntType>
-void test_div_struct() {
-    TestType obj;
-    static_assert(sizeof(obj) >= sizeof(IntType) * 2, ""); // >= to account for alignment.
-    static_assert((std::is_same<decltype(obj.quot), IntType>::value), "");
-    static_assert((std::is_same<decltype(obj.rem), IntType>::value), "");
-    ((void) obj);
-};
-
 template <class T, class = decltype(std::abs(std::declval<T>()))>
 std::true_type has_abs_imp(int);
 template <class T>
@@ -85,14 +76,39 @@ void test_abs() {
     assert(std::abs(-1.) == 1);
 }
 
+template <class TestType, class IntType>
+void test_div_struct() {
+  TestType obj;
+  static_assert(sizeof(obj) >= sizeof(IntType) * 2,
+                "");  // >= to account for alignment.
+  static_assert((std::is_same<decltype(obj.quot), IntType>::value), "");
+  static_assert((std::is_same<decltype(obj.rem), IntType>::value), "");
+  ((void)obj);
+}
+
+void test_div() {
+  {  // tests member types of std::div_t, etc.
+    test_div_struct<std::div_t, int>();
+    test_div_struct<std::ldiv_t, long>();
+    test_div_struct<std::lldiv_t, long long>();
+  }
+
+  {  // tests return type of std::div
+    // clang-format off
+    static_assert((std::is_same<decltype(std::div(  0,   0  )), std::div_t  >::value), "");
+    static_assert((std::is_same<decltype(std::div(  0L,  0L )), std::ldiv_t >::value), "");
+    static_assert((std::is_same<decltype(std::div(  0LL, 0LL)), std::lldiv_t>::value), "");
+    static_assert((std::is_same<decltype(std::ldiv( 0L,  0L )), std::ldiv_t >::value), "");
+    static_assert((std::is_same<decltype(std::lldiv(0LL, 0LL)), std::lldiv_t>::value), "");
+    // clang-format on
+  }
+}
+
 int main(int, char**)
 {
     std::size_t s = 0;
     ((void)s);
     static_assert((std::is_same<std::size_t, decltype(sizeof(int))>::value), "");
-    test_div_struct<std::div_t, int>();
-    test_div_struct<std::ldiv_t, long>();
-    test_div_struct<std::lldiv_t, long long>();
     char** endptr = 0;
     static_assert((std::is_same<decltype(std::atof("")), double>::value), "");
     static_assert((std::is_same<decltype(std::atoi("")), int>::value), "");
@@ -131,11 +147,6 @@ int main(int, char**)
     static_assert((std::is_same<decltype(std::abs((long long)0)), long long>::value), "");
     static_assert((std::is_same<decltype(std::labs((long)0)), long>::value), "");
     static_assert((std::is_same<decltype(std::llabs((long long)0)), long long>::value), "");
-    static_assert((std::is_same<decltype(std::div(0,0)), std::div_t>::value), "");
-    static_assert((std::is_same<decltype(std::div(0L,0L)), std::ldiv_t>::value), "");
-    static_assert((std::is_same<decltype(std::div(0LL,0LL)), std::lldiv_t>::value), "");
-    static_assert((std::is_same<decltype(std::ldiv(0L,0L)), std::ldiv_t>::value), "");
-    static_assert((std::is_same<decltype(std::lldiv(0LL,0LL)), std::lldiv_t>::value), "");
 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
     wchar_t* pw = 0;
     const wchar_t* pwc = 0;
@@ -148,6 +159,5 @@ int main(int, char**)
 #endif
 
     test_abs();
-
-    return 0;
+    test_div();
 }

>From d231ef8b4835212063e44d27d8a8d4735cfdb1d7 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Thu, 15 Aug 2024 21:33:03 +0200
Subject: [PATCH 02/10] add test for simple input

---
 .../support.runtime/cstdlib.pass.cpp           | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
index 4f38fda86b2d3a..32410cba1fb285 100644
--- a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -102,6 +102,24 @@ void test_div() {
     static_assert((std::is_same<decltype(std::lldiv(0LL, 0LL)), std::lldiv_t>::value), "");
     // clang-format on
   }
+
+  {  // check one basic input for correctness.
+    // (42 // 5 == 8) AND (42 % 5 == 2)
+    const auto check = [](const auto callable_div) -> void {
+      // fixme: change to static_assert() when constexpr-ready
+      const auto div = callable_div(42, 5);
+      assert(div.quot == 8);
+      assert(div.rem == 2);
+    };
+
+    // clang-format off
+    check([](int       n, int       k) { return std::div(  n, k); });
+    check([](long      n, long      k) { return std::div(  n, k); });
+    check([](long long n, long long k) { return std::div(  n, k); });
+    check([](long      n, long      k) { return std::ldiv( n, k); });
+    check([](long long n, long long k) { return std::lldiv(n, k); });
+    // clang-format on
+  }
 }
 
 int main(int, char**)

>From 258e3dc862adaffe2758a441fd6eb3a2917977d5 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 16 Aug 2024 14:37:38 +0200
Subject: [PATCH 03/10] std::div(int,int) constexpr

---
 libcxx/include/cstdlib                        | 26 ++++++++++++++++---
 .../support.runtime/cstdlib.pass.cpp          | 19 +++++++++-----
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index c817fd8f4accda..24e36b3461d04c 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -131,9 +131,6 @@ using ::qsort _LIBCPP_USING_IF_EXISTS;
 using ::abs _LIBCPP_USING_IF_EXISTS;
 using ::labs _LIBCPP_USING_IF_EXISTS;
 using ::llabs _LIBCPP_USING_IF_EXISTS;
-using ::div _LIBCPP_USING_IF_EXISTS;
-using ::ldiv _LIBCPP_USING_IF_EXISTS;
-using ::lldiv _LIBCPP_USING_IF_EXISTS;
 using ::mblen _LIBCPP_USING_IF_EXISTS;
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 using ::mbtowc _LIBCPP_USING_IF_EXISTS;
@@ -149,6 +146,29 @@ using ::quick_exit _LIBCPP_USING_IF_EXISTS;
 using ::aligned_alloc _LIBCPP_USING_IF_EXISTS;
 #endif
 
+using ::ldiv _LIBCPP_USING_IF_EXISTS;
+using ::lldiv _LIBCPP_USING_IF_EXISTS;
+
+#if _LIBCPP_STD_VER < 23
+// use non-constexpr versions from libc
+using ::div _LIBCPP_USING_IF_EXISTS;
+
+#else  // _LIBCPP_STD_VER >= 23
+
+template <class _Div_t, class _Int>
+_LIBCPP_HIDE_FROM_ABI constexpr _Div_t __div(_Int __x, _Int __y) {
+  _Div_t __d;
+  __d.quot = __x / __y;
+  __d.rem = __x % __y;
+  return __d;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI constexpr div_t div(int __x, int __y) {
+  return std::__div<std::div_t>(__x, __y);
+}
+
+#endif  // _LIBCPP_STD_VER
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_CSTDLIB
diff --git a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
index 32410cba1fb285..236002efe9f158 100644
--- a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -96,8 +96,8 @@ void test_div() {
   {  // tests return type of std::div
     // clang-format off
     static_assert((std::is_same<decltype(std::div(  0,   0  )), std::div_t  >::value), "");
-    static_assert((std::is_same<decltype(std::div(  0L,  0L )), std::ldiv_t >::value), "");
-    static_assert((std::is_same<decltype(std::div(  0LL, 0LL)), std::lldiv_t>::value), "");
+    // static_assert((std::is_same<decltype(std::div(  0L,  0L )), std::ldiv_t >::value), "");
+    // static_assert((std::is_same<decltype(std::div(  0LL, 0LL)), std::lldiv_t>::value), "");
     static_assert((std::is_same<decltype(std::ldiv( 0L,  0L )), std::ldiv_t >::value), "");
     static_assert((std::is_same<decltype(std::lldiv(0LL, 0LL)), std::lldiv_t>::value), "");
     // clang-format on
@@ -106,18 +106,23 @@ void test_div() {
   {  // check one basic input for correctness.
     // (42 // 5 == 8) AND (42 % 5 == 2)
     const auto check = [](const auto callable_div) -> void {
-      // fixme: change to static_assert() when constexpr-ready
       const auto div = callable_div(42, 5);
       assert(div.quot == 8);
       assert(div.rem == 2);
+
+#if _LIBCPP_STD_VER >= 23
+      constexpr auto div2 = callable_div(42, 5);
+      static_assert(div2.quot == 8);
+      static_assert(div2.rem == 2);
+#endif
     };
 
     // clang-format off
     check([](int       n, int       k) { return std::div(  n, k); });
-    check([](long      n, long      k) { return std::div(  n, k); });
-    check([](long long n, long long k) { return std::div(  n, k); });
-    check([](long      n, long      k) { return std::ldiv( n, k); });
-    check([](long long n, long long k) { return std::lldiv(n, k); });
+    // check([](long      n, long      k) { return std::div(  n, k); });
+    // check([](long long n, long long k) { return std::div(  n, k); });
+    // check([](long      n, long      k) { return std::ldiv( n, k); });
+    // check([](long long n, long long k) { return std::lldiv(n, k); });
     // clang-format on
   }
 }

>From 1c11ce348553188f1215dfeda6fa03d9dca427b3 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 16 Aug 2024 14:42:09 +0200
Subject: [PATCH 04/10] std::div() for long, and long long as constexpr

---
 libcxx/include/cstdlib                                   | 9 +++++++++
 .../language.support/support.runtime/cstdlib.pass.cpp    | 8 ++++----
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index 24e36b3461d04c..b12c28894f0a86 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -167,6 +167,15 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr div_t div(int __x, int __y) {
   return std::__div<std::div_t>(__x, __y);
 }
 
+inline _LIBCPP_HIDE_FROM_ABI constexpr ldiv_t div(long __x, long __y) {
+  return std::__div<std::ldiv_t>(__x, __y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI constexpr lldiv_t div(long long __x,
+                                                   long long __y) {
+  return std::__div<std::lldiv_t>(__x, __y);
+}
+
 #endif  // _LIBCPP_STD_VER
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
index 236002efe9f158..a7ff6be1b240b8 100644
--- a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -96,8 +96,8 @@ void test_div() {
   {  // tests return type of std::div
     // clang-format off
     static_assert((std::is_same<decltype(std::div(  0,   0  )), std::div_t  >::value), "");
-    // static_assert((std::is_same<decltype(std::div(  0L,  0L )), std::ldiv_t >::value), "");
-    // static_assert((std::is_same<decltype(std::div(  0LL, 0LL)), std::lldiv_t>::value), "");
+    static_assert((std::is_same<decltype(std::div(  0L,  0L )), std::ldiv_t >::value), "");
+    static_assert((std::is_same<decltype(std::div(  0LL, 0LL)), std::lldiv_t>::value), "");
     static_assert((std::is_same<decltype(std::ldiv( 0L,  0L )), std::ldiv_t >::value), "");
     static_assert((std::is_same<decltype(std::lldiv(0LL, 0LL)), std::lldiv_t>::value), "");
     // clang-format on
@@ -119,8 +119,8 @@ void test_div() {
 
     // clang-format off
     check([](int       n, int       k) { return std::div(  n, k); });
-    // check([](long      n, long      k) { return std::div(  n, k); });
-    // check([](long long n, long long k) { return std::div(  n, k); });
+    check([](long      n, long      k) { return std::div(  n, k); });
+    check([](long long n, long long k) { return std::div(  n, k); });
     // check([](long      n, long      k) { return std::ldiv( n, k); });
     // check([](long long n, long long k) { return std::lldiv(n, k); });
     // clang-format on

>From 067b03ac48e4f787ab8ab34a95879e76483a72fb Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 16 Aug 2024 20:57:00 +0200
Subject: [PATCH 05/10] constexpr std::ldiv, std::lldiv

---
 libcxx/include/cstdlib                             | 14 +++++++++++---
 .../support.runtime/cstdlib.pass.cpp               |  4 ++--
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index b12c28894f0a86..8452cf164346ed 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -146,12 +146,11 @@ using ::quick_exit _LIBCPP_USING_IF_EXISTS;
 using ::aligned_alloc _LIBCPP_USING_IF_EXISTS;
 #endif
 
-using ::ldiv _LIBCPP_USING_IF_EXISTS;
-using ::lldiv _LIBCPP_USING_IF_EXISTS;
-
 #if _LIBCPP_STD_VER < 23
 // use non-constexpr versions from libc
 using ::div _LIBCPP_USING_IF_EXISTS;
+using ::ldiv _LIBCPP_USING_IF_EXISTS;
+using ::lldiv _LIBCPP_USING_IF_EXISTS;
 
 #else  // _LIBCPP_STD_VER >= 23
 
@@ -176,6 +175,15 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr lldiv_t div(long long __x,
   return std::__div<std::lldiv_t>(__x, __y);
 }
 
+inline _LIBCPP_HIDE_FROM_ABI constexpr ldiv_t ldiv(long __x, long __y) {
+  return std::div(__x, __y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI constexpr lldiv_t lldiv(long long __x,
+                                                     long long __y) {
+  return std::div(__x, __y);
+}
+
 #endif  // _LIBCPP_STD_VER
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
index a7ff6be1b240b8..cc2686d19a8f84 100644
--- a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -121,8 +121,8 @@ void test_div() {
     check([](int       n, int       k) { return std::div(  n, k); });
     check([](long      n, long      k) { return std::div(  n, k); });
     check([](long long n, long long k) { return std::div(  n, k); });
-    // check([](long      n, long      k) { return std::ldiv( n, k); });
-    // check([](long long n, long long k) { return std::lldiv(n, k); });
+    check([](long      n, long      k) { return std::ldiv( n, k); });
+    check([](long long n, long long k) { return std::lldiv(n, k); });
     // clang-format on
   }
 }

>From 0552117c42cdec6c44203a959c8dde11ce5df04a Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 16 Aug 2024 21:17:26 +0200
Subject: [PATCH 06/10] clang format

---
 libcxx/include/cstdlib                        | 96 +++++++------------
 .../support.runtime/cstdlib.pass.cpp          | 20 ++--
 2 files changed, 48 insertions(+), 68 deletions(-)

diff --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index 8452cf164346ed..fe6298c10da380 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -36,55 +36,43 @@ int       atoi (const char* nptr);
 long      atol (const char* nptr);
 long long atoll(const char* nptr);                                        // C99
 double             strtod  (const char* restrict nptr, char** restrict endptr);
-float              strtof  (const char* restrict nptr, char** restrict endptr); // C99
-long double        strtold (const char* restrict nptr, char** restrict endptr); // C99
-long               strtol  (const char* restrict nptr, char** restrict endptr, int base);
-long long          strtoll (const char* restrict nptr, char** restrict endptr, int base); // C99
-unsigned long      strtoul (const char* restrict nptr, char** restrict endptr, int base);
-unsigned long long strtoull(const char* restrict nptr, char** restrict endptr, int base); // C99
-int rand(void);
-void srand(unsigned int seed);
-void* calloc(size_t nmemb, size_t size);
-void free(void* ptr);
-void* malloc(size_t size);
-void* realloc(void* ptr, size_t size);
-void abort(void);
-int atexit(void (*func)(void));
-void exit(int status);
-void _Exit(int status);
-char* getenv(const char* name);
-int system(const char* string);
-void* bsearch(const void* key, const void* base, size_t nmemb, size_t size,
-              int (*compar)(const void *, const void *));
-void qsort(void* base, size_t nmemb, size_t size,
-           int (*compar)(const void *, const void *));
-int         abs(      int j);
-long        abs(     long j);
-long long   abs(long long j);                                             // C++0X
-long       labs(     long j);
+float              strtof  (const char* restrict nptr, char** restrict endptr);
+// C99 long double        strtold (const char* restrict nptr, char** restrict
+endptr); // C99 long               strtol  (const char* restrict nptr, char**
+restrict endptr, int base); long long          strtoll (const char* restrict
+nptr, char** restrict endptr, int base); // C99 unsigned long      strtoul
+(const char* restrict nptr, char** restrict endptr, int base); unsigned long
+long strtoull(const char* restrict nptr, char** restrict endptr, int base); //
+C99 int rand(void); void srand(unsigned int seed); void* calloc(size_t nmemb,
+size_t size); void free(void* ptr); void* malloc(size_t size); void*
+realloc(void* ptr, size_t size); void abort(void); int atexit(void
+(*func)(void)); void exit(int status); void _Exit(int status); char*
+getenv(const char* name); int system(const char* string); void* bsearch(const
+void* key, const void* base, size_t nmemb, size_t size, int (*compar)(const void
+*, const void *)); void qsort(void* base, size_t nmemb, size_t size, int
+(*compar)(const void *, const void *)); int         abs(      int j); long abs(
+long j); long long   abs(long long j); // C++0X long       labs(     long j);
 long long llabs(long long j);                                             // C99
 div_t     div(      int numer,       int denom);
 ldiv_t    div(     long numer,      long denom);
-lldiv_t   div(long long numer, long long denom);                          // C++0X
-ldiv_t   ldiv(     long numer,      long denom);
-lldiv_t lldiv(long long numer, long long denom);                          // C99
-int mblen(const char* s, size_t n);
-int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t n);
-int wctomb(char* s, wchar_t wchar);
-size_t mbstowcs(wchar_t* restrict pwcs, const char* restrict s, size_t n);
-size_t wcstombs(char* restrict s, const wchar_t* restrict pwcs, size_t n);
-int at_quick_exit(void (*func)(void))                                     // C++11
-void quick_exit(int status);                                              // C++11
-void *aligned_alloc(size_t alignment, size_t size);                       // C11
+lldiv_t   div(long long numer, long long denom);                          //
+C++0X ldiv_t   ldiv(     long numer,      long denom); lldiv_t lldiv(long long
+numer, long long denom);                          // C99 int mblen(const char*
+s, size_t n); int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t
+n); int wctomb(char* s, wchar_t wchar); size_t mbstowcs(wchar_t* restrict pwcs,
+const char* restrict s, size_t n); size_t wcstombs(char* restrict s, const
+wchar_t* restrict pwcs, size_t n); int at_quick_exit(void (*func)(void)) //
+C++11 void quick_exit(int status); // C++11 void *aligned_alloc(size_t
+alignment, size_t size);                       // C11
 
 }  // std
 
 */
 
-#include <__config>
-
 #include <stdlib.h>
 
+#include <__config>
+
 #ifndef _LIBCPP_STDLIB_H
 #   error <cstdlib> tried including <stdlib.h> but didn't find libc++'s <stdlib.h> header. \
           This usually means that your header search paths are not configured properly. \
@@ -94,7 +82,7 @@ void *aligned_alloc(size_t alignment, size_t size);                       // C11
 #endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
+#pragma GCC system_header
 #endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -152,40 +140,30 @@ using ::div _LIBCPP_USING_IF_EXISTS;
 using ::ldiv _LIBCPP_USING_IF_EXISTS;
 using ::lldiv _LIBCPP_USING_IF_EXISTS;
 
-#else  // _LIBCPP_STD_VER >= 23
+#else // _LIBCPP_STD_VER >= 23
 
 template <class _Div_t, class _Int>
 _LIBCPP_HIDE_FROM_ABI constexpr _Div_t __div(_Int __x, _Int __y) {
   _Div_t __d;
   __d.quot = __x / __y;
-  __d.rem = __x % __y;
+  __d.rem  = __x % __y;
   return __d;
 }
 
-inline _LIBCPP_HIDE_FROM_ABI constexpr div_t div(int __x, int __y) {
-  return std::__div<std::div_t>(__x, __y);
-}
+inline _LIBCPP_HIDE_FROM_ABI constexpr div_t div(int __x, int __y) { return std::__div<std::div_t>(__x, __y); }
 
-inline _LIBCPP_HIDE_FROM_ABI constexpr ldiv_t div(long __x, long __y) {
-  return std::__div<std::ldiv_t>(__x, __y);
-}
+inline _LIBCPP_HIDE_FROM_ABI constexpr ldiv_t div(long __x, long __y) { return std::__div<std::ldiv_t>(__x, __y); }
 
-inline _LIBCPP_HIDE_FROM_ABI constexpr lldiv_t div(long long __x,
-                                                   long long __y) {
+inline _LIBCPP_HIDE_FROM_ABI constexpr lldiv_t div(long long __x, long long __y) {
   return std::__div<std::lldiv_t>(__x, __y);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI constexpr ldiv_t ldiv(long __x, long __y) {
-  return std::div(__x, __y);
-}
+inline _LIBCPP_HIDE_FROM_ABI constexpr ldiv_t ldiv(long __x, long __y) { return std::div(__x, __y); }
 
-inline _LIBCPP_HIDE_FROM_ABI constexpr lldiv_t lldiv(long long __x,
-                                                     long long __y) {
-  return std::div(__x, __y);
-}
+inline _LIBCPP_HIDE_FROM_ABI constexpr lldiv_t lldiv(long long __x, long long __y) { return std::div(__x, __y); }
 
-#endif  // _LIBCPP_STD_VER
+#endif // _LIBCPP_STD_VER
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_CSTDLIB
+#endif  // _LIBCPP_CSTDLIB
diff --git a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
index cc2686d19a8f84..305031a7e56382 100644
--- a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -80,30 +80,30 @@ template <class TestType, class IntType>
 void test_div_struct() {
   TestType obj;
   static_assert(sizeof(obj) >= sizeof(IntType) * 2,
-                "");  // >= to account for alignment.
+                ""); // >= to account for alignment.
   static_assert((std::is_same<decltype(obj.quot), IntType>::value), "");
   static_assert((std::is_same<decltype(obj.rem), IntType>::value), "");
   ((void)obj);
 }
 
 void test_div() {
-  {  // tests member types of std::div_t, etc.
+  { // tests member types of std::div_t, etc.
     test_div_struct<std::div_t, int>();
     test_div_struct<std::ldiv_t, long>();
     test_div_struct<std::lldiv_t, long long>();
   }
 
-  {  // tests return type of std::div
+  { // tests return type of std::div
     // clang-format off
-    static_assert((std::is_same<decltype(std::div(  0,   0  )), std::div_t  >::value), "");
-    static_assert((std::is_same<decltype(std::div(  0L,  0L )), std::ldiv_t >::value), "");
-    static_assert((std::is_same<decltype(std::div(  0LL, 0LL)), std::lldiv_t>::value), "");
-    static_assert((std::is_same<decltype(std::ldiv( 0L,  0L )), std::ldiv_t >::value), "");
-    static_assert((std::is_same<decltype(std::lldiv(0LL, 0LL)), std::lldiv_t>::value), "");
+    static_assert(std::is_same<decltype(std::div(  0,   0  )), std::div_t  >::value, "");
+    static_assert(std::is_same<decltype(std::div(  0L,  0L )), std::ldiv_t >::value, "");
+    static_assert(std::is_same<decltype(std::div(  0LL, 0LL)), std::lldiv_t>::value, "");
+    static_assert(std::is_same<decltype(std::ldiv( 0L,  0L )), std::ldiv_t >::value, "");
+    static_assert(std::is_same<decltype(std::lldiv(0LL, 0LL)), std::lldiv_t>::value, "");
     // clang-format on
   }
 
-  {  // check one basic input for correctness.
+  { // check one basic input for correctness.
     // (42 // 5 == 8) AND (42 % 5 == 2)
     const auto check = [](const auto callable_div) -> void {
       const auto div = callable_div(42, 5);
@@ -183,4 +183,6 @@ int main(int, char**)
 
     test_abs();
     test_div();
+
+    return 0;
 }

>From 810d2bb26cac8b992f47bad8ef9740d19e4c0232 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 16 Aug 2024 21:43:40 +0200
Subject: [PATCH 07/10] restore synopsis' formatting

---
 libcxx/include/cstdlib | 66 +++++++++++++++++++++++++-----------------
 1 file changed, 39 insertions(+), 27 deletions(-)

diff --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index fe6298c10da380..5985e3e0b2f9e3 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -36,34 +36,46 @@ int       atoi (const char* nptr);
 long      atol (const char* nptr);
 long long atoll(const char* nptr);                                        // C99
 double             strtod  (const char* restrict nptr, char** restrict endptr);
-float              strtof  (const char* restrict nptr, char** restrict endptr);
-// C99 long double        strtold (const char* restrict nptr, char** restrict
-endptr); // C99 long               strtol  (const char* restrict nptr, char**
-restrict endptr, int base); long long          strtoll (const char* restrict
-nptr, char** restrict endptr, int base); // C99 unsigned long      strtoul
-(const char* restrict nptr, char** restrict endptr, int base); unsigned long
-long strtoull(const char* restrict nptr, char** restrict endptr, int base); //
-C99 int rand(void); void srand(unsigned int seed); void* calloc(size_t nmemb,
-size_t size); void free(void* ptr); void* malloc(size_t size); void*
-realloc(void* ptr, size_t size); void abort(void); int atexit(void
-(*func)(void)); void exit(int status); void _Exit(int status); char*
-getenv(const char* name); int system(const char* string); void* bsearch(const
-void* key, const void* base, size_t nmemb, size_t size, int (*compar)(const void
-*, const void *)); void qsort(void* base, size_t nmemb, size_t size, int
-(*compar)(const void *, const void *)); int         abs(      int j); long abs(
-long j); long long   abs(long long j); // C++0X long       labs(     long j);
+float              strtof  (const char* restrict nptr, char** restrict endptr); // C99
+long double        strtold (const char* restrict nptr, char** restrict endptr); // C99
+long               strtol  (const char* restrict nptr, char** restrict endptr, int base);
+long long          strtoll (const char* restrict nptr, char** restrict endptr, int base); // C99
+unsigned long      strtoul (const char* restrict nptr, char** restrict endptr, int base);
+unsigned long long strtoull(const char* restrict nptr, char** restrict endptr, int base); // C99
+int rand(void);
+void srand(unsigned int seed);
+void* calloc(size_t nmemb, size_t size);
+void free(void* ptr);
+void* malloc(size_t size);
+void* realloc(void* ptr, size_t size);
+void abort(void);
+int atexit(void (*func)(void));
+void exit(int status);
+void _Exit(int status);
+char* getenv(const char* name);
+int system(const char* string);
+void* bsearch(const void* key, const void* base, size_t nmemb, size_t size,
+              int (*compar)(const void *, const void *));
+void qsort(void* base, size_t nmemb, size_t size,
+           int (*compar)(const void *, const void *));
+int         abs(      int j);
+long        abs(     long j);
+long long   abs(long long j);                                             // C++0X
+long       labs(     long j);
 long long llabs(long long j);                                             // C99
 div_t     div(      int numer,       int denom);
 ldiv_t    div(     long numer,      long denom);
-lldiv_t   div(long long numer, long long denom);                          //
-C++0X ldiv_t   ldiv(     long numer,      long denom); lldiv_t lldiv(long long
-numer, long long denom);                          // C99 int mblen(const char*
-s, size_t n); int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t
-n); int wctomb(char* s, wchar_t wchar); size_t mbstowcs(wchar_t* restrict pwcs,
-const char* restrict s, size_t n); size_t wcstombs(char* restrict s, const
-wchar_t* restrict pwcs, size_t n); int at_quick_exit(void (*func)(void)) //
-C++11 void quick_exit(int status); // C++11 void *aligned_alloc(size_t
-alignment, size_t size);                       // C11
+lldiv_t   div(long long numer, long long denom);                          // C++0X
+ldiv_t   ldiv(     long numer,      long denom);
+lldiv_t lldiv(long long numer, long long denom);                          // C99
+int mblen(const char* s, size_t n);
+int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t n);
+int wctomb(char* s, wchar_t wchar);
+size_t mbstowcs(wchar_t* restrict pwcs, const char* restrict s, size_t n);
+size_t wcstombs(char* restrict s, const wchar_t* restrict pwcs, size_t n);
+int at_quick_exit(void (*func)(void))                                     // C++11
+void quick_exit(int status);                                              // C++11
+void *aligned_alloc(size_t alignment, size_t size);                       // C11
 
 }  // std
 
@@ -82,7 +94,7 @@ alignment, size_t size);                       // C11
 #endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+#  pragma GCC system_header
 #endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -166,4 +178,4 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr lldiv_t lldiv(long long __x, long long __
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // _LIBCPP_CSTDLIB
+#endif // _LIBCPP_CSTDLIB

>From 82468a1345d37c334aae84ddbf9c55a4790b0d73 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 16 Aug 2024 21:44:38 +0200
Subject: [PATCH 08/10] synopsis: mark functions as constexpr

---
 libcxx/include/cstdlib | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index 5985e3e0b2f9e3..db70c6df87ce23 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -63,11 +63,11 @@ long        abs(     long j);
 long long   abs(long long j);                                             // C++0X
 long       labs(     long j);
 long long llabs(long long j);                                             // C99
-div_t     div(      int numer,       int denom);
-ldiv_t    div(     long numer,      long denom);
-lldiv_t   div(long long numer, long long denom);                          // C++0X
-ldiv_t   ldiv(     long numer,      long denom);
-lldiv_t lldiv(long long numer, long long denom);                          // C99
+constexpr div_t     div(      int numer,       int denom);
+constexpr ldiv_t    div(     long numer,      long denom);
+constexpr lldiv_t   div(long long numer, long long denom);                          // C++0X
+constexpr ldiv_t   ldiv(     long numer,      long denom);
+constexpr lldiv_t lldiv(long long numer, long long denom);                          // C99
 int mblen(const char* s, size_t n);
 int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t n);
 int wctomb(char* s, wchar_t wchar);

>From 34182ee0a880e5133825118cb35e2e68f8e79011 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 16 Aug 2024 21:46:25 +0200
Subject: [PATCH 09/10] restore header include order

---
 libcxx/include/cstdlib | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index db70c6df87ce23..2fe6baba45d817 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -81,10 +81,10 @@ void *aligned_alloc(size_t alignment, size_t size);                       // C11
 
 */
 
-#include <stdlib.h>
-
 #include <__config>
 
+#include <stdlib.h>
+
 #ifndef _LIBCPP_STDLIB_H
 #   error <cstdlib> tried including <stdlib.h> but didn't find libc++'s <stdlib.h> header. \
           This usually means that your header search paths are not configured properly. \

>From fc7a3efaf75f5f870b25e0d82b4fe09e2fb16258 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sat, 17 Aug 2024 13:13:02 +0200
Subject: [PATCH 10/10] make test c++03 compatible

---
 .../support.runtime/cstdlib.pass.cpp          | 42 ++++++++++---------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
index 305031a7e56382..b83bc4d66c445e 100644
--- a/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/libcxx/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -8,9 +8,10 @@
 
 // test <cstdlib>
 
+#include <cassert>
 #include <cstdlib>
 #include <type_traits>
-#include <cassert>
+#include <__config>
 
 #include "test_macros.h"
 
@@ -86,6 +87,22 @@ void test_div_struct() {
   ((void)obj);
 }
 
+#if _LIBCPP_STD_VER >= 23
+#  define TEST_DIV_42_5(DIV_T, div_var)                                                                                \
+    {                                                                                                                  \
+      constexpr DIV_T d = div_var;                                                                                     \
+      static_assert(d.quot == 8);                                                                                      \
+      static_assert(d.rem == 2);                                                                                       \
+    }
+#else
+#  define TEST_DIV_42_5(DIV_T, div_var)                                                                                \
+    {                                                                                                                  \
+      const DIV_T d = div_var;                                                                                         \
+      assert(d.quot == 8);                                                                                             \
+      assert(d.rem == 2);                                                                                              \
+    }
+#endif // _LIBCPP_STD_VER
+
 void test_div() {
   { // tests member types of std::div_t, etc.
     test_div_struct<std::div_t, int>();
@@ -104,25 +121,12 @@ void test_div() {
   }
 
   { // check one basic input for correctness.
-    // (42 // 5 == 8) AND (42 % 5 == 2)
-    const auto check = [](const auto callable_div) -> void {
-      const auto div = callable_div(42, 5);
-      assert(div.quot == 8);
-      assert(div.rem == 2);
-
-#if _LIBCPP_STD_VER >= 23
-      constexpr auto div2 = callable_div(42, 5);
-      static_assert(div2.quot == 8);
-      static_assert(div2.rem == 2);
-#endif
-    };
-
     // clang-format off
-    check([](int       n, int       k) { return std::div(  n, k); });
-    check([](long      n, long      k) { return std::div(  n, k); });
-    check([](long long n, long long k) { return std::div(  n, k); });
-    check([](long      n, long      k) { return std::ldiv( n, k); });
-    check([](long long n, long long k) { return std::lldiv(n, k); });
+    TEST_DIV_42_5(std::div_t,   std::div(  42,   5  ));
+    TEST_DIV_42_5(std::ldiv_t,  std::div(  42L,  5L ));
+    TEST_DIV_42_5(std::lldiv_t, std::div(  42LL, 5LL));
+    TEST_DIV_42_5(std::ldiv_t,  std::ldiv( 42L,  5L ));
+    TEST_DIV_42_5(std::lldiv_t, std::lldiv(42LL, 5LL));
     // clang-format on
   }
 }



More information about the libcxx-commits mailing list