Sun
19
Aug 2018
tl;dr I've written a small library, which I called "str_view - null-termination-aware string-view class for C++". You can find code and documentation on GitHub - sawickiap/str_view. Read on to see full story behind it...
Let me disclose my controversial beliefs: I like C++ STL. I think that any programming language needs to provide some built-in strings and containers to be called modern and suitable for developing large programs. But of course I'm aware that careless use of classes like std::list
or std::map
makes program very slow due to large number of dynamic allocations.
What I value the most is RAII - the concept that memory is automatically freed whenever an object referenced by value is destroyed. That's why I use std::unique_ptr
all over the place in my personal code. Whenever I create and own an array, I use std::vector
, but when I just pass it to some other code for reading, I pass raw pointer and number of elements - myVec.data()
and myVec.size()
. Similarly, whenever I own and build a string, I use std::string
(or rather std::wstring
- I like Unicode), but when I pass it somewhere for reading, I use raw pointer.
There are multiple ways a string can be passed. One is pointer to first character and number of characters. Another one is pointer to first character and pointer to the next after last character - a pair of iterators, also called range. These two can be trivially converted between each other. Out of these, I prefer pointer + length, because I think that number of characters is slightly more often needed than pointer past the end.
But there is another way of passing strings common in C and C++ programs - just one pointer to a string that needs to be null-terminated. I think that null-terminated strings is one of the worst and the most stupid inventions in computer science. Not only it limits set of characters available to be used in string content by excluding '\0'
, but it also makes calculation of string length O(n) time complexity. It also creates opportunity for security bugs. Still we have to deal with it because that's the format that most libraries expect.
I came up with an idea for a class that would encapsulate a reference to an externally-owned, immutable string, or a piece of thereof. Objects of such class could be used to pass strings to library functions instead of e.g. a pointer to null-terminated string or a pair of iterators. They can be then queried for length()
, indexed to access individual characters etc., as well as asked for a null-terminated copy using c_str()
method - similar to std::string
.
Code like this already exists, e.g. C++17 introduces class std::string_view
. But my implementation has a twist that I'm quite happy with, which made me call my class "null-termination-aware". My str_view
class not only remembers pointer and length of the referred string, but also the way it was created to avoid unnecessary operations and lazily evaluate those that are requested.
c_str()
trivially returns pointer to the original string.length()
.length()
trivially returns it.c_str()
creates a local, null-terminated copy of the string upon first call.If you consider such class useful in your C++ code, see GitHub - sawickiap/str_view project for code (it's just a single header file), documentation, and extensive set of tests. I share this code for free, on MIT license. Feel free to contact me if you find any bugs or have any suggestions regarding this library.
Comments | #productions #libraries #c++ Share