Document ID: /fineweb-2-swissfilter-quality_10-filterrobots/filtered/03514.jsonl.gz/2190

Ex W4

|home |print view |recent changes |changed March 14, 2018 | |You are <ip-pii> <- set your identity!
In dieser Aufgabe erstellen Sie schrittweise die grundlegende Datenstruktur für einen BoundedBuffer. Ihre Implementation wird die erste Testatabgabe sein. Sie können das Testat in Gruppen von bis zu drei Studenten abgeben:
BoundedBuffers werden in einer Umgebung eingesetzt, in welcher Producer und Consumer eine gemeinsame Datenstruktur zur Austausch von Elementen verwenden. Der BoundedBuffer hat eine fixe Grösse und wird als FIFO-Queue implementiert. Für einen Consumer ist es wichtig, dass er nicht Daten aus einem leeren Buffer auslesen kann. Der Producer auf der anderen Seite darf nicht in einen vollen Buffer hineinschreiben.
Ihre Implementation wird auf einem Array (std::array) basieren und der Funktionsweise eines Circular Buffers entsprechen.
Folgende Member Funktionen muss ihr BoundedBuffer aufweisen:
empty– dient der Abfrage ob der Buffer leer ist
full– dient der Abfrage ob der Buffer voll ist
size– gibt die Anzahl Elemente im Buffer zurück
front– liefert das erste Element im Buffer zurück; dies kann veränderbar sein
back– liefert das letzte Element im Buffer zurück; dies kann veränderbar sein
push– fügt ein neues Element in den Buffer ein
pop– entfernt das erste Element aus dem Buffer
swap– tauscht den Inhalt mit einem anderen BoundedBuffer (Parameter) aus
Folgende Member Typen muss ihr BoundedBuffer haben:
value_type
container_type
reference
const_reference
size_type
Sie erhalten für jede Aufgabe Test-Suiten. Wir empfehlen Ihnen jeweils nur einen einzelnen Test hinzuzunehmen (die nachfolgenden auskommentieren). Meistens wird dies zu einer Red-Bar führen. Implementieren Sie nur so viel Code, dass Sie wieder eine Green-Bar erhalten. Fügen Sie anschliessend den nächsten Test hinzu.
Implementieren Sie zuerst die Deklarationen der Member von BoundedBuffer ohne Logik, um einen kompilierfähigen BoundedBuffer Typ zu erhalten.
bounded_buffer_signatures_suite
Tipp: Wenn Sie sich bei den Signaturen der Member Funktionen unsicher sind, können Sie sich bei denjenigen von Queue inspirieren lassen.
Anmerkung: Wir haben einige Tests zur Verfügung gestellt, welche nicht wirklich sinnvoll für ein reales Test-Szenario sind. Sie helfen Ihnen jedoch die Member direkt richtig zu deklarieren, so dass Sie sie später nicht mehr anpassen müssen. Diese Tests sind von Boost (type_index.hpp) abhängig. Entsprechend sollte die Boost-Library auf dem System installiert oder im Projekt eingebunden werden. Vorsicht! Die Boost-Headers eines CUTE Projekts (Häkchen im Wizard) reichen nicht für diese Test-Cases.
Implementieren Sie nun das Verhalten der Member-Funktionen für einen default-konstruierten Buffer. Vermeiden Sie dabei Undefined Behavior!
empty- gibt true zurück
full– gibt false zurück, ausser wenn der Buffer mit Grösse 0 erstellt wurde
size– liefert 0
front– wirft eine Exception (std::logic_error)
back– wirft eine Exception (std::logic_error)
push– fügt ein Element hinzu, dies ist jedoch nicht ohne weiteres zu beobachten und das Abspeichern des Elements kann im Moment ignoriert werden. Für einen Buffer der Grösse 0 wird jedoch eine Exception (std::logic_error) geworfen, da der Buffer voll ist.
pop– wirft eine Exception (std::logic_error)
swap– bei leeren Buffern passiert hier nichts
bounded_buffer_default_behavior_suite
Da das Buffer-Interface jetzt steht, können Sie die benötigte Logik implementieren. Sie haben beim Array-basierten zirkulären Buffer zwei Möglichkeiten, wie sie diesen realisieren. Dies wissen Sie jedoch bereits aus Algorithmen & Datenstrukturen. Eine kurze Zusammenfassung:
Die letztere Variante ist einfacher zu implementieren und verständlicher zu lesen. Sie können aber auch die erste Variante nehmen, dann müssen Sie den Test, welcher den Typ
BoundedBuffer::container prüft aber anpassen.
Ansonsten sollte das Verhalten des Buffers selbsterklärend sein:
push()) wird auch zuerst wieder entfernt (
pop()). Das zuerst eingefügte Element kann mit
front()geholt werden und
back()liefert das zuletzt eingefügte Element zurück.
swap()vertauscht den Inhalt mit dem Argument-Buffer
Verwenden Sie für den Elementzugriff vom Array möglichst die
at()-Funktion, damit Sie sehen, falls Sie versehentlich auf ein Element ausserhalb des gültigen Bereichs zugreifen.
bounded_buffer_content_suite
Weiter gibt es noch eine Test-Suite, welche sicherstellt, dass die Elemente mit den richtigen Operationen verschoben und kopiert werden. Diese Suite arbeitet mit einem Objekt welches die Memory-Operationen aufzeichnet und schlussendlich prüft, ob die erwarteten Copy/Move-Operationen verwendet wurden.
bounded_buffer_semantic_suite
Die impliziten-Konstruktoren genügen für die Implementation bis anhin. Implementieren diese nun selber, so dass jeweils die passende Operation auf die Elemente angewendet wird, so wie es die impliziten Konstruktoren auch machen. Implementieren Sie die folgenden Special Member Functions:
Später werden wir den BoundedBuffer abändern, so dass er mit Heap-Memory arbeitet und dann werden wir die eigenen Konstruktoren benötigen.
Da Sie nun alles durchgelesen haben, hier ist das Archiv mit den vorgegeben Dateien:
Erstellen Sie ein neues CUTE Executable Projekt und legen Sie die Dateien des Archivs im
src-Verzeichnis ab. Die Datei BoundedBuffer.h müssen Sie selber erstellen.
In the lecture you have been taught about type deduction for function templates (and
auto), e.g. in source code as follows:
template<typename T> void f(T && t) {...}
When the template above is instanciated, the type
T is deduced, which also implies the specific type of the parameter
t. This deduction follows specific rules, depending on the declared template parameter type (above
T&&). If you don't recall them exactly, have a look at the corresponding slides. If you have trouble understanding the rules, discuss them with your colleagues or ask your supervisor.
When you are confident you can play a game we have prepared for you. It's a console-based trivia game which asks you about ten specific cases with a given function template declaration and a corresponding call. You will be asked about the deduced type of
T and
t.
Here are the sources of the game. Create a new empty C++ project (and add the boost library to the includes if necessary). Have fun!
Sources: https:files/TypeDeductionTrivia.zip
Remarks: You can have a look at the source code of the game. But, beware of the QuestionGenerator.cpp! There is some preprocessor magic in it, which might be tough to understand if you are unfamilliar with it. It was necessary for overcomming the lack of reflection in C++. Don't worry, we won't ask you to know about such stuff in the exam though.
Remarks 2.0: The cases are hardcoded, but the actual answers are retrieved from the cases (under the assumption your compiler and boost do a decent job in figuring them out). If you feel you might have missed some of the cases due to the random selection for the trivia, you can use the
printAll function to see all questions with the correct answers.

|home |print view |recent changes |changed March 14, 2018 |
|You are <ip-pii>
<- set your identity!

Ex W4