mirror of https://github.com/bsnes-emu/bsnes.git
nall: always pass by reference to make_string()
Many specializations of stringify store a reference to the wrapped value. Therefore, passing arguments to make_string() by value can be disastrous if the compiler does not perform copy elision and stringify stores a reference to a variable that goes out of scope when make_string() returns. Cherry-picked from ares commit 3d826f5b266027529f0c12211c744a23bbe25a56.
This commit is contained in:
parent
df4981787c
commit
9fbbea23d3
|
@ -169,16 +169,6 @@ template<uint Bits> struct stringify<Real<Bits>> {
|
|||
//arrays
|
||||
|
||||
template<> struct stringify<vector<uint8_t>> {
|
||||
stringify(vector<uint8_t> source) {
|
||||
_text.resize(source.size());
|
||||
memory::copy(_text.data(), source.data(), source.size());
|
||||
}
|
||||
auto data() const -> const char* { return _text.data(); }
|
||||
auto size() const -> uint { return _text.size(); }
|
||||
vector<char> _text;
|
||||
};
|
||||
|
||||
template<> struct stringify<const vector<uint8_t>&> {
|
||||
stringify(const vector<uint8_t>& source) {
|
||||
_text.resize(source.size());
|
||||
memory::copy(_text.data(), source.data(), source.size());
|
||||
|
@ -191,7 +181,7 @@ template<> struct stringify<const vector<uint8_t>&> {
|
|||
//char arrays
|
||||
|
||||
template<> struct stringify<char*> {
|
||||
stringify(char* source) : _data(source ? source : "") {}
|
||||
stringify(const char* source) : _data(source ? source : "") {}
|
||||
auto data() const -> const char* { return _data; }
|
||||
auto size() const -> uint { return strlen(_data); }
|
||||
const char* _data;
|
||||
|
@ -213,13 +203,6 @@ template<> struct stringify<string> {
|
|||
const string& _text;
|
||||
};
|
||||
|
||||
template<> struct stringify<const string&> {
|
||||
stringify(const string& source) : _text(source) {}
|
||||
auto data() const -> const char* { return _text.data(); }
|
||||
auto size() const -> uint { return _text.size(); }
|
||||
const string& _text;
|
||||
};
|
||||
|
||||
template<> struct stringify<string_view> {
|
||||
stringify(const string_view& source) : _view(source) {}
|
||||
auto data() const -> const char* { return _view.data(); }
|
||||
|
@ -227,13 +210,6 @@ template<> struct stringify<string_view> {
|
|||
const string_view& _view;
|
||||
};
|
||||
|
||||
template<> struct stringify<const string_view&> {
|
||||
stringify(const string_view& source) : _view(source) {}
|
||||
auto data() const -> const char* { return _view.data(); }
|
||||
auto size() const -> uint { return _view.size(); }
|
||||
const string_view& _view;
|
||||
};
|
||||
|
||||
template<> struct stringify<array_view<uint8_t>> {
|
||||
stringify(const array_view<uint8_t>& source) : _view(source) {}
|
||||
auto data() const -> const char* { return _view.data<const char>(); }
|
||||
|
@ -241,13 +217,6 @@ template<> struct stringify<array_view<uint8_t>> {
|
|||
const array_view<uint8_t>& _view;
|
||||
};
|
||||
|
||||
template<> struct stringify<const array_view<uint8_t>&> {
|
||||
stringify(const array_view<uint8_t>& source) : _view(source) {}
|
||||
auto data() const -> const char* { return _view.data<const char>(); }
|
||||
auto size() const -> uint { return _view.size(); }
|
||||
const array_view<uint8_t>& _view;
|
||||
};
|
||||
|
||||
template<> struct stringify<string_pascal> {
|
||||
stringify(const string_pascal& source) : _text(source) {}
|
||||
auto data() const -> const char* { return _text.data(); }
|
||||
|
@ -255,13 +224,6 @@ template<> struct stringify<string_pascal> {
|
|||
const string_pascal& _text;
|
||||
};
|
||||
|
||||
template<> struct stringify<const string_pascal&> {
|
||||
stringify(const string_pascal& source) : _text(source) {}
|
||||
auto data() const -> const char* { return _text.data(); }
|
||||
auto size() const -> uint { return _text.size(); }
|
||||
const string_pascal& _text;
|
||||
};
|
||||
|
||||
//pointers
|
||||
|
||||
//note: T = char* is matched by stringify<string_view>
|
||||
|
@ -281,8 +243,8 @@ template<typename T> struct stringify<T*> {
|
|||
|
||||
//
|
||||
|
||||
template<typename T> auto make_string(T value) -> stringify<T> {
|
||||
return stringify<T>(forward<T>(value));
|
||||
template<typename T> auto make_string(const T& value) {
|
||||
return stringify<std::decay_t<T>>(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue