writing your own stl container
DESCRIPTION
Ray Lischner [email protected]. Writing Your Own STL Container. Who Am I?. Ray Lischner Author C++ in a Nutshell Learning C++ STL Pocket Reference Oregon State University. What Is The STL?. A.Silly Three Letters B.Standard Template Library C.So That’s Life D.Sue The Lawyers!. - PowerPoint PPT PresentationTRANSCRIPT
Who Am I?
• Ray Lischner
• Author● C++ in a Nutshell● Learning C++● STL Pocket Reference
• Oregon State University
What Is The STL?
• A. Silly Three Letters
• B. Standard Template Library
• C. So That’s Life
• D. Sue The Lawyers!
What Is The STL?
• A. Silly Three Letters
• B. Standard Template Library
• C. So That’s Life
• D. Sue The Lawyers!
What Is The STL?
• A. Silly Three Letters
• B. Standard Template Library
• C. So That’s Life
• D. Sue The Lawyers!
STL
• Standard Template Library
• Containers● deque, list, map, multimap, multiset, set, vector● string
• Iterators
• Algorithms
STL
• Standard Template Library
• Containers● deque, list, map, multimap, multiset, set, vector● string● TR1 adds: array, unordered_map,
unordered_multimap, unordered_multiset, unordered_set,
• Iterators
• Algorithms
Experience
• A. I’ve never used STL containers
• B. I have used containers, iterators, and algorithms a little
• C. I use containers, iterators, and algorithms often
• D. I have implemented my own container
What Is a Container?
• A template, parameterized on element type
• Stores multiple, homogeneous elements
• Characterized by complexity metrics● # of operations for insertion, deletion● # of operations for lookup
Kinds of Containers
• Sequence● deque, list, vector● array
• Associative● map, set● multimap, multiset● unordered_map, unordered_set● unordered_multimap, unordered_multiset
Common Standards
• Standard dictates common attributes
• Common sense
Container Review
• Elements must be assignable, copy-constructible● T a, b● T c(a);● b = a;
•Common Members
• Types:● value_type, size_type, etc.
• Constructors: default, copy
• Destructor
• Assignment operator
• Relational and equality operators
• Member functions● begin(), end()● size(), swap(), max_size(), empty()
Sequence Members
• insert() single or multiple elements
• erase() single or multiple elements
• clear() entire container
• sequence constructors
Integer or Not?
• Insertion and construction● insert(position, x, y)● std::vector<sometype> example(x, y);
• If x and y are integers● Insert or construct x copies of y
• Else x and y must be iterators● Copy elements from range [x, y)
Sequence Members
• Only if constant complexity● back(), pop_back(), push_back()● front(), pop_front(), push_front()● at(), operator[]
Singly-linked List
template<class T>
class slist {
...
};
Singly-Linked List Review
next
value next
value
next
value
next
value
Inserting a Node
next
value next
value
next
value
next
value
next
value
Erasing a Node
next
value next
value
next
value
next
value
next
value
Design Decisions
• Store head only?
• Store head and tail?
• Store size or compute as needed?
Front and Back
• Sequence containers
• Constant complexity
• Member functions:● front(), push_front(), pop_front()● back(), push_back(), pop_back()
Container Adapters
• priority_queue, queue, stack
• queue● Requires back(), front(), push_back(),
pop_front()
• stack● Requires back(), push_back(), pop_back()
Heads and Tails
• Does tail help implement adapters?
• Call the head “front” or “back”?
Insertion and Erasure
• Can insert after a given node
• Can erase the node after a given node
• Can easily erase at head
Stack vs. Queue
• Stacks● head is back
• Queue● head is front● tail is back
What Good Is a Tail?
• push_back()
• back_inserter iterator adapter
Container Size
• Standard does not require constant complexity
• Gotcha for std::list::size()
Splicing
• std::list::splice moves nodes from one doubly-linked list to another
• Splicing is fast
• But explicit size data member requires linear complexity
• What’s more important, size or splice?
Lazy Evaluation
• Explicit size data member
• Kept up-to-date after insertion, erasure
• Can be marked as “unknown” after calling splice
• Call to size() when size is unknown counts every node in list
More Important?
• A: Optimize size()
• B: Optimize splice()
• C: Lazy-evaluation
• D: I have a better idea
More Important?
• A: Optimize size()
• B: Optimize splice()
• C: Lazy-evaluation
• D: I have a better idea
•Allocators
• Second template parametertemplate<class T,
class Alloc = ::std::allocator<T> >
class slist { ... };
• Allocates/deallocates memory
• Constructs/destructs nodes
Separate Allocation and Construction
• allocate(number_of_items)
• construct(pointer, value_to_copy)
• deallocate(pointer, number_of_items)
• destroy(pointer)
Rebind
• Alloc<T> allocates items of type T
• But slist needs to allocate nodes, not elements
• Need to rebind allocator for nodes● allocator<T>::rebind<node_type>::other
Avoid Memory Leaks
• new_node allocates & constructs nodes
• If constructor throws, new_node should deallocate memory
Iterator
• Points to one node in a list
• Advances to next node
• Compares with other iterators
• Special value denotes “one past end”
Iterator Review
• Like a smart pointerslist<int> list;
slist<int>::iterator iter =list.begin();
if (not list.empty())
++iter;
if (iter != list.end())
std::cout << *iter << '\n';
Iterator Review
• Five flavors● Input● Output● Forward● Bidirectional● Random Access
How Are Iterators Used?
• Insertion point
• Item(s) to erase
• Item(s) to copy
Insertion
next
value next
value
next
value
next
value
next
valueiterator
Erasure
next
value next
value
next
value
next
value
next
valueiterator
Iterator Design
• Need to store pointer to prior node
• Null prior pointer when iterator at head
• What about end()?
• Also store pointer to current node
• Null current pointer means end()
Comparing Iterators
• Compare iterators by comparing current node pointers
• Difficulty comparing iterator and const_iterator● See Scott Meyers’ Effective STL, Item 26
• Use a common base class
Iterator Design
iterator_base
operator==operator!=
iterator const_iterator
Iterator Invalidation
• Certain operations render iterators invalid
• Erasure● Invalidates iterators that point to the erased
node● Or to the subsequent node
• Insertion● Invalidates iterators that point to the insertion
position
Exception Safety
• Basic guarantee: list remains valid● unique
• Strong guarantee: list is unchanged● sort
• No-throw guarantee● swap, splice
Which Guarantee for insert of one item?
• A: None
• B: Basic
• C: Strong
• D: No throw
Which Guarantee for insert of one item?
• A: None
• B: Basic
• C: Strong
• D: No throw
Which Guarantee for insert of multiple items?
• A: None
• B: Basic
• C: Strong
• D: No throw
Which Guarantee for insert of multiple items?
• A: None
• B: Basic
• C: Strong
• D: No throw
Rollback
• insert() multiple items
• After inserting x items, an exception is thrown
• Need to erase those x items before returning
Insert or Construct Multiple Items
• insert() function or constructor:● insert(position, x, y)● slist(x, y)
• If arguments are integers● Insert x copies of y
• Else arguments must be iterators● Copy elements from range [x, y)
Test for Integer Type
• If TR1 is available, use its type_traits● #include <type_traits>● Specialize on compile-time constant
std::tr1::is_integral<T>::value
• Use Boost● #include <boost/type_traits.hpp>● Specialize on boost::is_integral<T>::value
• Write your own
Miscellaneous List Functions
• splice
• merge, merge_sort
• unique
• Relational and equality operators
For More Information
• C++ in a Nutshell, Ray Lischner
• The C++ Standard Library, Nicolai Josuttis
• Effective STL, Scott Meyers
• The C++ Standard Template Library, Plauger, et al.
• STL Pocket Reference, Ray Lischner
Questions?