#ifndef RTC_IMPL_UTILS_H
#define RTC_IMPL_UTILS_H
#include "common.hpp"
#include <climits>
#include <limits>
#include <map>
#include <random>
#include <stdexcept>
#include <vector>
namespace rtc::impl::utils {
std::vector<string> explode(const string &str, char delim);
string implode(const std::vector<string> &tokens, char delim);
string url_decode(const string &str);
string base64_encode(const binary &data);
std::seed_seq random_seed();
template <typename Generator, typename Result = typename Generator::result_type>
struct random_engine_wrapper {
Generator &engine;
using result_type = Result;
static constexpr result_type min() { return static_cast<Result>(Generator::min()); }
static constexpr result_type max() { return static_cast<Result>(Generator::max()); }
inline result_type operator()() { return static_cast<Result>(engine()); }
inline void discard(unsigned long long z) { engine.discard(z); }
};
template <typename Generator = std::mt19937, typename Result = typename Generator::result_type>
auto random_engine() {
static thread_local std::seed_seq seed = random_seed();
static thread_local Generator engine{seed};
return random_engine_wrapper<Generator, Result>{engine};
}
template <typename Generator = std::mt19937> auto random_bytes_engine() {
using char_independent_bits_engine =
std::independent_bits_engine<Generator, CHAR_BIT, unsigned short>;
static_assert(char_independent_bits_engine::min() == std::numeric_limits<uint8_t>::min());
static_assert(char_independent_bits_engine::max() == std::numeric_limits<uint8_t>::max());
return random_engine<char_independent_bits_engine, uint8_t>();
}
template <typename T> uint16_t to_uint16(T i) {
if (i >= 0 && static_cast<typename std::make_unsigned<T>::type>(i) <=
std::numeric_limits<uint16_t>::max())
return static_cast<uint16_t>(i);
else
throw std::invalid_argument("Integer out of range");
}
template <typename T> uint32_t to_uint32(T i) {
if (i >= 0 && static_cast<typename std::make_unsigned<T>::type>(i) <=
std::numeric_limits<uint32_t>::max())
return static_cast<uint32_t>(i);
else
throw std::invalid_argument("Integer out of range");
}
namespace this_thread {
void set_name(const string &name);
}
}
#endif