#ifndef __SPEED_TEST_CLASS_H__
#define __SPEED_TEST_CLASS_H__

#include "errorClass.h"
#include <iostream>
#include <vector>

#ifdef _WIN32
#include <windows.h>
typedef LARGE_INTEGER SPD;
#else
#include <sys/time.h>
typedef union _SPD{
        long long QuadPart;                     //!< 128ビット
        struct{
            long          sec;         //!< 下位64ビット
            long          usec;        //!< 上位64ビット
        };
	   struct timeval tv;
        _SPD():QuadPart(0){};              //!< 初期化リストで初期化
    }SPD;
#endif //_WIN32


//! プログラムの実行速度を計測するクラス.
/*!  */
class speedTestClass
{
//変数とか
private:
    unsigned long                           max_length;
    SPD                                     cpu_freq;               //!< 計測の精度
    SPD                                     t_start;                //!< 計測が終了した時の時間を入れる
    SPD                                     t_end;                  //!< 計測を開始した時の時間を入れる
    std::vector<long long>                  wlonglist;              //!< long型の双方向リスト
    std::vector<long long>::iterator        wlonglistit;            //!< long型の双方向リスト
    std::vector<std::string>                stringlist;             //!< std::string型の双方向リスト 計測時のプロセス名とかを格納
    std::vector<std::string>::iterator      stringlistit;           //!< std::string型の双方向リスト 計測時のプロセス名とかを格納
    void                                    (speedTestClass::*Switch)(std::string);                //!< テーブル処理用変数
protected:
public:
//関数とか
private:
    void                start(std::string memo);
    void                stop(std::string memo);
    void                forceStop(void);                        // 測定中にshowTimeなどの関数を呼んだ時に強制的に測定を止める
    void                checkTimeIndex(unsigned int &index);    // 参照のチェック
    unsigned long       checkTimeIndex(std::string &name);      // 参照のチェック
protected:
public:
    speedTestClass();                                           // 変数の初期化など
    ~speedTestClass();                                          // とくになし
    void                st();                                   // 呼ぶたびに計測の開始と終了
    void                st(std::string);                        // 呼ぶたびに計測の開始と終了

    long double         getTime(unsigned int index);            // ラップタイムの取得
    long double         getTime(std::string name);              // ラップタイムの取得
    void                showTime(unsigned int index);           // ラップタイムの表示
    void                showTime(std::string name);             // ラップタイムの表示
    void                showTimeAll(void);                      // すべてのタイムの取得
    void                clearTime(unsigned int index);          // 記録を削除
    void                clearTime(std::string name);            // 記録を削除
    void                clearTimeAll(void);                     // 記録を削除
};

#endif //__SPEED_TEST_CLASS_H__
