online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
// Main Program and Application for ALL five Exercises // =================================================== // What this program does is configured by enabling // one or more of the following #define-s // // Exercise 1: Manual Testing: no #define-s enabled // Unit-Testing: enable #define TEST1 // Exercise 2: Manual Testing: #define-s EXCEPTION // Unit-Testing: enable #define TEST2 // Exercise 3: Manual Testing: #define-s OBSERVER // Unit-Testing: enable #define TEST3 // Exercise 4: Manual Testing: #define-s CONTAINER // Unit-Testing: enable #define TEST4 // Exercise 5: Manual Testing: enable THREAD // Unit-Testing: (none provided) // NOTE: #define-s for manual testing accumulate, i.e. // they are meant to be enabled and stay enabled // as the exercise progresses. But if ANY of // TEST1, TEST2, TEST3, TEST4 is enabled ONLY // the respective unit-testing takes place. // enable manual test cases // --------------------------------------------- //#define EXCEPTION //#define OBSERVER //#define CONTAINER //#define THREAD // enable/disable unit tests // --------------------------------------------- //#define TEST1 #define TEST2 //#define TEST3 //#define TEST4 #include <cassert> #include <iostream> #include <sstream> #include "limit_counter.h" #include "overflow_counter.h" #include "clock.h" #if defined(TEST1) // ------ Unit-Testing for Exercise 1 int main() { Clock c{23, 59, 58}; std::ostringstream expect; // should only step up the seconds here c.Update(expect); assert(expect.str() == "Clock [hh:mm:ss] 23:59:59\n"); expect.str(""); // should step up the seconds which resets and in turn // steps up the minutes which resets and in turn steps // up the hours which resets. // MOTE: This test will FAIL if LimitCounter::Count is // not virtual and properly overwritten in // OverflowCounter::Count c.Update(expect); assert(expect.str() == "Clock [hh:mm:ss] 00:00:00\n"); expect.str(""); // should only step up the seconds here c.Update(expect); assert(expect.str() == "Clock [hh:mm:ss] 00:00:01\n"); expect.str(""); // should only step up the seconds here c.Update(expect); assert(expect.str() == "Clock [hh:mm:ss] 00:00:02\n"); expect.str(""); c.SetHours(3); c.SetMinutes(59); c.SetSeconds(59); // should reset seconds and minutes, stepping up hours // NOTE: This one will FAIL if LimitCounter::Count uses // plain Reset() to set value_ to zero. Correct // implementation must use LimitCounter::Reset() // to avoid the whole counter chain uop to hours // is reset to zero c.Update(expect); assert(expect.str() == "Clock [hh:mm:ss] 04:00:00\n"); expect.str(""); c.Reset(); c.Update(expect); // Note: // c.Update() FIRST increments the Clock and only then // shows "hh:mm:ss" so the expection is not "00:00:00" assert(expect.str() == "Clock [hh:mm:ss] 00:00:01\n"); expect.str(""); std::cout << "passed all tests of clock functionality\n"; } #elif defined(TEST2) // ---- Unit-Testing for Exercise 2 int main() { try { LimitCounter lc{0, 10}; lc.SetValue(11); assert(!"LimitCounter exeception expected"); } catch (const char *) {} catch (...) { assert(!"not the expected exception"); } } #elif defined(TEST3) // ---- Unit-Testing for Exercise 3 // ... TBD #elif defined(TEST4) // ---- Unit-Testing for Exercise 4 // ... TBD #else // ----------------------- Manual Testing selected #include <cctype> #include <iostream> void ShowValue() { std::cout << std::endl; } template <typename T> void ShowValue(T text) { std::cout << text << std::endl; } template <typename T, typename... Other> void ShowValue(T text, Other... other) { std::cout << text << " "; ShowValue(other...); } char GetCommand() { std::cout << "::> " << std::flush; char cmd; while (std::cin.get(cmd)) { if (cmd == '\n') continue; std::cin.ignore(99999, '\n'); if (std::isupper(cmd = std::toupper(cmd))) { return cmd; } } return 'Q'; } // ===================================================== // DEFINITION of Actual Application (will usually have // its own application.h file but is included directly // for convenient use in onlineGDB) #include <memory> #include <string> #include "clock.h" #include "iclock_factory.h" class Application { private: IClockFactory& clock_factory_; std::shared_ptr<Clock> clock_; public: explicit Application(IClockFactory& clock_factory) : clock_factory_{clock_factory} { } void SetClock(const std::shared_ptr<Clock>& clock) { // if clock == nullptr) throw "error"; // if (clock == nullptr) throw std::string("no clock service available"); using namespace std::string_literals; if (clock == nullptr) throw "no clock service available"s; clock_ = clock; } void Run(); }; // ===================================================== // System Manager Services (will usually have its own // header and implementation file but included directly // for convenient use in onlineGDB). #include "iclock_factory.h" #ifdef THREAD #include "timer.h" #endif constexpr unsigned kStartHours = 23; constexpr unsigned kStartMinutes = 59; constexpr unsigned kStartSeconds = 55; class SystemManager : public IClockFactory { private: std::shared_ptr<Clock> clock_; #ifdef THREAD std::shared_ptr<Timer> timer_; #endif std::shared_ptr<Application> application_; public: SystemManager() { Create(); BuildRelations(); } void Execute() const { ShowValue("Clock Observer ..."); application_->Run(); } #ifdef THREAD timer_->Wait(); #endif std::shared_ptr<Clock> GetNewClock(unsigned hours, unsigned minutes, unsigned seconds) override { return std::make_shared<Clock>(hours, minutes, seconds); } private: void Create() { clock_.reset(new Clock{kStartHours, kStartMinutes, kStartSeconds}); application_.reset(new Application{*this}); } void BuildRelations() const { application_->SetClock(clock_); } }; // ===================================================== // IMPLEMENTATION of Actual Application (will usually // application.cpp file but included directly for // convenient use in onlineGDB) void Application::Run() { while (true) { ShowValue("\n"); #ifndef OBSERVER #ifndef CONTAINER ShowValue("'A': Tick clock"); ShowValue("'B': Reset clock"); #ifdef EXCEPTION ShowValue("'C': Set IClock-Pointer to nullptr"); #endif #endif #endif #if defined(OBSERVER) || defined(CONTAINER) ShowValue("'A': Tick all clocks"); ShowValue("'B': Attach a clock"); ShowValue("'C': Detach a clock"); ShowValue("'D': Reset clock"); ShowValue("'E': Attach five different initialized clocks"); #endif #ifdef THREAD ShowValue("'F': Start the timer thread"); #endif ShowValue("'Q': Quit this program"); ShowValue(); switch (GetCommand()) { #ifndef OBSERVER #ifndef CONTAINER case 'A': clock_->Update(std::cout); break; case 'B': clock_->Reset(); break; #ifdef EXCEPTION case 'C': SetClock(nullptr); break; #endif #endif #endif #if defined(OBSERVER) || defined(CONTAINER) case 'A': timer_->Tick(); break; case 'B': timer_->Attach(clock_); break; case 'C': timer_->Detach(clock_); break; case 'D': clock_->Reset(); break; case 'E': timer_->Attach(clock_factory_.GetNewClock(1, 0, 0)); timer_->Attach(clock_factory_.GetNewClock(2, 0, 0)); timer_->Attach(clock_factory_.GetNewClock(3, 0, 0)); timer_->Attach(clock_factory_.GetNewClock(4, 50, 40)); timer_->Attach(clock_factory_.GetNewClock(5, 59, 50)); break; #endif #ifdef THREAD case 'F': timer_->Start(); break; #endif case 'Q': #ifdef THREAD timer_->Stop(); #endif return; default: break; } } } #include <string> int main() { const std::unique_ptr<SystemManager> system_manager{new SystemManager}; try { system_manager->Execute(); } catch (const std::string &ex) { std::clog << "Execution Terminated (details: " << ex << ")\n"; } catch (const char *ex) { std::clog << "Execution Terminated: " << ex << ".\n"; } catch (const std::exception &ex) { std::clog << "Execution Terminated by '" << ex.what() << "' exception\n"; } catch (...) { std::clog << "Execution Terminated by unknkwon exception\n"; } } #endif
#include "limit_counter.h" #include <string> #include <stdexcept> LimitCounter::LimitCounter (const unsigned value, const unsigned limit) : value_{value}, limit_{limit} { } void LimitCounter::SetValue (const unsigned value) { if (value >= limit_) { // throw 7; //"error"; } value_ = value; } unsigned LimitCounter::GetValue () const { return value_; } bool LimitCounter::Count () { const auto temp_value = GetValue () + 1; if (temp_value >= limit_) { LimitCounter::Reset (); return true; } SetValue(temp_value); return false; } void LimitCounter::Reset () { value_ = 0; }
#ifndef LIMIT_COUNTER_H #define LIMIT_COUNTER_H #include <stdexcept> class LimitCounter { private: unsigned value_; const unsigned limit_; public: class ValueOutOfRange; LimitCounter(unsigned value, unsigned limit); virtual ~LimitCounter() = default; void SetValue(unsigned value); unsigned GetValue() const; virtual bool Count(); virtual void Reset(); }; class LimitCounter::ValueOutOfRange : public std::out_of_range { public: ValueOutOfRange(unsigned val, unsigned lim) : std::out_of_range{"LimitCounter::ValueOutOfRange"} {} }; #endif // include guard
#include "overflow_counter.h" OverflowCounter::OverflowCounter(const unsigned value, const unsigned limit, LimitCounter& next_counter) : LimitCounter{value, limit}, next_counter_{next_counter} { } void OverflowCounter::Reset() { LimitCounter::Reset(); next_counter_.Reset(); } bool OverflowCounter::Count() { const auto is_overflow = LimitCounter::Count(); if (is_overflow) { next_counter_.Count(); } return is_overflow; }
#ifndef OVERFLOW_COUNTER_H #define OVERFLOW_COUNTER_H #include "limit_counter.h" class OverflowCounter : public LimitCounter { private: LimitCounter& next_counter_; public: OverflowCounter(unsigned value, unsigned limit, LimitCounter& next_counter); void Reset() override; bool Count() override; }; #endif // include guard
#ifndef CLOCK_H #define CLOCK_H #include <iosfwd> #include "limit_counter.h" #include "overflow_counter.h" class Clock { private: LimitCounter hours_; OverflowCounter minutes_; OverflowCounter seconds_; public: Clock(unsigned hours, unsigned minutes, unsigned seconds); void SetHours(unsigned hours); void SetMinutes(unsigned minutes); void SetSeconds(unsigned seconds); unsigned GetHours() const; unsigned GetMinutes() const; unsigned GetSeconds() const; void Reset(); void Update(std::ostream &os); void Show(std::ostream&) const; }; #endif // include guard
#include "clock.h" #include <iomanip> #include <iostream> Clock::Clock(const unsigned hours, const unsigned minutes, const unsigned seconds) : hours_{hours, 24}, minutes_{minutes, 60, hours_}, seconds_{seconds, 60, minutes_} { } void Clock::SetHours(const unsigned hours) { hours_.SetValue(hours); } void Clock::SetMinutes(const unsigned minutes) { minutes_.SetValue(minutes); } void Clock::SetSeconds(const unsigned seconds) { seconds_.SetValue(seconds); } unsigned Clock::GetHours() const { return hours_.GetValue(); } unsigned Clock::GetMinutes() const { return minutes_.GetValue(); } unsigned Clock::GetSeconds() const { return seconds_.GetValue(); } void Clock::Reset() { seconds_.Reset(); } void Clock::Update(std::ostream& os) { seconds_.Count(); Show(os); } void Clock::Show(std::ostream& os) const { os << "Clock [hh:mm:ss] " << std::setfill('0') << std::setw(2) << GetHours() << ":" << std::setfill('0') << std::setw(2) << GetMinutes() << ":" << std::setfill('0') << std::setw(2) << GetSeconds() << "\n"; }
#ifndef ICLOCK_FACTORY_H #define ICLOCK_FACTORY_H #include <memory> #include "clock.h" class IClockFactory { public: virtual ~IClockFactory() = default; virtual std::shared_ptr<Clock> GetNewClock(unsigned hours, unsigned minutes, unsigned seconds) = 0; }; #endif // include guard

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue