#include "Time_s.hpp" #include #include ////////////////// // Constructors // ////////////////// // Construct a non-negative time. Time_s::Time_s( std::uint32_t const hours, unsigned int const minutes, unsigned int const seconds ): seconds_{ 0 } { if ( minutes >= 60 ) { throw std::invalid_argument{ "minutes must be between 0 and 59" }; } if ( seconds >= 60 ) { throw std::invalid_argument{ "seconds must be between 0 and 59" }; } seconds_ = 3600LL*static_cast( hours ) + static_cast( 60*minutes ) + static_cast( seconds ); } // Construct a time directly from a signed number of seconds. Time_s::Time_s( std::int64_t const seconds ): seconds_{ seconds } { // Everything is in the initialization } /////////////////////////////////////////////// // The hours, minutes, and seconds of a time // /////////////////////////////////////////////// // Return whether this time is negative. bool Time_s::negative() const { return seconds_ < 0; } // Return the hour component of the magnitude. std::uint32_t Time_s::hours() const { std::uint64_t const magnitude{ seconds_ < 0 ? static_cast( -(seconds_ + 1) ) + 1 : static_cast( seconds_ ) }; std::uint64_t const hours{ magnitude/3600 }; // If durations of 2^32 hours or more were permitted, // we would need to check that hours fits in 32 bits. return static_cast( hours ); } // Return the minute component of the magnitude. std::uint8_t Time_s::minutes() const { std::uint64_t const magnitude{ seconds_ < 0 ? static_cast( -(seconds_ + 1) ) + 1 : static_cast( seconds_ ) }; return static_cast( (magnitude/60)%60 ); } // Return the second component of the magnitude. std::uint8_t Time_s::seconds() const { std::uint64_t const magnitude{ seconds_ < 0 ? static_cast( -(seconds_ + 1) ) + 1 : static_cast( seconds_ ) }; return static_cast( magnitude%60 ); } //////////////////////////////////////////// // Boolean-valued functions and operators // // - Comparison operators // //////////////////////////////////////////// // Test if two times are equal. bool Time_s::operator==( Time_s const &other ) const { return seconds_ == other.seconds_; } // Test if two times are different. bool Time_s::operator!=( Time_s const &other ) const { return seconds_ != other.seconds_; } // Test if the left-hand time is less than the right-hand time. bool Time_s::operator<( Time_s const &other ) const { return seconds_ < other.seconds_; } // Test if the left-hand time is less than or equal to the right-hand time. bool Time_s::operator<=( Time_s const &other ) const { return seconds_ <= other.seconds_; } // Test if the left-hand time is greater than or equal to the right-hand time. bool Time_s::operator>=( Time_s const &other ) const { return seconds_ >= other.seconds_; } // Test if the left-hand time is greater than the right-hand time. bool Time_s::operator>( Time_s const &other ) const { return seconds_ > other.seconds_; } ///////////////////////// // The unary operators // // +Time{...} // // -Time{...} // ///////////////////////// // Return this time. Time_s Time_s::operator+() const { return *this; } // Return the additive inverse of this time. Time_s Time_s::operator-() const { return Time_s{ -seconds_ }; } ////////////////////////////// // The binary operators // // Time{...} + Time{...} // // Time{...} - Time{...} // ////////////////////////////// // Add another time. Time_s Time_s::operator+( Time_s const &other ) const { Time_s result{ *this }; return result += other; } // Subtract another time. Time_s Time_s::operator-( Time_s const &other ) const { Time_s result{ *this }; return result -= other; } /////////////////////////////////////// // The compound assignment operators // // Time{...} += Time{...} // // Time{...} -= Time{...} // /////////////////////////////////////// // Add another time to this time. Time_s &Time_s::operator+=( Time_s const &other ) { seconds_ += other.seconds_; return *this; } // Subtract another time from this time. Time_s &Time_s::operator-=( Time_s const &other ) { seconds_ -= other.seconds_; return *this; } /////////////////////////////////////////// // The increment and decrement operators // // ++time time++ // // --time time-- // /////////////////////////////////////////// // Increment this time by one second. Time_s &Time_s::operator++() { ++seconds_; return *this; } // Increment this time by one second, returning the original time. Time_s Time_s::operator++( int ) { Time_s original{ *this }; ++(*this); return original; } // Decrement this time by one second. Time_s &Time_s::operator--() { --seconds_; return *this; } // Decrement this time by one second, returning the original time. Time_s Time_s::operator--( int ) { Time_s original{ *this }; --(*this); return original; } /////////////////////////////// // std::string and std::cout // /////////////////////////////// // Return a string representation of this time. std::string Time_s::to_string() const { std::string result{}; if ( negative() ) { result += "-"; } result += std::to_string( hours() ); result += ":"; if ( minutes() < 10 ) { result += "0"; } result += std::to_string( minutes() ); result += ":"; if ( seconds() < 10 ) { result += "0"; } result += std::to_string( seconds() ); return result; } // Insert a time into an output stream. std::ostream &operator<<( std::ostream &out, Time_s const &time ) { return out << time.to_string(); }