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