1.3 Resource Ownership

Judging from its usage illustrated above: which rule must be satisfied in the implementation of class LogFileReader (or one of its members)?

Name a popular technique in resource management that depends on this rule, and briefly explain its principle.

2. Iterators

2.1 Algorithm Basics

The following algorithm dereferences and returns a given iterator’s successor unless the successor’s referenced value matches some condition. The algorithm is semantically correct but does not compile for iterators of some containers.

Which containers? Briefly explain why the algorithm does not work for these and how it has to be changed.

2.2 Container Wrapper

The STL’s std::vector guarantess that its elements are stored in a contiguous memory region and is therefore compatible to C-style arrays. The member function .data() returns a pointer to the vector’s underlying raw memory.

For many hardware-tuning techniques, data is accessed in chunks. Assuming a std::vector<uint32_t> and 64 bytes per cache line, for example, vector elements could be loaded in chunks of 64/(32/8) = 16 elements.

Write a container wrapper

cpppc::chunks<B, T, Container>

that provides a sequential container interface on elements in Container in chunks of maximum size B bytes.

The template signature is derived from std::stack, a similar wrapper type defined in the STL:

3. Algorithms, Function Templates, Type Deduction

prints the base 10 logarithm of the value’s square root if it is a floating point value

Implement a function interface void print_walk(T begin, T end) that accepts a range of iterators of type T and prints all values in the range. In this, the iteration order depends on the iterator type:

for random-access iterators, the order should be (pseudo) random but every element in the range must only be printed once

for input iterators, elements are printed in order from begin to end-1

for bidirectional iterators, elements are printed in reverse order from end-1 to begin

4. Thread-Safety

4.1 Parallelism and STL Containers

Given the following operations on an instance of std::vector, consider operations in the same table row to be executed by multiple threads in parallel:

For every pair of operation on the same table row, give a brief explanation on the guarantees with respect to thread-safety according to the C++ standard.

4.2 Producer-Consumer Problem

Simply put, one thread is producing goods and another thread is consuming goods. We want the consumer thread to wait using a condition variable, and we want goods.push(i) to be mutually exclusive to goods.pop().

We are letting c++ and c– be surrogates for this mutual exclusion, since we can easily check if we correctly end up with 0 in the end.

Run the code as it is, and you will see that the net value is way off:

Note:

I know there is an easier solution, however the condition variable approach is more efficient in many cases and not as commonly known as it should be.