One of the finest universities north of Prospect in Fort Collins

Jack Applin



For this assignment, you will write two classes: Event and Schedule. Event represents a single date, per HW3?, and Schedule is a collection of Event objects.

For this assignment, you you will provide:

  • Event.h, which will contain the interface for class Event
  • Schedule.h, which will contain the interface for class Schedule
  • the library libwikisandbox.a, which will contain the implementation of those classes.

To use class Event, the user must #include "Event.h". To use class Schedule, the user must #include "Schedule.h".


One method is forbidden:

no default ctor
The default (no-argument) ctor for Event must fail to compile. This is not a run-time error; it’s a compile-time error.

Event must have the following methods:

Event(C string)
Event(C++ string)
The string must contain an event, in one of the five HW3? formats, with optional leading whitespace. Initialize the Event to that date. Throw a runtime_error with an appropriate string, if the date is bad in any way, syntactically or semantically.
Copy ctor
Assignment operator
Copy the information from the other Event.
.set(year, month, day)
Set the date for this event. to that date. Throw a runtime_error, containing the bad datum, if the date is bad in any way. .set(2020,4,3) would set the date to today.
Return the int year, month, or day associated with this Event. They have the same values that would be passed to .set().

Schedule must have the following public methods:

Create a Schedule containing no Events.
Read Events from the istream, separated by whitespace, into the Schedule. Throw a runtime_error upon syntactic or semantic error.
Schedule(C string filename)
Schedule(C++ string filename)
Read Events from the or file, separated by whitespace, into the Schedule. Throw a runtime_error, including the filename, upon syntactic or semantic error.
Copy constructor
Takes another object of the same class, and deep-copies the information, replacing any previous information.
Assignment operator
Takes another object of the same class, and deep-copies the information, replacing any previous information.
Destroys this object, including all the Events associated with it.
Read all Events from the istream, separated by whitespace, into the Schedule. This method does not replace previous contents—it adds to them.
Upon syntactic or semantic error:
  • set the istream to a failed state
  • the Schedule must contain all the previously-encountered Events in the istream up to the point
  • It is not acceptable to leave a half-baked Event in the Schedule.
Make this Schedule empty. If it’s already empty, then make it like, totally empty.
Return the number of Events in this object, as a size_t.
Return true iff this object has no entries.
Given a zero-based index, return the corresponding Event by reference. If the index is out of range, throw a range_error, (not a runtime_error) including the erroneous index and the number of Events in this Schedule.
Provide two versions of this method: a const one that returns const Event &, and a non-const one that returns an Event &.
For a Schedule s, s[0] must return the Event with the earliest date, s[s.size()-1] must return the Event with the last date, and the Events in between must be in nondescending order. It is not guaranteed that the subscript operator will be called in any particular order.


ostream << Event
Write this Event to the stream in YYYY-MM-DD format. Write exactly ten characters–nothing else.
ostream << Schedule
Write all the Events in this Schedule to the stream in YYYY-MM-DD format, each followed by a newline. Write exactly eleven characters per Event–nothing else. They must be written in chronological order, oldest events first, as described in the [] operator.

For both of the output operators above, I/O manipulators such as setw or showpos may add extra characters. That’s ok.

Const-correctness, both arguments & methods, is your job. For example, it must be possible to call .size() on a const Schedule, or to pass a const string to Schedule::read().

You may define other methods, data, or classes, public or private, as you see fit. You may create other source & header files, but we will only #include "Schedule.h" to use a class Schedule, and #include "Event.h" to use a class Event. Note that it is possible to manipulate an Event without a Schedule, and it’s also possible to manipulate a Schedule without dealing with Events.

Sample Run

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


  • When a Event is read in HW3? format, whether from a file, stream, or string, it must follow the validity rules from HW3?. For example, 23.55 is ok, 23.400 is bad, 0000-01-01 is bad, TOMorrOw is ok, etc. 2020-01-32 is bad—it won’t get normalized to February 1.
  • No method may call exit() or produce any output.
  • It’s ok for a Schedule to contain two Events with the same date.
    • If your next thought is “Which one comes first?”, well, that’s a good thought—keep thinking about the subject.
  • You have permission to copy GCD (Greatest Common Divisor) or LCM (Least Common Multiple) code from a book or the internet. However, you must have a comment before the copied code citing the book (Author, title, page) or URL where you found the code.
  • In case of a failed .read(), the position of the input stream is unspecified.
  • You may use the CMakeLists.txt shown, or create your own.
  • Do not put using namespace std; in any header (*.h) file. It’s fine in an implementation (*.cc) file.
  • All copies (copy ctor, assignment operator) are “deep”. Do not share data between copies—that’s not making a copy.
  • You may not use any external programs via system(), fork(), popen(), exec*(), etc.
  • You may not use C-style <stdio.h> or <cstdio> facilities, such as printf(), scanf(), fopen(), and getchar().
  • You may not use dynamic memory via new, delete, malloc(), calloc(), realloc(), free(), strdup(), etc.
    • It’s ok to implicitly use dynamic memory via containers such as string or vector.
  • No global variables.
  • For readability, don’t use ASCII int constants (65) instead of char constants ('A') for printable characters.
  • We will compile your program like this: cmake . && make
    • If that generates warnings, you will lose a point.
      • If you still don’t have a project directive in CMakeLists.txt, then you’re not paying attention at all, so you’re not reading this.
    • If that generates errors, you will lose all points.
  • There is no automated testing/pre-grading/re-grading.
    • Test your code yourself. It’s your job.
    • Even if you only change it a little bit.
    • Even if all you do is add a comment.

If you have any questions about the requirements, ask. In the real world, your programming tasks will almost always be vague and incompletely specified. Same here.

Tar file

  • The tar file for this assignment must be called: wikisandbox.tar
  • It must contain:
    • source files (*.cc), including and
    • header files (*.h), including Event.h and Schedule.h
    • CMakeLists.txt, which will create the library file libwikisandbox.a.
  • These commands must produce the library libwikisandbox.a:
    cmake . && make
  • Your CMakeLists.txt must use at least -Wall when compiling.

How to submit your homework:

    ~applin/bin/checkin WikiSandbox wikisandbox.tar

How to receive negative points:

Turn in someone else’s work.