From 0e54eae28e3ffb83386efe2ad87c0ee711d8e2b2 Mon Sep 17 00:00:00 2001
From: joris <joris.dauphin@gmail.com>
Date: Thu, 16 Feb 2012 14:59:44 +0100
Subject: [PATCH] Rev.8022 fixed a warning, but broke the behavior of some
 method. Here is the fix for these methods.

---
 src/ai/ai_force.cpp      |  69 ++++-----
 src/ai/ai_plan.cpp       |  47 +++---
 src/include/unit_cache.h | 169 +++++++---------------
 src/map/map_fog.cpp      |  26 ++--
 src/unit/unit.cpp        | 128 +++++++++--------
 src/unit/unit_find.cpp   | 300 ++++++++++++++++++---------------------
 6 files changed, 339 insertions(+), 400 deletions(-)

diff --git a/src/ai/ai_force.cpp b/src/ai/ai_force.cpp
index 0a7a2eec5..c7218b3f4 100644
--- a/src/ai/ai_force.cpp
+++ b/src/ai/ai_force.cpp
@@ -50,40 +50,43 @@
 ----------------------------------------------------------------------------*/
 
 template <const bool IN_REACT_RANGE>
-struct AiForceEnemyFinder {
-	const CUnit *enemy;
-
-	inline bool found() const
-	{
-		return enemy != NULL;
-	}
-
-	inline bool operator() (const CUnit *const unit)
-	{
-		if (IN_REACT_RANGE) {
-			if (unit->Type->CanAttack) {
-				enemy = AttackUnitsInReactRange(*unit);
-			}
-		} else {
-			if (unit->Type->CanAttack) {
-				enemy = AttackUnitsInDistance(*unit, MaxMapWidth);
-			}
-		}
-		return enemy == NULL;
-	}
-
-	AiForceEnemyFinder(int force) : enemy(NULL)
+class AiForceEnemyFinder
+{
+public:
+	AiForceEnemyFinder(int force, const CUnit** enemy) : enemy(enemy)
 	{
+		Assert(enemy != NULL);
+		*enemy = NULL;
 		AiPlayer->Force[force].Units.for_each_if(*this);
 	}
 
-	AiForceEnemyFinder(AiForce *force) : enemy(NULL)
+	AiForceEnemyFinder(AiForce &force, const CUnit** enemy) : enemy(enemy)
 	{
-		force->Units.for_each_if(*this);
+		Assert(enemy != NULL);
+		*enemy = NULL;
+		force.Units.for_each_if(*this);
 	}
+
+	bool found() const { return *enemy != NULL; }
+
+	bool operator() (const CUnit *const unit) const
+	{
+		if (unit->Type->CanAttack == false) {
+			return *enemy == NULL;
+		}
+		if (IN_REACT_RANGE) {
+			*enemy = AttackUnitsInReactRange(*unit);
+		} else {
+			*enemy = AttackUnitsInDistance(*unit, MaxMapWidth);
+		}
+		return *enemy == NULL;
+	}
+private:
+	const CUnit **enemy;
 };
 
-class AiForceAttackSender {
+class AiForceAttackSender
+{
 public:
 	//  Send all units in the force to enemy at pos.
 	AiForceAttackSender(int force, const Vec2i &pos) : goalPos(pos), delta(0)
@@ -106,7 +109,7 @@ public:
 		force->Units.for_each(*this);
 	}
 
-	void operator() (CUnit *const unit)
+	void operator() (CUnit *const unit) const
 	{
 		// this may be problem if units are in bunker and we want sent
 		// them to attack
@@ -126,7 +129,7 @@ public:
 
 private:
 	Vec2i goalPos;
-	int delta;
+	mutable int delta;
 };
 
 
@@ -246,7 +249,7 @@ public:
 		memset(data, 0, len);
 		units.for_each(*this);
 	}
-	inline void operator() (CUnit *const unit) {
+	inline void operator() (const CUnit *const unit) const {
 		data[UnitTypeEquivs[unit->Type->Slot]]++;
 	}
 private:
@@ -324,7 +327,8 @@ void AiForce::Attack(const Vec2i &pos)
 
 	if (goalPos.x == -1 || goalPos.y == -1) {
 		/* Search in entire map */
-		const CUnit *enemy = AiForceEnemyFinder<false>(this).enemy;
+		const CUnit *enemy = NULL;
+		AiForceEnemyFinder<false>(*this, &enemy);
 		if (enemy) {
 			goalPos = enemy->tilePos;
 		}
@@ -733,7 +737,7 @@ void AiForce::Update()
 		Vec2i pos;
 
 		if (State == AiForceAttackingState_Attacking) {
-			unit = AiForceEnemyFinder<false>(this).enemy;
+			AiForceEnemyFinder<false>(*this, &unit);
 
 			if (!unit) {
 				// No enemy found, give up
@@ -761,7 +765,8 @@ void AiForceManager::Update()
 		if (force.Defending) {
 			force.Clean();
 			//  Look if still enemies in attack range.
-			if(!AiForceEnemyFinder<true>(&force).found()) {
+			const CUnit *dummy = NULL;
+			if(!AiForceEnemyFinder<true>(force, &dummy).found()) {
 				DebugPrint("%d:FIXME: not written, should send force #%d home\n"
 					_C_ AiPlayer->Player->Index _C_ f);
 				force.Defending = false;
diff --git a/src/ai/ai_plan.cpp b/src/ai/ai_plan.cpp
index 15ec2c6b9..e90812cf1 100644
--- a/src/ai/ai_plan.cpp
+++ b/src/ai/ai_plan.cpp
@@ -53,40 +53,45 @@
 --  Functions
 ----------------------------------------------------------------------------*/
 
-struct _EnemyOnMapTile {
-	CUnit *best;
-	const CUnit *const source;
-	const Vec2i pos;
-	_EnemyOnMapTile(const CUnit &unit, const Vec2i _pos) : best(0), source(&unit) , pos(_pos) {}
-	inline void operator() (CUnit *const unit) {
-		const CUnitType *const type = unit->Type;
+class _EnemyOnMapTile
+{
+public:
+	_EnemyOnMapTile(const CUnit &unit, const Vec2i _pos, CUnit **enemy) :
+		source(&unit) , pos(_pos), best(enemy)
+	{
+	}
+
+	void operator() (CUnit *const unit) const {
+		const CUnitType &type = *unit->Type;
 		// unusable unit ?
 		// if (unit->IsUnusable()) can't attack constructions
 		// FIXME: did SelectUnitsOnTile already filter this?
 		// Invisible and not Visible
-		if (unit->Removed || unit->Variable[INVISIBLE_INDEX].Value ||
-				//(!UnitVisible(unit, source->Player)) ||
-				unit->CurrentAction() == UnitActionDie) {
+		if (unit->Removed || unit->Variable[INVISIBLE_INDEX].Value
+			// || (!UnitVisible(unit, source->Player))
+			|| unit->CurrentAction() == UnitActionDie) {
 			return;
 		}
-		if (pos.x < unit->tilePos.x || pos.x >= unit->tilePos.x + type->TileWidth ||
-				pos.y < unit->tilePos.y || pos.y >= unit->tilePos.y + type->TileHeight) {
+		if (pos.x < unit->tilePos.x || pos.x >= unit->tilePos.x + type.TileWidth
+			|| pos.y < unit->tilePos.y || pos.y >= unit->tilePos.y + type.TileHeight) {
 			return;
 		}
-		if (!CanTarget(source->Type, type)) {
+		if (!CanTarget(source->Type, &type)) {
 			return;
 		}
 		if (!source->Player->IsEnemy(*unit)) { // a friend or neutral
 			return;
 		}
-		//
 		// Choose the best target.
-		//
-		if (!best || best->Type->Priority < type->Priority) {
-			best = unit;
+		if (!*best || (*best)->Type->Priority < type.Priority) {
+			*best = unit;
 		}
-		return;
 	}
+
+private:
+	const CUnit *const source;
+	const Vec2i pos;
+	CUnit **best;
 };
 
 /**
@@ -99,9 +104,11 @@ struct _EnemyOnMapTile {
 */
 static CUnit *EnemyOnMapTile(const CUnit &source, const Vec2i& pos)
 {
-	_EnemyOnMapTile filter(source, pos);
+	CUnit* enemy = NULL;
+
+	_EnemyOnMapTile filter(source, pos, &enemy);
 	Map.Field(pos)->UnitCache.for_each(filter);
-	return filter.best;
+	return enemy;
 }
 
 /**
diff --git a/src/include/unit_cache.h b/src/include/unit_cache.h
index 7e864579c..ddd6b25e1 100644
--- a/src/include/unit_cache.h
+++ b/src/include/unit_cache.h
@@ -44,83 +44,52 @@
 ----------------------------------------------------------------------------*/
 
 class CUnit;
-
+class CMap;
 /**
 **  Unit cache
 */
-struct CUnitCache {
-	std::vector<CUnit *> Units;
+class CUnitCache
+{
+public:
+	typedef std::vector<CUnit *>::iterator iterator;
+	typedef std::vector<CUnit *>::const_iterator const_iterator;
 
-	CUnitCache() : Units() { Units.clear();}
+public:
+	CUnitCache() : Units()
+	{
+	}
 
-	inline size_t size() const
-	{
-		return Units.size();
-	}
-	inline void clear()
-	{
-		Units.clear();
-	}
-	inline CUnit * operator[] (const unsigned int index) const
+	size_t size() const { return Units.size(); }
+
+	void clear() { Units.clear(); }
+
+	const_iterator begin() const { return Units.begin(); }
+	iterator begin() { return Units.begin(); }
+	const_iterator end() const { return Units.end(); }
+	iterator end() { return Units.end(); }
+
+	CUnit * operator[] (const unsigned int index) const
 	{
 		//Assert(index < Units.size());
 		return Units[index];
 	}
-	inline CUnit * operator[] (const unsigned int index) {
+	CUnit * operator[] (const unsigned int index) {
 		//Assert(index < Units.size());
 		return Units[index];
 	}
 
 	/**
-	 *  @brief Find the first unit in a tile chache for which a predicate is true.
+	 *  @brief Find the first unit in a tile cache for which a predicate is true.
 	 *  @param  pred   A predicate object vith bool operator()(const CUnit *).
-	 *  @return   The first unit i in the cache
-	 *  such that @p pred(*i) is true, or NULL if no such iterator exists.
+	 *  @return   The first unit u in the cache
+	 *  such that @p pred(u) is true, or NULL if no such unit exists.
 	 */
 	template<typename _T>
-	inline CUnit *find(const _T &pred) const
+	CUnit *find(const _T &pred) const
 	{
-#if __GNUC__ <  4
-		if(Units.size()) {
-			std::vector<CUnit *>::const_iterator beg(Units.begin()), end(Units.end());
-			std::vector<CUnit *>::const_iterator ret = std::find_if(beg, end, pred);
-			return ret != end ? (*ret) : NULL;
-		}
-		return NULL;
-#else
-		//GCC version only since std::vector::data() is not in STL
-		const size_t size = Units.size();
-		if(size) {
-			const CUnit *unit;
-			int n = (size+3)/4;
-			const CUnit **cache = (const CUnit **)Units.data();
-			switch (size & 3) {
-				case 0:
-				do {
-					unit = *cache;
-					if(pred(unit))
-						return (CUnit *)unit;
-					cache++;
-				case 3:
-					unit = *cache;
-					if(pred(unit))
-						return (CUnit *)unit;
-					cache++;
-				case 2:
-					unit = *cache;
-					if(pred(unit))
-						return (CUnit *)unit;
-					cache++;
-				case 1:
-					unit = *cache;
-					if(pred(unit))
-						return (CUnit *)unit;
-					cache++;
-				} while ( --n > 0 );
-			}
-		}
-		return NULL;
-#endif
+		std::vector<CUnit *>::const_iterator ret = std::find_if(Units.begin(), Units.end(), pred);
+
+		return ret != Units.end() ? (*ret) : NULL;
 	}
 
 	/**
@@ -132,27 +101,13 @@ struct CUnitCache {
 	 *  @p functor must not modify the order of the cache.
 	 */
 	template<typename _T>
-	inline void for_each(_T functor)
+	void for_each(const _T &functor)
 	{
 		const size_t size = Units.size();
-#if __GNUC__ <  4
-		for(unsigned int i = 0; i < size; ++i)
+
+		for (size_t i = 0; i != size; ++i) {
 			functor(Units[i]);
-#else
-		//GCC version only since std::vector::data() is not in STL
-		if(size) {
-			int n = (size+3)/4;
-			CUnit **cache = (CUnit **)Units.data();
-			switch (size & 3) {
-				case 0: do {
-								functor(*cache++);
-				case 3:			functor(*cache++);
-				case 2:			functor(*cache++);
-				case 1:			functor(*cache++);
-					} while ( --n > 0 );
-			}
 		}
-#endif
 	}
 
 	/**
@@ -165,38 +120,16 @@ struct CUnitCache {
 	 *  If @p functor return false then loop is exited.
 	 */
 	template<typename _T>
-	inline int for_each_if(_T &functor)
+	int for_each_if(const _T &functor)
 	{
 		const size_t size = Units.size();
-		size_t count = 0;
-#ifdef _MSC_VER
-		while(size && functor(Units[count]) && ++count < size);
-#else
-		if(size) {
-			int n = (size+3)/4;
-			switch (size & 3) {
-				case 0:
-				do {
-					if(!functor(Units[count]))
-						return count;
-					count++;
-				case 3:
-					if(!functor(Units[count]))
-						return count;
-					count++;
-				case 2:
-					if(!functor(Units[count]))
-						return count;
-					count++;
-				case 1:
-					if(!functor(Units[count]))
-						return count ;
-					count++;
-					} while ( --n > 0 );
+
+		for (size_t count = 0; count != size; ++count) {
+			if (functor(Units[count]) == false) {
+				return count;
 			}
 		}
-#endif
-		return count;
+		return size;
 	}
 
 
@@ -206,12 +139,12 @@ struct CUnitCache {
 	**  @param index  Unit index to remove from container.
 	**  @return pointer to removed element.
 	*/
-	inline CUnit * Remove(const unsigned int index)
+	CUnit *Remove(const unsigned int index)
 	{
 		const size_t size = Units.size();
 		Assert(index < size);
 		CUnit *tmp = Units[index];
-		if(size > 1) {
+		if (size > 1) {
 			Units[index] = Units[size - 1];
 		}
 		Units.pop_back();
@@ -223,15 +156,15 @@ struct CUnitCache {
 	**
 	**  @param unit  Unit pointer to remove from container.
 	*/
-	inline bool Remove(CUnit *const unit)
+	bool Remove(CUnit *const unit)
 	{
 #ifndef SECURE_UNIT_REMOVING
 		const size_t size = Units.size();
-		if(size == 1 && unit == Units[0]) {
+		if (size == 1 && unit == Units[0]) {
 			Units.pop_back();
 			return true;
 		} else {
-			for(unsigned int i = 0; i < size; ++i) {
+			for (unsigned int i = 0; i < size; ++i) {
 				// Do we care on unit sequence in tile cache ?
 				if (Units[i] == unit) {
 					Units[i] = Units[size - 1];
@@ -241,8 +174,7 @@ struct CUnitCache {
 			}
 		}
 #else
-		for(std::vector<CUnit *>::iterator i(Units.begin()), end(Units.end());
-			 i != end; ++i) {
+		for (std::vector<CUnit *>::iterator i(Units.begin()), end(Units.end()); i != end; ++i) {
 			if ((*i) == unit) {
 				Units.erase(i);
 				return true;
@@ -257,10 +189,9 @@ struct CUnitCache {
 	**
 	**  @param unit  Unit pointer to remove from container.
 	*/
-	inline void RemoveS(CUnit *const unit)
+	void RemoveS(CUnit *const unit)
 	{
-		for(std::vector<CUnit *>::iterator i(Units.begin()), end(Units.end());
-			 i != end; ++i) {
+		for (std::vector<CUnit *>::iterator i(Units.begin()), end(Units.end()); i != end; ++i) {
 			if ((*i) == unit) {
 				Units.erase(i);
 				return;
@@ -270,12 +201,12 @@ struct CUnitCache {
 
 	/**
 	**  Insert new unit into tile cache.
-	**	Sorted version for binary searching.
+	**  Sorted version for binary searching.
 	**
 	**  @param unit  Unit pointer to place in cache.
 	**  @return false if unit is already in cache and nothing is added.
 	*/
-	inline bool InsertS(CUnit *unit) {
+	bool InsertS(CUnit *unit) {
 		if (!binary_search(Units.begin(), Units.end(), unit))
 		{
   			Units.insert(std::lower_bound(Units.begin(), Units.end(), unit), unit);
@@ -284,15 +215,17 @@ struct CUnitCache {
 		return false;
 	}
 
-
 	/**
 	**  Insert new unit into tile cache.
 	**
 	**  @param unit  Unit pointer to place in cache.
 	*/
-	inline void Insert(CUnit *unit) {
+	void Insert(CUnit *unit) {
 		Units.push_back(unit);
 	}
+
+public:
+	std::vector<CUnit *> Units;
 };
 
 
diff --git a/src/map/map_fog.cpp b/src/map/map_fog.cpp
index 392ef4351..3faf1153a 100644
--- a/src/map/map_fog.cpp
+++ b/src/map/map_fog.cpp
@@ -81,15 +81,22 @@ static CGraphic *AlphaFogG;
 ----------------------------------------------------------------------------*/
 
 
-struct _filter_flags {
-	const CPlayer *player;
-	int fogmask;
-	_filter_flags(const CPlayer &p, int m) : player(&p), fogmask(m) {}
-	inline void operator() (const CUnit *const unit) {
+class _filter_flags
+{
+public:
+	_filter_flags(const CPlayer &p, int *fogmask) : player(&p), fogmask(fogmask)
+	{
+		Assert(fogmask != NULL);
+	}
+
+	void operator() (const CUnit *const unit) const {
 		if (!unit->IsVisibleAsGoal(*player)) {
-			fogmask &= ~unit->Type->FieldFlags;
+			*fogmask &= ~unit->Type->FieldFlags;
 		}
 	}
+private:
+	const CPlayer *player;
+	int *fogmask;
 };
 
 /**
@@ -104,10 +111,11 @@ struct _filter_flags {
 */
 int MapFogFilterFlags(CPlayer &player, const unsigned int index, int mask)
 {
-	_filter_flags filter(player, -1);
-	Map.Field(index)->UnitCache.for_each(filter);
-	return mask & filter.fogmask;
+	int fogMask = mask;
 
+	_filter_flags filter(player, &fogMask);
+	Map.Field(index)->UnitCache.for_each(filter);
+	return fogMask;
 }
 
 int MapFogFilterFlags(CPlayer &player, const Vec2i &pos, int mask)
diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp
index 40b0612bf..d6c022e43 100644
--- a/src/unit/unit.cpp
+++ b/src/unit/unit.cpp
@@ -681,16 +681,21 @@ void MarkUnitFieldFlags(const CUnit &unit)
 	} while (--h);
 }
 
-struct _UnmarkUnitFieldFlags {
-	const CUnit *const main;
-	CMapField *mf;
-	_UnmarkUnitFieldFlags(const CUnit &unit)
-		 : main(&unit) {}
-	inline void operator () (CUnit *const unit) {
+class _UnmarkUnitFieldFlags
+{
+public:
+	_UnmarkUnitFieldFlags(const CUnit &unit, CMapField *mf) : main(&unit), mf(mf)
+	{}
+
+	void operator () (CUnit *const unit) const
+	{
 		if (main != unit && unit->CurrentAction() != UnitActionDie) {
 			mf->Flags |= unit->Type->FieldFlags;
 		}
 	}
+private:
+	const CUnit *const main;
+	CMapField *mf;
 };
 
 
@@ -701,24 +706,22 @@ struct _UnmarkUnitFieldFlags {
 */
 void UnmarkUnitFieldFlags(const CUnit &unit)
 {
-	CMapField *mf;
-	const unsigned int flags = ~unit.Type->FieldFlags; //
-	int w, h = unit.Type->TileHeight;          // Tile height of the unit.
-	const int width = unit.Type->TileWidth;          // Tile width of the unit.
+	const unsigned int flags = ~unit.Type->FieldFlags;
+	const int width = unit.Type->TileWidth;
+	int h = unit.Type->TileHeight;
 	unsigned int index = unit.Offset;
 
 	if (unit.Type->Vanishes) {
 		return ;
 	}
-
-	_UnmarkUnitFieldFlags funct(unit);
-
 	do {
-		mf = Map.Field(index);
-		w = width;
+		CMapField *mf = Map.Field(index);
+
+		int w = width;
 		do {
 			mf->Flags &= flags;//clean flags
-			funct.mf = mf;
+			_UnmarkUnitFieldFlags funct(unit, mf);
+
 			mf->UnitCache.for_each(funct);
 			++mf;
 		} while(--w);
@@ -1201,64 +1204,63 @@ void UnitGoesOutOfFog(CUnit &unit, const CPlayer &player)
 }
 
 template<const bool MARK>
-struct _TileSeen {
-	const CPlayer *player;
-	int cloak;
+class _TileSeen
+{
+public:
+	_TileSeen(const CPlayer &p , int c) : player(&p), cloak(c)
+	{}
 
-	_TileSeen(const CPlayer &p , int c): player(&p), cloak(c) {}
-
-	inline void operator() ( CUnit *const unit) {
-		if (cloak == (int)unit->Type->PermanentCloak) {
-			const int p = player->Index;
-			if(MARK) {
-				//
-				//  If the unit goes out of fog, this can happen for any player that
-				//  this player shares vision with, and can't YET see the unit.
-				//  It will be able to see the unit after the Unit->VisCount ++
-				//
-				if (!unit->VisCount[p]) {
-					for (int pi = 0; pi < PlayerMax; ++pi) {
-						if ((pi == p /*player->Index*/) ||
-								player->IsBothSharedVision(Players[pi])) {
-							if (!unit->IsVisible(Players[pi])) {
-								UnitGoesOutOfFog(*unit, Players[pi]);
-							}
+	void operator() (CUnit *const unit) const {
+		if (cloak != (int)unit->Type->PermanentCloak) {
+			return ;
+		}
+		const int p = player->Index;
+		if (MARK) {
+			//  If the unit goes out of fog, this can happen for any player that
+			//  this player shares vision with, and can't YET see the unit.
+			//  It will be able to see the unit after the Unit->VisCount ++
+			if (!unit->VisCount[p]) {
+				for (int pi = 0; pi < PlayerMax; ++pi) {
+					if ((pi == p /*player->Index*/)
+						|| player->IsBothSharedVision(Players[pi])) {
+						if (!unit->IsVisible(Players[pi])) {
+							UnitGoesOutOfFog(*unit, Players[pi]);
 						}
 					}
 				}
-				unit->VisCount[p/*player->Index*/]++;
-			} else {
-				/*
-				 * HACK: UGLY !!!
-				 * There is bug in Seen code conneded with
-				 * UnitActionDie and Cloacked units.
-				 */
-				if(!unit->VisCount[p] && unit->CurrentAction() == UnitActionDie)
-				{
-					return;
-				}
+			}
+			unit->VisCount[p/*player->Index*/]++;
+		} else {
+			/*
+			 * HACK: UGLY !!!
+			 * There is bug in Seen code conneded with
+			 * UnitActionDie and Cloacked units.
+			 */
+			if (!unit->VisCount[p] && unit->CurrentAction() == UnitActionDie) {
+				return;
+			}
 
-				Assert(unit->VisCount[p]);
-				unit->VisCount[p]--;
-				//
-				//  If the unit goes under of fog, this can happen for any player that
-				//  this player shares vision to. First of all, before unmarking,
-				//  every player that this player shares vision to can see the unit.
-				//  Now we have to check who can't see the unit anymore.
-				//
-				if (!unit->VisCount[p]) {
-					for (int pi = 0; pi < PlayerMax; ++pi) {
-						if (pi == p/*player->Index*/ ||
-							player->IsBothSharedVision(Players[pi])) {
-							if (!unit->IsVisible(Players[pi])) {
-								UnitGoesUnderFog(*unit, Players[pi]);
-							}
+			Assert(unit->VisCount[p]);
+			unit->VisCount[p]--;
+			//  If the unit goes under of fog, this can happen for any player that
+			//  this player shares vision to. First of all, before unmarking,
+			//  every player that this player shares vision to can see the unit.
+			//  Now we have to check who can't see the unit anymore.
+			if (!unit->VisCount[p]) {
+				for (int pi = 0; pi < PlayerMax; ++pi) {
+					if (pi == p/*player->Index*/ ||
+						player->IsBothSharedVision(Players[pi])) {
+						if (!unit->IsVisible(Players[pi])) {
+							UnitGoesUnderFog(*unit, Players[pi]);
 						}
 					}
 				}
 			}
 		}
 	}
+private:
+	const CPlayer *player;
+	int cloak;
 };
 
 /**
diff --git a/src/unit/unit_find.cpp b/src/unit/unit_find.cpp
index 5ac98088d..9e2eaf16d 100644
--- a/src/unit/unit_find.cpp
+++ b/src/unit/unit_find.cpp
@@ -229,94 +229,86 @@ CUnit *ResourceDepositOnMap(const Vec2i &pos, int resource)
 --  Finding units for attack
 ----------------------------------------------------------------------------*/
 
-struct BestTargetFinder {
-	const CUnit *attacker;
-	const int range;
-	CUnit *best_unit;
-	int best_cost;
+class BestTargetFinder
+{
+public:
+	BestTargetFinder(const CUnit &a, int r) :
+		attacker(&a), range(r)
+	{}
+	
+	CUnit *Find(CUnit* table[], const int table_size) const
+	{
+		return Find(table, table + table_size);
+	}
 
-	BestTargetFinder(const CUnit &a, int r) : attacker(&a), range(r),
-		 best_unit(0), best_cost(INT_MAX) {};
+	CUnit *Find(CUnitCache &cache) const
+	{
+		return Find(cache.begin(), cache.end());
+	}
 
-	inline void operator() (CUnit *const dest) {
+private:
+	template <typename Iterator>
+	CUnit *Find(Iterator begin, Iterator end) const
+	{
+		CUnit *enemy = NULL;
+		int best_cost = INT_MAX;
+
+		for (Iterator it = begin; it != end; ++it) {
+			const int cost = ComputeCost(*it);
+
+			if (cost < best_cost) {
+				enemy = *it;
+				best_cost = cost;
+			}
+		}
+		return enemy;
+	}
+
+	int ComputeCost(CUnit *const dest) const
+	{
 		const CPlayer &player = *attacker->Player;
+		const CUnitType &type = *attacker->Type;
+		const CUnitType &dtype = *dest->Type;
+		const int attackrange = attacker->Stats->Variables[ATTACKRANGE_INDEX].Max;
 
-		if (!player.IsEnemy(*dest)) { // a friend or neutral
-			return;
+		if (!player.IsEnemy(*dest) // a friend or neutral
+			|| !dest->IsVisibleAsGoal(player)
+			|| !CanTarget(&type, &dtype)) {
+			return INT_MAX;
+		}
+		// Unit in range ?
+		const int d = attacker->MapDistanceTo(*dest);
+
+		if (d > range || !UnitReachable(*attacker, *dest, attackrange)) {
+			return INT_MAX;
 		}
 
-		if (!dest->IsVisibleAsGoal(player)) {
-			return;
-		}
-
-		const CUnitType *const type =  attacker->Type;
-		const CUnitType *const dtype = dest->Type;
-		if (!CanTarget(type, dtype)) { // can't be attacked.
-			return;
-		}
-
-		//
-		// Unit in attack range?
-		//
-		int d = attacker->MapDistanceTo(*dest);
-
-		// Use Circle, not square :)
-		if (d > range) {
-			return;
-		}
-
-		//
 		// Calculate the costs to attack the unit.
 		// Unit with the smallest attack costs will be taken.
-		//
-		int attackrange = attacker->Stats->Variables[ATTACKRANGE_INDEX].Max;
 		int cost = 0;
 
-		//
 		// Priority 0-255
-		//
-		cost -= dtype->Priority * PRIORITY_FACTOR;
-		//
+		cost -= dtype.Priority * PRIORITY_FACTOR;
 		// Remaining HP (Health) 0-65535
-		//
 		cost += dest->Variable[HP_INDEX].Value * HEALTH_FACTOR;
 
-		if (d <= attackrange && d >= type->MinAttackRange) {
+		if (d <= attackrange && d >= type.MinAttackRange) {
 			cost += d * INRANGE_FACTOR;
 			cost -= INRANGE_BONUS;
 		} else {
 			cost += d * DISTANCE_FACTOR;
 		}
 
-		//
 		// Unit can attack back.
-		//
-		if (CanTarget(dtype, type)) {
+		if (CanTarget(&dtype, &type)) {
 			cost -= CANATTACK_BONUS;
 		}
-
-		//
-		// Take this target?
-		//
-		if (cost < best_cost && (d <= attackrange ||
-				UnitReachable(*attacker, *dest, attackrange))) {
-			best_unit = dest;
-			best_cost = cost;
-		}
-	}
-
-	CUnit *Find(CUnit* table[], const int table_size) {
-		for (int i = 0; i < table_size; ++i) {
-			this->operator() (table[i]);
-		}
-		return best_unit;
-	}
-
-	CUnit *Find(CUnitCache &cache) {
-		cache.for_each(*this);
-		return best_unit;
+		return cost;
 	}
 
+private:
+	const CUnit *attacker;
+	const int range;
 };
 
 /**
@@ -330,14 +322,8 @@ struct BestTargetFinder {
 **  @note   Limited to attack range smaller than 16.
 **  @note Will be moved to unit_ai.c soon.
 */
-struct BestRangeTargetFinder {
-	const CUnit *attacker;
-	const int range;
-	CUnit *best_unit;
-	int best_cost;
-	int good[32*32];
-	int bad[32*32];
-
+class BestRangeTargetFinder {
+public:
 	/**
 	**  @param a      Find in distance for this unit.
 	**  @param range  Distance range to look.
@@ -349,19 +335,35 @@ struct BestRangeTargetFinder {
 		memset(bad, 0 , sizeof(int) * 32 * 32);
 	};
 
-	struct FillBadGood {
-		const CUnit *attacker;
-		const int range;
-		int enemy_count;
-		int *good;
-		int *bad;
-
+	class FillBadGood
+	{
+	public:
 		FillBadGood(const CUnit &a, int r, int *g, int *b):
 			attacker(&a), range(r),
-			enemy_count(0), good(g), bad(b) {
+			enemy_count(0), good(g), bad(b)
+		{
 		}
 
-		inline void operator() (CUnit *const dest)
+		int Fill(CUnit *table[], const int table_size)
+		{
+			return Fill(table, table + table_size);
+		}
+
+		int Fill(CUnitCache &cache)
+		{
+			return Fill(cache.begin(), cache.end());
+		}
+	private:
+		template <typename Iterator>
+		int Fill(Iterator begin, Iterator end)
+		{
+			for (Iterator it = begin; it != end; ++it) {
+				Compute(*it);
+			}
+			return enemy_count;
+		}
+
+		void Compute(CUnit *const dest)
 		{
 			const CPlayer &player = *attacker->Player;
 
@@ -370,18 +372,16 @@ struct BestRangeTargetFinder {
 				return;
 			}
 
-			const CUnitType *const type =  attacker->Type;
-			const CUnitType *const dtype = dest->Type;
+			const CUnitType &type =  *attacker->Type;
+			const CUnitType &dtype = *dest->Type;
 			// won't be a target...
-			if (!CanTarget(type, dtype)) { // can't be attacked.
+			if (!CanTarget(&type, &dtype)) { // can't be attacked.
 				dest->CacheLock = 1;
 				return;
 			}
 
-			//
 			//  Calculate the costs to attack the unit.
 			//  Unit with the smallest attack costs will be taken.
-			//
 
 			int cost = 0;
 			const int hp_damage_evaluate =
@@ -399,65 +399,46 @@ struct BestRangeTargetFinder {
 				// FIXME : assume that PRIORITY_FACTOR>HEALTH_FACTOR
 				cost = HEALTH_FACTOR * (2 * hp_damage_evaluate -
 						 dest->Variable[HP_INDEX].Value) /
-					(dtype->TileWidth * dtype->TileWidth);
+					(dtype.TileWidth * dtype.TileWidth);
 				if (cost < 1) {
 					cost = 1;
 				}
 				cost = (-cost);
 			} else {
-				//
 				//  Priority 0-255
-				//
-				cost += dtype->Priority * PRIORITY_FACTOR;
-				//
+				cost += dtype.Priority * PRIORITY_FACTOR;
 				//  Remaining HP (Health) 0-65535
-				//
 				// Give a boost to unit we can kill in one shoot only
 
-				//
 				// calculate HP which will remain in the enemy unit, after hit
-				//
-				int effective_hp =
-					(dest->Variable[HP_INDEX].Value - 2 * hp_damage_evaluate);
+				int effective_hp = (dest->Variable[HP_INDEX].Value - 2 * hp_damage_evaluate);
 
-				//
 				// Unit we won't kill are evaluated the same
-				//
 				if (effective_hp > 0) {
 					effective_hp = 0;
 				}
 
-				//
 				// Unit we are sure to kill are all evaluated the same (except PRIORITY)
-				//
 				if (effective_hp < -hp_damage_evaluate) {
 					effective_hp = -hp_damage_evaluate;
 				}
 
-				//
 				// Here, effective_hp vary from -hp_damage_evaluate (unit will be killed) to 0 (unit can't be killed)
 				// => we prefer killing rather than only hitting...
-				//
 				cost += -effective_hp * HEALTH_FACTOR;
 
-				//
 				//  Unit can attack back.
-				//
-				if (CanTarget(dtype, type)) {
+				if (CanTarget(&dtype, &type)) {
 					cost += CANATTACK_BONUS;
 				}
 
-				//
 				// the cost may be divided accros multiple cells
-				//
-				cost = cost / (dtype->TileWidth * dtype->TileWidth);
+				cost = cost / (dtype.TileWidth * dtype.TileWidth);
 				if (cost < 1) {
 					cost = 1;
 				}
 
-				//
 				// Removed Unit's are in bunkers
-				//
 				int d;
 				if (attacker->Removed) {
 					d = attacker->Container->MapDistanceTo(*dest);
@@ -465,8 +446,7 @@ struct BestRangeTargetFinder {
 					d = attacker->MapDistanceTo(*dest);
 				}
 
-				int attackrange =
-					attacker->Stats->Variables[ATTACKRANGE_INDEX].Max;
+				int attackrange = attacker->Stats->Variables[ATTACKRANGE_INDEX].Max;
 				if (d <= attackrange ||
 					(d <= range && UnitReachable(*attacker, *dest, attackrange))) {
 					++enemy_count;
@@ -475,15 +455,15 @@ struct BestRangeTargetFinder {
 				}
 			}
 
-			const int missile_range = type->Missile.Missile->Range + range - 1;
+			const int missile_range = type.Missile.Missile->Range + range - 1;
 			const int x = dest->tilePos.x - attacker->tilePos.x + missile_range + 1;
 			const int y = dest->tilePos.y - attacker->tilePos.y + missile_range + 1;
 
 			// Mark the good/bad array...
 			int yy_offset = x + y * 32;
-			for (int yy = 0; yy < dtype->TileHeight; ++yy) {
+			for (int yy = 0; yy < dtype.TileHeight; ++yy) {
 				if ((y + yy >= 0) && (y + yy < 2 * missile_range + 1)) {
-					for (int xx = 0; xx < dtype->TileWidth; ++xx) {
+					for (int xx = 0; xx < dtype.TileWidth; ++xx) {
 						if ((x + xx >= 0) && (x + xx < 2 * missile_range + 1)) {
 							if (cost < 0) {
 								good[yy_offset + xx] -= cost;
@@ -495,50 +475,63 @@ struct BestRangeTargetFinder {
 				}
 				yy_offset += 32;
 			}
-
-		}
-
-		inline int Fill(CUnit *table[], const int table_size) {
-			for (int i = 0; i < table_size; ++i) {
-				this->operator() (table[i]);
-			}
-			return enemy_count;
-		}
-
-		inline int Fill(CUnitCache &cache) {
-			cache.for_each(*this);
-			return enemy_count;
 		}
 
 
+	private:
+		const CUnit *attacker;
+		const int range;
+		int enemy_count;
+		int *good;
+		int *bad;
 	};
 
-	inline void operator() (CUnit *const dest) {
+	CUnit *Find(CUnit* table[], const int table_size) {
+		FillBadGood(*attacker, range, good, bad).Fill(table, table_size);
+		return Find(table, table + table_size);
 
+	}
+
+	CUnit *Find(CUnitCache &cache) {
+		FillBadGood(*attacker, range, good, bad).Fill(cache);
+		return Find(cache.begin(), cache.end());
+	}
+
+private:
+	template <typename Iterator>
+	CUnit *Find(Iterator begin, Iterator end)
+	{
+		for (Iterator it = begin; it != end; ++it) {
+			Compute(*it);
+		}
+		return best_unit;
+	}
+
+	void Compute(CUnit *const dest)
+	{
 		if (dest->CacheLock) {
 			dest->CacheLock = 0;
 			return;
 		}
-
-		const CUnitType *const type =  attacker->Type;
-		const CUnitType *const dtype = dest->Type;
-		const int missile_range = type->Missile.Missile->Range + range - 1;
+		const CUnitType &type =  *attacker->Type;
+		const CUnitType &dtype = *dest->Type;
+		const int missile_range = type.Missile.Missile->Range + range - 1;
 		int x,y;
 
 		// put in x-y the real point which will be hit...
 		// (only meaningful when dtype->TileWidth > 1)
 		if (attacker->tilePos.x < dest->tilePos.x) {
 			x = dest->tilePos.x;
-		} else if (attacker->tilePos.x > dest->tilePos.x + dtype->TileWidth - 1) {
-			x = dest->tilePos.x + dtype->TileWidth - 1;
+		} else if (attacker->tilePos.x > dest->tilePos.x + dtype.TileWidth - 1) {
+			x = dest->tilePos.x + dtype.TileWidth - 1;
 		} else {
 			x = attacker->tilePos.x;
 		}
 
 		if (attacker->tilePos.y < dest->tilePos.y) {
 			y = dest->tilePos.y;
-		} else if (attacker->tilePos.y > dest->tilePos.y + dtype->TileHeight - 1) {
-			y = dest->tilePos.y + dtype->TileHeight - 1;
+		} else if (attacker->tilePos.y > dest->tilePos.y + dtype.TileHeight - 1) {
+			y = dest->tilePos.y + dtype.TileHeight - 1;
 		} else {
 			y = attacker->tilePos.y;
 		}
@@ -550,12 +543,12 @@ struct BestRangeTargetFinder {
 
 		int sbad = 0;
 		int sgood = 0;
-		int yy = -(type->Missile.Missile->Range - 1);
+		int yy = -(type.Missile.Missile->Range - 1);
 		int yy_offset = x + yy * 32;
-		for (;yy <= type->Missile.Missile->Range - 1; ++yy) {
+		for (;yy <= type.Missile.Missile->Range - 1; ++yy) {
 			if ((y + yy >= 0) && ((y + yy) < 2 * missile_range + 1)) {
-				for (int xx = -(type->Missile.Missile->Range - 1);
-					xx <= type->Missile.Missile->Range - 1; ++xx) {
+				for (int xx = -(type.Missile.Missile->Range - 1);
+					xx <= type.Missile.Missile->Range - 1; ++xx) {
 					if ((x + xx >= 0) && ((x + xx) < 2 * missile_range + 1)) {
 						sbad += bad[yy_offset + xx];
 						sgood += good[yy_offset + xx];
@@ -582,20 +575,13 @@ struct BestRangeTargetFinder {
 	}
 
 
-	inline CUnit *Find(	CUnit* table[], const int table_size) {
-		FillBadGood(*attacker, range, good, bad).Fill(table, table_size);
-		for (int i = 0; i < table_size; ++i) {
-			this->operator() (table[i]);
-		}
-		return best_unit;
-	}
-
-	inline CUnit *Find(CUnitCache &cache) {
-		FillBadGood(*attacker, range, good, bad).Fill(cache);
-		cache.for_each(*this);
-		return best_unit;
-	}
-
+private:
+	const CUnit *attacker;
+	const int range;
+	CUnit *best_unit;
+	int best_cost;
+	int good[32*32];
+	int bad[32*32];
 };
 
 struct CompareUnitDistance {
@@ -630,13 +616,11 @@ CUnit *AutoAttackUnitsInDistance(const CUnit &unit, int range,
 		CUnitCache &autotargets)
 {
 	// if necessary, take possible damage on allied units into account...
-	if (unit.Type->Missile.Missile->Range > 1 &&
-			(range + unit.Type->Missile.Missile->Range < 15)) {
+	if (unit.Type->Missile.Missile->Range > 1
+		&& (range + unit.Type->Missile.Missile->Range < 15)) {
 		return BestRangeTargetFinder(unit, range).Find(autotargets);
 	} else {
-		//
 		// Find the best unit to auto attack
-		//
 		return BestTargetFinder(unit, range).Find(autotargets);
 	}
 }