108 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// The behavior of std::random_device changed on Apple platforms with10// https://llvm.org/D116045 (d202c76441e1).11// XFAIL: target={{.+}}-apple-{{.+}} && using-built-library-before-llvm-1412 13// UNSUPPORTED: no-random-device14 15// <random>16 17// class random_device;18 19// explicit random_device(const string& token = implementation-defined); // before C++2020// random_device() : random_device(implementation-defined) {} // C++2021// explicit random_device(const string& token); // C++2022 23// For the following ctors, the standard states: "The semantics and default24// value of the token parameter are implementation-defined". Implementations25// therefore aren't required to accept any string, but the default shouldn't26// 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#endif36 37#include "test_macros.h"38#if TEST_STD_VER >= 1139#include "test_convertible.h"40#endif41 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_EXCEPTIONS48 try {49 std::random_device r(token);50 LIBCPP_ASSERT(false);51 } catch (const std::system_error&) {52 }53#else54 ((void)token);55#endif56}57 58int main(int, char**) {59 {60 std::random_device r;61 (void)r;62 }63 // Check the validity of various tokens64 {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#else78 check_random_device_valid("/dev/urandom");79 check_random_device_invalid("/dev/random");80 check_random_device_invalid("/dev/null");81 check_random_device_invalid("/dev/nonexistent");82 check_random_device_invalid("wrong file");83#endif84 }85 86#if !defined(_WIN32)87// Test that random_device(const string&) properly handles getting88// a file descriptor with the value '0'. Do this by closing the standard89// 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 >= 11103 static_assert(test_convertible<std::random_device>(), "");104#endif105 106 return 0;107}108