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:
invertego 2022-09-05 06:12:08 -07:00 committed by Screwtapello
parent df4981787c
commit 9fbbea23d3
1 changed files with 3 additions and 41 deletions

View File

@ -169,16 +169,6 @@ template<uint Bits> struct stringify<Real<Bits>> {
//arrays //arrays
template<> struct stringify<vector<uint8_t>> { 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) { stringify(const vector<uint8_t>& source) {
_text.resize(source.size()); _text.resize(source.size());
memory::copy(_text.data(), source.data(), source.size()); memory::copy(_text.data(), source.data(), source.size());
@ -191,7 +181,7 @@ template<> struct stringify<const vector<uint8_t>&> {
//char arrays //char arrays
template<> struct stringify<char*> { 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 data() const -> const char* { return _data; }
auto size() const -> uint { return strlen(_data); } auto size() const -> uint { return strlen(_data); }
const char* _data; const char* _data;
@ -213,13 +203,6 @@ template<> struct stringify<string> {
const string& _text; 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> { template<> struct stringify<string_view> {
stringify(const string_view& source) : _view(source) {} stringify(const string_view& source) : _view(source) {}
auto data() const -> const char* { return _view.data(); } auto data() const -> const char* { return _view.data(); }
@ -227,13 +210,6 @@ template<> struct stringify<string_view> {
const string_view& _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>> { template<> struct stringify<array_view<uint8_t>> {
stringify(const array_view<uint8_t>& source) : _view(source) {} stringify(const array_view<uint8_t>& source) : _view(source) {}
auto data() const -> const char* { return _view.data<const char>(); } 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; 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> { template<> struct stringify<string_pascal> {
stringify(const string_pascal& source) : _text(source) {} stringify(const string_pascal& source) : _text(source) {}
auto data() const -> const char* { return _text.data(); } auto data() const -> const char* { return _text.data(); }
@ -255,13 +224,6 @@ template<> struct stringify<string_pascal> {
const string_pascal& _text; 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 //pointers
//note: T = char* is matched by stringify<string_view> //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> { template<typename T> auto make_string(const T& value) {
return stringify<T>(forward<T>(value)); return stringify<std::decay_t<T>>(value);
} }
} }