This commit is contained in:
2019-02-27 18:09:30 -05:00
4 changed files with 149 additions and 16 deletions

View File

@@ -29,7 +29,7 @@
#include <cinttypes> #include <cinttypes>
//Use this for anything besides Linux. It replaces random_device //Use this for anything besides Linux. It replaces random_device
//I know this doesn't work correctly with mingw on Windows, not sure about msbuild or mac so I don't take the chance //I know this doesn't work correctly with mingw on Windows, not sure about msbuild or mac so I don't take the chance
#ifndef linux #ifndef __linux
#include <ctime> #include <ctime>
#endif //ifndef linux #endif //ifndef linux
@@ -37,23 +37,24 @@
namespace mee{ namespace mee{
template<class T>
class Dice{ class Dice{
private: private:
uint64_t face; //Holds the currently rolled number T face; //Holds the currently rolled number
uint64_t sides; //Holds the number of sides the dice has T sides; //Holds the number of sides the dice has
std::default_random_engine generator; //The number generator that all the numbers come from std::default_random_engine generator; //The number generator that all the numbers come from
std::uniform_int_distribution<uint64_t> dist; //A distribution to make sure the numbers come out relatively evenly std::uniform_int_distribution<T> dist; //A distribution to make sure the numbers come out relatively evenly
public: public:
#ifdef linux #ifdef __linux
Dice(uint64_t sides = 6) : face(1), sides(sides), generator(std::random_device{}()), dist(1, sides) { } Dice(T sides = 6) : face(1), sides(sides), generator(std::random_device{}()), dist(1, sides) { }
#else #else
Dice(uint64_t sides = 6) : face(1), sides(sides), generator(time(0)), dist(1, sides) { } Dice(T sides = 6) : face(1), sides(sides), generator(time(0)), dist(1, sides) { }
#endif //ifdef linux #endif //ifdef linux
//Setup ways to get information from the class //Setup ways to get information from the class
uint64_t getFace() const { return face; } T getFace() const { return face; }
uint64_t getSides() const { return sides; } T getSides() const { return sides; }
//Used to simulate rolling the dice. Returns the new number //Used to simulate rolling the dice. Returns the new number
uint64_t roll() { T roll() {
face = dist(generator); face = dist(generator);
return face; return face;
} }

View File

@@ -26,15 +26,22 @@
#include <chrono> #include <chrono>
#include <sstream>
#include <iomanip>
namespace mee{ namespace mee{
class Stopwatch{ class Stopwatch{
public:
//Create an error class
class stopBeforeStart{}; //Used in stop() to check if you are trying to stop the stopwatch before starting it
class timeBeforeStart{}; //Used in getTime() to check if you are trying to get a time before you start it
class invalidTimeResolution{}; //Used to detect invalid time resolution in the getStr function
private: private:
std::chrono::high_resolution_clock::time_point startTime; //The time the start function was called std::chrono::high_resolution_clock::time_point startTime; //The time the start function was called
std::chrono::high_resolution_clock::time_point endTime; //The time the stop function was called std::chrono::high_resolution_clock::time_point endTime; //The time the stop function was called
bool hasStarted; //A flag to show that start() has been called bool hasStarted; //A flag to show that start() has been called
bool hasStopped; //A flag to show that stop() has been called bool hasStopped; //A flag to show that stop() has been called
enum TIME_RESOLUTION {HOUR, MINUTE, SECOND, MILLISECOND, MICROSECOND, NANOSECOND, DEFAULT}; enum TIME_RESOLUTION {NANOSECOND, MICROSECOND, MILLISECOND, SECOND, MINUTE, HOUR, DEFAULT};
//Return the duration in the default time period for the high_resolution_clock //Return the duration in the default time period for the high_resolution_clock
double getTime(TIME_RESOLUTION timeResolution){ double getTime(TIME_RESOLUTION timeResolution){
double timePassed = 0; //Holds the amount of time that has passed double timePassed = 0; //Holds the amount of time that has passed
@@ -43,9 +50,9 @@ private:
if(!hasStopped){ if(!hasStopped){
endTime = std::chrono::high_resolution_clock::now(); endTime = std::chrono::high_resolution_clock::now();
} }
//If the timer hasn't been started return a -1 as an error //If the timer hasn't been started throw an exception
if(!hasStarted){ if(!hasStarted){
return -1; throw timeBeforeStart();
} }
//Decide what resolution to make the duration //Decide what resolution to make the duration
if(timeResolution == HOUR){ if(timeResolution == HOUR){
@@ -98,11 +105,16 @@ public:
//Set the stop time and flag //Set the stop time and flag
void stop(){ void stop(){
//Put this first to ensure the time recorded is as close to the call time as possible //Put this first to ensure the time recorded is as close to the call time as possible
endTime = std::chrono::high_resolution_clock::now(); std::chrono::high_resolution_clock::time_point tempTime = std::chrono::high_resolution_clock::now();
//Make sure the stopwatch has started before you say it has stopped //Make sure the stopwatch has started before you say it has stopped
if(hasStarted){ if(hasStarted){
endTime = tempTime; //Set the end time appropriately
hasStopped = true; //Show that the stop function has been called hasStopped = true; //Show that the stop function has been called
} }
//If the stopwatch hadn't been started throw an exception
else{
throw stopBeforeStart();
}
} }
//Return the duration in nanoseconds //Return the duration in nanoseconds
double getNano(){ double getNano(){
@@ -132,6 +144,37 @@ public:
double getTime(){ double getTime(){
return getTime(DEFAULT); return getTime(DEFAULT);
} }
//Returns a string with the time at best resolution
std::string getStr(){
//Setup the variables
double tempTime = getTime(NANOSECOND); //Holds the
std::stringstream timeStr;
//Decide what time resolution would be best. Looking for the format of XXX.XXX
int timeRes = NANOSECOND;
for(timeRes = MICROSECOND;(timeRes < DEFAULT) && (tempTime >= 1000);++timeRes){
tempTime = getTime(static_cast<TIME_RESOLUTION>(timeRes));
}
--timeRes; //Take this variable back down to the right place. It has to go one too far to trigger the loop stop
//Put the number in the string
timeStr << std::fixed << std::setprecision(3) << tempTime << ' ';
//From the timeRes variable decide what word should go on the end of the string
switch(timeRes){
case HOUR: timeStr << "hours"; break;
case MINUTE: timeStr << "minutes"; break;
case SECOND: timeStr << "seconds"; break;
case MILLISECOND: timeStr << "milliseconds"; break;
case MICROSECOND: timeStr << "microseconds"; break;
case NANOSECOND: timeStr << "nanoseconds"; break;
case DEFAULT: timeStr << "time"; break;
default: throw invalidTimeResolution(); //This should never be hit with this code, but it's good to have all the bases covered
}
//Return the string
return timeStr.str();
}
//This function resets all the variables so that it can be run again //This function resets all the variables so that it can be run again
void reset(){ void reset(){
hasStarted = hasStopped = false; //Set the flags as though nothing has happened hasStarted = hasStopped = false; //Set the flags as though nothing has happened

View File

@@ -22,6 +22,7 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <cinttypes>
#include "Dice.hpp" #include "Dice.hpp"
const int LENGTH_OF_TEST = 100; //How many times the dice will get rolled * the number of sides const int LENGTH_OF_TEST = 100; //How many times the dice will get rolled * the number of sides
@@ -30,7 +31,7 @@ const int LENGTH_OF_TEST = 100; //How many times the dice will get rolled * the
int main(){ int main(){
//Check the default constructor //Check the default constructor
std::cout << "Checking the default constructor of the Dice class:\n"; std::cout << "Checking the default constructor of the Dice class:\n";
mee::Dice die1; mee::Dice<int> die1;
if(die1.getSides() == 6){ if(die1.getSides() == 6){
std::cout << "Default constructor passes the test\n"; std::cout << "Default constructor passes the test\n";
} }
@@ -40,7 +41,7 @@ int main(){
//Check the constructor with a high side number //Check the constructor with a high side number
std::cout << "\nChecking a constructor with a high number of sides\n"; std::cout << "\nChecking a constructor with a high number of sides\n";
mee::Dice die2(50); mee::Dice<uint64_t> die2(50);
if(die2.getSides() == 50){ if(die2.getSides() == 50){
std::cout << "Parameterized constructor passed the test\n"; std::cout << "Parameterized constructor passed the test\n";
} }

88
testStopwatch.cpp Normal file
View File

@@ -0,0 +1,88 @@
//myClasses/testStopwatch.cpp
//Matthew Ellison
// Created: 02-12-19
//Modified: 02-12-19
//This file is a simple test for the Stopwatch class
#include <iostream>
#include "Stopwatch.hpp"
int main(){
mee::Stopwatch timer;
//Try to stop the timer without starting it
std::cout << "Testing the stopBeforeStart error" << std::endl;
try{
timer.stop();
std::cout << "Test failed" << std::endl;
}
catch(mee::Stopwatch::invalidTimeResolution){
std::cout << "There was an invalid time resolution" << std::endl;
std::cout << "Test failed" << std::endl;
}
catch(mee::Stopwatch::timeBeforeStart){
std::cout << "Tried to get time before the stopwatch was started" << std::endl;
std::cout << "Test failed" << std::endl;
}
catch(mee::Stopwatch::stopBeforeStart){
std::cout << "Tried to stop the stopwatch before it was started" << std::endl;
std::cout << "Test successful" << std::endl;
}
//Try to get the time on it without starting it
std::cout << "Testing the timeBeforeStart error" << std::endl;
try{
std::cout << timer.getStr() << std::endl;
std::cout << "Test failed" << std::endl;
}
catch(mee::Stopwatch::invalidTimeResolution){
std::cout << "There was an invalid time resolution" << std::endl;
std::cout << "Test failed" << std::endl;
}
catch(mee::Stopwatch::timeBeforeStart){
std::cout << "Tried to get time before the stopwatch was started" << std::endl;
std::cout << "Test successful" << std::endl;
}
catch(mee::Stopwatch::stopBeforeStart){
std::cout << "Tried to stop the stopwatch before it was started" << std::endl;
std::cout << "Test failed" << std::endl;
}
//Use it correctly
std::cout << "Using the class correctly" << std::endl;
try{
timer.start();
for(int cnt = 0;cnt < 1000000;++cnt){
int num = cnt;
}
timer.stop();
std::cout << "It took " << timer.getStr() << " to complete this loop" << std::endl;
std::cout << "Test successful" << std::endl;
}
catch(mee::Stopwatch::invalidTimeResolution){
std::cout << "There was an invalid time resolution" << std::endl;
std::cout << "Test failed" << std::endl;
}
catch(mee::Stopwatch::timeBeforeStart){
std::cout << "Tried to get time before the stopwatch was started" << std::endl;
std::cout << "Test failed" << std::endl;
}
catch(mee::Stopwatch::stopBeforeStart){
std::cout << "Tried to stop the stopwatch before it was started" << std::endl;
std::cout << "Test failed" << std::endl;
}
return 0;
}
/* Results:
Testing the stopBeforeStart error
Tried to stop the stopwatch before it was started
Test successful
Testing the timeBeforeStart error
Tried to get time before the stopwatch was started
Test successful
Using the class correctly
It took 1.855 milliseconds to complete this loop
Test successful
*/