CS253: Software Development with C++

Spring 2022

HW 6

CS253 HW6: a real container!                

📺                 

Changes                

Updates to the assignment will be noted here. None yet!                 

Description                

For this assignment, you will improve upon your HW4 work. The Show and Schedule will have all the functionality of HW4, with additions described below.                 

Order                

Unlike HW4, the order of the Show objects within a Schedule is now defined. They are ordered primarily by time, and secondarily by channel name, e.g.:

This sorted order will be reflected in ostream << Schedule, subscripting via [ ], and for-each loops.                 

Methods & operators                

Schedule will have the following additional methods:                 

.grups(flag)
(Term used in ST:TOS: Miri.)
Control adult content for this Schedule. If flag is false, then iteration via for-each will exclude adult shows. If the optional flag is true or not given, or if this method has not been called on an object, then for-each will return all shows, adult or not.
This doesn’t affect subscripting via [ ], or ostream << Schedule output.
.begin()
Return an object of type Schedule::iterator “pointing” to the first show that matches the .grups() criteria.
.end()
Return an object of type Schedule::iterator “pointing” one past the last show that matches the .grups() criteria.

Schedule::iterator is a ForwardIterator, so these operators must work, where sit is a Schedule::iterator:                 

++sit
sit++
Increment the iterator, going to the next show, as filtered by the .grups() setting. Preincrement returns the new iterator value, and postincrement returns the previous value, in the same manner as ++ works on integers.
*sit
Yields, by value, the Show that the iterator is “pointing” to.
sit == sit
sit != sit
Compares two iterators for equality or inequality.
copy, assignment
Iterators are copy-constructable, and assignable.

Const-correctness, for arguments, methods, and operators, is your job. For example, it must be possible to iterate over a const Schedule using for-each.                 

Debugging                

If you encounter “STACK FRAME LINK OVERFLOW”, then try this:

    export STACK_FRAME_LINK_OVERRIDE=ffff-ad921d60486366258809553a3db49a4a

This is the Colorado State University CS253 web page https://cs.colostate.edu/~cs253/Spring22/HW6 fetched by unknown <unknown> with Linux UID 65535 at 2024-06-26T09:55:01 from IP address 18.189.193.210. Registered CSU students are permitted to copy this web page for personal use, but it is forbidden to repost the information from this web page to the internet. Doing so is a violation of the rules in the CS253 syllabus, will be considered cheating, and will get you an F in CS253.

Sample Run                

Here is a sample run, where % is my shell prompt:                 

% cat CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(hw6)

# Are we in the wrong directory?
if (CMAKE_SOURCE_DIR MATCHES "[Hh][Ww]([0-9])$"
   AND NOT PROJECT_NAME MATCHES "${CMAKE_MATCH_1}$")
    message(FATAL_ERROR "Building ${PROJECT_NAME} in ${CMAKE_SOURCE_DIR}")
endif()

# Using -Wall is required:
add_compile_options(-Wall)

# These compile flags are highly recommended, but not required:
add_compile_options(-Wextra -Wpedantic)

# Optional super-strict mode:
add_compile_options(-fno-diagnostics-show-option
    -fstack-protector-all -g -O3 -std=c++17 -Walloc-zero -Walloca
    -Wctor-dtor-privacy -Wduplicated-cond
    -Wduplicated-branches -Werror -Wextra-semi -Wfatal-errors
    -Winit-self -Wlogical-op -Wold-style-cast -Wshadow
    -Wunused-const-variable=1 -Wzero-as-null-pointer-constant)

# add_compile_options must be BEFORE add_executable.

# Create the executable from the source file main.cc:
add_library(${PROJECT_NAME} Show.cc Schedule.cc)
add_executable(test test.cc)
target_link_libraries(test ${PROJECT_NAME})

# Create a tar file every time:
add_custom_target(${PROJECT_NAME}.tar ALL COMMAND
    tar -cf ${PROJECT_NAME}.tar *.cc *.h CMakeLists.txt)

% cmake . && make
… cmake output appears here …
… make output appears here …
% cat test.cc
#include "Schedule.h"
#include <cassert>      // assert
#include <string>       // string
#include <iostream>     // cout

using namespace std;

int main() {
    Schedule s;
    s += Show("Bull", "CBS", 21*4, 4, true);
    s += Show("Young Sheldon", "CBS", 19*4, 2);
    s += Show("How We Roll", "CBS", 20*4+2, 2);
    s += Show("Law & Order: Organized Crime", "NBC", 21*4, 4, true);
    s += Show("United States of Al", "CBS", 19*4+2, 2);
    s += Show("Law & Order", "NBC", 19*4, 4, true);
    s += Show("Ghosts", "CBS", 20*4, 2, false);
    s += Show("Law & Order: SVU", "NBC", 20*4, 4, true);

    cout << "Via <<:\n" << s;
    cout << "Via []:\n";
    for (size_t i=0; i<s.size(); i++)
        cout << "   " << s[i].name() << '\n';
    cout << "Via for-each:\n";
    for (const auto v : s)
        cout << "   " << v.name() << '\n';
    cout << "Via for-each for kids\n";
    s.grups(false);
    for (const auto &v : s)
        cout << "   " << v.name() << '\n';

    Schedule::iterator it = s.begin();
    assert((*it).name() == "Young Sheldon");
    assert((*it++).name() == "Young Sheldon");
    assert((*++it).name() == "Ghosts");
    assert(it == it);
    assert(it != s.begin());
    assert(s.end() != it);
    assert(not (it == s.end()));

    return 0;
}
% ./test
Via <<:
19:00-19:30 CBS Young Sheldon
19:00-20:00 NBC Law & Order*
19:30-20:00 CBS United States of Al
20:00-20:30 CBS Ghosts
20:00-21:00 NBC Law & Order: SVU*
20:30-21:00 CBS How We Roll
21:00-22:00 CBS Bull*
21:00-22:00 NBC Law & Order: Organized Crime*
Via []:
   Young Sheldon
   Law & Order
   United States of Al
   Ghosts
   Law & Order: SVU
   How We Roll
   Bull
   Law & Order: Organized Crime
Via for-each:
   Young Sheldon
   Law & Order
   United States of Al
   Ghosts
   Law & Order: SVU
   How We Roll
   Bull
   Law & Order: Organized Crime
Via for-each for kids
   Young Sheldon
   United States of Al
   Ghosts
   How We Roll

Hints                

Store your Show objects in a set, using a comparison functor to put them in the desired order.                 

Requirements                

The requirements from HW4 apply, plus:

Testing for undefined behavior                

Here’s how the TA will test for undefined behavior:

  • He will write test programs for each condition defined as undefined behavior, above.
  • He will compile & execute your code with each of those test programs.
  • He will then ignore the output of those test programs, including whether or not they compile, produce warnings, produce correct output, or segmentation faults, or if they even terminate at all, because any result at all is acceptable for undefined behavior.
  • Or, instead of doing all that, he may take a nap, which will have the same result.
  • There is no need in English for the sarcasm point

Testing                

You will have to write a main() function to test your code. Put it in a separate file. Particularly, do not put main() in Schedule.h. We will test your program by doing something like this:                 

    mkdir a-new-directory
    cd the-new-directory
    tar -x </some/where/else/hw6.tar
    cmake . && make
    cp /some/other/place/test-program.cc .
    g++ -Wall test-program.cc libhw6.a
    ./a.out

We will supply a main program to do the testing that we want. You should do something similar. It’s your choice whether to include your test program in your hw6.tar file. However, cmake . && make must work. If it fails because you didn’t package test.cc, but your CMakeLists.txt requires test.cc, then your build failed, and you get no points. Test your tar file, not just your code.                 

Tar file                

    cmake . && make

How to submit your work:                

In Canvas, check in the file hw6.tar to the assignment “HW6”. It’s due 11:59ᴘᴍ MT Saturday, with a five-day late period.                 

How to receive negative points:                

Turn in someone else’s work.