////////////////////////////////////////////////////////////////////// // TINT.h // // Copyright (C) SHINOHARA Takayuki 1998 // ////////////////////////////////////////////////////////////////////// // 「intクラスを作ろう!」と言って作ったジョークプログラムです。 // 組込み型intが持つインターフェイスをほぼすべて満たすという本格 // 的なクラスに仕上がっています。 // このソースを見れば、あなたの'int'への理解をより一層深めること // ができるかも知れません。 // (篠原隆之:1998/8/15) #ifndef HEADER_TINT #define HEADER_TINT // 多くの組込み型について宣言を展開するマクロ // (すべて) #define TINT_A(S) \ TINT_I(S) \ TINT_F(S) // (整数型) #define TINT_I(S) \ TINT_LE(S) \ TINT_S(S) // (浮動小数型) #define TINT_F(S) \ TINT_X(float,float) \ TINT_X(double,double) \ TINT_X(long double,long double) // (int以上の整数) #define TINT_LE(S) \ TINT_X(int,int) \ TINT_X(unsigned int,unsigned int) \ TINT_L(S) // (intより大きい整数) #define TINT_L(S) \ TINT_X(long,long) \ TINT_X(unsigned long,unsigned long) // (int以下の整数) #define TINT_SE(S) \ TINT_X(int,int) \ TINT_X(unsigned int,unsigned int) \ TINT_S(S) // (intより小さい整数) #define TINT_S(S) \ TINT_X(char,S) \ TINT_X(signed char,S) \ TINT_X(unsigned char,S) \ TINT_X(short,S) \ TINT_X(unsigned short,S) class TInt { protected: int x; public: // 補助関数 int& c_int() {return x;} int c_int()const {return x;} // デフォルトコンストラクタ TInt() {} // 組込み型によるコンストラクタ # define TINT_X(X,S) \ TInt(X a) :x(a){} TINT_SE(_) # undef TINT_X # define TINT_X(X,S) \ explicit TInt(X a) :x((int)a){} TINT_L(_) TINT_F(_) // コピーコンストラクタ TInt(const TInt& b) :x(b.x){} // 代入 const TInt& operator=(const TInt& b) {x=b.x;return*this;} # undef TINT_X # define TINT_X(X,S) \ const TInt& operator=(X b) {x=(int)b;return*this;} TINT_A(_) // キャスト operator int()const {return x;} # if !defined(__BORLANDC__) operator int&() {return x;} # endif // アドレス int* operator&() {return &x;} const int* operator&()const {return &x;} // 単項算術演算 TInt operator+()const {return TInt(x);} TInt operator-()const {return TInt(-x);} // 単項ビット演算 TInt operator~()const {return TInt(~x);} // 単項論理演算 bool operator!()const {return !x;} // 前置インクリメント、前置デクリメント const TInt& operator++() {++x;return*this;} const TInt& operator--() {--x;return*this;} // 後置インクリメント、後置デクリメント TInt operator++(int) {int w=x++;return TInt(w);} TInt operator--(int) {int w=x--;return TInt(w);} // 算術代入 const TInt& operator+=(const TInt& b) {x+=b.x;return*this;} const TInt& operator-=(const TInt& b) {x-=b.x;return*this;} const TInt& operator*=(const TInt& b) {x*=b.x;return*this;} const TInt& operator/=(const TInt& b) {x/=b.x;return*this;} const TInt& operator%=(const TInt& b) {x%=b.x;return*this;} # undef TINT_X # define TINT_X(X,S) \ const TInt& operator+=(X b) {x+=(int)b;return*this;} \ const TInt& operator-=(X b) {x-=(int)b;return*this;} \ const TInt& operator*=(X b) {x*=(int)b;return*this;} \ const TInt& operator/=(X b) {x/=(int)b;return*this;} TINT_A(_) # undef TINT_X # define TINT_X(X,S) \ const TInt& operator%=(X b) {x%=(int)b;return*this;} TINT_I(_) // ビットシフト代入 const TInt& operator<<=(const TInt& b) {x<<=b.x;return*this;} const TInt& operator>>=(const TInt& b) {x>>=b.x;return*this;} # undef TINT_X # define TINT_X(X,S) \ const TInt& operator<<=(X b) {x<<=b;return*this;} \ const TInt& operator>>=(X b) {x>>=b;return*this;} TINT_I(_) // ビット代入 const TInt& operator&=(const TInt& b) {x&=b.x;return*this;} const TInt& operator|=(const TInt& b) {x|=b.x;return*this;} const TInt& operator^=(const TInt& b) {x^=b.x;return*this;} # undef TINT_X # define TINT_X(X,S) \ const TInt& operator&=(X b) {x&=(int)b;return*this;} \ const TInt& operator|=(X b) {x|=(int)b;return*this;} \ const TInt& operator^=(X b) {x^=(int)b;return*this;} TINT_I(_) // 二項算術演算 friend TInt operator+(const TInt& a, const TInt& b) {return TInt(a.x+b.x);} friend TInt operator-(const TInt& a, const TInt& b) {return TInt(a.x-b.x);} friend TInt operator*(const TInt& a, const TInt& b) {return TInt(a.x*b.x);} friend TInt operator/(const TInt& a, const TInt& b) {return TInt(a.x/b.x);} friend TInt operator%(const TInt& a, const TInt& b) {return TInt(a.x%b.x);} # undef TINT_X # define TINT_X(X,S) \ friend S operator+(const TInt& a, X b) {return a.x+b;} \ friend S operator-(const TInt& a, X b) {return a.x-b;} \ friend S operator*(const TInt& a, X b) {return a.x*b;} \ friend S operator/(const TInt& a, X b) {return a.x/b;} \ friend S operator+(X a, const TInt& b) {return a+b.x;} \ friend S operator-(X a, const TInt& b) {return a-b.x;} \ friend S operator*(X a, const TInt& b) {return a*b.x;} \ friend S operator/(X a, const TInt& b) {return a/b.x;} TINT_A(TInt) # undef TINT_X # define TINT_X(X,S) \ friend S operator%(const TInt& a, X b) {return a.x%b;} \ friend S operator%(X a, const TInt& b) {return a%b.x;} TINT_I(TInt) // ビットシフト演算 friend TInt operator<<(const TInt& a, const TInt& b) {return a.x<>(const TInt& a, const TInt& b) {return a.x>>b.x;} # undef TINT_X # define TINT_X(X,S) \ friend TInt operator<<(const TInt& a, X b) {return a.x<<(int)b;} \ friend TInt operator>>(const TInt& a, X b) {return a.x>>(int)b;} \ friend S operator<<(X a, const TInt& b) {return a<>(X a, const TInt& b) {return a>>b.x;} TINT_I(TInt) // 二項ビット演算 friend TInt operator&(const TInt& a, const TInt& b) {return a.x&b.x;} friend TInt operator|(const TInt& a, const TInt& b) {return a.x|b.x;} friend TInt operator^(const TInt& a, const TInt& b) {return a.x^b.x;} # undef TINT_X # define TINT_X(X,S) \ friend S operator&(const TInt& a, X b){return a.x&b;} \ friend S operator|(const TInt& a, X b){return a.x|b;} \ friend S operator^(const TInt& a, X b){return a.x^b;} \ friend S operator&(X a, const TInt& b){return a&b.x;} \ friend S operator|(X a, const TInt& b){return a|b.x;} \ friend S operator^(X a, const TInt& b){return a^b.x;} TINT_I(TInt) // 比較演算 friend bool operator==(const TInt& a, const TInt& b) {return a.x==b.x;} friend bool operator!=(const TInt& a, const TInt& b) {return a.x!=b.x;} friend bool operator<=(const TInt& a, const TInt& b) {return a.x<=b.x;} friend bool operator>=(const TInt& a, const TInt& b) {return a.x>=b.x;} friend bool operator<(const TInt& a, const TInt& b) {return a.x(const TInt& a, const TInt& b) {return a.x>b.x;} # undef TINT_X # define TINT_X(X,S) \ friend bool operator==(const TInt& a, X b) {return a.x==b;} \ friend bool operator!=(const TInt& a, X b) {return a.x!=b;} \ friend bool operator<=(const TInt& a, X b) {return a.x<=b;} \ friend bool operator>=(const TInt& a, X b) {return a.x>=b;} \ friend bool operator<(const TInt& a, X b) {return a.x(const TInt& a, X b) {return a.x>b;} \ friend bool operator==(X a, const TInt& b) {return a==b.x;} \ friend bool operator!=(X a, const TInt& b) {return a!=b.x;} \ friend bool operator<=(X a, const TInt& b) {return a<=b.x;} \ friend bool operator>=(X a, const TInt& b) {return a>=b.x;} \ friend bool operator<(X a, const TInt& b) {return a(X a, const TInt& b) {return a>b.x;} TINT_A(_) }; // ポインタ template T* operator+(T* a, const TInt& b){return a+(int)b;} template T* operator-(T* a, const TInt& b){return a-(int)b;} template T* operator+=(T* a, const TInt& b){return a+=(int)b;} template T* operator-=(T* a, const TInt& b){return a-=(int)b;} #ifdef TINT_UTILITIES // ストリーム挿入、抽出 #include //ostream& operator<<(ostream& os, const TInt& a) {return os<>(istream& is, TInt& a) {return is>>a.c_int();} #endif //TINT_UTILITIES // TIntについての補足説明 // ---------------------- // ■'int'との互換性の高さ // // ・あらゆる組込みスカラー型との間で相互に変換可能。 // // ・printf等の可変個引数関数に対して、intとして振る舞う。 // (例)TInt x=10; // printf("%d", x); // // ・'&'演算子が'int*'型を返す。 // (例)void func(int*); // TInt x=10; // func(&x); // // ・任意のポインタに対するオフセット演算のオフセットとして使用できる。 // (例)class A; // TInt x=10; // A *p=new A[100]; // p += x; // // ・iostreamクラスにおける挿入と抽出で'int'と同じ扱いになる。 // TIntに対する<<,>>演算子を定義する必要がない。 // (ただし、一部のコンパイラで問題あり) // // ■'int'に取って代われない場面(言語仕様上の壁) // // ・静的な配列の宣言の添字は明示的整定数を要求する。 // (例)const int i=10; // const TInt x=10; // int a[i]; // int A[x]; // エラー(xは定数ではない) // // ・'int'と同じインターフェイスを持っていても'int'とは同一ではない。 // (例)TInt x = 10; // int y = 20; // bool b = true; // int z = b ? x : y; // エラー(xとyは型が違う) // // ■一部のコンパイラにおける問題 // // ・new[]演算子の添字。(Watcom C/C++ 11.0J) // (例)const int i=10; // const TInt x=10; // int *b = new int[i]; // int *B = new int[x]; // エラー(xは整数ではない) // int *C = new int[(int)x]; // OK(キャストで解決) // Watcom C/C++がnew[]の添字に明示的整数を要求することが問題。 // // ・iostreamクラスにおける抽出。(Borland C++ 5.02J) // TIntに対する>>演算子を定義する必要がある。 // これは operator int&() と operator int()const を曖昧と判断する // Borland C++の問題。 // #undef TINT_A #undef TINT_I #undef TINT_F #undef TINT_LE #undef TINT_L #undef TINT_SE #undef TINT_S #undef TINT_X #endif //HEADER_TINT