Boost logo

Boost :

Subject: Re: [boost] [string_ref] Feature requests
From: Marshall Clow (mclow.lists_at_[hidden])
Date: 2012-12-29 13:37:00


On Dec 29, 2012, at 9:33 AM, Daniel James <dnljms_at_[hidden]> wrote:
> On 29 December 2012 16:56, Marshall Clow <mclow.lists_at_[hidden]> wrote:
>> On Dec 29, 2012, at 6:33 AM, Daniel James <dnljms_at_[hidden]> wrote:
>>
>>> and there are a few missing features that might be useful:
>>>
>>> Construction from a pair of iterators, either
>>> std::basic_string::const_iterator, or
>>> boost::basic_string_ref::const_iterator. Which of course can be the
>>> same type, which is annoying but not too hard to work around.
>>
>> Hrm.
>> Given a pair of iterators (first, last),
>> how do you ensure that the range [first, last) is contiguous in memory?
>>
>> If you (the caller) know that, then you can construct thus:
>> string_ref (&*first, std::distance(first, last))
>
> This is technically more dangerous, as it will work for
> std::list<char>. There's also the risk of using different variables
> for 'first' (and yes, I did exactly that).
>
> If I wasn't clear enough, I'm not suggesting supporting arbitrary
> iterators. Just std::basic_string::const_iterator and
> boost::basic_string_ref::const_iterator. I suppose I should have
> included raw char pointers as well.
>
>> but how would a string_ref constructor know that?
>
> How does your existing constructor know that the length doesn't overflow?

I think we're talking about different things here.
I'm talking about how a string_ref constructor would know that the range defined by two iterators is contiguous.

>>> Easy conversion to std::basic_string. There's a C++11 explicit string
>>> operator, but that isn't much good for portable code. Something like a
>>> 'string' or 'to_string' member would do the trick.
>>
>> Makes all kinds of sense.
>> However, this is problematic in C++03.
>>
>> I tried:
>> template<typename Allocator = std::allocator <charT> >
>> std::basic_string<charT, traits, Allocator> to_string () const
>> { return std::basic_string<charT, traits, Allocator> ( ptr_, len_ ); }
>>
>> But that doesn't work, because you can't have default template arguments in functions.
>
> I wouldn't expect support for arbitrary allocators. Olaf pointed out
> std::to_string which doesn't seem to support such things.

I think that std::to_string is just dumb.
Not the idea (which I like) but the limited implementation.
The fact that std::to_wstring exists (for example) seems just wrong to me.

> But if you must have support, how about returning a type which is implicitly
> convertible to std::basic_string?

Hrm. (Not saying no, just thinking)

>>> Support for comparisons with std::basic_string. The comparison
>>> operators are templates so they aren't called with an implicit
>>> conversion. Could use a template parameter for the type so that it
>>> picks up anything which is (implicitly?) convertible to
>>> boost::basic_string_ref, maybe using SFINAE.
>>
>> I like this idea. I'll have to think about the best way to do it.

On the other hand, you can write:
        string_ref sr1;
        string str1;

        if ( sr1 == string_ref (str1))

today - for any of the relational operators.

How important is the notational convenience of being able to write:

        if ( sr1 == str1 )
and
        if ( str1 == sr1 )

Just wondering.

-- Marshall

Marshall Clow Idio Software <mailto:mclow.lists_at_[hidden]>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait).
        -- Yu Suzuki


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk