+#define ENABLE_SAFE_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) { return T(-int(d)); } \
+inline T& operator+=(T& d1, const T d2) { d1 = d1 + d2; return d1; } \
+inline T& operator-=(T& d1, const T d2) { d1 = d1 - d2; return d1; } \
+inline T& operator*=(T& d, int i) { d = T(int(d) * i); return d; }
+
+#define ENABLE_OPERATORS_ON(T) ENABLE_SAFE_OPERATORS_ON(T) \
+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 T operator/(const T d, int i) { return T(int(d) / i); } \
+inline T& operator/=(T& d, int i) { d = T(int(d) / i); return d; }
+
+ENABLE_OPERATORS_ON(Value)
+ENABLE_OPERATORS_ON(PieceType)
+ENABLE_OPERATORS_ON(Piece)
+ENABLE_OPERATORS_ON(Color)
+ENABLE_OPERATORS_ON(Depth)
+ENABLE_OPERATORS_ON(Square)
+ENABLE_OPERATORS_ON(File)
+ENABLE_OPERATORS_ON(Rank)
+
+/// Added operators for adding integers to a Value
+inline Value operator+(Value v, int i) { return Value(int(v) + i); }
+inline Value operator-(Value v, int i) { return Value(int(v) - i); }
+
+ENABLE_SAFE_OPERATORS_ON(Score)
+
+/// Only declared but not defined. We don't want to multiply two scores due to
+/// a very high risk of overflow. So user should explicitly convert to integer.
+inline Score operator*(Score s1, Score s2);
+
+/// Division of a Score must be handled separately for each term
+inline Score operator/(Score s, int i) {
+ return make_score(mg_value(s) / i, eg_value(s) / i);
+}
+
+/// Weight score v by score w trying to prevent overflow
+inline Score apply_weight(Score v, Score w) {
+ return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
+ (int(eg_value(v)) * eg_value(w)) / 0x100);
+}
+
+#undef ENABLE_OPERATORS_ON
+#undef ENABLE_SAFE_OPERATORS_ON
+
+const Value PawnValueMidgame = Value(0x0C6);
+const Value PawnValueEndgame = Value(0x102);
+const Value KnightValueMidgame = Value(0x331);
+const Value KnightValueEndgame = Value(0x34E);
+const Value BishopValueMidgame = Value(0x344);
+const Value BishopValueEndgame = Value(0x359);
+const Value RookValueMidgame = Value(0x4F6);
+const Value RookValueEndgame = Value(0x4FE);
+const Value QueenValueMidgame = Value(0x9D9);
+const Value QueenValueEndgame = Value(0x9FE);
+
+extern const Value PieceValueMidgame[17]; // Indexed by Piece or PieceType
+extern const Value PieceValueEndgame[17];
+extern int SquareDistance[64][64];
+extern uint8_t BitCount8Bit[256];
+
+inline Color operator~(Color c) {
+ return Color(c ^ 1);
+}
+
+inline Square operator~(Square s) {
+ return Square(s ^ 56); // Vertical flip SQ_A1 -> SQ_A8
+}
+
+inline Value mate_in(int ply) {
+ return VALUE_MATE - ply;
+}
+
+inline Value mated_in(int ply) {
+ return -VALUE_MATE + ply;
+}
+
+inline Piece make_piece(Color c, PieceType pt) {
+ return Piece((c << 3) | pt);
+}
+
+inline PieceType type_of(Piece p) {
+ return PieceType(p & 7);
+}
+
+inline Color color_of(Piece p) {
+ return Color(p >> 3);
+}
+
+inline Square make_square(File f, Rank r) {
+ return Square((r << 3) | f);
+}
+
+inline bool is_ok(Square s) {
+ return s >= SQ_A1 && s <= SQ_H8;
+}
+
+inline File file_of(Square s) {
+ return File(s & 7);
+}
+
+inline Rank rank_of(Square s) {
+ return Rank(s >> 3);
+}
+
+inline Square mirror(Square s) {
+ return Square(s ^ 7); // Horizontal flip SQ_A1 -> SQ_H1
+}
+
+inline Square relative_square(Color c, Square s) {
+ return Square(s ^ (c * 56));
+}
+
+inline Rank relative_rank(Color c, Rank r) {
+ return Rank(r ^ (c * 7));
+}
+
+inline Rank relative_rank(Color c, Square s) {
+ return relative_rank(c, rank_of(s));
+}
+
+inline bool opposite_colors(Square s1, Square s2) {
+ int s = s1 ^ s2;
+ return ((s >> 3) ^ s) & 1;
+}
+
+inline int file_distance(Square s1, Square s2) {
+ return abs(file_of(s1) - file_of(s2));
+}
+
+inline int rank_distance(Square s1, Square s2) {
+ return abs(rank_of(s1) - rank_of(s2));
+}
+
+inline int square_distance(Square s1, Square s2) {
+ return SquareDistance[s1][s2];
+}
+
+inline char piece_type_to_char(PieceType pt) {
+ return " PNBRQK"[pt];
+}
+
+inline char file_to_char(File f) {
+ return char(f - FILE_A + int('a'));
+}
+
+inline char rank_to_char(Rank r) {
+ return char(r - RANK_1 + int('1'));
+}
+
+inline Square pawn_push(Color c) {
+ return c == WHITE ? DELTA_N : DELTA_S;
+}
+
+inline Square from_sq(Move m) {
+ return Square((m >> 6) & 0x3F);
+}
+
+inline Square to_sq(Move m) {
+ return Square(m & 0x3F);
+}
+
+inline bool is_special(Move m) {
+ return m & (3 << 14);
+}
+
+inline bool is_promotion(Move m) {
+ return (m & (3 << 14)) == (1 << 14);
+}
+
+inline int is_enpassant(Move m) {
+ return (m & (3 << 14)) == (2 << 14);
+}
+
+inline int is_castle(Move m) {
+ return (m & (3 << 14)) == (3 << 14);
+}
+
+inline PieceType promotion_type(Move m) {
+ return PieceType(((m >> 12) & 3) + 2);
+}
+
+inline Move make_move(Square from, Square to) {
+ return Move(to | (from << 6));
+}
+
+inline Move make_promotion(Square from, Square to, PieceType pt) {
+ return Move(to | (from << 6) | (1 << 14) | ((pt - 2) << 12)) ;
+}
+
+inline Move make_enpassant(Square from, Square to) {
+ return Move(to | (from << 6) | (2 << 14));
+}
+
+inline Move make_castle(Square from, Square to) {
+ return Move(to | (from << 6) | (3 << 14));
+}
+
+inline bool is_ok(Move m) {
+ return from_sq(m) != to_sq(m); // Catches also MOVE_NULL and MOVE_NONE
+}
+
+#include <string>
+
+inline const std::string square_to_string(Square s) {
+ char ch[] = { file_to_char(file_of(s)), rank_to_char(rank_of(s)), 0 };
+ return ch;
+}
+
+/// Our insertion sort implementation, works with pointers and iterators and is
+/// guaranteed to be stable, as is needed.
+template<typename T, typename K>
+void sort(K first, K last)
+{
+ T tmp;
+ K p, q;
+
+ for (p = first + 1; p < last; p++)
+ {
+ tmp = *p;
+ for (q = p; q != first && *(q-1) < tmp; --q)
+ *q = *(q-1);
+ *q = tmp;
+ }
+}
+