| Thread overview | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 31, 2005 string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
I was looking at string_view to figure out how to implement BASIC-style left$, right$ and mid$ functions here's a few comments after looking at the source...
1) I think the (rhs, pos, cch) constructor, is missing an assert for (pos +
cch < rhs.length), pos is being checked but cch is taken literally with no
checks
2) The (char const* s, cch) constructor is missing the check for cch's
validity also
3) Doesn't m_base have to be pointed to m_cstr if m_cstr is allocated (when
using c_str()) ?
On "standard" issues (and please correct me since I'm likely be outdated on
this):
a) Can you can construct using the (char const* s[,cch]) versions from
pointers returned by c_str()? Aren't these pointers NOT guaranteed to be
valid after the function call?
b) How would you construct a string_view from an std::string if:
- iterators aren't necessarily pointers (so it can't be done through
begin(), end())
- string memory isn't guaranteed to be contiguous (as it was pointed out
some time ago, but I can't find the post) ? (so it can't be done either with
&str[pos], &str[pos + cch])
I assume it was considered storing a pair of iterators rather than a base and length as a possibility, what were the cons for that approach?
BTW, saw myself in string_view's header, thanks!
Pablo
| ||||
March 31, 2005 Re: string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Pablo Aguilar | "Pablo Aguilar" <paguilarg@hotmail.com> wrote in message news:d2flvs$2jic$1@digitaldaemon.com... >I was looking at string_view to figure out how to implement BASIC-style left$, right$ and mid$ functions here's a few comments after looking at the source... Cool. Did you figure it out? It might be a nice addition ... > 1) I think the (rhs, pos, cch) constructor, is missing an assert for (pos + cch < rhs.length), pos is being checked but cch is taken literally with no checks I think I thought about this, and considered that the user might expect to be able to 'know' more about the real extent of available string than the rhs string_view instance. I'm still not 100% about it, so I'd be interested in hearing opinions on this from others. > 2) The (char const* s, cch) constructor is missing the check for cch's validity also Definitely not in this case. <g> One important point of string_view is that it can be applied to any sequence of bytes, whether or not they're null-terminated. Also, string_view, in common with std::basic_string (and BSTR, and many other string types) may contain embedded NUL characters. Given that, how would we 'check' cch? :-) > 3) Doesn't m_base have to be pointed to m_cstr if m_cstr is allocated (when using c_str()) ? I thought it did. :$ Let me check ... ... ah, now I remember: I reasoned that users would want to be able to depend on data() and the iterators pointing into the original memory. Now that I'm reminded of that, I think it's definitely a powerful argument. > On "standard" issues (and please correct me since I'm likely be outdated on this): > a) Can you can construct using the (char const* s[,cch]) versions from pointers returned by c_str()? Aren't these > pointers NOT guaranteed to be valid after the function call? I don't follow. Can you rephrase? (and please stipulate explicitly which class you're meaning on both lhs and rhs of such interactions.) > b) How would you construct a string_view from an std::string if: > - iterators aren't necessarily pointers (so it can't be done through begin(), end()) > - string memory isn't guaranteed to be contiguous (as it was pointed out some time ago, but I can't find the post) > ? (so it can't be done either with &str[pos], &str[pos + cch]) Doing it is simple: std::basic_string<char> ss("Pablo's help is highly prized"); string_view<char> sv(ss.data(), ss.length()); But you're correct in suggesting that it's not theoretically valid to do so. But (I think) you're missing a more fundamental point. data() is guaranteed to return a contiguous array of characters whose first size() elements are identical to those in the actual storage (if different). The returned pointer is invalidated by a host of different operations on std::basic_string - including c_str()! - which would invalidate the pointer that the string_view instance is holding onto. But, and this is where this bad news is actually not that bad, the exact same could be said if a string-view class held onto iterators. Anything that invalidates iterators will invalidate the pointer returned by data(), after all. <g> So, bizarrely as it seems, the issue is moot. :-) (BTW: This is all good stuff for doing in the documentation. If only someone was motivated to help me out on the docs .... <G>) > I assume it was considered storing a pair of iterators rather than a base and length as a possibility, what were the cons for that approach? Theoretically, string_view is _only_ for use with *arrays of characters*. The fact that a standards compliant string class (or indeed any other string class) may store non-continguously, means that iterators may not be used. Practically speaking, I've found that it's more convenient and more efficient to represent strings as len+ptr rather than two bounding ptrs. (And this will be reflected in the forthcoming rewrite of recls: recls2) > BTW, saw myself in string_view's header, thanks! You're entirely welcome. :-) I'm a strong believer in people's help being recognised and valued. Cheers Matthew | |||
March 31, 2005 Re: string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Matthew Attachments: | "Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:d2gc12$bv9$1@digitaldaemon.com... > > "Pablo Aguilar" <paguilarg@hotmail.com> wrote in message news:d2flvs$2jic$1@digitaldaemon.com... >>I was looking at string_view to figure out how to implement BASIC-style >>left$, right$ and mid$ functions here's a few >>comments after looking at the source... > > Cool. Did you figure it out? It might be a nice addition ... I'll reply to the whole message in a while... for now, would you mind looking at the following, it compiles fine under VC71, but either complains about "typename" being used outsie a template or ICEs on me with VC6.5 <code> template<typename string_type> stlsoft_ns_qual(basic_string_view)<typename string_type::value_type> right_view( string_type const& str , typename string_type::size_type cch ) { typedef stlsoft_ns_qual(basic_string_view)<typename string_type::value_type> string_view; // <<< complains/crashes here // This assumes that string types below have contiguous memory storage typename string_type::size_type size = str.size(); // We know we're not modifying the string // so the const_cast is ok, we need it to // get the reference version of operator[] // otherwise we get an rvalue return type string_type& ncstr = *const_cast<string_type*>(&str); return (size <= cch) ? string_view(&ncstr[0], size) : string_view(&ncstr[size - cch], cch) ; } template<typename char_type> stlsoft_ns_qual(basic_string_view)<char_type> right_view( char_type const* str , size_t cch ) { typedef stlsoft_ns_qual(basic_string_view)<char_type> string_view; size_t size = c_str_len(str); return (size <= cch) ? string_view(str, cch) : string_view(str + (size - cch), cch) ; } </code> Once this works, left_view and mid_view should be trivial to implement... Maybe taking the address of characters in certain positions should be replaced by using a string traits class. Attached is the test program I'm using... Thanks for your help... Pablo | |||
March 31, 2005 Re: string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Pablo Aguilar | I need softsteel/string_algo.hpp Can you post / email it to me? "Pablo Aguilar" <paguilarg@hotmail.com> wrote in message news:d2hslp$21mv$1@digitaldaemon.com... > > "Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:d2gc12$bv9$1@digitaldaemon.com... >> >> "Pablo Aguilar" <paguilarg@hotmail.com> wrote in message news:d2flvs$2jic$1@digitaldaemon.com... >>>I was looking at string_view to figure out how to implement BASIC-style left$, right$ and mid$ functions here's a few comments after looking at the source... >> >> Cool. Did you figure it out? It might be a nice addition ... > > I'll reply to the whole message in a while... for now, would you mind looking at the following, it compiles fine under VC71, but either complains about "typename" being used outsie a template or ICEs on me with VC6.5 > > <code> > template<typename string_type> > stlsoft_ns_qual(basic_string_view)<typename string_type::value_type> > right_view( > string_type const& str > , typename string_type::size_type cch > ) > { > typedef stlsoft_ns_qual(basic_string_view)<typename string_type::value_type> string_view; // <<< complains/crashes > here > // This assumes that string types below have contiguous memory storage > typename string_type::size_type size = str.size(); > > // We know we're not modifying the string > // so the const_cast is ok, we need it to > // get the reference version of operator[] > // otherwise we get an rvalue return type > string_type& ncstr = *const_cast<string_type*>(&str); > return (size <= cch) > ? string_view(&ncstr[0], size) > : string_view(&ncstr[size - cch], cch) > ; > } > > template<typename char_type> > stlsoft_ns_qual(basic_string_view)<char_type> > right_view( > char_type const* str > , size_t cch > ) > { > typedef stlsoft_ns_qual(basic_string_view)<char_type> string_view; > size_t size = c_str_len(str); > return (size <= cch) > ? string_view(str, cch) > : string_view(str + (size - cch), cch) > ; > } > </code> > > Once this works, left_view and mid_view should be trivial to implement... > Maybe taking the address of characters in certain positions should be replaced by using a string traits class. > Attached is the test program I'm using... > > Thanks for your help... > > Pablo > > > | |||
March 31, 2005 Re: string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Matthew | Doh! Belay that order. :$ "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d2ht4g$226m$1@digitaldaemon.com... >I need softsteel/string_algo.hpp > > Can you post / email it to me? > > "Pablo Aguilar" <paguilarg@hotmail.com> wrote in message news:d2hslp$21mv$1@digitaldaemon.com... >> >> "Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:d2gc12$bv9$1@digitaldaemon.com... >>> >>> "Pablo Aguilar" <paguilarg@hotmail.com> wrote in message news:d2flvs$2jic$1@digitaldaemon.com... >>>>I was looking at string_view to figure out how to implement BASIC-style left$, right$ and mid$ functions here's a >>>>few >>>>comments after looking at the source... >>> >>> Cool. Did you figure it out? It might be a nice addition ... >> >> I'll reply to the whole message in a while... for now, would you mind looking at the following, it compiles fine under VC71, but either complains about "typename" being used outsie a template or ICEs on me with VC6.5 >> >> <code> >> template<typename string_type> >> stlsoft_ns_qual(basic_string_view)<typename string_type::value_type> >> right_view( >> string_type const& str >> , typename string_type::size_type cch >> ) >> { >> typedef stlsoft_ns_qual(basic_string_view)<typename string_type::value_type> string_view; // <<< complains/crashes >> here >> // This assumes that string types below have contiguous memory storage >> typename string_type::size_type size = str.size(); >> >> // We know we're not modifying the string >> // so the const_cast is ok, we need it to >> // get the reference version of operator[] >> // otherwise we get an rvalue return type >> string_type& ncstr = *const_cast<string_type*>(&str); >> return (size <= cch) >> ? string_view(&ncstr[0], size) >> : string_view(&ncstr[size - cch], cch) >> ; >> } >> >> template<typename char_type> >> stlsoft_ns_qual(basic_string_view)<char_type> >> right_view( >> char_type const* str >> , size_t cch >> ) >> { >> typedef stlsoft_ns_qual(basic_string_view)<char_type> string_view; >> size_t size = c_str_len(str); >> return (size <= cch) >> ? string_view(str, cch) >> : string_view(str + (size - cch), cch) >> ; >> } >> </code> >> >> Once this works, left_view and mid_view should be trivial to implement... >> Maybe taking the address of characters in certain positions should be replaced by using a string traits class. >> Attached is the test program I'm using... >> >> Thanks for your help... >> >> Pablo >> >> >> > > | |||
March 31, 2005 Re: string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Pablo Aguilar | Here's the Arturius output. Very encouraging so far:
arcc.debug -c --exception-handling=on --announce-tools --compilers=bcc/5.6,cw/8,dm/beta-stlport,gcc/3.2,gcc/3.4,icl/7,icl/8,vc/6,vc/7,vc/7.1,v
c/8 -I.. -IH:\STLSoft\Identities\STLSoft\stlsoft -IH:\STLSoft\Identities\STLSoft\stlsoft\inprogress -IH:\STLSoft\Identities\STLSoft\stlsoft\re
search --output-path=.\string_algo_test.obj ..\string_algo_test.cpp
Tool: bcc/5.6
Tool: cw/8
Tool: dm/beta-stlport
Tool: gcc/3.2
Tool: gcc/3.4
Tool: icl/7
Tool: icl/8
Tool: vc/6
..\string_algo_test.cpp(21): error C2899: typename cannot be used outside a template declaration
..\string_algo_test.cpp(21): error C2899: typename cannot be used outside a template declaration
..\string_algo_test.cpp(21): error C2899: typename cannot be used outside a template declaration
..\string_algo_test.cpp(21): error C2899: typename cannot be used outside a template declaration
Tool: vc/7
..\string_algo_test.cpp(15): fatal error C1507: previous user errors and subsequent error recovery halt further
compilation
Tool: vc/7.1
Tool: vc/8
"Pablo Aguilar" <paguilarg@hotmail.com> wrote in message news:d2flvs$2jic$1@digitaldaemon.com...
>I was looking at string_view to figure out how to implement BASIC-style left$, right$ and mid$ functions here's a few comments after looking at the source...
>
> 1) I think the (rhs, pos, cch) constructor, is missing an assert for (pos + cch < rhs.length), pos is being checked
> but cch is taken literally with no checks
> 2) The (char const* s, cch) constructor is missing the check for cch's validity also
> 3) Doesn't m_base have to be pointed to m_cstr if m_cstr is allocated (when using c_str()) ?
>
> On "standard" issues (and please correct me since I'm likely be outdated on this):
> a) Can you can construct using the (char const* s[,cch]) versions from pointers returned by c_str()? Aren't these
> pointers NOT guaranteed to be valid after the function call?
> b) How would you construct a string_view from an std::string if:
> - iterators aren't necessarily pointers (so it can't be done through begin(), end())
> - string memory isn't guaranteed to be contiguous (as it was pointed out some time ago, but I can't find the post)
> ? (so it can't be done either with &str[pos], &str[pos + cch])
>
> I assume it was considered storing a pair of iterators rather than a base and length as a possibility, what were the cons for that approach?
>
> BTW, saw myself in string_view's header, thanks!
>
>
> Pablo
>
| |||
March 31, 2005 Re: string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Matthew | Getting rid of the compile error is easy: just take out the typename
typedef stlsoft_ns_qual(basic_string_view)</* typename */ STRING_TYPE::value_type> string_view; // <<<
complains/crashes here
However, then VC 6 has an internal compiler error. That's bound up with the c-string form of right_view.
If that's not used in the client code, then all is well. If it's in: ICE.
If we comment out the other right_view, then the c-string form works fine.
If we have the c-string form and the following stub version, it all works fine
template<ss_typename_param_k C>
const ::stlsoft::basic_string_view<C> right_view(long, long, long n, C const *s)
{
typedef ::stlsoft::basic_string_view<C> string_view_t;
return string_view_t(s, n);
}
c-string + following compilers fine
template<ss_typename_param_k S>
const ::stlsoft::basic_string_view<typename S::value_type> right_view(S const &s, long, long n)
{
typedef ::stlsoft::basic_string_view<C> string_view_t;
return string_view_t(s.data(), n);
}
c-string + following compiles fine:
template<ss_typename_param_k S>
const ::stlsoft::basic_string_view<typename S::value_type> right_view(S const &s, size_t n, long l)
{
typedef ::stlsoft::basic_string_view<C> string_view_t;
return string_view_t(s.data(), n);
}
c-string + following ICEs:
template<ss_typename_param_k S>
const ::stlsoft::basic_string_view<typename S::value_type> right_view(S const &s, size_t n, long l = 1)
{
typedef ::stlsoft::basic_string_view<C> string_view_t;
return string_view_t(s.data(), n);
}
It seems, then, that the ICE comes from having two forms of right_view with one template-type param and one (unsigned) integral param.
More digging required ....
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d2huui$23m1$1@digitaldaemon.com...
> Here's the Arturius output. Very encouraging so far:
>
> arcc.debug -c --exception-handling=on --announce-tools --compilers=bcc/5.6,cw/8,dm/beta-stlport,gcc/3.2,gcc/3.4,icl/7,icl/8,vc/6,vc/7,vc/7.1,v
>
> 8 -I.. -IH:\STLSoft\Identities\STLSoft\stlsoft -IH:\STLSoft\Identities\STLSoft\stlsoft\inprogress -IH:\STLSoft\Identities\STLSoft\stlsoft\re
> search --output-path=.\string_algo_test.obj ..\string_algo_test.cpp
> Tool: bcc/5.6
> Tool: cw/8
> Tool: dm/beta-stlport
> Tool: gcc/3.2
> Tool: gcc/3.4
> Tool: icl/7
> Tool: icl/8
> Tool: vc/6
> ..\string_algo_test.cpp(21): error C2899: typename cannot be used outside a template declaration
> ..\string_algo_test.cpp(21): error C2899: typename cannot be used outside a template declaration
> ..\string_algo_test.cpp(21): error C2899: typename cannot be used outside a template declaration
> ..\string_algo_test.cpp(21): error C2899: typename cannot be used outside a template declaration
> Tool: vc/7
> ..\string_algo_test.cpp(15): fatal error C1507: previous user errors and subsequent error recovery halt further
> compilation
> Tool: vc/7.1
> Tool: vc/8
>
>
>
> "Pablo Aguilar" <paguilarg@hotmail.com> wrote in message news:d2flvs$2jic$1@digitaldaemon.com...
>>I was looking at string_view to figure out how to implement BASIC-style left$, right$ and mid$ functions here's a few comments after looking at the source...
>>
>> 1) I think the (rhs, pos, cch) constructor, is missing an assert for (pos + cch < rhs.length), pos is being checked
>> but cch is taken literally with no checks
>> 2) The (char const* s, cch) constructor is missing the check for cch's validity also
>> 3) Doesn't m_base have to be pointed to m_cstr if m_cstr is allocated (when using c_str()) ?
>>
>> On "standard" issues (and please correct me since I'm likely be outdated on this):
>> a) Can you can construct using the (char const* s[,cch]) versions from pointers returned by c_str()? Aren't these
>> pointers NOT guaranteed to be valid after the function call?
>> b) How would you construct a string_view from an std::string if:
>> - iterators aren't necessarily pointers (so it can't be done through begin(), end())
>> - string memory isn't guaranteed to be contiguous (as it was pointed out some time ago, but I can't find the post)
>> ? (so it can't be done either with &str[pos], &str[pos + cch])
>>
>> I assume it was considered storing a pair of iterators rather than a base and length as a possibility, what were the cons for that approach?
>>
>> BTW, saw myself in string_view's header, thanks!
>>
>>
>> Pablo
>>
>
>
| |||
March 31, 2005 Re: string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Matthew | Great! You tweaked first it right? I very much doubt it would've compiled that cleanly on all compilers! Handy tool Arturius, BTW... "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d2huui$23m1$1@digitaldaemon.com... > Here's the Arturius output. Very encouraging so far: > > arcc.debug -c --exception-handling=on --announce-tools --compilers=bcc/5.6,cw/8,dm/beta-stlport,gcc/3.2,gcc/3.4,icl/7,icl/8,vc/6,vc/7,vc/7.1,v > > 8 -I.. -IH:\STLSoft\Identities\STLSoft\stlsoft -IH:\STLSoft\Identities\STLSoft\stlsoft\inprogress > -IH:\STLSoft\Identities\STLSoft\stlsoft\re > search --output-path=.\string_algo_test.obj ..\string_algo_test.cpp > Tool: bcc/5.6 > Tool: cw/8 > Tool: dm/beta-stlport > Tool: gcc/3.2 > Tool: gcc/3.4 > Tool: icl/7 > Tool: icl/8 > Tool: vc/6 > ..\string_algo_test.cpp(21): error C2899: typename cannot be used outside > a template declaration > ..\string_algo_test.cpp(21): error C2899: typename cannot be used outside > a template declaration > ..\string_algo_test.cpp(21): error C2899: typename cannot be used outside > a template declaration > ..\string_algo_test.cpp(21): error C2899: typename cannot be used outside > a template declaration > Tool: vc/7 > ..\string_algo_test.cpp(15): fatal error C1507: previous user errors and > subsequent error recovery halt further compilation > Tool: vc/7.1 > Tool: vc/8 | |||
March 31, 2005 Re: string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Pablo Aguilar | "Pablo Aguilar" <paguilarg@hotmail.com> wrote in message news:d2hvii$248v$1@digitaldaemon.com... > Great! > > You tweaked first it right? I very much doubt it would've compiled that cleanly on all compilers! Barely > Handy tool Arturius, BTW... Yes. I *really* need to get it out to the world. ;$ | |||
March 31, 2005 Re: string_view in 1.8.3b4 | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Matthew | I've rewritten to try and get around VC6. But the following still ICEs
template<ss_typename_param_k T>
struct string_traits_
{
typedef typename T::value_type char_type;
typedef typename T::size_type size_type;
static char_type const *get_data(T const &s)
{
return s.data();
}
static size_type get_length(T const &s)
{
return s.size();
}
};
template<>
struct string_traits_<char const*>
{
typedef char char_type;
typedef size_t size_type;
static char_type const *get_data(char_type const *s)
{
return s;
}
static size_type get_length(char_type const *s)
{
return strlen(s);
}
};
template<>
struct string_traits_<wchar_t const*>
{
typedef wchar_t char_type;
typedef size_t size_type;
static char_type const *get_data(char_type const *s)
{
return s;
}
static size_type get_length(char_type const *s)
{
return wcslen(s);
}
};
template<ss_typename_param_k S>
const ::stlsoft::basic_string_view<ss_typename_type_k string_traits_<S>::char_type> right_view(S const &s,
ss_typename_type_k string_traits_<S>::size_type n)
{
typedef string_traits_<S> traits_t;
typedef traits_t::char_type char_t;
typedef traits_t::size_type size_t;
typedef ::stlsoft::basic_string_view<char_t> string_view_t;
char_t const *data = traits_t::get_data(s);
const size_t len = c_str_len(s);///* traits_t::get_length(s) */0;
if(n > len)
{
n = len;
}
return string_view_t(data + (len - n), n);
}
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply