changes
This commit is contained in:
@@ -26,7 +26,13 @@
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
<<<<<<< HEAD
|
||||
#include <limits>
|
||||
=======
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <iomanip>
|
||||
>>>>>>> 4e754377ee4922940c37a20710314befeff0d84e
|
||||
|
||||
#include "luastack.hpp"
|
||||
#include "spookyv2.hpp"
|
||||
@@ -60,9 +66,17 @@ bool valid_double(string_view v);
|
||||
bool valid_int64(string_view v);
|
||||
bool valid_hex64(string_view v);
|
||||
|
||||
// Parse numbers as int32, int64, or double. Returns errval on failure.
|
||||
// Convert strings to numbers. Returns errval on failure.
|
||||
//
|
||||
// The integer parser accepts a sequence of digits,
|
||||
// with or without a + or - sign. The hex parser
|
||||
// does not allow a + or - sign. For both the int64
|
||||
// and hex64 parser, it is a failure if the number
|
||||
// does not fit in 64 bits. The double parser does
|
||||
// not accept the strings 'nan' or 'inf'.
|
||||
//
|
||||
double to_double(string_view v, double errval = std::numeric_limits<double>::quiet_NaN());
|
||||
int64_t to_int64(string_view v, int64_t errval = std::numeric_limits<int64_t>::min());
|
||||
int64_t to_int64(string_view v, int64_t errval = std::numeric_limits<int64_t>::max());
|
||||
uint64_t to_hex64(string_view v, uint64_t errval = std::numeric_limits<uint64_t>::max());
|
||||
|
||||
// Trim whitspace from a string_view.
|
||||
@@ -116,6 +130,13 @@ string_view read_to_sep(string_view &source, char sep);
|
||||
//
|
||||
string_view read_to_line(string_view &source);
|
||||
|
||||
// Read a prefix string from a string_view.
|
||||
//
|
||||
// Returns false if the string view doesn't start with
|
||||
// the specified prefix.
|
||||
//
|
||||
bool read_prefix(string_view &source, string_view prefix);
|
||||
|
||||
// Read from a string_view until whitespace is reached.
|
||||
//
|
||||
// If there's any whitespace in the source, returns the text
|
||||
@@ -137,9 +158,46 @@ string_view read_nbytes(string_view &source, int nbytes);
|
||||
//
|
||||
string_view read_ascii_identifier(string_view &source);
|
||||
|
||||
// Read a number from a string view
|
||||
//
|
||||
// This is basically a regex pattern matching routine
|
||||
// hardwired with the regex for numbers. You must
|
||||
// specify which of the following parts of the regex
|
||||
// are allowed or not:
|
||||
//
|
||||
// * plus sign
|
||||
// * minus sign
|
||||
// * decimal point
|
||||
// * scientific notation exponents
|
||||
//
|
||||
// Returns the number as a string_view. There is
|
||||
// no guarantee that the number is small enough to
|
||||
// fit into any particular number of bits. This
|
||||
// always uses base 10.
|
||||
//
|
||||
std::string_view read_number(string_view &source, bool plus, bool minus, bool dec, bool exp);
|
||||
|
||||
// Read an ascii character from a string.
|
||||
//
|
||||
// Returns -1 if the string is empty.
|
||||
//
|
||||
int32_t read_ascii_char(string_view &source);
|
||||
|
||||
// Read a UTF8 codepoint from a string_view.
|
||||
//
|
||||
// If the next thing in the string_view isn't a valid
|
||||
// codepoint, returns -1 and doesn't update the view.
|
||||
//
|
||||
int32_t read_codepoint_utf8(string_view &source);
|
||||
|
||||
// Return true if the string is valid utf-8.
|
||||
bool valid_utf8(string_view s);
|
||||
|
||||
// Return true if the number conforms to the spec.
|
||||
// See read_number for more information.
|
||||
//
|
||||
bool valid_number(string_view v, bool plus, bool minus, bool dec, bool exp);
|
||||
|
||||
} // namespace sv
|
||||
|
||||
namespace util {
|
||||
@@ -176,9 +234,22 @@ double profiling_clock();
|
||||
// Output a string to a stream using Lua string escaping and quoting.
|
||||
void quote_string(const eng::string &str, std::ostream *os);
|
||||
|
||||
// base64 encode.
|
||||
void base64_encode(std::string_view v, std::ostream *oss);
|
||||
|
||||
// base64 decode.
|
||||
//
|
||||
// Returns true if the base64 was 'clean' base64, as
|
||||
// opposed to base64 with extraneous characters.
|
||||
//
|
||||
bool base64_decode(std::string_view v, std::ostream *oss);
|
||||
|
||||
// ID vector quick create.
|
||||
IdVector id_vector_create(int64_t id1=-1, int64_t id2=-1, int64_t id3=-1, int64_t id4=-1);
|
||||
|
||||
// Print an ID vector to a stream.
|
||||
void print_id_vector(const IdVector &idv, std::ostream *os);
|
||||
|
||||
// ID vector debug string.
|
||||
eng::string id_vector_debug_string(const IdVector &idv);
|
||||
|
||||
@@ -198,6 +269,16 @@ eng::string hash_to_hex(const HashValue &hash);
|
||||
// This is a good hash, but not cryptographically good.
|
||||
uint64_t hash_ints(uint64_t n1, uint64_t n2, uint64_t n3, uint64_t n4);
|
||||
|
||||
// Hash a single 64-bit integer.
|
||||
// This is a good hash, but not cryptographically good.
|
||||
// Published by David Stafford in his article 'Better Bit Mixing'.
|
||||
inline uint64_t hash_int(uint64_t x) {
|
||||
x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
|
||||
x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
|
||||
x = x ^ (x >> 31);
|
||||
return x;
|
||||
}
|
||||
|
||||
// Convert a 64-bit hash value into a floating point number between 0 and 1.
|
||||
double hash_to_double(uint64_t hash);
|
||||
|
||||
@@ -220,6 +301,14 @@ eng::string repeat_string(const eng::string &a, int n);
|
||||
eng::string tolower(eng::string input);
|
||||
eng::string toupper(eng::string input);
|
||||
|
||||
// Convert a codepoint number into a utf8 string.
|
||||
// If the codepoint is invalid, returns empty string.
|
||||
eng::string get_codepoint_utf8(int32_t cp);
|
||||
|
||||
// Write a codepoint in utf8 to a stream.
|
||||
// If the codepoint is invalid, writes nothing and returns false.
|
||||
bool write_codepoint_utf8(int32_t cp, std::ostream *out);
|
||||
|
||||
// Calculate distance between two points
|
||||
double distance_squared(double x1, double y1, double x2, double y2);
|
||||
|
||||
@@ -247,15 +336,12 @@ struct XYZ {
|
||||
XYZ(float ix, float iy, float iz) { x=ix; y=iy; z=iz; }
|
||||
bool operator ==(const XYZ &o) const { return x==o.x && y == o.y && z==o.z; }
|
||||
bool operator !=(const XYZ &o) const { return x!=o.x || y != o.y || z!=o.z; }
|
||||
XYZ operator -(const XYZ &o) const { return XYZ(x-o.x, y-o.y, z-o.z); }
|
||||
XYZ operator +(const XYZ &o) const { return XYZ(x+o.x, y+o.y, z+o.z); }
|
||||
XYZ operator *(float scale) const { return XYZ(x*scale, y*scale, z*scale); }
|
||||
eng::string debug_string() const;
|
||||
};
|
||||
|
||||
// These are formatting directives that can be sent to a std::ostream.
|
||||
class hex64 {};
|
||||
class hex32 {};
|
||||
class hex16 {};
|
||||
class hex8 {};
|
||||
|
||||
class NullStreamBuffer : public std::streambuf
|
||||
{
|
||||
public:
|
||||
@@ -265,24 +351,69 @@ public:
|
||||
// send_to_stream: send all arguments to the specified stream.
|
||||
inline void send_to_stream(std::ostream &os) {}
|
||||
template <class ARG, class... REST>
|
||||
inline void send_to_stream(std::ostream &os, ARG arg, REST & ... rest) {
|
||||
inline void send_to_stream(std::ostream &os, const ARG &arg, const REST & ... rest) {
|
||||
os << arg;
|
||||
send_to_stream(os, rest...);
|
||||
}
|
||||
|
||||
// ss: convert all arguments to a string by sending them to a stringstream.
|
||||
template <class... ARGS>
|
||||
inline eng::string ss(ARGS & ... args) {
|
||||
inline eng::string ss(const ARGS & ... args) {
|
||||
eng::ostringstream oss;
|
||||
send_to_stream(oss, args...);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// A better API than std::setfill, std::hex, std::setw, std::setprecision
|
||||
//
|
||||
// Usage examples:
|
||||
// std::cout << util::hex.width(5).fill('0').val(123)
|
||||
// std::cout << util::dec.fill('$').precision(val(123)
|
||||
//
|
||||
// The reason that other API is bad is that it can leave std::cout
|
||||
// in an unpredictable state. This API always leaves the stream clean.
|
||||
//
|
||||
template <class VALUE>
|
||||
class FormattedNumber {
|
||||
public:
|
||||
VALUE value_;
|
||||
bool hex_;
|
||||
int width_;
|
||||
char fill_;
|
||||
int precision_;
|
||||
|
||||
constexpr FormattedNumber(VALUE v, bool h, int w, char f, int p)
|
||||
: value_(v), hex_(h), width_(w), fill_(f), precision_(p) {}
|
||||
|
||||
constexpr FormattedNumber width(int w) const { return FormattedNumber(value_, hex_, w, fill_, precision_); }
|
||||
constexpr FormattedNumber fill(char f) const { return FormattedNumber(value_, hex_, width_, f, precision_); }
|
||||
constexpr FormattedNumber precision(int p) const { return FormattedNumber(value_, hex_, width_, fill_, p); }
|
||||
|
||||
template <class NVALUE>
|
||||
constexpr FormattedNumber val(NVALUE v) const { return FormattedNumber(v, hex_, width_, fill_, precision_); }
|
||||
};
|
||||
|
||||
constexpr auto hex = FormattedNumber<int>(0, true, 0, '0', 6);
|
||||
constexpr auto hex8 = FormattedNumber<int>(0, true, 2, '0', 6);
|
||||
constexpr auto hex16 = FormattedNumber<int>(0, true, 4, '0', 6);
|
||||
constexpr auto hex32 = FormattedNumber<int>(0, true, 8, '0', 6);
|
||||
constexpr auto hex64 = FormattedNumber<int>(0, true, 16, '0', 6);
|
||||
constexpr auto dec = FormattedNumber<int>(0, false, 0, ' ', 6);
|
||||
|
||||
} // namespace util
|
||||
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex64 &v);
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex32 &v);
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex16 &v);
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex8 &v);
|
||||
template<class VALUE>
|
||||
inline std::ostream &operator<<(std::ostream &oss, util::FormattedNumber<VALUE> n) {
|
||||
if (n.hex_) oss << std::hex;
|
||||
else oss << std::dec;
|
||||
oss << std::setprecision(n.precision_) << std::setfill(n.fill_) << std::setw(n.width_) << n.value_;
|
||||
oss << std::dec << std::setfill(' ') << std::setprecision(6);
|
||||
return oss;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &oss, const util::XYZ &xyz) {
|
||||
oss << xyz.x << "," << xyz.y << "," << xyz.z;
|
||||
return oss;
|
||||
}
|
||||
|
||||
#endif // UTIL_HPP
|
||||
|
||||
Reference in New Issue
Block a user