Here's my stab at it: https://github.com/OpenImageIO/oiio/pull/772
Feedback appreciated. Now that I've done it, I rather like it. On Dec 26, 2013, at 12:35 PM, Larry Gritz <[email protected]> wrote: > Here's the C++ draft document: > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html > It's being considered for C++14. > > Boost 1.55 has an implementation, but not everybody (including my employers) > is on such a recent boost, so I don't think we can depend on that. It's a > simple class, I don't mind rolling our own, and in fact if we do we can also > make it a bit more optimized in dealing with ustring. > > The basic gist is that, say you have a library function foo(x), where x is a > character sequence. What type should x be? Let's assume that foo needs to > read the characters but doesn't wish to assume ownership or modify them in > place. And also let's assume that the library function may be used by apps > that like char*, and other apps that like std::string. > > If x is const char*, then (a) it's technically unsafe because no length is > passed, so it assumes that the characters are valid and are 0-terminated, and > also (b) an app that is dealing with std::string needs to call it as > foo(s.c_str()), which is a little clunky and may rub some people wrong. > > On the other hand, if x is a std::string&, that works really nicely for an > app already using std::string, but if the caller just has a char array, it'll > end up converting to a std::string to pass (which involves allocating memory, > copying the chars, then deallocating after the call, very wasteful). > > So the idea is that you'd declare a non-owning (char* + length) object and > pass that around with implied conversions. You can just pass either a char* > or a std::string, works fine both ways, and in neither case will it allocate, > copy, or deallocate. For the char* case, if the app knows the length of the > string already, it further provides safety by passing the length without > having to scan the string. > > Also, there are examples of functions that currently return a string where > the string will necessarily be a contiguous subregion of another existing > string that was passed as an argument (example: substr). Instead of > allocating std::strings, it can return string_ref's. The allocation, if ever > needed, is done on the assignment after return, if you know what I mean. > > To answer your question, you can have an empty string_ref, yes. > > > > On Dec 26, 2013, at 3:02 PM, Mark Visser <[email protected]> wrote: > >> I'm really only familiar with the oiiotool part of the codebase, but I >> noticed there are a few places that pass const char* instead of std::string >> because the latter can't represent NULL. Does string_ref allow the null >> string? >> >> Is this the same thing? >> http://www.boost.org/doc/libs/1_55_0/libs/utility/doc/html/string_ref.html >> >> cheers >> >> On Dec 26, 2013, at 1:10 PM, Larry Gritz <[email protected]> wrote: >> >>> Just floating the idea to see what people think. >>> >>> Many packages have some version of a "string reference" class that is a >>> non-owning (and non-allocating) reference to character data that >>> auto-converts to char* or std::string when assigned. C++14 is drafting it >>> into its standard library. >>> >>> I've been toying with the idea of doing an implementation of this in OIIO, >>> and changing many of the utility and other functions that take strings -- >>> which are currently a bit of a mish-mash of std::string, char*, and ustring >>> -- to accepting a string_ref, then internally it can do what it wishes. For >>> many uses that just need to look at the characters, this can eliminate many >>> transitory std::string allocations and copies. Since we can't count on >>> C++14 (hah, we can't even count on C++11), I'd have to write my own (it's >>> very simple) and so it could also be aware of ustring. >>> >>> Does anybody have strong opinions? Including: >>> >>> 1. Don't change anything ever, we hate string_ref. >>> >>> 2. A nice idea to use it when it's available from C++14, but wait until >>> then. >>> >>> 3. Yes, do it and convert anyplace where it's appropriate. Making it >>> ustring-aware is great, even if it means deviating from what C++14 will >>> eventually offer as std::string_ref. >>> >>> 4. Do it, but only if it's exactly like what C++14 std::string_ref will end >>> up being. >>> >>> 5. Something else. >>> >>> If you don't care one way or the other, as long as it won't really affect >>> what the source code looks like on the app side, you don't need to chime >>> in, that's the default answer. >>> >>> Similarly, there are a lot of places where we pass arrays as just a T*. It >>> sometimes bugs me how unsafe this is, there are always assumptions about >>> how many T's it points to. We could make an array_ref<T> template, which >>> is just a bundling of the pointer and a length, and use that in many places >>> instead of raw pointers. There's no allocation issue here, but forcing the >>> callers to pass an explicit length (and have the called function given an >>> explicit length) could be useful in improving code safety. >>> >>> -- >>> Larry Gritz >>> [email protected] >>> >>> >>> >>> _______________________________________________ >>> Oiio-dev mailing list >>> [email protected] >>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >> >> _______________________________________________ >> Oiio-dev mailing list >> [email protected] >> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org > > -- > Larry Gritz > [email protected] > > > > _______________________________________________ > Oiio-dev mailing list > [email protected] > http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org -- Larry Gritz [email protected] _______________________________________________ Oiio-dev mailing list [email protected] http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
