ISO/CEI JTC1 SC22 WG21 N3921
Data:
Jeffrey Yaskin<jyasskin@google.com>
ignore index
overview
String references are very common in C++ programs, but often the receiver doesn't care about the exact type of object that contains the data. In this case, 3 things usually happen:
- The call is made
Default constant::string&
and insists that callers copy the data if it originally belonged to a different type. - The receiver receives two parameters - one
Characters*
and a length (or justCharacters*
and assumes termination 0), reduces readability and call security, and loses all helper functions of the type originally shipped. - The receiver is rewritten as a template and its implementation is moved to a header file. This can increase flexibility if the author is slow to code a weaker iterator concept, but it can also increase compile time, code size, and even introduce bugs if the author loses the assumption that the argument's content is contiguous.
Google, LLVM, and Bloomberg independently implemented a String reference type to encapsulate this type of argument.view stringis implicitly constructible fromconstant character*
miPattern::Chain
. proportional toConstantly
member operationPattern::Chain
to make the transition easier. This document followsChrommiBloombergthe extentview string
forbasic_string_view<diagram>
, and extends it with aCharacteristics
Adjust parametersbasic_string
. We provide typedefs for Parallel 4basic_string
type definitions
Google and LLVMview string
Types (but not Bloomberg) extend the interface ofPattern::Chain
to provide some useful useful features:
- begins with
- ends with
- delete_prefix
- delete_suffix
- Split
- you accept
- consuma_prefix
- say
versions ofPattern::Chain
perform operationsview string
Instead, also provide the standard with a way to provide direct operations on non-null-terminated byte/strings:
- hashish, as requested by c++std-lib-31935
- In a future addition, numeric conversions
inventions in this article
google malSeilstück
offerslike rope
miSeries
methods to convertPattern::Chain
. LLVMstring reference
offers both aChain()
explicit and implicit conversionStandardoperator::string()
. Since this article is based on C++11, we provide aexplicit conversion constructoras well as a less detailed oneto_string Function.
None of the existing classes hasconstexpr
methods.
bike garage!
we find roughconsensus on the name change of this classview string
. Other options include:
- basic_string_range (i.e. a modeled iterator range)
- canvas
- const_string_facade
- cadena_ext
- outer_string
- str_ref
- string_cref (y string_ref for no constant)
- rope_piece
- string range
- cadena_ref
- view string
- sub_string
Modifications to std::string
an interface ofview string
is similar but not exactly the same as the interface ofPattern::Chain
. In general, we want to minimize the differences betweenPattern::Chain
miview string
So users can often switch back and forth between the two. This section explains the differences that we believe are useful beyond this general rule.
additive
remove_prefix()
miremove_suffix()
Make it easier to parse strings withview string
. Both can be implemented as non-member functions (e.g.str.remove_prefix(n)
), but it seems sensible to provide the simpler modifiers as member functions. Note that other traversal primitives must be non-members to be extensible, which might make a case for removing them as well.=== str = str.substr(n)
Why not change <my-pet-feature>?
I did not accept all the proposed amendmentsview string
. This section explains why.
Remove find*() methods
A lot of people have asked why we don't remove them allmeet*
Methods as they are widely regarded as a wartPattern::Chain
. First, we want to make converting code for use as easy as possible.view string
, so it makes sense to keep the UI as similar as possiblePattern::Chain
. Second, replacing these methods with uses of the standard algorithm library requires changing the indices in iterators, writing some complicated conversion code, and/or passing custom lambdas tomeet
. Let's look at the replacement code for each of the remaining methods:
haystack.find (Nadel)
- Replaced by:
auto iter = std::search(haystack.begin(), pajar.end(), aguja.begin(), aguja.end());return iter == pajar.end() ? std::string::npos : iter - haystack.begin();
Haystack.rfind(Needle)
- Replaced by:
Automatische Iteration = std::find_end(haystack.begin(), haystack.end(), needle.begin(), needle.end());return iter == haystack.end() ? std::string::npos : iter - haystack.begin();
pajar.find_first_of(agujas)
- Replaced by:
auto iter = std::find_first_of(palheiro.begin(), palheiro.end(), agulhas.begin(), agulhas.end());return iter == palheiro.end() ? std::string::npos : iter - haystack.begin();
haystack.find_last_of(Nadeln)
- Replaced by:
auto iter = std::find_first_of(haystack.Rbegin(), haystack.REnd(), Needles.Start(), Needles.End()); return iter == haystack.Rfim() ? std::string::npos: iterieren.base() - 1- pajar. begin();
palheiro.find_first_not_of(palha)
- Replaced by:
auto iter = std::find_if(pajar.begin(), pajar.end(), [&](char c) { return std::find(paja.comienzo(), paja.fin(), c) == palha.end();});return iter == palheiro.end() ? std::string::npos : iter - haystack.begin();
palheiro.find_last_not_of(palha)
- Replaced by:
Automatic iteration = std::find_if(haystack.Rbegin(), haystack.Rend(), [&](char c) { return std::find(paja.begin(), pajilla.end(), c) == pajilla.end();});return iter == pajar.Rfim() ? std::string::npos: iterieren.base() - 1- pajar. begin();
meet
,meet
, mifind_first_of
They're straightforward, although turning indexes into iterators prevents many users from switching to them in the first place.find_last_of
,find_first_not_of
, mifind_last_not_of
They're becoming increasingly unmanageable, even in an iterator-based function.
That was the result of the discussion in Bristolview string
must contain all constant signatures ofRope
.
SF | WF | Norte | Washington | one |
5 | 4 | 1 | 2 | 0 |
SF | WF | Norte | Washington | one |
4 | 2 | 2 | 3 | 2 |
Againbasic_string_view<character>
muddy
...and I usebasic_string_view<constant character>
for the constant case. The constant case is much more common than the changing case and should be the default. Making case-sensitive by default avoids passing string literals toview string
Parameters that would thwart a meaningful use case forview string
. In a somewhat analogous situation, LLVM has defined aArrayRef
classroomin February 2011 and found no need for correspondenceMutableArrayRef
until January 2012. You have not yet required a modifiable version ofstring reference
. A possible reason for this is that most applications that need to change a string also need to be able to change its length, and this is impossible even for a mutable version ofview string
.
UsI couldusetypedef basic_string_view<const char> string_view
to make the immutable case the default while still supporting the mutable case with the same model. I didn't do this because it would complicate model definition without significantly helping users.
add abool explicit operator
This would be an abbreviation for!file()
, usable for initialization incon
Testify.N3509He came to SG9 in Bristol and was not accepted.
SF | WF | Washington | one |
0 | 1 | 3 | 5 |
Avoidstrlen("literally de cadena")
With a form builder:
template<size_t N>basic_string_view(const charT (&str)[N]);
we could avoid onestrlen()
call if abasic_string_view
is constructed from a string literal. Unfortunately, this constructor does something completely wrong when called like this:
char space[PATH_MAX];snprintf(space, sizeof(space), "some string");string_view str(space);
It would be possible to avoid this problem by defining abasic_string_view(char* str)
what do you usestrlen()
again, but this adds complexity. Some people suggested astring_view::from_literal
method, but it seems to me to be too verbose.
Even the original concern is obsolete due to modern optimizers: both gcc and clang Optimizestrlen("literal")
to a constant, making the simple and safe code as efficient as the model. Other implementations should provide the same optimization as a QoI problem.
Turn on comparisonbegin
/Film
instead of elements
operations onview string
They apply to the characters in the string, not the pointers that point to the characters. This leads to the possibility that the underlying characters will change while aview string
The reference to them is in an associative container, which would break the container, but we think it's worth the risk as it aligns with existing practice and user intentions most of the time.
Waiting forcontiguous_range<charT>
contiguous_range<T>
together with ais_contiguous<IteratorOrRange>
Function would be useful for many purposes. However, a string-specific reference class offers some additional advantages:
view string
can have an implicit conversion fromconstant character*
, although providing this is a surprising special casecontiguous_range<const char*>
.- We can provide a subset of these
basic_string
to facilitate transitions to and from the property, while such methods would be very impracticalcontiguous_range
. basic_string_view
take onecharacteristic_signs
-argument that allows you to customize the comparison.contiguous_range
probably not.- We compare and mix
view string
s Using the items they refer to. There is a stronger argument for comparing acontiguous_range
with the pointers in it, that is, twocontiguous_range<characters>
s of the same character can be compared unequally. - The notion of a "string" is different from the notion of a set of characters, which is one of the reasons for this
Pattern::Chain
in addition tostd::vector<character>
. Users benefit from saying what they want to say in interfaces.
Againview string
finished zero
Doing this naively doesSubstr
cannot be implemented without a copy. We can imagine inventing a more complex interface that logs whether the input string is null-terminated and allows the user to use that string when trying to pass aview string
to a legacy or C function that expects null terminationconstant character*
. This proposal does not include such an interface as it wouldview string
larger or more expensive and because there is no exercise that will lead us to the right interface.
Another option would be to set aview_zstring
Class to represent null-terminated strings and to which it can decayview string
if needed. This is plausible but not part of this proposal.
s/remove_prefix/pop_front/ usw.
emes 2012, one suggestedrest<>
class withpop_front
, etc. Members who have adjusted the area boundaries. The discussion there showed that committee members were uncomfortable using the same names for short-range operations as for container operations. Existing practice does not agree on a name for this process, so I've kept the name Google uses.Seilstück
.
Allow implicit conversion of other types.
suggested Beman Dawesdefinestd::string_view_{comienzo, fin}
and allow users to add overloadsStandard
. Using ADL is a minor variation. We can also allow conversions of any kind.Data()
mi.Size()
Members that return the correct types.
Finally, I think we want to allow this conversion based on contiguous region detection. Any builder we add to prevent this from happening will look like a wart in a few years. I think it will be better for users to convert explicitly if they can't add a proper conversion operator, and then we can add the optimal constructor when the contiguous iterators come into the library.
SF | WF | Norte | Washington | one |
0 | 0 | 1 | 5 | 6 |
Plans for future changes
- There are many functions outside of the String chapter that you should include
view string
. I will propose these changes in a later article based on thatPart of N3685that's not on this paper. - We want a literal operator to produce
view string
, Perhaps""sv
.
History of Paper Revision
This document updates the N3849 with:
- To move
Series
be a member function, similar tobit set
. - Change
pointer
miReference
not to be-Constantly
Species, for consistency with containers, includingdefine
. - Add to
constexpr
I missed it in a few places, but the LWG pointed it out. - allowed
string_view(nullptr, 0)
, voted for by a mixed LEWG/LWG faction. - Change "Effects: Equivalent
to return ...
" for "Effects: Equivalent...
on the theory that "if F has nonereturns: element, a non-empty return from F is indicated byreturns: Elements in code string." means everything is fine, and if not, this wording needs improvement. - Adding complexity guarantees to string conversions and
Copy of()
. - Various other minor wording adjustments.
N3849N3762 updated by:
- explain why
string_view().data() != Nullpunkt
and add an alternate writing section if we think it's possible, - Correction of references and namespaces to TS Fundamentals,
- Declare each function as
constexpr
which could be a constant expression if theCharacteristics
the class is reasonable and - Add exposure only
Data_
miSize_
members, and explain various members in their terms.
N3762Updated N3685 by removing other standard library updates so the kernelview string
the class can be accepted independently. Me too:
- Fixed some bugs in
Position
miNorte
Parameter, - Aggregate
Copy of()
Come back, - Removes the assumption thatLWG Issue 2232It will be fixed
- added a member
Trocar ()
Since it's a constant time - assured that
default::exchange
and area access features are available when<view string>
is included and - some fixed
not except
S.
N3685N3609 updated with the results ofLEWG-Diskussion in Bristol. The main changes include:
- Redirected to a TS instead of C++14
- moved to a
<view string>
Header. - Added
Position
miNorte
parameters back toview string
methods. - remote control
begins with
miends with
.
N3609was a minor update for N3512 that changed the proposed class name tobasic_string_view
and corrected some editorial errors.
N3512N3442 updated with wording for theC++14 Standard Draft. Note that we're still not sure if we're targeting TS or C++14.
N3442it was intended for a TS and updatedN3334removedarray_ref
.
Ölatest version of this articleis maintained on GitHub.
Writing for TS Basics
clausula x, string_view
the class modelbasic_string_view
describes an object that can refer to a constant contiguous sequence of objects of type char (C++11[strings.general]) where the first element of the sequence is at position zero. The remainder of this section describes the type of coal-like objects found in abasic_string_view
Object is denoted byChart
.
[Note: The library provides implicit conversions fromTABLE OF CONSTITUTIONS*
mistd::basic_string<character, ...>
forstd::basic_string_view<characters, ...>
i.e. can only accept the user codestd::basic_string_view<charT>
as a non-template parameter whenever a string is expected. User-defined types must define their own implicit conversionsstd::basic_string_view
to interact with these features. - final remark]
The complexity ofbasic_string_view
Membership functions is O(1) unless otherwise noted.
Add an "<experimental/string_view> header synopsis".
namespace std {experimental namespace { inline namespace fundamentals_v1 { // [basic.string.view], basic_string_view: template<class charT, class traits = char_traits<charT>> class basic_string_view; // [string.view.comparison], comparison functions basic_string_view no members template<class charT, class traits> constexpr bool operator==(basic_string_view<charT, traits> x, basic_string_view<charT, traits> y) noexcept; template<class character, class characteristics> constexpr operator bool!=(basic_string_view<character, characteristics> x, basic_string_view<character, characteristics> y) noexcept; template<class character, class properties> constexpr bool operator< (basic_string_view<character, properties> x, basic_string_view<character, properties> y) noexcept; template<class character, class traits> constexpr bool operator> (basic_string_view<charT, traits> x, basic_string_view<charT, traits> y) noexcept; template<class character, class properties> constexpr bool operator<=(basic_string_view<character, properties> x, basic_string_view<character, properties> y) noexcept; template<class character, class properties> constexpr operator bool>=(basic_string_view<character, properties> x, basic_string_view<character, properties> y) noexcept; //see below, weitere ausreichende Vergleichsfunktionen // [string.view.io], eingefügte und extrahierte Vorlagen<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, basic_string_view <charT, Merkmale> str); // basic_string_view typedef Namen typedef basic_string_view<char> string_view; typedef basic_string_view<char16_t> u16string_view; typedef basic_string_view<char32_t> u32string_view; typedef basic_string_view<wchar_t> wstring_view;} // Namensraum fundamentals_v1} // Namensraum experimentell // [string.view.hash], soporta un hash: plantilla <class T> struct hash; plantilla <> struct hash<experimental::string_view>; plantilla <> struct hash<experimental::u16string_view>; plantilla <> struct hash<experimental::u32string_view>; template <> struct hash<experimental::wstring_view>;} // espacio de nombres estándar
The templates for functions defined in C++11[utility.swap] and C++11[iterator.range] are available when<view string>
it is included
Normally I would update the list in C++11[iterator.range] but we're still not sure how to do it in a TS so I went with the more independent option.
Namespace std {Namespace Experimental {Namespace Fundamentals_v1 { Template<class charT, class traits = char_traits<charT>> class basic_string_view { public: // tipos typedef traits traits_type; typedef charT value_type; typedef charT* ponteiro; typedef const charT* const_pointer; typedef charT& referencia; typedef const charT& const_reference; Definition des Typsimplementation-definedconst_iterador; // [string.view.iterators] konsultieren typedef const_iterator iterator; // [Nota de rodapé: Como basic_string_view is referiere a a sequência constante, iterator and const_iterator as do mesmo tipo. --end footnote] typedef reverse_iterator<const_iterator> const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; typedef tamanho_t tamanho_tipo; typedef ptrdiff_t differenztyp; static constexpr size_type npos = size_type(-1); // [string.view.cons], construir/copiar constexpr basic_string_view() noexcept; constexpr basic_string_view(const basic_string_view&) noexcept = predeterminado; basic_string_view& operator=(const basic_string_view&) noexcept = padrão; template<class Asignador> basic_string_view(const basic_string<charT, traits, Allocator>& str) noexcept; constexpr basic_string_view(const charT* str);
The above constructor is constexpr to consume user-written feature classes that a constexpr can provide.Long()
Function. Must not be part of a constant expression withstd::char_traits<characters>
There are no changes in this class.
constexpr basic_string_view(const charT* str, size_type len);
There is no initializer_list constructor because C++11[dcl.init.list]p6 says it would probably store a dangling reference in itbasic_string_view
.
// [string.view.iterators], iteradores constexpr const_iterator begin() const noexcept; constexpr const_iterator end() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept;
The reverse_iterator methods are not constexpr because reverse_iterator is not a type literal. To seeLWG Edition 2208.
const_reverse_iterator rbegin() const noexcept; const_reverse_iterator rend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; // [string.view.capacity], Kapazität constexpr size_type size() const noexcept; constexpr size_type length() const noexcept; constexpr size_type max_size() const noexcept; constexpr bool vacío() const noexcept; // [string.view.access], Zugang zu allen Elementen constexpr const_reference operator[](size_type pos) const; constexpr const_reference at(size_type pos) const; constexpr const_reference front() const; constexpr const_reference back() const; constexpr const_pointer data() const noexcept; // [string.view.modifiers], Modifikatoren: constexpr void clear() noexcept; constexpr void remove_prefix(tamaño_tipo n); constexpr void remove_suffix(tamaño_tipo n); constexpr void swap(basic_string_view& s) noexcept; // [string.view.ops], Stringoperationen: template<class Allocator> Operator erklärt basic_string<charT, traits, Allocator>() const; template<clase Asignador = asignador<carT> > basic_string<charT, rasgos, Asignador> to_string( const Asignador& a = Asignador()) const; size_type copy(charT* s, size_type n, size_type pos = 0) const; constexpr basic_string_view substr(tamaño_tipo pos = 0, tamaño_tipo n = npos) const; constexpr int vergleichen (basic_string_view s) const noexcept; constexpr int Compare(size_type pos1, size_type n1, basic_string_view s) const; constexpr int Compare(size_type pos1, size_type n1, basic_string_view s, size_type pos2, size_type n2) const; constexprint int Compare(const charT* s) const; constexpr int Compare(size_type pos1, size_type n1, const charT* s) const; constexpr int Compare(size_type pos1, size_type n1, const charT* s, size_type n2) const; constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept; constexpr size_type find(charT c, size_type pos = 0) const noexcept; constexpr size_type find(const charT* s, size_type pos, size_type n) const; constexpr size_type find(const charT* s, size_type pos = 0) const; constexpr size_type rfind (basic_string_view s, size_type pos = npos) const noexcept; constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; constexpr size_type rfind(const charT* s, size_type pos, size_type n) const; constexpr size_type rfind(const charT* s, size_type pos = npos) const; constexpr size_type find_first_of (basic_string_view s, size_type pos = 0) const noexcept; constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_first_of(const charT* s, size_type pos = 0) const; constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept; constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_last_of(const charT* s, size_type pos = npos) const; constexpr size_type find_first_not_of (basic_string_view s, size_type pos = 0) const noexcept; constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const; constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept; constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; privado: const_puntero datos_; //exposure onlysize_type size_; //exposure only};} // namespace v1_fundamentals} // experimental namespace } // default namespace
in every subjectbasic_string_view<charT, Merkmale>
, the guyCharacteristics
must meet character trait requirements (C++11[char.traits]) and typeCharacteristics::char_type
must name the same type asChart
.
Add a subclause "x.1 basic_string_view constructors and assignment operators [string.view.cons]".
constexpr basic_string_view() noexcept;
Effects: Create a voidbasic_string_view
.
by state:size_ == 0
, midata_ == zero point
.
template<Klassenzuweisung>basic_string_view(const basic_string<charT, traits, Allocator>& str) noexcept;
Effects: Build inbasic_string_view
, with postconditions in table [tab:string.view.ctr.1]
Element | bravery |
---|---|
Data_ | str.data() |
Size_ | str.size() |
constexpr basic_string_view(const charT* str);
requires: [call up
,str + Bindestriche::length(str)
) is a valid range.
Effects: Build inbasic_string_view
refers to the same string ascall up
, with postconditions in table [tab:string.view.ctr.2]
Element | bravery |
---|---|
Data_ | call up |
Size_ | dashes::length(string) |
complexity:Ö(dashes::length(string)
)
constexpr basic_string_view(const charT* str, size_type len);
requires: [call up
,street + length
) is a valid range.
Effects: Build inbasic_string_view
, with postconditions in table [tab:string.view.ctr.3]
Element | bravery |
---|---|
Data_ | call up |
Size_ | Len |
Agree to a subclause "x.2 iterator support basic_string_view [string.view.iterators]"
implementation-defined const_iterator typedef;
A kind of constant random access iterator such that for abe const_iterator
, se&*(is+N)
applies, then it is the same(&*dies)+N
.
Forbasic_string_view str
, any operation that takes a pointer in the range [str.data()
,str.data()+str.size()
) overrides pointers, iterators, and references returned bycall up
methods of.
All container iterator requirements (C++11[container.requirements]) apply tobasic_string_view::const_iterator
Also.
constexpr const_iterator begin() const noexcept;constexpr const_iterator cbegin() const noexcept;
returns: An iterator such that&*start() == data_
con!file()
, or an unspecified value such that [begin()
,fim()
) is a valid range.
constexpr const_iterator end() const noexcept;constexpr const_iterator cend() const noexcept;
returns:start() + size()
const_reverse_iterator rbegin() const noexcept;const_reverse_iterator crbegin() const noexcept;
returns:const_reverse_iterator(fin())
.
const_reverse_iterator rend() const noexcept;const_reverse_iterator crend() const noexcept;
returns:const_reverse_iterator(begin())
.
Add a sub clause "capacity x.3 basic_string_view [string.view.capacity]"
constexpr size_type size() const noexcept;
returns:Size_
constexpr size_type length() const noexcept;
returns:Size_
.
constexpr size_type max_size() const noexcept;
returns: As many coal-like objects as possible that can be referenced by abasic_string_view
.
constexpr bool void() const noexcept;
returns:size_ == 0
.
Adicione uma subcláusula "x.4 basic_string_view element access [string.view.access]"
constexpr const_reference operator[](size_type pos) const;
requires:Pos<Size()
.
returns:data_[pos]
spears: Anything.
[Note: differentbasic_string::operator[]
,basic_string_view::operator[](size())
has undefined behavior instead of returningChart()
. - final remark]
constexpr const_reference at(size_type pos) const;
spears:out of range
conposition >= size()
.
returns:data_[pos]
.
constexpr const_reference front() const;
requires:!file()
returns:data_[0]
.
spears: Anything.
constexpr const_reference back() const;
requires:!file()
returns:data_[size() - 1]
.
spears: Anything.
constexpr const_pointer data() const noexcept;
returns:Data_
[Note: differentbasic_string::data()
and string literals,Data()
can return a pointer to a non-null-terminated buffer. Therefore, passing is usually a mistakeData()
to a routine that only takes oneTABLE OF CONSTITUTIONS*
and expects a null-terminated string. - final remark]
Add a sub-clause "x.5 basic_string_view modifiers [string.view.modifiers]".
constexpr void clear() noexcept;
Effects: Equivalent*est = basic_string_view()
constexpr void remove_prefix(size_type n);
requires:n <= size()
Effects: Equivalentdata_ += n; size_ -= n;
constexpr void remove_suffix (size_type n);
requires:n <= size()
Effects: Equivalentsize_ -= n;
constexpr void swap(basic_string_view& s) noexcept;
Effects: Swaps the values of*be
miS
.
Add a sub clause "x.6 basic_string_view string operations [string.view.ops]".
template<class Allocator>explicit // Footnote: This cast is explicit to prevent accidental O(N) operations on type mismatches. --end footnoteoperator basic_string<charT, traits, Allocator>() const;
Effects: Equivalentbasic_string<charT, traits, Allocator>(begin(), end()).
complexity:Ö(Size()
)
[Note: Users wishing to control the assignment instance must callto_string(Zuweiser)
. -- final remark ]
template<class Mapper = mapper<charT> >basic_string<charT, features, Mapper> to_string( const Mapper& a = Mapper()) const;
returns:basic_string<charT, features, Allocator>(begin(), end(), a)
.
complexity:Ö(Size()
)
size_type copy(charT* s, size_type n, size_type pos = 0) const;
Leaverlen
be the smallestNorte
misize() - Position
.
spears:out of range
conposition > size()
.
requires: [S
,s+rlen
) is a valid range.
Effects: Equivalentstd::copy_n(begin() + pos,rlen, S).
returns:rlen
.
complexity:Ö(rlen
)
constexpr basic_string_view substr(type_size pos = 0, type_size n = npos) const;
spears:out of range
conposition > size()
.
Effects: Determines the effective lengthrlen
the string to be referenced as the smallestNorte
misize() - Position
.
returns:basic_string_view(daten()+pos,rlen)
.
constexpr int vergleichen (basic_string_view str) const noexcept;
Effects: Determines the effective lengthrlen
of strings to be compared as the smallest ofSize()
mistr.size()
. The function then compares the two strings by callingProperties::compare(data(), str.data(),rlen)
.
complexity:Ö(rlen
)
returns: The non-zero result if the comparison result is non-zero. Otherwise, it returns a value as specified in table [tab:string.view.compare].
Illness | return value |
---|---|
size() < str.size() | < 0 |
size() == str.size() | 0 |
size() > str.size() | > 0 |
constexpr int vergleichen (size_type pos1, size_type n1, basic_string_view str) const;
Effects: Equivalentsubstr(pos1, n1).compare(str)
.
constexpr int Compare(size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2) const;
Effects: Equivalentsubstr(pos1, n1).compare(str.substr(pos2, n2))
.
constexprint int Compare(const charT* s) const;
Effects: Equivalentcompare(basic_string_view(s))
.
constexpr int Compare(size_type pos1, size_type n1, const charT* s) const;
Effects: Equivalentsubstr(pos1, n1).compare(basic_string_view(s))
.
constexpr int Compare(size_type pos1, size_type n1, const charT* s, size_type n2) const;
Effects: Equivalentsubstr(pos1, n1).compare(basic_string_view(s, n2))
.
Add a sub clause "x.6.1 Search basic_string_view [string.view.find]"
This section specifies thebasic_string_view
Named member functionsmeet
,meet
,find_first_of
,find_last_of
,find_first_not_of
, mifind_last_not_of
.
The member functions in this section have complexity O(size() * str.size()
) in the worst case, although it is recommended that implementations perform better.
Each member function of the form
constexprReturn type fx1(const charT* s, size_type pos);
It is equivalent tofor example 1(basic_string_view(s), pos)
.
Each member function of the form
constexprReturn type fx1(const charT* s, size_type pos, size_type n);
It is equivalent tofor example 1(basic_string_view(s, n), pos)
.
Each member function of the form
constexprfx2 return type(charT c, size_type pos);
It is equivalent tofx2(basic_string_view(&c, 1), pos)
.
constexpr size_type find(basic_string_view str, size_type pos = 0) const noexcept;
Effects: determines the lowest positionPos x
, if possible, so that the following conditions are met:
Position <= Position x
xpos + str.size() <= size()
Merkmale::eq(en(xpos+I), str.en(I))
for all elementsUE
from the referenced stringcall up
.
returns:Pos x
if the function can determine such a value forPos x
. otherwise come backnpos
.
Comments: IntestinesProperties::eq()
.
constexpr size_type rfind (basic_string_view str, size_type pos = npos) const noexcept;
Effects: determines the highest positionPos x
, if possible, so that the following conditions are met:
digit x <= digit
xpos + str.size() <= size()
Merkmale::eq(en(xpos+I), str.en(I))
for all elementsUE
from the referenced stringcall up
.
returns:Pos x
if the function can determine such a value forPos x
. otherwise come backnpos
.
Comments: IntestinesProperties::eq()
.
constexpr size_type find_first_of (basic_string_view str, size_type pos = 0) const noexcept;
Effects: determines the lowest positionPos x
, if possible, so that the following conditions are met:
Position <= Position x
xpos <size()
Merkmale::eq(en(xpos), str.en(I))
for any itemUE
from the referenced stringcall up
.
returns:Pos x
if the function can determine such a value forPos x
. otherwise come backnpos
.
Comments: IntestinesProperties::eq()
.
constexpr size_type find_last_of(basic_string_view str, size_type pos = npos) const noexcept;
Effects: determines the highest positionPos x
, if possible, so that the following conditions are met:
digit x <= digit
xpos <size()
Merkmale::eq(en(xpos), str.en(I))
for any itemUE
from the referenced stringcall up
.
returns:Pos x
if the function can determine such a value forPos x
. otherwise come backnpos
.
Comments: IntestinesProperties::eq()
.
constexpr size_type find_first_not_of (basic_string_view str, size_type pos = 0) const noexcept;
Effects: determines the lowest positionPos x
, if possible, so that the following conditions are met:
Position <= Position x
xpos <size()
Merkmale::eq(en(xpos), str.en(I))
for no itemUE
from the referenced stringcall up
.
returns:Pos x
if the function can determine such a value forPos x
. otherwise come backnpos
.
Comments: IntestinesProperties::eq()
.
constexpr size_type find_last_not_of(basic_string_view str, size_type pos = npos) const noexcept;
Effects: determines the highest positionPos x
, if possible, so that the following conditions are met:
digit x <= digit
xpos <size()
Merkmale::eq(en(xpos), str.en(I))
for no itemUE
from the referenced stringcall up
.
returns:Pos x
if the function can determine such a value forPos x
. otherwise come backnpos
.
Comments: IntestinesProperties::eq()
.
Add a sub-clause "x.7 basic_string_view non-member comparison functions [string.view.comparison]"
LeaveS
bebasic_string_view<charT, Merkmale>
, misv
be an exampleS
. Implementations must provide sufficient marked additional overheadconstexpr
minot except
thus an objectT
with an implicit cast toS
can be compared according to table [tab:string.view.comparison.overloads].
Expression | Equivalent |
---|---|
t == sv | S(t) == sv |
sv == t | sv == S(t) |
t != sv | S(t) != sv |
sv != t | sv != S(t) |
t <sv | S(t) < sv |
sv < t | sv < S(t) |
t> call | S(t) > sv |
sv > t | sv > S(t) |
t <= sv | S(t) <= sv |
sv <= t | sv <= S(t) |
t >= sv | S(t) >= sv |
sv >= t | sv >= S(t) |
[Example: An example conforming implementation for operator== would be:
template<class T> using __identity = typename std::decay<T>::type; template<Klassenzeichen, Klasseneigenschaften> constexpr bool operator==( basic_string_view<Zeichen, Eigenschaften> lhs, basic_string_view<Zeichen, Eigenschaften> rhs) noexcept { return lhs.compare(rhs) == 0; } template<class character, class traits> constexpr bool operator==( basic_string_view<charT, traits> lhs, __identity<basic_string_view<charT, traits>> rhs) noexcept { return lhs.compare(rhs) == 0; } template<Klassenzeichen, Klassenmerkmale> constexpr bool operator==( __identity<basic_string_view<character, properties>> lhs, basic_string_view<character, properties> rhs) noexcept { return lhs.compare(rhs) == 0;}
— last example]
template<class character, class properties> constexpr bool operator==(basic_string_view<character, properties> lhs, basic_string_view<character, properties> rhs) noexcept;
returns:lhs.compare(rhs) == 0
.
template<Klassenzeichen, Klassenklassen> constexpr bool operator!=(basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs) noexcept;
returns:lhs.compare(rhs) != 0
.
template<class character, class properties> constexpr bool operator< (basic_string_view<character, properties> lhs, basic_string_view<character, properties> rhs) noexcept;
returns:lhs.compare(rhs) < 0
.
template<Klassenzeichen, Klassenklassen> constexpr bool operator> (basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs) noexcept;
returns:lhs.compare(rhs) > 0
.
template<class character, class properties> constexpr bool operator<=(basic_string_view<character, properties> lhs, basic_string_view<character, properties> rhs) noexcept;
returns:lhs.compare(rhs) <= 0
.
template<Klassenzeichen, Klassenklassen> constexpr bool operator>=(basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs) noexcept;
returns:lhs.compare(rhs) >= 0
.
Add a sub-clause "Pinser and Extractors x.9 [string.view.io]".
template<class character, class traits> basic_ostream<character, traits>& operator<<(basic_ostream<character, traits>& os, basic_string_view<character, traits> str);
Effects: Equivalentos << str.to_string()
.
Add a sub-clause "x.10 hash support [string.view.hash]".
plantilla <> struct hash<experimental::string_view>;template <> struct hash<experimental::u16string_view>;template <> struct hash<experimental::u32string_view>;template <> struct hash<experimental::wstring_view>;
Template specializations must meet the class template hash requirements (C++11[unord.hash]).
expression of gratitude
I would like to thank Marshall Clow, Olaf van der Spek, the Boost and std-proposals mailing lists, Chandler Carruth, Beman Dawes, Alisdair Meredith and especially Daniel Krügler for their help, advice and writing this article.