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// The behavior of std::random_device changed on Apple platforms with
10// https://llvm.org/D116045 (d202c76441e1).
11// XFAIL: target={{.+}}-apple-{{.+}} && using-built-library-before-llvm-14
12
13// UNSUPPORTED: no-random-device
14
15// <random>
16
17// class random_device;
18
19// explicit random_device(const string& token = implementation-defined); // before C++20
20// random_device() : random_device(implementation-defined) {} // C++20
21// explicit random_device(const string& token); // C++20
22
23// For the following ctors, the standard states: "The semantics and default
24// value of the token parameter are implementation-defined". Implementations
25// therefore aren't required to accept any string, but the default shouldn't
26// throw.
27
28#include <random>
29#include <string>
30#include <system_error>
31#include <cassert>
32
33#if !defined(_WIN32)
34#include <unistd.h>
35#endif
36
37#include "test_macros.h"
38#if TEST_STD_VER >= 11
39#include "test_convertible.h"
40#endif
41
42void check_random_device_valid(const std::string &token) {
43 std::random_device r(token);
44}
45
46void check_random_device_invalid(const std::string &token) {
47#ifndef TEST_HAS_NO_EXCEPTIONS
48 try {
49 std::random_device r(token);
50 LIBCPP_ASSERT(false);
51 } catch (const std::system_error&) {
52 }
53#else
54 ((void)token);
55#endif
56}
57
58int main(int, char**) {
59 {
60 std::random_device r;
61 (void)r;
62 }
63 // Check the validity of various tokens
64 {
65#if defined(_LIBCPP_USING_ARC4_RANDOM)
66 check_random_device_valid("/dev/urandom");
67 check_random_device_valid("/dev/random");
68 check_random_device_valid("/dev/null");
69 check_random_device_valid("/dev/nonexistent");
70 check_random_device_valid("wrong file");
71#elif defined(_LIBCPP_USING_DEV_RANDOM)
72 check_random_device_valid("/dev/urandom");
73 check_random_device_valid("/dev/random");
74 check_random_device_valid("/dev/null");
75 check_random_device_invalid("/dev/nonexistent");
76 check_random_device_invalid("wrong file");
77#else
78 check_random_device_valid(token: "/dev/urandom");
79 check_random_device_invalid(token: "/dev/random");
80 check_random_device_invalid(token: "/dev/null");
81 check_random_device_invalid(token: "/dev/nonexistent");
82 check_random_device_invalid(token: "wrong file");
83#endif
84 }
85
86#if !defined(_WIN32)
87// Test that random_device(const string&) properly handles getting
88// a file descriptor with the value '0'. Do this by closing the standard
89// streams so that the descriptor '0' is available.
90 {
91 int ec;
92 ec = close(STDIN_FILENO);
93 assert(!ec);
94 ec = close(STDOUT_FILENO);
95 assert(!ec);
96 ec = close(STDERR_FILENO);
97 assert(!ec);
98 std::random_device r;
99 }
100#endif // !defined(_WIN32)
101
102#if TEST_STD_VER >= 11
103 static_assert(test_convertible<std::random_device>(), "");
104#endif
105
106 return 0;
107}
108

source code of libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp