エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

定期的に書きたくなる演算子のはなし

時間をおいて、ときどき書きたくなる。

もう一段階うえにいけそうでいけずにマンネリ化しつつあるところ。

C++11だともっといい手があるのかな。勉強せんと…。

#include <iostream>
#include <iomanip>

class Time
{
public:
    static const int SEC_PER_MIN  = 60;
    static const int MIN_PER_HOUR = 60;
    static const int SEC_PER_HOUR = SEC_PER_MIN * MIN_PER_HOUR;

    Time() : _sec(0) {}
    Time(int sec) : _sec(sec) {}
    Time(int h, int m, int s) : _sec(h * SEC_PER_HOUR + m * SEC_PER_MIN + s) {}

    int hour() const { return _sec / SEC_PER_HOUR;                 }
    int min() const  { return (_sec % SEC_PER_HOUR) / SEC_PER_MIN; }
    int sec() const  { return _sec % SEC_PER_MIN;                  }

    friend bool operator == (const Time& lhs, const Time& rhs) { return lhs._sec == rhs._sec;        }
    friend bool operator <  (const Time& lhs, const Time& rhs) { return lhs._sec <  rhs._sec;        }
    friend bool operator != (const Time& lhs, const Time& rhs) { return ! (lhs == rhs);              }
    friend bool operator <= (const Time& lhs, const Time& rhs) { return (lhs < rhs) || (lhs == rhs); }
    friend bool operator >  (const Time& lhs, const Time& rhs) { return rhs < lhs;                   }
    friend bool operator >= (const Time& lhs, const Time& rhs) { return rhs <= lhs;                  }

    friend Time operator + (const Time& lhs, const Time& rhs) { return Time(lhs._sec + rhs._sec); }
    friend Time operator - (const Time& lhs, const Time& rhs) { return Time(lhs._sec - rhs._sec); }

private:
    const int _sec;
};

std::ostream& operator << (std::ostream& out, const Time& time)
{
    char fill = out.fill('0');
    out << std::setw(2) << time.hour() << ':'
        << std::setw(2) << time.min()  << ':'
        << std::setw(2) << time.sec();
    out.fill(fill);
    return out;
}

enum Hour   { hour   };
enum Minute { minute };
enum Second { second };

Time operator * (int h, Hour)   { return Time(h, 0, 0); }
Time operator * (int m, Minute) { return Time(0, m, 0); }
Time operator * (int s, Second) { return Time(0, 0, s); }

int main(int, char* [])
{
    Time now(1, 23, 45);

    std::cout << "now          " << now             << std::endl;
    std::cout << "+  1 hour    " << now +  1*hour   << std::endl;
    std::cout << "+ 99 hours   " << now + 99*hour   << std::endl;
    std::cout << "+  1 minute  " << now +  1*minute << std::endl;
    std::cout << "+ 90 minutes " << now + 90*minute << std::endl;
    std::cout << "- 30 minutes " << now - 30*minute << std::endl;
    std::cout << "+ 90 seconds " << now + 90*second << std::endl;
    std::cout << "- 90 seconds " << now - 90*second << std::endl;

    return 0;
}


実行結果。

 $ ./time
 now          01:23:45
 +  1 hour    02:23:45
 + 99 hours   100:23:45
 +  1 minute  01:24:45
 + 90 minutes 02:53:45
 - 30 minutes 00:53:45
 + 90 seconds 01:25:15
 - 90 seconds 01:22:15