diff --git a/vnr/cpputil/cppcstring.h b/vnr/cpputil/cppcstring.h new file mode 100644 index 0000000..d1cd3dc --- /dev/null +++ b/vnr/cpputil/cppcstring.h @@ -0,0 +1,122 @@ +#ifndef CPPCSTRING_H +#define CPPCSTRING_H + +// cppcstring.h +// 10/12/2014 jichi + +#include // for size_t +#include +//#include // for std::min +#include "ccutil/ccmacro.h" + +// strlen + +template +inline size_t cpp_basic_strlen(const charT *s) +{ + const charT *p = s; + while (*p) p++; + return p - s; +} + +inline size_t cpp_strlen(const char *s) { return cpp_basic_strlen(s); } +inline size_t cpp_wstrlen(const wchar_t *s) { return cpp_basic_strlen(s); } + +template +inline size_t cpp_basic_strnlen(const charT *s, size_t n) +{ + const charT *p = s; + while (*p && n) p++, n--; + return p - s; +} + +inline size_t cpp_strnlen(const char *s, size_t n) { return cpp_basic_strnlen(s, n); } +inline size_t cpp_wstrnlen(const wchar_t *s, size_t n) { return cpp_basic_strnlen(s, n); } + +// strnchr + +#define cpp_basic_strnchr_(s, c, n) \ + { \ + while (*s && n) { \ + if (*s == c) \ + return s; \ + s++, n--; \ + } \ + return nullptr; \ + } +template +inline charT *cpp_basic_strnchr(charT *s, int c, size_t n) +cpp_basic_strnchr_(s, c, n) + +template +inline const charT *cpp_basic_strnchr(const charT *s, int c, size_t n) +cpp_basic_strnchr_(s, c, n) + +// The same as memchr +inline char *cpp_strnchr(char *s, int c, size_t n) { return cpp_basic_strnchr(s, c, n); } +inline const char *cpp_strnchr(const char *s, int c, size_t n) { return cpp_basic_strnchr(s, c, n); } + +inline wchar_t *cpp_wcsnchr(wchar_t *s, int c, size_t n) { return cpp_basic_strnchr(s, c, n); } +inline const wchar_t *cpp_wcsnchr(const wchar_t *s, int c, size_t n) { return cpp_basic_strnchr(s, c, n); } + +// strnstr + +#define cpp_basic_strnstr_(s, slen, r, rlen, ncmp) \ + { \ + while (*s && slen >= rlen) { \ + if (ncmp(s, r, CC_MIN(slen, rlen)) == 0) \ + return s; \ + s++, slen--; \ + } \ + return nullptr; \ + } + +template +inline charT *cpp_basic_strnstr(charT *s, const charT *r, size_t n) +cpp_basic_strnstr_(s, n, r, ::strlen(r), ::strncmp) + +template +inline const charT *cpp_basic_strnstr(const charT *s, const charT *r, size_t n) +cpp_basic_strnstr_(s, n, r, ::strlen(r), ::strncmp) + +template <> +inline wchar_t *cpp_basic_strnstr(wchar_t *s, const wchar_t *r, size_t n) +cpp_basic_strnstr_(s, n, r, ::wcslen(r), ::wcsncmp) + +template <> +inline const wchar_t *cpp_basic_strnstr(const wchar_t *s, const wchar_t *r, size_t n) +cpp_basic_strnstr_(s, n, r, ::wcslen(r), ::wcsncmp) + +inline char *cpp_strnstr(char *s, const char *r, size_t n) { return cpp_basic_strnstr(s, r, n); } +inline const char *cpp_strnstr(const char *s, const char *r, size_t n) { return cpp_basic_strnstr(s, r, n); } +inline wchar_t *cpp_wcsnstr(wchar_t *s, const wchar_t *r, size_t n) { return cpp_basic_strnstr(s, r, n); } +inline const wchar_t *cpp_wcsnstr(const wchar_t *s, const wchar_t *r, size_t n) { return cpp_basic_strnstr(s, r, n); } + +// strnpbrk + +// it might be faster to use strchr functions, which is not portable though +#define cpp_basic_strnpbrk_(s, sep, n) \ + { \ + while (*s && n) { \ + for (auto p = sep; *p; p++) \ + if (*s == *p) \ + return s; \ + s++, n--; \ + } \ + return nullptr; \ + } + +template +inline charT *cpp_basic_strnpbrk(charT *dest, const char2T *breakset, size_t n) +cpp_basic_strnpbrk_(dest, breakset, n) + +template +inline const charT *cpp_basic_strnpbrk(const charT *dest, const char2T *breakset, size_t n) +cpp_basic_strnpbrk_(dest, breakset, n) + +inline char *cpp_strnpbrk(char *dest, const char *breakset, size_t n) { return cpp_basic_strnpbrk(dest, breakset, n); } +inline const char *cpp_strnpbrk(const char *dest, const char *breakset, size_t n) { return cpp_basic_strnpbrk(dest, breakset, n); } +inline wchar_t *cpp_wcsnpbrk(wchar_t *dest, const wchar_t *breakset, size_t n) { return cpp_basic_strnpbrk(dest, breakset, n); } +inline const wchar_t *cpp_wcsnpbrk(const wchar_t *dest, const wchar_t *breakset, size_t n) { return cpp_basic_strnpbrk(dest, breakset, n); } + +#endif // CPPCSTRING_H diff --git a/vnr/cpputil/cpplocale.h b/vnr/cpputil/cpplocale.h new file mode 100644 index 0000000..71041f4 --- /dev/null +++ b/vnr/cpputil/cpplocale.h @@ -0,0 +1,21 @@ +#ifndef CPPLOCALE_H +#define CPPLOCALE_H + +// cpplocale.h +// 9/26/2014 jichi + +#include +#include + +//#include + +// See: http://stackoverflow.com/questions/20195262/how-to-read-an-utf-8-encoded-file-containing-chinese-characters-and-output-them +// The same as boost::locale::generator().generate("UTF-8"), which require linking +// See: http://en.cppreference.com/w/cpp/locale/codecvt_utf8 +// - 0x10ffff is the default maximum value. +// - std::consume_header will skip the leading encoding byte from the input. +template +inline std::locale cpp_utf8_locale(std::locale init = std::locale()) +{ return std::locale(init, new std::codecvt_utf8()); } + +#endif // CPPLOCALE_H diff --git a/vnr/cpputil/cppmarshal.h b/vnr/cpputil/cppmarshal.h new file mode 100644 index 0000000..8b81639 --- /dev/null +++ b/vnr/cpputil/cppmarshal.h @@ -0,0 +1,110 @@ +#ifndef CPPMARSHAL_H +#define CPPMARSHAL_H + +// cppmarshal.h +// 10/12/2014 jichi +// +// Functions are by default big-endian, the same as memory layout. +#include "cpputil/cppcstring.h" +#include "cpputil/cpptype.h" +#include + +/* Read */ + +// Read number + +template +inline const byteT *cpp_marshal_getval(const byteT *p, valT *v) +{ *v = *reinterpret_cast(p); return p + sizeof(valT); } + +// Read pointer + +template \ +inline const byteT *cpp_marshal_getptr(const byteT *p, ptrT v) +{ return cpp_marshal_getval(p, reinterpret_cast(v)); } + +// Read string + +template +inline const byteT *cpp_marshal_getstr(const byteT *p, charT *s) +{ + size_t n = cpp_basic_strlen(p); + ::memcpy(s, p, n + 1); // including '\0' + return p + n + 1; +} + +template +inline const byteT *cpp_marshal_getnstr(const byteT *p, charT *s, size_t n) +{ + if (n = cpp_basic_strnlen(p, n)) + ::memcpy(s, p, n); // including '\0' + s[n] = 0; + return p + n + 1; +} + +/* Write */ + +// Write number + +template +inline byteT *cpp_marshal_putval(byteT *p, valT v) +{ *reinterpret_cast(p) = v; return p + sizeof(valT); } + +// Write pointer + +template \ +inline byteT *cpp_marshal_putptr(byteT *p, ptrT v) +{ return cpp_marshal_putval(p, reinterpret_cast(v)); } + +// Write string + +template +inline byteT *cpp_marshal_putstr(byteT *p, charT *s) +{ + size_t n = cpp_basic_strlen(s); + ::memcpy(p, s, n + 1); // including '\0' + return p + n + 1; +} + +template +inline byteT *cpp_marshal_putstr(byteT *p, charT *s, size_t n) +{ + if (n = cpp_basic_strnlen(s, n)) + ::memcpy(p, s, n); // including '\0' + s[n] = 0; + return p + n + 1; +} + +/* Expansion */ + +#define CPP_DECLARE_MARSHAL_GETVAL(type) \ + template \ + inline const byteT *cpp_marshal_get##type(const byteT *p, cpp_##type *v) { return cpp_marshal_getval(p, v); } + +#define CPP_DECLARE_MARSHAL_PUTVAL(type) \ + template \ + inline byteT *cpp_marshal_put##type(byteT *p, cpp_##type v) { return cpp_marshal_putval(p, v); } + +CPP_DECLARE_MARSHAL_PUTVAL(float) +CPP_DECLARE_MARSHAL_PUTVAL(double) +CPP_DECLARE_MARSHAL_GETVAL(float) +CPP_DECLARE_MARSHAL_GETVAL(double) +CPP_DECLARE_MARSHAL_GETVAL(int) +CPP_DECLARE_MARSHAL_GETVAL(int8) +CPP_DECLARE_MARSHAL_GETVAL(int32) +CPP_DECLARE_MARSHAL_GETVAL(int64) +CPP_DECLARE_MARSHAL_GETVAL(uint) +CPP_DECLARE_MARSHAL_GETVAL(uint8) +CPP_DECLARE_MARSHAL_GETVAL(uint32) +CPP_DECLARE_MARSHAL_GETVAL(uint64) + +CPP_DECLARE_MARSHAL_PUTVAL(int) +CPP_DECLARE_MARSHAL_PUTVAL(int8) +CPP_DECLARE_MARSHAL_PUTVAL(int32) +CPP_DECLARE_MARSHAL_PUTVAL(int64) +CPP_DECLARE_MARSHAL_PUTVAL(uint) +CPP_DECLARE_MARSHAL_PUTVAL(uint8) +CPP_DECLARE_MARSHAL_PUTVAL(uint32) +CPP_DECLARE_MARSHAL_PUTVAL(uint64) + +#endif // CPPMARSHAL_H diff --git a/vnr/cpputil/cppmath.h b/vnr/cpputil/cppmath.h new file mode 100644 index 0000000..2ed2296 --- /dev/null +++ b/vnr/cpputil/cppmath.h @@ -0,0 +1,25 @@ +#ifndef CPPMATH_H +#define CPPMATH_H + +// cppmacro.h +// 10/12/2014 jichi +#include + +// The same as qMin +template +inline const T &cpp_min(const T &a, const T &b) { return (a < b) ? a : b; } + +// The same as qMax +template +inline const T &cpp_max(const T &a, const T &b) { return (a < b) ? b : a; } + +// The same as qBound +template +inline const T &cpp_bound(const T &min, const T &val, const T &max) +{ return cpp_max(min, cpp_min(max, val)); } + +// The same as qFuzzyCompare +inline bool cpp_fuzzy_compare(float p1, float p2) +{ return (abs(p1 - p2) <= 0.00001f * cpp_min(abs(p1), abs(p2))); } + +#endif // CPPMATH_H diff --git a/vnr/cpputil/cpppath.h b/vnr/cpputil/cpppath.h new file mode 100644 index 0000000..e812a9d --- /dev/null +++ b/vnr/cpputil/cpppath.h @@ -0,0 +1,54 @@ +#ifndef CPPPATH_H +#define CPPPATH_H + +// cpppath.h +// 5/7/2014 jichi + +#include // for size_t + +enum : char { cpp_pathsep_unix = '/' , cpp_pathsep_win = '\\' }; + +// basename + +template +inline const charT *cpp_basic_basename(const charT *s) +{ + const charT *p = s; + //if (s) // not checked + for (; *s; s++) + if (*s == cpp_pathsep_unix || *s == cpp_pathsep_win) + p = s + 1; + return p; +} + +//if (const char *r = ::strrchr(s, pathsep)) +// return r + 1; // skip the path seperator +//else +// return s; +inline const char *cpp_basename(const char *s) { return cpp_basic_basename(s); } + +//if (const wchar_t *r = ::wcsrchr(s, pathsep)) +// return r + 1; // skip the path seperator +//else +// return s; +inline const wchar_t *cpp_wbasename(const wchar_t *s) { return cpp_basic_basename(s); } + +// dirmame + +/// Return the length so that s[len] == pathsep +template +inline size_t cpp_basic_dirlen(const charT *s) +{ + const charT *p = s, + *t = s; + //if (s) // not checked + for (; *s; s++) + if (*s == cpp_pathsep_unix || *s == cpp_pathsep_win) + p = s + 1; + return p - t; +} + +inline size_t cpp_wdirlen(const char *s) { return cpp_basic_dirlen(s); } +inline size_t cpp_wdirlen(const wchar_t *s) { return cpp_basic_dirlen(s); } + +#endif // CPPPATH_H diff --git a/vnr/cpputil/cppstring.h b/vnr/cpputil/cppstring.h new file mode 100644 index 0000000..77c65fe --- /dev/null +++ b/vnr/cpputil/cppstring.h @@ -0,0 +1,36 @@ +#ifndef CPPSTRING_H +#define CPPSTRING_H + +// cppstring.h +// 10/12/2014 jichi + +#include +#include + +// Initializers + +template +inline std::basic_string cpp_basic_string_of(const stringT &s) +{ return std::basic_string(s.cbegin(), s.cend()); } + +template +inline std::string cpp_string_of(const stringT &s) +{ return std::string(s.cbegin(), s.cend()); } + +inline std::string cpp_string_of(const char *s) +{ return s; } + +inline std::string cpp_string_of(const wchar_t *s) +{ return std::string(s, s + ::wcslen(s)); } + +template +inline std::wstring cpp_wstring_of(const stringT &s) +{ return std::wstring(s.cbegin(), s.cend()); } + +inline std::wstring cpp_wstring_of(const wchar_t *s) +{ return s; } + +inline std::wstring cpp_wstring_of(const char *s) +{ return std::wstring(s, s + ::strlen(s)); } + +#endif // CPPSTRING_H diff --git a/vnr/cpputil/cpptype.h b/vnr/cpputil/cpptype.h new file mode 100644 index 0000000..cc381ae --- /dev/null +++ b/vnr/cpputil/cpptype.h @@ -0,0 +1,42 @@ +#ifndef CPPTYPE_H +#define CPPTYPE_H + +// cpptype.h +// 10/12/2014 jichi +#include + +// Platform-dependent + +typedef char cpp_char; +typedef unsigned char cpp_uchar; + +typedef short cpp_short; +typedef unsigned short cpp_ushort; + +typedef int cpp_int; +typedef unsigned int cpp_uint; + +typedef long cpp_long; +typedef unsigned long cpp_ulong; + +typedef long long cpp_llong; +typedef unsigned long long cpp_ullong; + +typedef float cpp_float; +typedef double cpp_double; + +// Platform-independent + +typedef int8_t cpp_int8; +typedef uint8_t cpp_uint8; + +typedef cpp_int8 cpp_byte; +typedef cpp_uint8 cpp_ubyte; + +typedef int32_t cpp_int32; +typedef uint32_t cpp_uint32; + +typedef int64_t cpp_int64; +typedef uint64_t cpp_uint64; + +#endif // CPPTYPE_H diff --git a/vnr/cpputil/cppunicode.h b/vnr/cpputil/cppunicode.h new file mode 100644 index 0000000..e874c38 --- /dev/null +++ b/vnr/cpputil/cppunicode.h @@ -0,0 +1,23 @@ +#ifndef CPPUNICODE_H +#define CPPUNICODE_H + +#include +typedef std::basic_string, std::allocator > cpp_u16string; +typedef std::basic_string, std::allocator > cpp_u32string; + +// +#if defined(_FSTREAM_) || defined(_LIBCPP_FSTREAM) || defined(_GLIBCXX_FSTREAM) +typedef std::basic_ifstream > cpp_u16ifstream; +typedef std::basic_ifstream > cpp_u32ifstream; + +typedef std::basic_ofstream > cpp_u16ofstream; +typedef std::basic_ofstream > cpp_u32ofstream; + +typedef std::basic_fstream > cpp_u16fstream; +typedef std::basic_fstream > cpp_u32fstream; +#endif // + +inline char16_t cpp_u32low(char32_t c) { return c; } +inline char16_t cpp_u32high(char32_t c) { return c >> 16; } + +#endif // CPPUNICODE_H diff --git a/vnr/cpputil/cpputil.pri b/vnr/cpputil/cpputil.pri new file mode 100644 index 0000000..4a354a6 --- /dev/null +++ b/vnr/cpputil/cpputil.pri @@ -0,0 +1,18 @@ +# cpputil.pri +# 9/26/2012 jichi + +DEFINES += WITH_LIB_CPPUTIL + +DEPENDPATH += $$PWD + +HEADERS += \ + $$PWD/cppcstring.h \ + $$PWD/cpplocale.h \ + $$PWD/cppmarshal.h \ + $$PWD/cpppath.h \ + $$PWD/cppregex.h \ + $$PWD/cppstring.h \ + $$PWD/cpptype.h \ + $$PWD/cppunicode.h + +# EOF