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

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