On Thu, Oct 14, 2010 at 5:22 AM, Branko Čibej <br...@xbc.nu> wrote: > On 13.10.2010 16:10, Hyrum K. Wright wrote: >> On Tue, Oct 12, 2010 at 5:06 PM, Branko Čibej <br...@xbc.nu> wrote: >>> On 12.10.2010 22:30, Hyrum K. Wright wrote: >>>> On Tue, Oct 12, 2010 at 2:40 PM, Branko Čibej <br...@xbc.nu> wrote: >>>>> On 12.10.2010 20:35, Hyrum K. Wright wrote: >>>>>> 1) Return everything by value >>>>>> Pros: simpler memory management, less overhead (?) >>>>>> Cons: doesn't allow the return of NULL values, need to establish >>>>>> conventions to represent NULL objects (an isNull() method?) >>>>> Meh. >>>>> >>>>> inline operator bool() const { return (this->c_struct_pointer != 0); } >>>> That works great for our own types, but what about stuff like std::string? >>>> >>>> inline std::string getAuthor() const { return std::string(ptr->author); } >>>> >>>> doesn't go over so well when ptr->author is NULL. If returning by >>>> value, we *have* to return a string, but there just isn't any way to >>>> indicate the null string. >>> Good point ... that's a mess. But returning a pointer to an std::string >>> is a bigger one ... eep. >> Another option is a custom SVN::String type which looks / smells / >> acts like a string, but also allows wrapping the NULL value, in a >> manner you suggest above. >> >>> So typically you'd add a hasAuthor function and throw an exception from >>> getAuthor if there is no author info for a revision. However, in this >>> particular case, returning an empty string is just as good, unless you >>> want to make the fine distinction between a svn:author property with an >>> empty value (is that even allowed?) and no svn:author property on the >>> revision. This is no different than if you had a getProperty(name) and >>> did a lookup in a private map of property name/value pairs. >> I just used getAuthor() as an example, and while I'm not certain as to >> the specifics in that particular case (ed: I see Mike has answered >> this elsethread), I know there are other places where the >> present-but-empty vs. not-present distinction is an important and >> valid one. > > All right. Then derive svn::string from std::string, and add a .null() > method. You get to use all the standard string alogorithm > specializations, plus you get what you want. > > You can even add a factory class method that is the only way you can > construct an svn::string object for which .null() returns true, so for > any normal use, svn::string and std:: string behave in exactly the same way. > > Of course, deriving that template is tricky, given that std::string is > already a template specialization, but since this is a library, it's > worth the trouble of doing it right.
The following is a somewhat naïve implementation, but does it jive with your suggestion? -Hyrum [[[ /* This class is similar to std::string, with the benefit that it allows non-existent strings, similar to a NULL char * value. When the possibility exists that the string is NULL, callers should check the value (using the "if(str)" idiom) before doing any other operation. Most operations on NULL mystring's are undefined. */ class mystring : public std::string { public: inline mystring() : isNull(false), std::string() { } inline mystring(const char *s) : isNull(s == NULL) { if (s) assign(s); } inline operator bool() const { return !isNull; } inline const char *c_str() const { if (isNull) return NULL; else return std::string::c_str(); } private: bool isNull; }; ]]]