/*
* ===========================================================================
* Clock Application (and tests)
* ===========================================================================
*/
#include <iostream>
#include <iomanip>
#include "clock.h"
#include "counter.h"
#ifdef TDD
void basic_counter_test() {
my::BaseCounter hh{24};
my::ChainCounter mm{60, hh};
my::ChainCounter ss{60, mm};
hh.set_value(6);
mm.set_value(59);
ss.set_value(57);
for (int i = 0; i < 5; ++ i) {
std::cout << hh << " | " << mm << " | " << ss << std::endl;
ss.incr();
}
}
int main() {
basic_counter_test();
}
#else
int main() {
std::cout << "??? clock application ???" << std::endl;
}
#endif
# 2_Clock Step 24 (action items)
## Clock class
Add the missing parts to the class Clock that is already
prepared in `clock.h` and `clock.c`
Rewrite the test code in `main.cpp` so that it tests the
whole clock, not separate counters
Output a `Clock clk` with
`std::cout << clk.to_string() << std::endl;`
# 2_Clock Step 0 (read first)
File | Syntax | Content
------------|--------|---------------------------------
main.cpp | C++14 | some source code
counter.h | C++14 | `counter` module header file
counter.cpp | C++14 | `counter` module implementation
clock.h | C++14 | `clock` module header file
clock.cpp | C++14 | `clock` module implementation
Makefile | make | build instructions
/* Module Header
* ============================================================================
* Chainable Counter Class
* ============================================================================
*/
#ifndef COUNTER_H_
#define COUNTER_H_
#include <iosfwd> // suffices as only references to iostreams are used
#include <limits> // this is NOT `<climits>` (neither `<limits.h>`)
namespace my {
class BaseCounter {
virtual void will_overflow() {};
virtual void has_overflown() {};
public:
using value_type = int;
BaseCounter(value_type limit)
: limit_{limit}
, value_{}
{ /*empty*/ }
auto set_value(value_type const value) {
value_ = value;
}
auto get_value() const {
return value_;
}
auto get_limit() const {
return limit_;
}
void incr() {
if (++value_ >= limit_) {
will_overflow();
value_ = value_type{};
has_overflown();
}
}
private:
value_type limit_{std::numeric_limits<value_type>::max()};
value_type value_{};
};
class ChainCounter : public BaseCounter {
public:
ChainCounter(value_type limit, BaseCounter& next)
: BaseCounter(limit)
, next_{next}
{ /*empty*/ }
virtual void will_overflow() override {
next_.incr();
}
private:
BaseCounter& next_;
}; // class
} // namespace
std::ostream& operator<<(std::ostream&, my::BaseCounter const&);
#endif // guard
/* Module Implementation
* ============================================================================
* Chainable Counter Class
* ============================================================================
*/
#include "counter.h" // own header file ALWAYS FIRST
#include <iostream> // `<ios_fwd>` not any longer suffices
#include <iomanip> // for `std::setw`
namespace my {
} // namespace
std::ostream& operator<<(std::ostream& lhs,
my::BaseCounter const& rhs) {
std::ostream s{std::cout.rdbuf()};
s.fill('0');
s << "value=" << std::setw(2) << rhs.get_value() << ", "
"limit=" << std::setw(2) << rhs.get_limit();
return lhs;
// return lhs << "value=" << rhs.get_value() << ", "
// "limit=" << rhs.get_limit();
}
/* Module Header
* ============================================================================
* HH:MM:SS Clock built from a `BaseCounter` and two `ChainCounter`-s
* ============================================================================
*/
#ifndef CLOCK_H_
#define CLOCK_H_
#include <string>
#include "counter.h"
namespace my {
class Clock {
public:
//
// TBD c'tor (no arguments)
//
void reset(int hh = 0, int mm = 0, int ss = 0);
void tick(int steps = 1);
std::string to_string() const;
private:
BaseCounter hh_;
ChainCounter mm_;
ChainCounter ss_;
};
} // namespace
#endif // guard
/* Module Implementation
* ============================================================================
* Chainable Counter Class
* ============================================================================
*/
#include "clock.h" // own header file ALWAYS FIRST
/* Module Implementation
* ============================================================================
* HH:MM:SS Clock built from a `BaseCounter` and two `ChainCounter`-s
* ============================================================================
*/
#include "clock.h" // own header file ALWAYS FIRST
#include <iomanip> // for `std::setw`
#include <sstream> // for `std::ostringstream`
namespace my {
void Clock::tick(int steps) {
// TBD
}
void Clock::reset(int hh, int mm, int ss) {
// TBD
}
std::string Clock::to_string() const {
std::ostringstream s;
s.fill('0');
// TBD: write counter values into stream
// with two digits each
s << std::setw(2) .....
return s.str();
}
} // namespace