[llvm-commits] Twine/StringRef enhancements & usage
David Blaikie
dblaikie at gmail.com
Thu Jul 28 16:24:28 PDT 2011
Here's some more Twine-ification of APIs. I realize this seems like a
somewhat random assortment - I haven't, for example, fully changed
some types to Twine (so there might be some functions in a type that
take Twine, others that take StringRef still), but it does seem to be
stable & I didn't want to just keep piling on more code.
API changes:
* Twine
* appendTo(std::string&)
Works like "toVector" but on std::strings. (I'd like to rename
toVector to appendTo to make it clear it's appending, not overwriting
- I added test cases to expose this existing deliberate design because
when I 'fixed' it by clearing the vector in toVector I broke a bunch
of stuff that was relying on it being appending)
* assignTo(std::string&)
clear() + appendTo
* StringRef
* StringRef(const char (&)[N])
an array constructor so it doesn't have to use strlen for string
literals. For some reason this doesn't work in GCC (try making the
StringRef(const char*) ctor explicit & GCC starts complaining about
how it can't convert the const char* in 'return "foo";' into a
StringRef). This is a little tricky - it doesn't include the trailing
null character if one is present. This is to maintain compatibility
with the existing implicit conversion from string arrays via the
(const char*) ctor.
* assignTo(std::string&)
the same idea as Twine::appendTo(std::string&). This is more
efficient than using str = strRef; because it doesn't produce an extra
temporary buffer to return through. ctor initialization (std::string
str = strRef;) is still efficient due to RVO.
* booleanTest()/SafeBool<T>
I've made StringRef boolean testable so it can be used as a drop
in replacement when null tests are required
* TwineString - a type that makes retrieving/manipulating a Twine
value a little simpler. Yes, it's a little dodgy that it derives from
StringRef but it's 'good enough' to make Twines the default string
arguments - any time you see a StringRef or std::string argument there
should be a specific explanation.
One current problem I have is that SmallString<T> is convertible to
StringRef and StringRef to Twine, but that seems to be insufficient to
implicitly convert from SmallString<T> to Twine - so I've added a few
explicit Twine(smallstr) calls around. If there's a better way to
approach this (ultimately we could add a SmallString option to Twine,
but it'd be sort of nice not to have to do that either) I'm all ears.
Aside: Twine::toNullTerminatedStringRef scares me. A lot. It relies on
UB to leave the null character beyond the end of the allocated buffer.
Could we fix this to return a StringRef that doesn't include the null
character (though I'm not sure this bit should matter, really - code
asking for the null terminated StringRef is probably doing it to pass
to a C API that's not going to care about the StringRef's concept of
length), but leave the character itself in the buffer? (& I was
thinking we could check if the Twine was a non-empty StringRef
already, test the last character for null, then return a StringRef
over that rather than using a new buffer - though this wouldn't work
for my current StringRef(const char(&)[N]) ctor, since the length
won't include the null character).
Thanks for your help,
- David
-------------- next part --------------
A non-text attachment was scrubbed...
Name: twine_clang.diff
Type: application/octet-stream
Size: 1262 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20110728/f90ebda3/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: twine.diff
Type: application/octet-stream
Size: 70174 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20110728/f90ebda3/attachment-0001.obj>
More information about the llvm-commits
mailing list