mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
replace format use of std::stringstream
with sprintf
This commit is contained in:
parent
0d78e54abe
commit
0af2855ce5
@ -48,9 +48,9 @@ struct VoidP{
|
||||
bool operator>=(const VoidP& other) const { return ptr >= other.ptr; }
|
||||
|
||||
Str hex() const{
|
||||
std::stringstream ss; // hex
|
||||
ss << std::hex << reinterpret_cast<intptr_t>(ptr);
|
||||
return "0x" + ss.str();
|
||||
SStream ss;
|
||||
ss.write_hex(ptr);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
|
@ -3,13 +3,11 @@
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <string_view>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
@ -127,37 +127,31 @@ struct SStream{
|
||||
PK_ALWAYS_PASS_BY_POINTER(SStream)
|
||||
// pod_vector<T> is allocated by pool64 so the buffer can be moved into Str without a copy
|
||||
pod_vector<char> buffer;
|
||||
int _precision = -1;
|
||||
|
||||
bool empty() const { return buffer.empty(); }
|
||||
void setprecision(int precision) { _precision = precision; }
|
||||
|
||||
SStream(){}
|
||||
SStream(int guess_size){ buffer.reserve(guess_size); }
|
||||
|
||||
Str str();
|
||||
|
||||
SStream& operator<<(const Str& s);
|
||||
SStream& operator<<(const char* s);
|
||||
SStream& operator<<(i64 val);
|
||||
SStream& operator<<(const std::string& s);
|
||||
SStream& operator<<(std::string_view s);
|
||||
SStream& operator<<(char c);
|
||||
SStream& operator<<(StrName sn);
|
||||
void write_hex(unsigned char c);
|
||||
SStream& operator<<(const Str&);
|
||||
SStream& operator<<(const char*);
|
||||
SStream& operator<<(int);
|
||||
SStream& operator<<(unsigned int);
|
||||
SStream& operator<<(unsigned long);
|
||||
SStream& operator<<(i64);
|
||||
SStream& operator<<(f64);
|
||||
SStream& operator<<(const std::string&);
|
||||
SStream& operator<<(std::string_view);
|
||||
SStream& operator<<(char);
|
||||
SStream& operator<<(StrName);
|
||||
|
||||
template<typename T>
|
||||
SStream& operator<<(T val){
|
||||
if constexpr(std::is_floating_point_v<T>){
|
||||
if(std::isinf(val) || std::isnan(val)){
|
||||
return (*this) << std::to_string(val);
|
||||
}
|
||||
std::stringstream ss; // float
|
||||
ss << std::setprecision(std::numeric_limits<f64>::max_digits10-1) << val;
|
||||
std::string s = ss.str();
|
||||
if(std::all_of(s.begin()+1, s.end(), isdigit)) s += ".0";
|
||||
return (*this) << s;
|
||||
}
|
||||
(*this) << std::to_string(val);
|
||||
return *this;
|
||||
}
|
||||
void write_hex(unsigned char);
|
||||
void write_hex(void*);
|
||||
void write_hex(i64);
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
|
@ -60,10 +60,12 @@ namespace pkpy{
|
||||
char c = 0;
|
||||
if(s[i]>='0' && s[i]<='9') c += s[i]-'0';
|
||||
else if(s[i]>='A' && s[i]<='F') c += s[i]-'A'+10;
|
||||
else if(s[i]>='a' && s[i]<='f') c += s[i]-'a'+10;
|
||||
else vm->ValueError(fmt("invalid hex char: '", s[i], "'"));
|
||||
c <<= 4;
|
||||
if(s[i+1]>='0' && s[i+1]<='9') c += s[i+1]-'0';
|
||||
else if(s[i+1]>='A' && s[i+1]<='F') c += s[i+1]-'A'+10;
|
||||
else if(s[i+1]>='a' && s[i+1]<='f') c += s[i+1]-'a'+10;
|
||||
else vm->ValueError(fmt("invalid hex char: '", s[i+1], "'"));
|
||||
buffer.p[i/2] = c;
|
||||
}
|
||||
|
@ -117,9 +117,9 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float
|
||||
}, {}, BindType::STATICMETHOD);
|
||||
|
||||
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
||||
PyVec2& self = _CAST(PyVec2&, obj);
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(3);
|
||||
Vec2 self = _CAST(PyVec2&, obj);
|
||||
SStream ss;
|
||||
ss.setprecision(3);
|
||||
ss << "vec2(" << self.x << ", " << self.y << ")";
|
||||
return VAR(ss.str());
|
||||
});
|
||||
@ -165,9 +165,9 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float
|
||||
});
|
||||
|
||||
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
||||
PyVec3& self = _CAST(PyVec3&, obj);
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(3);
|
||||
Vec3 self = _CAST(PyVec3&, obj);
|
||||
SStream ss;
|
||||
ss.setprecision(3);
|
||||
ss << "vec3(" << self.x << ", " << self.y << ", " << self.z << ")";
|
||||
return VAR(ss.str());
|
||||
});
|
||||
@ -202,9 +202,9 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float
|
||||
});
|
||||
|
||||
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
||||
PyVec4& self = _CAST(PyVec4&, obj);
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(3);
|
||||
Vec4 self = _CAST(PyVec4&, obj);
|
||||
SStream ss;
|
||||
ss.setprecision(3);
|
||||
ss << "vec4(" << self.x << ", " << self.y << ", " << self.z << ", " << self.w << ")";
|
||||
return VAR(ss.str());
|
||||
});
|
||||
@ -261,9 +261,9 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float
|
||||
});
|
||||
|
||||
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
||||
PyMat3x3& self = _CAST(PyMat3x3&, obj);
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(3);
|
||||
const PyMat3x3& self = _CAST(PyMat3x3&, obj);
|
||||
SStream ss;
|
||||
ss.setprecision(3);
|
||||
ss << "mat3x3([" << self._11 << ", " << self._12 << ", " << self._13 << ",\n";
|
||||
ss << " " << self._21 << ", " << self._22 << ", " << self._23 << ",\n";
|
||||
ss << " " << self._31 << ", " << self._32 << ", " << self._33 << "])";
|
||||
|
@ -254,9 +254,9 @@ void init_builtins(VM* _vm) {
|
||||
});
|
||||
|
||||
_vm->bind_func<1>(_vm->builtins, "hex", [](VM* vm, ArgsView args) {
|
||||
std::stringstream ss; // hex
|
||||
ss << std::hex << CAST(i64, args[0]);
|
||||
return VAR("0x" + ss.str());
|
||||
SStream ss;
|
||||
ss.write_hex(CAST(i64, args[0]));
|
||||
return VAR(ss.str());
|
||||
});
|
||||
|
||||
_vm->bind_func<1>(_vm->builtins, "iter", [](VM* vm, ArgsView args) {
|
||||
@ -300,9 +300,10 @@ void init_builtins(VM* _vm) {
|
||||
// tp_object
|
||||
_vm->bind__repr__(VM::tp_object, [](VM* vm, PyObject* obj) {
|
||||
if(is_tagged(obj)) PK_FATAL_ERROR();
|
||||
std::stringstream ss; // hex
|
||||
ss << "<" << _type_name(vm, vm->_tp(obj)) << " object at 0x";
|
||||
ss << std::hex << reinterpret_cast<intptr_t>(obj) << ">";
|
||||
SStream ss;
|
||||
ss << "<" << _type_name(vm, vm->_tp(obj)) << " object at ";
|
||||
ss.write_hex(obj);
|
||||
ss << ">";
|
||||
return VAR(ss.str());
|
||||
});
|
||||
|
||||
|
57
src/str.cpp
57
src/str.cpp
@ -469,6 +469,19 @@ int utf8len(unsigned char c, bool suppress){
|
||||
return *this << sn.sv();
|
||||
}
|
||||
|
||||
SStream& SStream::operator<<(unsigned int val){
|
||||
return (*this) << static_cast<i64>(val);
|
||||
}
|
||||
|
||||
SStream& SStream::operator<<(unsigned long val){
|
||||
// unsigned long could be out of range of `i64`, use `std::to_string` instead
|
||||
return (*this) << std::to_string(val);
|
||||
}
|
||||
|
||||
SStream& SStream::operator<<(int val){
|
||||
return (*this) << static_cast<i64>(val);
|
||||
}
|
||||
|
||||
SStream& SStream::operator<<(i64 val){
|
||||
// str(-2**64).__len__() == 21
|
||||
buffer.reserve(buffer.size() + 24);
|
||||
@ -489,9 +502,53 @@ int utf8len(unsigned char c, bool suppress){
|
||||
return *this;
|
||||
}
|
||||
|
||||
SStream& SStream::operator<<(f64 val){
|
||||
if(std::isinf(val) || std::isnan(val)){
|
||||
return (*this) << std::to_string(val);
|
||||
}
|
||||
char b[32];
|
||||
if(_precision == -1){
|
||||
int prec = std::numeric_limits<f64>::max_digits10-1;
|
||||
sprintf(b, "%.*g", prec, val);
|
||||
}else{
|
||||
int prec = _precision;
|
||||
sprintf(b, "%.*f", prec, val);
|
||||
}
|
||||
(*this) << b;
|
||||
if(std::all_of(b+1, b+strlen(b), isdigit)){
|
||||
(*this) << ".0";
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SStream::write_hex(unsigned char c){
|
||||
*this << "0123456789ABCDEF"[c >> 4];
|
||||
*this << "0123456789ABCDEF"[c & 0xf];
|
||||
}
|
||||
|
||||
void SStream::write_hex(void* p){
|
||||
(*this) << "0x";
|
||||
uintptr_t p_t = reinterpret_cast<uintptr_t>(p);
|
||||
for(int i=sizeof(void*)-1; i>=0; i--){
|
||||
unsigned char cpnt = (p_t >> (i * 8)) & 0xff;
|
||||
write_hex(cpnt);
|
||||
}
|
||||
}
|
||||
|
||||
void SStream::write_hex(i64 val){
|
||||
if(val < 0){
|
||||
(*this) << "-";
|
||||
val = -val;
|
||||
}
|
||||
(*this) << "0x";
|
||||
if(val == 0){
|
||||
(*this) << "0";
|
||||
return;
|
||||
}
|
||||
for(int i=56; i>=0; i-=8){
|
||||
unsigned char cpnt = (val >> i) & 0xff;
|
||||
if(cpnt != 0) write_hex(cpnt);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pkpy
|
@ -1,5 +1,4 @@
|
||||
#include "pocketpy/vm.h"
|
||||
#include "pocketpy/config.h"
|
||||
|
||||
namespace pkpy{
|
||||
|
||||
@ -507,8 +506,9 @@ PyObject* VM::_format_string(Str spec, PyObject* obj){
|
||||
if(type == 'f'){
|
||||
f64 val = CAST(f64, obj);
|
||||
if(precision < 0) precision = 6;
|
||||
std::stringstream ss; // float
|
||||
ss << std::fixed << std::setprecision(precision) << val;
|
||||
SStream ss;
|
||||
ss.setprecision(precision);
|
||||
ss << val;
|
||||
ret = ss.str();
|
||||
}else if(type == 'd'){
|
||||
ret = std::to_string(CAST(i64, obj));
|
||||
|
Loading…
x
Reference in New Issue
Block a user