random_device.hpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #ifndef BOOST_UUID_DETAIL_RANDOM_DEVICE_HPP_INCLUDED
  2. #define BOOST_UUID_DETAIL_RANDOM_DEVICE_HPP_INCLUDED
  3. // Copyright 2024 Peter Dimov
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // https://www.boost.org/LICENSE_1_0.txt
  6. #if defined(__MINGW32__)
  7. // Under MinGW up to GCC 9, std::random_device is
  8. // deterministic and always produces the same
  9. // sequence
  10. #include <boost/throw_exception.hpp>
  11. #include <system_error>
  12. #include <limits>
  13. #include <stdlib.h>
  14. extern "C" int __cdecl rand_s( unsigned int *randomValue );
  15. namespace boost {
  16. namespace uuids {
  17. namespace detail {
  18. struct random_device
  19. {
  20. // noncopyable to match std::random_device
  21. random_device() = default;
  22. random_device( random_device&& ) = delete;
  23. random_device& operator=( random_device&& ) = delete;
  24. using result_type = unsigned;
  25. static constexpr result_type min()
  26. {
  27. return std::numeric_limits<result_type>::min();
  28. }
  29. static constexpr result_type max()
  30. {
  31. return std::numeric_limits<result_type>::max();
  32. }
  33. result_type operator()()
  34. {
  35. unsigned v;
  36. auto r = rand_s( &v );
  37. if( r != 0 )
  38. {
  39. BOOST_THROW_EXCEPTION( std::system_error( r, std::generic_category(), "rand_s" ) );
  40. }
  41. return v;
  42. }
  43. };
  44. } // detail
  45. } // uuids
  46. } // boost
  47. #else
  48. #include <random>
  49. namespace boost {
  50. namespace uuids {
  51. namespace detail {
  52. using std::random_device;
  53. } // detail
  54. } // uuids
  55. } // boost
  56. #endif
  57. #endif // BOOST_UUID_DETAIL_RANDOM_DEVICE_HPP_INCLUDED