Last active
October 27, 2022 10:19
-
-
Save yumetodo/68bd4796e128babb506766c03f116641 to your computer and use it in GitHub Desktop.
random_device warkaround for mingw gcc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.exe | |
*.out | |
.vscode/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "random_device.hpp" | |
#include <iostream> | |
#include <vector> | |
#include <functional> | |
#include <algorithm> | |
using seed_v_t = std::vector<cpprefjp::random_device::result_type>; | |
seed_v_t create_seed_v() | |
{ | |
cpprefjp::random_device rnd; | |
seed_v_t sed_v(9); | |
std::generate(sed_v.begin(), sed_v.end(), std::ref(rnd)); | |
return sed_v; | |
} | |
int main() | |
{ | |
const auto sed_v = create_seed_v(); | |
std::seed_seq seq(sed_v.begin(), sed_v.end()); | |
std::mt19937 engine(seq); | |
std::uniform_int_distribution<int> dist(1, 32); | |
for(int i = 0; i < 10; ++i) std::cout << dist(engine) << std::endl; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <random> | |
#if defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__) | |
#include <system_error> | |
#include <limits> | |
#include <string> | |
#include <Windows.h> | |
#include <wincrypt.h> | |
namespace workaround_mingw_gcc { | |
class random_device { | |
private: | |
class crypt_context { | |
private: | |
HCRYPTPROV prov_; | |
public: | |
crypt_context(DWORD prov_type, LPCTSTR container = nullptr, LPCTSTR provider = nullptr, DWORD flags = 0) | |
{ | |
using std::system_category; | |
using std::system_error; | |
const auto er = ::CryptAcquireContext(&this->prov_, container, provider, prov_type, flags); | |
if(!er) { | |
throw system_error( | |
std::error_code(::GetLastError(), system_category()), | |
"CryptAcquireContext:(" + std::to_string(er) + ')' | |
); | |
} | |
} | |
crypt_context(const crypt_context&) = delete; | |
void operator=(const crypt_context&) = delete; | |
~crypt_context() noexcept | |
{ | |
::CryptReleaseContext(this->prov_, 0); | |
} | |
//HCRYPTPROV& get() noexcept { return this->prov_; } | |
const HCRYPTPROV& get() const noexcept { return this->prov_; } | |
}; | |
crypt_context prov_; | |
public: | |
using result_type = unsigned int; | |
explicit random_device(const std::string& /*token*/ = "workaround_mingw_gcc ") | |
: prov_(PROV_RSA_FULL) | |
{} | |
random_device(const random_device&) = delete; | |
void operator=(const random_device&) = delete; | |
//~random_device() = default; | |
double entropy() const noexcept { return 0.0; } | |
result_type operator()() | |
{ | |
using std::system_category; | |
using std::system_error; | |
result_type re; | |
const auto er = ::CryptGenRandom(this->prov_.get(), sizeof(re), reinterpret_cast<BYTE*>(&re)); | |
if(!er) { | |
throw system_error( | |
std::error_code(::GetLastError(), system_category()), | |
"CryptGenRandom:(" + std::to_string(er) + ')' | |
); | |
} | |
return re; | |
} | |
static constexpr result_type min() { return std::numeric_limits<result_type>::min(); } | |
static constexpr result_type max() { return std::numeric_limits<result_type>::max(); } | |
}; | |
} | |
namespace cpprefjp { | |
using workaround_mingw_gcc::random_device; | |
} | |
#else //defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__) | |
namespace cpprefjp { | |
using std::random_device; | |
} | |
#endif //defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__) |
Author
yumetodo
commented
Aug 22, 2017
- https://cpprefjp.github.io/reference/random/random_device.html
- cpprefjp/site#458
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment