Skip to content

Commit ca48d4d

Browse files
authored
[libc++] Add a static_assert for a Mandates in seed_seq (#86992)
Fixes #84843
1 parent bf1df25 commit ca48d4d

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

libcxx/include/__random/seed_seq.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <__algorithm/max.h>
1515
#include <__config>
1616
#include <__iterator/iterator_traits.h>
17+
#include <__type_traits/is_unsigned.h>
1718
#include <cstdint>
1819
#include <initializer_list>
1920
#include <vector>
@@ -79,6 +80,11 @@ void seed_seq::__init(_InputIterator __first, _InputIterator __last) {
7980

8081
template <class _RandomAccessIterator>
8182
void seed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last) {
83+
using _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type;
84+
static_assert(is_unsigned<_ValueType>::value && sizeof(_ValueType) >= sizeof(uint32_t),
85+
"[rand.util.seedseq]/7 requires the value_type of the iterator to be an unsigned "
86+
"integer capable of accommodating 32-bit quantities.");
87+
8288
if (__first != __last) {
8389
std::fill(__first, __last, 0x8b8b8b8b);
8490
const size_t __n = static_cast<size_t>(__last - __first);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <random>
10+
11+
// class seed_seq;
12+
13+
// template<class RandomAccessIterator>
14+
// void generate(RandomAccessIterator begin, RandomAccessIterator end);
15+
16+
// Check the following requirement: https://eel.is/c++draft/rand.util.seedseq#7
17+
//
18+
// Mandates: iterator_traits<RandomAccessIterator>::value_type is an unsigned integer
19+
// type capable of accommodating 32-bit quantities.
20+
21+
// UNSUPPORTED: c++03
22+
// REQUIRES: stdlib=libc++
23+
24+
#include <random>
25+
#include <climits>
26+
27+
#include "test_macros.h"
28+
29+
void f() {
30+
std::seed_seq seq;
31+
32+
// Not an integral type
33+
{
34+
double* p = nullptr;
35+
seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires{{.+}}}}
36+
// expected-error@*:* 0+ {{invalid operands to}}
37+
}
38+
39+
// Not an unsigned type
40+
{
41+
long long* p = nullptr;
42+
seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires{{.+}}}}
43+
}
44+
45+
// Not a 32-bit type
46+
{
47+
#if UCHAR_MAX < UINT32_MAX
48+
unsigned char* p = nullptr;
49+
seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires{{.+}}}}
50+
#endif
51+
}
52+
53+
// Everything satisfied
54+
{
55+
unsigned long* p = nullptr;
56+
seq.generate(p, p); // no diagnostic
57+
}
58+
}

0 commit comments

Comments
 (0)