C++ Training Datascope Lawrence D’Antonio

363
Datascope Datascope Lawrence Lawrence D’Antonio D’Antonio Lecture 10 Lecture 10 An Overview of C++: An Overview of C++: The Standard Template The Standard Template Library Library

description

C++ Training Datascope Lawrence D’Antonio. Lecture 10 An Overview of C++: The Standard Template Library. Why Should You Learn STL?. STL is generic. It involves data structures and algorithms that are designed to work on as wide a range of data types as possible. - PowerPoint PPT Presentation

Transcript of C++ Training Datascope Lawrence D’Antonio

Page 1: C++ Training Datascope Lawrence D’Antonio

C++ TrainingC++ TrainingDatascopeDatascope

Lawrence D’AntonioLawrence D’AntonioLecture 10Lecture 10

An Overview of C++:An Overview of C++:The Standard Template LibraryThe Standard Template Library

Page 2: C++ Training Datascope Lawrence D’Antonio

Why Should You Learn STL?Why Should You Learn STL? STL is generic. It involves data structures STL is generic. It involves data structures

and algorithms that are designed to work and algorithms that are designed to work on as wide a range of data types as on as wide a range of data types as possible.possible.

STL is useful. It provides a variety of basic STL is useful. It provides a variety of basic tools that are easy to learn and to use. tools that are easy to learn and to use. STL has a well-designed architecture that STL has a well-designed architecture that provides a variety of algorithms that can provides a variety of algorithms that can manipulate a number of data structures.manipulate a number of data structures.

Page 3: C++ Training Datascope Lawrence D’Antonio

Why Should You Learn STL?Why Should You Learn STL? STL is efficient. STL algorithms come with STL is efficient. STL algorithms come with

performance guarantees. For example, insertion performance guarantees. For example, insertion into a map data structure is guaranteed to be at into a map data structure is guaranteed to be at most logarithmic.most logarithmic.

STL is extensible.The components of STL may STL is extensible.The components of STL may be put together to create powerful generic be put together to create powerful generic libraries. For example, there exists an MTL libraries. For example, there exists an MTL (Matrix Template Library), a GTL (Graph (Matrix Template Library), a GTL (Graph Template Library), and Regex++, a regular Template Library), and Regex++, a regular expression library based on STL.expression library based on STL.

Page 4: C++ Training Datascope Lawrence D’Antonio

What is STL?What is STL?

The Standard Template Library (STL) is a The Standard Template Library (STL) is a powerful collection of generic data powerful collection of generic data structures and algorithms that is part of the structures and algorithms that is part of the standard library in C++. The algorithms in standard library in C++. The algorithms in STL are orthogonal to the data structures, STL are orthogonal to the data structures, in the sense that algorithms are designed in the sense that algorithms are designed to work without having to know details of to work without having to know details of the data structures to which they are being the data structures to which they are being applied.applied.

Page 5: C++ Training Datascope Lawrence D’Antonio

What is STL? 2What is STL? 2

In order for this process to work, data In order for this process to work, data containers are required to define the containers are required to define the concept of an iterator (i.e., objects that concept of an iterator (i.e., objects that define an addressing mechanism for the define an addressing mechanism for the data structure). These iterators are used in data structure). These iterators are used in turn by the STL algorithms to access the turn by the STL algorithms to access the data structure. data structure.

Page 6: C++ Training Datascope Lawrence D’Antonio

What is STL? 3What is STL? 3 Different algorithms require different types Different algorithms require different types

of access. of access. For example, the generic sorting For example, the generic sorting

algorithms in the STL require random algorithms in the STL require random access. This restricts the data structures access. This restricts the data structures that sorting algorithms can be used with to that sorting algorithms can be used with to ones that provide random access (in the ones that provide random access (in the standard library this includes arrays, standard library this includes arrays, strings, vectors, and deques).strings, vectors, and deques).

Page 7: C++ Training Datascope Lawrence D’Antonio

What is STL? 4What is STL? 4

Alexander Stepanov, the primary Alexander Stepanov, the primary developer of the STL, identifies four developer of the STL, identifies four principles that underlie the design of STL.principles that underlie the design of STL.

Generic programmingGeneric programming Abstractness without loss of efficiencyAbstractness without loss of efficiency Von Neumann computational modelVon Neumann computational model Value semanticsValue semantics

Page 8: C++ Training Datascope Lawrence D’Antonio

Generic programmingGeneric programming

Generic programming can be thought of Generic programming can be thought of as writing software components that can as writing software components that can be used for as wide a range of types as be used for as wide a range of types as possible. possible.

Stepanov states that generic programming Stepanov states that generic programming attempts to find the most abstract form of attempts to find the most abstract form of an efficient algorithm.an efficient algorithm.

Page 9: C++ Training Datascope Lawrence D’Antonio

Generic programming 2Generic programming 2 The central abstraction in STL is that of the The central abstraction in STL is that of the

concept. A concept is a set of requirements for concept. A concept is a set of requirements for data types. data types.

For example, a Sequence is a concept For example, a Sequence is a concept describing data containers that store elements in describing data containers that store elements in a linearly ordered range and allow for insertion a linearly ordered range and allow for insertion or deletion at any point in that range. or deletion at any point in that range.

Any data structure fitting these requirements is a Any data structure fitting these requirements is a model for the Sequence concept. STL defines model for the Sequence concept. STL defines three sequence types; vectors, lists, and three sequence types; vectors, lists, and deques.deques.

Page 10: C++ Training Datascope Lawrence D’Antonio

Generic programming 3Generic programming 3

Concepts can be classified and organized Concepts can be classified and organized in hierarchies. For example, one of the in hierarchies. For example, one of the primary concepts of the STL is that of the primary concepts of the STL is that of the Iterator. Iteration allows for movement Iterator. Iteration allows for movement from one address location in a data from one address location in a data structure to another. structure to another.

There are various categories of Iterators. There are various categories of Iterators.

Page 11: C++ Training Datascope Lawrence D’Antonio

Generic programming 4Generic programming 4 A ForwardIterator only allows movement in A ForwardIterator only allows movement in

one direction. There are two Iterator one direction. There are two Iterator concepts that the ForwardIterator refines, concepts that the ForwardIterator refines, the InputIterator and the OutputIterator. the InputIterator and the OutputIterator.

The InputIterator can only read from the The InputIterator can only read from the current location and allows movement current location and allows movement forward. The OutputIterator can only write forward. The OutputIterator can only write to the current location and allows to the current location and allows movement forward.movement forward.

Page 12: C++ Training Datascope Lawrence D’Antonio

Generic programming 5Generic programming 5 The algorithms that form the STL are The algorithms that form the STL are

themselves organized around concepts. themselves organized around concepts. A generic algorithm consists of an A generic algorithm consists of an

implementation and the set of implementation and the set of requirements that its arguments must requirements that its arguments must satisfy. satisfy.

For example, the STL algorithm For example, the STL algorithm reverse()reverse() will reverse the elements of any container will reverse the elements of any container that is a model of the Sequence concept.that is a model of the Sequence concept.

Page 13: C++ Training Datascope Lawrence D’Antonio

Generic programming 6Generic programming 6 Here is a non-generic gcd function.Here is a non-generic gcd function.int gcd(int x, int y)int gcd(int x, int y){{ while (y != 0) {while (y != 0) { int t = x % y;int t = x % y; x = y;x = y; y = t;y = t; }} return x < 0 ? -x : x; return x < 0 ? -x : x; }}

Page 14: C++ Training Datascope Lawrence D’Antonio

Generic programming 7Generic programming 7

This algorithm is fine as it goes, but a This algorithm is fine as it goes, but a generic version should be valid for other generic version should be valid for other algebraic quantities besides integers (in algebraic quantities besides integers (in fact, for any principal ideal domain). For fact, for any principal ideal domain). For example, we would want to extend the example, we would want to extend the algorithm to polynomials and Gaussian algorithm to polynomials and Gaussian integers. integers.

Page 15: C++ Training Datascope Lawrence D’Antonio

Generic programming 8Generic programming 8

One problem arises here, the return One problem arises here, the return statement, which is assuming that the gcd statement, which is assuming that the gcd returns a positive value, will only be valid returns a positive value, will only be valid for types that satisfy the requirement of for types that satisfy the requirement of being totally ordered. being totally ordered.

Page 16: C++ Training Datascope Lawrence D’Antonio

Generic programming 9Generic programming 9 Here is a generic gcd function.Here is a generic gcd function.template <class T>template <class T>T gcd(T x, T y)T gcd(T x, T y){{ while (y != 0) {while (y != 0) { T t = x % y;T t = x % y; x = y;x = y; y = t;y = t; }} return x;return x;}}

Page 17: C++ Training Datascope Lawrence D’Antonio

Generic programming 10Generic programming 10

In this case, the 'greatest' divisor that we In this case, the 'greatest' divisor that we are returning is only unique up to are returning is only unique up to multiplication by a unit. Each type will have multiplication by a unit. Each type will have its own concept of greatest (greatest its own concept of greatest (greatest degree for polynomials, greatest modulus degree for polynomials, greatest modulus for Gaussian integers). for Gaussian integers).

Page 18: C++ Training Datascope Lawrence D’Antonio

Generic programming 11Generic programming 11

To summarize (and perhaps oversimplify).To summarize (and perhaps oversimplify).   object-oriented programming = data object-oriented programming = data

abstraction + object types + type inheritanceabstraction + object types + type inheritance

generic programming = data abstraction + generic programming = data abstraction + generic types + concept refinementgeneric types + concept refinement

Page 19: C++ Training Datascope Lawrence D’Antonio

AbstractionAbstraction STL makes efficiency an important part of the STL makes efficiency an important part of the

design of the library. design of the library. Complexity guarantees are part of interface of Complexity guarantees are part of interface of

each STL component. each STL component. For example, there are three sequence For example, there are three sequence

containers, vector<Type>, list<Type>, containers, vector<Type>, list<Type>, deque<Type>. deque<Type>.

The C++ standard gives the following time The C++ standard gives the following time guarantees for element access, element guarantees for element access, element insert/delete, and range insert/delete.insert/delete, and range insert/delete.

Page 20: C++ Training Datascope Lawrence D’Antonio

Abstraction 2Abstraction 2

OperationOperation VectorVector DequeDeque ListListAccess at frontAccess at front ConstantConstant ConstantConstant ConstantConstant

Access at backAccess at back ConstantConstant ConstantConstant ConstantConstant

Random access Random access ConstantConstant ConstantConstant LinearLinear

Insert at frontInsert at front LinearLinear Constant*Constant* ConstantConstant

Insert at backInsert at back Constant*Constant* Constant*Constant* ConstantConstant

Random insertRandom insert LinearLinear LinearLinear ConstantConstant

Insert rangeInsert range LinearLinear LinearLinear ConstantConstant

Page 21: C++ Training Datascope Lawrence D’Antonio

Abstraction 3Abstraction 3 STL also provides associative containers that, in STL also provides associative containers that, in

general, store elements of the form (key, value), in general, store elements of the form (key, value), in some sort of tree structure (usually a red-black tree). some sort of tree structure (usually a red-black tree). There are four types of associative containers: There are four types of associative containers:

Sets (which are collections of unique keys without Sets (which are collections of unique keys without corresponding values).corresponding values).

Multisets (which allow for multiple occurrences of a Multisets (which allow for multiple occurrences of a key).key).

Maps (which store key, value pairs with keys being Maps (which store key, value pairs with keys being unique).unique).

Multisets (which store key, value pairs with multiple Multisets (which store key, value pairs with multiple keys possible). keys possible).

Page 22: C++ Training Datascope Lawrence D’Antonio

Abstraction 4Abstraction 4 The basic operations for associative The basic operations for associative

containers are, finding an element with a containers are, finding an element with a given key, inserting an element, erasing given key, inserting an element, erasing an element, erasing all elements pointed an element, erasing all elements pointed to by a key. to by a key.

In the following table, N represents the In the following table, N represents the number of elements in the container, K number of elements in the container, K represents the number of values represents the number of values corresponding to a particular key. corresponding to a particular key.

Page 23: C++ Training Datascope Lawrence D’Antonio

Abstraction 5Abstraction 5

OperationOperation SetSet MultisetMultiset MapMap MultimapMultimap

FindFind Log(N)Log(N) Log(N)Log(N) Log(N)Log(N) Log(N)Log(N)

InsertInsert Log(N)Log(N) Log(N)Log(N) Log(N)Log(N) Log(N)Log(N)

EraseErase Constant*Constant* Constant*Constant* Constant*Constant* Constant*Constant*

Erase KeyErase Key Log(N)Log(N) Log(N)+KLog(N)+K Log(N)Log(N) Log(N)+KLog(N)+K

Page 24: C++ Training Datascope Lawrence D’Antonio

Von Neumann ModelVon Neumann Model

Stepanov notes the significance of Stepanov notes the significance of addressing in the design of STL. addressing in the design of STL.

The STL containers provide services for The STL containers provide services for adding or deleting addresses to a data adding or deleting addresses to a data structure. Iterators can be seen as moving structure. Iterators can be seen as moving from one address to another in a from one address to another in a container.container.

Page 25: C++ Training Datascope Lawrence D’Antonio

Value SemanticsValue Semantics

In the STL containers own their elements. In the STL containers own their elements. When a container is copied, all elements When a container is copied, all elements are copied. When a container is are copied. When a container is destroyed, all objects it contains are in turn destroyed, all objects it contains are in turn destroyed. destroyed.

All copies in STL are deep copies.All copies in STL are deep copies. These value semantics imply that STL These value semantics imply that STL

containers can never overlap.containers can never overlap.

Page 26: C++ Training Datascope Lawrence D’Antonio

Value Semantics 2Value Semantics 2

Of course, for the sake of efficiency, one Of course, for the sake of efficiency, one can store pointers to larger structures in a can store pointers to larger structures in a container. container.

But this itself presents problems. One has But this itself presents problems. One has to adapt the comparison functions that to adapt the comparison functions that several STL containers and algorithms several STL containers and algorithms require to work with pointers. require to work with pointers.

Page 27: C++ Training Datascope Lawrence D’Antonio

Value Semantics 3Value Semantics 3 A more important consideration is the use A more important consideration is the use

of STL with polymorphic objects. of STL with polymorphic objects. Because of the use of value semantics in Because of the use of value semantics in

STL, polymorphic objects are either sliced STL, polymorphic objects are either sliced (i.e., only their base parts are copied or (i.e., only their base parts are copied or assigned) or, if pointers are used, there is assigned) or, if pointers are used, there is a problem of ownership of the object (e.g., a problem of ownership of the object (e.g., what should happen if the object is what should happen if the object is removed from the container). removed from the container).

Page 28: C++ Training Datascope Lawrence D’Antonio

Value Semantics 4Value Semantics 4 One solution to this problem is the use a One solution to this problem is the use a

type of smart pointer. type of smart pointer. For example, one can define a pointer For example, one can define a pointer

object containing a reference to a object containing a reference to a polymorphic object. polymorphic object.

When copying or assigning the smart When copying or assigning the smart pointer, a new copy of the referenced pointer, a new copy of the referenced object is made (with the correct dynamic object is made (with the correct dynamic type).type).

Page 29: C++ Training Datascope Lawrence D’Antonio

A Short History of STLA Short History of STL The first explorations of the concept of generic The first explorations of the concept of generic

programming go back to work of Alexander programming go back to work of Alexander Stepanov in the late '70s. Stepanov in the late '70s.

Later work at General Electric Research and Later work at General Electric Research and Development in collaboration with David Musser Development in collaboration with David Musser led to the development of a list processing led to the development of a list processing library in Ada, the first language to support library in Ada, the first language to support generic programming. generic programming.

This work, in 1987, was followed by additional This work, in 1987, was followed by additional work in Scheme work in Scheme

Page 30: C++ Training Datascope Lawrence D’Antonio

A Short History of STL 2A Short History of STL 2 Stepanov, in work at Bell Laboratories and then Stepanov, in work at Bell Laboratories and then

later at Hewlett-Packard Research Laboratories, later at Hewlett-Packard Research Laboratories, turned his attention to formulating generic turned his attention to formulating generic algorithms in C++. algorithms in C++.

He was particularly attracted to the C++ feature He was particularly attracted to the C++ feature of templates, which allow for parametrized types. of templates, which allow for parametrized types.

Bjarne Stroustrup, the developer of C++, Bjarne Stroustrup, the developer of C++, introduced templates in 1991, in the cfront introduced templates in 1991, in the cfront Release 3.0 Release 3.0

Page 31: C++ Training Datascope Lawrence D’Antonio

A Short History of STL 3A Short History of STL 3 While Stepanov was at Hewlett-Packard, Meng While Stepanov was at Hewlett-Packard, Meng

Lee joined his project and became a major Lee joined his project and became a major contributor to the library that was eventually contributor to the library that was eventually called STL. called STL.

Andrew Koenig of Bell Laboratories, a member Andrew Koenig of Bell Laboratories, a member of the X3J16 ANSI/ISO committee for C++ of the X3J16 ANSI/ISO committee for C++ standardization, invited Stepanov to present the standardization, invited Stepanov to present the basic ideas of the library at the November 1993 basic ideas of the library at the November 1993 X3J16 meeting. X3J16 meeting.

This led to request from the committee for This led to request from the committee for Stepanov and Lee to write a draft proposal for Stepanov and Lee to write a draft proposal for STL at the March 1994 committee meeting.STL at the March 1994 committee meeting.

Page 32: C++ Training Datascope Lawrence D’Antonio

A Short History of STL 4A Short History of STL 4 Further revisions and extensions were proposed Further revisions and extensions were proposed

to the STL at this point. to the STL at this point. The major extension, associative containers, The major extension, associative containers,

was implemented by David Musser. was implemented by David Musser. After this work, the STL proposal was accepted After this work, the STL proposal was accepted

by the ANSI committee at their July 1994 by the ANSI committee at their July 1994 meeting. meeting.

The document produced by Stepanov and Lee The document produced by Stepanov and Lee was accepted into the X3J16 draft standard.was accepted into the X3J16 draft standard.

Page 33: C++ Training Datascope Lawrence D’Antonio

A Short History of STL 5A Short History of STL 5

The dissemination of the STL became The dissemination of the STL became widespread with the decision by HP, in widespread with the decision by HP, in August 1994, to make the library freely August 1994, to make the library freely available on the Internet. available on the Internet.

This implementation, due primarily to This implementation, due primarily to Stepanov, Lee, and Musser, is the basis Stepanov, Lee, and Musser, is the basis for all future versions of the STL.for all future versions of the STL.

Page 34: C++ Training Datascope Lawrence D’Antonio

A Short History of STL 6A Short History of STL 6 In 1996 Stepanov joined SGI and together with In 1996 Stepanov joined SGI and together with

Matthew Austern and Hans Boehm, worked on Matthew Austern and Hans Boehm, worked on an implementation of the STL. an implementation of the STL.

This implementation includes various extensions This implementation includes various extensions of the STL, such as thread-safe memory of the STL, such as thread-safe memory allocation and hash tables. allocation and hash tables.

It should be noted that the extensions in the SGI It should be noted that the extensions in the SGI version of the library have not yet been accepted version of the library have not yet been accepted into the C++ standard. into the C++ standard.

This implementation may be downloaded, This implementation may be downloaded, together with extensive documentation on the together with extensive documentation on the library, at library, at http://http://www.sgi.com/tech/stlwww.sgi.com/tech/stl//

Page 35: C++ Training Datascope Lawrence D’Antonio

STL by exampleSTL by example

First, to see the power of STL and how it First, to see the power of STL and how it functions let us look at a simple series of functions let us look at a simple series of examples, adapted from David Harvey's examples, adapted from David Harvey's online STL tutorial: online STL tutorial: http://www.davethehat.com/articles/eff_stl.http://www.davethehat.com/articles/eff_stl.htmhtm

Page 36: C++ Training Datascope Lawrence D’Antonio

STL by example 2STL by example 2

Word Copy Example Word Copy Example

The task is to write a function that reads in The task is to write a function that reads in strings from an input stream, sorts them, strings from an input stream, sorts them, eliminates duplicates, and then prints the eliminates duplicates, and then prints the results to an output stream, one word per results to an output stream, one word per line. line.

Page 37: C++ Training Datascope Lawrence D’Antonio

STL by example 3STL by example 3

Version 1 (Non-STL)Version 1 (Non-STL)

This version is given in pseudo-code to This version is given in pseudo-code to spare the reader the gory details (which spare the reader the gory details (which they can presumably fill in for they can presumably fill in for themselves).themselves).

Page 38: C++ Training Datascope Lawrence D’Antonio

STL by example 4STL by example 4ostream& wordcopy(istream &in, ostream &out)ostream& wordcopy(istream &in, ostream &out){{ string s; //string to be readstring s; //string to be read //Also need a container to store the strings//Also need a container to store the strings   while( !in.eof() && in >> s ) {while( !in.eof() && in >> s ) { //store s in container//store s in container }}   //Sort the container in alphabetical order //Sort the container in alphabetical order  //Remove duplicates, this gets ugly if you used an array //Remove duplicates, this gets ugly if you used an array  //Print each string to output stream, one per line//Print each string to output stream, one per line   return out;return out;}}

Page 39: C++ Training Datascope Lawrence D’Antonio

STL by example 5STL by example 5 Version 2 (STL using vector container)Version 2 (STL using vector container)ostream& wordcopy(istream &in, ostream&out)ostream& wordcopy(istream &in, ostream&out){{ string s; //string to be readstring s; //string to be read vector<string> v; vector<string> v; //STL vector container for the strings//STL vector container for the strings

   while( !in.eof() && in >> s )while( !in.eof() && in >> s ) v.push_back(s); v.push_back(s); //inserts s at end of container//inserts s at end of container

Page 40: C++ Training Datascope Lawrence D’Antonio

STL by example 6STL by example 6//STL sort algorithm//STL sort algorithmsort(v.begin(), v.end()); sort(v.begin(), v.end());

   //Use the STL unique() to 'eliminate‘ duplicates//Use the STL unique() to 'eliminate‘ duplicates //unique 'removes' consecutive duplicates//unique 'removes' consecutive duplicates vector<string>::iterator p = vector<string>::iterator p =

unique(v.begin(), v.end());unique(v.begin(), v.end());   //Now send results to output//Now send results to output for(vector<string>::iterator i = v.begin(); i != p; i++)for(vector<string>::iterator i = v.begin(); i != p; i++) out << *i << '\n';out << *i << '\n'; return out;return out;}}

Page 41: C++ Training Datascope Lawrence D’Antonio

STL by example 7STL by example 7 A couple of comments on this version.A couple of comments on this version.

The use of iterator is an essential part of The use of iterator is an essential part of STL. Iterators are used to traverse STL. Iterators are used to traverse containers, and to add or remove items containers, and to add or remove items from containers. from containers.

Each container-type has a corresponding Each container-type has a corresponding iterator-type. Vectors use random-access iterator-type. Vectors use random-access iterators. iterators.

Page 42: C++ Training Datascope Lawrence D’Antonio

STL by example 8STL by example 8 The unique algorithm has a quirk that one must The unique algorithm has a quirk that one must

get used to. get used to. Since it is a generic algorithm, and hence knows Since it is a generic algorithm, and hence knows

nothing about the underlying organization of the nothing about the underlying organization of the data it is being applied to, it cannot actually data it is being applied to, it cannot actually remove duplicates from the container. remove duplicates from the container.

What it in fact does is to place any duplicates at What it in fact does is to place any duplicates at the end of the container. After the algorithm is the end of the container. After the algorithm is completed, there will be a range of non-completed, there will be a range of non-duplicates, say in positions [first,last). The duplicates, say in positions [first,last). The function will return position last. function will return position last.

Page 43: C++ Training Datascope Lawrence D’Antonio

unique()unique() algorithm algorithmtemplate<class FwdIt>template<class FwdIt>FwdIt unique(FwdIt F, FwdIt L)FwdIt unique(FwdIt F, FwdIt L){{ FwdIt X = F; //X will step through duplicatesFwdIt X = F; //X will step through duplicates FwdIt Fb = F; //Fb will store position of first duplicateFwdIt Fb = F; //Fb will store position of first duplicate

for( *X++ = *Fb; ++F != L; ) {for( *X++ = *Fb; ++F != L; ) { if( !(*Fb == *F) ) {if( !(*Fb == *F) ) { Fb = F;Fb = F; *X++ = *Fb;*X++ = *Fb; }} }} return X;return X;}}

Page 44: C++ Training Datascope Lawrence D’Antonio

unique()unique() algorithm 2 algorithm 2main() {main() { int A[ ] = {1,1,1,2,3,3};int A[ ] = {1,1,1,2,3,3}; int *p = std::unique(&A[0],&A[6]);int *p = std::unique(&A[0],&A[6]); for(int *q = &A[0]; q != p; q++)for(int *q = &A[0]; q != p; q++) std::cout << *q << ' ';std::cout << *q << ' '; std::cout << '\n';std::cout << '\n'; return 0;return 0;}}

Page 45: C++ Training Datascope Lawrence D’Antonio

unique()unique() algorithm 3 algorithm 3template<class FwdIt, class BinPred>template<class FwdIt, class BinPred>FwdIt unique(FwdIt F, FwdIt L, BinPred P)FwdIt unique(FwdIt F, FwdIt L, BinPred P){{ FwdIt X = F;FwdIt X = F; FwdIt Fb = F;FwdIt Fb = F;

for( *X++ = *Fb; ++F != L; ) {for( *X++ = *Fb; ++F != L; ) { if( !P(*Fb,*F) ) {if( !P(*Fb,*F) ) { Fb = F;Fb = F; *X++ = *Fb;*X++ = *Fb; }} }} return X;return X;}}

Page 46: C++ Training Datascope Lawrence D’Antonio

unique()unique() algorithm 4 algorithm 4

Consider the following predicateConsider the following predicateclass P {class P {public:public:

bool operator()(int x, int y) {bool operator()(int x, int y) {return ((x % 2) != (y%2));return ((x % 2) != (y%2));

}}};};

Page 47: C++ Training Datascope Lawrence D’Antonio

unique()unique() algorithm 5 algorithm 5main() {main() { int A[ ] = {1,1,1,2,3,3};int A[ ] = {1,1,1,2,3,3};

int *p = unique(&A[0],&A[6],P());int *p = unique(&A[0],&A[6],P()); for(int *q = &A[0]; q != p; q++)for(int *q = &A[0]; q != p; q++) std::cout << *q << ' ';std::cout << *q << ' '; std::cout << '\n';std::cout << '\n'; return 0;return 0;}}

Page 48: C++ Training Datascope Lawrence D’Antonio

STL by example 9STL by example 9 Version 3 (STL using set container)Version 3 (STL using set container) A student studying STL quickly learns A student studying STL quickly learns

about the benefits of the STL about the benefits of the STL associative containers. associative containers.

For the task at hand, the set container For the task at hand, the set container is particularly useful. Data in a set is is particularly useful. Data in a set is kept in sorted order, and no duplicates kept in sorted order, and no duplicates are allowed. This is exactly what we are allowed. This is exactly what we want.want.

Page 49: C++ Training Datascope Lawrence D’Antonio

STL by example 10STL by example 10

ostream& wordcopy(istream &in, ostream &out)ostream& wordcopy(istream &in, ostream &out){{

string s; //string to be readstring s; //string to be readset<string> words; //STL set container for the stringsset<string> words; //STL set container for the strings

while( !in.eof() && in >> s )while( !in.eof() && in >> s ) words.insert(s); //Insert in sorted orderwords.insert(s); //Insert in sorted order

Page 50: C++ Training Datascope Lawrence D’Antonio

STL by example 11STL by example 11

//Now send results to output//Now send results to outputfor(set<string>::iterator i = words.begin(); for(set<string>::iterator i = words.begin();

i != words.end(); i++)i != words.end(); i++) out << *i << '\n';out << *i << '\n';  

return out;return out;}}

Page 51: C++ Training Datascope Lawrence D’Antonio

STL by example 12STL by example 12 Note, if the input string s is already in set, Note, if the input string s is already in set,

then the insertion does nothing. then the insertion does nothing. The insert function returns a pair The insert function returns a pair

consisting of an iterator and a bool. consisting of an iterator and a bool. If the insertion was successful, it returns If the insertion was successful, it returns

(new position, true). (new position, true). If the insertion failed, because the value If the insertion failed, because the value

was already in the set, the return will be was already in the set, the return will be (existing position, false).(existing position, false).

Page 52: C++ Training Datascope Lawrence D’Antonio

STL by example 13STL by example 13 Version 4 (STL using sets and stream Version 4 (STL using sets and stream

adaptors)adaptors) Copying operations in the STL often make Copying operations in the STL often make

use of adaptors. An adaptor makes one use of adaptors. An adaptor makes one object act like another. object act like another.

A stream adaptor makes an input or output A stream adaptor makes an input or output stream look like a container to an STL stream look like a container to an STL algorithm. algorithm.

In general, the copy algorithms in the library In general, the copy algorithms in the library use source and destination containers. But use source and destination containers. But by using adaptors, we can copy from or to a by using adaptors, we can copy from or to a stream.stream.

Page 53: C++ Training Datascope Lawrence D’Antonio

STL by example 14STL by example 14 One difficulty in using the copy algorithms One difficulty in using the copy algorithms

is the fact that the destination container is is the fact that the destination container is assumed to have the space to hold the assumed to have the space to hold the data copied over from the source. data copied over from the source.

If this is not the case, as in the example If this is not the case, as in the example below, then an inserter object must be below, then an inserter object must be used for the destination (the inserter will used for the destination (the inserter will call the underlying insert() member call the underlying insert() member function).function).

Page 54: C++ Training Datascope Lawrence D’Antonio

STL by example 15STL by example 15ostream& wordcopy(istream &in, ostream &out)ostream& wordcopy(istream &in, ostream &out){{

set<string> words; set<string> words; //STL set container for the strings//STL set container for the strings

  //Read in from istream and store in set//Read in from istream and store in setcopy(istream_iterator<string>(in),copy(istream_iterator<string>(in), istream_iterator<string>(), istream_iterator<string>(), inserter(words, words.begin()));inserter(words, words.begin()));

Page 55: C++ Training Datascope Lawrence D’Antonio

STL by example 16STL by example 16

//Now send results to output//Now send results to outputcopy(words.begin(), words.end(), copy(words.begin(), words.end(),

ostream_iterator<string>(out, "\ostream_iterator<string>(out, "\n"));n"));

  return out;return out;

}}

Page 56: C++ Training Datascope Lawrence D’Antonio

STL by example 17STL by example 17 A few comments are in order. A few comments are in order. The adaptor, istream_iterator, needs to know the The adaptor, istream_iterator, needs to know the

data type that is being read, string in this case.data type that is being read, string in this case. Note that the extraction operator >> is used by Note that the extraction operator >> is used by

istream_iterator, so it can only read types for istream_iterator, so it can only read types for which this operator has been defined. which this operator has been defined.

Also, we have used a constructor to create the Also, we have used a constructor to create the istream_iterator and to give it the input stream to istream_iterator and to give it the input stream to read from. read from.

Page 57: C++ Training Datascope Lawrence D’Antonio

STL by example 18STL by example 18 The default constructor for istream_iterator is The default constructor for istream_iterator is

used to create an end of file position that is used used to create an end of file position that is used to terminate the algorithm.to terminate the algorithm.

The mechanism to make this work is a little The mechanism to make this work is a little tricky, since the default istream_iterator doesn't tricky, since the default istream_iterator doesn't know what file it is supposed to be the end of!know what file it is supposed to be the end of!

Here is the way it works. Istream iterators keep a Here is the way it works. Istream iterators keep a data member that is a pointer, lets call it Istr, to data member that is a pointer, lets call it Istr, to the istream it traverses. the istream it traverses.

Page 58: C++ Training Datascope Lawrence D’Antonio

STL by example 19STL by example 19 Suppose we declare (note the string type Suppose we declare (note the string type

plays no role) two istream iterators and plays no role) two istream iterators and then increment one of them. then increment one of them.

istream_iterator<string> i(in_file);istream_iterator<string> i(in_file);//i.Istr = &in_file//i.Istr = &in_file

istream_iterator<string> j; istream_iterator<string> j; //j.Istr = 0//j.Istr = 0

++i;++i;

Page 59: C++ Training Datascope Lawrence D’Antonio

STL by example 20STL by example 20

The increment operator for i calls an The increment operator for i calls an internal read function that uses the internal read function that uses the extraction operator >>. extraction operator >>.

If the extraction fails, i.Istr is set equal to 0, If the extraction fails, i.Istr is set equal to 0, and then iterators i, j will compare as being and then iterators i, j will compare as being equal.equal.

Page 60: C++ Training Datascope Lawrence D’Antonio

STL by example 21STL by example 21

A third comment on the above version is A third comment on the above version is that the ostream_iterator constructor takes that the ostream_iterator constructor takes two arguments, the ostream and a string two arguments, the ostream and a string to be used as a delimiter between outputs. to be used as a delimiter between outputs.

Page 61: C++ Training Datascope Lawrence D’Antonio

Iterator adaptorsIterator adaptors

Let’s look in more detail at the iterator Let’s look in more detail at the iterator adaptors adaptors istream_iteratoristream_iterator, , ostream_iteratorostream_iterator, , insert_iteratorinsert_iterator (which (which inserterinserter returns).returns).

Page 62: C++ Training Datascope Lawrence D’Antonio

istream_iteratoristream_iteratortemplate<class T, class E = char, template<class T, class E = char,

class Tr = std::char_traits<E> >class Tr = std::char_traits<E> >class istream_iterator {class istream_iterator {public:public: typedef istream_iterator<T,E,Tr> Iter;typedef istream_iterator<T,E,Tr> Iter; typedef E char_type; typedef E char_type; typedef Tr traits_type;typedef Tr traits_type; typedef std::basic_istream<E,Tr> istream_type;typedef std::basic_istream<E,Tr> istream_type;

Page 63: C++ Training Datascope Lawrence D’Antonio

istream_iterator 2istream_iterator 2

protected:protected: T val;T val; istream_type *Istr;istream_type *Istr; void Getval() {void Getval() { if (Istr != 0 && !(*Istr >> val))if (Istr != 0 && !(*Istr >> val)) Istr = 0;Istr = 0; }}

Page 64: C++ Training Datascope Lawrence D’Antonio

istream_iterator 3istream_iterator 3public:public: istream_iterator()istream_iterator() : Istr(0) {}: Istr(0) {} istream_iterator(istream_type &I)istream_iterator(istream_type &I) : Istr(&I) { Getval(); }: Istr(&I) { Getval(); } const T& operator*() constconst T& operator*() const { return val; } { return val; } const T* operator->() constconst T* operator->() const { return &**this; }{ return &**this; } Iter &operator++()Iter &operator++() { Getval(); return *this; }{ Getval(); return *this; } Iter operator++(int)Iter operator++(int) { Iter temp; Getval(); return temp; }{ Iter temp; Getval(); return temp; }

Page 65: C++ Training Datascope Lawrence D’Antonio

istream_iterator 4istream_iterator 4bool Equal(const Iter& x) const bool Equal(const Iter& x) const { return Istr == x.Istr; }{ return Istr == x.Istr; }};}; template<class T, class E, class Tr>template<class T, class E, class Tr>bool operator==(const istream_iterator<T,E,Tr> &x,bool operator==(const istream_iterator<T,E,Tr> &x, const istream_iterator<T,E,Tr> &y)const istream_iterator<T,E,Tr> &y) { return x.Equal(y); }{ return x.Equal(y); } template<class T, class E, class Tr> template<class T, class E, class Tr> bool operator!=(const istream_iterator<T,E,Tr> &x,bool operator!=(const istream_iterator<T,E,Tr> &x, const istream_iterator<T,E,Tr> &y)const istream_iterator<T,E,Tr> &y) { return !(x == y); }{ return !(x == y); }

Page 66: C++ Training Datascope Lawrence D’Antonio

ostream_iteratorostream_iteratortemplate<class T, class E = char, template<class T, class E = char,

class Tr = std::char_traits<E> >class Tr = std::char_traits<E> >class ostream_iterator {class ostream_iterator {public:public: typedef ostream_iterator<T,E,Tr> Iter;typedef ostream_iterator<T,E,Tr> Iter; typedef T value_type;typedef T value_type; typedef E char_type;typedef E char_type; typedef Tr traits_type;typedef Tr traits_type; typedef std::basic_ostream<E,Tr> ostream_type;typedef std::basic_ostream<E,Tr> ostream_type;protected:protected: const E *Delim; const E *Delim; ostream_type *Ostr;ostream_type *Ostr;

Page 67: C++ Training Datascope Lawrence D’Antonio

ostream_iterator 2ostream_iterator 2public:public: ostream_iterator(ostream_type &O, const E *D = 0)ostream_iterator(ostream_type &O, const E *D = 0) : Ostr(&O), Delim(D) { }: Ostr(&O), Delim(D) { }

Iter &operator=(const T&x)Iter &operator=(const T&x) { *Ostr << x;{ *Ostr << x; if (Delim != 0)if (Delim != 0) *Ostr << Delim;*Ostr << Delim; }}

Page 68: C++ Training Datascope Lawrence D’Antonio

ostream_iterator 3ostream_iterator 3

const T& operator*() constconst T& operator*() const { return *this; }{ return *this; } Iter &operator++()Iter &operator++() { return *this; }{ return *this; } Iter operator++(int)Iter operator++(int) { return *this; }{ return *this; }};};

Page 69: C++ Training Datascope Lawrence D’Antonio

insert_iteratorinsert_iteratortemplate<class C>template<class C>class insert_iterator {class insert_iterator {public:public: typedef C container_type;typedef C container_type; typedef typename C::reference reference_type;typedef typename C::reference reference_type; typedef typename C::value_type value_type;typedef typename C::value_type value_type;

protected:protected: C *container;C *container; typename C::iterator iter;typename C::iterator iter;

Page 70: C++ Training Datascope Lawrence D’Antonio

insert_iterator 2insert_iterator 2public:public: insert_iterator(C &X, typename C::iterator I)insert_iterator(C &X, typename C::iterator I) :container(&X), iter(I) {}:container(&X), iter(I) {}

insert_iterator<C>& operator=(insert_iterator<C>& operator=( typename C::const_reference val)typename C::const_reference val) { iter = container->insert(iter,val);{ iter = container->insert(iter,val); ++iter;++iter; return *this; return *this; }}

Page 71: C++ Training Datascope Lawrence D’Antonio

insert_iterator 3insert_iterator 3 insert_iterator<C>& operator*()insert_iterator<C>& operator*()

{ return *this; }{ return *this; } insert_iterator<C>& operator++() insert_iterator<C>& operator++() { return *this; }{ return *this; } insert_iterator<C>& operator++(int)insert_iterator<C>& operator++(int) { return *this; }{ return *this; }};}; template<class C,class Iter>template<class C,class Iter>insert_iterator<C> inserter(C& X, Iter I)insert_iterator<C> inserter(C& X, Iter I){{ return insert_iterator<C>(X, C::iterator(I));return insert_iterator<C>(X, C::iterator(I));}}

Page 72: C++ Training Datascope Lawrence D’Antonio

STL by example 22STL by example 22 Version 5 (STL using transform() for string Version 5 (STL using transform() for string

conversion)conversion) The problem of sorting strings is The problem of sorting strings is

complicated by the issue of case. The complicated by the issue of case. The versions above are case-sensitive (so "The" versions above are case-sensitive (so "The" and "the" would both be in the output). and "the" would both be in the output).

A simple way to handle is to convert the A simple way to handle is to convert the strings to lower case as they are being read. strings to lower case as they are being read. But we would like to do this while keeping But we would like to do this while keeping the simplicity of version 4.the simplicity of version 4.

Page 73: C++ Training Datascope Lawrence D’Antonio

STL by example 23STL by example 23

This is where the transform algorithm This is where the transform algorithm comes into play. This function will comes into play. This function will apply a function (or function object), to apply a function (or function object), to each element in a source container, each element in a source container, and pass the return value of this and pass the return value of this function to the destination container.function to the destination container.

Page 74: C++ Training Datascope Lawrence D’Antonio

STL by example 24STL by example 24ostream& wordcopy(istream &in, ostream &out)ostream& wordcopy(istream &in, ostream &out){{

set<string> words; set<string> words; //STL set container for the strings//STL set container for the strings

  //Read in from istream, convert to lower case,//Read in from istream, convert to lower case,//Store in set//Store in settransform(istream_iterator<string>(in),transform(istream_iterator<string>(in),

istream_iterator(),istream_iterator(), inserter(words, words.begin()), inserter(words, words.begin()),

to_lower); to_lower);

Page 75: C++ Training Datascope Lawrence D’Antonio

STL by example 25STL by example 25

//Now send results to output//Now send results to outputcopy(words.begin(), words.end(),copy(words.begin(), words.end(),

ostream_iterator<string>(out, "\ostream_iterator<string>(out, "\n"));n"));

  return out;return out;

}}

Page 76: C++ Training Datascope Lawrence D’Antonio

STL by example 26STL by example 26 Here is the function to_lowerHere is the function to_lowerstring to_lower(const string &s)string to_lower(const string &s){{ string temp(s.size(),0);string temp(s.size(),0); for(int i = 0; i < s.size(); i++) for(int i = 0; i < s.size(); i++) temp[i] = tolower(s[i]);temp[i] = tolower(s[i]); return temp;return temp;} }

Page 77: C++ Training Datascope Lawrence D’Antonio

STL by example 27STL by example 27

Version 6 (STL with a different sorting Version 6 (STL with a different sorting criterion)criterion)

In this version we want the strings sorted In this version we want the strings sorted according to the following criterion. according to the following criterion.

The strings should be printed out The strings should be printed out according to order of their word length. If according to order of their word length. If two strings are the same length, then print two strings are the same length, then print out in alphabetical order.out in alphabetical order.

Page 78: C++ Training Datascope Lawrence D’Antonio

STL by example 28STL by example 28

To accomplish this we must give the set To accomplish this we must give the set container a comparison function object. container a comparison function object.

A function object (called a functor) is an A function object (called a functor) is an object with an overloaded function call object with an overloaded function call operator.operator.

Page 79: C++ Training Datascope Lawrence D’Antonio

STL by example 29STL by example 29struct lengthcomp {struct lengthcomp { bool operator() (const string &s1, const string &s2)bool operator() (const string &s1, const string &s2)

constconst

{{ return return

( s1.size() < s2.size() ) || ( s1.size() < s2.size() ) || ( (s1.size() == s2.size()) && (s1 < s2) );( (s1.size() == s2.size()) && (s1 < s2) );

}}};};

Page 80: C++ Training Datascope Lawrence D’Antonio

STL by example 30STL by example 30

The only other change we make is:The only other change we make is:

set<string,lengthcomp> words; set<string,lengthcomp> words;

Page 81: C++ Training Datascope Lawrence D’Antonio

How Much C++ Do You Need to How Much C++ Do You Need to Know for STL?Know for STL?

Template MetaprogrammingTemplate Metaprogramming Templates can be viewed as an interpreted Templates can be viewed as an interpreted

programming language. For example, consider programming language. For example, consider the following example:the following example:

template<int N>template<int N>struct Factorial {struct Factorial { enum { value = N * Factorial<N-1>::value };enum { value = N * Factorial<N-1>::value };};};

Page 82: C++ Training Datascope Lawrence D’Antonio

How Much …? 2How Much …? 2

//Specialized version//Specialized versiontemplate <>template <>struct Factorial<1> {struct Factorial<1> { enum { value = 1 };enum { value = 1 };};};  //...//...cout << '5!= ' << Factorial<5>::value;cout << '5!= ' << Factorial<5>::value;

Page 83: C++ Training Datascope Lawrence D’Antonio

How Much …? 3How Much …? 3 Traits classesTraits classes Traits are a method for associating information Traits are a method for associating information

about related types, values and functions with a about related types, values and functions with a template parameter type. template parameter type.

Traits are used in several parts of the STL, but Traits are used in several parts of the STL, but especially with iterators. especially with iterators.

Consider an example from the Nathan Myers Consider an example from the Nathan Myers paper that introduced the concept of traits to the paper that introduced the concept of traits to the C++ community.C++ community.

Page 84: C++ Training Datascope Lawrence D’Antonio

How Much …? 4How Much …? 4 Myers invented traits to handle a certain Myers invented traits to handle a certain

problem with the C++ I/O library. problem with the C++ I/O library. The C I/O library is meant to work with the char The C I/O library is meant to work with the char

type. But C++ is meant to be a reusable, type. But C++ is meant to be a reusable, extensible language. extensible language.

So that the design of the iostream library should, So that the design of the iostream library should, as far as possible, support the extension of the as far as possible, support the extension of the I/O routines to generic character types (different I/O routines to generic character types (different character sets, different size character types, character sets, different size character types, etc.). etc.).

Page 85: C++ Training Datascope Lawrence D’Antonio

How Much …? 5How Much …? 5 Consider the streambuf class, which is the Consider the streambuf class, which is the

central class in the iostream library. In the central class in the iostream library. In the original version of C++, streambuf was defined original version of C++, streambuf was defined in the form:in the form:

class streambuf {class streambuf { int sgetc(); //return the next character or EOFint sgetc(); //return the next character or EOF int sgetn(char*, int N); //get N charactersint sgetn(char*, int N); //get N characters};};

Page 86: C++ Training Datascope Lawrence D’Antonio

How Much …? 6How Much …? 6

Suppose we want to parametrize this class Suppose we want to parametrize this class with respect to character type. with respect to character type.

We have a problem with the return type of We have a problem with the return type of sgetc(). If we are using a different sgetc(). If we are using a different character type, then we may need a character type, then we may need a different type to represent EOF. different type to represent EOF.

One solution is to also make the return One solution is to also make the return type of sgetc() a type parameter.type of sgetc() a type parameter.

Page 87: C++ Training Datascope Lawrence D’Antonio

How Much …? 7How Much …? 7

template<class charT, class intT>template<class charT, class intT>class basic_stream_buf {class basic_stream_buf { intT sgetc();intT sgetc(); int sgetn(charT*, int N);int sgetn(charT*, int N);};};

Page 88: C++ Training Datascope Lawrence D’Antonio

How Much …? 8How Much …? 8 This has two problems. This has two problems. First of all it is annoying for the user to First of all it is annoying for the user to

have to remember the type of the end-of-have to remember the type of the end-of-file marker. file marker.

Second, and perhaps more important, is Second, and perhaps more important, is the question of how sgetc() should be the question of how sgetc() should be written. written.

What should it actually return in the case What should it actually return in the case that the end of file is found?that the end of file is found?

Page 89: C++ Training Datascope Lawrence D’Antonio

How Much …? 9How Much …? 9

The traits technique works as follows. The traits technique works as follows. One defines a character traits class, which One defines a character traits class, which

gives the properties (i.e., the traits) for gives the properties (i.e., the traits) for each character type for which we want to each character type for which we want to use the iostream library. use the iostream library.

Page 90: C++ Training Datascope Lawrence D’Antonio

How Much …? 10How Much …? 10

One defines the default traits class,One defines the default traits class,template<class charT>template<class charT>struct ios_char_traits { };struct ios_char_traits { }; The default traits class is empty because The default traits class is empty because

what are the traits of an arbitrary character what are the traits of an arbitrary character type?type?

One can specialize this class for specific One can specialize this class for specific character types.character types.

Page 91: C++ Training Datascope Lawrence D’Antonio

How Much …? 11How Much …? 11

Here is the specialized version for char.Here is the specialized version for char.

struct ios_char_traits<char> { struct ios_char_traits<char> { typedef char char_type; typedef char char_type; typedef int int_type; typedef int int_type; static inline int_type eof() { return EOF; } static inline int_type eof() { return EOF; }

}; };

Page 92: C++ Training Datascope Lawrence D’Antonio

How Much …? 12How Much …? 12 Here is the specialized version for wide Here is the specialized version for wide

char.char.

struct ios_char_traits<wchar_t> { struct ios_char_traits<wchar_t> { typedef wchar_t char_type; typedef wchar_t char_type; typedef wint_t int_type; typedef wint_t int_type; static inline int_type eof() { return WEOF; }static inline int_type eof() { return WEOF; }

}; };

Page 93: C++ Training Datascope Lawrence D’Antonio

How Much …? 13How Much …? 13 Here is the revised streambuf class.Here is the revised streambuf class.template <class charT> class basic_streambuf { template <class charT> class basic_streambuf { public: public:

typedef ios_char_traits<charT> traits_type; typedef ios_char_traits<charT> traits_type; typedef traits_type::int_type int_type; typedef traits_type::int_type int_type; int_type eof() { return traits_type::eof(); }int_type eof() { return traits_type::eof(); }int_type sgetc();int_type sgetc();int_type sbumpc(); int_type sbumpc(); int_type snextc();int_type snextc();int sgetn(charT*, int N); int sgetn(charT*, int N);

}; };

Page 94: C++ Training Datascope Lawrence D’Antonio

A Short Tour of STLA Short Tour of STL The components of STLThe components of STL ConceptsConcepts IteratorsIterators Iterator AdaptorsIterator Adaptors ContainersContainers Container AdaptorsContainer Adaptors AlgorithmsAlgorithms FunctorsFunctors AllocatorsAllocators

Page 95: C++ Training Datascope Lawrence D’Antonio

Basic ConceptsBasic Concepts

AssignableAssignable Concept:Concept: A type is Assignable if it allows A type is Assignable if it allows

for copying objects of that type and for for copying objects of that type and for assigning values to variables of that type. assigning values to variables of that type.

Operations:Operations: copy constructor and copy constructor and operator=operator=

Models:Models: All built-in types and STL All built-in types and STL containers, except for const types. containers, except for const types.

Page 96: C++ Training Datascope Lawrence D’Antonio

Basic Concepts 2Basic Concepts 2

Default ConstructibleDefault Constructible Concept:Concept: A type is Default Constructible if A type is Default Constructible if

it has a default constructor. it has a default constructor. Operations:Operations: Default constructor Default constructor Models:Models: All built-in types and STL All built-in types and STL

containers. containers.

Page 97: C++ Training Datascope Lawrence D’Antonio

Basic Concepts 3Basic Concepts 3 Equality ComparableEquality Comparable Concept:Concept: A type is Equality Comparable if two A type is Equality Comparable if two

values of this type can be compared for equality values of this type can be compared for equality using the == operator, and this operator must using the == operator, and this operator must define an equivalence relation. define an equivalence relation.

Operations:Operations: == and != == and != Models:Models: All built-in numeric and pointer types. All built-in numeric and pointer types.

Any STL container of the form Container<T> will Any STL container of the form Container<T> will be Equality Comparable if and only if T is be Equality Comparable if and only if T is Equality Comparable. Equality Comparable.

Page 98: C++ Training Datascope Lawrence D’Antonio

Basic Concepts 4Basic Concepts 4 Less Than ComparableLess Than Comparable Concept:Concept: A type is LessThan Comparable if two A type is LessThan Comparable if two

values of this type can be compared using the < values of this type can be compared using the < operator, and this operator must define a partial operator, and this operator must define a partial ordering. The relation, x strictly divides y, is a ordering. The relation, x strictly divides y, is a partial order for integers that is not a total order.partial order for integers that is not a total order.

Operations:Operations: <, >, <=, >= <, >, <=, >= Models:Models: All built-in numeric types. Pointers All built-in numeric types. Pointers

storing addresses within the same array. storing addresses within the same array. Random Access Iterators traversing the same Random Access Iterators traversing the same container. container.

Page 99: C++ Training Datascope Lawrence D’Antonio

Basic Concepts 5Basic Concepts 5 Strict Weakly ComparableStrict Weakly Comparable Concept:Concept: A type is Strict Weakly Comparable if A type is Strict Weakly Comparable if

two values of this type can be compared using two values of this type can be compared using the < operator, and this operator defines an the < operator, and this operator defines an equivalence relation in the following sense. Two equivalence relation in the following sense. Two values, x and y, are considered equivalent if values, x and y, are considered equivalent if both x < y and y < x are false. Case-insensitive both x < y and y < x are false. Case-insensitive string comparison is a strict weak ordering that string comparison is a strict weak ordering that is not a total ordering. is not a total ordering.

Page 100: C++ Training Datascope Lawrence D’Antonio

Basic Concepts 6Basic Concepts 6

Refines:Refines: LessThan Comparable LessThan Comparable Models:Models: All built-in numeric types. Pointers All built-in numeric types. Pointers

storing addresses within the same array. storing addresses within the same array. Random Access Iterators traversing the Random Access Iterators traversing the same container.same container.

Page 101: C++ Training Datascope Lawrence D’Antonio

IteratorsIterators

An iterator is a generalization of the An iterator is a generalization of the concept of a pointer.concept of a pointer.

An iterator makes it possible to traverse a An iterator makes it possible to traverse a range of objects.range of objects.

Algorithms in STL generally manipulate Algorithms in STL generally manipulate iterators, instead of dealing with data iterators, instead of dealing with data structures directly.structures directly.

Page 102: C++ Training Datascope Lawrence D’Antonio

Iterator ConceptIterator Concept

Trivial iteratorTrivial iterator Input IteratorInput Iterator Output IteratorOutput Iterator Forward IteratorForward Iterator Bidirectional IteratorBidirectional Iterator Random Access IteratorRandom Access Iterator

Page 103: C++ Training Datascope Lawrence D’Antonio

Trivial IteratorTrivial Iterator

Concept:Concept: An object is a Trivial Iterator if it An object is a Trivial Iterator if it can be dereferenced. A Trivial Iterator may can be dereferenced. A Trivial Iterator may be mutable (its dereferenced value may be be mutable (its dereferenced value may be modified) or constant (the dereferenced modified) or constant (the dereferenced value cannot be modified). value cannot be modified).

Refines:Refines: Assignable, Equality Comparable Assignable, Equality Comparable

Page 104: C++ Training Datascope Lawrence D’Antonio

Trivial Iterator 2Trivial Iterator 2

Operations:Operations: Dereference: *p (p must be Dereference: *p (p must be

dereferenceable)dereferenceable) Dereference Assignment: *p = x (p must Dereference Assignment: *p = x (p must

be mutable)be mutable) Member Access: p->m (p must be Member Access: p->m (p must be

dereferenceable)dereferenceable) Equality: p == q (same as &*p == &*q)Equality: p == q (same as &*p == &*q)

Page 105: C++ Training Datascope Lawrence D’Antonio

Trivial Iterator 3Trivial Iterator 3

Models:Models: All pointer and iterator types All pointer and iterator types

Page 106: C++ Training Datascope Lawrence D’Antonio

Input IteratorInput Iterator Concept:Concept: An object is an input iterator if it An object is an input iterator if it

can be dereferenced and incremented. An can be dereferenced and incremented. An input iterator must give read access to its input iterator must give read access to its dereferenced value, but not necessarily dereferenced value, but not necessarily write access. Also, an input iterator does write access. Also, an input iterator does not necessarily support a multipass not necessarily support a multipass algorithm. algorithm.

Input iterators may be mutuable or Input iterators may be mutuable or constant.constant.

Page 107: C++ Training Datascope Lawrence D’Antonio

Input Iterator 2Input Iterator 2

Refines:Refines: Trivial Iterator Trivial Iterator Associated Types:Associated Types: iterator_traits<X>::value_typeiterator_traits<X>::value_type The type of the object dereferenced by The type of the object dereferenced by

iteratoriterator iterator_traits<X>::difference_typeiterator_traits<X>::difference_type A signed integral type representing the A signed integral type representing the

distance from one iterator to another.distance from one iterator to another.

Page 108: C++ Training Datascope Lawrence D’Antonio

Input Iterator 3Input Iterator 3 iterator_traits<X>::referenceiterator_traits<X>::reference Reference to the iterator’s value type.Reference to the iterator’s value type. iterator_traits<X>::pointeriterator_traits<X>::pointer Pointer to the iterator’s value type.Pointer to the iterator’s value type. iterator_traits<X>::iterator_categoryiterator_traits<X>::iterator_category One of the iterator tag types: input_iterator_tag, One of the iterator tag types: input_iterator_tag,

forward_iterator_tag, bidirectional_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tagrandom_access_iterator_tag

Page 109: C++ Training Datascope Lawrence D’Antonio

Input Iterator 4Input Iterator 4 Definitions:Definitions: An iterator is An iterator is past-the-endpast-the-end if it points if it points

beyond the last element of a container.beyond the last element of a container. An input iterator An input iterator jj is reachable from input is reachable from input

iterator iterator ii after applying ++ after applying ++ii a number of a number of times, we have i == j.times, we have i == j.

The notation The notation [i,j)[i,j) refers to a range of refers to a range of iterators beginning with I and up to but not iterators beginning with I and up to but not including j.including j.

Page 110: C++ Training Datascope Lawrence D’Antonio

Input Iterator 5Input Iterator 5

Operations:Operations: Those of Trivial Iterator together with:Those of Trivial Iterator together with: ++i, i++++i, i++ Note: after ++i is executed it is not Note: after ++i is executed it is not

guaranteed that copies of the old value of i guaranteed that copies of the old value of i be dereferenceable. be dereferenceable.

*i++*i++

Page 111: C++ Training Datascope Lawrence D’Antonio

Input Iterator 6Input Iterator 6

Models:Models: All pointer and STL iterators All pointer and STL iterators (except for ostream_iterator). The (except for ostream_iterator). The istream_iterator, used for traversing input istream_iterator, used for traversing input streams, is an example of an input iterator streams, is an example of an input iterator that does not belong to any of the classes that does not belong to any of the classes defined below.defined below.

Page 112: C++ Training Datascope Lawrence D’Antonio

Output IteratorOutput Iterator

Concept:Concept: An object is an output iterator if An object is an output iterator if it can store to its present location and be it can store to its present location and be incremented. An output iterator must give incremented. An output iterator must give write access to its location, but not write access to its location, but not necessarily read access. Also, an output necessarily read access. Also, an output iterator does not necessarily support a iterator does not necessarily support a multipass algorithm. multipass algorithm.

Page 113: C++ Training Datascope Lawrence D’Antonio

Output Iterator 2Output Iterator 2

Refines:Refines: Assignable Assignable Associated Types: Associated Types: Only the followingOnly the following iterator_categoryiterator_category One of the iterator tag types: One of the iterator tag types:

output_iterator_tag, forward_iterator_tag, output_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tagrandom_access_iterator_tag

Page 114: C++ Training Datascope Lawrence D’Antonio

Output Iterator 3Output Iterator 3

Operations: those of Assignable together Operations: those of Assignable together withwith

Dereference assignment: *x = tDereference assignment: *x = t ++x, x++++x, x++ Postincrement assignment: *x++ = tPostincrement assignment: *x++ = t

Page 115: C++ Training Datascope Lawrence D’Antonio

Output Iterator 4Output Iterator 4

Models:Models: front_insert_iterator, front_insert_iterator, back_insert_iterator, insert_iterator, back_insert_iterator, insert_iterator, ostream_iteratorostream_iterator

Page 116: C++ Training Datascope Lawrence D’Antonio

Forward IteratorForward Iterator

Concept:Concept: An object is a Forward Iterator if An object is a Forward Iterator if the iterator may be incremented and gives the iterator may be incremented and gives both read and write access (for mutable both read and write access (for mutable iterators).iterators).

Refines:Refines: Default Constructible, Input Default Constructible, Input Iterator, Output Iterator Iterator, Output Iterator

Page 117: C++ Training Datascope Lawrence D’Antonio

Forward Iterator 2Forward Iterator 2

Associated Types:Associated Types: Same as Input Same as Input Iterator.Iterator.

Operations:Operations: Same as Default Same as Default Constructible and Input Iterator (but not Constructible and Input Iterator (but not the restrictions of Input Iterator).the restrictions of Input Iterator).

Models:Models: Pointers, all STL container Pointers, all STL container iterators iterators

Page 118: C++ Training Datascope Lawrence D’Antonio

Bidirectional IteratorBidirectional Iterator

Concept:Concept: An object is a bidirectional An object is a bidirectional iterator if it allows for increments and iterator if it allows for increments and decrements. It gives both read and write decrements. It gives both read and write access (for mutable iterators). access (for mutable iterators).

Refines:Refines: Forward Iterator Forward Iterator Associated Types:Associated Types: Same as for Forward Same as for Forward

IteratorIterator

Page 119: C++ Training Datascope Lawrence D’Antonio

Bidirectional Iterator 2Bidirectional Iterator 2

Operations:Operations: Those of Forward Iterator Those of Forward Iterator together with --x, x--.together with --x, x--.

Invariant:Invariant: ++x; --x; or --x; ++x; are null operations++x; --x; or --x; ++x; are null operations Models:Models: Pointers, all STL container Pointers, all STL container

iterators iterators

Page 120: C++ Training Datascope Lawrence D’Antonio

Random Access IteratorRandom Access Iterator

Concept:Concept: An object is a Random Access An object is a Random Access Iterator if it allows arbitrary jumps and Iterator if it allows arbitrary jumps and pointer arithmetic.pointer arithmetic.

Refines:Refines: Bidirectional Iterator Bidirectional Iterator Associated Types:Associated Types: Same as for Same as for

Bidirectional Iterator.Bidirectional Iterator.

Page 121: C++ Training Datascope Lawrence D’Antonio

Random Access Iterator 2Random Access Iterator 2 Operations: Operations: i += n (equivalent to performing ++i n i += n (equivalent to performing ++i n

timestimes i -= n (equivalent to i += (-n) )i -= n (equivalent to i += (-n) ) i+n, n+i i+n, n+i Equivalent to X tmp = i; return tmp += n;Equivalent to X tmp = i; return tmp += n; i-n;i-n; Equivalent to X tmp = i; return tmp -= n;Equivalent to X tmp = i; return tmp -= n;

Page 122: C++ Training Datascope Lawrence D’Antonio

Random Access Iterator 3Random Access Iterator 3 More operations:More operations: i – ji – j Returns a number n such that i == j+nReturns a number n such that i == j+n i[n]i[n] Equivalent to *(i + n)Equivalent to *(i + n) Invariants:Invariants: If i + n is defined then i += n; i -= n; is a If i + n is defined then i += n; i -= n; is a

null operation (similarly for i – n)null operation (similarly for i – n)

Page 123: C++ Training Datascope Lawrence D’Antonio

Random Access Iterator 4Random Access Iterator 4

Models: Pointers and the iterators for Models: Pointers and the iterators for vector and deque containers. vector and deque containers.

Page 124: C++ Training Datascope Lawrence D’Antonio

Iterator AdaptorsIterator Adaptors

An iterator adaptor is a class that is a An iterator adaptor is a class that is a wrapper for an iterator.wrapper for an iterator.

Adaptors have their own concepts Adaptors have their own concepts (discussed below).(discussed below).

Page 125: C++ Training Datascope Lawrence D’Antonio

Reverse IteratorReverse Iterator

Concept:Concept: A reverse_iterator takes a A reverse_iterator takes a bidirectional or random access iterator and bidirectional or random access iterator and creates a new iterator that traverses in the creates a new iterator that traverses in the opposite direction of usual iteration. opposite direction of usual iteration.

Operations:Operations: *p, ++p, p++ (each performs *p, ++p, p++ (each performs a decrement), --p, p--(each performs an a decrement), --p, p--(each performs an increment).increment).

Page 126: C++ Training Datascope Lawrence D’Antonio

Reverse Iterator 2Reverse Iterator 2 ExampleExamplevector<int> v;vector<int> v;//Suppose we place data in v//Suppose we place data in vcopy(v.rbegin(), v.rend(), copy(v.rbegin(), v.rend(),

ostream_iterator<int>(cout," "));ostream_iterator<int>(cout," ")); This copies the data from to cout in reverse This copies the data from to cout in reverse

order. The call, v.rbegin() creates a order. The call, v.rbegin() creates a reverse_iterator that points to the last location in reverse_iterator that points to the last location in v. The call, v.rend(), points to a position one v. The call, v.rend(), points to a position one before the first location in v.before the first location in v.

Page 127: C++ Training Datascope Lawrence D’Antonio

Istream IteratorIstream Iterator

Concept:Concept: An istream_iterator is used for An istream_iterator is used for traversing an input stream (allowing only traversing an input stream (allowing only read access and increments). read access and increments).

Models:Models: Input Iterator Input Iterator

Page 128: C++ Training Datascope Lawrence D’Antonio

Ostream IteratorOstream Iterator

Concept:Concept: An ostream_iterator is used for An ostream_iterator is used for traversing an output stream (allowing only traversing an output stream (allowing only write access and decrements). write access and decrements).

Models:Models: Output Iterator Output Iterator

Page 129: C++ Training Datascope Lawrence D’Antonio

Back Insert IteratorBack Insert Iterator Concept:Concept: A back_insert_iterator takes a A back_insert_iterator takes a

container x and converts assignments into container x and converts assignments into x.push_back(). Frequently one uses the x.push_back(). Frequently one uses the template function back_inserter, that template function back_inserter, that returns a back_insert_iterator. returns a back_insert_iterator.

Operations:Operations: *p, ++p, p++ (all do nothing *p, ++p, p++ (all do nothing except return *this). *p = t (calls except return *this). *p = t (calls x.push_back(t), where x is the container x.push_back(t), where x is the container associated with p). associated with p).

Page 130: C++ Training Datascope Lawrence D’Antonio

Back Insert Iterator 2Back Insert Iterator 2

Models:Models: Output Iterator Output Iterator

Page 131: C++ Training Datascope Lawrence D’Antonio

Front Insert IteratorFront Insert Iterator Concept:Concept: A front_insert_iterator takes a A front_insert_iterator takes a

container x and converts assignments into container x and converts assignments into x.push_front(). Frequently one uses the x.push_front(). Frequently one uses the template function front_inserter, that template function front_inserter, that returns a front_insert_iterator. returns a front_insert_iterator.

Operations:Operations: *p, ++p, p++ (all do nothing *p, ++p, p++ (all do nothing except return *this). *p = t (calls except return *this). *p = t (calls x.push_front(t), where x is the container x.push_front(t), where x is the container associated with p). associated with p).

Page 132: C++ Training Datascope Lawrence D’Antonio

Front Insert Iterator 2Front Insert Iterator 2

Models:Models: Output Iterator Output Iterator

Page 133: C++ Training Datascope Lawrence D’Antonio

Insert IteratorInsert Iterator Concept:Concept: An insert_iterator takes a An insert_iterator takes a

container x and converts assignments into container x and converts assignments into x.insert(). Frequently one uses the x.insert(). Frequently one uses the template function inserter, that returns a template function inserter, that returns a insert_iterator. insert_iterator.

Operations:Operations: *p, ++p, p++ (all do nothing *p, ++p, p++ (all do nothing except return *this). *p = t (calls except return *this). *p = t (calls x.insert(p,t), where x is the container x.insert(p,t), where x is the container associated with p).associated with p).

Page 134: C++ Training Datascope Lawrence D’Antonio

Insert Iterator 2Insert Iterator 2

Models:Models: Output Iterator Output Iterator

Page 135: C++ Training Datascope Lawrence D’Antonio

ExampleExample Suppose we want to read in a file of Suppose we want to read in a file of

grades.grades.multiset<int> grade_set;multiset<int> grade_set;ifstream in_file("grades.dat");ifstream in_file("grades.dat");  copy(istream_iterator<int>(in_file), copy(istream_iterator<int>(in_file), istream_iterator<int>(),istream_iterator<int>(), inserter(grade_set));inserter(grade_set));

Page 136: C++ Training Datascope Lawrence D’Antonio

Iterator traitsIterator traits

struct input_iterator_tag {};struct input_iterator_tag {};struct output_iterator_tag {};struct output_iterator_tag {};struct forward_iterator_tagstruct forward_iterator_tag

: public input_iterator_tag {};: public input_iterator_tag {};struct bidirectional_iterator_tagstruct bidirectional_iterator_tag

: public forward_iterator_tag {};: public forward_iterator_tag {};struct random_access_iterator_tagstruct random_access_iterator_tag

: public bidirectional_iterator_tag {};: public bidirectional_iterator_tag {};

Page 137: C++ Training Datascope Lawrence D’Antonio

Iterator traits 2Iterator traits 2template<class Iterator>template<class Iterator>struct iterator_traits {struct iterator_traits {

typedef typename Iterator::iterator_categorytypedef typename Iterator::iterator_categoryiterator_category;iterator_category;typedef typename Iterator::value_type typedef typename Iterator::value_type value_type;value_type;typedef typename Iterator::difference_typetypedef typename Iterator::difference_type

difference_type;difference_type;typedef typename Iterator::pointer typedef typename Iterator::pointer pointer;pointer;typedef typename Iterator::reference typedef typename Iterator::reference reference;reference;

};};

Page 138: C++ Training Datascope Lawrence D’Antonio

Iterator traits 3Iterator traits 3

template<class T>template<class T>struct iterator_traits<T*> {struct iterator_traits<T*> {

typedef random_access_iterator_tagtypedef random_access_iterator_tagiterator_category;iterator_category;

typedef T typedef T value_type;value_type;typedef ptrdiff_t difference_type;typedef ptrdiff_t difference_type;typedef T* typedef T* pointer;pointer;typedef T& reference;typedef T& reference;

};};

Page 139: C++ Training Datascope Lawrence D’Antonio

Iterator traits 4Iterator traits 4

template<class T>template<class T>struct iterator_traits<const T*> {struct iterator_traits<const T*> {

typedef random_access_iterator_tagtypedef random_access_iterator_tagiterator_category;iterator_category;

typedef T typedef T value_type;value_type;typedef ptrdiff_t difference_type;typedef ptrdiff_t difference_type;typedef const T* pointer;typedef const T* pointer;typedef const T& reference;typedef const T& reference;

};};

Page 140: C++ Training Datascope Lawrence D’Antonio

Iterator traits 5Iterator traits 5template<class Category, class Value, template<class Category, class Value, class Distance = ptrdiff_t, class Distance = ptrdiff_t, class Pointer = Value*, class Pointer = Value*, class Reference = Value&>class Reference = Value&>struct iterator {struct iterator {

typedef Category iterator_category;typedef Category iterator_category;typedef Value value_type;typedef Value value_type;typedef Distance difference_type;typedef Distance difference_type;typedef Pointer pointer;typedef Pointer pointer;typedef Reference reference;typedef Reference reference;

};};

Page 141: C++ Training Datascope Lawrence D’Antonio

Iterator traits 6Iterator traits 6

template<class Value, class Distance,template<class Value, class Distance, class Pointer, class Reference>class Pointer, class Reference>struct BidirectionalIteratorstruct BidirectionalIterator: public Iterator<bidirectional_iterator_tag,: public Iterator<bidirectional_iterator_tag, Value,Distance,Pointer, Value,Distance,Pointer, Reference> {};Reference> {};

Page 142: C++ Training Datascope Lawrence D’Antonio

Iterator traits 7Iterator traits 7

template<class Value, class Distance,template<class Value, class Distance, class Pointer, class Reference>class Pointer, class Reference>struct RandomAccessIteratorstruct RandomAccessIterator: public Iterator<random_access_iterator_tag, : public Iterator<random_access_iterator_tag,

Value,Distance, Value,Distance, Pointer,Reference> {};Pointer,Reference> {};

Page 143: C++ Training Datascope Lawrence D’Antonio

Iterator traits 8Iterator traits 8

template<class Value, class Distance,template<class Value, class Distance, class Pointer, class Reference>class Pointer, class Reference>struct OutputIteratorstruct OutputIterator: public Iterator<output_iterator_tag,: public Iterator<output_iterator_tag,

Value,Distance,Value,Distance, Pointer,Reference> {};Pointer,Reference> {};

Page 144: C++ Training Datascope Lawrence D’Antonio

Iterator traits 9Iterator traits 9

template<class InputIter, class Distance>template<class InputIter, class Distance>void advance(InputIter &I, Distance N)void advance(InputIter &I, Distance N){{

Advance(I, N, typename Advance(I, N, typename iterator_traits<InputIter>::iterator_category());iterator_traits<InputIter>::iterator_category());

}}

Page 145: C++ Training Datascope Lawrence D’Antonio

Iterator traits 10Iterator traits 10

template<class InputIter, class Distance>template<class InputIter, class Distance>void Advance(InputIter &I, Distance N,void Advance(InputIter &I, Distance N,

input_iterator_tag) input_iterator_tag) {{

for( ; 0 < N; --N)for( ; 0 < N; --N)++I;++I;

}}

Page 146: C++ Training Datascope Lawrence D’Antonio

Iterator traits 11Iterator traits 11

template<class ForwardIter, class Distance>template<class ForwardIter, class Distance>void Advance(ForwardIter &I, Distance N,void Advance(ForwardIter &I, Distance N,

forward_iterator_tag) {forward_iterator_tag) {for( ; 0 < N; --N)for( ; 0 < N; --N)

++I;++I;}}

Page 147: C++ Training Datascope Lawrence D’Antonio

Iterator traits 12Iterator traits 12

template<class BidirectionalIter, class Distance>template<class BidirectionalIter, class Distance>void Advance(BidirectionalIter &I, Distance N, void Advance(BidirectionalIter &I, Distance N,

bidirectional_iterator_tag) {bidirectional_iterator_tag) {for( ; 0 < N; --N)for( ; 0 < N; --N)

++I;++I;for( ; N < 0; ++N)for( ; N < 0; ++N)

--I;--I;}}

Page 148: C++ Training Datascope Lawrence D’Antonio

Iterator traits 13Iterator traits 13

template<class RandomAccessIter, template<class RandomAccessIter, class Distance>class Distance>

void Advance(RandomAccessIter &I, void Advance(RandomAccessIter &I, Distance N, forward_iterator_tag) {Distance N, forward_iterator_tag) {

I += N;I += N;}}

Page 149: C++ Training Datascope Lawrence D’Antonio

Container conceptsContainer concepts

There are several container concepts that There are several container concepts that are used in STL.are used in STL.

There are three types of containers: There are three types of containers: general containers which are models for general containers which are models for types of iterators, sequence containers, types of iterators, sequence containers, and associative containers.and associative containers.

Page 150: C++ Training Datascope Lawrence D’Antonio

ContainerContainer

Concept:Concept: A Container stores other A Container stores other objects. The lifetimes of these objects are objects. The lifetimes of these objects are at most the lifetime of the Container. at most the lifetime of the Container.

Refines:Refines: Assignable Assignable Associated TypesAssociated Types X::value_type: the type of the elements of X::value_type: the type of the elements of

the container. Must be Assignable.the container. Must be Assignable.

Page 151: C++ Training Datascope Lawrence D’Antonio

Container 2Container 2

X::reference: behaves as a reference to X::reference: behaves as a reference to the Container’s value type (usually just the Container’s value type (usually just value_type&).value_type&).

X::const_reference: usually just const X::const_reference: usually just const value_type&value_type&

X::pointer: behaves as a pointer to the X::pointer: behaves as a pointer to the Container’s elements (usually just Container’s elements (usually just value_type*, but can be a smart pointer)value_type*, but can be a smart pointer)

Page 152: C++ Training Datascope Lawrence D’Antonio

Container 3Container 3

X::const_pointer: usually just const X::const_pointer: usually just const value_type*.value_type*.

X::iterator: an iterator that points to the X::iterator: an iterator that points to the Container’s elements. Must be at least an Container’s elements. Must be at least an Input Iterator.Input Iterator.

X::const_iterator: a constant iterator that X::const_iterator: a constant iterator that points to the Container’s elements.points to the Container’s elements.

Page 153: C++ Training Datascope Lawrence D’Antonio

Container 4Container 4

X::difference_type: a signed integral type X::difference_type: a signed integral type used to measure the distance between used to measure the distance between two of the Container’s iterators.two of the Container’s iterators.

X::size_type: an unsigned integral type X::size_type: an unsigned integral type that can represent nonnegative values of that can represent nonnegative values of the Container’s difference type.the Container’s difference type.

Page 154: C++ Training Datascope Lawrence D’Antonio

Container 5Container 5

Operations:Operations: copy constructor, copy constructor, assignment (if LHS is mutable), destructor, assignment (if LHS is mutable), destructor, begin(), end(), size(), max_size() (for that begin(), end(), size(), max_size() (for that type of Container), empty(), swap()type of Container), empty(), swap()

Models:Models: all STL containers. all STL containers.

Page 155: C++ Training Datascope Lawrence D’Antonio

Forward ContainerForward Container

Concept:Concept: A Forward Container stores A Forward Container stores elements in a definite order. These elements in a definite order. These containers support forward iterators. containers support forward iterators.

Refines:Refines: Container, Equality Comparable, Container, Equality Comparable, LessThan ComparableLessThan Comparable

Associated Types:Associated Types: same as Container, same as Container, except X::iterator must be a Forward except X::iterator must be a Forward Iterator. Iterator.

Page 156: C++ Training Datascope Lawrence D’Antonio

Forward Container 2Forward Container 2

Operations:Operations: Same as Container plus the Same as Container plus the following.following.

==, !=, <, >, <=, >= (the last four use a ==, !=, <, >, <=, >= (the last four use a lexicographical comparison).lexicographical comparison).

Models: All STL containers Models: All STL containers

Page 157: C++ Training Datascope Lawrence D’Antonio

Reversible ContainerReversible Container

Concept:Concept: A Reversible Container defines A Reversible Container defines a bidirectional iterator.a bidirectional iterator.

Refines:Refines: Forward Container Forward Container Associated Types:Associated Types: All types associated All types associated

with Container (with the requirement that with Container (with the requirement that iterators must be Bidirectional Iterators) iterators must be Bidirectional Iterators) plus the following:plus the following:

Page 158: C++ Training Datascope Lawrence D’Antonio

Reversible Container 2Reversible Container 2

X::reverse_iterator: A reverse iterator X::reverse_iterator: A reverse iterator adaptor that has X::iterator as its base adaptor that has X::iterator as its base iterator type. The reverse iterator maps iterator type. The reverse iterator maps operator++ to operator– (and vice versa).operator++ to operator– (and vice versa).

X::const_reverse_iterator: A reverse X::const_reverse_iterator: A reverse iterator adaptor that has X::const_iterator iterator adaptor that has X::const_iterator as its base iterator type.as its base iterator type.

Page 159: C++ Training Datascope Lawrence D’Antonio

Reversible Container 3Reversible Container 3

Operations:Operations: Same as Forward Container Same as Forward Container plus the following.plus the following.

rbegin() (points at last element of the rbegin() (points at last element of the container)container)

rend() (points at one before the first rend() (points at one before the first element of the container)element of the container)

Models:Models: All STL containers All STL containers

Page 160: C++ Training Datascope Lawrence D’Antonio

Random Access ContainerRandom Access Container

Concept:Concept: A Random Access Container A Random Access Container defines a random access iterator. defines a random access iterator.

Operations:Operations: Those of Reversible Those of Reversible Container plus element access, Container plus element access, a[n]a[n]..

Models:Models: Vectors and deques. Vectors and deques.

Page 161: C++ Training Datascope Lawrence D’Antonio

Vector ExampleVector Example Here is a program illustrating some ways of initializing a Here is a program illustrating some ways of initializing a

vector, together with a common error. The program below vector, together with a common error. The program below inserts a range of values into vectors v1, v2, v3, v4 by a inserts a range of values into vectors v1, v2, v3, v4 by a variety of methods.variety of methods.

   One can insert a range of the form [first, last) via:One can insert a range of the form [first, last) via:   - Constructor- Constructor vector<T> v(first,last);vector<T> v(first,last);   - Assign member function. This method deletes any data - Assign member function. This method deletes any data

previously held in the vectorpreviously held in the vector v.assign(first,last)v.assign(first,last)

Page 162: C++ Training Datascope Lawrence D’Antonio

Vector Example 2Vector Example 2 - Insert member function. This method does not delete - Insert member function. This method does not delete

any existing data. The following inserts the range at the any existing data. The following inserts the range at the end of vector. Any valid location could be used as the end of vector. Any valid location could be used as the insertion point.insertion point.

v.insert(v.end(), first, last);v.insert(v.end(), first, last);   - Copy algorithm. This algorithm assumes that the space - Copy algorithm. This algorithm assumes that the space

for the data being copied already exists. So the following for the data being copied already exists. So the following version is incorrect if v does not already have space version is incorrect if v does not already have space allocated to hold the data to be copied. The code will allocated to hold the data to be copied. The code will compile, but crash at run-time.compile, but crash at run-time.

copy(first, last, v.begin());copy(first, last, v.begin());

Page 163: C++ Training Datascope Lawrence D’Antonio

Vector Example 3Vector Example 3main()main(){{ int a[5] = {7, 3, 2, 5, 9};int a[5] = {7, 3, 2, 5, 9};   std::vector<int> v1(&a[0], &a[5]);std::vector<int> v1(&a[0], &a[5]); std::cout << "Vector 1: ";std::cout << "Vector 1: "; std::copy(v1.begin(), v1.end(), std::ostream_iterator<int>(cout," "));std::copy(v1.begin(), v1.end(), std::ostream_iterator<int>(cout," ")); cout << "\n\n";cout << "\n\n";   std::vector<int> v2;std::vector<int> v2; v2.assign(v1.begin(),v1.end());v2.assign(v1.begin(),v1.end()); cout << "Vector 2: ";cout << "Vector 2: "; std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(cout," "));std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(cout," ")); cout << "\n\n";cout << "\n\n";

Page 164: C++ Training Datascope Lawrence D’Antonio

Vector Example 4Vector Example 4vector<int> v3;vector<int> v3;

v3.insert(v3.end(),v2.begin(),v2.end());v3.insert(v3.end(),v2.begin(),v2.end()); cout << "Vector 3: ";cout << "Vector 3: "; copy(v3.begin(), v3.end(), ostream_iterator<int>(cout," "));copy(v3.begin(), v3.end(), ostream_iterator<int>(cout," ")); cout << "\n\n";cout << "\n\n";   vector<int> v4;vector<int> v4; //copy(v3.begin(), v3.end(), v4.begin());//copy(v3.begin(), v3.end(), v4.begin()); copy(v3.begin(), v3.end(), back_inserter(v4));copy(v3.begin(), v3.end(), back_inserter(v4)); cout << "Vector 4: ";cout << "Vector 4: "; copy(v4.begin(), v4.end(), ostream_iterator<int>(cout," "));copy(v4.begin(), v4.end(), ostream_iterator<int>(cout," ")); cout << "\n\n";cout << "\n\n";}}

Page 165: C++ Training Datascope Lawrence D’Antonio

Sequence ContainerSequence Container

Concept:Concept: A Sequence stores its elements A Sequence stores its elements in a linear ordering. in a linear ordering.

Refines:Refines: Forward Container, Default Forward Container, Default Constructible Constructible

Operations:Operations: Those of Forward Container Those of Forward Container plus,plus,

Default constructor, Default constructor,

Page 166: C++ Training Datascope Lawrence D’Antonio

Sequence Container 2Sequence Container 2

Fill constructor c(n,x) creates container Fill constructor c(n,x) creates container with n copies equal to xwith n copies equal to x

Fill constructor c(n) creates container with Fill constructor c(n) creates container with n elements initialized to default value,n elements initialized to default value,

Range constructor c(i,j). Here, i and j are Range constructor c(i,j). Here, i and j are input iterators. Creates a sequence that is input iterators. Creates a sequence that is a copy of the range [i,j).a copy of the range [i,j).

Page 167: C++ Training Datascope Lawrence D’Antonio

Sequence Container 3Sequence Container 3 Insert: c.insert(p,x) inserts the value x Insert: c.insert(p,x) inserts the value x

before position p. before position p. Special cases:Special cases: a.insert(a.begin(), x) inserts x before the a.insert(a.begin(), x) inserts x before the

first element of a.first element of a. a.insert(a.end(),x) inserts x after the last a.insert(a.end(),x) inserts x after the last

element of a.element of a. Note: the iterator p need not be valid after Note: the iterator p need not be valid after

the insert is performed.the insert is performed.

Page 168: C++ Training Datascope Lawrence D’Antonio

Sequence Container 4Sequence Container 4

Fill insert: a.insert(p, n, x) inserts n copies Fill insert: a.insert(p, n, x) inserts n copies of value x before position p.of value x before position p.

This is guaranteed to be no slower than This is guaranteed to be no slower than calling insert(p,x) n times.calling insert(p,x) n times.

Range insert: a.insert(p, i, j) inserts a copy Range insert: a.insert(p, i, j) inserts a copy of the range [i,j) before position p.of the range [i,j) before position p.

Page 169: C++ Training Datascope Lawrence D’Antonio

Sequence Container 5Sequence Container 5

Erase: a.erase(p) erases the element at Erase: a.erase(p) erases the element at position p.position p.

This assumes that p is dereferenceable.This assumes that p is dereferenceable. It returns an iterator to the element It returns an iterator to the element

immediately following the one removed or immediately following the one removed or else a.end() if there is no such element.else a.end() if there is no such element.

Note: erase may invalidate iterators into Note: erase may invalidate iterators into the sequence.the sequence.

Page 170: C++ Training Datascope Lawrence D’Antonio

Sequence Container 6Sequence Container 6

Range erase: a.erase(p,q) erases all Range erase: a.erase(p,q) erases all elements in the range [p,q).elements in the range [p,q).

The return value is an iterator pointing to The return value is an iterator pointing to the element immediately after the range the element immediately after the range that was removed or a.end() if no such that was removed or a.end() if no such element exists.element exists.

Page 171: C++ Training Datascope Lawrence D’Antonio

Sequence Container 7Sequence Container 7

Front: a.front() returns a reference to the Front: a.front() returns a reference to the first element in the sequence.first element in the sequence.

Assumes the sequence is not empty.Assumes the sequence is not empty. Models:Models: vector, list, deque vector, list, deque

Page 172: C++ Training Datascope Lawrence D’Antonio

Sequence Container 8Sequence Container 8

Can the range insertion be used to copy Can the range insertion be used to copy from a container to itself?from a container to itself?

Can the range overlap with the position of Can the range overlap with the position of the insertion?the insertion?

Consider the following example.Consider the following example.

Page 173: C++ Training Datascope Lawrence D’Antonio

Sequence Container 9Sequence Container 9main() {main() { std::vector<int> v;std::vector<int> v; int a[ ] = {5,2,3,4,6};int a[ ] = {5,2,3,4,6};

v.insert(v.end(),&a[0],&a[5]);v.insert(v.end(),&a[0],&a[5]);

std::vector<int>::iterator p,i;std::vector<int>::iterator p,i; p = find(v.begin(),v.end(),2);p = find(v.begin(),v.end(),2);

v.insert(p,v.begin(),v.end());v.insert(p,v.begin(),v.end()); copy(v.begin(),v.end(),copy(v.begin(),v.end(), std::ostream_iterator<int>(std::cout, " "));std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n';std::cout << '\n';}}

Page 174: C++ Training Datascope Lawrence D’Antonio

Sequence Container 10Sequence Container 10

The output isThe output is5 5 2 3 4 6 2 3 4 65 5 2 3 4 6 2 3 4 6

How does the insert function work?How does the insert function work?

Page 175: C++ Training Datascope Lawrence D’Antonio

vector::insertvector::insert

template<class InputIter>template<class InputIter>void insert(iterator p, InputIter F, InputIter L)void insert(iterator p, InputIter F, InputIter L){{

size_type M = F - L;size_type M = F - L;size_type N = capacity();size_type N = capacity();

Page 176: C++ Training Datascope Lawrence D’Antonio

vector::insert 2vector::insert 2

if (M == 0)if (M == 0);;

else if (max_size() < M + size())else if (max_size() < M + size())throw length_error("vector too long");throw length_error("vector too long");

Page 177: C++ Training Datascope Lawrence D’Antonio

vector::insert 3vector::insert 3else if (N < size() + M) {else if (N < size() + M) {

N = (max_size() < N + N/2) ? N + N/2 : size() + N = (max_size() < N + N/2) ? N + N/2 : size() + M;M;

pointer S = Mybase::Alval.allocate(N, (void *) pointer S = Mybase::Alval.allocate(N, (void *) 0);0);

pointer Q;pointer Q;Q = copy(begin(),P,S);Q = copy(begin(),P,S);Q = copy(F,L,Q);Q = copy(F,L,Q);copy(P,end(),Q);copy(P,end(),Q);

}}

Page 178: C++ Training Datascope Lawrence D’Antonio

vector::insert 4vector::insert 4

else if ( (size_type) (end() - P) < M ) {else if ( (size_type) (end() - P) < M ) {copy(P, end(), P+M);copy(P, end(), P+M);

InputIter Mid = F;InputIter Mid = F;advance(Mid, end() - P);advance(Mid, end() - P);

copy(Mid, L, end());copy(Mid, L, end());copy(F, Mid, P);copy(F, Mid, P);

}}

Page 179: C++ Training Datascope Lawrence D’Antonio

vector::insert 5vector::insert 5

else if ( 0 < M ) {else if ( 0 < M ) {iterator Old_end() = end();iterator Old_end() = end();copy(Old_end - M, Old_end, end());copy(Old_end - M, Old_end, end());copy_backward(P, Old_end - M, copy_backward(P, Old_end - M,

Old_end);Old_end);copy(F,L,P);copy(F,L,P);

}}}}

Page 180: C++ Training Datascope Lawrence D’Antonio

GCC vector::insertGCC vector::insert

template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc> template<typename _ForwardIterator>template<typename _ForwardIterator>

voidvoid vector<_Tp,_Alloc>::vector<_Tp,_Alloc>:: _M_range_insert(iterator __position,_ForwardIterator _M_range_insert(iterator __position,_ForwardIterator

__first, _ForwardIterator __last, forward_iterator_tag)__first, _ForwardIterator __last, forward_iterator_tag){{

Page 181: C++ Training Datascope Lawrence D’Antonio

GCC vector::insert 2GCC vector::insert 2

if (__first != __last)if (__first != __last) {{ size_type __n = std::distance(__first, __last);size_type __n = std::distance(__first, __last); if (size_type(this->_M_impl._M_end_of_storage – if (size_type(this->_M_impl._M_end_of_storage –

this->_M_impl._M_finish) >= __n)this->_M_impl._M_finish) >= __n) {{

Page 182: C++ Training Datascope Lawrence D’Antonio

GCC vector::insert 3GCC vector::insert 3 const size_type __elems_after = end() - __position;const size_type __elems_after = end() - __position;

iterator __old_finish(this->_M_impl._M_finish);iterator __old_finish(this->_M_impl._M_finish); if (__elems_after > __n)if (__elems_after > __n) { { std::uninitialized_copy(this->_M_impl._M_finish - std::uninitialized_copy(this->_M_impl._M_finish -

__n, this->_M_impl._M_finish, this->_M_impl._M_finish);__n, this->_M_impl._M_finish, this->_M_impl._M_finish);

this->_M_impl._M_finish += __n;this->_M_impl._M_finish += __n; std::copy_backward(__position, __old_finish - __n, std::copy_backward(__position, __old_finish - __n,

__old_finish);__old_finish); std::copy(__first, __last, __position);std::copy(__first, __last, __position); } }

Page 183: C++ Training Datascope Lawrence D’Antonio

GCC vector::insert 4GCC vector::insert 4 elseelse {{ _ForwardIterator __mid = __first;_ForwardIterator __mid = __first; std::advance(__mid, __elems_after);std::advance(__mid, __elems_after); std::uninitialized_copy(__mid, __last, std::uninitialized_copy(__mid, __last,

this->_M_impl._M_finish);this->_M_impl._M_finish); this->_M_impl._M_finish += __elems_after;this->_M_impl._M_finish += __elems_after; std::copy(__first, __mid, __position);std::copy(__first, __mid, __position); }} }}

Page 184: C++ Training Datascope Lawrence D’Antonio

GCC vector::insert 5GCC vector::insert 5elseelse{{ const size_type __old_size = size();const size_type __old_size = size(); const size_type __len = __old_size + const size_type __len = __old_size +

std::max(__old_size, __n);std::max(__old_size, __n); iterator __new_start(this->_M_allocate(__len));iterator __new_start(this->_M_allocate(__len)); iterator __new_finish(__new_start);iterator __new_finish(__new_start); trytry {{ __new_finish = __new_finish =

std::uninitialized_copy(iterator(this->_M_impl._M_start),std::uninitialized_copy(iterator(this->_M_impl._M_start), __position, __new_start);__position, __new_start);

Page 185: C++ Training Datascope Lawrence D’Antonio

GCC vector::insert 6GCC vector::insert 6 __new_finish = __new_finish =

std::uninitialized_copy(__first, __last, __new_finish);std::uninitialized_copy(__first, __last, __new_finish);

__new_finish = std::uninitialized_copy(__position,__new_finish = std::uninitialized_copy(__position, iterator(this->_M_impl._M_finish), __new_finish);iterator(this->_M_impl._M_finish), __new_finish);}}catch(...)catch(...){{ std::_Destroy(__new_start,__new_finish);std::_Destroy(__new_start,__new_finish); _M_deallocate(__new_start.base(), __len);_M_deallocate(__new_start.base(), __len); __throw_exception_again;__throw_exception_again;}}

Page 186: C++ Training Datascope Lawrence D’Antonio

GCC vector::insert 7GCC vector::insert 7std::_Destroy(this->_M_impl._M_start, std::_Destroy(this->_M_impl._M_start,

this->_M_impl._M_finish);this->_M_impl._M_finish);_M_deallocate(this->_M_impl._M_start,_M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage – this->_M_impl._M_end_of_storage –

this->_M_impl._M_start);this->_M_impl._M_start);this->_M_impl._M_start = __new_start.base();this->_M_impl._M_start = __new_start.base();this->_M_impl._M_finish = __new_finish.base();this->_M_impl._M_finish = __new_finish.base();this->_M_impl._M_end_of_storage = this->_M_impl._M_end_of_storage =

__new_start.base() + __len;__new_start.base() + __len; }} }} }}

Page 187: C++ Training Datascope Lawrence D’Antonio

Is this legal?Is this legal?template<class T>template<class T>class my_sequence {class my_sequence {private:private:

//Some data //Some data public:public:

//Assume the appropriate iterator has been defined//Assume the appropriate iterator has been defined

//Consider the following insert functions//Consider the following insert functionsvoid insert(iterator p, size_type n, const T &t) void insert(iterator p, size_type n, const T &t) { std::cout << "insert(p,n,t)\n"; }{ std::cout << "insert(p,n,t)\n"; }

template<class InputIterator>template<class InputIterator>void insert(iterator p, InputIterator first, InputIterator last) void insert(iterator p, InputIterator first, InputIterator last) { std::cout << "insert(p,first,last)\n"; }{ std::cout << "insert(p,first,last)\n"; }

};};

Page 188: C++ Training Datascope Lawrence D’Antonio

Example 2Example 2

main() {main() {my_sequence<int> m;my_sequence<int> m;

m.insert(m.begin(), 100, 5);m.insert(m.begin(), 100, 5);return 0;return 0;

}}

Page 189: C++ Training Datascope Lawrence D’Antonio

This is legal. But not what one might expect. The output is:

insert(p,first,last)insert(p,first,last)

In other words, the compiler decides that In other words, the compiler decides that

m.insert(m.begin(), 100, 5);m.insert(m.begin(), 100, 5);

best fits the second insert function (whereas we best fits the second insert function (whereas we expected to match the first).expected to match the first).

Page 190: C++ Training Datascope Lawrence D’Antonio

Why is that?

void insert(iterator p, InputIterator first, InputIterator last) void insert(iterator p, InputIterator first, InputIterator last)

Is an exact match because the last two arguments for m.insert(m.begin(), 100, 5)m.insert(m.begin(), 100, 5) are are both ints. both ints.

So the compiler matches the type InputIterator to So the compiler matches the type InputIterator to int.int.

Page 191: C++ Training Datascope Lawrence D’Antonio

But in the other insert function,

void insert(iterator p, size_type n, const T &t)void insert(iterator p, size_type n, const T &t)

The compiler matches T to be an int. Usually The compiler matches T to be an int. Usually size_t will be a typedef for unsigned int. So that size_t will be a typedef for unsigned int. So that m.insert(m.begin(), 100, 5)m.insert(m.begin(), 100, 5) is not an exact match for this version of insert.

Page 192: C++ Training Datascope Lawrence D’Antonio

Where did we go wrong?Where did we go wrong? This is actually a very difficult problem to This is actually a very difficult problem to

solve. There is no simple way to get the solve. There is no simple way to get the compiler to match the correct version of compiler to match the correct version of insert.insert.

One could specialize the class for the case One could specialize the class for the case when T is an int.when T is an int.

One could overload the first insert function One could overload the first insert function for cases where the second argument is for cases where the second argument is an int, a long, etc.an int, a long, etc.

Page 193: C++ Training Datascope Lawrence D’Antonio

Where did we go wrong? 2Where did we go wrong? 2

These methods are cumbersome (one has These methods are cumbersome (one has to write a lot of extra code that looks to write a lot of extra code that looks exactly the same).exactly the same).

Another solution is to test if the parameter Another solution is to test if the parameter type InputIter is an integral type. There is a type InputIter is an integral type. There is a static member of the class numeric_limits static member of the class numeric_limits called is_integer. called is_integer.

Page 194: C++ Training Datascope Lawrence D’Antonio

Where did we go wrong? 3Where did we go wrong? 3 How does that work? The class How does that work? The class

numeric_limits looks like:numeric_limits looks like:template<class T>template<class T>class numeric_limits {class numeric_limits {public:public:

static const bool is_integer = false;static const bool is_integer = false;//…//…};};

Page 195: C++ Training Datascope Lawrence D’Antonio

Where did we go wrong? 4Where did we go wrong? 4

There are specialized versions of There are specialized versions of numeric_limits for each integral type. numeric_limits for each integral type.

In each of these specialized classes In each of these specialized classes is_integer is set equal to true.is_integer is set equal to true.

Page 196: C++ Training Datascope Lawrence D’Antonio

Corrected versionCorrected version#include<iostream>#include<iostream>#include<limits>#include<limits>

template<bool B>template<bool B>struct int_test { };struct int_test { };

template<class T>template<class T>class my_sequence {class my_sequence {public:public: typedef T* iterator;typedef T* iterator;

private:private: //Some data//Some data

Page 197: C++ Training Datascope Lawrence D’Antonio

Corrected version 2Corrected version 2private:private:

void fill_insert(iterator p, unsigned int n, void fill_insert(iterator p, unsigned int n, const T &t)const T &t)

{ std::cout << "insert(p,n,t)\n"; }{ std::cout << "insert(p,n,t)\n"; }

template<class InputIter>template<class InputIter> void range_insert(iterator p, InputIter first,void range_insert(iterator p, InputIter first,

InputIter last)InputIter last) { std::cout << "insert(p,first,last)\n"; }{ std::cout << "insert(p,first,last)\n"; }

Page 198: C++ Training Datascope Lawrence D’Antonio

Corrected version 3Corrected version 3 template<class Integral>template<class Integral> void insert(iterator p, Integral n, Integral t,void insert(iterator p, Integral n, Integral t,

int_test<true>) {int_test<true>) { fill_insert(p,n,t);fill_insert(p,n,t); }}

template<class InputIter>template<class InputIter> void insert(iterator p, InputIter f, InputIter l,void insert(iterator p, InputIter f, InputIter l,

int_test<false>) {int_test<false>) { range_insert(p,f,l);range_insert(p,f,l); }}

Page 199: C++ Training Datascope Lawrence D’Antonio

Corrected version 4Corrected version 4public:public: //Consider the following insert functions//Consider the following insert functions void insert(iterator p, unsigned int n, const T &t) {void insert(iterator p, unsigned int n, const T &t) { fill_insert(p,n,t);fill_insert(p,n,t); }}

template<class InputIter>template<class InputIter> void insert(iterator p, InputIter first, InputIter last)void insert(iterator p, InputIter first, InputIter last) {{ insert(p,first,last,insert(p,first,last, int_test<std::numeric_limits<InputIter>::is_integer>());int_test<std::numeric_limits<InputIter>::is_integer>()); }}};};

Page 200: C++ Training Datascope Lawrence D’Antonio

Corrected version 5Corrected version 5

main() {main() { my_sequence<int> m;my_sequence<int> m; m.insert(m.begin(), 100, 5);m.insert(m.begin(), 100, 5); return 0;return 0;}}//Output is now//Output is nowinsert(p,n,t)insert(p,n,t)

Page 201: C++ Training Datascope Lawrence D’Antonio

Front Insertion SequenceFront Insertion Sequence

Concept:Concept: A container is a Front Insertion A container is a Front Insertion Sequence if it allows insertion/deletion of Sequence if it allows insertion/deletion of an element at the beginning of a sequence an element at the beginning of a sequence in constant time. in constant time.

Refines:Refines: Sequence Sequence Operations:Operations: In addition to the Sequence In addition to the Sequence

operations we have the following:operations we have the following:

Page 202: C++ Training Datascope Lawrence D’Antonio

Front Insertion Sequence 2Front Insertion Sequence 2

Push front: a.push_front(t) is equivalent to Push front: a.push_front(t) is equivalent to a.insert(a.begin(),t)a.insert(a.begin(),t)

Pop front: a.pop_front() is equivalent to Pop front: a.pop_front() is equivalent to a.erase(a.begin(),t). Has a void return.a.erase(a.begin(),t). Has a void return.

Note: Note: push_frontpush_front followed by followed by pop_frontpop_front is a null operation. is a null operation.

Page 203: C++ Training Datascope Lawrence D’Antonio

Back Insertion SequenceBack Insertion Sequence

Concept:Concept: A container is a Back Insertion A container is a Back Insertion Sequence if it allows insertion/deletion of Sequence if it allows insertion/deletion of an element at the end of a sequence in an element at the end of a sequence in constant time. constant time.

Refines:Refines: Sequence Sequence Operations:Operations: In addition to the Sequence In addition to the Sequence

operations we have the following:operations we have the following:

Page 204: C++ Training Datascope Lawrence D’Antonio

Back Insertion Sequence 2Back Insertion Sequence 2

Back: a.back() returns a reference or Back: a.back() returns a reference or const_reference to the final element of const_reference to the final element of aa (depending on whether the container (depending on whether the container aa is is const).const).

Push back: a.push_back(t) is equivalent to Push back: a.push_back(t) is equivalent to a.insert(a.end(), t)a.insert(a.end(), t)

Pop back: a.pop_back() is equivalent to Pop back: a.pop_back() is equivalent to a.erase(--a.end()). Has a void return.a.erase(--a.end()). Has a void return.

Page 205: C++ Training Datascope Lawrence D’Antonio

Associative ContainerAssociative Container Concept:Concept: An Associative Container accesses An Associative Container accesses

elements in the container based on keys. Keys elements in the container based on keys. Keys are kept in a sorted order (where the user may are kept in a sorted order (where the user may supply the sorting criterion). The keys and supply the sorting criterion). The keys and associated values are stored with a tree data associated values are stored with a tree data structure (in particular, a red-black tree is the structure (in particular, a red-black tree is the usual implementation). Since the sorted order of usual implementation). Since the sorted order of the keys is an invariant for this container, the keys is an invariant for this container, insertions are not allowed to specify the position insertions are not allowed to specify the position of insertion. of insertion.

Page 206: C++ Training Datascope Lawrence D’Antonio

Associative Container 2Associative Container 2

Refines:Refines: Forward Container, Default Forward Container, Default Constructible Constructible

Associated Types:Associated Types: those of Forward those of Forward Container together with,Container together with,

X::key_type the type of the key associated X::key_type the type of the key associated with X::value_typewith X::value_type

Page 207: C++ Training Datascope Lawrence D’Antonio

Associative Container 3Associative Container 3

Operations:Operations: Same as Forward Container Same as Forward Container together with the followingtogether with the following

Default ConstructorDefault Constructor Find: a.find(k) returns an iterator pointing Find: a.find(k) returns an iterator pointing

to an element whose key is k. Returns to an element whose key is k. Returns a.end() if key not found.a.end() if key not found.

Count: a.count(k) returns the number of Count: a.count(k) returns the number of elements whose key is k.elements whose key is k.

Page 208: C++ Training Datascope Lawrence D’Antonio

Associative Container 4Associative Container 4 Equal Range: a.equal_range(k) returns a Equal Range: a.equal_range(k) returns a

pair P of iterators with key equal to k. The pair P of iterators with key equal to k. The range is [P.first,P.second).range is [P.first,P.second).

Erase key: a.erase_key(k) erase all Erase key: a.erase_key(k) erase all elements whose key is k. elements whose key is k.

Erase element: a.erase(p) erases the Erase element: a.erase(p) erases the element pointed to by p.element pointed to by p.

Erase range: a.erase(i,j) erases the Erase range: a.erase(i,j) erases the elements in the range [i,j)elements in the range [i,j)

Page 209: C++ Training Datascope Lawrence D’Antonio

Associative Container 5Associative Container 5

Models:Models: set, multiset, map, multimap set, multiset, map, multimap

Page 210: C++ Training Datascope Lawrence D’Antonio

Associative Container FAQAssociative Container FAQ

What does end() return for an associative What does end() return for an associative container?container?

end() returns an iterator to a special tree end() returns an iterator to a special tree node Head.node Head.

This node contains no data, its left pointer This node contains no data, its left pointer points at the smallest element in the tree, points at the smallest element in the tree, its right pointer points at the largest its right pointer points at the largest element in the tree, its parent is the root.element in the tree, its parent is the root.

Page 211: C++ Training Datascope Lawrence D’Antonio

Associative Container FAQ 2Associative Container FAQ 2

How do you increment an iterator for an How do you increment an iterator for an Associative Container?Associative Container?

Such iterators internally store a node Such iterators internally store a node pointer Ptr.pointer Ptr.

Page 212: C++ Training Datascope Lawrence D’Antonio

void increment()void increment(){{

if ( Isnil(Ptr) )if ( Isnil(Ptr) );;

else if ( !Isnil(Right(Ptr)) )else if ( !Isnil(Right(Ptr)) )Ptr = Min(Right(Ptr));Ptr = Min(Right(Ptr));

else {else {Nodeptr P;Nodeptr P;while ( !Isnil(P = Parent(Ptr)) while ( !Isnil(P = Parent(Ptr))

&& Ptr == Right(P) )&& Ptr == Right(P) )Ptr = P;Ptr = P;

Ptr = P;Ptr = P;}}

}}

Page 213: C++ Training Datascope Lawrence D’Antonio

Associative Container FAQ 3Associative Container FAQ 3

How do lower_bound(), upper_bound() How do lower_bound(), upper_bound() and equal_range() work?and equal_range() work?

Lower_bound finds the first of an Lower_bound finds the first of an equivalent sequence of keys.equivalent sequence of keys.

Upper_bound finds the first element past Upper_bound finds the first element past an equivalent sequence of keys.an equivalent sequence of keys.

Equal_range returns the pair of iterators, Equal_range returns the pair of iterators, lower_bound and upper_bound.lower_bound and upper_bound.

Page 214: C++ Training Datascope Lawrence D’Antonio

Nodeptr Lbound(const key_type &k) const{

Nodeptr X = Root();Nodeptr Y = Head;

while( !Isnil(X) )if( comp(Key(X),k) )

X = Right(X);else {

Y = X;X = Left(X);

}return Y;

}

Page 215: C++ Training Datascope Lawrence D’Antonio

Nodeptr Ubound(const key_type &k) const{

Nodeptr X = Root();Nodeptr Y = Head;

while( !Isnil(X) )if( comp(k,Key(X)) ) {

Y = X;X = Left(X);

}else

X = Right(X);return Y;

}

Page 216: C++ Training Datascope Lawrence D’Antonio

Unique Associative ContainerUnique Associative Container

Concept:Concept: A Unique Associative Container A Unique Associative Container is an Associative Container with the is an Associative Container with the property that each key in the container is property that each key in the container is unique. An element doesn’t get inserted unique. An element doesn’t get inserted into a container if its key is already into a container if its key is already present.present.

Refines:Refines: Associative Container Associative Container

Page 217: C++ Training Datascope Lawrence D’Antonio

Unique Associative Container 2Unique Associative Container 2

Operations:Operations: Same as Associative Same as Associative Container plus,Container plus,

Range constructor: X a(i,j) creates an Range constructor: X a(i,j) creates an associative container that includes all associative container that includes all elements in [i,j) that have unique keys.elements in [i,j) that have unique keys.

Page 218: C++ Training Datascope Lawrence D’Antonio

Unique Associative Container 3Unique Associative Container 3

Insert element: a.insert(t) inserts the Insert element: a.insert(t) inserts the element if and only if t’s key is not already element if and only if t’s key is not already in container. Returns pair<iterator,bool>. If in container. Returns pair<iterator,bool>. If element is already in container, iterator element is already in container, iterator points to an element in the container with points to an element in the container with that key and the bool is false. If the that key and the bool is false. If the element not in the container then the element not in the container then the iterator points to where the element is iterator points to where the element is inserted and the bool is true.inserted and the bool is true.

Page 219: C++ Training Datascope Lawrence D’Antonio

Unique Associative Container 4Unique Associative Container 4

Insert range: a.insert(i,j) inserts all the Insert range: a.insert(i,j) inserts all the elements in [i,j) whose key is not already elements in [i,j) whose key is not already in the container.in the container.

Models:Models: set, map set, map

Page 220: C++ Training Datascope Lawrence D’Antonio

Multiple Associative ContainerMultiple Associative Container

Concept:Concept: A Multiple Associative Container A Multiple Associative Container is an Associative Container that may is an Associative Container that may contain more than one element with the contain more than one element with the same key.same key.

Refines:Refines: Associative Container Associative Container Operations:Operations: Those of Associative Those of Associative

Container together with the following,Container together with the following,

Page 221: C++ Training Datascope Lawrence D’Antonio

Multiple Associative Container 2Multiple Associative Container 2

Range constructor: X a(i,j) creates an Range constructor: X a(i,j) creates an associative container that contains all the associative container that contains all the elements in the range [i,j).elements in the range [i,j).

Insert element: a.insert(t) inserts t and Insert element: a.insert(t) inserts t and returns a pointer to the newly inserted returns a pointer to the newly inserted element.element.

Insert range: a.insert(i,j) inserts all the Insert range: a.insert(i,j) inserts all the elements in the range [i,j).elements in the range [i,j).

Page 222: C++ Training Datascope Lawrence D’Antonio

Multiple Associative Container 3Multiple Associative Container 3

Models:Models: multiset, multimap multiset, multimap

Page 223: C++ Training Datascope Lawrence D’Antonio

Simple Associative ContainerSimple Associative Container

Concept:Concept: A Simple Associative Container A Simple Associative Container is an Associative Container whose is an Associative Container whose elements are their own keys. A value elements are their own keys. A value stored in such a container is just a key, not stored in such a container is just a key, not a key plus additional data.a key plus additional data.

Refines:Refines: Associative Container Associative Container

Page 224: C++ Training Datascope Lawrence D’Antonio

Simple Associative Container 2Simple Associative Container 2 Associated Types:Associated Types: Those of Associative Those of Associative

Container together with:Container together with: X::iterator. Mutable iterators are not X::iterator. Mutable iterators are not

allowed for Simple Associative Containers. allowed for Simple Associative Containers. Both X::iterator and X::const_iterator must Both X::iterator and X::const_iterator must have the same behavior.have the same behavior.

Invariant:Invariant: Elements are immutable. They Elements are immutable. They cannot be modified in place (but can be cannot be modified in place (but can be removed).removed).

Page 225: C++ Training Datascope Lawrence D’Antonio

Simple Associative Container 3Simple Associative Container 3

Models:Models: set and multiset. set and multiset.

Page 226: C++ Training Datascope Lawrence D’Antonio

Pair Associative ContainerPair Associative Container Concept:Concept: A Pair Associative Container A Pair Associative Container

associates a key with some other object.associates a key with some other object. Refines:Refines: Associative Container Associative Container Associated Types:Associated Types: Those of Associative Those of Associative

Container together withContainer together with X::key_type the type of an element’s key.X::key_type the type of an element’s key. X::mapped_type the type of an element’s X::mapped_type the type of an element’s

data. The container associates keys and data. The container associates keys and values of type mapped_type.values of type mapped_type.

Page 227: C++ Training Datascope Lawrence D’Antonio

Pair Associative Container 2Pair Associative Container 2

X::value_type the type of object stored in X::value_type the type of object stored in the container. The value type is the container. The value type is pair<const key_type, mapped_type>. Note pair<const key_type, mapped_type>. Note the use of const key_type. This happens the use of const key_type. This happens because the keys in a Pair Associative because the keys in a Pair Associative Container are immutable. The Container are immutable. The mapped_type part of an element may be mapped_type part of an element may be modified but not the key.modified but not the key.

Page 228: C++ Training Datascope Lawrence D’Antonio

Pair Associative Container 3Pair Associative Container 3

X::iterator. A Pair Associative Container X::iterator. A Pair Associative Container cannot provide mutable iterators. This is cannot provide mutable iterators. This is because the value type of a mutable because the value type of a mutable iterator must be Assignable and iterator must be Assignable and pair<const key_type, mapped_type> is not pair<const key_type, mapped_type> is not Assignable. However iterators are not Assignable. However iterators are not constant since you are allowed to have constant since you are allowed to have expressions such as i->second = val.expressions such as i->second = val.

Page 229: C++ Training Datascope Lawrence D’Antonio

Pair Associative Container 4Pair Associative Container 4

Models:Models: map and multimap map and multimap

Page 230: C++ Training Datascope Lawrence D’Antonio

Sorted Associative ContainerSorted Associative Container

Concept:Concept: A Sorted Associative Container A Sorted Associative Container sorts elements by key, using a Strict Weak sorts elements by key, using a Strict Weak Ordering.Ordering.

Refines:Refines: Associative Container and Associative Container and Reversible Container.Reversible Container.

Associated Types:Associated Types: Those of Associative Those of Associative and Reversible Container together with the and Reversible Container together with the following:following:

Page 231: C++ Training Datascope Lawrence D’Antonio

Sorted Associative Container 2Sorted Associative Container 2 X::key_compare is a function object type. X::key_compare is a function object type.

It uses a Strict Weak Ordering to compare It uses a Strict Weak Ordering to compare keys. It takes two arguments of type keys. It takes two arguments of type X::key_type and returns a bool.X::key_type and returns a bool.

X::value_compare is a function object that X::value_compare is a function object that compares two objects of value_type by compares two objects of value_type by passing the keys associated with these passing the keys associated with these objects to a function object of type objects to a function object of type key_compare.key_compare.

Page 232: C++ Training Datascope Lawrence D’Antonio

Sorted Associative Container 3Sorted Associative Container 3 Operations:Operations: Those of Associative Those of Associative

Container and Reversible Container Container and Reversible Container together with:together with:

Default constructor: X() creates an empty Default constructor: X() creates an empty container using key_compare() as the container using key_compare() as the comparison function.comparison function.

Default constructor with comparison: X(c) Default constructor with comparison: X(c) creates an empty container with creates an empty container with comparison function c.comparison function c.

Page 233: C++ Training Datascope Lawrence D’Antonio

Sorted Associative Container 4Sorted Associative Container 4

Range constructor: X(i,j) is equivalent toRange constructor: X(i,j) is equivalent toX a;X a;a.insert(i,j);a.insert(i,j);

Range constructor with comparison: Range constructor with comparison: X(i,j,c) is equivalent toX(i,j,c) is equivalent to

X a(c);X a(c);a.insert(i,j);a.insert(i,j);

Page 234: C++ Training Datascope Lawrence D’Antonio

Sorted Associative Container 5Sorted Associative Container 5

Key comparison: a.key_comp() returns a’s Key comparison: a.key_comp() returns a’s key comparison object.key comparison object.

Value comparison: a.value_comp() returns Value comparison: a.value_comp() returns a’s value comparison object.a’s value comparison object.

Lower bound: a.lower_bound(k) returns Lower bound: a.lower_bound(k) returns an iterator to the first element whose key an iterator to the first element whose key is not less than k. It returns a.end() if no is not less than k. It returns a.end() if no such element is present. such element is present.

Page 235: C++ Training Datascope Lawrence D’Antonio

Sorted Associative Container 6Sorted Associative Container 6

Upper bound: a.upper_bound(k) returns Upper bound: a.upper_bound(k) returns an iterator to the first element whose key an iterator to the first element whose key is greater than k. It returns a.end() if no is greater than k. It returns a.end() if no such element exists.such element exists.

Page 236: C++ Training Datascope Lawrence D’Antonio

Sorted Associative Container 7Sorted Associative Container 7

Equal range: a.equal_range(k) returns a Equal range: a.equal_range(k) returns a pair P such that P.first is a.lower_bound(k) pair P such that P.first is a.lower_bound(k) and P.second is a.upper_bound(k). If there and P.second is a.upper_bound(k). If there are no elements equal to k then an empty are no elements equal to k then an empty range is returned that indicates the range is returned that indicates the position where those elements would have position where those elements would have been if they did exist. All elements with been if they did exist. All elements with key k will be contained in the range key k will be contained in the range [P.first, P.second).[P.first, P.second).

Page 237: C++ Training Datascope Lawrence D’Antonio

Equal range exampleEqual range example#include <iostream>#include <iostream>#include <set>#include <set>#include <algorithm>#include <algorithm>#include <iterator>#include <iterator>#include <utility>#include <utility>

main() {main() { std::multiset<int> s;std::multiset<int> s;

s.insert(5);s.insert(5); s.insert(3);s.insert(3); s.insert(12);s.insert(12); s.insert(6);s.insert(6); s.insert(6);s.insert(6); s.insert(10);s.insert(10);

Page 238: C++ Training Datascope Lawrence D’Antonio

Equal range example 2Equal range example 2

std::copy(s.begin(), s.end(), std::copy(s.begin(), s.end(), std::ostream_iterator<int>(std::cout, " "));std::ostream_iterator<int>(std::cout, " "));std::cout << '\n';std::cout << '\n'; typedef std::multiset<int>::const_iterator CI;typedef std::multiset<int>::const_iterator CI;

Page 239: C++ Training Datascope Lawrence D’Antonio

Equal range example 3Equal range example 3

std::pair<CI,CI> pi = s.equal_range(6);std::pair<CI,CI> pi = s.equal_range(6);

std::copy(pi.first, pi.second,std::copy(pi.first, pi.second, std::ostream_iterator<int>(std::cout, " "));std::ostream_iterator<int>(std::cout, " "));std::cout << '\n';std::cout << '\n';

Page 240: C++ Training Datascope Lawrence D’Antonio

Equal range example 4Equal range example 4

pi = s.equal_range(11);pi = s.equal_range(11);if (pi.first == s.end())if (pi.first == s.end()) std::cout << "equal_range returned end()\n";std::cout << "equal_range returned end()\n";if (pi.second == s.end())if (pi.second == s.end()) std::cout << "equal_range returned end()\n";std::cout << "equal_range returned end()\n";std::cout << "equal_range.first = " std::cout << "equal_range.first = " << *pi.first << '\n';<< *pi.first << '\n';std::cout << "equal_range.second = " std::cout << "equal_range.second = " << *pi.second << '\n';<< *pi.second << '\n';

Page 241: C++ Training Datascope Lawrence D’Antonio

Equal range example 5Equal range example 5

std::copy(pi.first, pi.second,std::copy(pi.first, pi.second, std::ostream_iterator<int>(std::cout, " "));std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n';std::cout << '\n'; return 0;return 0;}}

Page 242: C++ Training Datascope Lawrence D’Antonio

Equal range example 6Equal range example 6

OutputOutput

3 5 6 6 10 12 3 5 6 6 10 12 6 6 6 6 equal_range.first = 12equal_range.first = 12equal_range.second = 12equal_range.second = 12

Page 243: C++ Training Datascope Lawrence D’Antonio

ExampleExample

Here is a small music database. We will Here is a small music database. We will load the database and then do a simple load the database and then do a simple query, “Print out all songs sung by Billie query, “Print out all songs sung by Billie Holiday in the database.”Holiday in the database.”

Page 244: C++ Training Datascope Lawrence D’Antonio

ArtistArtist SongSongBillie HolidayBillie Holiday Mean to MeMean to MeBillie HolidayBillie Holiday SummertimeSummertimeBillie HolidayBillie Holiday I Can’t Get StartedI Can’t Get StartedBix BeiderbeckeBix Beiderbecke In a MistIn a MistBix BeiderbeckeBix Beiderbecke Singin’ the BluesSingin’ the BluesRuth EttingRuth Etting Singin’ the BluesSingin’ the BluesBunny BeriganBunny Berigan I Can’t Get StartedI Can’t Get StartedLouis ArmstrongLouis Armstrong ChinatownChinatownLouis ArmstrongLouis Armstrong StardustStardustJack JenneyJack Jenney StardustStardust

Page 245: C++ Training Datascope Lawrence D’Antonio

#include<iostream>#include <map>#include <string>

using namespace std;

typedef string artist;typedef string song;typedef multimap<artist,song>::iterator

music_iterator; main(){ multimap<artist,song> music;

Page 246: C++ Training Datascope Lawrence D’Antonio

music.insert(make_pair("Billie Holiday","Mean to Me"));

music.insert(make_pair("Billie Holiday","Summertime"));

music.insert(make_pair("Billie Holiday","I Can\'t Get Started"));

music.insert(make_pair("Bix Beiderbecke", "Singin\' the Blues"));

music.insert(make_pair("Bix Beiderbecke","In a Mist"));

music.insert(make_pair("Ruth Etting", "Singin\' the Blues"));

Page 247: C++ Training Datascope Lawrence D’Antonio

music.insert(make_pair("Bunny Berigan","I Can\'t Get Started"));

music.insert(make_pair("Louis Armstrong", "West End Blues"));

music.insert(make_pair("Louis Armstrong", "Stardust"));

music.insert(make_pair("Louis Armstrong", "Chinatown"));

music.insert(make_pair("Jack Jenney", "Stardust"));music.insert(make_pair("Sidney Bechet",

"Summertime"));music.insert(make_pair("Sidney Bechet",

"Wild Man Blues"));music.insert(make_pair("Cootie Williams",

"West End Blues"));

Page 248: C++ Training Datascope Lawrence D’Antonio

//Find songs by Billie Holidaypair<music_iterator,music_iterator> p =

music.equal_range("Billie Holiday"); //Print out songs by Billie Holidaycout << "Songs by Billie Holiday\n";

for(music_iterator i = p.first, i != p.second; i++) cout << i->second << '\n'; return 0;}

Page 249: C++ Training Datascope Lawrence D’Antonio

OUTPUT

Songs by Billie HolidayMean to MeSummertimeI Can't Get Started

Page 250: C++ Training Datascope Lawrence D’Antonio

AllocatorAllocator

Concept:Concept: Manages the details of memory Manages the details of memory allocation and deallocation.allocation and deallocation.

Refines:Refines: Equality Comparable and Default Equality Comparable and Default Constructible.Constructible.

Associated Types:Associated Types: X::value_type the type that the allocator X::value_type the type that the allocator

managesmanages

Page 251: C++ Training Datascope Lawrence D’Antonio

Allocator 2Allocator 2

X::pointer is a pointer (not necessarily a X::pointer is a pointer (not necessarily a built-in pointer type) to X::value_type. The built-in pointer type) to X::value_type. The pointer type must be convertible to pointer type must be convertible to const_pointer, void*, and value_type*.const_pointer, void*, and value_type*.

X::const_pointer is a const pointer to X::const_pointer is a const pointer to X::value_type.X::value_type.

X::reference is a reference to X::reference is a reference to X::value_type (must be X::value_type&).X::value_type (must be X::value_type&).

Page 252: C++ Training Datascope Lawrence D’Antonio

Allocator 3Allocator 3 X::const_reference is a const reference to X::const_reference is a const reference to

X::value_type (must be const X::value_type (must be const X::value_type&).X::value_type&).

X::difference_type is a signed integral type X::difference_type is a signed integral type that represents the difference of two that represents the difference of two values of type X::pointer.values of type X::pointer.

X::size_type is an unsigned integral type X::size_type is an unsigned integral type that can represent any non-negative value that can represent any non-negative value of type X::difference_type.of type X::difference_type.

Page 253: C++ Training Datascope Lawrence D’Antonio

Allocator 4Allocator 4

X::rebind<U>::other is an allocator whose X::rebind<U>::other is an allocator whose type is U.type is U.

Operations:Operations: Default constructor: X() creates a default Default constructor: X() creates a default

allocator.allocator. Copy constructor: X b(a) creates a copy of Copy constructor: X b(a) creates a copy of

a (and compares equal to a).a (and compares equal to a).

Page 254: C++ Training Datascope Lawrence D’Antonio

Allocator 5Allocator 5 Generalized copy constructor: X a(y) Generalized copy constructor: X a(y)

creates a copy of y, an Allocator of value creates a copy of y, an Allocator of value type U.type U.

Comparison: a == b returns true if and Comparison: a == b returns true if and only if the storage allocated by a can be only if the storage allocated by a can be deallocated using b and vice versa.deallocated using b and vice versa.

Allocate: a.allocate(n) allocates n*sizeof(T) Allocate: a.allocate(n) allocates n*sizeof(T) bytes and returns a pointer to an bytes and returns a pointer to an uninitialized block of memory.uninitialized block of memory.

Page 255: C++ Training Datascope Lawrence D’Antonio

Allocator 6Allocator 6 Allocate with hint: a.allocate(n,p) allocates Allocate with hint: a.allocate(n,p) allocates

n*sizeof(T) bytes. The pointer p is a hint to n*sizeof(T) bytes. The pointer p is a hint to where the memory may be allocated (the where the memory may be allocated (the hint may be simply ignored). Returns a hint may be simply ignored). Returns a pointer to an uninitialized block of memory.pointer to an uninitialized block of memory.

Deallocate: a.deallocate(p, n) frees the Deallocate: a.deallocate(p, n) frees the memory for n objects of type T stored at memory for n objects of type T stored at location p. The pointer p must have been location p. The pointer p must have been obtained from a previous call to allocate.obtained from a previous call to allocate.

Page 256: C++ Training Datascope Lawrence D’Antonio

Allocator 7Allocator 7

Maximum size: a.max_size returns the Maximum size: a.max_size returns the maximum number of elements that may be maximum number of elements that may be passed as the first argument to allocate.passed as the first argument to allocate.

Construct: a.construct(p, val) constructs Construct: a.construct(p, val) constructs an object of type T at position p. an object of type T at position p. Equivalent to the placement new operator Equivalent to the placement new operator new( (void *) p) T(val). new( (void *) p) T(val).

Page 257: C++ Training Datascope Lawrence D’Antonio

Allocator 8Allocator 8

Destroy: a.destroy(p) destroys the object Destroy: a.destroy(p) destroys the object pointed to by p. Equivalent to pointed to by p. Equivalent to ( (T*) p) -> ~T()( (T*) p) -> ~T()

Address: a.address(t) returns of object t (in Address: a.address(t) returns of object t (in the form of a pointer or const pointer)the form of a pointer or const pointer)

Page 258: C++ Training Datascope Lawrence D’Antonio

Container AdaptorsContainer Adaptors

A container adaptor is a class that provide A container adaptor is a class that provide a limited number of container operations.a limited number of container operations.

There are three container adaptors in STL: There are three container adaptors in STL: stack, queue, and priority queue.stack, queue, and priority queue.

These classes are implemented in terms These classes are implemented in terms of underlying containers.of underlying containers.

Page 259: C++ Training Datascope Lawrence D’Antonio

StackStack Concept:Concept: A stack adapts a sequence container A stack adapts a sequence container

(deque by default). It permits insertion, deletion, (deque by default). It permits insertion, deletion, or inspection only at one end of the sequence or inspection only at one end of the sequence (designated the top of the stack). Stacks do not (designated the top of the stack). Stacks do not have iterators.have iterators.

Template parameters:Template parameters: stack<T,C>. Here T is stack<T,C>. Here T is the type of element stored in stack and C is the the type of element stored in stack and C is the underlying sequence container.underlying sequence container.

Page 260: C++ Training Datascope Lawrence D’Antonio

Stack 2Stack 2

MembersMembers stack::value_type is the type of object stack::value_type is the type of object

stored in the stack.stored in the stack. Default constructor: stack::stack() declares Default constructor: stack::stack() declares

an empty stack.an empty stack. Constructor with sequence: stack::stack(c) Constructor with sequence: stack::stack(c)

declares a stack having the same declares a stack having the same elements as container c.elements as container c.

Page 261: C++ Training Datascope Lawrence D’Antonio

Stack 3Stack 3

Copy constructor, destructor, assignment Copy constructor, destructor, assignment operator, size(), empty()operator, size(), empty()

top() returns a mutable reference to the top() returns a mutable reference to the top of the stack. It actually returns top of the stack. It actually returns c.back().c.back().

push(x) inserts x at the top of the stack. push(x) inserts x at the top of the stack. Calls c.push_back(x).Calls c.push_back(x).

Page 262: C++ Training Datascope Lawrence D’Antonio

Stack 4Stack 4

pop() removes (but does not return) the pop() removes (but does not return) the element at the top of the stack. Calls element at the top of the stack. Calls c.pop_back().c.pop_back().

Type Requirements: Container C is a Type Requirements: Container C is a model of Back Insertion Sequence.model of Back Insertion Sequence.

Page 263: C++ Training Datascope Lawrence D’Antonio

QueueQueue

Concept:Concept: A queue adapts a sequence A queue adapts a sequence container (deque by default). A queue is a container (deque by default). A queue is a model of a “first in first out” container. model of a “first in first out” container. Elements are inserted at the back and Elements are inserted at the back and removed from the front of the sequence. removed from the front of the sequence. Iterators are not allowed on queues.Iterators are not allowed on queues.

Template parameters:Template parameters: queue<T,C>. Here T queue<T,C>. Here T is the type of element stored in stack and C is is the type of element stored in stack and C is the underlying sequence container.the underlying sequence container.

Page 264: C++ Training Datascope Lawrence D’Antonio

Queue 2Queue 2

Members:Members: queue::value_type is the type of object queue::value_type is the type of object

stored in the queue.stored in the queue. Default constructor: queue::queue() Default constructor: queue::queue()

declares an empty queue.declares an empty queue. Constructor with sequence: queue:: Constructor with sequence: queue::

queue(c) declares a queue having the queue(c) declares a queue having the same elements as container c.same elements as container c.

Page 265: C++ Training Datascope Lawrence D’Antonio

Queue 3Queue 3 Copy constructor, destructor, assignment Copy constructor, destructor, assignment

operator, size(), empty()operator, size(), empty() front() returns the element at the front of front() returns the element at the front of

the queue. Calls c.front().the queue. Calls c.front(). back() returns the element at the back of back() returns the element at the back of

the queue. Calls c.back().the queue. Calls c.back(). push(x) inserts x at the back of the queue. push(x) inserts x at the back of the queue.

No value is returned. Calls No value is returned. Calls c.push_back(x).c.push_back(x).

Page 266: C++ Training Datascope Lawrence D’Antonio

Queue 4Queue 4

pop() removes the element at the front of pop() removes the element at the front of the queue.the queue.

Type RequirementsType Requirements: Container C is a : Container C is a model for Back Insertion Sequence and model for Back Insertion Sequence and Front Insertion Sequence.Front Insertion Sequence.

Page 267: C++ Training Datascope Lawrence D’Antonio

Priority QueuePriority Queue

Concept:Concept: A priority queue adapts a A priority queue adapts a sequence container (vector by default). It sequence container (vector by default). It provides for insertion of elements, and provides for insertion of elements, and inspection and removal of the top element. inspection and removal of the top element. Iterators and the modification of elements Iterators and the modification of elements are not permitted. The top element is are not permitted. The top element is always the largest in the queue (elements always the largest in the queue (elements are ordered using < by default). The are ordered using < by default). The elements are stored in a heap.elements are stored in a heap.

Page 268: C++ Training Datascope Lawrence D’Antonio

Priority Queue 2Priority Queue 2

Template Parameters:Template Parameters: priority_queue<T,C,Compare>. T is the priority_queue<T,C,Compare>. T is the type of element stored in queue. C is the type of element stored in queue. C is the underlying sequence container. Compare underlying sequence container. Compare is the comparison function used to find the is the comparison function used to find the largest element in the queue.largest element in the queue.

Page 269: C++ Training Datascope Lawrence D’Antonio

Priority Queue 3Priority Queue 3 Members:Members: priority_queue::value_type is the same as priority_queue::value_type is the same as

T.T. Default constructor creates a priority Default constructor creates a priority

queue with the default container and queue with the default container and compare function.compare function.

Constructor with compare function: explicit Constructor with compare function: explicit priority_queue::priority_queue(Compare priority_queue::priority_queue(Compare comp).comp).

Page 270: C++ Training Datascope Lawrence D’Antonio

Priority Queue 4Priority Queue 4

Constructor with comparison and Constructor with comparison and sequence: sequence: priority_queue::priority_queue(Compare priority_queue::priority_queue(Compare comp, C cont).comp, C cont).

Range constructor with comparison, range Range constructor with comparison, range constructor with comparison and constructor with comparison and container.container.

Page 271: C++ Training Datascope Lawrence D’Antonio

Priority Queue 5Priority Queue 5

Destructor, assignment operator, size(), Destructor, assignment operator, size(), empty().empty().

top() returns a const reference to the top() returns a const reference to the largest element of the queue (which would largest element of the queue (which would be the root of the heap). Calls c.front().be the root of the heap). Calls c.front().

push(x) inserts x into the queue. Calls push(x) inserts x into the queue. Calls c.push_back() and then “bubbles up” the c.push_back() and then “bubbles up” the heap.heap.

Page 272: C++ Training Datascope Lawrence D’Antonio

Priority Queue 6Priority Queue 6

pop() removes the element at the top of pop() removes the element at the top of the queue. Switches the top and bottom the queue. Switches the top and bottom elements of the heap, rebuilds the hea, elements of the heap, rebuilds the hea, and then calls c.pop_back().and then calls c.pop_back().

Type Requirements:Type Requirements: Container must be a Container must be a Random Access Container. Compare Random Access Container. Compare must be a Strict Weak Ordering.must be a Strict Weak Ordering.

Page 273: C++ Training Datascope Lawrence D’Antonio

FunctorsFunctors A functor, or function object, is any object that A functor, or function object, is any object that

can be used using function call syntax.can be used using function call syntax. A function pointer is a functor, as is any object of A function pointer is a functor, as is any object of

a class that overloads the function call operator, a class that overloads the function call operator, i.e., operator().i.e., operator().

A pointer to a member function is not a functor.A pointer to a member function is not a functor. The standard library functors are limited to The standard library functors are limited to

generators, unary and binary functions, but still generators, unary and binary functions, but still provide a useful starting point for someone provide a useful starting point for someone writing their own functors.writing their own functors.

Page 274: C++ Training Datascope Lawrence D’Antonio

Functors 2Functors 2

A unary function returning a bool is called A unary function returning a bool is called a Predicate. A binary function returning a a Predicate. A binary function returning a bool is called a Binary Predicate.bool is called a Binary Predicate.

An adaptable functor has typedefs for its An adaptable functor has typedefs for its argument types and return type.argument types and return type.

Adaptable functors can be used by Adaptable functors can be used by function adaptors. function adaptors.

Page 275: C++ Training Datascope Lawrence D’Antonio

GeneratorGenerator

Concept:Concept: A Generator is a function object A Generator is a function object called with no arguments.called with no arguments.

Refines:Refines: Assignable Assignable Associated Types:Associated Types: Result type, the type Result type, the type

returned when the Generator is called.returned when the Generator is called. Operations: fOperations: function call f().unction call f(). Models:Models: any function R (*)(). any function R (*)().

Page 276: C++ Training Datascope Lawrence D’Antonio

Unary FunctionUnary Function

Concept:Concept: A Unary Function is a function A Unary Function is a function object that is called with a single object that is called with a single argument.argument.

Refines:Refines: Assignable Assignable Associated Types:Associated Types: Argument type: Argument type is the type Argument type: Argument type is the type

of the function’s argument.of the function’s argument.

Page 277: C++ Training Datascope Lawrence D’Antonio

Unary Function 2Unary Function 2

Result type: result_type is the type of the Result type: result_type is the type of the return value.return value.

Operation:Operation: function call f(x) function call f(x) Models: Models: any function R (*)(T)any function R (*)(T)

Page 278: C++ Training Datascope Lawrence D’Antonio

Binary FunctionBinary Function

Concept:Concept: A Binary Function is a function A Binary Function is a function object that is called with two arguments.object that is called with two arguments.

Refines:Refines: Assignable Assignable Associated Types:Associated Types: Argument types: First argument type and Argument types: First argument type and

Second argument type are the types of the Second argument type are the types of the function’s arguments.function’s arguments.

Page 279: C++ Training Datascope Lawrence D’Antonio

Binary Function 2Binary Function 2

Result type: Result type is the type of the Result type: Result type is the type of the return value.return value.

Operation:Operation: function call f(x,y) function call f(x,y) Models: Models: any function R (*)(T1,T2)any function R (*)(T1,T2)

Page 280: C++ Training Datascope Lawrence D’Antonio

Adaptive GeneratorAdaptive Generator

Concept:Concept: An Adaptive Generator is a An Adaptive Generator is a Generator that has a nested typedef for Generator that has a nested typedef for the return type.the return type.

Refines:Refines: Assignable Assignable Associated Types:Associated Types: f::result_type, the type f::result_type, the type

returned when the Generator is called.returned when the Generator is called. Operations: fOperations: function call f().unction call f(). Models:Models: None in standard library None in standard library

Page 281: C++ Training Datascope Lawrence D’Antonio

Adaptive Unary FunctionAdaptive Unary Function

Concept:Concept: An Adaptive Unary Function is a An Adaptive Unary Function is a Unary Function that has nested typedefs Unary Function that has nested typedefs for the argument and return types.for the argument and return types.

Refines:Refines: Assignable Assignable Associated Types:Associated Types: Argument type: f::argument_type is the Argument type: f::argument_type is the

type of the function’s argument.type of the function’s argument.

Page 282: C++ Training Datascope Lawrence D’Antonio

Adaptive Unary Function 2Adaptive Unary Function 2

Result type: f::result_type is the type of the Result type: f::result_type is the type of the return value.return value.

Operation:Operation: function call f(x) function call f(x) Models: Models: negate, logical_not, negate, logical_not,

pointer_to_unary_function.pointer_to_unary_function.

Page 283: C++ Training Datascope Lawrence D’Antonio

Adaptive Binary FunctionAdaptive Binary Function

Concept:Concept: An Adaptive Binary Function is An Adaptive Binary Function is a Binary Function with nested typedefs for a Binary Function with nested typedefs for the argument and return types.the argument and return types.

Refines:Refines: Assignable Assignable Associated Types:Associated Types: Argument types: f::first_argument_type Argument types: f::first_argument_type

and f::second_argument_type are the and f::second_argument_type are the types of the function’s arguments.types of the function’s arguments.

Page 284: C++ Training Datascope Lawrence D’Antonio

Adaptive Binary Function 2Adaptive Binary Function 2

Result type: result_type is the type of the Result type: result_type is the type of the return value.return value.

Operation:Operation: function call f(x,y) function call f(x,y) Models: Models: plus, minus, multiplies, divides, plus, minus, multiplies, divides,

modulus, equal_to, not_equal_to, greater, modulus, equal_to, not_equal_to, greater, less, greater_equal, less_equal, less, greater_equal, less_equal, logical_and, logical_or, logical_and, logical_or, pointer_to_binary_function.pointer_to_binary_function.

Page 285: C++ Training Datascope Lawrence D’Antonio

PredicatePredicate

Concept:Concept: A Predicate is a Unary Function A Predicate is a Unary Function whose return is a bool.whose return is a bool.

Refines:Refines: Unary Function Unary Function Associated Type:Associated Type: the Result type must the Result type must

be convertible to bool.be convertible to bool. Models:Models: Any function of the form Any function of the form

bool (*)(T)bool (*)(T)

Page 286: C++ Training Datascope Lawrence D’Antonio

Binary PredicateBinary Predicate

Concept:Concept: A Binary Predicate is a Binary A Binary Predicate is a Binary Function that returns a bool.Function that returns a bool.

Refines:Refines: Binary Function Binary Function Associated Types:Associated Types: the Result type must the Result type must

be a bool.be a bool. Models:Models: Any function of the form Any function of the form

bool (*)(T1,T2)bool (*)(T1,T2)

Page 287: C++ Training Datascope Lawrence D’Antonio

Adaptive PredicateAdaptive Predicate

Concept:Concept: An Adaptive Predicate is a An Adaptive Predicate is a Predicate with nested typedefs for the Predicate with nested typedefs for the argument and return types.argument and return types.

Refines:Refines: Predicate, Adaptive Unary Predicate, Adaptive Unary FunctionFunction

Models: logical_notModels: logical_not

Page 288: C++ Training Datascope Lawrence D’Antonio

Adaptive Binary PredicateAdaptive Binary Predicate

Concept:Concept: An Adaptive Binary Predicate is An Adaptive Binary Predicate is a Binary Predicate with nested typedefs a Binary Predicate with nested typedefs for the argument and return types.for the argument and return types.

Refines:Refines: Binary Predicate, Adaptive Unary Binary Predicate, Adaptive Unary FunctionFunction

Models:Models: equal_to, not_equal_to, greater, equal_to, not_equal_to, greater, less, greater_equal, less_equal, less, greater_equal, less_equal, logical_and, logical_orlogical_and, logical_or

Page 289: C++ Training Datascope Lawrence D’Antonio

ExampleExample Here is an example of a user defined adaptive binary Here is an example of a user defined adaptive binary

predicate. This functor returns true if string s1 contains predicate. This functor returns true if string s1 contains string s2 as a substring.string s2 as a substring.

  class str_contains : public class str_contains : public

binary_function<string,string,bool>{binary_function<string,string,bool>{public:public: bool operator() (const string &s1, const string &s2)bool operator() (const string &s1, const string &s2) {{ return s1.find(s2) != string::npos;return s1.find(s2) != string::npos; }}};};

Page 290: C++ Training Datascope Lawrence D’Antonio

RNG ExampleRNG Example

Here is an adaptive unary functor that was Here is an adaptive unary functor that was almost part of STL.almost part of STL.

This is an example of a subtractive This is an example of a subtractive random number generator.random number generator.

Page 291: C++ Training Datascope Lawrence D’Antonio

RNG Example 2RNG Example 2class subtractive_rng : public class subtractive_rng : public

std::unary_function<unsigned int, unsigned int> {std::unary_function<unsigned int, unsigned int> {private:private: unsigned int _M_table[55];unsigned int _M_table[55]; size_t _M_index1;size_t _M_index1; size_t _M_index2;size_t _M_index2;public:public: // Returns a number less than the argument.// Returns a number less than the argument. unsigned int operator()(unsigned int __limit) {unsigned int operator()(unsigned int __limit) { _M_index1 = (_M_index1 + 1) % 55;_M_index1 = (_M_index1 + 1) % 55; _M_index2 = (_M_index2 + 1) % 55;_M_index2 = (_M_index2 + 1) % 55; _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index1] = _M_table[_M_index1] -

_M_table[_M_index2];_M_table[_M_index2]; return _M_table[_M_index1] % __limit;return _M_table[_M_index1] % __limit; }}

Page 292: C++ Training Datascope Lawrence D’Antonio

RNG Example 3RNG Example 3void _M_initialize(unsigned int __seed)void _M_initialize(unsigned int __seed) {{ unsigned int __k = 1;unsigned int __k = 1; _M_table[54] = __seed;_M_table[54] = __seed; size_t __i;size_t __i; for (__i = 0; __i < 54; __i++) {for (__i = 0; __i < 54; __i++) { size_t __ii = (21 * (__i + 1) % 55) - 1;size_t __ii = (21 * (__i + 1) % 55) - 1; _M_table[__ii] = __k;_M_table[__ii] = __k; __k = __seed - __k;__k = __seed - __k; __seed = _M_table[__ii];__seed = _M_table[__ii]; }} for (int __loop = 0; __loop < 4; __loop++) {for (int __loop = 0; __loop < 4; __loop++) { for (__i = 0; __i < 55; __i++)for (__i = 0; __i < 55; __i++) _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55];_M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; }} _M_index1 = 0;_M_index1 = 0; _M_index2 = 31;_M_index2 = 31; }}

Page 293: C++ Training Datascope Lawrence D’Antonio

RNG Example 4RNG Example 4 // Ctor allowing you to initialize the seed.// Ctor allowing you to initialize the seed. subtractive_rng(unsigned int __seed) { _M_initialize(__seed); }subtractive_rng(unsigned int __seed) { _M_initialize(__seed); }

// Default ctor; initializes its state with some number you don't see.// Default ctor; initializes its state with some number you don't see. subtractive_rng() { _M_initialize(161803398u); }subtractive_rng() { _M_initialize(161803398u); } }; }; main()main(){ { subtractive_rng s;subtractive_rng s; for(int i = 0; i < 20; i++)for(int i = 0; i < 20; i++) std::cout << s(10) << ' ';std::cout << s(10) << ' '; std::cout << '\n';std::cout << '\n';} }

Page 294: C++ Training Datascope Lawrence D’Antonio

RNG Example 5RNG Example 5

Here is the output from the above Here is the output from the above program.program.

3 2 1 6 7 0 7 8 0 9 3 2 1 7 6 9 3 1 0 63 2 1 6 7 0 7 8 0 9 3 2 1 7 6 9 3 1 0 6

Page 295: C++ Training Datascope Lawrence D’Antonio

Function adaptorsFunction adaptors

A function adaptor converts one type of A function adaptor converts one type of function object into another type.function object into another type.

For example, the functions bind1st and For example, the functions bind1st and bind2nd convert an Adaptable Binary bind2nd convert an Adaptable Binary Function into an Adaptable Unary Function into an Adaptable Unary Function.Function.

Page 296: C++ Training Datascope Lawrence D’Antonio

Class binder1stClass binder1st Takes an Adaptable Binary Function F(x,y) Takes an Adaptable Binary Function F(x,y)

and converts it into an Adaptable Unary and converts it into an Adaptable Unary Function Function f(y) = F(c,y)f(y) = F(c,y) where c is a where c is a constant.constant.

The function bind1st returns a binder1st The function bind1st returns a binder1st object.object.

For example, bind1st(equal_to<int>(),10) For example, bind1st(equal_to<int>(),10) returns a function object which acts like returns a function object which acts like equal_to(10,y).equal_to(10,y).

Page 297: C++ Training Datascope Lawrence D’Antonio

Class binder1st 2Class binder1st 2template <class _Operation>template <class _Operation> class binder1stclass binder1st : public unary_function<: public unary_function<

typename typename _Operation::second_argument_type,_Operation::second_argument_type,

typename _Operation::result_type>typename _Operation::result_type>{{protected:protected: _Operation op;_Operation op; typename _Operation::first_argument_type value;typename _Operation::first_argument_type value;

Page 298: C++ Training Datascope Lawrence D’Antonio

Class binder1st 3Class binder1st 3public:public: binder1st(const _Operation& __x,binder1st(const _Operation& __x, const typename _Operation::first_argument_type& __y)const typename _Operation::first_argument_type& __y) : op(__x), value(__y) { }: op(__x), value(__y) { } typename _Operation::result_type typename _Operation::result_type operator() operator() (const typename (const typename

_Operation::second_argument_type& __x) const_Operation::second_argument_type& __x) const { return op(value, __x); }{ return op(value, __x); }

};};

Page 299: C++ Training Datascope Lawrence D’Antonio

Class binder1st 4Class binder1st 4template <class _Operation, class _Tp>template <class _Operation, class _Tp> inline binder1st<_Operation>inline binder1st<_Operation> bind1st(const _Operation& __fn, bind1st(const _Operation& __fn, const _Tp& __x)const _Tp& __x){{ typedef typename _Operation::first_argument_type typedef typename _Operation::first_argument_type

_Arg1_type;_Arg1_type;

return binder1st<_Operation>(__fn, _Arg1_type(__x));return binder1st<_Operation>(__fn, _Arg1_type(__x));} }

Page 300: C++ Training Datascope Lawrence D’Antonio

Class binder2ndClass binder2nd Takes an Adaptable Binary Function F(x,y) Takes an Adaptable Binary Function F(x,y)

and converts it into an Adaptable Unary and converts it into an Adaptable Unary Function Function f(x) = F(x,c)f(x) = F(x,c) where c is a where c is a constant.constant.

The function bind2nd returns a binder2nd The function bind2nd returns a binder2nd object.object.

For example, bind2nd(equal_to<int>(),10) For example, bind2nd(equal_to<int>(),10) returns a function object which acts like returns a function object which acts like equal_to(x,10).equal_to(x,10).

Page 301: C++ Training Datascope Lawrence D’Antonio

Binder exampleBinder example

We have a list of student grades. We want to We have a list of student grades. We want to copy the grades which are below 60 into a copy the grades which are below 60 into a failures list. Since STL does not provide a failures list. Since STL does not provide a copy_if function we use the next best thing, the copy_if function we use the next best thing, the remove_copy_if function. remove_copy_if function.

This function copies all elements from a source This function copies all elements from a source range for which a given predicate evaluates as range for which a given predicate evaluates as false (i.e., it 'removes' the ones which make false (i.e., it 'removes' the ones which make the predicate true). the predicate true).

Page 302: C++ Training Datascope Lawrence D’Antonio

Binder example 2Binder example 2

So we will remove_copy_if() all grades So we will remove_copy_if() all grades which are greater than or equal to 60. which are greater than or equal to 60. There is a built-in greater_equal binary There is a built-in greater_equal binary predicate. We will bind its second predicate. We will bind its second argument to 60, to turn it into the unary argument to 60, to turn it into the unary predicate that we want to use.predicate that we want to use.

Page 303: C++ Training Datascope Lawrence D’Antonio

Binder example 3Binder example 3main()main(){{ int a[10] = { 50, 80, 60, 40, 30, 90, 100, 20 ,40 ,70 };int a[10] = { 50, 80, 60, 40, 30, 90, 100, 20 ,40 ,70 }; vector<int> grades(&a[0], &a[10]);vector<int> grades(&a[0], &a[10]); vector<int> failures;vector<int> failures;   remove_copy_if(grades.begin(), grades.end(),remove_copy_if(grades.begin(), grades.end(),

back_inserter(failures), back_inserter(failures), bind2nd(greater_equal<int>(),60));bind2nd(greater_equal<int>(),60));

   cout << "Failing grades\n";cout << "Failing grades\n"; copy(failures.begin(), failures.end(), ostream<int>(cout, “ "));copy(failures.begin(), failures.end(), ostream<int>(cout, “ "));

return 0;return 0;}}

Page 304: C++ Training Datascope Lawrence D’Antonio

Binder example 4Binder example 4

OutputOutput

Failing gradesFailing grades50 40 30 20 4050 40 30 20 40

Page 305: C++ Training Datascope Lawrence D’Antonio

Class pointer_to_unary_functionClass pointer_to_unary_function

Takes a pointer to a unary function and Takes a pointer to a unary function and converts it into an Adaptable Unary converts it into an Adaptable Unary Function.Function.

The function ptr_fun returns a The function ptr_fun returns a pointer_to_unary_function object.pointer_to_unary_function object.

Page 306: C++ Training Datascope Lawrence D’Antonio

pointer_to_unary_function 2pointer_to_unary_function 2 template <class _Arg, class _Result>template <class _Arg, class _Result> class pointer_to_unary_function : class pointer_to_unary_function :

public unary_function<_Arg, _Result> public unary_function<_Arg, _Result> {{ protected:protected: _Result (*_M_ptr)(_Arg);_Result (*_M_ptr)(_Arg); public:public: pointer_to_unary_function() { }pointer_to_unary_function() { }

Page 307: C++ Training Datascope Lawrence D’Antonio

pointer_to_unary_function 3pointer_to_unary_function 3

explicit pointer_to_unary_function(_Result explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) { }(*__x)(_Arg)) : _M_ptr(__x) { } _Result operator() (_Arg __x) const_Result operator() (_Arg __x) const { return _M_ptr(__x); }{ return _M_ptr(__x); } };};

Page 308: C++ Training Datascope Lawrence D’Antonio

pointer_to_unary_function 4pointer_to_unary_function 4

template <class _Arg, class _Result>template <class _Arg, class _Result> inline pointer_to_unary_function<_Arg, _Result>inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) { ptr_fun(_Result (*__x)(_Arg)) {

return return pointer_to_unary_function<_Arg, _Result>(__x); pointer_to_unary_function<_Arg, _Result>(__x);

}}

Page 309: C++ Training Datascope Lawrence D’Antonio

ExampleExample

Suppose we want to transform the Suppose we want to transform the elements of a vector into the negative of elements of a vector into the negative of their absolute value.their absolute value.

Page 310: C++ Training Datascope Lawrence D’Antonio

Example 2Example 2

vector<int> v;vector<int> v;//…//…transform(v.begin(), v.end(), v.begin(),transform(v.begin(), v.end(), v.begin(),

compose1(negate<int>(),compose1(negate<int>(), ptr_fun(fabs)));ptr_fun(fabs)));

Page 311: C++ Training Datascope Lawrence D’Antonio

Example 3Example 3

Here compose1 is a function returning the Here compose1 is a function returning the function adaptor, unary_compose.function adaptor, unary_compose.

The function unary_compose takes two The function unary_compose takes two functions f, g and returns their composition functions f, g and returns their composition h defined by h(x) = f(g(x)).h defined by h(x) = f(g(x)).

These elements, compose1 and These elements, compose1 and unary_compose are not in the C++ unary_compose are not in the C++ standard.standard.

Page 312: C++ Training Datascope Lawrence D’Antonio

Example 4Example 4

template <class OP1, class OP2>template <class OP1, class OP2>class unary_compose: publicclass unary_compose: public std::unary_function<typename OP2::argument_type, std::unary_function<typename OP2::argument_type,                               typename OP1::result_type>                               typename OP1::result_type>{{  private:  private:    OP1 op1;        OP1 op1;    // process: op1(op2(x))// process: op1(op2(x))    OP2 op2;    OP2 op2;

Page 313: C++ Training Datascope Lawrence D’Antonio

Example 5Example 5  public:public:

        // constructor// constructor    unary_compose(const OP1& o1, const OP2& o2)    unary_compose(const OP1& o1, const OP2& o2)     : op1(o1), op2(o2) {     : op1(o1), op2(o2) {    }    }

        // function call// function call    typename OP1::result_type    typename OP1::result_type    operator()(const typename OP2::argument_type& x)     operator()(const typename OP2::argument_type& x) 

const const  {      return op1(op2(x));   }{      return op1(op2(x));   }

};};

Page 314: C++ Training Datascope Lawrence D’Antonio

Example 6Example 6

template <class OP1, class OP2>template <class OP1, class OP2>inline unary_compose<OP1,OP2>inline unary_compose<OP1,OP2>compose1(const OP1& o1, const OP2& o2compose1(const OP1& o1, const OP2& o2

{{    return unary_compose<OP1,OP2>(o1,o2);    return unary_compose<OP1,OP2>(o1,o2);

}}

Page 315: C++ Training Datascope Lawrence D’Antonio

Class pointer_to_binary_functionClass pointer_to_binary_function

Takes a pointer to a binary function and Takes a pointer to a binary function and converts it into an Adaptable Binary converts it into an Adaptable Binary Function.Function.

The function ptr_fun returns a The function ptr_fun returns a pointer_to_binary_function object.pointer_to_binary_function object.

Page 316: C++ Training Datascope Lawrence D’Antonio

Class pointer_to_binary_function 2Class pointer_to_binary_function 2

template <class _Arg1, class _Arg2, class template <class _Arg1, class _Arg2, class _Result>_Result>

class pointer_to_binary_functionclass pointer_to_binary_function : public binary_function<_Arg1, _Arg2, _Result>: public binary_function<_Arg1, _Arg2, _Result> {{ protected:protected: _Result (*_M_ptr)(_Arg1, _Arg2);_Result (*_M_ptr)(_Arg1, _Arg2); public:public: pointer_to_binary_function() { }pointer_to_binary_function() { }

Page 317: C++ Training Datascope Lawrence D’Antonio

Class pointer_to_binary_function 3Class pointer_to_binary_function 3

explicitexplicit pointer_to_binary_function(pointer_to_binary_function(

_Result (*__x)(_Arg1, _Arg2))_Result (*__x)(_Arg1, _Arg2)) : _M_ptr(__x) { }: _M_ptr(__x) { } _Result _Result operator()(_Arg1 __x, _Arg2 __y) constoperator()(_Arg1 __x, _Arg2 __y) const { return _M_ptr(__x, __y); }{ return _M_ptr(__x, __y); }};};

Page 318: C++ Training Datascope Lawrence D’Antonio

Class pointer_to_binary_function 4Class pointer_to_binary_function 4

template <class _Arg1, class _Arg2, class _Result>template <class _Arg1, class _Arg2, class _Result> inline pointer_to_binary_function<_Arg1, _Arg2, inline pointer_to_binary_function<_Arg1, _Arg2,

_Result>_Result> ptr_fun(_Result (*__x)(_Arg1, _Arg2))ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { {

return return pointer_to_binary_function<_Arg1, _Arg2, pointer_to_binary_function<_Arg1, _Arg2,

_Result>(__x); _Result>(__x); }}

Page 319: C++ Training Datascope Lawrence D’Antonio

ExampleExample

list<char *> L;list<char *> L;

list<char *>::iterator li =list<char *>::iterator li =find_if(L.begin(), L.end(),find_if(L.begin(), L.end(),

not1(binder2nd(ptr_fun(strcmp), not1(binder2nd(ptr_fun(strcmp), “OK”)));“OK”)));

Page 320: C++ Training Datascope Lawrence D’Antonio

Class unary_negateClass unary_negate

Class unary_negate is an Adaptable Class unary_negate is an Adaptable Predicate that represents logical negation Predicate that represents logical negation of some other Adaptable Predicate.of some other Adaptable Predicate.

If f is a unary_negate object constructed If f is a unary_negate object constructed with predicate pred, then f(x) returns !with predicate pred, then f(x) returns !pred(x).pred(x).

The function not1 returns a unary_negate The function not1 returns a unary_negate object.object.

Page 321: C++ Training Datascope Lawrence D’Antonio

Class binary_negateClass binary_negate Class binary_negate is an Adaptable Class binary_negate is an Adaptable

Binary Predicate that represents logical Binary Predicate that represents logical negation of some other Adaptable Binary negation of some other Adaptable Binary Predicate.Predicate.

If f is a binary_negate object constructed If f is a binary_negate object constructed with predicate pred, then f(x,y) returns !with predicate pred, then f(x,y) returns !pred(x,y).pred(x,y).

The function not2 returns a binary_negate The function not2 returns a binary_negate object.object.

Page 322: C++ Training Datascope Lawrence D’Antonio

ExampleExample

struct U : public binary_function<U,U,bool> {struct U : public binary_function<U,U,bool> {int id;int id;bool operator() (const U &x, const U &y) {bool operator() (const U &x, const U &y) {

return x.id >= y.id;return x.id >= y.id;}}

};};

Page 323: C++ Training Datascope Lawrence D’Antonio

Example 2Example 2

main() {main() {vector<U> v;vector<U> v;

//Sort v in ascending order.//Sort v in ascending order.sort(v.begin(), v.end(), not2(U()));sort(v.begin(), v.end(), not2(U()));

}}

Page 324: C++ Training Datascope Lawrence D’Antonio

Class mem_fun_tClass mem_fun_t Class mem_fun_t is a function adaptor Class mem_fun_t is a function adaptor

that takes a member function with that takes a member function with signature R X::f() and makes it possible to signature R X::f() and makes it possible to call it as if it were an ordinary function.call it as if it were an ordinary function.

If F is a mem_fun_t that was constructed If F is a mem_fun_t that was constructed to use X::f and x is an X* pointer then F(x) to use X::f and x is an X* pointer then F(x) is equivalent to x->f().is equivalent to x->f().

The function mem_fun returns a The function mem_fun returns a mem_fun_t object.mem_fun_t object.

Page 325: C++ Training Datascope Lawrence D’Antonio

Class mem_fun_t 2Class mem_fun_t 2 There are several similar function objects.There are several similar function objects. The class const_mem_fun_t adapts a The class const_mem_fun_t adapts a

member function of the form R X::f() const.member function of the form R X::f() const. The class mem_fun_ref_t has its The class mem_fun_ref_t has its

operator() take an X& argument. So that operator() take an X& argument. So that F(x) is equivalent to x.f(). The F(x) is equivalent to x.f(). The corresponding function is mem_fun_ref().corresponding function is mem_fun_ref().

The class const_mem_fun_ref_t adapts a The class const_mem_fun_ref_t adapts a const member function.const member function.

Page 326: C++ Training Datascope Lawrence D’Antonio

Class mem_fun_t 3Class mem_fun_t 3template <class _Ret, class _Tp>template <class _Ret, class _Tp> class mem_fun_t : public unary_function<_Tp*, _Ret>class mem_fun_t : public unary_function<_Tp*, _Ret> {{ public:public: explicitexplicit mem_fun_t(_Ret (_Tp::*__pf)())mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {}: _M_f(__pf) {}

_Ret operator()(_Tp* __p) const_Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } { return (__p->*_M_f)(); }

private:private: _Ret (_Tp::*_M_f)();_Ret (_Tp::*_M_f)(); };};

Page 327: C++ Training Datascope Lawrence D’Antonio

Class mem_fun_t 4Class mem_fun_t 4

template <class _Ret, class _Tp>template <class _Ret, class _Tp> inline mem_fun_t<_Ret, _Tp> inline mem_fun_t<_Ret, _Tp> mem_fun(_Ret (_Tp::*__f)())mem_fun(_Ret (_Tp::*__f)()) { return mem_fun_t<_Ret, _Tp>(__f); }{ return mem_fun_t<_Ret, _Tp>(__f); }

Page 328: C++ Training Datascope Lawrence D’Antonio

ExampleExamplestruct B {struct B { virtual void print() = 0;virtual void print() = 0;};};

struct C: public B {struct C: public B { void print() { std::cout << "I'm a C\n"; }void print() { std::cout << "I'm a C\n"; }};};

struct D: public B {struct D: public B { void print() { std::cout << "I'm a D\n"; }void print() { std::cout << "I'm a D\n"; }};};

Page 329: C++ Training Datascope Lawrence D’Antonio

Example 2Example 2main() {main() { std::vector<B*> vbp;std::vector<B*> vbp;

vbp.push_back(new C);vbp.push_back(new C); vbp.push_back(new D);vbp.push_back(new D); vbp.push_back(new C);vbp.push_back(new C); vbp.push_back(new D);vbp.push_back(new D);

std::for_each(vbp.begin(), vbp.end(), std::for_each(vbp.begin(), vbp.end(), std::mem_fun(&B::print));std::mem_fun(&B::print));

Page 330: C++ Training Datascope Lawrence D’Antonio

Example 3Example 3

std::vector<C> vb;std::vector<C> vb;

vb.push_back(C());vb.push_back(C()); vb.push_back(C());vb.push_back(C());

std::for_each(vb.begin(), vb.end(),std::for_each(vb.begin(), vb.end(),std::mem_fun_ref(&B::print));std::mem_fun_ref(&B::print));

Page 331: C++ Training Datascope Lawrence D’Antonio

Example 4Example 4 std::vector<std::vector<int> > vi;std::vector<std::vector<int> > vi;

vi.push_back(std::vector<int>(2));vi.push_back(std::vector<int>(2)); vi.push_back(std::vector<int>(7));vi.push_back(std::vector<int>(7)); vi.push_back(std::vector<int>(6));vi.push_back(std::vector<int>(6)); transform(vi.begin(),vi.end(),transform(vi.begin(),vi.end(), std::ostream_iterator<int>(std::cout, " "),std::ostream_iterator<int>(std::cout, " "), std::mem_fun_ref(&std::vector<int>::size));std::mem_fun_ref(&std::vector<int>::size)); std::cout << '\n'; std::cout << '\n';

Page 332: C++ Training Datascope Lawrence D’Antonio

Example 5Example 5 OutputOutputI'm a CI'm a CI'm a DI'm a DI'm a CI'm a CI'm a DI'm a DI'm a CI'm a CI'm a CI'm a C2 7 6 2 7 6

Page 333: C++ Training Datascope Lawrence D’Antonio

Class mem_fun1_tClass mem_fun1_t Class mem_fun1_t is a function adaptor that Class mem_fun1_t is a function adaptor that

takes a member function with signature R X::f(A) takes a member function with signature R X::f(A) and makes it possible to call it as if it were an and makes it possible to call it as if it were an ordinary function.ordinary function.

If F is a mem_fun1_t that was constructed to use If F is a mem_fun1_t that was constructed to use X::f, a is a value of type A and x is an X* pointer X::f, a is a value of type A and x is an X* pointer then F(x) is equivalent to x->f(a).then F(x) is equivalent to x->f(a).

The function mem_fun returns a mem_fun1_t The function mem_fun returns a mem_fun1_t object.object.

Page 334: C++ Training Datascope Lawrence D’Antonio

Class mem_fun1_t 2Class mem_fun1_t 2

There are also function objects There are also function objects mem_fun1_ref_t, const_mem_fun1_t, and mem_fun1_ref_t, const_mem_fun1_t, and const_mem_fun1_ref_t.const_mem_fun1_ref_t.

Page 335: C++ Training Datascope Lawrence D’Antonio

STL AlgorithmsSTL Algorithmsfor_each()for_each()  Function Function for_eachfor_each(InputIterator beg, InputIterator end, Function f)(InputIterator beg, InputIterator end, Function f) - Applies function f to each element in range [beg,end)- Applies function f to each element in range [beg,end) - Returns f- Returns f    Nonmutating AlgorithmsNonmutating Algorithms  size_t size_t countcount(InputIterator beg, InputIterator end, const T &val)(InputIterator beg, InputIterator end, const T &val) - Returns the number of occurrences of val in range [beg,end)- Returns the number of occurrences of val in range [beg,end)size_t size_t countcount(InputIterator beg, InputIterator end, const T &val, Size &n)(InputIterator beg, InputIterator end, const T &val, Size &n) - Adds the number of occurrences of val in [beg,end) to n- Adds the number of occurrences of val in [beg,end) to n

Page 336: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 2STL Algorithms 2

size_t count_if(InputIterator beg, InputIterator end, Predicate pred)size_t count_if(InputIterator beg, InputIterator end, Predicate pred) - Returns the number of elements in range [beg,end) for which - Returns the number of elements in range [beg,end) for which

pred is truepred is true    InputIterator min_element(InputIterator beg, InputIterator end)InputIterator min_element(InputIterator beg, InputIterator end)InputIterator max_element(InputIterator beg, InputIterator end)InputIterator max_element(InputIterator beg, InputIterator end) - Returns the minimum or maximum element in range - Returns the minimum or maximum element in range

[beg,end)[beg,end)

Page 337: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 3STL Algorithms 3bool lexicographical_compare(InputIterator1 beg1, bool lexicographical_compare(InputIterator1 beg1,

InputIterator1 end1,InputIterator1 end1, InputIterator2 beg2, InputIterator end2) (Bin. Pred.)InputIterator2 beg2, InputIterator end2) (Bin. Pred.) - Returns whether or not the elements in the range - Returns whether or not the elements in the range

[beg1,end1) are less than the elements in the range [beg2,end2)[beg1,end1) are less than the elements in the range [beg2,end2)    Search FunctionsSearch Functions    InputIterator find(InputIterator beg, InputIterator end, const T &val)InputIterator find(InputIterator beg, InputIterator end, const T &val) - Finds and returns the first position of val in range [beg,end)- Finds and returns the first position of val in range [beg,end) - Returns end if val not found- Returns end if val not found

Page 338: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 4STL Algorithms 4InputIterator adjacent_find(InputIterator beg, InputIterator adjacent_find(InputIterator beg,

InputIterator end) (Bin. Pred.)InputIterator end) (Bin. Pred.) - Finds and returns the first position in range - Finds and returns the first position in range

[beg,end) for which two consecutive elements are [beg,end) for which two consecutive elements are equalequal

- Returns end if no match found- Returns end if no match found  InputIterator find_if(InputIterator beg, InputIterator end, InputIterator find_if(InputIterator beg, InputIterator end,

Predicate pred)Predicate pred) - Finds and returns the first position in range - Finds and returns the first position in range

[beg,end) for which pred is true[beg,end) for which pred is true - Returns end if no matching element found- Returns end if no matching element found

Page 339: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 5STL Algorithms 5InputIterator InputIterator adjacent_find_ifadjacent_find_if(InputIterator beg, (InputIterator beg,

InputIterator end, Predicate pred)InputIterator end, Predicate pred) - Finds and returns the first position in range [beg,end) - Finds and returns the first position in range [beg,end)

for which pred is true for two consecutive elementsfor which pred is true for two consecutive elements - Returns end if no match found- Returns end if no match found    InputIterator InputIterator search_nsearch_n(InputIterator beg, InputIterator end, (InputIterator beg, InputIterator end,

Size n, const T &val) (Bin Pred)Size n, const T &val) (Bin Pred) - Finds and returns the first position in range [beg,end) - Finds and returns the first position in range [beg,end)

for which n consecutive vals occur, in the first casefor which n consecutive vals occur, in the first case - Returns end if no matching element found- Returns end if no matching element found

Page 340: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 6STL Algorithms 6ForwardIterator1 ForwardIterator1 searchsearch(ForwardIterator1 beg1, ForwardIterator1 (ForwardIterator1 beg1, ForwardIterator1

end1, ForwardIterator2 beg2, ForwardIterator2 end2) (Bin Pred)end1, ForwardIterator2 beg2, ForwardIterator2 end2) (Bin Pred) - Returns the position of the first element of the first subrange in - Returns the position of the first element of the first subrange in

the range [beg1,end1) that matches all of the elements in the range the range [beg1,end1) that matches all of the elements in the range [beg2,end2)[beg2,end2)

- Returns end1 if no match found- Returns end1 if no match found    ForwardIterator1 ForwardIterator1 find_endfind_end(ForwardIterator1 beg1, ForwardIterator1 (ForwardIterator1 beg1, ForwardIterator1

end1, ForwardIterator2 beg2, ForwardIterator2 end2) (Bin Pred)end1, ForwardIterator2 beg2, ForwardIterator2 end2) (Bin Pred) - Returns the position of the first element of the last subrange in - Returns the position of the first element of the last subrange in

the range [beg1,end1) that matches all of the elements in the range the range [beg1,end1) that matches all of the elements in the range [beg2,end2)[beg2,end2)

- Returns end1 if no match found- Returns end1 if no match found

Page 341: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 7STL Algorithms 7ForwardIterator1 ForwardIterator1 find_first_offind_first_of(ForwardIterator1 beg1, (ForwardIterator1 beg1,

ForwardIterator1 end1, ForwardIterator2 beg2, ForwardIterator1 end1, ForwardIterator2 beg2, ForwardIterator2 end2) (Binary Pred)ForwardIterator2 end2) (Binary Pred)

- Returns the postion of the first element in the range - Returns the postion of the first element in the range [beg1,end1) that is also in the range [beg2,end2)[beg1,end1) that is also in the range [beg2,end2)

- Returns end1 if no match found- Returns end1 if no match found    bool bool equalequal(InputIterator1 beg1, InputIterator1 end1, (InputIterator1 beg1, InputIterator1 end1,

InputIterator2 beg2) (Binary Pred)InputIterator2 beg2) (Binary Pred) - Returns whether or not the elements in the range - Returns whether or not the elements in the range

[beg1,end1) are equal to the corresponding elements in [beg1,end1) are equal to the corresponding elements in the range [beg2,end2)the range [beg2,end2)

Page 342: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 8STL Algorithms 8pair<InputIterator1, InputIterator2> pair<InputIterator1, InputIterator2> mismatchmismatch(InputIterator1 (InputIterator1

beg1, InputIterator1 end1, beg1, InputIterator1 end1, InputIterator2 beg2) (Binary Pred)InputIterator2 beg2) (Binary Pred)

- Returns the first positions in the ranges starting with - Returns the first positions in the ranges starting with beg1 and beg2 that are differentbeg1 and beg2 that are different

- Returns end1 if no mismatch found- Returns end1 if no mismatch found    Mutating AlgorithmsMutating Algorithms  Note: Associative containers cannot be used as the Note: Associative containers cannot be used as the

destination of any of the following algorithms (because of destination of any of the following algorithms (because of the underlying sort of these containers) the underlying sort of these containers)

Page 343: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 8STL Algorithms 8OutputIterator OutputIterator copycopy(InputIterator sourceBeg, (InputIterator sourceBeg,

InputIterator sourceEnd, OutputIterator destBeg)InputIterator sourceEnd, OutputIterator destBeg) - Copies the range [sourceBeg,sourceEnd) to - Copies the range [sourceBeg,sourceEnd) to

the range starting at position destBeg, the range starting at position destBeg, overwriting the elements already there (no overwriting the elements already there (no memory is allocated, unless insert iterators are memory is allocated, unless insert iterators are used)used)

- The source and destination may overlap- The source and destination may overlap - Returns the position in the destination after - Returns the position in the destination after

the last element copiedthe last element copied

Page 344: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 9STL Algorithms 9BidirectionalIterator BidirectionalIterator copy_backwardcopy_backward(InputIterator (InputIterator

sourceBeg, InputIterator sourceEnd, sourceBeg, InputIterator sourceEnd, BidirectionalIterator destEnd)BidirectionalIterator destEnd)

- Copies the range [sourceBeg,sourceEnd) to - Copies the range [sourceBeg,sourceEnd) to the range starting at position destEnd (moving the range starting at position destEnd (moving backwards through the destination, so that the backwards through the destination, so that the elements end up in the same order as the elements end up in the same order as the source). Elements are overwritten (no memory is source). Elements are overwritten (no memory is allocated, unless insert iterators are used)allocated, unless insert iterators are used)

- The source and destination may overlap- The source and destination may overlap - Returns the position in destination before the - Returns the position in destination before the

last element copiedlast element copied

Page 345: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 10STL Algorithms 10OutputIterator OutputIterator transformtransform(InputIterator sourceBeg, (InputIterator sourceBeg,

InputIterator sourceEnd,InputIterator sourceEnd, OutputIterator destBeg, Function f)OutputIterator destBeg, Function f) - Applies the function f to each element of source - Applies the function f to each element of source

range and copies the return value of the function to the range and copies the return value of the function to the destination (no memory is allocated, unless insert destination (no memory is allocated, unless insert iterators are used)iterators are used)

- The source and destination ranges may be the same- The source and destination ranges may be the same - Returns the position after the last element copied- Returns the position after the last element copied

Page 346: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 11STL Algorithms 11OutputIterator OutputIterator transformtransform(InputIterator1 source1Beg, (InputIterator1 source1Beg,

InputIterator1 source1End,InputIterator1 source1End, InputIterator2 source2Beg, OutputIterator destBeg, InputIterator2 source2Beg, OutputIterator destBeg,

BinaryFunction f)BinaryFunction f) - Applies the binary function f to the corresponding - Applies the binary function f to the corresponding

elements of the two source ranges and copies the return elements of the two source ranges and copies the return value to the destination (no memory is allocated, unless value to the destination (no memory is allocated, unless insert iterators are used)insert iterators are used)

- The source and destination ranges may be the same- The source and destination ranges may be the same - Returns the position after the last element copied- Returns the position after the last element copied

Page 347: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 12STL Algorithms 12ForwardIterator2 ForwardIterator2 swap_rangesswap_ranges(ForwardIterator1 beg1, (ForwardIterator1 beg1,

ForwardIterator1 end1, ForwardIterator2 beg2)ForwardIterator1 end1, ForwardIterator2 beg2) - Swaps the elements in the ranges beginning with - Swaps the elements in the ranges beginning with

beg1 and beg2beg1 and beg2 - Returns the position after the last swapped element - Returns the position after the last swapped element

in second rangein second range    void void fillfill(ForwardIterator beg, ForwardIterator end, const T (ForwardIterator beg, ForwardIterator end, const T

&val)&val) - Assigns val to the elements in the range [beg,end)- Assigns val to the elements in the range [beg,end)

Page 348: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 13STL Algorithms 13void void fill_nfill_n(OutputIterator pos, Size n, const T &val)(OutputIterator pos, Size n, const T &val) - Assigns val to the first n elements beginning at - Assigns val to the first n elements beginning at

position posposition pos - Destination must be large enough (else insert - Destination must be large enough (else insert

iterators must be used)iterators must be used)    void void generategenerate(ForwardIterator beg, ForwardIterator end, (ForwardIterator beg, ForwardIterator end,

Function f)Function f) - Assigns the output of function f to the elements in - Assigns the output of function f to the elements in

range [beg,end)range [beg,end) - Note: the elements are not used as input to f (as in - Note: the elements are not used as input to f (as in

the transform algorithm)the transform algorithm)

Page 349: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 14STL Algorithms 14

void void generate_ngenerate_n(OutputIterator pos, Size n, (OutputIterator pos, Size n, Function f)Function f)

- Assigns the output of f to the n elements - Assigns the output of f to the n elements beginning at position posbeginning at position pos

    void void replacereplace(ForwardIterator beg, ForwardIterator (ForwardIterator beg, ForwardIterator

end, const T &old_val, const T &new_val)end, const T &old_val, const T &new_val) - Replaces each instance of old_val with - Replaces each instance of old_val with

new_val in the range [beg,end)new_val in the range [beg,end)

Page 350: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 15STL Algorithms 15void void replace_ifreplace_if(ForwardIterator beg, ForwardIterator end, (ForwardIterator beg, ForwardIterator end,

Predicate pred, const T &new_val)Predicate pred, const T &new_val) - Replaces each element in the range [beg,end) which - Replaces each element in the range [beg,end) which

makes pred true with new_valmakes pred true with new_val    void void replace_copyreplace_copy(ForwardIterator beg, ForwardIterator (ForwardIterator beg, ForwardIterator

end, OutputIterator destBeg, const T &old_val, const T end, OutputIterator destBeg, const T &old_val, const T &new_val)&new_val)

- Copies source range to destination range, in the - Copies source range to destination range, in the process it replaces each instance of old_val with process it replaces each instance of old_val with new_val in the destination rangenew_val in the destination range

Page 351: C++ Training Datascope Lawrence D’Antonio

STL Algorithms 16STL Algorithms 16void void replace_copy_ifreplace_copy_if(ForwardIterator beg, ForwardIterator end, (ForwardIterator beg, ForwardIterator end,

OutputIterator destBeg, Predicate pred, const T &new_val)OutputIterator destBeg, Predicate pred, const T &new_val) - Copies source range to destination range, in the process it - Copies source range to destination range, in the process it

replaces each element that makes pred true with new_val in the replaces each element that makes pred true with new_val in the destination rangedestination range

    Removing AlgorithmsRemoving Algorithms

ForwardIterator ForwardIterator removeremove(ForwardIterator beg, ForwardIterator end, const (ForwardIterator beg, ForwardIterator end, const T &val)T &val)

- "Removes" all elements in the range equal to val- "Removes" all elements in the range equal to val - The "removed" elements are moved to positions after return - The "removed" elements are moved to positions after return

position.position. - The function returns the position after the last element not removed- The function returns the position after the last element not removed

Page 352: C++ Training Datascope Lawrence D’Antonio

next_permutationnext_permutation#include <iostream>#include <iostream>#include <iterator>#include <iterator>#include <algorithm>#include <algorithm>

template <class BidirectionalIterator>template <class BidirectionalIterator>int snail_sort(BidirectionalIterator first, int snail_sort(BidirectionalIterator first,

BidirectionalIterator last)BidirectionalIterator last){{ int count = 0;int count = 0; while (std::next_permutation(first, last)) { ++count; }while (std::next_permutation(first, last)) { ++count; } return ++count;return ++count;}}

Page 353: C++ Training Datascope Lawrence D’Antonio

next_permutation 2next_permutation 2int main()int main(){{ int A[] = {7, 1, 3, 8, 4};int A[] = {7, 1, 3, 8, 4}; const int N = sizeof(A) / sizeof(int);const int N = sizeof(A) / sizeof(int); int count = snail_sort(A, A+N);int count = snail_sort(A, A+N); std::cout << "Sort took " << count << " permutations.\n";std::cout << "Sort took " << count << " permutations.\n"; std::copy(A, A+N, std::copy(A, A+N, std::ostream_iterator<int>(std::cout, " "));std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n';std::cout << '\n';

return 0;return 0;}}

Page 354: C++ Training Datascope Lawrence D’Antonio

next_permutation 3next_permutation 3

Output:Output:

Sort took 47 permutations.Sort took 47 permutations.1 3 4 7 81 3 4 7 8

Page 355: C++ Training Datascope Lawrence D’Antonio

next_permutation 4next_permutation 4

If we defineIf we define int A[] = {1, 3, 4, 7, 8};int A[] = {1, 3, 4, 7, 8};

Output:Output:

Sort took 120 permutations.Sort took 120 permutations.1 3 4 7 8 1 3 4 7 8

Page 356: C++ Training Datascope Lawrence D’Antonio

next_permutation 5next_permutation 5

If we defineIf we defineint A[] = {1, 4, 4, 7, 8};int A[] = {1, 4, 4, 7, 8};

Output:Output:

Sort took 60 permutations.Sort took 60 permutations.1 4 4 7 81 4 4 7 8

Page 357: C++ Training Datascope Lawrence D’Antonio

next_permutation 6next_permutation 6int main()int main(){{ int A[] = {1, 4, 7, 8};int A[] = {1, 4, 7, 8}; const int N = sizeof(A) / sizeof(int);const int N = sizeof(A) / sizeof(int);

int count = 0;int count = 0; while (std::next_permutation(A, A+N)) {while (std::next_permutation(A, A+N)) { ++count;++count; std::copy(A, A+N, std::ostream_iterator<int>(std::cout, " "));std::copy(A, A+N, std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n';std::cout << '\n'; }} ++count;++count; std::cout << "Sort took " << count << " permutations.\n";std::cout << "Sort took " << count << " permutations.\n"; return 0;return 0;}}

Page 358: C++ Training Datascope Lawrence D’Antonio

next_permutation 7next_permutation 71 4 8 7 1 4 8 7 1 7 4 8 1 7 4 8 1 7 8 4 1 7 8 4 1 8 4 7 1 8 4 7 1 8 7 4 1 8 7 4 4 1 7 8 4 1 7 8 4 1 8 7 4 1 8 7 4 7 1 8 4 7 1 8 4 7 8 1 4 7 8 1 4 8 1 7 4 8 1 7 4 8 7 1 4 8 7 1 7 1 4 8 7 1 4 8 7 1 8 4 7 1 8 4

Page 359: C++ Training Datascope Lawrence D’Antonio

next_permutation 8next_permutation 87 4 1 8 7 4 1 8 7 4 8 1 7 4 8 1 7 8 1 4 7 8 1 4 7 8 4 1 7 8 4 1 8 1 4 7 8 1 4 7 8 1 7 4 8 1 7 4 8 4 1 7 8 4 1 7 8 4 7 1 8 4 7 1 8 7 1 4 8 7 1 4 8 7 4 1 8 7 4 1 Sort took 24 permutations.Sort took 24 permutations.

Page 360: C++ Training Datascope Lawrence D’Antonio

next_permutation 9next_permutation 9

template<typename _BidirectionalIterator>template<typename _BidirectionalIterator>bool next_permutation(bool next_permutation( _BidirectionalIterator __first,_BidirectionalIterator __first, _BidirectionalIterator __last)_BidirectionalIterator __last){{ if (__first == __last)if (__first == __last) return false;return false; _BidirectionalIterator __i = __first;_BidirectionalIterator __i = __first; ++__i;++__i;

Page 361: C++ Training Datascope Lawrence D’Antonio

next_permutation 10next_permutation 10 if (__i == __last)if (__i == __last) return false;return false; __i = __last;__i = __last; --__i;--__i; for( ; ; )for( ; ; ) {{ _BidirectionalIterator __ii = __i;_BidirectionalIterator __ii = __i; --__i;--__i;

Page 362: C++ Training Datascope Lawrence D’Antonio

next_permutation 11next_permutation 11

if (*__i < *__ii)if (*__i < *__ii) {{ _BidirectionalIterator __j = __last;_BidirectionalIterator __j = __last; while (!(*__i < *--__j)) { }while (!(*__i < *--__j)) { } std::iter_swap(__i, __j);std::iter_swap(__i, __j); std::reverse(__ii, __last);std::reverse(__ii, __last); return true;return true; } }

Page 363: C++ Training Datascope Lawrence D’Antonio

next_permutation 12next_permutation 12

if (__i == __first)if (__i == __first) {{ std::reverse(__first, __last);std::reverse(__first, __last); return false;return false; }} }} }}