25#ifndef JOIN_CORE_UTILS_HPP
26#define JOIN_CORE_UTILS_HPP
45#define JOIN_LIKELY(x) __builtin_expect (!!(x), 1)
46#define JOIN_UNLIKELY(x) __builtin_expect (!!(x), 0)
56 template <
typename Type,
size_t sz>
61 throw std::out_of_range (
"data size");
65 template <
typename Type>
74 template <
typename Type>
79 if (BYTE_ORDER == LITTLE_ENDIAN)
81 return (val >> 8) | (val << 8);
87 template <
typename Type>
92 if (BYTE_ORDER == LITTLE_ENDIAN)
94 return ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) |
95 ((val & 0x000000ff) << 24);
101 template <
typename Type>
106 if (BYTE_ORDER == LITTLE_ENDIAN)
108 return ((val & 0xff00000000000000ull) >> 56) | ((val & 0x00ff000000000000ull) >> 40) |
109 ((val & 0x0000ff0000000000ull) >> 24) | ((val & 0x000000ff00000000ull) >> 8) |
110 ((val & 0x00000000ff000000ull) << 8) | ((val & 0x0000000000ff0000ull) << 24) |
111 ((val & 0x000000000000ff00ull) << 40) | ((val & 0x00000000000000ffull) << 56);
122 if (BYTE_ORDER == LITTLE_ENDIAN)
143 if (BYTE_ORDER == LITTLE_ENDIAN)
159 template <
class Type>
170 bool operator() (
const std::string& a,
const std::string& b)
const noexcept
172 return ::strcasecmp (a.c_str (), b.c_str ()) < 0;
182 template <
class Type>
197 return ((a.size () == b.size ()) && std::equal (a.begin (), a.end (), b.begin (), [] (
char c1,
char c2) {
198 return std::toupper (c1) == std::toupper (c2);
209 return s.erase (0, s.find_first_not_of (
"\f\t\v\r\n "));
219 return s.erase (s.find_last_not_of (
" \f\t\v\r\n") + 1);
227 inline std::string&
trim (std::string& s)
239 inline std::string&
replaceAll (std::string& str,
const std::string& toReplace,
const std::string& by)
243 while ((pos = str.find (toReplace, pos)) != std::string::npos)
245 str.replace (pos, toReplace.length (), by);
258 inline std::vector<std::string>
split (
const std::string& in,
const std::string& delim)
260 std::vector<std::string> tokens;
263 size_t beg = 0, end = in.find (delim);
264 size_t sz = delim.size ();
265 while (end != std::string::npos)
267 tokens.push_back (in.substr (beg, end - beg));
269 end = in.find (delim, beg);
271 tokens.push_back (in.substr (beg));
282 inline std::vector<std::string>
rsplit (
const std::string& in,
const std::string& delim)
284 std::vector<std::string> tokens;
287 size_t beg = in.rfind (delim), end = std::string::npos;
288 size_t sz = delim.size ();
289 while (beg != std::string::npos)
291 tokens.push_back (in.substr (beg + sz, end - beg - sz));
293 beg = in.rfind (delim, end - sz);
295 tokens.push_back (in.substr (0, end));
307 inline bool getline (std::istream& in, std::string& line, std::streamsize max = 1024)
344 inline bool getline (std::streambuf& in, std::string& line, std::streamsize max = 1024)
346 std::istream istream (&in);
347 return getline (istream, line, max);
357 inline uint16_t
checksum (
const uint16_t* data,
size_t len, uint16_t current = 0) noexcept
359 uint32_t sum = current;
369#if __BYTE_ORDER == __LITTLE_ENDIAN
370 sum += *
reinterpret_cast<const uint8_t*
> (data);
372 sum += *
reinterpret_cast<const uint8_t*
> (data) << 8;
376 sum = (sum >> 16) + (sum & 0xffff);
379 return static_cast<uint16_t
> (~sum);
387 inline void dump (
const void* data,
unsigned long size, std::ostream& out = std::cout)
389 const uint8_t* buf =
reinterpret_cast<const uint8_t*
> (data);
391 for (
int i = 0; i < int (size); i += 16)
393 out << std::hex << std::uppercase << std::setw (8);
394 out << std::setfill (
'0') << i << std::dec <<
":";
396 for (
int j = 0; j < 16; ++j)
399 out << std::dec <<
" ";
401 if (i + j <
int (size))
403 out << std::hex << std::uppercase << std::setw (2);
404 out << std::setfill ('0') << static_cast<int> (buf[i + j]);
407 out << std::dec <<
" ";
410 out << std::dec <<
" ";
412 for (
int j = 0; j < 16; ++j)
414 if (i + j <
int (size))
416 if (isprint (buf[i + j]))
433 template <
typename Type>
434 std::enable_if_t<std::numeric_limits<Type>::is_integer, Type>
randomize ()
436 std::random_device rnd;
437 std::uniform_int_distribution<Type> dist{};
447 template <
class Func,
class... Args>
448 std::chrono::milliseconds
benchmark (Func&& func, Args&&... args)
450 auto beg = std::chrono::steady_clock::now ();
451 func (std::forward<Args> (args)...);
452 auto end = std::chrono::steady_clock::now ();
453 return std::chrono::duration_cast<std::chrono::milliseconds> (end - beg);
461 template <
typename Clock,
typename Duration>
462 struct timespec
toTimespec (
std::chrono::time_point<Clock, Duration> timePoint)
464 auto secs = std::chrono::time_point_cast<std::chrono::seconds> (timePoint);
465 auto ns = std::chrono::time_point_cast<std::chrono::nanoseconds> (timePoint) -
466 std::chrono::time_point_cast<std::chrono::nanoseconds> (secs);
468 auto scount = secs.time_since_epoch ().count ();
469 auto ncount = ns.count ();
471 return {.tv_sec = scount, .tv_nsec = ncount};
479 template <
typename Rep,
typename Period>
482 auto secs = std::chrono::duration_cast<std::chrono::seconds> (duration);
483 auto ns = std::chrono::duration_cast<std::chrono::nanoseconds> (duration - secs);
485 auto scount = secs.count ();
486 auto ncount = ns.count ();
488 return {.tv_sec = scount, .tv_nsec = ncount};
496 constexpr bool isPow2 (uint64_t value)
noexcept
498 return (value != 0) && ((value & (value - 1)) == 0);
506 constexpr uint64_t
nextPow2 (uint64_t value)
noexcept
518 value |= value >> 16;
519 value |= value >> 32;
Definition acceptor.hpp:32
void dump(const void *data, unsigned long size, std::ostream &out=std::cout)
dump data to standard output stream.
Definition utils.hpp:387
constexpr bool isPow2(uint64_t value) noexcept
check if a value is a power of two.
Definition utils.hpp:496
Type & swap(Type &val)
swaps byte orders.
Definition utils.hpp:183
std::chrono::milliseconds benchmark(Func &&func, Args &&... args)
benchmark function call.
Definition utils.hpp:448
std::string & trim(std::string &s)
trim.
Definition utils.hpp:227
struct timespec toTimespec(std::chrono::time_point< Clock, Duration > timePoint)
converts time_point to timespec.
Definition utils.hpp:462
std::enable_if_t< std::numeric_limits< Type >::is_integer, Type > randomize()
create a random number.
Definition utils.hpp:434
constexpr uint64_t nextPow2(uint64_t value) noexcept
round up to the next power of two.
Definition utils.hpp:506
uint16_t checksum(const uint16_t *data, size_t len, uint16_t current=0) noexcept
get standard 1s complement checksum.
Definition utils.hpp:357
bool compareNoCase(const std::string &a, const std::string &b)
case insensitive string comparison.
Definition utils.hpp:195
std::vector< std::string > split(const std::string &in, const std::string &delim)
split a string using a delimiter.
Definition utils.hpp:258
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195
thread_local std::error_code lastError
last error.
Definition error.cpp:32
std::string & trimLeft(std::string &s)
trim left.
Definition utils.hpp:207
bool getline(std::istream &in, std::string &line, std::streamsize max=1024)
read line (delimiter "\r\n").
Definition utils.hpp:307
std::vector< std::string > rsplit(const std::string &in, const std::string &delim)
split a string in reverse order using a delimiter.
Definition utils.hpp:282
std::string & replaceAll(std::string &str, const std::string &toReplace, const std::string &by)
replace all occurrences of a substring.
Definition utils.hpp:239
std::string & trimRight(std::string &s)
trim right.
Definition utils.hpp:217
Type operator()(Type val)
Definition utils.hpp:59
Type operator()(Type val)
Definition utils.hpp:162
bool operator()(const std::string &a, const std::string &b) const noexcept
Definition utils.hpp:170