United States |
Previous | Contents | Index |
Compaq C++ currently provides a partial implementation of the C++ Standard Library. The ANSI X3/J16 C++ committee is in the process of standardizing the C++ Standard Library, and when this process is complete Compaq C++ will provide a complete library implementation. In the meantime, the subset provided has been selected from among the most stable parts of the library as defined in the ANSI C++ draft.
This release of Compaq C++ contains the following components of the C++ Standard Library:
Some of the components in the C++ Standard Library are designed to replace nonstandard components that are currently distributed in the Compaq C++ Class Library. Compaq will continue to provide the Compaq C++ Class Library in its nonstandard form. However you now have the option of using the new standard components.
The following sections provide more information on the Compaq C++
implementation of the Standard Library, including upward compatibility,
compiling and linking, thread safety, and details on each component of
the library.
7.1 Important Compatibility Information
Because the standardization process for the C++ Standard Library is not yet completed, Compaq cannot guarantee that this version of the library is compatible with any past or future releases. We ship the run-time portion of the library in object form, not in shareable form, to emphasize this situation.
Therefore, Compaq recommends that you do not use this library for any
production code that requires upward compatibility. This release of the
library matches as closely as is feasible the standard described in the
post-Stockholm ANSI C++ draft dated 24 September 1996.
7.2 How to Build Programs Using the C++ Standard Library
To build programs that use the C++ Standard Library, certain changes to the Compaq C++ compiler and linker commands are necessary.
The cxx command line must include the following qualifier:
/assume=noheader_type_default |
This qualifier is required because Standard Library header files do not have file name extensions, and Compaq C++ by default appends a file name extension to such header file names (for backward compatibility). The /assume=noheader_type_default qualifier instructs Compaq C++ to not append a file extension.
You do not need to specify the /template=auto qualifier on the command line because the Compaq C++ compiler performs automatic template instantiation by default.
To link a program that uses the C++ Standard Library, you must use the cxxlink command in place of the link command. The cxxlink command continues the automatic template instantiation process, includes the Standard Library run-time support ( SYS$LIBRARY:LIBCXXSTD.OLB ) at link time, and creates the final image.
For example, to build a program called prog.cxx that uses the Standard Library, you can use the following commands:
cxx/assume=noheader_type_default prog.cxx cxxlink prog.obj |
The C++ Standard Library is thread safe, meaning that all internal
library data is protected against simultaneous access from multiple
threads.
7.3 Incompatibilities Between the Standard Library and the ANSI C++ Draft
Compaq C++ currently does not support all the necessary language features to compile a Standard Library that meets the specifications of the September ANSI C++ draft. Therefore, where possible, Compaq's implementation of the Standard Library contains workarounds for these missing language features.
The following list shows the unsupported ANSI C++ language features and their workarounds in the Compaq C++ Standard Library:
The following data structures and algorithms supplied with the current STL differ from those specified in the September 1996 ANSI C++ draft:
Additionally, the following are some minor incompatibilities in the current String Library that correct what Compaq believes are mistakes in the draft:
Compaq C++ provides an implementation of the Standard Template Library (STL).
The following sections provide information specific to the
Compaq C++ implementation of the STL. For information on how to
program with the STL, refer to the STL Tutorial and Reference
Guide that is part of the Compaq C++ printed documentation set.
See Section 7.4.3 for differences between the STL Tutorial and
Reference Guide and the Compaq C++ implementation of the STL.
7.4.1 Examples of Use
The following are some simple examples of using the containers and algorithms in the STL. You should compile and link these examples with the commands:
cxx/assume=noheader_type_default prog.cxx cxxlink prog |
For details on how to build programs that use the STL, see Section 7.2.
// This example shows how to create a vector, // initialize it with values, sort and print it #include <vector> #include <algorithm> #include <iostream.hxx> int main() { // create a vector of 4 ints vector<int> v(4); // initialize the vector with values v[0]=2; v[1]=0; v[2]=3; v[3]=1; // sort the vector sort(v.begin(),v.end()); // print the sorted vector for (vector<int>::iterator viter=v.begin();viter!=v.end();viter++) cout << *viter << " "; cout << endl; return 0; } |
// This example shows how to create a list, initialize // it with values, find a particular value and print // the element before and after that value #include <list> #include <iostream.hxx> #include <string> int main() { // create a list list<string> l; // add some values to the list l.insert(l.end(),"Stepanov"); l.insert(l.end(),"Koenig"); l.insert(l.end(),"Stroustrup"); l.insert(l.end(),"Lippman"); // find the value "Stroustrup" string value("Stroustrup"); list<string>::iterator liter=find(l.begin(),l.end(), value); // print out the value before and after "Stroustrup" if (liter!=l.end()) cout << "Stroustrup was found after " << *(--liter) << " and before " << *(++(++liter)) << endl; return 0; } |
// This example shows how to create a map, // add some values, and find the number of elements // which match a specified criterion #include <map> #include <iostream.hxx> bool smaller (pair<const char* const, float> p) { // returns true if element costs less than $3.00 return p.second < 3.00; } int main() { // create a map map<const char*,float, less<const char*> > shopmap; // add some elements to the map shopmap["milk"]=1.29; shopmap["steak"]=5.99; shopmap["cornflakes"]=2.69; shopmap["cheese"]=3.42; shopmap["ricekrispies"]=2.25; // count the number of items less than $3.00 int num_items = 0; count_if(shopmap.begin(),shopmap.end(),smaller,num_items); // print the results cout << "number of items less than 3 dollars is: " << num_items << endl; return 0; } |
The following discussion guides you through upgrading Compaq C++
Class Library code to use the STL, specifically replacing the vector
and stack classes that are currently in the
vector.hxx
header file.
7.4.2.1 Upgrading from the Compaq C++ Class Library Vector to the STL Vector
To change your code from using the Class Library vector to the STL vector, consider the following actions:
Nonstandard Vector Function | Replaced with STL Vector Function |
---|---|
elem(int index) | operator[](size_t index) (no bounds checking) |
operator[](int index) | at(size_t index) (bounds checking) |
setsize(int newsize) | resize(size_t newsize) |
To change your code from using the nonstandard Compaq C++ stack to the STL stack, consider the following actions:
Nonstandard Stack | STL Stack |
---|---|
size_used() | Does not exist because the size() function always is equal to the size_used() function. |
full() | Does not exist because the stack always is full. |
pop() |
Does not return the popped element. To simulate nonstandard stack
behavior, first get the element as the return type from the
top()
function and then call the
pop()
function. For example, change:
int i=s.pop();
to the following:
int i=s.top(); |
The STL Tutorial and Reference Guide (the Guide) is based on
the STL implementation provided by the Hewlett-Packard Company. Because
the Compaq C++ STL incorporates changes from the ANSI C++ draft, the
two implementations differ slightly. Differences also exist because the
Compaq C++ compiler does not currently support all of the new
language features specified in the ANSI C++ draft; refer to
Section 7.3 for the list of missing language features. This section
discusses the remaining differences.
7.4.3.1 Header File Names
The header file names shown in the STL Tutorial and Reference Guide differ from the Compaq C++ header file names, as shown in the following table:
Names Used in the Guide | Names Supplied by Compaq C++ |
---|---|
algo.h | Divided into algorithm and numeric |
deque.h | deque |
function.h | functional |
iterator.h | iterator |
list.h | list |
multiset.h | set |
map.h | map |
multimap.h | map |
set.h | set |
stack.h | Divided into stack and queue |
vector.h | vector |
The STL Tutorial and Reference Guide states that you need to compile the run-time .cpp files that are provided with the Hewlett-Packard implementation, such as random.cpp and tempbuf.cpp .
Compaq C++ already provides this run-time support in an object
library and automatically links this library into your application;
therefore, you can ignore the Guide's comments about compiling this
support.
7.4.3.3 Guide Examples Need to Be Modified
The STL Tutorial and Reference Guide contains many example programs. Appendix B of the Guide shows a World Wide Web address (active as of this printing) from which you can copy these example programs. Because of the differences outlined in the previous sections, these example programs must be modified to work with the Compaq C++ STL. To perform the necessary modifications, Compaq C++ provides the following procedure:
sys$common:[syshlp.examples.cxx]update_stl_book_examples.com |
Before running this procedure, copy and prepare the example programs. Use the following steps as guidance:
ftp://ftp.digital.com/pub/VMS/unzip-vax.exe |
ftp://ftp.digital.com/pub/VMS/unzip-axp.exe |
$ unzip :== $sys$login:unzip-vax.exe $ unzip diction.zip $ unzip examples.zip |
$ unzip :== $sys$login:unzip-axp.exe $ unzip diction.zip $ unzip examples.zip |
$ @sys$common:[syshlp.examples.cxx]update_stl_book_examples.com |
Now that your example programs are ready, compile and link them with the following commands:
$ cxx/exception/template_define/assume=(noheader_type_default,- writable_string_literals) ex.cpp $ cxxlink ex.obj |
To link ex17-01 , you must compile screen.cpp and shape.cpp and link with the resulting object files.
The header file, bstring.h , which is included with the example programs, is based on the string library as defined by an old version of the ANSI C++ draft. Compaq recommends that you do not use this header file and instead use the <string> header provided by Compaq C++. |
This section describes functional differences between the Compaq C++ STL and the STL Tutorial and Reference Guide by chapter.
assign(size_type position, const T& value) |
The Compaq C++ STL description of the reverse_iterator type definition differs from the description in §18.9 of the Guide as follows:
typedef reverse_iterator<RandomAccessIterator, T, Reference, Pointer, Distance> self; |
a.clear() |
a.assign(q1, q2) |
a.assign(n, t) |
See also Section 7.5.5 for differences between the Guide string class
and the Compaq C++ Standard String Library.
7.4.4 Optional Switch to Control Buffering
The inplace_merge, stable_sort and stable_partition algorithms require the use of a temporary buffer. Two methods are available for allocating this buffer:
By default, the current Compaq C++ library makes use of the preallocated buffer, which avoids the overhead of run-time allocation. If your application requires a buffer that exceeds 16K, it can not take advantage of this default.
If you are concerned with minimizing the use of stack space in your program, or if your application requires a buffer that exceeds 16K, define the __DEC_DYN_ALLOC macro to enable dynamic buffering. Do this by adding the following to your compile command line:
/define=__DEC_DYN_ALLOC |
Compaq C++ provides an implementation of the basic_string Library that consists of the basic_string template class, with parameters for the following:
This manual refers to the new standard String class implementation in Compaq C++ as the basic_string Library. This is in contrast with an earlier (still maintained) implementation known as the String Package. |
The basic_string Library also declares a string typedef to represent the typical usage, which is a string of normal (skinny) characters. For example:
#include <string> string str("abc"); // create a string containing "abc" str.append('d'); // str now contains "abcd" cout << s << endl; // print str to cout |
The wide character typedef (
wstring
) is not yet supported.
7.5.1 The basic_string Member Functions
The basic_string class can be used as character text, as an array of
characters, or as an STL-like sequence of characters. The string member
functions described below support these alternative uses.
7.5.1.1 Constructors/Destructors/Assignment
basic_string(const Allocator& a = Allocator());
Constructs an empty string.basic_string(const basic_string& str, size_type pos = 0, size_type n = npos, const Allocator& a = Allocator());
Constructs a string by copying all elements from str, starting at position pos in str and ending at position pos + n.basic_string(const charT* s,size_type n,const Allocator& a = Allocator());
basic_string(const charT* s, const Allocator& a = Allocator());
Constructs a string from s. If n is supplied it only copies the first n characters from s.basic_string(size_type n, charT c, const Allocator& a = Allocator());
Constructs a string with n copies of c, that is: string(4,'a') would construct a string of aaaa .basic_string(iterator begin, iterator end, const Allocator& a = Allocator());
Constructs a string from the characters between begin and end.~basic_string();
Destroys the string and frees all associated memory.basic_string& operator=(const basic_string& str);
basic_string& operator=(const charT* s);basic_string& operator=(charT c);
Assigns str, s or c to the current string.
size_type size() const;
size_type length() const;
Returns a count of the number of characters in the string.size_type max_size() const;
Specifies the maximum number of elements that can be in the string, usually limited by the amount of available memory.void resize(size_type n);
If n is less than the current value of size() , resize() truncates the string to length n. If n is greater than the current value of size() , resize() expands the string to length n and pads the string with null characters.void resize(size_type n, charT c);
If n is less than the current value of size() , resize() truncates the string to length n. If n is greater than the current value of size() , resize() expands the string to length n and pads the string with c characters.size_type capacity() const;
Returns the number of elements allocated in the string.void reserve(size_type res_arg);
Reallocates the string if the current capacity is less than res_arg. Invalidates all iterators, pointers and references to the string.bool empty() const;
Returns true if length is zero, otherwise returns false.
charT operator[](size_type pos) const;
reference operator[](size_type pos);charT at(size_type pos) const;
The subscript operator returns the character at position pos in the string. The at() function is similar except it throws an out-of-range exception if pos is invalid, that is, if it is greater than the current length of the string.
reference at(size_type pos);
basic_string& operator+=(const basic_string& str);
basic_string& operator+=(const charT* s); basic_string& operator+=(charT c);basic_string& append(const basic_string& str);
Appends str, s or c to the string and returns *this .
basic_string& append(const charT* s);basic_string& append(const basic_string& str,size_type pos,size_type n);
Appends a string constructed by copying all elements from str onto the string, starting at position pos in str and ending at position pos + n. Returns *this .basic_string& append(const charT* s, size_type n);
Appends onto the string the string created from the first n characters of s. Returns *this .basic_string& append(size_type n, charT c);
Appends onto the string n number of the value of c. Returns *this .basic_string& append(iterator first, iterator last);
Appends onto the current string the string constructed from the elements in the range first to last. Returns *this .basic_string& assign(const basic_string& str);
basic_string& assign(const charT* s);
Assigns str or s to the current string. Returns *this .basic_string& assign(const basic_string& str,size_type pos, size_type n);
Assigns a string constructed by copying onto the current string all elements from str, starting at position pos in str and ending at position pos + n Returns *this .basic_string& assign(const charT* s, size_type n);
Assigns the string created from the first n characters of s to the current string. Returns *this .basic_string& assign(size_type n, charT c);
Assigns n number of values of c to the string. Returns *this .basic_string& assign(iterator first, iterator last);
Assigns the string constructed from the elements in in the range first to last. Returns *this .basic_string& insert(size_type pos1, const basic_string& str);
Inserts str into the string after position pos1. Returns *this . If pos1 is greater than the size of the string, this function throws a length-error exception. Returns *this .basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n);
Inserts into the string after position pos1 the elements of str beginning at position pos2 and ending at either pos2+n or the end of str (whichever is smallest). If pos1 is greater than the size of the string or pos2 is greater than the size of str, this function throws a length-error exception. Returns *this .basic_string& insert(size_type pos,const charT* s);
Inserts the character string s into the string beginning after position pos. Returns *this .basic_string& insert(size_type pos, const charT* s, size_type n);
Inserts the first n characters of the character string s into the string after position pos. Returns *this .basic_string& insert(size_type pos, size_type n, charT c);
Inserts n copies of the character c into the string after position pos. Returns *this .iterator insert(iterator p, charT c);
Inserts the character c into the string before the character referred to by p and returns an iterator pointing at the element immediately following p prior to the element being inserted.void insert(iterator p, size_type n, charT c);
Inserts the n copies of the character c into the string before the character referred to by p.void insert(iterator p, iterator first, iterator last);
Inserts before the character referred to by p the characters in the string from first up to but not including lastbasic_string& erase(size_type pos = 0, size_type n = npos);
Erases from the string the characters beginning at position pos and ending at position n. Returns *this .iterator erase(iterator pos);
Erases the character in the string at pos and returns an iterator pointing at the element immediately following p prior to the element being erased.iterator erase(iterator first, iterator last);
Erases the characters in the string from first up to but not including last and returns an iterator pointing at the element immediately following last prior to the element being erased.basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
Removes the characters in the string from pos1 to pos1+n1 or to the end of the string (whichever is smaller). Inserts str into the string at pos1. Returns *this . If pos1 is greater than the size of the string, this function throws an out-of-range exception.basic_string& replace(size_type pos1,size_type n1, const basic_string& str,size_type pos2,size_type n);
Removes the characters in the string from pos1 to pos1+n1 or to the end of the string (whichever is smaller). Inserts the string created by using the characters in str from pos2 to pos2+n or the end of str (whichever is less) into the string at pos1. Returns *this . If pos1 is greater than the size of the string or pos2 is greater than str, this function throws an out-of-range exception. If the size() of the string minus the size of the string to be removed is greater than the npos minus the size of the string to be inserted, this function throws an length-error exception.basic_string& replace(size_type pos1,size_type n1,const charT* s);
Removes the characters in the string from pos1 to pos1+n1 or to the end of the string (whichever is smaller). Inserts s into the string at pos1. Returns *this . If pos1 is greater than the size of the string, this function throws an out-of-range exception.basic_string& replace(size_type pos1,size_type n1,const charT* s,size_type n2);
Removes the characters in the string from pos1 to pos1+n1 or to the end of the string (whichever is smaller). Inserts the string created by copying the first n2 characters of s into the string at pos1. Returns *this . If pos1 is greater than the size of the string, this function throws an out-of-range exception.basic_string& replace(size_type pos1,size_type n1,size_type n2,charT c);
Removes the characters in the string from pos1 to pos1+n1 or to the end of the string (whichever is smaller). Inserts the string created by copying the first n2 characters of the character c into the string at pos1. Returns *this . If pos1 is greater than the size of the string, this function throws an out-of-range exception.basic_string& replace(iterator i1, iterator i2, const basic_string& str);
Removes the characters in the range i1 to i2 and inserts str at i1. Returns *this .basic_string& replace(iterator i1, iterator i2, const charT* s);
Removes the characters in the range i1 to i2 and inserts s at i1. Returns *this .basic_string& replace(iterator i1, iterator i2, const charT* s, size_type n);
Removes the characters in the range i1 to i2 and inserts n characters of s at i1. Returns *this .basic_string& replace(iterator i1, iterator i2, size_type n, charT c);
Removes the characters in the range i1 to i2 and inserts n copies of the character c at i1. Returns *this .basic_string& replace(iterator i1, iterator i2, iterator i3, iterator i4);
Removes the characters in the range i1 to i2 and inserts the characters in the range i3 to i4. Returns *this .size_type copy(charT* s, size_type n, size_type pos = 0) const;
Replaces s with the elements from the string beginning at position pos and ending at either pos+n or the end of the string (whichever is smaller). If pos is greater than the value of size() , this function throws an out-of-range exception. It returns the size of the new string s. Before calling the copy() function, s must have already been allocated to have as least as many elements as needed to hold the results of the copy.void swap(basic_string<charT,traits,Allocator>& s);
Swaps the contents (that is, the data members) of s and *this .
const charT* c_str() const;
const charT* data() const;
Returns a pointer to the char* representation of the string.const allocator_type& get_allocator() const;
Returns a reference to the string's allocator object.size_type find(const basic_string& str, size_type pos = 0) const;
Returns the lowest position at which str is embedded in the string starting at position pos in the string, if no such position exists, the function returns npos.size_type find(const charT* s, size_type pos = 0) const;
Returns the lowest position at which s is embedded in the string starting at position pos in the string, if no such position exists, the function returns npos.size_type find(charT c, size_type pos = 0) const;
Returns the lowest position at which c is embedded in the string starting at position pos in the string, if no such position exists, the function returns npos.size_type find(const charT* s, size_type pos, size_type n) const;
Returns the lowest position at which the first n characters of s are embedded in the string starting at position pos in the string, if no such position exists, the function returns npos.The function rfind() is similar to the find() function except that it returns the highest position in the string.
size_type find_first_of(const basic_string<charT, traits, Allocator>& str, size_type pos = npos);
Returns the first position in the string that one of the characters contained in the argument str matches. For example:
string s = "abcdef"; size_t index = s.find_first_of("cehb"); // index of 'b' is 2If the pos argument is supplied, no character in the string beyond position pos will be considered.
size_type find_first_of(const charT* s, size_type pos = npos);
Calls the find_first_of() function (described above) constructing the str argument from s.size_type find_first_of(const charT* s, size_type pos, size_type n);
Calls the find_first_of() function (described above) constructing the str argument from the first n characters of s.size_type find_first_of(charT c, size_type pos = npos);
Calls the find_first_of() function (described above) constructing the str argument from the character c.size_type find_last_of(const basic_string<charT, traits, Allocator>& str, size_type pos = npos);
Returns the last position in the string that one of the characters contained in the argument str matches. For example:
string s = "abcdef"; size_t index = s.find_last_of("cehb"); // index of 'e' is 4If the pos argument is supplied, no character in the string beyond position pos will be considered.
size_type find_last_of(const charT* s, size_type pos = npos);
Calls the find_last_of() function (described above) constructing the str argument from s.size_type find_last_of(const charT* s, size_type pos, size_type n);
Calls the find_last_of() function (described above) constructing the str argument from the first n characters of s.size_type find_last_of(charT c, size_type pos = npos);
Calls the find_last_of() function (described above) constructing the str argument from the character c.The find_first_not_of() and find_last_not_of() functions are similar to the functions described above except that they return the first (or last) position of one of the characters NOT in the string. For example:
string s = "abcdef"; size_t index = s.find_last_not_of("cfehb"); // index of 'd' is 4 index = s.find_first_not_of("cda"); // index of 'b' is 2basic_string substr(size_type pos = 0, size_type n = npos) const;
Returns the substring starting at pos of length n. If pos is greater than the current size of the string, this function throws an out-of-range exception.int compare(const basic_string& str);
Compares each corresponding character starting at the beginning of the string and str. The number of elements used for the comparison is the smaller of the size of str or the size of the string. If the character in the string is less than the corresponding character in str, a negative value is returned. If the character in the string is greater than the corresponding character in str, a positive value is returned. If all of the elements are equal a negative value is returned if the value of the size of the string is less than the size of str, 0 if they are equal, and a positive value of the size of the string is greater than the size of str.int compare(charT* s) const;
Calls the compare() function (described above) by constructing the string str out of s.int compare(size_type pos, size_type n1, charT* s,size_type n2 = npos);
Calls the compare() function (described above). The string to compare is created from the first n1 elements of the string beginning at position pos and the argument str is created from the first n2 elements of s.int compare(size_type pos, size_type n1, const basic_string& str);
Calls the compare() function (described above). The string to compare is created from the first n1 elements of the string beginning at position pos and is compared to str.int compare(size_type pos, size_type n1, const basic_string& str, size_type pos2, size_type n2);
Calls the compare() function (described above). The string to compare is created from the first n1 elements of the string beginning at position pos and the argument str is created from the first n2 elements of str beginning at position pos2.
iterator begin();
const_iterator begin() const;iterator rbegin();
Returns a random access iterator. Dereferencing the return value will give the character at the beginning of the string. The iterator returned by the begin() function will move forward through the string with operator++, and the rbegin() will move forward through the string with operator -- .
const_iterator rbegin() const;iterator end();
const_iterator end() const;iterator rend();
Returns a random access iterator to one-past the end of the string. Dereferencing the return value--1 will give the character at the end of the string. The iterator returned by the end() function will move backward through the string with operator -- , and the rend() will move backward through the string with operator++.
const_iterator rend() const;The following is an example of a simple use of iterators:
#include <string> string str("azbzc"); int count = 0; // count the number of z's for (string::iterator iter = str.begin(); iter!= str.end(); iter++) if ((*(iter)=='z') count++;
The following operator+ functions return the string constructed from adding the character or characters in lhs to the character or characters in rhs:
template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+( const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+( const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const charT lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+( const basic_string<charT, traits, Allocator>& lhs, const charT rhs); |
The following operator== functions return a value of TRUE if lhs == rhs, where lhs and rhs are converted into strings if necessary; otherwise, the following return a value of FALSE:
template <class charT, class traits, class Allocator> bool operator==( const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> bool operator==( const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); |
The following operator!= functions return a value of TRUE if lhs != rhs, where lhs and rhs are converted into strings if necessary; otherwise, the following return a value of FALSE:
template <class charT, class traits, class Allocator> bool operator!=( const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> bool operator!=( const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); |
The following operator< functions return a value of TRUE if lhs < rhs, where lhs and rhs are converted into strings if necessary; otherwise, the following return a value of FALSE:
template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator<( const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator<(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator<( const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); |
The following operator> functions return a value of TRUE if lhs > rhs, where lhs and rhs are converted into strings if necessary; otherwise, the following return a value of FALSE:
template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator>( const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator>(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator>( const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); |
The following operator<= functions return a value of TRUE if lhs <= rhs, where lhs and rhs are converted into strings if necessary; otherwise, the following return a value of FALSE:
template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator<=( const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator<=( const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); |
The following operator>= functions return a value of TRUE if lhs >= rhs, where lhs and rhs are converted into strings if necessary; otherwise, the following return a value of FALSE:
template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator>=( const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template <class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator>=( const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); |
The following swaps the contents (that is, the data members) of lhs and rhs:
template <class charT, class traits, class Allocator> void swap(basic_string<charT, traits, Allocator>& lhs, basic_string<charT, traits, Allocator>& rhs); |
The following extracts characters from stream is into str until either end-of-file occurs on is or whitespace is encountered in is; Any leading whitespace is skipped and str is erased before the extraction:
template <class charT, class STR_traits, class STR_Alloc> istream& operator>>(istream& is, basic_string<charT,STR_traits,STR_Alloc>& str) |
The following writes str into the output stream os:
template <class charT, class STR_traits, class STR_Alloc> ostream& operator<<(ostream& os, const basic_string<charT,STR_traits,STR_Alloc> & str) |
The following extracts up until the delim (or end-of-file) into the is; it does not skip leading whitespace and str is erased before the extraction:
template <class charT, class STR_traits, class STR_Alloc> istream& getline(istream& is, basic_string<charT,STR_traits,STR_Alloc>& str, charT delim = '\n') |
7.5.3 The basic_string typedefs
The following typedefs are provided in the basic_string class:
traits
Is the type used to represent the character traits class used in the string. The traits class provides character primitives such as assignment, comparison, find() , length() , copy() , move() , and assign() .value_type
Is the type of the charT elements in the string, for example char or wchar_t .allocator_type
Is the type of the allocator. The default is allocator<value_type> .size_type
Is the type used to represent the index into the string. The default is size_t .difference_type
Is the type used to represent the result of arithmetic operations on the iterators. The default is ptrdiff_t .reference
const_reference
Is the type used to represent a reference (or const reference) of value_type .pointer
const_pointer
Is the type used to represent a pointer (or const pointer) to value_type .iterator
const_iterator
Is the type used to iterate over elements of the string.reverse_iterator
const_reverse_iterator
Is the type used to iterate over elements of the string. This typedef differs from iterator in that ++ will move backward through the string and -- will move forward through the string.
The Compaq C++ basic_string Library is designed to replace the nonstandard Compaq C++ String Package.
The following discussion guides you through upgrading nonstandard code to use the new basic_string Library.
string s("abc"); char* cp = s; // not allowed const char* cp = s.data(); // ok |
template <class charT, class traits, class Allocator> inline basic_string<charT, traits, Allocator> upper(const basic_string<charT,traits, Allocator>& str) { basic_string<charT, traits, Allocator> newstr(str); for (size_t index = 0; index < str.length(); index++) if (islower(str[index])) newstr[index] = toupper(str[index]); return newstr; } template <class charT, class traits, class Allocator> inline basic_string<charT, traits, Allocator> lower(const basic_string<charT,traits, Allocator>& str) { basic_string<charT, traits, Allocator> newstr(str); for (size_t index = 0; index < str.length(); index++) if (isupper(str[index])) newstr[index] = tolower(str[index]); return newstr; } |
s2 = s1.upper(); // does not compile s2 = upper(s1); // ok |
string s1("abcdef"); string s2("abcdgf"); assert(s1.match(s2)==4); // does not compile pair<string::iterator,string::iterator> p(0,0); // ok p=mismatch(s1.begin(),s1.end(),s2.begin()); assert(p.first-s1.begin()==4); string s3 = s1; p=mismatch(s1.begin(),s1.end(),s3.begin()); assert(p.first == s1.end()); // everything matched |
string s("abcde"); string s2 = s1(1,3); // does not compile string s2 = s1.substr(1,3); // ok |
This section describes differences between the Compaq C++ basic_string Library and the string class described in the STL Tutorial and Reference Guide (the Guide string class). The Guide string class was included with the original STL implementation provided by the Hewlett-Packard Company.
The major difference between the basic_string Library and the Guide string class is that the basic_string Library can be treated directly as an STL container. The Guide string class can be used as an STL container only if you explicitly apply the conversion operator to vector<char> . For example:
// string class in the Guide #include <bstring.h> #include <vector.h> main() { vector<char> v = string("Hello"); // call an STL algorithm sort(v.begin(),v.end()); for (vector<char>::iterator iter = v.begin(); iter!= v.end(); iter++) cout << (*iter) ; cout << endl; } // equivalent code using the basic_string Library #include <string> main() { string s("Hello"); // call an STL algorithm sort(s.begin(),s.end()); for (string::iterator iter = s.begin(); iter!= s.end(); iter++) cout << (*iter) ; cout << endl; } |
A minor difference is that the basic_string Library uses the header file <string> not <bstring.h> . Also, the header file <bstring.h> automatically included <vector> whereas <string> does not.
The basic_string Library is also fully functional; that is, it supports
the functions
size()
,
at()
, and
swap()
, plus those member functions that take STL iterators as arguments.
7.6 Numeric Limits Class
The Numeric Limits class represents information about arithmetic types. For each arithmetic type, the class provides a combination of the information that can be found in the following:
Not all of the information provided by the class members is meaningful
for all types. Any value which is not meaningful for a type is set to 0
or false.
7.6.1 The numeric_limits Template Class
A synopsis of the numeric_limits class follows.
template<class T> class numeric_limits { public: static const bool is_specialized = false; inline static T min() throw(); inline static T max() throw(); static const int digits = 0; static const int digits10 = 0; static const bool is_signed = false; static const bool is_integer = false; static const bool is_exact = false; static const int radix = 0; inline static T epsilon() throw(); inline static T round_error() throw(); static const int min_exponent = 0; static const int min_exponent10 = 0; static const int max_exponent = 0; static const int max_exponent10 = 0; static const bool has_infinity = false; static const bool has_quiet_NaN = false; static const bool has_signaling_NaN = false; static const bool has_denorm = false; static const bool has_denorm_loss = false; inline static T infinity() throw(); inline static T quiet_NaN() throw(); inline static T signaling_NaN() throw(); inline static T denorm_min() throw(); static const bool is_iec559 = false; static const bool is_bounded = false; static const bool is_modulo = false; static const bool traps = false; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; |
Specializations are provided for the following types:
numeric_limits<char> numeric_limits<signed char> numeric_limits<unsigned char> numeric_limits<short> numeric_limits<int> numeric_limits<long> numeric_limits<unsigned short> numeric_limits<unsigned int> numeric_limits<unsigned long> numeric_limits<float> numeric_limits<double> numeric_limits<long double> |
Note that the ANSI C++ September 1996 draft includes specializations for the bool and wchar_t types as follows:
numeric_limits<bool> numeric_limits<wchar_t> |
However, due to lack of support for these types in the current
Compaq C++ compiler, specializations for them are not provided in
the library.
7.6.2 Numeric Limits Class Member Functions
static T min() throw();
This function returns the minimum finite value. Its return value is equivalent to CHAR_MIN , SHRT_MIN , FLT_MIN , DBL_MIN , and so forth. For floating types with denormalization, the function returns the minimum positive normalized value. This function is meaningful for specializations where is_bounded is not equal to false or is_bounded is equal to false and is_signed is equal to false.static T max() throw();
This function returns the maximum finite value. Its return value is equivalent to CHAR_MAX , SHRT_MAX , FLT_MAX , DBL_MAX , and so forth. The function is meaningful for all specializations in which is_bounded is not equal to false.static T epsilon() throw();
This function returns machine epsilon. Its return value is equivalent to FLT_EPSILON , DBL_EPSILON , or LDBL_EPSILON . The function is meaningful for all floating point types.static T round_error() throw();
This function returns the maximum rounding error.static T infinity() throw();
This function returns the representation of positive infinity if it is available. The function is meaningful for all specializations for which has_infinity is true. It is required by specializations for which is_iec559 is true.static T quiet_NaN() throw();
This function returns the representation of a quiet Not a Number if it is available. The function is meaningful for all specializations where has_quiet_NaN is not false. It is is required in specializations where is_iec559 is true.static T signaling_NaN() throw();
This function returns the representation of a signaling Not a Number if it is available. The function is meaningful for all specializations where has_signaling_NaN is not false. It is required in specializations for which is_iec550 is true.static T denorm_min() throw();
This function returns the minimum positive denormalized value. It is meaningful for all floating point types. It is required in specializations for which has_denorm is false.
const bool is_specialized;
This data member is used to distinguish between types that have specializations and types that do not. If a specialization exists is_specialized is true, otherwise it is false.const int digits;
This data member indicates the number of radix digits that can be represented. For integer types this is the number of nonsign bits in the representation. For floating point types this is the number of radix digits in the mantissa and is equivalent to FLT_MANT_DIG , DBL_MANT_DIG , or LDBL_MANT_DIG .const int digits10;
This data member indicates the number of base 10 digits that can be represented without change. It applies to all specializations where is_bounded is true. For floating point types digits10 is equivalent to FLT_DIG , DBL_DIG , or LDBL_DIG .const bool is_signed;
This data member indicates whether a type is signed or not. It applies to all specializations.const bool is_integer;
This data member indicates whether a type is an integer or not. It applies to all specializations.const bool is_exact;
This data member is true if a type has an exact representation. All integer types are exact. It applies to all specializations.const int radix;
For floating types this data member specifies the base or radix of the exponent and is equivalent to FLT_RADIX . For integer types it specifies the base of the representation.const int min_exponent;
This data member indicates the minimum negative integer such that radix raised to the power of one less than that integer is a normalized floating point number. It applies to all floating types and is equivalent to FLT_MIN_EXP , DBL_MIN_EXP , or LDBL_MIN_EXP .const int min_exponent10;
This data member indicates the minimum negative integer such that 10 raised to that power is in the range of normalized floating point numbers. It applies to all floating types and is equivalent to FLT_MIN_10_EXP , DBL_MIN_10_EXP , or LDBL_MIN_10_EXP .const int max_exponent;
This data member indicates the maximum positive integer such that radix raised to the power one less than that integer is a representable finite floating point number. It applies to all floating types and is equivalent to FLT_MAX_EXP , DBL_MAX_EXP , or LDBL_MAX_EXP .const int max_exponent10;
This data member indicates the maximum positive integer such that 10 raised to that power is in the range of representable finite floating point numbers. It applies to all floating types and is equivalent to FLT_MAX_10_EXP , DBL_MAX_10_EXP , or LDBL_MAX_10_EXP .const bool has_infinity;
This data member is true if the type has a representation for positive infinity. It applies to all floating types.const bool has_quiet_NaN;
This data member is true if the type has a quiet (that is, nonsignaling) Not a Number . It applies to all floating types.const bool has_signaling_NaN;
This data member is true if the type supports a signaling Not a Number . It applies to all floating types.const bool has_denorm;
This data member is true for types that support denormalized values. It applies to all floating types.const bool has_denorm_loss;
This data member is true if loss of accuracy is detected as a denormalization loss, rather than as an inexact result.const bool is_iec559;
This data member is true if the type adheres to the International Electrotechnical Commission (IEC) 559 standard. It applies to all floating types.const bool is_bounded;
This data member is true if the set of values represented by the type is finite. All built-in types are bounded. It applies to all specializations.const bool is_modulo;
This data member is true if a type is modulo. A type is modulo if you can add two positive numbers and have a result that wraps around to a number less than the two operands. This data member is usually false for floating types, true for unsigned integers and true for signed integers on most machines. It applies to all specializations.const bool traps;
This data member is true if the type supports trapping. It applies to all specializations.const bool tinyness_before;
This data member is true if tinyness is detected before rounding. It applies to all floating types.const float_round_style round_style;
This data member indicates the rounding style for the type. It applies to all floating types. Specializations for integer types return round_toward_zero . See Section 7.6.4 for possible values.
enum float_round_style
This data type is used to indicate the rounding mode for floating point arithmetic. It contains the following values:
Value Rounding Style round_indeterminate Indeterminable round_toward_zero Toward zero round_to_nearest To the nearest representable value round_toward_infinity Toward infinity round_neg_infinity Toward negative infinity
The auto_ptr class provides a simple class for smart pointers; it stores a pointer to an object obtained by way of the new operator and deletes that object when the auto_ptr object is destroyed. The auto_ptr class provides semantics of strict ownership. After construction an auto_ptr object owns the object whose pointer it holds. When an instantiation of auto_ptr is copied, ownership of the object is transferred to the destination auto_ptr. The behavior is undefined if more than one instantiation of auto_ptr owns the same object at the same time.
The ANSI C++ September 1996 auto_ptr class makes use of member
templates for its copy constructor and assignment operator. Because the
current Compaq C++ compiler does not support member templates,
auto_ptr does not make use of them for copy construction or assignment
operations.
7.7.1 The auto_ptr Member Functions
explicit auto_ptr(T* p=0) throw();
Constructs an object of class auto_ptr<T>. The pointer held by the auto_ptr class is initialized to p. The p variable points to an object of type T or a class derived from T for which delete p is defined and accessible, or p is a null pointer.auto_ptr(const auto_ptr<T>& a) throw();
Constructs an object of class auto_ptr<T>. The argument a is copied to *this . If a owns the held pointer, ownership is transferred to *this .auto_ptr<T>& operator=(const auto_ptr<T>& rhs) throw();
The argument rhs is copied to *this . If rhs owns the held pointer, ownership is transferred to *this . If *this already owns a pointer (not equal to the pointer owned by rhs), that held pointer is deleted first.~auto_ptr();
If *this owns the held pointer, the pointer is deleted.T& operator*() const throw();
Returns a reference to the object to which the underlying held pointer points.T* operator->() const throw();
Returns the underlying held pointer.T* get() const throw();
Returns the underlying held pointer.T* release() throw();
Returns the underlying held pointer after releasing ownership of it.
The standard exception classes are all classes derived from the exception class and are used in the standard library to report errors detected during program execution. A simple example of using this class follows:
#include <stdexcept> #include <string> int main() { try { string s("abc"); if (s.at(4)=='d') ; // out of range } catch(const exception& e) { cout << e.what() << endl; } catch(...) { cout << "unknown exception" << endl; } } |
The output from this example is as follows:
position beyond end of string |
Users may also use the standard exception hierarchy to report errors in
their own classes.
7.8.1 Types of Standard Exceptions
All standard exceptions are rooted at the base class exception. No standard library errors are of type exception (they are always of a more specific or derived type). This class is simply used as base class when a user wants to catch all standard exceptions, as in the previous example.
The six classes derived from exception are: logic_error, runtime_error, bad_exception, bad_alloc, bad_cast, and bad_typeid.
The logic_error class has four derived classes:
domain_error (used to report domain errors)
invalid_argument (used to report invalid arguments)
length_error (used to report an attempt to produce an object whose length exceeds it maximum allowable size)
out_of_range (used to report an argument value not in its expected range)
The runtime_error class has three derived classes:
range_error (used to report errors in internal computations)
overflow_error (used to report an arithmetic overflow error)
underflow_error (used to report an arithmetic underflow error)
exception() throw();
Constructs an object of class exception.exception(const exception&) throw();
Copies an exception object.exception& operator=(const exception&) throw();
Assigns an exception object.virtual ~exception() throw();
Destroys the exception object.virtual const char* what() const throw();
Returns a null-terminated byte string that contains information about the type of error. The contents of the string are implementation dependent. In the Compaq C++ library the string contains an indication of the problem --- that is, string index out of range or invalid string size parameter .
All of the standard exception classes are derived from class exception; thus, they inherit all of the exception class member functions. The only difference is in the constructor---all have an overridden constructor that takes a string argument; that is:
class logic_error: public exception { public: logic_error(const string& what_arg); }; class domain_error: public logic_error { public: domain_error(const string& what_arg); }; class invalid_argument: public logic_error { public: invalid_argument(const string& what_arg); }; class length_error: public logic_error { public: length_error(const string& what_arg); }; class out_of_range: public logic_error { public: out_of_range(const string& what_arg); }; class runtime_error: public exception { public: runtime_error(const string& what_arg); }; class range_error: public runtime_error { public: range_error(const string& what_arg); }; class overflow_error: public runtime_error { public: overflow_error(const string& what_arg); }; class underflow_error: public runtime_error { public: underflow_error(const string& what_arg); }; |
A complex number has a real part and an imaginary part. The standard
complex library utilizes templates, so that any underlying type can be
used to represent these parts. Template specializations are provided
for float, double, and long double.
7.9.1 Example of Use
A simple example of use is:
#include <complex> int main() { complex<double> c1(1,1), c2(3.14,3.14); cout << "c2/c1: " << c2/c1 << endl; } |
Note that you must explicitly link the sys$share:cma$open_rtl.exe library to access the math routines; that is:
cxxlink prog,sys$input:/opt sys$share:cma$open_rtl.exe/share <Ctrl Z> |
complex(const T& re = T(), const T& im = T());
Constructs an object of type complex with the real part set to re and the imaginary part set to im.complex(const complex<T>& c);
Constructs a complex number by copying all elements from c.complex<T>& operator=(const complex<T>& c);
Assigns c to *this and returns *this .complex<T>& operator=(const T& c);
Assigns c to the real part of *this . Sets the imaginary part of *this to zero and returns *this .complex<T>& operator+=(const complex<T>& c);
Adds c to *this and then returns the result.complex<T>& operator-=(const complex<T>& c);
Subtracts c from *this and then returns the result.complex<T>& operator*=(const complex<T>& c);
Multiplies c and *this and then returns the result.complex<T>& operator/=(const complex<T>& c);
Divides *this by c and then returns the result.T real();
Returns the real part of *this .T imag();
Returns the imaginary part of *this .
template <class T>
T real(const complex<T>& c);
Returns the real part of c.template <class T>
T imag(const complex<T>& c);
Returns the imaginary part of c.template <class T>
T abs(const complex<T>& c);
Returns the magnitude of c.template <class T>
T norm(const complex<T>& c);
Returns the squared magnitude of c.template <class T>
T arg(const complex<T>& c);
Returns the phase angle of c.template <class T>
complex<T> conj(const complex<T>& c);
Returns the complex conjugate of c.template <class T>
complex<T> polar(const T& rho, const T& theta = 0);
Returns the complex value corresponding to a complex number whose magnitude is rho and whose phase angle is theta.template <class T>
complex<T> cos(const complex<T>& c);
Returns the complex cosine of c.template <class T>
complex<T> cosh(const complex<T>& c);
Returns the complex hyperbolic cosine of c.template <class T>
complex<T> exp(const complex<T>& c);
Returns the complex base e exponential of c.template <class T>
complex<T> log(const complex<T>& c);
Returns the complex natural (base e) logarithm of x.template <class T>
complex<T> log10(const complex<T>& c);
Returns the complex common (base 10) logarithm of x.template <class T>
complex<T> pow(const complex<T>& x, int y); template <class T> complex<T> pow(const complex<T>& x, int y); template <class T> complex<T> pow(const complex<T>& x, const complex<T>& y);template <class T>
Returns the complex power of base x raised to the y-th power.
complex<T> pow(const complex<T>& x, const T& y); template <class T> complex<T> pow(const T& x, const complex<T>& y);template <class T>
complex<T> sin(const complex<T>& c);
Returns the complex sine of c.template <class T>
complex<T> sinh(const complex<T>& c);
Returns the complex hyperbolic sine of c.template <class T>
complex<T> sqrt(const complex<T>& c);
Returns the complex square root of c, in the range of the right half-plane.template <class T>
complex<T> tan(const complex<T>& c);
Returns the complex tangent of c.template <class T>
complex<T> tanh(const complex<T>& c);
Returns the complex hyperbolic tangent of c.
template <class T>
complex<T> operator+(const complex<T>& lhs, const T& rhs);template <class T>
Adds rhs to lhs and returns the sum.
complex<T> operator+(const T& lhs, const complex<T>& rhs);template <class T>
complex<T> operator+(const complex<T>& lhs, const T& rhs);template <class T>
Subtracts rhs from lhs and returns the difference.
complex<T> operator+(const T& lhs, const complex<T>& rhs);template <class T>
complex<T> operator*(const complex<T>& lhs, const T& rhs);template <class T>
Multiplies rhs and lhs and returns the product.
complex<T> operator*(const T& lhs, const complex<T>& rhs);template <class T>
complex<T> operator/(const complex<T>& lhs, const T& rhs);template <class T>
Divides rhs into lhs and returns the quotient.
complex<T> operator/(const T& lhs, const complex<T>& rhs);template <class T>
complex<T> operator==(const complex<T>& lhs, const T& rhs);template <class T>
Compares lhs to rhs and returns true if they are equal, otherwise returns false. The imaginary parts of the scalars are assumed to be the value T() .
complex<T> operator==(const T& lhs, const complex<T>& rhs);template <class T>
complex<T> operator!=(const complex<T>& lhs, const T& rhs);template <class T>
Compares lhs to rhs and returns true if they are not equal, otherwise returns false. The imaginary parts of the scalars are assumed to be T() .
complex<T> operator!=(const T& lhs, const complex<T>& rhs);template <class T, class charT, class traits>
istream& operator>>(istream& is, complex<T>& c);
Extracts a complex number c from the istream is of the form u , (u) , or (u,v) , where u is the real part and v is the imaginary part. If bad input is encountered, sets ios::failbit .template <class T, class charT, class traits>
ostream operator<<(ostream& os, const complex<T>& c);
Returns os << "(" << c.real() << "," << c.imag() << ")" .
typedef T value_type;
The type used to represent the real and imaginary parts of the complex number.
Because the Compaq C++ compiler does not yet support the
explicit
keyword (that is, nonconverting constructors), unsafe downcasts will be
allowed; that is, users can convert a
complex<double>
to a
complex<float>
.
7.9.7 Upgrading from the Nonstandard Complex Math Library
This section explains how to upgrade from the pre-ANSI Compaq C++ complex library to the current Compaq C++ standard complex library, which is based on the 24 September 1996 ANSI C++ working draft.
In the ANSI library, complex objects are templatized on the type of the real and imaginary parts, the pre-ANSI Compaq C++ library, complex objects are not templatized. The pre-ANSI library assumes the type is double, whereas the new library provides specializations for float, double, and long double, as well as allowing users to specialize on their own floating point types.
Also note that mathematical error checking is not supported in the ANSI library. Users who rely on detection of underflow, overflow, and divide by zero should continue using the pre-ANSI Compaq C++ complex library. The following is a detailed list of important changes:
complex c; |
complex<double> c; |
complex c; c = polar(c); // get polar |
complex<double> c; c = polar(c,0.0); |
complex c = polar(0,0); complex c2 = c+1; |
complex<double> c = polar(0.0,0.0); // 0.0 is double complex<double> c2= c + 1.0; // 1.0 is double |
static const complex<double> complex_zero(0.0,0.0); |
template <class T> inline complex<T> sqr(const complex<T>& a) { return complex<T>(real(a) * real(a) - imag(a) * imag(a), 2 * real(a) * imag(a)); } template <class T> inline T arg1(const complex<T>& a) { double val = arg(a); if(val > -M_PI && val <= M_PI) return val; if(val > M_PI) return val - (2*M_PI); // val <= -PI return val + (2*M_PI); } |
pow(c,1); |
pow(c,1.0); |
complex<double> c; cout << "(" << c.real() << ", " << c.imag() << ")"; // add extra space |
The Standard C++ Library defines an allocator class that is used to control the memory model containers will use. Every container class in the Standard C++ library takes an allocator as one of its template arguments. In this way each container can manage its own storage requirements. Containers can make use of different memory models by using allocators that implement different types of memory management schemes. A default allocator that makes use of the global new and delete is provided by the Standard library.
The allocator as defined in the 24 September 1996 draft C++ Standard makes use of member function templates and member class templates. The lack of member template support in the current version of Compaq C++ mandates the use of an allocator that does not utilize this feature. Therefore, the Compaq C++ library provides an alternate allocator class. The alternate allocator allocates raw bytes of storage. Its types and functions are provided by an allocator_interface class. Under this scheme the allocator makes use of the allocator_interface class to allocate typed storage rather than allocating itself directly. The implementation is not standard conforming so its use will be documented in this section.
Note that the current version of the Compaq C++ library also contains a specialization for void. The specialization for void does not conform to standard either. Please refer to the 24 September 1996 ANSI C++ draft for details on the ANSI C++ draft conforming allocator.
The rest of this section defines the allocator provided with the
current version of Compaq C++. It also describes how to build custom
allocators and containers that make use of this allocator class.
7.10.1 Allocator Class Member Functions
allocator();
Default allocator constructor.~allocator();
Allocator destructor.void * allocate (size_type n, void * = 0)
Allocate n*size_type bytes of storage.void deallocate (void* p)
Deallocate the storage pointed to by p.size_type max_size (size_type size) const
Returns the largest size for which allocate might succeed.
The allocator_interface class excepts two input parameters, an alternate allocator and the type of the objects to be allocated. The class has the following syntax:
template <class Allocator,class T> class allocator_interface { //... } |
allocator_interface();
Default constructor.allocator_interface(const Allocator& a);
Constructs an allocator_interface and stores the allocator object internally.pointer address (T& x);
Returns the address of the reference x as a pointer.size_type max_size () const;
Returns the largest size for which allocate() of an object of type T might succeed.pointer allocate(size_type n, pointer = 0)
Allocates n*sizeof(T) bytes of storage aligned appropriately of objects of type T. Throws bad_alloc if storage can not be obtained. The second parameter is intended to be used to allocate memory at a particular location.void deallocate(pointer p)
Deallocates the storage that p points to.void construct(pointer p, const T& val)
Constructs an object of type T with an initial value of val at the location specified by p.void destroy(T* p)
Calls the destructor on the object that p points to but do not delete the object.
Allocators can be designed to provide a customized memory management model. To do this, define an allocator that has the same interface as the library allocator.
The following is an example of a customized allocator class that supports the Compaq C++ allocator:
template <class T> class shared_allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; shared_allocator() {;} ~shared_allocator() {;} void * allocate(size_type n, void* = 0) { return (void*) new size_t[n]; } void deallocate (void *p) { delete(p); } size_type max_size (size_type size) const { return 1 > UINT_MAX/size ? size_type(1) : size_type(UINT_MAX/size); } }; // end shared_allocator<T> class shared_allocator<void> { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef void* pointer; typedef const void* const_pointer; typedef void value_type; shared_allocator() {;} ~shared_allocator() {;} void * allocate (size_type n, void * = 0) { return (void *) new size_t[n]; } void deallocate (void* p) { delete(p); } size_type max_size (size_type size) const { return 1 > UINT_MAX/size ? size_type(1) : size_type(UINT_MAX/size); } }; // shared_allocator<void> |
Custom allocators are easily used with existing standard library containers. You need only to provide an allocator type when you instantiate a container as follows:
vector <int, shared_allocator<int> > v1; list <int, shared_allocator<int> > l1; |
To implement custom containers, your container must define the following:
The following is a sample of what a container might look like:
template <class T, class Allocator> class my_container { private: typedef allocator_interface<Allocator,T> value_alloc_type; Allocator my_allocator; } Any member function which allocates elements needs to do: value_alloc_type(my_allocator).allocate(n,0); Any member function which deallocates elements needs to do: value_alloc_type(my_allocator).deallocate(p); |
Previous | Next | Contents | Index |
|