generic programming in the stl and beyond david r. musser rensselaer polytechnic institute

55
Generic Programming in the STL and Beyond David R. Musser Rensselaer Polytechnic Institute

Post on 19-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

Generic Programmingin the STL and Beyond

David R. MusserRensselaer Polytechnic Institute

Generic programming starts with algorithms

Lift

Minimal requirements: works with maximal

family of types

Concrete algorithm: requires specific data type

Less specialized: works with more

than one type

A 0

A 1

Lift

Lift

A m

Remove an unneeded

requirement on the type

Generic algorithm

. . .

Start here

Maximal with respect to what?

Lift

Maintain usefulness of the algorithm – make efficiency part of the

requirements

Concrete algorithmA 0

A 1

Lift

Lift

A mGeneric

algorithm

. . .

float max_element(float a[], int N) { if (N == 0) throw MaxElementEmptyArrayError; int first = 0; float max = a[0]; while (++first < N) if (max < a[first]) max = a[first]; return max;}

int max_element(float a[], int first, int last) { if (first == last) return first; int result = first; while (++first != last) if (a[result] < a[first]) result = first; return result;}

float_list_node* max_element(float_list_node* first, float_list_node* last) { if (first == last) return first; float_list_node* result = first; while (first->next != last) if (result->data < first->data) result = first; return result;}

int max_element(float a[], int first, int last) { if (first == last) return first; int result = first; while (++first != last) if (a[result] < a[first]) result = first; return result;}

template <typename E>int max_element(E a[], int first, int last) { if (first == last) return first; int result = first; while (++first != last) if (a[result] < a[first]) result = first; return result;}

template <typename T>T*max_element(T* first, T* last) { if (first == last) return first; T* result = first; while (++first != last) if (*result < *first) result = first; return result;}

template <typename ForwardIterator>ForwardIterator max_element(ForwardIterator first, ForwardIterator last){ if (first == last) return first; ForwardIterator result = first; while (++first != last) if (*result < *first) result = first; return result;}

int a[] = {6, 3, 7, 5};

int* ai = max_element(a, a+4);

vector<int> v(a, a+4);vector<int>::iterator vi = max_element(v.begin(), v.end());

list<int> x(a, a+4); list<int>::iterator li = max_element(x.begin(), x.end());

. . .

Forward Container

Concept

max_element

max_element

max_element

373

7

Generic algorithm

on

j kj k

k = ++j*j = 3*k = 7

++i*ii==j

What is a concept?

Concept

Intension Extension

Requirement 1

Requirement 2....Requirement N

Abstraction 1

Abstraction 2...Abstraction K...

Polygon Concept

Intension Extension

Closed plane figure

N sides

. . .

Container Concept

Intension Extension

Must be a type whose objects can store other objects (elements)

Must have an associated iterator type that can be used to iterate through the elements.

. . .

vector<T>, for any Tdeque<T> for any Tlist<T> for any Tslist<T> for any Tset<T> for any Tmap<T> for any Tself_adjusting_bag

A

Algorithm A works with every type T in concept C

Definition: an algorithm is generic if it works with every type in a concept

“works”: is correct and efficient

CT…

What does it mean to refine a concept?

Requirement 1Requirement 2. . .Requirement N

refine

Requirement 1Requirement 2. . .Requirement NRequirement N+1

Abstraction 1Abstraction 2. . .Abstraction K. . .

Abstraction 1

Abstraction 3. . .

. . .

Abstraction 2. . .Abstraction K. . .

More Requirements,

FewerAbstractions

Polygon Concept

Closed plane figureN sides

refine

Closed plane figureN sidesN = 3

Triangle Concept

. . .

. . .

Requirement 1Requirement 2. . .Requirement N

refine

Requirement 1Requirement 2. . .Requirement NRequirement N+1

Abstraction 1Abstraction 2. . .Abstraction K. . .

Abstraction 1

Abstraction 3. . .

. . .

Abstractionsthat remain are ones that are morespecialized.

Polygon Concept

Closed plane figureN sides

refine

Closed plane figureN sidesEqual side lengths

EquilateralPolygon Concept

. . .

. . .

Container Concept

refine

refine

refine

Forward Container

Concept

Reversible Container

Concept

Random Access Container

Concept

Forward Container Concept

Intension Extension

Container Intension

Elements must be arranged in a definite order

Iterator type must model Forward Iterator concept

. . .

vector<T> for any Tdeque<T> for any Tlist<T> for any Tslist<T> for any Tset<T> for any Tmap<T> for any T

self_adjusting_bag

Reversible Container Concept

Intension Extension

Forward Container Intension

Must have an associated reverse iterator type

Iterator and reverse iterator types must model Bidirectional Iterator concept . . .

vector<T> for any Tdeque<T> for any Tlist<T> for any T

set<T> for any Tmap<T> for any T

slist<T> for any T

Random Access Container Concept

Intension Extension

Reversible Container Intension

Iterator types must model Random Access Iterator concept . . .

vector<T> for any Tdeque<T> for any T

list<T> for any Tset<T> for any Tmap<T> for any T

A more refined conceptpermits

better algorithms

refine

A

Algorithm B can be more efficient than A

(B doesn’t have to work with as many types as A)

B

C

D

For any Polygon P

Circumference(P) =

sum = 0; for s in sides(P) sum += length(s)

For any Equilateral Polygon P

Circumference(P) =

N * side_length(P)

Container

refine

refine

refine

Forward Container

Reversible Container

Random Access Container

enables generic algorithms copy, equal, transform, …

enables find, merge, fill, replace, remove, unique, rotate, max_element, …

enables reverse, partition, rotate, inplace_merge, …

enables sort, binary_search, rotate random_shuffle, …

RequiresInput Iterators

Forward Iterators

Bidirectional

Iterators

Random Access Iterators

Container

refine

refine

refine

Forward Container

Reversible Container

Random Access Container

enables generic algorithms copy, equal, transform, …

enables find, merge, fill, replace, remove, unique, rotate, max_element, …

enables reverse, partition, rotate, inplace_merge, …

enables sort, binary_search, rotate, random_shuffle, …

RequiresInput Iterators

Forward Iterators

Bidirectional

Iterators

Random Access Iterators

Container

Forward Container

Reversible Container

Random Access Container

Sequence

Front InsertionSequence

Back InsertionSequence

VectorDequeSlist

List

Concept C

Intension Extension

A models C A is in Extension of C

A

A satisfies Intension of C (A makes R , …, R true)

R , …, R

N1

1 N

. . .

. . .

Output Iterator

Forward Iterator

Bidirectional Iterator

Random Access Iterator

Vector iterator

Input Iterator

Deque iterator

Slist iterator

List iterator

Istream iterator Ostream iterator

template <typename ForwardIterator>ForwardIterator max_element(ForwardIterator first, ForwardIterator last){ if (first == last) return first; ForwardIterator result = first; while (++first != last) if (*result < *first) result = first; return result;}

template <typename Iterator models Forward Iterator>Iterator max_element(Iterator first, Iterator last){ if (first == last) return first; Iterator result = first; while (++first != last) if (*result < *first) result = first; return result;}

int a[] = {6, 3, 7, 5};

int* ai = max_element(a, a+4);

vector<int> v(a, a+4);vector<int>::iterator vi = max_element(v.begin(), v.end());

list<int> x(a, a+4); list<int>::iterator li = max_element(x.begin(), x.end());

int a[] = {6, 3, 7, 5};assert int* models Forward Iterator;int* ai = max_element(a, a+4);

vector<int> v(a, a+4);assert vector<int>::iterator models Forward Iterator;vector<int>::iterator vi = max_element(v.begin(), v.end());

list<int> x(a, a+4); assert list<int>::iterator models Forward Iterator;list<int>::iterator li = max_element(x.begin(), x.end());

template <typename T models C>

Assume that T satisfies Intension of C when checking uses of T in the algorithm. We need to use both the syntactic and the semantic properties listed in the intension.

assert T models C;

Check that T satisfies Intension of C.

Should check that both the syntactic and the semantic requirements are satisfied.

What’s this aboutsemantic requirements?

template <typename ForwardIterator>ForwardIterator max_element(ForwardIterator first, ForwardIterator last){ if (first == last) return first; ForwardIterator result = first; while (++first != last) if (*result < *first) result = first; return result;}

template <typename ForwardIterator, typename StrictWeakOrder>ForwardIterator max_element(ForwardIterator first, ForwardIterator last, StrictWeakOrder compare){ if (first == last) return first; ForwardIterator result = first; while (++first != last) if (compare(*result,*first)) result = first; return result;}

Strict Weak Order:assumed in all STL

sorting-related algorithms

<:TTbool

Transitive[E/<]E(x,y) not(x<y) & not(y<x)

Binary Relation

for all x: not(x < x)

Irreflexive

for all x, y, z: x < y & y < z implies x < z

Transitive

Strict Partial Order

Strict Weak Order

Functor

IrreflexiveTransitiveTransitive[E/<]E(x,y) not(x<y) & not(y<x)

Strict Weak Order

for all x, y: x < y | y < x | x = y

Trichotomy

TotalOrder

Sufficient for all STL sorting-relatedgeneric algorithms

Not needed!

vector<int> v;// Put some elements in v: ... ... // Sort v into descending order:sort(v.begin(), v.end(), greater_equal<int>());

// Why doesn’t the above call// terminate?

vector<int> v;// Put some elements in v: ... ...// Sort v into descending order:sort(v.begin(), v.end(), greater<int>());

// Now we get here - that’s better!

vector<int> v;// Put some elements in v: ...// Sort v into descending order:assert greater<int> models Strict Weak Order;sort(v.begin(), v.end(), greater<int>());

Container Iterator Algorithm Functor Adaptor Allocator

STL Concepts

Container Iterator Algorithm Functor Adaptor Allocator

Boost Graph Library Concepts

Graph Visitor

BFS Visitor

DFS Visitor

Uniform Cost Visitor

See http://www.boost.org

Graph Algorithm

Graph Algorithm + Visitor = More Specialized Algorithm

Visitor

BFS Visitor

DFS Visitor

Uniform Cost Visitor

Algorithm

DFS+ topological_sort_visitor =

TopologicalSort

+ cycle_detection_visitor = Cycle Detector

Let’s summarize

Lift

Concrete algorithms

A 0

A1

Lift

Lift

Am

Generic algorithms

. .

Concept Taxonomy

Useful Data and Algorithm Abstractions – a Generic Library

C requires . . .

template <typename T models C>. . .assert T models C

Making Concepts First Class Constructs

. . . for formal checking of

syntactic and semantic

properties and using

them in software

engineering

Algorithms, Concepts & Challenges