[libc++] Add a static_assert for a Mandates in seed_seq (#86992)

Fixes #84843
This commit is contained in:
Louis Dionne
2024-04-03 06:06:52 -04:00
committed by GitHub
parent bf1df25048
commit ca48d4dfd3
2 changed files with 64 additions and 0 deletions

View File

@@ -14,6 +14,7 @@
#include <__algorithm/max.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_unsigned.h>
#include <cstdint>
#include <initializer_list>
#include <vector>
@@ -79,6 +80,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) >= sizeof(uint32_t),
"[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);

View File

@@ -0,0 +1,58 @@
//===----------------------------------------------------------------------===//
//
// 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{{.+}}}}
// 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{{.+}}}}
}
// Not a 32-bit type
{
#if UCHAR_MAX < UINT32_MAX
unsigned char* p = nullptr;
seq.generate(p, p); // expected-error-re@*:* {{static assertion failed{{.+}}: [rand.util.seedseq]/7 requires{{.+}}}}
#endif
}
// Everything satisfied
{
unsigned long* p = nullptr;
seq.generate(p, p); // no diagnostic
}
}