140 likes | 245 Views
Extending STL. when more is needed. Iterator Review. input (read) – read only access, forward-only, can be assigned and copied forward – read/write access, forward-only, can be assigned and copied bidirectional – same as forward plus can move backward
E N D
Extending STL when more is needed
Iterator Review • input (read) – read only access, forward-only, can be assigned and copied • forward – read/write access, forward-only, can be assigned and copied • bidirectional – same as forward plus can move backward • random access – same as forward plus operator arithmetic and comparison (including <, >, >= <=) – same as (dumb) pointers • output (write) – write-only access, forward only, cannot be assigned, cannot be compared for equality
void Iterator Movement Functions implemented as templates • advance(iterator, position) – move iterator,position elements, returns void, iterator needs to be at least input • if iterator is input – moves copy of iterator by repeatedly calling increment • if iterator is random access – calls operator+(position) • next(iterator, position) – returns iterator pointing position elements forward, original iterator is not modified • prev(iterator,position) - same as next in reverse direction • distance(firstIterator, lastIterator) – returns the number of elements between firstIterator and lastIterator. If iterators are random access, uses subtract, otherwise repeatedly calls increment++
Iterator Adapters • declared in <iterator> • reverse_iterator – iterates in reverse order (increment advances backward) • rbegin() – returns reverse iterator starting at the last element of container • rend() – returns iterator before the first element • base() – returns underlying iterator plus one – useful to determine distance to beginning • insert iterators – special type of output iterators designed for algorithms (such as copy) to insert rather than overwrite elements • insert_iterator() – calls insert(position, element) on container • is initialized with container, position • inserter(conaiter, position) returns insert iterator on this position • useful for associative containers whose keys are usually not modifiable on iteration • back_insert_iterator() – calls push_back() on container • back_inserter(container) returns back_insert_iteratorfor this container • front_insert_iterator() – calls push_front()
Algorithms • extending STL with specialized algorithms is relatively straightforward • algorithm find_all • implemented as template • takes an iterator range and a predicate and returns a vector of iterators pointing to values that match predicate • internally uses find_if • would be nice to rather return a specialized iterator that iterates over matching values • need iterator/container – more involved
Container Example: Hashmap • hashmap a variant of unordered_map developed from scratch • we start with a basic hashmap that does not implement iterators and cannot be used with STL algorithms • elements – key, value pairs • hashes, or maps, a key to a bucket • implements a vector of buckets with a list of <key,values> at each bucket (chained hashing)
Hashmap: Hash • hash – hashing function • clients may provide their own, specify number of buckets • DefaultHash a separate class - default implementation, accepts numBuckets, throws invalid_argument exception if number of buckets is less than one • computes a sum of bytes in a key, modulo numBuckets • basic hash, key uniformity is not achieved • specializes template for strings – since only need to hash the string values, not whole object
Hashmap: Interface & Implementation • supports three basic functions: insertion, deletion and lookup • constructor, destructor, copy constructor, (basic) copy assignment, (c++11) move, (c++11) move assingment • template parameters • key • value • compare – by default an equal_to functor for comparison – to detect attempts to insert elements with duplicate keys • hash – by default DefaultHash • typedefs: key_type, mapped_type, value_typeshorten code • implementation • fixed size (number of buckets) vector of pointers to lists containing <key, element> pairs • comparison object • hash object • number of elements in the container
Hashmap: Element Lookup • helper method findElement() – uses hash to find bucket, then looks into bucket to find element, using functor for comparison, if not found returns end of bucket • note the use of typename in return value – needed because template parameters are used • find() - a wrapper around findElement() • operator[] – uses find() to determine if element present • if yes – returns it • if not – use insert() to insert it, find() to find and return it • insert() – finds using findElement() if not found - insert
FinalHashmap: STL Compliant Container need to implement • public typedefs • additional typedefs for associative container • methods required per container • additional methods for associative container • iterator
FinalHashmap: Typedefs need to have public typedefs • value_type • reference • const_reference • iterator • const_iterator • size_type – usually size_t • difference_type - difference between two iterators addional typedefs for associative container • key_type • key_compare • value_compare – implemented as nested class
FinalHashmap: Typedefs need to have public typedefs • value_type • reference • const_reference • iterator • const_iterator • size_type – usually size_t • difference_type - difference between two iterators addional typedefs for associative container • key_type • key_compare • value_compare – implemented as nested class
FinalHashmap: Methods not a complete list • default constructor, copy constructor, move constructor (C++11) • copy assignment operator, move assignment operator • iterator begin(), iterator end() • operator== • swap() • size_type size() • size_type max_size() - this needs to be no larger than a single list • empty() associative container methods • range constructor • initializer list constructor (C++11) • key_comp, value_comp() – key/value comparison functions • insert() – several different versions • clear() • size_type (key_type) • returns iterator to specified key
FinalHashmap: Iterator design decisions • need to implement at least: operator* and operator-> • decide on kind: bidirectional (random access does not make sense) Therefore, need to implement • operator++, operator--, operator==, operator!= • how to order: step through buckets (sorted order is inefficient) • internal representation: hashmap object, bucket number, bucket list iterator • representation of the end-iterator: end of the last list implementation • implement as a template, sublcass from iterator template • operator++, operator-- (all forms) refer to increment() and decrement() helpers which find previous/next element in container