パラメーター用のクラス

経緯とか書くと長くなるのでまずはコードから

```cpp:PossibleChangeStatus.hpp
#ifndef __POSSIBLECHANGESTATUS_HPP__
#define __POSSIBLECHANGESTATUS_HPP__
#ifdef _MINWINDEF_ // Windows.h等がこのヘッダーより先にincludeされるとダメなのでundefする
#undef max
#undef min
#endif
#include <type_traits>
#include <algorithm>

inline float ChangeTwoDigits(const double Data) {
	return static_cast<float>(static_cast<int>((Data + 0.005) * 100)) / 100;
}

//C++17
template<typename T>
const T& clamp(const T& v, const T& lo, const T& hi) {
	return assert( !comp(hi, lo) ),
		(v < lo) ? lo : (hi < v) ? hi : v;
}

template<class T> class PossibleChangeStatus {
private:
	T MinStatus;
public:
	//public member variable
	T CurrentStatus, MaxStatus;

	PossibleChangeStatus() = default;
	PossibleChangeStatus(const PossibleChangeStatus&) = default;
	PossibleChangeStatus& operator=(const PossibleChangeStatus&) = default;
	PossibleChangeStatus(const T Max) : PossibleChangeStatus(Max, Max) {}
	PossibleChangeStatus(const T Current, const T Max, const T Min = 0)
		: MinStatus(Min), CurrentStatus(Current), MaxStatus(Max) {}


	//public member function
	PossibleChangeStatus operator+(const T Num) {
		return {
			clamp(this->CurrentStatus + Num, this->MinStatus, this->MaxStatus),
			this->MaxStatus, this->MinStatus
		};
	}
	PossibleChangeStatus operator-(const T Num) {
		return {
			clamp(this->CurrentStatus - Num, this->MinStatus, this->MaxStatus),
			this->MaxStatus, this->MinStatus
		};
	}
	PossibleChangeStatus operator*(const T Num) {
		return {
			clamp(this->CurrentStatus * Num, this->MinStatus, this->MaxStatus),
			this->MaxStatus, this->MinStatus
		};
	}
	PossibleChangeStatus operator/(const T Num) {
		return {
			clamp(this->CurrentStatus / Num, this->MinStatus, this->MaxStatus),
			this->MaxStatus, this->MinStatus
		};
	}
	PossibleChangeStatus& operator += (const T Num) {
		this->CurrentStatus = clamp(this->CurrentStatus + Num, this->MinStatus, this->MaxStatus);
		return *this;
	}
	PossibleChangeStatus& operator -= (const T Num) {
		this->CurrentStatus = clamp(this->CurrentStatus - Num, this->MinStatus, this->MaxStatus);
		return *this;
	}
	PossibleChangeStatus& operator *= (const T Num) {
		this->CurrentStatus = clamp(this->CurrentStatus * Num, this->MinStatus, this->MaxStatus);
		return *this;
	}
	PossibleChangeStatus& operator /= (const T Num) {
		this->CurrentStatus = clamp(this->CurrentStatus / Num, this->MinStatus, this->MaxStatus);
		return *this;
	}
	PossibleChangeStatus& operator++() {
		this->CurrentStatus = std::min(this->CurrentStatus + 1, this->MaxStatus);
		return *this;
	}
	PossibleChangeStatus operator++(int) {
		const auto re = *this;
		++(*this);
		return re;
	}
	PossibleChangeStatus& operator--() {
		this->CurrentStatus = std::max(this->CurrentStatus - 1, this->MinStatus);
		return *this;
	}
	PossibleChangeStatus operator--(int) {
		const auto re = *this;
		--(*this);
		return re;
	}
	T& operator * () { return this->CurrentStatus; }
	const T& operator * () const { return this->CurrentStatus; }
	T& get() { return this->CurrentStatus; }
	const T& get() const { return this->CurrentStatus; }
	bool operator< (const T CompareNum) const { return this->CurrentStatus < CompareNum; }
	bool operator<= (const T CompareNum) const { return this->CurrentStatus <= CompareNum; }
	bool operator> (const T CompareNum) const { return this->CurrentStatus > CompareNum; }
	bool operator>= (const T CompareNum) const { return this->CurrentStatus >= CompareNum; }
	bool IsMin() const { return this->CurrentStatus == this->MinStatus; }
	bool IsMax() const { return this->CurrentStatus == this->MaxStatus; }
	float GetProportion() const { return ChangeTwoDigits(static_cast<double>(this->CurrentStatus) / static_cast<double>(this->MaxStatus - this->MinStatus)); }
};
template<typename T>
inline bool operator==(T l, const PossibleChangeStatus<T>& r) { return l == r.CurrentStatus; }
template<typename T>
inline bool operator==(const PossibleChangeStatus<T>& l, T r) { return r == l; }
template<typename T>
inline bool operator!=(T l, const PossibleChangeStatus<T>& r) { return !(l == r); }
template<typename T>
inline bool operator!=(const PossibleChangeStatus<T>& l, T r) { return r != l; }

#endif
```
このクラス作った環境がVisual Studio Professional 2013だった関係もありますが、一応constexprの使用は控えてありますので、C++11以前でも一応使える(？)ようになってます。([yumetodo](http://qiita.com/yumetodo)氏みたく企画書読んだり大学の単位を捧げたりするほどC++やってないのでC++いくつまで使えるのかは知りません)

さて、作った経緯なんですが、現在公開中の未完成作品[モンスター討伐ゲーム　アンチ核家族化](http://aimegu.webcrow.jp/KamiodaGames/KamiodaWarrior/DefeatMonster/trial/)のパラメーターを管理するにあたり、Statusというクラスがこんなことになってまして…

```cpp:Status.h
#include <string>

class Status {
public:
	Status(std::vector<status_data> arr, int i, bool is_player_setting);
	std::string name;
	int hp, max_hp, mp, max_mp, attack, defence, magic_attack, magic_defence, speed, graph_handle;
	bool is_male;
};
```
変数定義もちょっと多いし、計算部分に毎度毎度std::maxとstd::min書くのがめちゃくちゃめんどくなりまして…。
特に敵からの範囲攻撃、味方による範囲回復になると各キャラのHP変更するだけで３個も書かないといけなくて…。

まあそれがあまりにめんどくて、このクラスを作ったわけです。
これならGetProportion関数使えばHPゲージの実装も楽ですし、Minimize関数使えば死亡判定可能ですし、Less関数使えばパラメーター表示色変更も実装できちゃいます。

># 追記１
>このクラスを他のキャラクター情報管理に使用するクラスと共にMITライセンスでGitHubに公開開始しました。
>当該リポジトリは[こちら](https://github.com/AinoMegumi/CharacterInformationLibrary)。
>2017年8月23日現在、動作を完全に保証できるコンパイル環境は以下の通りです。 
>
> - Microsoft Visual Studio 2013(PossibleChangeStatusクラスのみ)
> - Microsoft Visual Studio 2015
> - Microsoft Visual Studio 2017