Boost logo

Boost :

Subject: Re: [boost] [string_ref] Feature requests
From: Marshall Clow (mclow.lists_at_[hidden])
Date: 2012-12-29 11:56:25


On Dec 29, 2012, at 6:33 AM, Daniel James <dnljms_at_[hidden]> wrote:

> Hi,
>
> I've been trying to convert quickbook to use boost::string_ref,

Great!

> 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))

but how would a string_ref constructor know that?

        
> 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 tried:
        template<typename Allocator>
        std::basic_string<charT, traits, Allocator> to_string () const
                { return std::basic_string<charT, traits, Allocator> ( ptr_, len_ ); }

and that works, but the user has to write:
        str2 = sr1.to_string<std::allocator<char> > ();

and that's just _ugly_

I could just leave the allocator parameter out altogether:

        std::basic_string<charT, traits> to_string () const
                { return std::basic_string<charT, traits> ( ptr_, len_ ); }
        
And that works, but you lose the ability to specify an allocator.

Another option is to just define a "convert" function:

        template <typename Result>
        Result convert () const { return Result ( ptr_, len ); }

and people could write:
        str2 = sr1.convert<std::string> ();

which is ugly too - but very clear.

> 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.

What happens if the basic_string has a different type_traits class than the string_ref?
How do they compare then? [ Of course, that could happen with two different instantiations
of std::basic_string today, so that's probably a solved problem. ]

> I didn't need it, but could probably also could do with a 'hash_value'
> function for boost::hash support. Is potentially error prone if the
> original string is modified or destroy, but there are some valid use
> cases.

Yeah, hashing support and conversion to numbers is in the header file, but commented out for now.

-- 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