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;
};
]]]

Reply via email to