From 83d8d542166d77f5417d334d2e6138ace0820ae4 Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Mon, 3 Jan 2011 16:09:38 +0200 Subject: [PATCH] Use simple macro to enable operators Signed-off-by: Marco Costalba --- src/color.h | 2 +- src/depth.h | 2 +- src/piece.h | 4 +-- src/square.h | 8 +++--- src/types.h | 74 +++++++++++----------------------------------------- src/value.h | 16 +++++++++--- 6 files changed, 35 insertions(+), 71 deletions(-) diff --git a/src/color.h b/src/color.h index c6897a2e..08eb8d81 100644 --- a/src/color.h +++ b/src/color.h @@ -38,7 +38,7 @@ enum SquareColor { LIGHT }; -ENABLE_OPERATORS_ON(Color); +ENABLE_OPERATORS_ON(Color) //// diff --git a/src/depth.h b/src/depth.h index 6b266adb..4b9e0753 100644 --- a/src/depth.h +++ b/src/depth.h @@ -38,6 +38,6 @@ enum Depth { DEPTH_NONE = -127 * ONE_PLY }; -ENABLE_OPERATORS_ON(Depth); +ENABLE_OPERATORS_ON(Depth) #endif // !defined(DEPTH_H_INCLUDED) diff --git a/src/piece.h b/src/piece.h index 604a4b3a..be77079a 100644 --- a/src/piece.h +++ b/src/piece.h @@ -46,8 +46,8 @@ enum Piece { BP = 9, BN = 10, BB = 11, BR = 12, BQ = 13, BK = 14, PIECE_NONE = 16 }; -ENABLE_OPERATORS_ON(PieceType); -ENABLE_OPERATORS_ON(Piece); +ENABLE_OPERATORS_ON(PieceType) +ENABLE_OPERATORS_ON(Piece) //// diff --git a/src/square.h b/src/square.h index 1c4a3902..f89c72ee 100644 --- a/src/square.h +++ b/src/square.h @@ -68,10 +68,10 @@ enum SquareDelta { DELTA_NW = DELTA_N + DELTA_W }; -ENABLE_OPERATORS_ON(Square); -ENABLE_OPERATORS_ON(File); -ENABLE_OPERATORS_ON(Rank); -ENABLE_OPERATORS_ON(SquareDelta); +ENABLE_OPERATORS_ON(Square) +ENABLE_OPERATORS_ON(File) +ENABLE_OPERATORS_ON(Rank) +ENABLE_OPERATORS_ON(SquareDelta) //// diff --git a/src/types.h b/src/types.h index d6c7d10a..161117f8 100644 --- a/src/types.h +++ b/src/types.h @@ -117,64 +117,20 @@ inline void __cpuid(int CPUInfo[4], int) } #endif - -// Templetized operators used by enum types like Depth, Piece, Square and so on. -// We don't want to write the same inline for each different enum. Note that we -// pass by value to silence scaring warnings when using volatiles. -// Because these templates override common operators and are included in all the -// files, there is a possibility that the compiler silently performs some unwanted -// overrides. To avoid possible very nasty bugs the templates are disabled by default -// and must be enabled for each type on a case by case base. The enabling trick -// uses template specialization, namely we just declare following struct. -template struct TempletizedOperator; - -// Then to enable the enum type we use following macro that defines a specialization -// of TempletizedOperator for the given enum T. Here is defined typedef Not_Enabled. -// Name of typedef is chosen to produce somewhat informative compile error messages. -#define ENABLE_OPERATORS_ON(T) \ - template<> struct TempletizedOperator { typedef T Not_Enabled; } - -// Finally we use macro OK(T) to check if type T is enabled. The macro simply -// tries to use Not_Enabled, if was not previously defined a compile error occurs. -// The check is done fully at compile time and there is zero overhead at runtime. -#define OK(T) typedef typename TempletizedOperator::Not_Enabled Type - -template -inline T operator+ (const T d1, const T d2) { OK(T); return T(int(d1) + int(d2)); } - -template -inline T operator- (const T d1, const T d2) { OK(T); return T(int(d1) - int(d2)); } - -template -inline T operator* (int i, const T d) { OK(T); return T(i * int(d)); } - -template -inline T operator* (const T d, int i) { OK(T); return T(int(d) * i); } - -template -inline T operator/ (const T d, int i) { OK(T); return T(int(d) / i); } - -template -inline T operator- (const T d) { OK(T); return T(-int(d)); } - -template -inline T operator++ (T& d, int) { OK(T); d = T(int(d) + 1); return d; } - -template -inline T operator-- (T& d, int) { OK(T); d = T(int(d) - 1); return d; } - -template -inline void operator+= (T& d1, const T d2) { OK(T); d1 = d1 + d2; } - -template -inline void operator-= (T& d1, const T d2) { OK(T); d1 = d1 - d2; } - -template -inline void operator*= (T& d, int i) { OK(T); d = T(int(d) * i); } - -template -inline void operator/= (T& d, int i) { OK(T); d = T(int(d) / i); } - -#undef OK +// Operators used by enum types like Depth, Piece, Square and so on. + +#define ENABLE_OPERATORS_ON(T) \ +inline T operator+ (const T d1, const T d2) { return T(int(d1) + int(d2)); } \ +inline T operator- (const T d1, const T d2) { return T(int(d1) - int(d2)); } \ +inline T operator* (int i, const T d) { return T(i * int(d)); } \ +inline T operator* (const T d, int i) { return T(int(d) * i); } \ +inline T operator/ (const T d, int i) { return T(int(d) / i); } \ +inline T operator- (const T d) { return T(-int(d)); } \ +inline T operator++ (T& d, int) {d = T(int(d) + 1); return d; } \ +inline T operator-- (T& d, int) { d = T(int(d) - 1); return d; } \ +inline void operator+= (T& d1, const T d2) { d1 = d1 + d2; } \ +inline void operator-= (T& d1, const T d2) { d1 = d1 - d2; } \ +inline void operator*= (T& d, int i) { d = T(int(d) * i); } \ +inline void operator/= (T& d, int i) { d = T(int(d) / i); } #endif // !defined(TYPES_H_INCLUDED) diff --git a/src/value.h b/src/value.h index 923a55e8..ef638923 100644 --- a/src/value.h +++ b/src/value.h @@ -43,7 +43,7 @@ enum Value { VALUE_ENSURE_SIGNED = -1 }; -ENABLE_OPERATORS_ON(Value); +ENABLE_OPERATORS_ON(Value) enum ScaleFactor { @@ -66,9 +66,6 @@ enum Score { SCORE_ENSURE_32_BITS_SIZE_N = -(1 << 16) }; -ENABLE_OPERATORS_ON(Score); - - // Extracting the _signed_ lower and upper 16 bits it not so trivial // because according to the standard a simple cast to short is // implementation defined and so is a right shift of a signed integer. @@ -91,6 +88,17 @@ inline Score operator/(Score s, int i) { return make_score(mg_value(s) / i, eg_v // a very high risk of overflow. So user should explicitly convert to integer. inline Score operator*(Score s1, Score s2); +// Rest of operators are standard: +inline Score operator+ (const Score d1, const Score d2) { return Score(int(d1) + int(d2)); } +inline Score operator- (const Score d1, const Score d2) { return Score(int(d1) - int(d2)); } +inline Score operator* (int i, const Score d) { return Score(i * int(d)); } +inline Score operator* (const Score d, int i) { return Score(int(d) * i); } +inline Score operator- (const Score d) { return Score(-int(d)); } +inline void operator+= (Score& d1, const Score d2) { d1 = d1 + d2; } +inline void operator-= (Score& d1, const Score d2) { d1 = d1 - d2; } +inline void operator*= (Score& d, int i) { d = Score(int(d) * i); } +inline void operator/= (Score& d, int i) { d = Score(int(d) / i); } + //// //// Inline functions -- 2.39.2