|
template<class CHAR_TYPE , class CHAR_TRAITS > |
bool | bslstl_string_fill (std::basic_ostream< CHAR_TYPE, CHAR_TRAITS > &os, std::basic_streambuf< CHAR_TYPE, CHAR_TRAITS > *buf, std::size_t n) |
| Do not use, for internal use by operator<< only.
|
|
Outline
Purpose
Provide a standard-compliant basic_string class template.
Classes
Canonical header: bsl_string.h
- See also
- ISO C++ Standard, Section 21 [strings]
Description
This component defines a single class template basic_string , implementing standard containers, std::string
and std::wstring
, that hold a sequence of characters.
An instantiation of basic_string is an allocator-aware, value-semantic type whose salient attributes are its size (number of characters) and the sequence of characters that the string contains. The basic_string class
is parameterized by the character type, CHAR_TYPE
, that character type's traits, CHAR_TRAITS
, and an allocator, ALLOCATOR
. The traits for each character type provide functions that assign, compare, and copy a sequence of those characters.
A basic_string meets the requirements of a sequential container with random access iterators as specified in the [basic.string] section of the C++ standard [21.4]. The basic_string implemented here adheres to the C++11 standard, except that it does not have template specializations std::u16string
and std::u32string
. Note that excluded C++11 features are those that require (or are greatly simplified by) C++11 compiler support.
Memory Allocation
The type supplied as a basic_string s ALLOCATOR
template parameter determines how that basic_string will allocate memory. The basic_string template supports allocators meeting the requirements of the C++11 standard, in addition it supports scoped-allocators derived from the bslma::Allocator
memory allocation protocol. Clients intending to use bslma
style allocators should use the template's default ALLOCATOR
type: The default type for the ALLOCATOR
template parameter, bsl::allocator
, provides a C++11 standard-compatible adapter for a bslma::Allocator
object.
bslma-Style Allocators
If the (template parameter) type ALLOCATOR
of an basic_string instantiation is bsl::allocator
, then objects of that basic_string type will conform to the standard behavior of a bslma
-allocator-enabled type. Such a basic_string accepts an optional bslma::Allocator
argument at construction. If the address of a bslma::Allocator
object is explicitly supplied at construction, it is used to supply memory for the basic_string throughout its lifetime; otherwise, the basic_string will use the default allocator installed at the time of the basic_string 's construction (see bslma_default ).
Lexicographical Comparisons
Two basic_string s lhs
and rhs
are lexicographically compared by first determining N
, the smaller of the lengths of lhs
and rhs
, and comparing characters at each position between 0 and N - 1
, using CHAR_TRAITS::lt
in lexicographical fashion. If CHAR_TRAITS::lt
determines that strings are non-equal (smaller or larger), then this is the result. Otherwise, the lengths of the strings are compared and the shorter string is declared the smaller. Lexicographical comparison returns equality only when both strings have the same length and the same character value in each respective position.
Operations
This section describes the run-time complexity of operations on instances of basic_string :
Legend
------
'V' - the 'CHAR_TYPE' template parameter type of the
'basic_string'
'a', 'b' - two distinct objects of type 'basic_string<V>'
'k' - an integral number
'al' - an STL-style memory allocator
'i1', 'i2' - two iterators defining a sequence of 'CHAR_TYPE'
characters
'v' - an object of type 'V'
'p1', 'p2' - two iterators belonging to 'a'
distance(i1,i2) - the number of values in the range [i1, i2)
+-----------------------------------------+-------------------------------+
| Operation | Complexity |
|=========================================+===============================|
| basic_string<V> a (default construction)| O[1] |
| basic_string<V> a(al) | |
|-----------------------------------------+-------------------------------|
| basic_string<V> a(b) (copy construction)| O[n] |
| basic_string<V> a(b, al) | |
|-----------------------------------------+-------------------------------|
| basic_string<V> a(std::move(b)) | O[1] |
| (move construction) | |
|-----------------------------------------+-------------------------------|
| basic_string<V> a(std::move(b), a1) | O[n] |
| (extended move construction) | |
|-----------------------------------------+-------------------------------|
| basic_string<V> a(k) | O[n] |
| basic_string<V> a(k, al) | |
|-----------------------------------------+-------------------------------|
| basic_string<V> a(i1, i2) | O[distance(i1,i2)] |
| basic_string<V> a(i1, i2, al) | |
|-----------------------------------------+-------------------------------|
| a.~basic_string<V>() (destruction) | O[1] |
|-----------------------------------------+-------------------------------|
| get_allocator() | O[1] |
|-----------------------------------------+-------------------------------|
| a.begin(), a.end(), | O[1] |
| a.cbegin(), a.cend(), | |
| a.rbegin(), a.rend(), | |
| a.crbegin(), a.crend() | |
|-----------------------------------------+-------------------------------|
| a.size() | O[1] |
|-----------------------------------------+-------------------------------|
| a.max_size() | O[1] |
|-----------------------------------------+-------------------------------|
| a.resize(k) | O[k] |
| a.resize(k, v) | |
|-----------------------------------------+-------------------------------|
| a.resize_and_overwrite(k, op) | O[k] |
|-----------------------------------------+-------------------------------|
| a.empty() | O[1] |
|-----------------------------------------+-------------------------------|
| a.reserve(k) | O[1] |
|-----------------------------------------+-------------------------------|
| a.shrink_to_fit() | O[n] |
|-----------------------------------------+-------------------------------|
| a[k] | O[1] |
|-----------------------------------------+-------------------------------|
| a.at(k) | O[1] |
|-----------------------------------------+-------------------------------|
| a.front() | O[1] |
|-----------------------------------------+-------------------------------|
| a.back() | O[1] |
|-----------------------------------------+-------------------------------|
| a.push_back() | O[1] |
|-----------------------------------------+-------------------------------|
| a.pop_back() | O[1] |
|-----------------------------------------+-------------------------------|
| a += b; | O[n] |
|-----------------------------------------+-------------------------------|
| a.append(b); | O[n] |
|-----------------------------------------+-------------------------------|
| a.assign(b); | O[n] |
|-----------------------------------------+-------------------------------|
| a.assign(std::move(b)); | O[1] if the allocator can be |
| | propagated on container move |
| | assignment or 'a' and 'b' use |
| | the same allocator; O[n] |
| | otherwise |
|-----------------------------------------+-------------------------------|
| a.assign(k, v) | O[k] |
|-----------------------------------------+-------------------------------|
| a.assign(i1, i2) | O[distance(i1,i2)] |
|-----------------------------------------+-------------------------------|
| a.insert(p1, v) | O[1 + distance(p1, a.end())] |
|-----------------------------------------+-------------------------------|
| a.insert(p1, k, v) | O[k + distance(p1, a.end())] |
|-----------------------------------------+-------------------------------|
| a.insert(p1, i1, i2) | O[distance(i1, i2) |
| | + distance(p1, a.end())] |
|-----------------------------------------+-------------------------------|
| a.erase(p1) | O[1 + distance(p1, a.end())] |
|-----------------------------------------+-------------------------------|
| a.erase(p1, p2) | O[1 + distance(p1, a.end())] |
|-----------------------------------------+-------------------------------|
| a.swap(b), swap(a, b) | O[1] if 'a' and 'b' allocators|
| | compare equal, O[n + m] |
| | otherwise |
|-----------------------------------------+-------------------------------|
| a.clear() | O[1] |
|-----------------------------------------+-------------------------------|
| a = b; (assignment) | O[n] |
|-----------------------------------------+-------------------------------|
| a = std::move(b); (move assignment) | O[1] if the allocator can be |
| | propagated on container move |
| | assignment or 'a' and 'b' use |
| | the same allocator; O[n] |
| | otherwise |
|-----------------------------------------+-------------------------------|
| a == b, a != b | O[n] |
|-----------------------------------------+-------------------------------|
| a < b, a <= b, a > b, a >= b | O[n] |
+-----------------------------------------+-------------------------------+
User-defined literals
The user-defined literal operators are declared for the bsl::string
and bsl::wstring
types. The ud-suffix _s
is chosen to distinguish between the bsl
-string's user-defined literal operators and the std
-string's user-defined literal operator ""s
introduced in the C++14 standard and implemented in the standard library provided by the compiler vendor. Note that the bsl
-string's operator "" _s
, unlike the std
-string's operator ""s
, can be used in a client's code if the compiler supports the C++11 standard. Also note that if the compiler supports the C++14 standard then the std
-string's operator ""s
can be used to initialize a bsl
-string as follows:
using namespace std::string_literals;
Definition bslstl_string.h:1281
however such initialization introduces significant performance overhead due to extra std
-string object creation/destruction.
Also note that bsl
-string's user-defined literal operators are declared in the bsl::literals::string_literals
namespace, where literals
and string_literals are inline namespaces. Access to these operators can be gained with either using namespace bsl::literals
, using namespace bsl::string_literals
or using namespace bsl::literals::string_literals
. But we recommend using namespace bsl::string_literals
to minimize the scope of the using declaration:
using namespace bsl::string_literals;
Memory Allocation For a File-Scope Strings
The operator "" _s
uses the currently installed default allocator to supply memory. Note that the default allocator can become locked prior to entering main
as a side-effect of initializing a file-scope static string object using operator "" _s
. To avoid the default allocator locking an operator "" _S
can be used instead. This operator uses the global allocator to supply memory and has no side-effects. (See the "Default
Allocator" section in the bslma::Default
component-level documentation for details.) For Example:
using namespace bsl::string_literals;
static const bsl::string s =
"Use '_S' to initialize a file-scope string"_S;
Usage
In this section we show intended use of this component.
Example 1: Basic Syntax
In this example, we will show how to create and use the string
typedef.
First, we will default-construct a string
object:
assert("" == s);
size_type size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6592
bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this string has length 0, and false otherwise.
Definition bslstl_string.h:6631
Then, we will construct a string
object from a string literal:
assert("Hello World" == t);
Next, we will clear the contents of t
and assign it a couple of values: first from a string literal; and second from another string
object:
assert("" == t);
t = "Good Morning";
assert("Good Morning" == t);
t = s;
assert("" == t);
assert(t == s);
void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:5430
Then, we will create three string
objects: the first representing a street name, the second a state, and the third a ZIP code. We will then concatenate them into a single address string
and print the contents of that string
on standard output:
const bsl::string fullAddress = street +
" " + state +
" " + zipCode;
bsl::cout << fullAddress << bsl::endl;
The above print statement should produce a single line of output:
731 Lexington Avenue NY 10022
Then, we search the contents of address
(using the find
function) to determine if it lies on a specified street:
bsl::cout << "The address " << fullAddress << " is located on "
<< streetName << "." << bsl::endl;
}
size_type find(const basic_string &substring, size_type position=0) const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6732
static const size_type npos
Definition bslstl_string.h:1676
Next, we show how to get a reference providing modifiable access to the null-terminated string literal stored by a string
object using the c_str
function. Note that the returned string literal can be passed to various standard functions expecting a null-terminated string:
const char *cs = v.
c_str();
assert(bsl::strlen(cs) == v.
size());
const CHAR_TYPE * c_str() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6705
Then, we construct two string
objects, x
and y
, using a user-specified allocator:
const char *SHORT_STRING = "A small string";
const char *LONG_STRING = "This long string would definitely cause "
"memory to be allocated on creation";
assert(SHORT_STRING == x);
assert(LONG_STRING == y);
Definition bslma_testallocator.h:384
Notice that, no memory was allocated from the allocator for object x
because of the short-string optimization used in the string
type.
Finally, we can track memory usage of x
and y
using allocator1
and allocator2
and check that memory was allocated only by allocator2
:
bsls::Types::Int64 numBlocksInUse() const
Definition bslma_testallocator.h:1087
Example 2: string as a data member
The most common use of string
objects are as data members in user-defined classes. In this example, we will show how string
objects can be used as data members.
First, we begin to define a class
, Employee
, that represents the data corresponding to an employee of a company:
class Employee {
int d_id;
Next, we define the creators for this class:
public:
int id,
Employee(const Employee& original,
Definition bslstl_stringview.h:441
Definition bslma_allocator.h:457
Notice that all constructors of the Employee
class are optionally provided an allocator that is then passed through to the string
data members of Employee
. This allows the user to control how memory is allocated by Employee
objects. Also note that the type of the firstName
and lastName
arguments of the value constructor is bsl::string_view
. The bsl::string_view
allows specifying a string
or a const char *
to represent a string value. For the sake of brevity its implementation is not explored here.
Then, declare the remaining methods of the class:
Employee& operator=(const Employee& rhs);
void setId(int value);
int id() const;
};
Next, we declare the free operators for Employee
:
inline
bool operator==(const Employee& lhs, const Employee& rhs);
inline
bool operator!=(const Employee& lhs, const Employee& rhs);
Then, we implement the various methods of the Employee
class:
inline
: d_firstName(basicAllocator)
, d_lastName(basicAllocator)
, d_id(0)
{
}
inline
int id,
: d_firstName(firstName.begin(), firstName.end(), basicAllocator)
, d_lastName(lastName.begin(), lastName.end(), basicAllocator)
, d_id(id)
{
}
inline
Employee::Employee(const Employee& original,
: d_firstName(original.d_firstName, basicAllocator)
, d_lastName(original.d_lastName, basicAllocator)
, d_id(original.d_id)
{
}
BSLS_KEYWORD_CONSTEXPR bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this view has length 0, and false otherwise.
Definition bslstl_stringview.h:1703
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
Notice that the basicAllocator
parameter can simply be passed as an argument to the constructor of bsl::string
.
Now, we implement the remaining manipulators of the Employee
class:
inline
Employee& Employee::operator=(const Employee& rhs)
{
d_firstName = rhs.d_firstName;
d_lastName = rhs.d_lastName;
d_id = rhs.d_id;
return *this;
}
inline
{
d_firstName.assign(value.
begin(), value.
end());
}
inline
{
d_lastName.assign(value.
begin(), value.
end());
}
inline
void Employee::setId(int value)
{
d_id = value;
}
inline
{
return d_firstName;
}
inline
{
return d_lastName;
}
inline
int Employee::id() const
{
return d_id;
}
BSLS_KEYWORD_CONSTEXPR const_iterator end() const BSLS_KEYWORD_NOEXCEPT
Return the past-the-end iterator for this view.
Definition bslstl_stringview.h:1620
BSLS_KEYWORD_CONSTEXPR const_iterator begin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_stringview.h:1602
Finally, we implement the free operators for Employee
class:
inline
bool operator==(const Employee& lhs, const Employee& rhs)
{
return lhs.firstName() == rhs.firstName()
&& lhs.lastName() == rhs.lastName()
&& lhs.id() == rhs.id();
}
inline
bool operator!=(const Employee& lhs, const Employee& rhs)
{
return lhs.firstName() != rhs.firstName()
|| lhs.lastName() != rhs.lastName()
|| lhs.id() != rhs.id();
}
Example 3: A stream text replacement filter
In this example, we will utilize the string
type and its associated utility functions to define a function that reads data from an input stream, replaces all occurrences of a specified text fragment with another text fragment, and writes the resulting text to an output stream.
First, we define the signature of the function, replace
:
void replace(bsl::ostream& outputStream,
bsl::istream& inputStream,
Then, we provide the implementation for replace
:
{
AllocatorTraits::size_type size_type
Definition bslstl_string.h:1303
std::basic_istream< CHAR_TYPE, CHAR_TRAITS > & getline(std::basic_istream< CHAR_TYPE, CHAR_TRAITS > &is, basic_string< CHAR_TYPE, CHAR_TRAITS, ALLOCATOR > &str, CHAR_TYPE delim)
Notice that we can use the getline
free function defined in this component to read a single line of data from an input stream into a bsl::string
.
if (!inputStream) {
return;
}
do {
Next, we use the find
function to search the contents of line
for characters matching the contents of oldString
:
int pos = line.
find(oldString);
Now, we use the replace
method to modify the contents of line
matching oldString
to newString
:
line.
replace(pos, oldStringSize, newString);
pos = line.
find(oldString, pos + newStringSize);
basic_string & replace(size_type outPosition, size_type outNumChars, const basic_string &replacement)
Definition bslstl_string.h:6142
Notice that we provide find
with the starting position from which to start searching.
Finally, we write the updated contents of line
to the output stream:
outputStream << line;
} while (inputStream);
}
◆ bslstl_string_fill()
template<class CHAR_TYPE , class CHAR_TRAITS >
bool bslstl_string_fill |
( |
std::basic_ostream< CHAR_TYPE, CHAR_TRAITS > & |
os, |
|
|
std::basic_streambuf< CHAR_TYPE, CHAR_TRAITS > * |
buf, |
|
|
std::size_t |
n |
|
) |
| |