[libcxx-commits] [libcxx] [libc++] Add a static_assert for a Mandates in seed_seq (PR #86992)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Mar 28 12:20:58 PDT 2024


https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/86992

>From 1f0a9d74fae6486d3a6ca841491cace3ca2ef6ef Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 28 Mar 2024 15:12:39 -0400
Subject: [PATCH 1/2] [libc++] Add a static_assert for a Mandates in seed_seq

Fixes #84843
---
 libcxx/include/__random/seed_seq.h            |  7 +++
 .../generate.mandates.verify.cpp              | 57 +++++++++++++++++++
 2 files changed, 64 insertions(+)
 create mode 100644 libcxx/test/std/numerics/rand/rand.util/rand.util.seedseq/generate.mandates.verify.cpp

diff --git a/libcxx/include/__random/seed_seq.h b/libcxx/include/__random/seed_seq.h
index 7e9888768ed931..d0dee4c3c0baad 100644
--- a/libcxx/include/__random/seed_seq.h
+++ b/libcxx/include/__random/seed_seq.h
@@ -14,6 +14,8 @@
 #include <__algorithm/max.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/is_unsigned.h>
+#include <climits>
 #include <cstdint>
 #include <initializer_list>
 #include <vector>
@@ -79,6 +81,11 @@ void seed_seq::__init(_InputIterator __first, _InputIterator __last) {
 
 template <class _RandomAccessIterator>
 void seed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last) {
+  using _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type;
+  static_assert(is_unsigned<_ValueType>::value && sizeof(_ValueType) * CHAR_BIT >= 32,
+                "[rand.util.seedseq]/7 requires the value_type of the iterator to be an unsigned "
+                "integer capable of accommodating 32-bit quantities.");
+
   if (__first != __last) {
     std::fill(__first, __last, 0x8b8b8b8b);
     const size_t __n = static_cast<size_t>(__last - __first);
diff --git a/libcxx/test/std/numerics/rand/rand.util/rand.util.seedseq/generate.mandates.verify.cpp b/libcxx/test/std/numerics/rand/rand.util/rand.util.seedseq/generate.mandates.verify.cpp
new file mode 100644
index 00000000000000..4320f4e32377dd
--- /dev/null
+++ b/libcxx/test/std/numerics/rand/rand.util/rand.util.seedseq/generate.mandates.verify.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <random>
+
+// class seed_seq;
+
+// template<class RandomAccessIterator>
+//     void generate(RandomAccessIterator begin, RandomAccessIterator end);
+
+// Check the following requirement: https://eel.is/c++draft/rand.util.seedseq#7
+//
+//  Mandates: iterator_traits<RandomAccessIterator>​::​​value_type is an unsigned integer
+//            type capable of accommodating 32-bit quantities.
+
+// UNSUPPORTED: c++03
+// REQUIRES: stdlib=libc++
+
+#include <random>
+#include <climits>
+
+#include "test_macros.h"
+
+void f() {
+  std::seed_seq seq;
+
+  // Not an integral type
+  {
+    double* p = nullptr;
+    seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires the value_type of the iterator {{.+}}}}
+    // expected-error@*:* 0+ {{invalid operands to}}
+  }
+
+  // Not an unsigned type
+  {
+    long long* p = nullptr;
+    seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires the value_type of the iterator {{.+}}}}
+  }
+
+  // Not a 32-bit type
+  {
+    static_assert(sizeof(unsigned char) * CHAR_BIT < 32, "the test doesn't work on this platform");
+    unsigned char* p = nullptr;
+    seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires the value_type of the iterator {{.+}}}}
+  }
+
+  // Everything satisfied
+  {
+    unsigned long* p = nullptr;
+    seq.generate(p, p); // no diagnostic
+  }
+}

>From 171c8c38898f16ad9819c1de6334a88aa741815e Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 28 Mar 2024 15:20:38 -0400
Subject: [PATCH 2/2] Formatting

---
 .../rand.util.seedseq/generate.mandates.verify.cpp          | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/test/std/numerics/rand/rand.util/rand.util.seedseq/generate.mandates.verify.cpp b/libcxx/test/std/numerics/rand/rand.util/rand.util.seedseq/generate.mandates.verify.cpp
index 4320f4e32377dd..f381108e0543d2 100644
--- a/libcxx/test/std/numerics/rand/rand.util/rand.util.seedseq/generate.mandates.verify.cpp
+++ b/libcxx/test/std/numerics/rand/rand.util/rand.util.seedseq/generate.mandates.verify.cpp
@@ -32,21 +32,21 @@ void f() {
   // Not an integral type
   {
     double* p = nullptr;
-    seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires the value_type of the iterator {{.+}}}}
+    seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires{{.+}}}}
     // expected-error@*:* 0+ {{invalid operands to}}
   }
 
   // Not an unsigned type
   {
     long long* p = nullptr;
-    seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires the value_type of the iterator {{.+}}}}
+    seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires{{.+}}}}
   }
 
   // Not a 32-bit type
   {
     static_assert(sizeof(unsigned char) * CHAR_BIT < 32, "the test doesn't work on this platform");
     unsigned char* p = nullptr;
-    seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires the value_type of the iterator {{.+}}}}
+    seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires{{.+}}}}
   }
 
   // Everything satisfied



More information about the libcxx-commits mailing list